Hello,
i want to create solids (dynamo) in python… need i a library for that? final aim is union all geometry to one
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
collectorColumns = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns)
placedColumns = collectorColumns.WhereElementIsNotElementType().ToElements()
#var options = new Options() { ComputeReferences = true, IncludeNonVisibleObjects = true };
#var geometry = placedColums.get_Geometry(options);
geoms = []
for i in placedColumns:
geoms.append(i.GetSymbolGeometry())
OUT = geoms
You’ll need to use the standard Dynamo geometry library to access the Dynamo geometry tools. These lines should do the trick:
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
1 Like
@jacob.small ,
it does still not work, the method does not exist
# Phython-Standard- und DesignScript-Bibliotheken laden
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
collectorColumns = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns)
placedColumns = collectorColumns.WhereElementIsNotElementType().ToElements()
geoms = []
for i in placedColumns:
geoms.append(i.GetSymbolGeometry())
OUT = geoms
Hi,
you need to convert the objects, here are 2 solutions:
the first by converting a Revit object (wrap into a Dynamo Revit.Element object )
the second by converting the geometries
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
collectorColumns = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns)
placedColumns = collectorColumns.WhereElementIsNotElementType().ToElements()
geomsA = []
geomsB = []
opt = Options()
for i in placedColumns:
# Solution 1
geomsA.append(i.ToDSType(True).Geometry())
# Solution 2
geoset = i.get_Geometry(opt)
for geo in geoset:
if isinstance(geo, DB.Solid) and geo.Volume > 0:
geomsB.append(geo.ToProtoType())
elif isinstance(geo, DB.GeometryInstance):
for geoi in geo.GetInstanceGeometry():
if isinstance(geoi, DB.Solid) and geoi.Volume > 0:
geomsB.append(geoi.ToProtoType())
OUT = geomsA, geomsB
1 Like
@c.poupin ,
thanks, i got following warning… how can i solve that?
i choose columns because i think thats the simplest geometry
try to change the geometry scale
1 Like
all 4 option do not work @c.poupin
with basic nodes i see “something” with the same error
intresting when i play with scales the error changes …
It’s a bug on some geometries
opened 09:44PM - 21 Mar 22 UTC
If this issue is **not** a bug report or improvement request, please check the [… Dynamo forum](https://forum.dynamobim.com/), and start a thread there to discuss your issue.
## Dynamo version
2.12
## Revit version
2022
## Operating system
Windows 10
## What did you do?
Convert Revit Geometry Element to Proto-Geometry
## What did you expect to see?
The Dynamo Geometry
## What did you see instead?
StandardError: trim_with_edge_loops requires all curves to touch surface

## Related issues
https://github.com/DynamoDS/DynamoRevit/issues/1814
## Related topics forum
https://forum.dynamobim.com/t/revitapi-geometry-got-empty-list/74334
https://forum.dynamobim.com/t/convert-rooms-to-mass-trim-with-edge-loops-requires-all-curves-to-touch-surface-dynamo/49042
https://forum.dynamobim.com/t/element-geometry-error-trim-with-edge-loops-requires-all-curves-to-touch-surface/55696
## Workaround
here a workaround using Solid.ByJoinedSurfaces() and Polycurve.Patch() instead (work only if the bug face(s) is planar face)
example with Python code
_Note;
code needs improvement when buggy face(s) has multiple loops_
```
import clr
import System
import sys
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
def get_AllSolid(lst_elem, inc = 0):
# sub functon
def populate_lstGeo(g):
if isinstance(g, Solid) and g.Volume > 0:
solids.append(g)
elif isinstance(g, GeometryInstance):
geoInst.append(g)
else:pass
#
# main functon
global opt
solids = []
geoInst = []
lst_elem = lst_elem if hasattr(lst_elem, "__iter__") else [lst_elem]
if len(lst_elem) > 0 and inc < 2000:
for elem in lst_elem:
if isinstance(elem, GeometryInstance):
for j in elem.GetInstanceGeometry():
populate_lstGeo(j)
else:
geoSet = elem.get_Geometry(opt)
for i in geoSet:
populate_lstGeo(i)
return solids + get_AllSolid(geoInst, inc + 1)
else:
return []
elem = UnwrapElement(IN[0])
opt = Options()
solids = get_AllSolid(elem)
ds_Solids = []
for s in solids:
try:
ds_Solid = s.ToProtoType()
ds_Solids.append(ds_Solid)
except Exception as ex:
if "trim_with_edge_loops" in str(ex):
# failed conversion DB.Solid to Prototype -> try get make solid with ByJoinedSurfaces
ds_face = []
for f in s.Faces:
try:
ds_face.extend(f.ToProtoType())
except:
# failed conversion DB.Face to Prototype -> try get make Surface with PolyCurves.Patch
ds_edges = [c.ToProtoType() for curveloop in f.GetEdgesAsCurveLoops() for c in curveloop]
ds_poly_edges = PolyCurve.ByJoinedCurves(ds_edges)
ds_face.append(ds_poly_edges.Patch())
ds_Solid = DS.Solid.ByJoinedSurfaces(ds_face)
ds_Solids.append(ds_Solid)
else:
raise Exception(ex)
OUT = ds_Solids
```

if the goal is only visualization, you may be able to extract only the surfaces rather than the complete geometry
@c.poupin ,
the goal is i want to compare two modells by geometry independed from categories.
i have also to make union of all categories to get this single concrete geometry!
f. e. Model (ARC) has a Volume from 200.000m³ and Model STATIK has a Volume from 201.000m³
so i can see it has a delta from 5.0 %
i see in my project the Planers have different model-rules but come to the same result. i want to say the model is fine inspite of the different “modelstyles”!
thats the aim
I think that the only solution will be to work only with native geometries of the Revit API (no conversion).
Or need to isolate elements that cause this bug (but the result may be wrong depending on the volume of this element).
2 Likes
@c.poupin ,
so it is not Element.Geometry it should be Element.NativeGeometry …hmmm
i need just the “shell” of the concrete building… it sounds easy
visualisation is no issue in outer softwares, but to get the volume of a shell is the challange
1 Like
Usually if you convert this kind of things to dynamo geometry, it will contain error.
For me I will stick with revit geometry.
and you can check is there solid in your object by using revit lookup:
here shows there is solid inside this wall.
Then use revitapi to extract its geometry.
1 Like
@newshunhk ,
for system families it works for one instance
import sys
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
#Preparing input from dynamo to revit
elements = UnwrapElement(IN[0])
geom = elements.get_Geometry(Options())
for g in geom:
if isinstance(g,Solid):
solid = g
OUT = solid.ToProtoType()
How to i interate true my elements?
elements = UnwrapElement(IN[0])
solids = []
truesolids = []
for i in elements:
solids.append(i.get_Geometry(Options()))
for g in solids:
if isinstance(g,Solid):
truesolids.append(g)
else:
pass
OUT = truesolids.ToProtoType()
my code is a pit off
you can add this in your code:
toList = lambda x : x if hasattr(x, '__iter__') else [x]
elements = toList(UnwrapElement(IN[0]))
this will turn your element into list if it is not a list
toList = lambda x: x if hasattr(x, '__iter__') else [x]
elements = toList(UnwrapElement(IN[0]))
solids = []
for i in elements:
geo = i.get_Geometry(Options())
for g in geo:
if isinstance(g, Solid):
solids.append(g.ToProtoType())
OUT = solids
1 Like
newshunhk:
get_Geometry
@newshunhk
from where do you get this methode ? it is not exposed to the revit API ?
@newshunhk ,
it works in the demo… in the real project it has difficulties to create the solids…
it says like curves “branching” …
how to get rid of that?
Post the full code, including imports when trouble shooting like this.
import sys
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
toList = lambda x: x if hasattr(x, '__iter__') else [x]
elements = toList(UnwrapElement(IN[0]))
solids = []
for i in elements:
geo = i.get_Geometry(Options())
for g in geo:
if isinstance(g, Solid):
solids.append(g.ToProtoType())
OUT = solids
Converting to a Dynamo solid isn’t always possible as the geometry tolerances of the two tools aren’t possible. Best to keep to Revit geometry as noted before, removing the need for the ToProtoType line.
See if it works when that is removed.
@jacob.small ,
the imports will be the static categories
beams
slabs
walls
columns