Hello, here’s a script to get the total exterior line of a part’s geometry.
There must be a better approach, as always.
I’ve commented out the Python node to follow the methodology used.
import sys,clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import Options,UV,CompoundStructure,XYZ,Line
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
#Function to Find the points of a surface
def findpts(f):
lpts=[]
clt=f.GetEdgesAsCurveLoops()
for cl in clt:
for c in cl:
lpts.append(c.GetEndPoint(0))
return lpts
elt=UnwrapElement(IN[0]) #elt is a Part#
#Get the Document
doc=elt.Document
#Get the Solid
opt=Options()
geoe=elt.get_Geometry(opt)
sol=[g for g in geoe][0]
#Get the wall source of the Part
w=doc.GetElement(elt.GetSourceElementIds()[0].HostElementId)
#Get the WallType
wt=w.WallType
#Find the outgoing vector of the outer face
veco=w.Orientation
vecon=veco.Negate()
#Finding the face of the solid coinciding with the exterior vector of the exterior face
faceext=[f for f in sol.Faces if round(f.ComputeNormal(UV.Zero).X,3)==round(veco.X,3) and round(f.ComputeNormal(UV.Zero).Y,3)==round(veco.Y,3)][0]
#Finding the face of the solid coinciding with the interior vector of the interior face
faceint=[f for f in sol.Faces if round(f.ComputeNormal(UV.Zero).X,3)==round(vecon.X,3) and round(f.ComputeNormal(UV.Zero).Y,3)==round(vecon.Y,3)][0]
#Searching the text index from the element properties (text is in French)
idxv=int(elt.LookupParameter("Index de calque").AsValueString())
#Find the thickness of the layer
epv=wt.GetCompoundStructure().GetLayerWidth(idxv-1)
#Find the Z of the location line
lc=w.Location.Curve
pstartloc=lc.GetEndPoint(0)
#Find all curveloop points and send them to the middle face
lptsext=findpts(faceext)
lptsint=findpts(faceint)
for p in lptsint:
lptsext.append(p.Add(veco.Multiply(epv)))
#Lower all points to the same level as the location line
newp=[XYZ(p.X,p.Y,pstartloc.Z) for p in lptsext]
#Arrange the points by increasing X and take the first and last to create the line
np2=sorted(newp,key=lambda p:(p.X))
pstart=np2[0].Add(veco.Multiply(-epv/2))
pend=np2[-1].Add(veco.Multiply(-epv/2))
lineht=Line.CreateBound(pstart,pend).ToProtoType()
OUT=lineht
Sincerely,
christian.stan