/// <summary> /// Retrieve plan view boundary loops from element /// solids using ExtrusionAnalyzer. /// </summary> static Dictionary <int, JtLoops> GetSolidLoops( Document doc, ICollection <ElementId> ids) { Dictionary <int, JtLoops> solidLoops = new Dictionary <int, JtLoops>(); int nFailures; foreach (ElementId id in ids) { Element e = doc.GetElement(id); if (e is Dimension) { continue; } Debug.Print(e.Name + " " + id.IntegerValue.ToString()); nFailures = 0; JtLoops loops = CmdUploadRooms.GetSolidPlanViewBoundaryLoops( e, false, ref nFailures); if (0 < nFailures) { Debug.Print("{0}: {1}", Util.ElementDescription(e), Util.PluralString(nFailures, "extrusion analyser failure")); } CmdUploadRooms.ListLoops(e, loops); loops.NormalizeLoops(); solidLoops.Add(id.IntegerValue, loops); } return(solidLoops); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; if (null == doc) { Util.ErrorMsg("Please run this command in a valid" + " Revit project document."); return(Result.Failed); } ICollection <ElementId> ids = Util.GetSelectedElements(uidoc); if ((null == ids) || (0 == ids.Count)) { return(Result.Cancelled); } // Third attempt: create the element 2D outline // from element solid faces and meshes in current // view by projecting them onto the XY plane and // executing 2d Boolean unions on them. View view = doc.ActiveView; Options opt = new Options { View = view }; Clipper c = new Clipper(); VertexLookup vl = new VertexLookup(); List <LineSegment> curves = new List <LineSegment>(); Polygons union = new Polygons(); Dictionary <int, JtLoops> booleanLoops = new Dictionary <int, JtLoops>(ids.Count); foreach (ElementId id in ids) { Element e = doc.GetElement(id); GeometryElement geo = e.get_Geometry(opt); c.Clear(); vl.Clear(); union.Clear(); AddToUnion(union, curves, vl, c, geo); //AddToUnion( union, vl, c, curves ); //c.AddPaths( subjects, PolyType.ptSubject, true ); //c.AddPaths( clips, PolyType.ptClip, true ); bool succeeded = c.Execute(ClipType.ctUnion, union, PolyFillType.pftPositive, PolyFillType.pftPositive); if (0 == union.Count) { Debug.Print(string.Format( "No outline found for {0} <{1}>", e.Name, e.Id.IntegerValue)); } else { JtLoops loops = ConvertToLoops(union); loops.NormalizeLoops(); booleanLoops.Add(id.IntegerValue, loops); } } string filepath = Path.Combine(Util.OutputFolderPath, doc.Title + "_element_2d_boolean_outline.json"); JtWindowHandle hwnd = new JtWindowHandle(uiapp.MainWindowHandle); string caption = doc.Title + " 2D Booleans"; Util.ExportLoops(filepath, hwnd, caption, doc, booleanLoops); return(Result.Succeeded); }
GetElementLoops( View view, ICollection <ElementId> ids) { Document doc = view.Document; Options opt = new Options { View = view }; Clipper c = new Clipper(); VertexLookup vl = new VertexLookup(); List <LineSegment> curves = new List <LineSegment>(); Polygons union = new Polygons(); Dictionary <int, JtLoops> booleanLoops = new Dictionary <int, JtLoops>(ids.Count); foreach (ElementId id in ids) { c.Clear(); vl.Clear(); union.Clear(); Element e = doc.GetElement(id); if (e is Room) { IList <IList <BoundarySegment> > boundary = (e as Room).GetBoundarySegments( new SpatialElementBoundaryOptions()); // Ignore all loops except first, which is // hopefully outer -- and hopefully the room // does not have several disjunct parts. AddToUnionRoom(union, curves, vl, c, boundary); } else { GeometryElement geo = e.get_Geometry(opt); AddToUnion(union, curves, vl, c, geo); } //AddToUnion( union, vl, c, curves ); //c.AddPaths( subjects, PolyType.ptSubject, true ); //c.AddPaths( clips, PolyType.ptClip, true ); bool succeeded = c.Execute(ClipType.ctUnion, union, PolyFillType.pftPositive, PolyFillType.pftPositive); if (0 == union.Count) { Debug.Print(string.Format( "No outline found for {0} <{1}>", e.Name, e.Id.IntegerValue)); } else { JtLoops loops = ConvertToLoops(union); loops.NormalizeLoops(); booleanLoops.Add(id.IntegerValue, loops); } } return(booleanLoops); }
//static List<ElementId> GetRoomBoundaryIds( // Room room, // SpatialElementBoundaryOptions seb_opt ) //{ // List<ElementId> ids = null; // IList<IList<BoundarySegment>> sloops // = room.GetBoundarySegments( seb_opt ); // if( null != sloops ) // the room may not be bounded // { // Debug.Assert( 1 == sloops.Count, "this add-in " // + "currently supports only rooms with one " // + "single boundary loop" ); // ids = new List<ElementId>(); // foreach( IList<BoundarySegment> sloop in sloops ) // { // foreach( BoundarySegment s in sloop ) // { // ids.Add( s.ElementId ); // } // // Skip out after first segement loop - ignore // // rooms with holes and disjunct parts // break; // } // } // return ids; //} /// <summary> /// Create a JtLoop representing the 2D outline of /// the given room including all its bounding elements /// by creating the inner room boundary loop and /// uniting it with the bounding elements solid faces /// and meshes in the given view, projecting /// them onto the XY plane and executing 2D Boolean /// unions on them. /// </summary> public static JtLoops GetRoomOuterBoundaryLoops( Room room, SpatialElementBoundaryOptions seb_opt, View view) { Document doc = view.Document; Options opt = new Options { View = view }; Clipper c = new Clipper(); VertexLookup vl = new VertexLookup(); List <LineSegment> curves = new List <LineSegment>(); Polygons union = new Polygons(); JtLoops loops = null; IList <IList <BoundarySegment> > boundary = room.GetBoundarySegments( new SpatialElementBoundaryOptions()); if (null != boundary) // the room may not be bounded { Debug.Assert(1 == boundary.Count, "this add-in currently supports only rooms " + "with one single boundary loop"); // Ignore all loops except first, which is // hopefully outer -- and hopefully the room // does not have several disjunct parts. // Ignore holes in the room and // multiple disjunct parts. AddToUnionRoom(union, curves, vl, c, boundary); // Retrieve bounding elements List <ElementId> ids = new List <ElementId>(); foreach (IList <BoundarySegment> loop in boundary) { foreach (BoundarySegment s in loop) { ids.Add(s.ElementId); } // Skip out after first segement loop - ignore // rooms with holes and disjunct parts break; } foreach (ElementId id in ids) { // Skip invalid element ids, generated, for // instance, by a room separator line. if (!id.Equals(ElementId.InvalidElementId)) { Element e = doc.GetElement(id); GeometryElement geo = e.get_Geometry(opt); AddToUnion(union, curves, vl, c, geo); bool succeeded = c.Execute(ClipType.ctUnion, union, PolyFillType.pftPositive, PolyFillType.pftPositive); if (0 == union.Count) { Debug.Print(string.Format( "No outline found for {0} <{1}>", e.Name, e.Id.IntegerValue)); } } } loops = ConvertToLoops(union); loops.NormalizeLoops(); } return(loops); }