Hello Dynamo Friends
I would like to get the geometry of a Civil surface to dynamo for revit so I can use it to cut Revit solids.
Here are my results so far.
With CivilConnection I can get the Civil Surface to Dynamo Revit. No big deal.
I can get points of the surface and build a topography in Dynamo Revit.
This will not represent the Civil Topography correct, to increase the quality I will may use much more points in the future, by just creating as many sample points in civil as I want.
I tried to create a mesh and thicken it with the help of MeshToolkit. In hopes of getting a solid.
Turns out this just gives me a mesh and not a solid, and a mesh is pretty useless for what I want to do, so I need another approach.
I had to get rid of unnecessary points because Dynamo couldnĀ“t deal with the number of elements anymore, so I tested for intersection with my Revit Solid and build a new topo.
And now i build faces from the mesh.
I can build a polysurface from the surfaces and as a last step I tried to surface.thicken to get my desired ātopo solidā that I want to cut with my revit solid. But I get the error:
[
An error occurred: Unable to compute thickened face : INCONSISTENT_ORIENTATION -- Faces in shell have inconsistent orientation
at Autodesk.LibG.Surface.thicken(Double thickness, Boolean both_sides)
at Autodesk.LibG.SurfaceHost.Thicken(Double thickness, Boolean bothSides)
at Autodesk.DesignScript.Geometry.Surface.Thicken(Double thickness, Boolean both_sides)
]
So IĀ“m not sure how to create a solid from the polysurface. I tried to create a python code to test and correct the orientation of the faces but it didnĀ“t work out.
As IĀ“m pretty sure there have to be better methods for what I want to achiev, IĀ“m asking for help and appreciate any suggestions on this topic.
Kind Regards!
I am not sure how to do what your are after and am too busy to take on such an exploration this week, butā¦
If memory serves this is the third āCivil to Revitā topic youāve asked about in around as many days.
Not that there is a problem with asking questions about a generic process (it helps the community grow as ideas are surfaced), but something more specific about the end goals is likely going to get you better results.
Asking something along the lines of āI have a surface in Civil 3D which I need to intersect with a solid geometry of a ____ in Revit with so that I can ______. How would you go about this?ā
and providing a small sample dataset will likely be more effective at getting you where you want to be.
Here is a solution, I maybe adding another one in the future and IĀ“m interested if someone has other solutions.
Task:
Fit a concrete block (Revit generic model, grey) to a topography (Civil 3D Surface, green)
Workflow:
- Get Surface.Triangles in Civil 3D and save in dynamo file with data.remember
- Call the Triangles in Revit and transform to project coordinate system
- Extrude Triangles in -z direction with Curve.ExtrudeAsSolid
- Test for intersections between concrete block solid and Triangle solids with Geometry.DoesIntersect
- Use Solid.DifferenceAll to remove Triangle solids from main solid
- Remove unnecessary stuff with Solid.Separate and create DirectShape
1 Like
Things that did not work out:
Looking how other people do that i found 2 resources.
-
Dealing withTopography in Dynamo
-
Wall follow topography
They create polysurfaces. This did not work out for me because i could not use the polysurface for anything. I could not extrude it or use it to split my solid. The topography is so big and complex it always lead to errors because auf the direction of the faces and so on. Thats why i decided to just extrude every single triangle itself.
I could not create a FreeForm because SAT is returning Mesh geometry:
My goal was to create a nice family with a FreeForm but the solid is too complex an could not meet the criteria. Here you can read about the limitations:
Causes:
Not supported geometry - thin, circle-based, and long extrusions could not be created in Revit.
https://www.autodesk.com/support/technical/article/caas/sfdcarticles/sfdcarticles/Dynamo-node-FamilyType-ByGeometry-is-unable-to-create-family-types-in-Revit.html
Trying to create a free form directly in a family document did not work out. Dynamo and Revit Solids are not easy convertible to each other, a workaround is to export the dyn solid to SAT and import it. Unfortunately this does not work if the SAT file gets to complex. In that case it will be retrieved as a mesh and not a solid when importing it back to dynamo, and a mesh is useless for my task.
So using a DirectShape is the only thing I could get working, sadly
ItĀ“s annoying that a DirectShape will not be listed in a material takeoff as soon as it is too complex.
Python code
As the core nodes were failing or did take too long for the calculations of the 100k elements i had to use a few python nodes.
Extrude Polycurves:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import Vector
polycurves = IN[0]
polycurves = polycurves if isinstance(polycurves, list) else [polycurves]
vector = Vector.ByCoordinates(0, 0, 1) # Z-direction
extruded_geometry = []
for polycurve in polycurves:
try:
extruded_geometry.append(polycurve.ExtrudeAsSolid(vector, -10))
except:
pass
OUT = extruded_geometry
Intersect Solids:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
def solids_intersect(solid1, solid2):
try:
intersection = Solid.Intersect(solid1, solid2)
if intersection:
return True
except:
pass
return False
input_solid = IN[0]
list_of_solids = IN[1]
intersecting_solids = []
for solid in list_of_solids:
if solids_intersect(input_solid, solid):
intersecting_solids.append(solid)
OUT = intersecting_solids
Solid Difference:
As Solid.DifferenceAll was failing if a single element fail and Solid.Difference did take forever i built this combination. Here the solids are grouped and every group is differenced with Solid.DifferenceAll, if a group fails the elements will be differenced with Solid.Difference. You have to experiment with group size.
import Autodesk.DesignScript.Geometry as geom
def subtract_solids(main_solid, solids_to_subtract, group_size=20):
if main_solid is None or main_solid.Volume <= 0:
return "Invalid main solid."
solid_groups = [solids_to_subtract[i:i+group_size] for i in range(0, len(solids_to_subtract), group_size)]
for group in solid_groups:
valid_group = [s for s in group if s is not None and s.Volume > 0]
try:
main_solid = geom.Solid.DifferenceAll(main_solid, valid_group)
except Exception:
# If DifferenceAll fails, subtract solids one by one
for solid in valid_group:
try:
main_solid = geom.Solid.Difference(main_solid, solid)
except Exception:
continue
return main_solid
main_solid = IN[0]
solids_to_subtract = IN[1]
result_solid = subtract_solids(main_solid, solids_to_subtract)
OUT = result_solid
Solid.Faces was also pretty useful to modify the solid in the end.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import Solid
ds_solid = IN[0]
def extract_faces_from_dynamo_solid(ds_solid):
if isinstance(ds_solid, Solid):
faces = ds_solid.Faces
return faces
else:
return "Input is not a Dynamo Solid."
OUT = extract_faces_from_dynamo_solid(ds_solid)
2 Likes