I’m trying to understand an issue related to retrieving solid geometry from structural columns.
As shown in the image below, when dealing with isolated columns, the code below does not return any solid geometry. However, when the same code is executed on columns connected to beams, the solids are successfully retrieved.
import clr
import sys
import System
from System.Collections.Generic import IList, List
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
def get_solid(column):
options = Options()
options.IncludeNonVisibleObjects = False
options.DetailLevel = ViewDetailLevel.Fine
geoElement = column.get_Geometry(options)
return next((g for g in geoElement if isinstance(g, Solid) and g.Volume > 0), None)
columns = list(FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_StructuralColumns)\
.WhereElementIsNotElementType()\
.ToElements())
OUT = [get_solid(col) for col in columns]
Could anyone please clarify why this difference occurs or what might cause isolated columns to return no solids?
@c.poupin
I was wondering if it’s possible to return the solid geometry as an instance directly from the main GeometryInstance itself (I mean, getting the solid geometry from the main transformed GeometryInstance)…for that I refactored your code for testing, and it gives the response for my question, as shown in the image below:
import clr
import sys
import System
from System.Collections.Generic import IList, List
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
def getSolidfromGeo(elem):
opt = Options()
opt.ComputeReferences = True
opt.IncludeNonVisibleObjects = True
geoSet = elem.get_Geometry(opt)
#
for geo in geoSet:
if isinstance(geo,Solid) and geo.Volume > 0 :
return geo, "Geometry"
for geo in geoSet:
if isinstance(geo, GeometryInstance):
outSolid = []
geoSetInst = geo.GetInstanceGeometry()
for geoI in geoSetInst:
if isinstance(geoI,Solid) and geoI.Volume > 0:
outSolid.append(geoI)
outSolid.sort(key = lambda x : x.Volume )
print(len(outSolid))
return outSolid[-1], "GeometryInstance"
return None, None
def column_edge(column, solid):
curveloops = [face.GetEdgesAsCurveLoops() for face in solid.Faces][2]
edges = list(curveloops[0])
plane = curveloops[0].GetPlane()
skp = SketchPlane.Create(doc, plane)
curves = [doc.Create.NewModelCurve(e, skp) for e in edges]
return curves
columns = list(FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_StructuralColumns)\
.WhereElementIsNotElementType()\
.ToElements())
Curves = []
with Transaction(doc, 'create ModelLines') as t:
t.Start()
for col in columns:
solid = getSolidfromGeo(col)[0]
crv = column_edge(col, solid)
Curves .append(crv)
t.Commit()
OUT = [c.GeometryCurve.ToProtoType() for list in Curves for c in list]