Hi All,
I want to extract the outer boundary of a road geometry. I saw in other topics that there is a method of offsetting geometry, turn it to a solid then intersecting it with the XY plan before offsetting it once again to its original place. but it doesn’t work in this case since arcs in road geometry has small radius values and can’t be always offset.
This is the road Geometry that I have
and this is what I want to achieve (extracting the outer boundary of the whole geometry)
(Forget about the hatches, consider the hatches boundaries as inputs in a form of polylines)
This is the dwg attached for testing. Thank you
Road Geometry.dwg (905.5 KB)
Since your drawing is 2d flat linework consisting of only closed curves, you can do this fairly easily. There are a few areas where the polycurves aren’t perfectly adjacent though, so you’ll have to do a bit of juggling there with Python to take advantage of some topology features which are not directly exposed. I’ll outline the base method for ‘clean’ surfaces first.
- Extract the geometry of each object as a closed curve (circle or PolyCurve). The node
Polyline2D.ConvertToPolyCurve
from @Anton_Huizinga’s The Civil Nodes package does this well in 2025.2, but you may need to separate your object types beforehand.
- Convert all of the closed curves into surfaces with a
Surface.Patch
node, and union them into a single surface with a Surface.ByUnion
node.
- Pull the perimeter curves of the unioned surface with a
Surface.PerimeterCurves
node, and generate a polycurve using a PolyCurve.ByJoinedCurves node.
- Convert the resulting polycurve into a PolyLine using a
Polyline.ByGeometry
node.
Now for the juggling bit. Step 3 fails as there are actually 3 loops in your unioned surface, as there are two areas where the polylines aren’t quite aligned with the adjacent segments. To deal with this, we need to build the polycurves from the face’s loops rather than just pulling the perimeter curves. The methods to do so (Face.Loops; Loop.CoEdges; CoEdge.Edge) are not exposed as nodes in Dynamo, so we’ll need to use some Python. This should work:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
surface = IN[0] #get the surface from the Dynamo environment
faces = surface.Faces #get the faces which make up the surface
loops = [i for face in faces for i in face.Loops ] #the loops which define the limits of each face
externalLoops, internalLoops = [],[] #empty lists to hold the external and internal loops
for loop in loops: #for each loop
curve = PolyCurve.ByJoinedCurves([coEdge.Edge.CurveGeometry for coEdge in loop.CoEdges]) #build a polycurve
if loop.IsExternal: #if the loop is external, add it to the external list
externalLoops.append(curve)
else: #otherwise
internalLoops.append(curve) #add the loop to the internal list
OUT = [externalLoops,internalLoops] #return the external and internal loops
From there we just need to convert to polylines as before in step 4. I’m sending the external and internal polycurves as polylines on their own layer so as to identify and validate where the interior openings are incase they’re a issue that needs to be addressed.
This should illustrate steps 2 to the end so you can build yourself a working tool:
2 Likes
Hi Jacob,
Thank you so much for your reply, I forgot to mention though that I am using an old version of dynamo for Civil 2022 (Dynamo Version: 2.12.0.5650) so unfortunately I have to stick with old nodes and maybe also an older version of Python (I am not sure if this version of dynamo needs Python 2 or if the newer version of python works on it).
I tried using the simple way that you described using a cleaner version (I created a closed polyline from scratch and simply copied it twice and placed the copies adjacent to the original polyline to end up having 3 closed polylines that are adjacent to each other), it works perfectly fine if your polylines are perfectly adjacent
So, in this case and as you said python is needed, however, I still can’t even reach the node in which I am supposed to use dynamo to correct the adjacency of polylines, I get an error (as shown in the photo below) when I am trying to create surfaces in the “Surface.ByPatch” node, any idea how can this be fixed ? or is there another method of achieving the final result by using another package like Topology for example ?
Thanks once again for your assistance with this.
Time for an upgrade! Historically new versions are released in the spring, and that is right around the corner. Once that happens you’ll be in an unsupported version which means no security updates and such.
But if you can’t do that… First make sure Geometry Scaling is on medium - ignore any scale info as they don’t impact the geometry, just the display. Then make sure the PolyCurve is completely on the XY plane by using a pull onto plane node. Then make sure it is closed using a ‘IsClosed’ property and if not a ‘CloseWithLine’ method. If that still doesn’t clean things up… I guess then go make the case to get the upgrade…
2 Likes
That solved my problem Jacob ! (setting geometry scaling to medium and use the “pull into plane” node) + Python node, thank you so much for your guidance and assistance with this.
1 Like