300 lines
14 KiB
C#
300 lines
14 KiB
C#
using Autodesk.Revit.DB;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace GraphicsStudy
|
||
{
|
||
public static class LineListMethod
|
||
{
|
||
/// <summary>
|
||
/// 封闭轮廓线首尾相连
|
||
/// </summary>
|
||
/// <param name="lineList"></param>
|
||
/// <returns></returns>
|
||
public static List<Line> OrderLineList(this List<Line> lineList)
|
||
{
|
||
List<Autodesk.Revit.DB.Line> lines = new List<Autodesk.Revit.DB.Line> { lineList[0] };
|
||
lineList.RemoveAt(0);
|
||
XYZ firstStart = lines[0].GetEndPoint(0);
|
||
while (lineList.Count != 0)
|
||
{
|
||
XYZ lastEnd = lines.Last().GetEndPoint(1);
|
||
//回到起点
|
||
if (lastEnd.DistanceTo(firstStart) < 1 / 304.8)
|
||
{
|
||
break;
|
||
}
|
||
int index = lineList.FindIndex(m => m.GetEndPoint(0).DistanceTo(lastEnd) < 1 / 304.8);
|
||
if (index != -1)//最后一根线的终点与集合中某条线的起点相同
|
||
{
|
||
lines.Add(lineList.ElementAt(index));
|
||
//移除线
|
||
lineList.RemoveAt(index);
|
||
}
|
||
else//最后一根线的终点与集合中某条线的终点相同
|
||
{
|
||
index = lineList.FindIndex(m => m.GetEndPoint(1).DistanceTo(lastEnd) < 1 / 304.8);
|
||
if (index != -1)//如果存在就将线前后翻转一下,添加进集合
|
||
{
|
||
lines.Add(lineList.ElementAt(index).CreateReversed() as Autodesk.Revit.DB.Line);
|
||
//移除线
|
||
lineList.RemoveAt(index);
|
||
}
|
||
else//可能是没有线与它相同
|
||
{
|
||
//可能是不封闭的
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
//MessageBox.Show(lines.Count.ToString());
|
||
CurveLoop cuLoop = CurveLoop.Create(lines.OfType<Curve>().ToList());
|
||
if (!cuLoop.IsOpen())
|
||
return lines;
|
||
return null;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 桥接线
|
||
/// </summary>
|
||
/// <param name="lines"></param>
|
||
/// <param name="range"></param>
|
||
/// <returns></returns>
|
||
public static List<Autodesk.Revit.DB.Line> JoinLines(this List<Autodesk.Revit.DB.Line> lines, double range)
|
||
{
|
||
var newLines = new List<Autodesk.Revit.DB.Line>();
|
||
//先按是否平行且间距小于range分组
|
||
List<List<Autodesk.Revit.DB.Line>> lineListList = new List<List<Autodesk.Revit.DB.Line>>();
|
||
for (int i = 0; i < lines.Count; i++)
|
||
{
|
||
int index = -1;
|
||
for (int j = 0; j < lineListList.Count; j++)
|
||
{
|
||
XYZ midPoint = lineListList[j][0].Evaluate(0.5, true);
|
||
Autodesk.Revit.DB.Line l = Autodesk.Revit.DB.Line.CreateBound(midPoint + 1000 * lineListList[j][0].Direction, midPoint - 1000 * lineListList[j][0].Direction);
|
||
XYZ pj = l.Project(lines[i].GetEndPoint(0)).XYZPoint;
|
||
double d = pj.DistanceTo(lines[i].GetEndPoint(0));
|
||
if (lineListList[j][0].Direction.IsParallel(lines[i].Direction) && d < range)
|
||
{
|
||
index = j;
|
||
break;
|
||
}
|
||
}
|
||
if (index == -1) lineListList.Add(new List<Autodesk.Revit.DB.Line>() { lines[i] });
|
||
else lineListList[index].Add(lines[i]);
|
||
}
|
||
for (int i = 0; i < lineListList.Count; i++)
|
||
{
|
||
List<Autodesk.Revit.DB.Line> lineList = lineListList[i];
|
||
//方向
|
||
var dirt = lineList.ElementAt(0).Direction;
|
||
//点乘信息 线索引 端点坐标 坐标点乘方向
|
||
List<Tuple<int, XYZ, double>> lineEndInfoList = new List<Tuple<int, XYZ, double>>();
|
||
//点乘信息添加
|
||
for (int j = 0; j < lineList.Count; j++)
|
||
{
|
||
lineEndInfoList.Add(Tuple.Create(j, lineList[j].GetEndPoint(0), lineList[j].GetEndPoint(0).DotProduct(dirt).Round(2)));
|
||
lineEndInfoList.Add(Tuple.Create(j, lineList[j].GetEndPoint(1), lineList[j].GetEndPoint(1).DotProduct(dirt).Round(2)));
|
||
}
|
||
//排序
|
||
lineEndInfoList = lineEndInfoList.OrderBy(x => x.Item3).ToList();
|
||
List<XYZ> xyzList = new List<XYZ>();
|
||
|
||
while (lineEndInfoList.Count > 0)
|
||
{
|
||
var first = lineEndInfoList.ElementAt(0);
|
||
lineEndInfoList.RemoveAt(0);
|
||
xyzList.Add(first.Item2);
|
||
//拿到第一个线对应的另外一个点
|
||
int index = lineEndInfoList.FindIndex(x => x.Item1 == first.Item1);
|
||
while (true)
|
||
{
|
||
//拿到这部分的集合
|
||
var tempInfoList = lineEndInfoList.GetRange(0, index + 1);
|
||
|
||
//最后的一个元素
|
||
var endTemp = tempInfoList.Last();
|
||
|
||
//移除该集合
|
||
lineEndInfoList.RemoveRange(0, index + 1);
|
||
|
||
//拿到只有一个点在该区域的集合
|
||
List<Tuple<int, XYZ, double>> remainTempList = new List<Tuple<int, XYZ, double>>();
|
||
//排除掉中间有2个索引的线
|
||
while (tempInfoList.Count > 0)
|
||
{
|
||
var firstTemp = tempInfoList.ElementAt(0);
|
||
tempInfoList.RemoveAt(0);
|
||
var tempIndex = tempInfoList.FindIndex(x => x.Item1 == firstTemp.Item1);
|
||
if (tempIndex != -1)
|
||
{
|
||
tempInfoList.RemoveAt(tempIndex);
|
||
}
|
||
else
|
||
{
|
||
remainTempList.Add(firstTemp);
|
||
}
|
||
}
|
||
if (remainTempList.Count == 0)
|
||
{
|
||
xyzList.Add(endTemp.Item2);
|
||
break;
|
||
}
|
||
//找对应最后的一个点的信息
|
||
index = remainTempList.Select(x => lineEndInfoList.FindIndex(m => m.Item1 == x.Item1)).OrderBy(x => x).Last();
|
||
if (index == -1)
|
||
{
|
||
if (lineEndInfoList.Count != 0 && lineEndInfoList[0].Item2.DistanceTo(endTemp.Item2) < 1 / 304.8)
|
||
{
|
||
//两线桥接--只有一个交点的情况
|
||
var firstIndex = lineEndInfoList[0].Item1;
|
||
lineEndInfoList.RemoveAt(0);
|
||
index = lineEndInfoList.FindIndex(x => x.Item1 == firstIndex);
|
||
}
|
||
else
|
||
{
|
||
xyzList.Add(endTemp.Item2);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for (int k = 0; k < xyzList.Count; k += 2)
|
||
{
|
||
XYZ pStart = xyzList[k];
|
||
XYZ pEnd = xyzList[k + 1];
|
||
if (pStart.DistanceTo(pEnd) > 1 / 304.8)
|
||
{
|
||
//var mc = Line.CreateBound(pStart, pEnd).GenerateMc(doc, true);
|
||
//mc.SetData(Properties.Resources.TestGuid, Properties.Resources.TestName, i.ToString() + " " + lineListList[i].Count);
|
||
newLines.Add(Autodesk.Revit.DB.Line.CreateBound(pStart, pEnd));
|
||
}
|
||
}
|
||
}
|
||
return newLines;
|
||
|
||
}
|
||
/// <summary>
|
||
/// 线相交打断
|
||
/// </summary>
|
||
/// <param name="curveList"></param>
|
||
/// <returns></returns>
|
||
public static List<Line> BreakInterLine(this List<Line> curveList)
|
||
{
|
||
List<Line> lineList = new List<Line>();
|
||
foreach (var m in curveList)
|
||
{
|
||
List<Line> breakLineList = new List<Line>();
|
||
int index = curveList.IndexOf(m);
|
||
//存储所需要的交点
|
||
List<XYZ> intersectPointList = new List<XYZ>();
|
||
//复制m线段然后变成无限长
|
||
Line mLine = Line.CreateBound(m.GetEndPoint(0), m.GetEndPoint(1));
|
||
mLine.MakeUnbound();
|
||
|
||
for (int i = 0; i < curveList.Count; i++)
|
||
{
|
||
if (mLine.Direction.IsParallel(curveList[i].Direction)) continue;
|
||
Line iLine = Line.CreateBound(curveList[i].GetEndPoint(0), curveList[i].GetEndPoint(1));
|
||
iLine.MakeUnbound();
|
||
mLine.Intersect(iLine, out IntersectionResultArray resultArray);
|
||
if (resultArray?.get_Item(0)?.XYZPoint != null)
|
||
{
|
||
XYZ resultPoint = resultArray.get_Item(0).XYZPoint;
|
||
double iDistance = curveList[i].GetEndPoint(0).DistanceTo(resultPoint) + curveList[i].GetEndPoint(1).DistanceTo(resultPoint);
|
||
double mDistance = m.GetEndPoint(0).DistanceTo(resultPoint) + m.GetEndPoint(1).DistanceTo(resultPoint);
|
||
if (iDistance - curveList[i].Length < 1 / 304.8 && mDistance - m.Length < 1 / 304.8)
|
||
{
|
||
intersectPointList.Add(resultArray.get_Item(0).XYZPoint);
|
||
}
|
||
}
|
||
}
|
||
//ToDo:不太确定起终点不放进去会不会有问题
|
||
//点去重
|
||
intersectPointList = intersectPointList.Where((x, i) => intersectPointList.FindIndex(c => c.DistanceTo(x) < 1 / 304.8) == i).ToList();
|
||
//排列点并重新生成线段集合
|
||
intersectPointList = intersectPointList.OrderBy(x => m.GetEndPoint(0).DistanceTo(x)).ToList();
|
||
//线段集合
|
||
List<Line> lines = new List<Line>();
|
||
for (int i = 0; i < intersectPointList.Count - 1; i++)
|
||
{
|
||
Line l = Line.CreateBound(intersectPointList[i], intersectPointList[i + 1]);
|
||
lines.Add(l);
|
||
}
|
||
lineList.AddRange(lines);
|
||
|
||
}
|
||
return lineList;
|
||
}
|
||
/// <summary>
|
||
/// 去除孤线
|
||
/// </summary>
|
||
/// <param name="curveList"></param>
|
||
/// <returns></returns>
|
||
public static List<Line> DeleteSolitary(this List<Line> curveList)
|
||
{
|
||
List<Line> lineList = new List<Line>();
|
||
foreach (var m in curveList)
|
||
{
|
||
List<Line> breakLineList = new List<Line>();
|
||
int index = curveList.IndexOf(m);
|
||
//存储所需要的交点
|
||
List<XYZ> intersectPointList = new List<XYZ>();
|
||
//复制m线段然后变成无限长
|
||
Line mLine = Line.CreateBound(m.GetEndPoint(0), m.GetEndPoint(1));
|
||
mLine.MakeUnbound();
|
||
|
||
for (int i = 0; i < curveList.Count; i++)
|
||
{
|
||
if (mLine.Direction.IsParallel(curveList[i].Direction)) continue;
|
||
Line iLine = Line.CreateBound(curveList[i].GetEndPoint(0), curveList[i].GetEndPoint(1));
|
||
iLine.MakeUnbound();
|
||
mLine.Intersect(iLine, out IntersectionResultArray resultArray);
|
||
if (resultArray?.get_Item(0)?.XYZPoint != null)
|
||
{
|
||
XYZ resultPoint = resultArray.get_Item(0).XYZPoint;
|
||
double iDistance = curveList[i].GetEndPoint(0).DistanceTo(resultPoint) + curveList[i].GetEndPoint(1).DistanceTo(resultPoint);
|
||
double mDistance = m.GetEndPoint(0).DistanceTo(resultPoint) + m.GetEndPoint(1).DistanceTo(resultPoint);
|
||
if (iDistance - curveList[i].Length < 1 / 304.8 && mDistance - m.Length < 1 / 304.8)
|
||
{
|
||
intersectPointList.Add(resultArray.get_Item(0).XYZPoint);
|
||
|
||
}
|
||
}
|
||
}
|
||
//点去重
|
||
intersectPointList = intersectPointList.Where((x, i) => intersectPointList.FindIndex(c => c.DistanceTo(x) < 1 / 304.8) == i).ToList();
|
||
//排列点并重新生成线段集合
|
||
intersectPointList = intersectPointList.OrderBy(x => m.GetEndPoint(0).DistanceTo(x)).ToList();
|
||
//线段集合
|
||
List<Line> lines = new List<Line>();
|
||
for (int i = 0; i < intersectPointList.Count - 1; i++)
|
||
{
|
||
Line l = Line.CreateBound(intersectPointList[i], intersectPointList[i + 1]);
|
||
lines.Add(l);
|
||
}
|
||
lineList.AddRange(lines);
|
||
|
||
}
|
||
return lineList;
|
||
}
|
||
/// <summary>
|
||
/// 生成详图线,事务在方法外面开启
|
||
/// </summary>
|
||
/// <param name="lines"></param>
|
||
/// <param name="v"></param>
|
||
public static void CreateDetailLine(this List<Line> lines, Document doc, View v)
|
||
{
|
||
foreach (var l in lines)
|
||
{
|
||
doc.Create.NewDetailCurve(v, l);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|