How to add your knowledge

Room and Space Geometry

    Table of contents
    No headers

    The Revit API provides access to the 3D geometry of spatial elements (rooms and spaces).

    The SpatialElementGeometryCalculator class can be used to calculate the geometry of a spatial element and obtain the relationships between the geometry and the element's boundary elements.  There are 2 options which can be provided to this utility:

    • SpatialElementBoundaryLocation – whether to use finish faces or boundary element centerlines for calculation
    • StoredFreeBoundaryFaces – whether to include faces which don’t map directly to a boundary element in the results.

    The results of calculating the geometry are contained in the class SpatialElementGeometryResults.  From the SpatialElementGeometryResults class, you can obtain:

    • The Solid volume representing the geometry (GetGeometry() method)
    • The boundary face information (a collection SpatialElementBoundarySubfaces)

    Each subface offers:

    • The face of the spatial element
    • The matching face of the boundary element
    • The subface (the portion of the spatial element face bounded by this particular boundary element)
    • The subface type (bottom, top, or side)

    Some notes about the use of this utility:

    • The calculator maintains an internal cache for geometry it has already processed. If you intend to calculate geometry for several elements in the same project you should use a single instance of this class. Note that the cache will be cleared when any change is made to the document.
    • Floors are almost never included in as boundary elements.  Revit uses the 2D outline of the room to form the bottom faces and does not match them to floor geometry.
    • Openings created by wall-cutting features such as doors and windows are not included in the returned faces.
    • The geometry calculations match the capabilities offered by Revit.  In some cases where Revit makes assumptions about how to calculate the volumes of boundaries of rooms and spaces, these assumptions will be present in the output of the utility.

    The following example calculates a room's geometry and finds its boundary faces

    Code Region: Face Area using SpatialElementGeometryCalculator

    SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc);
    
    // compute the room geometry
    SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(room);
    
    // get the solid representing the room's geometry
    Solid roomSolid = results.GetGeometry(); 
    
    foreach (Face face in roomSolid.Faces)
    {
        double faceArea = face.Area;
    
        // get the sub-faces for the face of the room
        IList<SpatialElementBoundarySubface> subfaceList = results.GetBoundaryFaceInfo(face);
        foreach (SpatialElementBoundarySubface subface in subfaceList)
        {
            if (subfaceList.Count > 1) // there are multiple sub-faces that define the face
            {
                // get the area of each sub-face
                double subfaceArea = subface.GetSubface().Area;             
                
                // sub-faces exist in situations such as when a room-bounding wall has been
                // horizontally split and the faces of each split wall combine to create the 
                // entire face of the room
            }
        }
    }

     

    The following example calculates a room's geometry and finds its the material of faces that belong to the elements that define the room.

    Code Region: Face Material using SpatialElementGeometryCalculator

    public void MaterialFromFace()
    {
    	string s = "";
        Document doc = this.Document;
    	UIDocument uidoc = new UIDocument(doc);
    	Room room = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element).ElementId) as Room;
    	
    	SpatialElementBoundaryOptions  spatialElementBoundaryOptions = new SpatialElementBoundaryOptions();
    	spatialElementBoundaryOptions.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish;
    	SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc, spatialElementBoundaryOptions);
    	SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(room);
    	Solid roomSolid = results.GetGeometry(); 
    
    	foreach (Face roomSolidFace in roomSolid.Faces)
    	{
    	    foreach (SpatialElementBoundarySubface subface in results.GetBoundaryFaceInfo(roomSolidFace))
    	    {
    	    	Face boundingElementface = subface.GetBoundingElementFace();
    	    	ElementId id = boundingElementface.MaterialElementId;
    	    	s +=  doc.GetElement(id).Name + ", id = " + id.IntegerValue.ToString() + "\n";
    	    }
    	}
        TaskDialog.Show("revit",s);			
    }