Wygenerowanie obrysu pomieszczenia przy pomocy Pythona jest stosunkowo proste. Służy do tego poniższa funkcja API:
loops = room.GetBoundarySegments(options)
Opcje to zmienna typu SpatialElementBoundaryOptions określająca pożądaną lokalizację obrysu – np. dla ścian oś lub lico wykończenia. W rezultacie otrzymujemy listę “obwodów” – każdy zaś obwód jest również listą – pojedynczych segmentów. W celu pobrania wszystkich linii obrysu możemy wywołać kod jak poniżej:
for loop in loops: for segment in loop: c = segment.GetCurve()
Sytuacja komplikuje się gdy chcemy pobrać obrysy dla pomieszczeń z plików podłączonych do naszego dokumentu. Podłączone pliki mogą być dowolnie przemieszczone lub obrócone i takie wywołanie funkcji jak powyżej zwróci nam nieprawidłowe lokalizacje segmentów.
Aby uporać się z tym problemem potrzebujemy znać transformację (przesunięcie, obrót) danego pliku. Szczęścliwie klasa API RevitLinkInstance zawiera funkcję GetTotalTransform(), która zwróci nam pożądaną transformację dla danego wystąpienia podłączonego dokumentu (podłączony dokument może występować w naszym pliku wielokrotnie – np. powtarzalne kondygnacje).
Znając już potrzebną transformację, jesteśmy w stanie skorygować położenie naszych segmentów:
transform = linkInstance.GetTotalTransform() c = segment.GetCurve() p0 = transform.OfPoint(c.GetEndPoint(0)).ToPoint() p1 = transform.OfPoint(c.GetEndPoint(1)).ToPoint()
Poniżej kod, który dla wskazanego obiektu typu RevitLinkInstance, zwróci nam listę występujących w nim pomieszczeń oraz ich obrysów:
import clr clr.AddReference('ProtoGeometry') from Autodesk.DesignScript.Geometry import * clr.AddReference('RevitAPI') import Autodesk from Autodesk.Revit.DB import * clr.AddReference("RevitNodes") import Revit clr.ImportExtensions(Revit.GeometryConversion) #The inputs to this node will be stored as a list in the IN variables. linkInstance = UnwrapElement(IN[0]) linkedDoc = linkInstance.GetLinkDocument() collector = FilteredElementCollector(linkedDoc).OfCategory(BuiltInCategory.OST_Rooms) transform = linkInstance.GetTotalTransform() rooms = [] boundaries = [] options = SpatialElementBoundaryOptions() options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish for r in collector.ToElements(): rooms.append(r) lines = [] for loop in r.GetBoundarySegments(options): for segment in loop: c = segment.GetCurve() p0 = transform.OfPoint(c.GetEndPoint(0)).ToPoint() p1 = transform.OfPoint(c.GetEndPoint(1)).ToPoint() #line = Line.CreateBound(p0,p1) line = Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint(p0,p1) lines.append(line) boundaries.append(lines) #Assign your output to the OUT variable. OUT = rooms, boundaries
Oraz defincja Dynamo, która powyższe obrysy zamieni na Revitowe linie modelowe:
