Exemple #1
0
        /// <summary>
        /// This node will try to check if the walls profile has been modified using the dependent elements method available in Revit 2018.1+
        /// </summary>
        /// <param name="wall">The walls to check.</param>
        /// <returns name="modelCurves">The result.</returns>
        /// <search>
        /// profile, wall
        /// </search>
        public static global::Revit.Elements.Element[] EditedProfile(global::Revit.Elements.Element wall)
        {
            Autodesk.Revit.DB.Document doc          = DocumentManager.Instance.CurrentDBDocument;
            Autodesk.Revit.DB.Element  internalWall = wall.InternalElement;

            //dependent elements method (available in Revit 2018.1 +)
            Autodesk.Revit.DB.ElementFilter elemFilter = new ElementIsElementTypeFilter(true);
            IList <ElementId> elemIds = internalWall.GetDependentElements(elemFilter);

            //get the elements
            List <Autodesk.Revit.DB.Element> elems = new List <Element>(elemIds.Select(e => doc.GetElement(e)));

            global::Autodesk.Revit.DB.Element[] internalCurves = elems.Where(e => e is Autodesk.Revit.DB.ModelCurve).ToArray();

            global::Revit.Elements.Element[] modelCurves = internalCurves.Select(e => e.ToDSType(true)).ToArray();

            return(modelCurves);
        }
        private static List <Polygon> GetProfile(this Autodesk.Revit.DB.Element element)
        {
            Document          doc             = element.Document;
            List <Polygon>    polygons        = new List <Polygon>();
            IList <Reference> firstSideFaces  = null;
            IList <Reference> secondSideFaces = null;

            switch (element)
            {
            case Wall revitWall:
                //use host object utils to get the outside face
                firstSideFaces  = HostObjectUtils.GetSideFaces(revitWall, ShellLayerType.Exterior);
                secondSideFaces = HostObjectUtils.GetSideFaces(revitWall, ShellLayerType.Interior);
                break;

            case Autodesk.Revit.DB.Floor revitFloor:
                firstSideFaces  = HostObjectUtils.GetTopFaces(revitFloor);
                secondSideFaces = HostObjectUtils.GetBottomFaces(revitFloor);
                break;
            }
            Element faceElement = doc.GetElement(firstSideFaces[0]);

            if (!(faceElement.GetGeometryObjectFromReference(firstSideFaces[0]) is Face exteriorFace) || !(faceElement.GetGeometryObjectFromReference(secondSideFaces[0]) is Face interiorFace))
            {
                return(null);
            }
            //this lets us pick the biggest face of the two sides. This is important because we want the shapes to close. 😁
            Face face = exteriorFace.Area > interiorFace.Area ? exteriorFace : interiorFace;
            // get the edges as curve loops and use the IFCUtils to sort them
            // credit: https://thebuildingcoder.typepad.com/blog/2015/01/getting-the-wall-elevation-profile.html
            IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops();
            //this does the sorting so outside is the first item
            IList <CurveLoop> loops = ExporterIFCUtils.SortCurveLoops(curveLoops)[0];

            for (int i = 0; i < loops.Count; i++)
            {
                //here for outermost loop
                if (i == 0)
                {
                    var            outer    = loops[i];
                    List <Vector3> vertices = new List <Vector3>();
                    foreach (Autodesk.Revit.DB.Curve c in outer)
                    {
                        vertices.Add(c.GetEndPoint(0).ToVector3());
                    }
                    polygons.Add(new Polygon(vertices));
                }
                //here for the inner loops (voids)
                else
                {
                    var            inner    = loops[i];
                    List <Vector3> vertices = new List <Vector3>();
                    foreach (Autodesk.Revit.DB.Curve c in inner)
                    {
                        vertices.Add(c.GetEndPoint(0).ToVector3());
                    }
                    Polygon innerPolygon = new Polygon(vertices);
                    polygons.Add(innerPolygon);
                }
            }

            return(polygons);
        }