Exemple #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="room"></param>
        /// <param name="boundaryLocation"></param>
        /// <returns></returns>
        public static double Height(Element room, string boundaryLocation = "Center")
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            var bLoc     = (Autodesk.Revit.DB.SpatialElementBoundaryLocation)Enum.Parse(typeof(Autodesk.Revit.DB.SpatialElementBoundaryLocation), boundaryLocation);
            var bOptions = new Autodesk.Revit.DB.SpatialElementBoundaryOptions
            {
                SpatialElementBoundaryLocation = bLoc
            };
            var doc        = DocumentManager.Instance.CurrentDBDocument;
            var rm         = (Autodesk.Revit.DB.SpatialElement)room.InternalElement;
            var calculator = new Autodesk.Revit.DB.SpatialElementGeometryCalculator(doc, bOptions);
            var result     = calculator.CalculateSpatialElementGeometry(rm);
            var geo        = result.GetGeometry();
            var bb         = geo.GetBoundingBox();
            var height     = bb.Max.Z - bb.Min.Z;

            var fu = Autodesk.Revit.DB.UnitUtils.GetAllMeasurableSpecs()
                     .FirstOrDefault(x => x.TypeId.StartsWith("autodesk.spec.aec:length"));
            var units = doc.GetUnits().GetFormatOptions(fu);

            return(Autodesk.Revit.DB.UnitUtils.ConvertFromInternalUnits(height, units.GetUnitTypeId()));
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="room"></param>
        /// <param name="boundaryLocation"></param>
        /// <returns></returns>
        public static List <Curve> Boundaries(Element room, string boundaryLocation = "Center")
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            var bLoc     = (Autodesk.Revit.DB.SpatialElementBoundaryLocation)Enum.Parse(typeof(Autodesk.Revit.DB.SpatialElementBoundaryLocation), boundaryLocation);
            var bOptions = new Autodesk.Revit.DB.SpatialElementBoundaryOptions
            {
                SpatialElementBoundaryLocation = bLoc
            };

            var rm = (Autodesk.Revit.DB.SpatialElement)room.InternalElement;
            var boundarySegments = rm.GetBoundarySegments(bOptions).First().ToList();

            return(boundarySegments.Select(x => x.GetCurve().ToProtoType()).ToList());
        }
Exemple #3
0
        private IEnumerable <IEnumerable <Autodesk.DesignScript.Geometry.Curve> > GetBoundaries(Autodesk.Revit.DB.SpatialElementBoundaryLocation position)
        {
            var options = new Autodesk.Revit.DB.SpatialElementBoundaryOptions()
            {
                SpatialElementBoundaryLocation = position,
                StoreFreeBoundaryFaces         = true
            };

            var boundaries = new List <List <Autodesk.DesignScript.Geometry.Curve> >();

            foreach (var segments in this.InternalRevitElement.GetBoundarySegments(options))
            {
                var boundary = new List <Autodesk.DesignScript.Geometry.Curve>();

                foreach (Autodesk.Revit.DB.BoundarySegment segment in segments)
                {
                    boundary.Add(segment.GetCurve().ToProtoType());
                }

                boundaries.Add(boundary);
            }

            return(boundaries);
        }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="room"></param>
        /// <param name="boundaryLocation"></param>
        /// <returns></returns>
        public static double Height(Element room, string boundaryLocation = "Center")
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            var bLoc     = (Autodesk.Revit.DB.SpatialElementBoundaryLocation)Enum.Parse(typeof(Autodesk.Revit.DB.SpatialElementBoundaryLocation), boundaryLocation);
            var bOptions = new Autodesk.Revit.DB.SpatialElementBoundaryOptions
            {
                SpatialElementBoundaryLocation = bLoc
            };
            var doc        = DocumentManager.Instance.CurrentDBDocument;
            var rm         = (Autodesk.Revit.DB.SpatialElement)room.InternalElement;
            var calculator = new Autodesk.Revit.DB.SpatialElementGeometryCalculator(doc, bOptions);
            var result     = calculator.CalculateSpatialElementGeometry(rm);
            var geo        = result.GetGeometry();
            var bb         = geo.GetBoundingBox();
            var height     = bb.Max.Z - bb.Min.Z;

            var units = doc.GetUnits().GetFormatOptions(Autodesk.Revit.DB.UnitType.UT_Length);

            return(Autodesk.Revit.DB.UnitUtils.ConvertFromInternalUnits(height, units.DisplayUnits));
        }
Exemple #5
0
        public static Dictionary <string, object> Faces(Element room, string boundaryLocation = "Center")
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            var bLoc     = (Autodesk.Revit.DB.SpatialElementBoundaryLocation)Enum.Parse(typeof(Autodesk.Revit.DB.SpatialElementBoundaryLocation), boundaryLocation);
            var bOptions = new Autodesk.Revit.DB.SpatialElementBoundaryOptions
            {
                SpatialElementBoundaryLocation = bLoc
            };
            var doc        = DocumentManager.Instance.CurrentDBDocument;
            var rm         = (Autodesk.Revit.DB.SpatialElement)room.InternalElement;
            var calculator = new Autodesk.Revit.DB.SpatialElementGeometryCalculator(doc, bOptions);
            var result     = calculator.CalculateSpatialElementGeometry(rm);

            var segments            = rm.GetBoundarySegments(bOptions);
            var outerBoundaryCurves = new List <Autodesk.Revit.DB.Curve>();
            var innerBoundaryCurves = new List <Autodesk.Revit.DB.Curve>();

            for (var i = 0; i < segments.Count; i++)
            {
                if (i == 0)
                {
                    outerBoundaryCurves = segments[i].Select(x => x.GetCurve()).ToList();
                }
                else
                {
                    innerBoundaryCurves.AddRange(segments[i].Select(x => x.GetCurve()));
                }
            }

            var bottom   = new List <Surface>();
            var top      = new List <Surface>();
            var boundary = new List <Surface>();
            var holes    = new List <Surface>();

            var faces = result.GetGeometry().Faces;

            for (var i = 0; i < faces.Size; i++)
            {
                var face          = faces.get_Item(i);
                var boundaryFaces = result.GetBoundaryFaceInfo(face).FirstOrDefault();

                if (boundaryFaces?.SubfaceType == Autodesk.Revit.DB.SubfaceType.Top)
                {
                    top.Add(face.ToProtoType().First());
                    continue;
                }

                if (boundaryFaces?.SubfaceType == Autodesk.Revit.DB.SubfaceType.Bottom)
                {
                    bottom.Add(face.ToProtoType().First());
                    continue;
                }

                var edges      = face.GetEdgesAsCurveLoops().First(); // first loop is outer boundary, first curve is bottom edge
                var outerIndex = outerBoundaryCurves.FindIndex(x => edges.Any(y => y.OverlapsWith(x)));
                var innerIndex = innerBoundaryCurves.FindIndex(x => edges.Any(y => y.OverlapsWith(x)));

                if (outerIndex != -1)
                {
                    boundary.Add(face.ToProtoType().First());
                }

                if (innerIndex != -1)
                {
                    holes.Add(face.ToProtoType().First());
                }
            }

            return(new Dictionary <string, object>
            {
                { "Boundary", boundary },
                { "Holes", holes },
                { "Bottom", bottom },
                { "Top", top }
            });
        }
Exemple #6
0
        public static Dictionary <string, object> PointsOnSurface(
            Element room,
            [DefaultArgument("Selection.Select.GetNull()")] List <Element> glazingMaterials,
            string boundaryLocation = "Center")
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            var materialIds = new List <Autodesk.Revit.DB.ElementId>();

            if (glazingMaterials != null && glazingMaterials.Any())
            {
                materialIds = glazingMaterials.Select(x => x.InternalElement.Id).ToList();
            }

            var bLoc     = (Autodesk.Revit.DB.SpatialElementBoundaryLocation)Enum.Parse(typeof(Autodesk.Revit.DB.SpatialElementBoundaryLocation), boundaryLocation);
            var bOptions = new Autodesk.Revit.DB.SpatialElementBoundaryOptions
            {
                SpatialElementBoundaryLocation = bLoc
            };
            var doc        = DocumentManager.Instance.CurrentDBDocument;
            var tolerance  = doc.Application.ShortCurveTolerance;
            var rm         = (Autodesk.Revit.DB.SpatialElement)room.InternalElement;
            var calculator = new Autodesk.Revit.DB.SpatialElementGeometryCalculator(doc, bOptions);
            var result     = calculator.CalculateSpatialElementGeometry(rm);
            var geo        = result.GetGeometry();

            var bb     = geo.GetBoundingBox();
            var height = bb.Max.Z - bb.Min.Z;
            //var units = doc.GetUnits().GetFormatOptions(Autodesk.Revit.DB.UnitType.UT_Length);
            //var convertedHeight = Autodesk.Revit.DB.UnitUtils.ConvertFromInternalUnits(height, units.DisplayUnits);

            var boundaryCurves = rm.GetBoundarySegments(bOptions).First().Select(x => x.GetCurve()).ToList();

            var glazingPoints = new List <List <List <Point> > >();
            var glazingRatios = new List <double>();

            for (var j = 1; j < geo.Faces.Size; j++) // skip 0 as that's the Floor.
            {
                var face       = geo.Faces.get_Item(j);
                var bottomEdge = face.GetEdgesAsCurveLoops().First().First(); // first loop is outer boundary, first curve is bottom edge
                var index      = boundaryCurves.FindIndex(x => x.OverlapsWith(bottomEdge));
                if (index == -1)
                {
                    continue;              // could be inner face/roof
                }
                var gPoints = new List <List <Point> >();
                var gAreas  = new List <double>();

                if (!(face is Autodesk.Revit.DB.PlanarFace))
                {
                    glazingPoints[index] = gPoints;
                    continue; // skip non-planar faces
                }

                var boundaryFaces = result.GetBoundaryFaceInfo(face);
                foreach (var bFace in boundaryFaces)
                {
                    var bElement = doc.GetElement(bFace.SpatialBoundaryElement.HostElementId);
                    if (bElement is Autodesk.Revit.DB.Wall wall)
                    {
                        if (wall.WallType.Kind == Autodesk.Revit.DB.WallKind.Curtain)
                        {
                            var cGrid  = wall.CurtainGrid;
                            var panels = cGrid.GetPanelIds().Select(x => doc.GetElement(x));
                            foreach (var panel in panels)
                            {
                                var mat = panel.GetMaterialIds(false);
                                if (!materialIds.Any() || !materialIds.Intersect(mat).Any())
                                {
                                    continue;
                                }

                                var winPts = new List <Autodesk.Revit.DB.XYZ>();
                                using (var opt = new Autodesk.Revit.DB.Options())
                                {
                                    opt.IncludeNonVisibleObjects = true;
                                    using (var geom = panel.get_Geometry(opt))
                                    {
                                        ExtractPtsRecursively(geom, ref winPts);
                                    }
                                }

                                var onSurface    = new HashSet <Autodesk.Revit.DB.XYZ>();
                                var onSurfaceUvs = new HashSet <Autodesk.Revit.DB.UV>();
                                foreach (var pt in winPts)
                                {
                                    var intResult = face.Project(pt);
                                    if (intResult == null)
                                    {
                                        continue;
                                    }

                                    if (onSurface.Add(intResult.XYZPoint))
                                    {
                                        onSurfaceUvs.Add(intResult.UVPoint.Negate());
                                    }
                                }

                                if (GetHull(onSurface.ToList(), onSurfaceUvs.ToList(), tolerance, out var hPts, out var hUvs))
                                {
                                    var outerEdges = face.GetEdgesAsCurveLoops().First();
                                    foreach (var edge in outerEdges)
                                    {
                                        for (var i = 0; i < hPts.Count; i++)
                                        {
                                            var pt = hPts[i];
                                            if (edge.Distance(pt) >= 0.01)
                                            {
                                                continue;
                                            }

                                            var direction     = (edge.GetEndPoint(1) - edge.GetEndPoint(0)).Normalize();
                                            var perpendicular = face.ComputeNormal(new Autodesk.Revit.DB.UV(0.5, 0.5)).CrossProduct(direction);
                                            var offset        = 0.1 * perpendicular;
                                            var offsetPt      = pt + offset;

                                            hPts[i] = offsetPt;
                                        }
                                    }

                                    gAreas.Add(PolygonArea(hUvs));
                                    gPoints.Add(hPts.Select(x => x.ToPoint()).ToList());
                                }
                            }
                        }

                        var inserts = wall.FindInserts(true, false, true, true).Select(x => doc.GetElement(x));
                        foreach (var insert in inserts)
                        {
                            if (insert.Category.Id.IntegerValue == Autodesk.Revit.DB.BuiltInCategory.OST_Windows.GetHashCode())
                            {
                                // (Konrad) We have a Window.
                                var winPts = new List <Autodesk.Revit.DB.XYZ>();
                                using (var opt = new Autodesk.Revit.DB.Options())
                                {
                                    opt.IncludeNonVisibleObjects = true;
                                    using (var geom = insert.get_Geometry(opt))
                                    {
                                        ExtractPtsRecursively(geom, ref winPts);
                                    }
                                }

                                var onSurface    = new HashSet <Autodesk.Revit.DB.XYZ>();
                                var onSurfaceUvs = new HashSet <Autodesk.Revit.DB.UV>();
                                foreach (var pt in winPts)
                                {
                                    var intResult = face.Project(pt);
                                    if (intResult == null)
                                    {
                                        continue;
                                    }

                                    if (onSurface.Add(intResult.XYZPoint))
                                    {
                                        onSurfaceUvs.Add(intResult.UVPoint.Negate());
                                    }
                                }

                                if (GetHull(onSurface.ToList(), onSurfaceUvs.ToList(), tolerance, out var hPts, out var hUvs))
                                {
                                    var winArea  = GetWindowArea(insert);
                                    var hullArea = PolygonArea(hUvs);

                                    if (hullArea > winArea * 0.5)
                                    {
                                        var outerEdges = face.GetEdgesAsCurveLoops().First();
                                        foreach (var edge in outerEdges)
                                        {
                                            for (var i = 0; i < hPts.Count; i++)
                                            {
                                                var pt = hPts[i];
                                                if (edge.Distance(pt) >= 0.01)
                                                {
                                                    continue;
                                                }

                                                var direction     = (edge.GetEndPoint(1) - edge.GetEndPoint(0)).Normalize();
                                                var perpendicular = face.ComputeNormal(new Autodesk.Revit.DB.UV(0.5, 0.5)).CrossProduct(direction);
                                                var offset        = 0.03 * perpendicular;
                                                var offsetPt      = pt + offset;

                                                hPts[i] = offsetPt;
                                            }
                                        }

                                        gAreas.Add(PolygonArea(hUvs));
                                        gPoints.Add(hPts.Select(x => x.ToPoint()).ToList());
                                    }
                                }
                            }
                        }
                    }
                    else if (bElement is Autodesk.Revit.DB.RoofBase roof)
                    {
                        var inserts = roof.FindInserts(true, false, true, true).Select(x => doc.GetElement(x));
                        foreach (var insert in inserts)
                        {
                            if (insert.Category.Id.IntegerValue == Autodesk.Revit.DB.BuiltInCategory.OST_Windows.GetHashCode())
                            {
                                // (Konrad) We have a Window.
                                var winPts = new List <Autodesk.Revit.DB.XYZ>();
                                using (var opt = new Autodesk.Revit.DB.Options())
                                {
                                    opt.IncludeNonVisibleObjects = true;
                                    using (var geom = insert.get_Geometry(opt))
                                    {
                                        ExtractPtsRecursively(geom, ref winPts);
                                    }
                                }

                                var onSurface    = new HashSet <Autodesk.Revit.DB.XYZ>();
                                var onSurfaceUvs = new HashSet <Autodesk.Revit.DB.UV>();
                                foreach (var pt in winPts)
                                {
                                    var intResult = face.Project(pt);
                                    if (intResult == null)
                                    {
                                        continue;
                                    }

                                    if (onSurface.Add(intResult.XYZPoint))
                                    {
                                        onSurfaceUvs.Add(intResult.UVPoint.Negate());
                                    }
                                }

                                if (GetHull(onSurface.ToList(), onSurfaceUvs.ToList(), tolerance, out var hPts, out var hUvs))
                                {
                                    var winArea  = GetWindowArea(insert);
                                    var hullArea = PolygonArea(hUvs);

                                    if (hullArea > winArea * 0.25)
                                    {
                                        gAreas.Add(hullArea);
                                        gPoints.Add(hPts.Select(x => x.ToPoint()).ToList());
                                    }
                                }
                            }
                        }
                    }
                }

                var curve = face.GetEdgesAsCurveLoops().FirstOrDefault()?.FirstOrDefault();
                if (curve == null)
                {
                    continue;
                }

                var faceArea = curve.Length * height;
                glazingPoints[index] = gPoints;
                glazingRatios[index] = gAreas.Sum() / faceArea;
            }

            return(new Dictionary <string, object>
            {
                { "GlazingPoints", glazingPoints },
                { "GlazingRatios", glazingRatios }
            });
        }
Exemple #7
0
        public static Dictionary <string, object> GlazingInfo(Element room, string boundaryLocation = "Center")
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            var doc      = DocumentManager.Instance.CurrentDBDocument;
            var bLoc     = (Autodesk.Revit.DB.SpatialElementBoundaryLocation)Enum.Parse(typeof(Autodesk.Revit.DB.SpatialElementBoundaryLocation), boundaryLocation);
            var bOptions = new Autodesk.Revit.DB.SpatialElementBoundaryOptions
            {
                SpatialElementBoundaryLocation = bLoc
            };

            var tolerance  = doc.Application.ShortCurveTolerance;
            var e          = (Autodesk.Revit.DB.SpatialElement)room.InternalElement;
            var calculator = new Autodesk.Revit.DB.SpatialElementGeometryCalculator(doc, bOptions);
            var roomGeo    = calculator.CalculateSpatialElementGeometry(e);
            var geo        = roomGeo.GetGeometry();
            var bb         = geo.GetBoundingBox();
            var height     = bb.Max.Z - bb.Min.Z;
            var segments   = e.GetBoundarySegments(bOptions);
            var faces      = roomGeo.GetGeometry().Faces;
            var offset     = e.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.ROOM_LOWER_OFFSET).AsDouble();

            var boundary   = new List <Point>();
            var holes      = new List <List <Point> >();
            var windows    = new List <double>();
            var walls      = new List <List <Element> >();
            var foundFaces = new List <Surface>();

            for (var i = 0; i < segments.Count; i++)
            {
                if (i == 0) // outer boundary
                {
                    foreach (var bs in segments[i])
                    {
                        var boundaryCurve = bs.GetCurve().Offset(offset);
                        if (boundaryCurve.Length < 0.01)
                        {
                            continue; // Exclude tiny curves, they don't produce faces.
                        }
                        var face = FindFace(faces, roomGeo, boundaryCurve);
                        if (face == null)
                        {
                            continue; // Couldn't find a matching face. Not good.
                        }
                        GetGlazingInfo(face, doc, roomGeo, tolerance, out var unused, out var glazingAreas, out var boundingWalls);

                        var faceArea     = boundaryCurve.Length * height;
                        var glazingArea  = glazingAreas.Sum();
                        var glazingRatio = glazingArea / faceArea;

                        // (Konrad) Number of Boundary points in the list has to match number of Window Parameters.
                        var boundaryPts = GetPoints(boundaryCurve);

                        boundary.AddRange(boundaryPts);
                        windows.AddRange(boundaryPts.Select(x => glazingRatio));
                        walls.Add(boundingWalls);
                        foundFaces.Add(face.ToProtoType().First());
                    }

                    continue;
                }

                var hole = new List <Point>();
                foreach (var bs in segments[i])
                {
                    //TODO: Floor Holes need Glazing info processed.

                    var boundaryCurve = bs.GetCurve();
                    var segmentPts    = GetPoints(boundaryCurve);

                    hole.AddRange(segmentPts);
                    windows.AddRange(segmentPts.Select(segmentPt => 0d));
                }

                holes.Add(hole);
            }

            return(new Dictionary <string, object>
            {
                { "Boundary", boundary },
                { "Holes", holes },
                { "GlazingRatios", windows },
                { "Height", height },
                { "Walls", walls },
                { "Faces", foundFaces }
            });
        }