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 { /// /// 封闭轮廓线首尾相连 /// /// /// public static List OrderLineList(this List lineList) { List lines = new List { 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().ToList()); if (!cuLoop.IsOpen()) return lines; return null; } /// /// 桥接线 /// /// /// /// public static List JoinLines(this List lines, double range) { var newLines = new List(); //先按是否平行且间距小于range分组 List> lineListList = new List>(); 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() { lines[i] }); else lineListList[index].Add(lines[i]); } for (int i = 0; i < lineListList.Count; i++) { List lineList = lineListList[i]; //方向 var dirt = lineList.ElementAt(0).Direction; //点乘信息 线索引 端点坐标 坐标点乘方向 List> lineEndInfoList = new List>(); //点乘信息添加 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 xyzList = new List(); 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> remainTempList = new List>(); //排除掉中间有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; } /// /// 线相交打断 /// /// /// public static List BreakInterLine(this List curveList) { List lineList = new List(); foreach (var m in curveList) { List breakLineList = new List(); int index = curveList.IndexOf(m); //存储所需要的交点 List intersectPointList = new List(); //复制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 lines = new List(); 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; } /// /// 去除孤线 /// /// /// public static List DeleteSolitary(this List curveList) { List lineList = new List(); foreach (var m in curveList) { List breakLineList = new List(); int index = curveList.IndexOf(m); //存储所需要的交点 List intersectPointList = new List(); //复制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 lines = new List(); 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; } /// /// 生成详图线,事务在方法外面开启 /// /// /// public static void CreateDetailLine(this List lines, Document doc, View v) { foreach (var l in lines) { doc.Create.NewDetailCurve(v, l); } } } }