/// <summary> /// 取得所有的梁(水平與垂直向) /// </summary> /// <returns></returns> private List <LINE> GetAllBeams(Level targetLevel_) { FilteredElementCollector collector = new FilteredElementCollector(revitDoc); collector.OfCategory(BuiltInCategory.OST_StructuralFraming); collector.OfClass(typeof(FamilyInstance)); IList <Element> beams = collector.ToElements(); List <LINE> Beams = new List <LINE>(); foreach (Element beam in beams) { try { ///// 取得梁的Level Parameter mLevel = beam.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM); string levelName = mLevel.AsValueString(); //// 取得梁的類型與其寬度 ElementType type = revitDoc.GetElement(beam.GetTypeId()) as ElementType; Parameter b = type.LookupParameter("b"); double width = b.AsDouble(); ///檢查梁中心線是否有偏移 BuiltInParameter paraIndex = BuiltInParameter.START_Y_JUSTIFICATION; Parameter p1 = beam.get_Parameter(paraIndex); string offset = p1.AsValueString(); // 取得梁偏移量 BuiltInParameter paraIndex1 = BuiltInParameter.STRUCTURAL_BEAM_END0_ELEVATION; Parameter of1 = beam.get_Parameter(paraIndex1); string offset1 = of1.AsValueString(); BuiltInParameter paraIndex2 = BuiltInParameter.STRUCTURAL_BEAM_END1_ELEVATION; Parameter of2 = beam.get_Parameter(paraIndex2); string offset2 = of2.AsValueString(); if (offset1 != offset2) { continue; } double shift = Convert.ToDouble(offset1) / 304.8; LocationCurve Locurve = beam.Location as LocationCurve; Line line = Locurve.Curve as Line; XYZ direction = line.Direction; XYZ VertiDir = offset == "左" ? new XYZ(line.Direction.Y, -line.Direction.X, line.Direction.Z) : offset == "右" ? new XYZ(-line.Direction.Y, line.Direction.X, line.Direction.Z) : line.Direction; XYZ pp1 = line.GetEndPoint(0); XYZ pp2 = line.GetEndPoint(1); ///Ori Points XYZ stPoint = new XYZ(pp1.X + width / 2 * VertiDir.X, pp1.Y + width / 2 * VertiDir.Y, pp1.Z + width / 2 * VertiDir.Z); XYZ enPoint = new XYZ(pp1.X + line.Length * line.Direction.X + width / 2 * VertiDir.X, pp1.Y + line.Length * line.Direction.Y + width / 2 * VertiDir.Y, pp1.Z + line.Length * line.Direction.Z + width / 2 * VertiDir.Z); LINE LINE = new LINE(stPoint, enPoint); LINE.Name = beam.Name; LINE.LevelName = levelName; LINE.Width = width; if (Math.Round(LINE.GetStartPoint().Z, 3) == Math.Round(LINE.GetEndPoint().Z, 3)) { Beams.Add(LINE); } } catch (Exception) { } } return(Beams); }
private List <LINE> GetPolylineAndLineClosedRegion(List <LINE> Lines, string RadioCase) { List <LINE> RESULT = new List <LINE>(); List <LINE> newResult = new List <LINE>(); List <LINE> processLines = new List <LINE>(); foreach (LINE line in Lines) { if (line.Name == "Circle" && RadioCase == "Circle") { newResult.Add(line); } else if (RadioCase != "Circle") { processLines.Add(line); } } if (RadioCase == "Circle") { return(newResult); } List <int> flag = new List <int>() { }; for (int i = 0; i < processLines.Count; i++) { int j = 0; flag.Add(i); List <LINE> polyline = new List <LINE>() { processLines[i] }; while (j < processLines.Count) { if (flag.Contains(j)) { j++; continue; } foreach (LINE tmpLine in polyline) { if (IsConnected(tmpLine, processLines[j])) { polyline.Add(processLines[j]); flag.Add(j); j = -1; break; } } j++; } if (polyline.Count != 1) { double newX = polyline.Sum(tt => tt.GetStartPoint().X) / polyline.Count; double newY = polyline.Sum(tt => tt.GetStartPoint().Y) / polyline.Count; XYZ newPoint = new XYZ(newX, newY, 0); LINE newLine = new LINE(newPoint, newPoint, 10); newResult.Add(newLine); } } RESULT = newResult; return(RESULT); }
private List <LINE> TakeOffColumnEdge(Dictionary <string, List <LINE> > columns, List <LINE> floor) { foreach (KeyValuePair <string, List <LINE> > column in columns) { List <LINE> newFloor = new List <LINE>(); Dictionary <int, List <LINE> > tmpData = new Dictionary <int, List <LINE> >(); for (int ii = 0; ii < column.Value.Count; ii++) { LINE columnEdge = column.Value[ii]; for (int jj = 0; jj < floor.Count; jj++) { LINE floorEdge = floor[jj]; if (Math.Round(floorEdge.GetSlope(), 3) == Math.Round(columnEdge.GetSlope(), 3)) { continue; } if (Math.Abs(Math.Round(floorEdge.GetDirection().X, 3)) == Math.Abs(Math.Round(columnEdge.GetDirection().X, 3)) && Math.Abs(Math.Round(floorEdge.GetDirection().Y, 3)) == Math.Abs(Math.Round(columnEdge.GetDirection().Y, 3))) { continue; } XYZ crossPoint = floorEdge.GetCrossPoint(columnEdge); try { if (floorEdge.IsPointInLine(crossPoint) && columnEdge.IsPointInLine(crossPoint)) { XYZ innerPoint = IsInner(columnEdge.GetStartPoint(), floor) ? columnEdge.GetStartPoint() : columnEdge.GetEndPoint(); double dis1 = (crossPoint - floorEdge.GetStartPoint()).GetLength(); double dis2 = (crossPoint - floorEdge.GetEndPoint()).GetLength(); LINE newLine = null; List <LINE> newList = new List <LINE>(); if (dis1 > dis2) { floorEdge.ResetParameters(crossPoint, "EndPoint"); newLine = new LINE(crossPoint, innerPoint); newList.Add(floorEdge); if (dis2 != 0) { newList.Add(newLine); } } else { newLine = new LINE(innerPoint, crossPoint); floorEdge.ResetParameters(crossPoint, "StartPoint"); if (dis1 != 0) { newList.Add(newLine); } newList.Add(floorEdge); } tmpData[jj] = newList; } } catch (Exception) { } } } for (int kk = 0; kk < floor.Count; kk++) { if (tmpData.ContainsKey(kk)) { foreach (LINE item in tmpData[kk]) { newFloor.Add(item); } } else { newFloor.Add(floor[kk]); } } floor = new List <LINE>(); floor = newFloor; } return(floor); }
/// <summary> /// Pick a DWG import instance, extract polylines /// from it visible in the current view and create /// filled regions from them. /// </summary> public Dictionary <string, List <LINE> > GeneralCAD(UIDocument uidoc) { Document doc = uidoc.Document; View active_view = doc.ActiveView; List <GeometryObject> visible_dwg_geo = new List <GeometryObject>(); // Pick Import Instance Reference r = uidoc.Selection.PickObject(ObjectType.Element, new JtElementsOfClassSelectionFilter <ImportInstance>()); var import = doc.GetElement(r) as ImportInstance; // Get Geometry var ge = import.get_Geometry(new Options()); foreach (var go in ge) { if (go is GeometryInstance) { var gi = go as GeometryInstance; var ge2 = gi.GetInstanceGeometry(); if (ge2 != null) { foreach (var obj in ge2) { // Only work on PolyLines if (obj is PolyLine | obj is Arc | obj is Line) { // Use the GraphicsStyle to get the // DWG layer linked to the Category // for visibility. var gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle; // Check if the layer is visible in the view. if (!active_view.GetCategoryHidden(gStyle.GraphicsStyleCategory.Id)) { visible_dwg_geo.Add(obj); } } } } } } // Do something with the info Dictionary <string, List <LINE> > res = new Dictionary <string, List <LINE> >(); if (visible_dwg_geo.Count > 0) { // Retrieve first filled region type var filledType = new FilteredElementCollector(doc) .WhereElementIsElementType() .OfClass(typeof(FilledRegionType)) .OfType <FilledRegionType>() .First(); using (var t = new Transaction(doc)) { t.Start("ProcessDWG"); List <LINE> tmp = new List <LINE>(); foreach (var obj in visible_dwg_geo) { var gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle; string layerName = gStyle.GraphicsStyleCategory.Name; tmp = res.ContainsKey(layerName) ? res[layerName] : new List <LINE>(); //if (obj is PolyLine) //{ // // Create loops for detail region // var poly = obj as PolyLine; // var points = poly.GetCoordinates(); // for (int kk = 0; kk < points.Count - 1; kk++) // { // tmp.Add(new LINE(points[kk], points[kk + 1])); // } //} //else if (obj is Line) //{ // var line = obj as Line; // tmp.Add(new LINE(line.GetEndPoint(0), // line.GetEndPoint(1))); //} //else if (obj is Arc) //{ // var Arc = obj as Arc; // pp[0] = Arc.Center; // pp[1] = Arc.Center; //} if (obj is Arc) { var Arc = obj as Arc; XYZ newPoint = new XYZ(Arc.Center.X, Arc.Center.Y, 0); LINE newLine = new LINE(newPoint, newPoint, 10); newLine.Name = "Circle"; tmp.Add(newLine); } if (obj is PolyLine) { // Create loops for detail region var poly = obj as PolyLine; var points = poly.GetCoordinates(); //List<XYZ> POINTs = points.ToList(); //double meanX = POINTs.Sum(tt => tt.X) / POINTs.Count; //double meanY = POINTs.Sum(tt => tt.Y) / POINTs.Count; //XYZ newPoint = new XYZ(meanX, meanY, 0); //LINE newLine = new LINE(newPoint, newPoint, 10); //newLine.Name = "PolyLine-" + POINTs.Count.ToString(); //tmp.Add(newLine); for (int kk = 0; kk < points.Count - 1; kk++) { LINE newLine = new LINE(points[kk], points[kk + 1]); newLine.Name = "Polyline"; tmp.Add(newLine); } } else if (obj is Line) { var line = obj as Line; LINE newLine = new LINE(line.GetEndPoint(0), line.GetEndPoint(1)); newLine.Name = "Line"; tmp.Add(newLine); } res[layerName] = tmp; } } } return(res); }
/// <summary> /// Pick a DWG import instance, extract polylines /// from it visible in the current view and create /// filled regions from them. /// </summary> public Dictionary <string, List <LINE> > ProcessVisible(UIDocument uidoc) { Document doc = uidoc.Document; View active_view = doc.ActiveView; List <GeometryObject> visible_dwg_geo = new List <GeometryObject>(); // Pick Import Instance Reference r = uidoc.Selection.PickObject(ObjectType.Element, new JtElementsOfClassSelectionFilter <ImportInstance>()); var import = doc.GetElement(r) as ImportInstance; // Get Geometry var ge = import.get_Geometry(new Options()); foreach (var go in ge) { if (go is GeometryInstance) { var gi = go as GeometryInstance; var ge2 = gi.GetInstanceGeometry(); if (ge2 != null) { foreach (var obj in ge2) { // Only work on PolyLines if (obj is PolyLine | obj is Arc | obj is Line) { // Use the GraphicsStyle to get the // DWG layer linked to the Category // for visibility. var gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle; // Check if the layer is visible in the view. if (!active_view.GetCategoryHidden(gStyle.GraphicsStyleCategory.Id)) { visible_dwg_geo.Add(obj); } } } } } } // Do something with the info Dictionary <string, List <LINE> > res = new Dictionary <string, List <LINE> >(); if (visible_dwg_geo.Count > 0) { // Retrieve first filled region type var filledType = new FilteredElementCollector(doc) .WhereElementIsElementType() .OfClass(typeof(FilledRegionType)) .OfType <FilledRegionType>() .First(); using (var t = new Transaction(doc)) { t.Start("ProcessDWG"); List <LINE> tmp = new List <LINE>(); foreach (var obj in visible_dwg_geo) { var gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle; string layerName = gStyle.GraphicsStyleCategory.Name; LINE pp = null; if (obj is PolyLine) { // Create loops for detail region var poly = obj as PolyLine; var points = poly.GetCoordinates(); pp = new LINE(points[0], points[2]); } else if (obj is Arc) { var Arc = obj as Arc; pp = new LINE(Arc.Center, Arc.Center); } else if (obj is Line) { var line = obj as Line; pp = new LINE(line.GetEndPoint(0), line.GetEndPoint(1)); } tmp = res.ContainsKey(layerName) ? res[layerName] : new List <LINE>(); tmp.Add(pp); res[layerName] = tmp; } } } return(res); }
/// <summary> /// 多邊形中心處理 /// </summary> /// <param name="Lines"></param> /// <param name="RadioCase"></param> /// <returns></returns> private List <LINE> GetPolylineAndLineClosedRegion(List <LINE> Lines, string RadioCase) { List <LINE> RESULT = new List <LINE>(); List <LINE> newResult = new List <LINE>(); List <LINE> processLines = new List <LINE>(); foreach (LINE line in Lines) { if (line.Name == "Circle" && RadioCase == "Circle") { newResult.Add(line); } else if (RadioCase != "Circle" && line.Name != "Circle") { processLines.Add(line); } } if (RadioCase == "Circle") { return(newResult); } List <int> flag = new List <int>() { }; for (int i = 0; i < processLines.Count; i++) { int j = 0; flag.Add(i); List <LINE> polyline = new List <LINE>() { processLines[i] }; while (j < processLines.Count) { if (flag.Contains(j)) { j++; continue; } foreach (LINE tmpLine in polyline) { if (IsConnected(tmpLine, processLines[j])) { polyline.Add(processLines[j]); flag.Add(j); j = -1; break; } } j++; } bool IsSquare = false; if (RadioCase == "Square" && polyline.Count == 4 && Math.Round(polyline[0].GetLength(true), 3) == Math.Round(polyline[1].GetLength(true), 3) && Math.Round(polyline[1].GetLength(true), 3) == Math.Round(polyline[2].GetLength(true), 3) && Math.Round(polyline[2].GetLength(true), 3) == Math.Round(polyline[3].GetLength(true), 3)) { IsSquare = true; } if (RadioCase == "Square" && !IsSquare) { continue; } if (polyline.Count != 1) { double newX1 = polyline.Sum(tt => tt.GetStartPoint().X) / polyline.Count; double newY1 = polyline.Sum(tt => tt.GetStartPoint().Y) / polyline.Count; double newX2 = polyline.Sum(tt => tt.GetEndPoint().X) / polyline.Count; double newY2 = polyline.Sum(tt => tt.GetEndPoint().Y) / polyline.Count; double newX = (newX1 + newX2) / 2; double newY = (newY1 + newY2) / 2; XYZ newPoint = new XYZ(newX, newY, 0); LINE newLine = new LINE(newPoint, newPoint, 10); newResult.Add(newLine); } } RESULT = newResult; return(RESULT); }
public BEAM(LINE line1, LINE line2) { this.E_LINE_1 = line1; this.E_LINE_2 = line2; this.Center_Line = GetCenterLine(); }
public static bool Is_Horizontal(LINE line) { return(line.GetStartPoint().Y == line.GetEndPoint().Y ? true : false); }
public static bool Is_Vertical(LINE line) { return(line.GetStartPoint().X == line.GetEndPoint().X ? true : false); }
/// <summary> /// Classify Lines to "closed curve" or "H_dir_lines" or "V_dir_lines" or "else_dir_lines" /// </summary> /// <param name="LINES"></param> /// <param name="Collect"></param> /// <param name="H_Direction_Lines"></param> /// <param name="V_Direction_Lines"></param> /// <param name="Else_Direction_Lines"></param> public static void ClassifyLines(List <LINE> LINES, out List <List <LINE> > Collect, out List <LINE> H_Direction_Lines, out List <LINE> V_Direction_Lines, out List <LINE> Else_Direction_Lines) { Collect = new List <List <LINE> >(); int[] is_pickup = new int[LINES.Count]; for (int i = 0; i < LINES.Count; i++) { if (is_pickup[i] == 1) { continue; } LINE baseLine = LINES[i]; List <LINE> tmpData = new List <LINE>(); tmpData.Add(baseLine); int j = 0; while (j < LINES.Count) { LINE cmpLine = LINES[j]; if (is_pickup[j] == 1 || j == i) { j = j + 1; continue; } if (cmpLine.GetStartPoint().X == baseLine.GetEndPoint().X&& cmpLine.GetStartPoint().Y == baseLine.GetEndPoint().Y) { baseLine = cmpLine; tmpData.Add(baseLine); is_pickup[j] = 1; j = 0; } else if (cmpLine.GetEndPoint().X == baseLine.GetEndPoint().X&& cmpLine.GetEndPoint().Y == baseLine.GetEndPoint().Y) { baseLine = new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint()); tmpData.Add(baseLine); is_pickup[j] = 1; j = 0; } else if (tmpData[0].GetStartPoint().X == cmpLine.GetStartPoint().X&& tmpData[0].GetStartPoint().Y == cmpLine.GetStartPoint().Y) { tmpData.Insert(0, new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint())); is_pickup[j] = 1; j = 0; } else if (tmpData[0].GetStartPoint().X == cmpLine.GetEndPoint().X&& tmpData[0].GetStartPoint().Y == cmpLine.GetEndPoint().Y) { tmpData.Insert(0, cmpLine); is_pickup[j] = 1; j = 0; } else { j = j + 1; } } if (tmpData.Count != 1) { Collect.Add(tmpData); is_pickup[i] = 1; } } H_Direction_Lines = new List <LINE>(); V_Direction_Lines = new List <LINE>(); Else_Direction_Lines = new List <LINE>(); for (int ii = 0; ii < is_pickup.Count(); ii++) { if (is_pickup[ii] == 0) { LINE line = LINES[ii]; if (GeometryResult.Is_Horizontal(line)) { H_Direction_Lines.Add(line); } else if (GeometryResult.Is_Vertical(line)) { V_Direction_Lines.Add(line); } else { Else_Direction_Lines.Add(line); } } } }
/// <summary> /// Get Beam parameter Lines using to Create beam those lines is the center line of beam /// </summary> /// <param name="Collect"></param> /// <param name="H_Direction_Lines"></param> /// <param name="V_Direction_Lines"></param> /// <param name="H_Beams"></param> /// <param name="V_Beams"></param> public static List <LINE> GetBeamDrawLines(List <List <LINE> > Collect, List <LINE> H_Direction_Lines, List <LINE> V_Direction_Lines) { List <LINE> RESULT = new List <LINE>(); /// Collect Part foreach (List <LINE> co in Collect) { if (co.Count() <= 4) { LINE line1 = co[0]; LINE line2 = co[1]; XYZ p1 = null; XYZ p2 = null; double ll1 = GeometryResult.Get_Length(line1); double ll2 = GeometryResult.Get_Length(line2); if (ll1 > ll2) { if (line1.GetStartPoint().Y == line1.GetEndPoint().Y) { p1 = new XYZ(line1.GetStartPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0); p2 = new XYZ(line1.GetEndPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0); } else if (line1.GetStartPoint().X == line1.GetEndPoint().X) { p1 = new XYZ((line1.GetStartPoint().X + line2.GetEndPoint().X) / 2, line1.GetStartPoint().Y, 0); p2 = new XYZ((line1.GetStartPoint().X + line2.GetEndPoint().X) / 2, line1.GetEndPoint().Y, 0); } } else { if (line2.GetStartPoint().Y == line2.GetEndPoint().Y) { p1 = new XYZ(line2.GetStartPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0); p2 = new XYZ(line2.GetEndPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0); } else if (line2.GetStartPoint().X == line2.GetEndPoint().X) { p1 = new XYZ((line1.GetStartPoint().X + line1.GetEndPoint().X) / 2, line2.GetStartPoint().Y, 0); p2 = new XYZ((line1.GetStartPoint().X + line1.GetEndPoint().X) / 2, line2.GetEndPoint().Y, 0); } } if (p1 != null) { RESULT.Add(new LINE(p1, p2)); } } } /// H-Beam Part List <LINE> sorted_H = H_Direction_Lines.OrderBy(e => e.GetStartPoint().Y).ToList(); List <LINE> H_Beams = new List <LINE>(); int[] is_pickup = new int[sorted_H.Count()]; for (int i = 0; i < sorted_H.Count(); i++) { if (is_pickup[i] == 1) { continue; } LINE baseLine = sorted_H[i]; for (int j = 0; j < sorted_H.Count(); j++) { if (j == i || is_pickup[j] == 1) { continue; } LINE cmpLine = sorted_H[j]; if (baseLine.GetSlope() == -cmpLine.GetSlope()) { cmpLine = new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint()); } if (baseLine.GetStartPoint().X == cmpLine.GetStartPoint().X&& baseLine.GetEndPoint().X == cmpLine.GetEndPoint().X) { is_pickup[i] = 1; is_pickup[j] = 1; XYZ p1 = new XYZ((baseLine.GetStartPoint().X + cmpLine.GetStartPoint().X) / 2, (baseLine.GetStartPoint().Y + cmpLine.GetStartPoint().Y) / 2, 0); XYZ p2 = new XYZ((baseLine.GetEndPoint().X + cmpLine.GetEndPoint().X) / 2, (baseLine.GetEndPoint().Y + cmpLine.GetEndPoint().Y) / 2, 0); H_Beams.Add(new LINE(p1, p2)); RESULT.Add(new LINE(p1, p2)); break; } } } /// V-Beam Part List <LINE> V_Beams = new List <LINE>(); List <LINE> sorted_V = V_Direction_Lines.OrderBy(e => e.GetStartPoint().X).ToList(); is_pickup = new int[sorted_V.Count()]; for (int i = 0; i < sorted_V.Count(); i++) { if (is_pickup[i] == 1) { continue; } LINE baseLine = sorted_V[i]; for (int j = 0; j < sorted_V.Count(); j++) { if (j == i || is_pickup[j] == 1) { continue; } LINE cmpLine = sorted_V[j]; if (baseLine.GetSlope() == -cmpLine.GetSlope()) { cmpLine = new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint()); } if (baseLine.GetStartPoint().Y == cmpLine.GetStartPoint().Y&& baseLine.GetEndPoint().Y == cmpLine.GetEndPoint().Y) { is_pickup[i] = 1; is_pickup[j] = 1; XYZ p1 = new XYZ((baseLine.GetStartPoint().X + cmpLine.GetStartPoint().X) / 2, (baseLine.GetStartPoint().Y + cmpLine.GetStartPoint().Y) / 2, 0); XYZ p2 = new XYZ((baseLine.GetEndPoint().X + cmpLine.GetEndPoint().X) / 2, (baseLine.GetEndPoint().Y + cmpLine.GetEndPoint().Y) / 2, 0); V_Beams.Add(new LINE(p1, p2)); RESULT.Add(new LINE(p1, p2)); break; } } } return(RESULT); }
private List <FloorEdges> SplitFloorBySubBeam(List <LINE> floor, LINE subbeam) { List <FloorEdges> Floors = new List <FloorEdges>(); /////// 檢查subBeam與板邊界是否有兩個交點 List <int> CrossPo = new List <int>(); for (int i = 0; i < floor.Count; i++) { LINE floorEdge = floor[i]; if (Math.Abs(Math.Round(floorEdge.GetSlope(), 3)) == Math.Abs(Math.Round(subbeam.GetSlope(), 3))) { continue; } XYZ crossPoint = floorEdge.GetCrossPoint(subbeam); if (IsCloseEndsPoint(subbeam, crossPoint) && floorEdge.IsPointInLine(crossPoint)) { CrossPo.Add(i); } } /////// 沒有兩個交點則不處理直接回傳 if (CrossPo.Count != 2) { FloorEdges Floor = new FloorEdges(floor); Floors.Add(Floor); return(Floors); } /////// 有兩個交點則開始處理梁的分離 /// 將板轉換成節點 List <XYZ> nodes = new List <XYZ>(); foreach (LINE item in floor) { nodes.Add(item.GetStartPoint()); } nodes.Add(floor[floor.Count - 1].GetEndPoint()); /// 取的偏移後的交點 XYZ targetPoint = floor[CrossPo[0]].GetStartPoint(); LINE offSetLine_1 = subbeam.GetShiftLines(floor[CrossPo[0]].GetStartPoint(), subbeam.Width / 2, "IN")[0]; LINE offSetLine_2 = subbeam.GetShiftLines(floor[CrossPo[0]].GetEndPoint(), subbeam.Width / 2, "IN")[0]; XYZ crossPoint1 = offSetLine_1.GetCrossPoint(floor[CrossPo[0]]); XYZ crossPoint2 = offSetLine_1.GetCrossPoint(floor[CrossPo[1]]); XYZ crossPoint3 = offSetLine_2.GetCrossPoint(floor[CrossPo[0]]); XYZ crossPoint4 = offSetLine_2.GetCrossPoint(floor[CrossPo[1]]); List <XYZ> crossPoint_1 = new List <XYZ>() { crossPoint1, crossPoint2 }; List <XYZ> crossPoint_2 = new List <XYZ>() { crossPoint3, crossPoint4 }; /// Part 1 int kk = 0; List <XYZ> part_1 = new List <XYZ>(); for (int i = 0; i < nodes.Count; i++) { if (i > CrossPo[0] && i <= CrossPo[1] && kk < 2) { part_1.Add(crossPoint_1[kk]); kk = kk + 1; } else if (i <= CrossPo[0] || i > CrossPo[1]) { part_1.Add(nodes[i]); } } /// Part 2 kk = 0; List <XYZ> part_2 = new List <XYZ>(); for (int i = 0; i < nodes.Count; i++) { if (i > CrossPo[0] && i <= CrossPo[1]) { part_2.Add(nodes[i]); } else if ((i == CrossPo[0] || i == CrossPo[1] + 1) && kk < 2) { part_2.Add(crossPoint_2[kk]); kk = kk + 1; } } part_2.Add(crossPoint_2[0]); try { /// 將節點轉換成LINE List <LINE> newFloor_1 = new List <LINE>(); for (int i = 0; i < part_1.Count() - 1; i++) { newFloor_1.Add(new LINE(part_1[i], part_1[i + 1])); } List <LINE> newFloor_2 = new List <LINE>(); for (int i = 0; i < part_2.Count() - 1; i++) { newFloor_2.Add(new LINE(part_2[i], part_2[i + 1])); } Floors.Add(new FloorEdges(newFloor_1)); Floors.Add(new FloorEdges(newFloor_2)); } catch (Exception) { return(new List <FloorEdges>() { new FloorEdges(floor) }); } return(Floors); }
/// <summary> /// Pick a DWG import instance, extract polylines /// from it visible in the current view and create /// filled regions from them. /// </summary> private void GeneralCAD(UIDocument uidoc) { Document doc = uidoc.Document; View active_view = doc.ActiveView; List <GeometryObject> visible_dwg_geo = new List <GeometryObject>(); // 點選匯入之CAD Reference r = uidoc.Selection.PickObject(ObjectType.Element, new JtElementsOfClassSelectionFilter <ImportInstance>()); var import = doc.GetElement(r) as ImportInstance; // 取得幾何 var ge = import.get_Geometry(new Options()); foreach (GeometryObject go in ge) { if (go is GeometryInstance) { GeometryInstance gi = go as GeometryInstance; GeometryElement ge2 = gi.GetInstanceGeometry(); this.Origin = gi.Transform.Origin; this.Rotation_Dir = new List <XYZ>() { gi.Transform.BasisX, gi.Transform.BasisY, gi.Transform.BasisZ }; this.Rotation = GetSita(this.Rotation_Dir[0]); this.Scale = gi.Transform.Scale; if (ge2 != null) { foreach (var obj in ge2) { /// 如果Object為幾何物件 if ((obj is PolyLine && IsPloyLine) || (obj is Arc && IsArc) || (obj is Line && IsLine)) { GraphicsStyle gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle; // Check if the layer is visible in the view. if (!active_view.GetCategoryHidden(gStyle.GraphicsStyleCategory.Id)) { visible_dwg_geo.Add(obj); } } else if (obj is Solid) { try { Solid soild = obj as Solid; string layerName = ""; foreach (PlanarFace planarFace in soild.Faces) { EdgeArrayArray Eaa = planarFace.EdgeLoops; foreach (EdgeArray edgearray in Eaa) { List <LINE> edges = new List <LINE>(); foreach (Edge edge in edgearray) { var gStyle = doc.GetElement(edge.GraphicsStyleId) as GraphicsStyle; layerName = gStyle.GraphicsStyleCategory.Name; Line curve = edge.AsCurve() as Line; LINE newLine = new LINE(curve.GetEndPoint(0), curve.GetEndPoint(1)); edges.Add(newLine); } List <List <LINE> > EDGEs = this.LayersAndClosedRegions.Keys.Contains(layerName) ? this.LayersAndClosedRegions[layerName] : new List <List <LINE> >(); EDGEs.Add(edges); this.LayersAndClosedRegions[layerName] = EDGEs; } } } catch (Exception) { } } } } } } /// 取得各格圖層的幾何資訊 Dictionary <string, List <LINE> > res = new Dictionary <string, List <LINE> >(); if (visible_dwg_geo.Count > 0) { // Retrieve first filled region type var filledType = new FilteredElementCollector(doc) .WhereElementIsElementType() .OfClass(typeof(FilledRegionType)) .OfType <FilledRegionType>() .First(); using (var t = new Transaction(doc)) { t.Start("ProcessDWG"); List <LINE> tmp = new List <LINE>(); foreach (var obj in visible_dwg_geo) { var gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle; string layerName = gStyle.GraphicsStyleCategory.Name; tmp = res.ContainsKey(layerName) ? res[layerName] : new List <LINE>(); if (obj is Arc) { var Arc = obj as Arc; XYZ newPoint = new XYZ(Arc.Center.X, Arc.Center.Y, 0); LINE newLine = new LINE(newPoint, newPoint, 10); newLine.Name = "Circle"; tmp.Add(newLine); } if (obj is PolyLine) { // Create loops for detail region var poly = obj as PolyLine; var points = poly.GetCoordinates(); for (int kk = 0; kk < points.Count - 1; kk++) { if (GetDistance(points[kk], points[kk + 1]) != 0) { LINE newLine = new LINE(points[kk], points[kk + 1]); newLine.Name = "Polyline"; tmp.Add(newLine); } } } else if (obj is Line) { var line = obj as Line; LINE newLine = new LINE(line.GetEndPoint(0), line.GetEndPoint(1)); newLine.Name = "Line"; tmp.Add(newLine); } res[layerName] = tmp; } } } this.LayersAndGeometries = res; try { } catch (Exception e) { } }
/// <summary> /// 取得所有梁並將轉換至各樓板邊緣線 /// </summary> /// <param name="BEAMS"></param> /// <returns></returns> private List <List <LINE> > GetBeamGroup(List <LINE> BEAMS) { double SHIFTDIST = 2000 / 304.8; int number = 0; int[] count = new int[BEAMS.Count]; Dictionary <string, List <int> > pickNumbers = new Dictionary <string, List <int> >(); Dictionary <string, List <LINE> > DictRes = new Dictionary <string, List <LINE> >(); for (int i = 0; i < BEAMS.Count; i++) { List <LINE> ResTmp = new List <LINE>(); List <int> tmpcheckPicked = new List <int>() { }; for (int j = 0; j < BEAMS.Count; j++) { if (j == i) { continue; } if (CMPPoints(BEAMS[i].GetEndPoint(), BEAMS[j].GetStartPoint(), SHIFTDIST)) { ResTmp.Add(BEAMS[j]); tmpcheckPicked.Add(j); } else if (CMPPoints(BEAMS[i].GetEndPoint(), BEAMS[j].GetEndPoint(), SHIFTDIST)) { ResTmp.Add(new LINE(BEAMS[j].GetEndPoint(), BEAMS[j].GetStartPoint(), BEAMS[j].Name, BEAMS[j].LevelName, BEAMS[j].Width)); tmpcheckPicked.Add(j); } } List <LINE> Res = null; for (int pp = 0; pp < ResTmp.Count; pp++) { bool open = true; Res = new List <LINE> { BEAMS[i], ResTmp[pp] }; List <int> checkPicked = new List <int>() { i, tmpcheckPicked[pp] }; while (open) { int j = 0; List <LINE> tmpRes = new List <LINE>(); tmpRes = Res.ToList(); List <int> tmpCheckPicked = new List <int>(); while (j < BEAMS.Count) { if (!checkPicked.Contains(j)) { if (CMPPoints(Res[Res.Count - 1].GetEndPoint(), BEAMS[j].GetStartPoint(), SHIFTDIST)) { tmpRes.Add(BEAMS[j]); tmpCheckPicked.Add(j); } else if (CMPPoints(Res[Res.Count - 1].GetEndPoint(), BEAMS[j].GetEndPoint(), SHIFTDIST)) { tmpRes.Add(new LINE(BEAMS[j].GetEndPoint(), BEAMS[j].GetStartPoint(), BEAMS[j].Name, BEAMS[j].LevelName, BEAMS[j].Width)); tmpCheckPicked.Add(j); } } j++; } if (tmpRes.Count != Res.Count) { LINE tmp = tmpRes[0]; List <double> diff = new List <double>(); for (int ii = Res.Count; ii < tmpRes.Count; ii++) { if (!IsSamePoint(tmp.GetStartPoint(), tmpRes[ii].GetEndPoint())) { diff.Add(new LINE(tmp.GetStartPoint(), tmpRes[ii].GetEndPoint()).GetLength()); } else { diff.Add(0); } } int po = diff.FindIndex(item => item.Equals(diff.Min())); checkPicked.Add(tmpCheckPicked[po]); Res.Add(tmpRes[Res.Count + po]); tmpCheckPicked.Clear(); if (diff.Min() < SHIFTDIST) { open = false; } else if (CMPPoints(Res[0].GetEndPoint(), Res[Res.Count - 1].GetEndPoint(), SHIFTDIST)) { open = false; SaveTmp(Res); Res.RemoveAt(0); checkPicked.RemoveAt(0); } } else { open = false; } } pickNumbers[number.ToString()] = checkPicked; DictRes[number.ToString()] = Res; number++; } } ////// Filter Groups List <int> sumOf = new List <int>(); List <string> keys = pickNumbers.Keys.ToList(); foreach (KeyValuePair <string, List <int> > item in pickNumbers) { sumOf.Add(item.Value.Sum()); } int[] flag = new int[sumOf.Count]; for (int ii = 0; ii < sumOf.Count; ii++) { if (flag[ii] == -1) { continue; } for (int j = 0; j < sumOf.Count; j++) { List <LINE> tmpBeams = DictRes[keys[j]]; double Len = IsSamePoint(tmpBeams[0].GetStartPoint(), tmpBeams[tmpBeams.Count - 1].GetEndPoint()) ? 0 : (new LINE(tmpBeams[0].GetStartPoint(), tmpBeams[tmpBeams.Count - 1].GetEndPoint())).GetLength(); if (ii != j && sumOf[ii] == sumOf[j]) { flag[j] = -1; } else if (Len > SHIFTDIST) { flag[j] = -1; } } } List <int> Flag = flag.ToList(); int[] lastPo = FindAllIndexof(Flag, 0); Dictionary <string, List <LINE> > DictResult = new Dictionary <string, List <LINE> >(); List <List <LINE> > RESULT = new List <List <LINE> >(); Dictionary <int, List <int> > poo = new Dictionary <int, List <int> >(); foreach (int pp in lastPo) { DictResult[keys[pp]] = DictRes[keys[pp]]; RESULT.Add(DictRes[keys[pp]]); poo[pp] = pickNumbers[pp.ToString()]; } return(RESULT); }
private List <List <LINE> > DataPreProcessing(Level targetLevel, Level targetLevelCol, List <LINE> BEAMs) { ///// 取得所有梁平均寬度 double SHIFTs_Width_Of_Beam = 0; foreach (LINE item in BEAMs) { SHIFTs_Width_Of_Beam += item.Width; } SHIFTs_Width_Of_Beam = SHIFTs_Width_Of_Beam / BEAMs.Count; ///// 取得目標樓層所有的柱 Dictionary <string, List <LINE> > columns = GetAllColumnsBoundary(targetLevelCol); int kk = 0; double SHIFTs = 0; List <XYZ> colCenterPoints = new List <XYZ>(); foreach (KeyValuePair <string, List <LINE> > item in columns) { foreach (LINE line in item.Value) { SHIFTs += line.GetLength(); kk = kk + 1; } if (item.Value.Count != 0) { double All_X = item.Value.Sum(t => t.GetStartPoint().X) / item.Value.Count; double All_Y = item.Value.Sum(t => t.GetStartPoint().Y) / item.Value.Count; colCenterPoints.Add(new XYZ(All_X, All_Y, 0)); } } SHIFTs = SHIFTs / kk; ////// 延伸梁的邊緣線至柱中心 /// 找出subBeam,將不做延伸處理 List <int> NonePo = new List <int>(); for (int i = 0; i < BEAMs.Count; i++) { for (int j = 0; j < BEAMs.Count; j++) { if (i == j) { continue; } LINE b1 = BEAMs[i]; LINE b2 = BEAMs[j]; if (Math.Round(b1.GetSlope(), 3) == Math.Round(b2.GetSlope(), 3)) { continue; } try { XYZ crossPoint = b1.GetCrossPoint(b2); if (IsCloseEndsPoint(b1, crossPoint, SHIFTs_Width_Of_Beam) && b2.IsPointInLine(crossPoint)) { NonePo.Add(i); break; } ; } catch (Exception) { } } } List <LINE> Beams_Connect = new List <LINE>(); for (int i = 0; i < BEAMs.Count; i++) { if (NonePo.Contains(i)) { Beams_Connect.Add(BEAMs[i]); continue; } ; List <XYZ> col = GetClosedColumn(colCenterPoints, BEAMs[i]); XYZ newStartPoint = GetNewEndedPoint(col[0], BEAMs[i].GetStartPoint(), BEAMs[i]); XYZ newEndPoint = GetNewEndedPoint(col[1], BEAMs[i].GetEndPoint(), BEAMs[i]); if (newStartPoint.X == newEndPoint.X && newStartPoint.Y == newEndPoint.Y) { Beams_Connect.Add(BEAMs[i]); continue; } LINE newBeam = new LINE(newStartPoint, newEndPoint); newBeam.Name = BEAMs[i].Name; newBeam.Width = BEAMs[i].Width; newBeam.LevelName = BEAMs[i].LevelName; Beams_Connect.Add(newBeam); } /// 將所有的梁轉換至各樓板邊緣線 List <LINE> nonSelected = new List <LINE>(); List <List <LINE> > BeamGroup = GetBeamGroup(Beams_Connect, ref nonSelected, SHIFTs); SaveTmp(BeamGroup); /// 將樓板邊緣線偏移並連接 List <List <LINE> > NewBeamGroup = BeamConnectAndShiftProcessing(BeamGroup); SaveTmp(NewBeamGroup); if (NewBeamGroup.Count == 0) { return(NewBeamGroup); } double newHeight = NewBeamGroup[0][0].GetStartPoint().Z; ///// 重設目標樓層所有的柱的高度 Dictionary <string, List <LINE> > columns2 = new Dictionary <string, List <LINE> >(); foreach (KeyValuePair <string, List <LINE> > item in columns) { SaveTmp(item.Value); List <LINE> newFloor = new List <LINE>(); foreach (LINE floor in item.Value) { XYZ newSt = new XYZ(floor.GetStartPoint().X, floor.GetStartPoint().Y, newHeight); XYZ newEn = new XYZ(floor.GetEndPoint().X, floor.GetEndPoint().Y, newHeight); newFloor.Add(new LINE(newSt, newEn)); } columns2[item.Key] = newFloor; } List <List <LINE> > Result = new List <List <LINE> >(); foreach (List <LINE> item in NewBeamGroup) { Result.Add(TakeOffColumnEdge(columns2, item)); } SaveTmp(Result); Result = ConnectedEdgeFromMiddleColumns(Result); SaveTmp(Result); /// 拿掉第一輪subBeam List <List <LINE> > Res = TakeOffSubBeams(Result, nonSelected, SHIFTs_Width_Of_Beam); List <List <LINE> > Res2 = TakeOffSubBeams(Res, nonSelected, SHIFTs_Width_Of_Beam); SaveTmp(Res2); return(Res2); }
public static double Get_Length(LINE Line) { return(Math.Sqrt( (Line.GetStartPoint().X - Line.GetEndPoint().X) * (Line.GetStartPoint().X - Line.GetEndPoint().X) + (Line.GetStartPoint().Y - Line.GetEndPoint().Y) * (Line.GetStartPoint().Y - Line.GetEndPoint().Y))); }
/// <summary> /// 取得所有梁並將轉換至各樓板邊緣線 /// </summary> /// <param name="BEAMS"></param> /// <returns></returns> private List <List <LINE> > GetBeamGroup(List <LINE> BEAMS, ref List <LINE> nonSelected, double SHIFTDIST) { //double SHIFTDIST = 2000 / 304.8; /// 計算梁的平均長度 //double SHIFTDIST = BEAMS.Sum(m => m.GetLength()) / BEAMS.Count / 3; SHIFTDIST = SHIFTDIST * 3; Dictionary <string, List <int> > pickNumbers = new Dictionary <string, List <int> >(); Dictionary <string, List <LINE> > DictRes = new Dictionary <string, List <LINE> >(); for (int i = 0; i < BEAMS.Count; i++) { int j = 0; List <int> picked = new List <int>() { i }; List <LINE> tmpBeams = new List <LINE>(); tmpBeams.Add(BEAMS[i]); string direction = ""; while (j < BEAMS.Count) { if (tmpBeams.Count > 1 && CMPPoints(tmpBeams[0].GetStartPoint(), tmpBeams[tmpBeams.Count - 1].GetEndPoint(), SHIFTDIST)) { break; } LINE target = tmpBeams[tmpBeams.Count - 1]; List <int> PickedTmp = new List <int>(); List <LINE> ResTmp = GetClosedBeams(BEAMS, target, ref PickedTmp, picked, SHIFTDIST); JudgeDir(tmpBeams, ref direction); List <double> angle = new List <double>(); for (int p = 0; p < ResTmp.Count; p++) { XYZ tarDir = target.GetDirection(); XYZ itemDir = ResTmp[p].GetDirection(); XYZ CrossRes = GetCross(tarDir, itemDir); double DotRes = -tarDir.X * itemDir.X + -tarDir.Y * itemDir.Y; double ang = Math.Acos(Math.Round(DotRes, 2)) * 180 / Math.PI; if (CrossRes.Z > 0) { ang = 360 - ang; } if (direction == "逆") { ang = 360 - ang; } angle.Add(ang); } if (ResTmp.Count != 0) { double minAng = angle.Min(); int po1 = FindAllIndexof(angle, minAng)[0]; tmpBeams.Add(ResTmp[po1]); picked.Add(PickedTmp[po1]); j = 0; } else { j++; } } DictRes[i.ToString()] = tmpBeams; pickNumbers[i.ToString()] = picked; } return(TakeOffSameRegion(ref nonSelected, pickNumbers, DictRes, BEAMS, SHIFTDIST)); }
/// <summary> /// 梁群組處理 /// </summary> /// <param name="LINES"></param> /// <returns></returns> private List <BEAM> BeamCenterLineProcessing(List <LINE> LINES) { List <BEAM> Beams = new List <BEAM>(); List <int> flag = new List <int>(); for (int i = 0; i < LINES.Count; i++) { if (flag.Contains(i)) { continue; } List <int> tmpFlag = new List <int>() { }; List <LINE> tmpLine = new List <LINE>(); List <double> tmpDistance = new List <double>(); for (int j = 0; j < LINES.Count; j++) { double dist = 0; if (i == j || tmpFlag.Contains(j)) { continue; } bool IsSameDir = IsSameDirection(LINES[i], LINES[j], ref dist); if (IsSameDir && dist != 0) { LINE tmpLine1 = LINES[i]; LINE tmpLine2 = LINES[j]; bool IsReverse = IsReverseDirection(tmpLine1.GetDirection(), tmpLine2.GetDirection()); XYZ stPoint_1; XYZ stPoint_2; XYZ enPoint_1; XYZ enPoint_2; if (IsReverse) { stPoint_1 = tmpLine1.GetStartPoint(); stPoint_2 = tmpLine2.GetEndPoint(); enPoint_1 = tmpLine1.GetEndPoint(); enPoint_2 = tmpLine2.GetStartPoint(); } else { stPoint_1 = tmpLine1.GetStartPoint(); stPoint_2 = tmpLine2.GetStartPoint(); enPoint_1 = tmpLine1.GetEndPoint(); enPoint_2 = tmpLine2.GetEndPoint(); } double dist_1 = GetDistanceByTwoPoint(stPoint_1, stPoint_2); double dist_2 = GetDistanceByTwoPoint(enPoint_1, enPoint_2); if (dist == dist_1 && dist_1 == dist_2) { LINE newLINE = LINES[j]; if (IsReverse) { newLINE = new LINE(LINES[j].GetEndPoint(), LINES[j].GetStartPoint()); newLINE.Name = LINES[j].Name; newLINE.LevelName = LINES[j].LevelName; newLINE.Width = LINES[j].Width; } tmpFlag.Add(j); tmpLine.Add(newLINE); tmpDistance.Add(dist); } } } if (tmpFlag.Count > 0) { double minDist = tmpDistance.Min(); int po = FindAllIndexof(tmpDistance, minDist)[0]; flag.Add(i); flag.Add(tmpFlag[po]); Beams.Add(new BEAM(LINES[i], tmpLine[po])); } } return(Beams); }