true; options.StoreFreeBoundaryFaces = options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; // Calculate results SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(element.Document, options); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(element); Solid solid = results.GetGeometry(); if null) (solid != { // Traverse each face in the spatial element volume FaceArray faces = solid.Faces; foreach in (Face face faces) { IList<SpatialElementBoundarySubface> subfaces = results.GetBoundaryFaceInfo(face); foreach (SpatialElementBoundarySubface subface in subfaces) { Face spatialElementFace = subface.GetSpatialElementFace(); // Bottom faces never have a boundary face reference. // Find floors with another technique. if (subface.SubfaceType == SubfaceType.Bottom) { double spatialElementFaceArea = spatialElementFace.Area; FindFloorBoundaries(element, options, spatialElementFaceArea); continue; } // Get material id from bounding face. Face boundingElementFace = subface.GetBoundingElementFace(); ElementId materialElementId = boundingElementFace != null ? boundingElementFace.MaterialElementId : ElementId.InvalidElementId; // Get area frm subface double subFaceArea = subface.GetSubface().Area; // Store information AddSurfaceArea(materialElementId, subFaceArea); } } } } The floors are extracted with some extra work: using the bottom outline of the room, it constructs temporary geometry extruded downward. It then uses the ElementIntersectsSolidFilter to find floor objects which intersect this temporary geometry, and the top face of the floor (from HostObjectUtils.GetTopFaces()) to get the face and its material.
options.StoreFreeBoundaryFaces = true; options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; // Calculate results SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(element.Document, options); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(element); Solid solid = results.GetGeometry(); if (solid != null) { // Traverse each face in the spatial element volume FaceArray faces = solid.Faces; foreach (Face face in faces) { IList<SpatialElementBoundarySubface> subfaces = results.GetBoundaryFaceInfo(face); foreach (SpatialElementBoundarySubface subface in subfaces) { Face spatialElementFace = subface.GetSpatialElementFace(); // Bottom faces never have a boundary face reference. // Find floors with another technique. if (subface.SubfaceType == SubfaceType.Bottom) { double spatialElementFaceArea = spatialElementFace.Area; FindFloorBoundaries(element, options, spatialElementFaceArea); continue; } // Get material id from bounding face. Face boundingElementFace = subface.GetBoundingElementFace(); ElementId materialElementId = boundingElementFace != null ? boundingElementFace.MaterialElementId : ElementId.InvalidElementId; // Get area frm subface double subFaceArea = subface.GetSubface().Area; // Store information AddSurfaceArea(materialElementId, subFaceArea); } } } } The floors are extracted with some extra work: using the bottom outline of the room, it constructs temporary geometry extruded downward. It then uses the ElementIntersectsSolidFilter to find floor objects which intersect this temporary geometry, and the top face of the floor (from HostObjectUtils.GetTopFaces()) to get the face and its material.
v1_CP4011_Conover.docx