前言
这个例子是区分是否有屋顶作为房间边界。
内容
屋顶并未覆盖到整个房间,只是作为边界,仍然会被记录。
如果远离边界,则不会有记录。
核心逻辑:
// 找到所有的房间
ElementFilter roomSpaceFilter = new LogicalOrFilter(new RoomFilter(), new SpaceFilter());
FilteredElementCollector collector = new FilteredElementCollector(m_document);
List<Element> rooms = collector.WherePasses(roomSpaceFilter).ToElements();
// 屋顶过滤器
LogicalOrFilter categoryFilter = new LogicalOrFilter(new ElementCategoryFilter(BuiltInCategory.OST_Roofs),
new ElementCategoryFilter(BuiltInCategory.OST_RoofSoffit));
// SpatialElementGeometryCalculator 是重点,它可以过滤空间元素,获取核心内容
SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(m_document);
// Stores the resulting room->roof relationships
Dictionary<Element, List<ElementId>> roomsAndRoofs = new Dictionary<Element, List<ElementId>>();
foreach (Element room in rooms){
// Get room geometry & boundaries
SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry((SpatialElement)room);
// Get solid geometry so we can examine each face
Solid geometry = results.GetGeometry();
foreach (Face face in geometry.Faces){
// 找到所有的和当前面相关的表面,可能会有多个表面
IList<SpatialElementBoundarySubface> boundaryFaces = results.GetBoundaryFaceInfo(face);
foreach (SpatialElementBoundarySubface boundaryFace in boundaryFaces){
// Get boundary element
LinkElementId boundaryElementId = boundaryFace.SpatialBoundaryElement;
// Only considering local file room bounding elements
ElementId localElementId = boundaryElementId.HostElementId;
// 如果边界是屋顶则记录下来
if (localElementId != ElementId.InvalidElementId && categoryFilter.PassesFilter(m_document, localElementId)){
// Room already has roofs, add more
if (roomsAndRoofs.ContainsKey(room)){
List<ElementId> roofs = roomsAndRoofs[room];
if (!roofs.Contains(localElementId))
roofs.Add(localElementId);
} else {
List<ElementId> roofs = new List<ElementId>();
roofs.Add(localElementId);
roomsAndRoofs.Add(room, roofs);
}
break;
}
}
}
}
核心接口SpatialElementGeometryCalculator
,用于查找空间的几何:
namespace Autodesk.Revit.DB
{
public class SpatialElementGeometryCalculator : IDisposable
{
public SpatialElementGeometryCalculator(Document aDoc);
public SpatialElementGeometryCalculator(Document aDoc, SpatialElementBoundaryOptions options);
public static bool CanCalculateGeometry(SpatialElement spatialElement);
public static bool IsRoomOrSpace(SpatialElement spatialElement);
public SpatialElementGeometryResults CalculateSpatialElementGeometry(SpatialElement spatialElement);
public SpatialElementBoundaryOptions GetOptions();
}
}