/// <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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        //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);
        }