前言
Revit 有不少分析功能,比如这个行进路径的规划。也可参考:Dynamo For Revit: Path of Travel 行进路径
行进路径
SDK 中的这个例子,有三个选项,分别是:
- 从单个房间的各个角点到单扇门;
- 从所有房间的中心点到单扇门;
- 从所有房间的各个角点到各个门。
从单个房间的各个角点到单扇门
关键逻辑
找到各个房间的角点:
- 拿到房间的边界;
- 循环各条边偏移并计算交叉点,即角点。
private static void AppendRoomNearCornerPoints(Room room, List<XYZ> nearCornerPoints)
{
IList<IList<BoundarySegment>> segments = room.GetBoundarySegments(new SpatialElementBoundaryOptions());
// First region only
IList<BoundarySegment> firstSegments = segments[0];
int numSegments = firstSegments.Count;
for (int i = 0; i < numSegments; i++)
{
BoundarySegment seg1 = firstSegments.ElementAt(i);
BoundarySegment seg2 = firstSegments.ElementAt(i == numSegments - 1 ? 0 : i + 1);
Curve curve1 = seg1.GetCurve();
Curve curve2 = seg2.GetCurve();
Curve offsetCurve1 = curve1.CreateOffset(-1.5, XYZ.BasisZ);
Curve offsetCurve2 = curve2.CreateOffset(-1.5, XYZ.BasisZ);
IntersectionResultArray intersections = null;
SetComparisonResult result = offsetCurve1.Intersect(offsetCurve2, out intersections);
// First intersection only
if (result == SetComparisonResult.Overlap && intersections.Size == 1)
{
nearCornerPoints.Add(intersections.get_Item(0).XYZPoint);
}
}
}
计算房间room
角点到各个终点endPoints
:
- 计算房间
room
的各个角点; - 用
PathOfTravel::CreateMapped
创建多对多的行进路径。
private static void GeneratePathsOfTravelForOneRoomManyDoors(Document doc, ViewPlan viewPlan, Room room, List<XYZ> endPoints, ResultsSummary resultsSummary)
{
List<XYZ> sourcePoints = GetRoomNearCornerPoints(room);
resultsSummary.numSourcePoints += sourcePoints.Count;
using (Transaction t = new Transaction(doc, "Generate paths of travel"))
{
t.Start();
IList<PathOfTravelCalculationStatus> statuses;
IList<PathOfTravel> pathsOfTravel = PathOfTravel.CreateMapped(viewPlan, sourcePoints, endPoints, out statuses);
foreach (PathOfTravel pOT in pathsOfTravel)
{
if (pOT == null) resultsSummary.numFailures++;
else resultsSummary.numSuccesses++;
}
t.Commit();
}
}
计算从单个房间各个角点到单扇门。
private static void GeneratePathsOfTravelForOneRoomOneDoor(Document doc, ViewPlan viewPlan, Room room, XYZ endPoint, ResultsSummary resultsSummary)
{
GeneratePathsOfTravelForOneRoomManyDoors(doc, viewPlan, room, new List<XYZ> { endPoint }, resultsSummary);
}
运行效果
从所有房间的中心点到单扇门
关键逻辑
private void CreatePathsOfTravelRoomCenterpointsToSingleDoor(UIDocument uiDoc)
{
Document doc = uiDoc.Document;
ViewPlan viewPlan = uiDoc.ActiveView as ViewPlan;
ElementId levelId = viewPlan.GenLevel.Id;
// 选择一扇门作为目标
Reference reference = uiDoc.Selection.PickObject(ObjectType.Element, new DoorSelectionFilter(), "Select a target door");
Instance doorElement = doc.GetElement(reference) as Instance;
Transform trf = doorElement.GetTransform();
XYZ endPoint = trf.Origin;
// 找到所有房间
FilteredElementCollector fec = new FilteredElementCollector(doc);
fec.WherePasses(new Autodesk.Revit.DB.Architecture.RoomFilter());
List<XYZ> startPoints = new List<XYZ>();
// 找到所有房间的中心点
foreach (Room room in fec.Cast<Room>().Where<Room>(rm => rm.Level.Id == levelId))
{
LocationPoint location = room.Location as LocationPoint;
if (location == null)
continue;
XYZ roomPoint = location.Point;
startPoints.Add(roomPoint);
}
// 生成行进路径
using (Transaction t = new Transaction(doc, "Generate paths of travel"))
{
t.Start();
IList<PathOfTravelCalculationStatus> statuses;
PathOfTravel.CreateMapped(viewPlan, startPoints, new List<XYZ> { endPoint }, out statuses);
t.Commit();
}
}
运行效果
从所有房间的各个角点到各个门
关键逻辑:实际上是上面两个功能的混合。可自行参考代码。