Get internal edges of polysurface


In Grasshopper it is very easy to separate out the naked (exterior) edges and the interior edges of a polysurface. I’m wondering if there is something similar in Dynamo. None of the typology nodes seem to have this. I would prefer not to have to run a bunch of geometric operations to discover them.

@Paul_Wintour ,

is there not something like perimeter.curves that can you extract from the element.Geometry…



I’m not after the perimeter curves. I’m after the interior curves.

This is the most direct way I’m aware of (and yes it’s unfortunately using a few steps. My guess is in Grasshopper there is a similar process in that particular node/function as well). Using filled regions in this case so up until the topology edges nodes is just me making a polysurface.



Thanks Gavin. Yep that will work but I was hoping for a single node but I guess it doesn’t exist. @solamour is this something you can add to the wish list.

1 Like

Single Python node :snake:

@Paul_Wintour You can use an Alpha-Shape calculation if the Polysurface lines are all on one plane. Alternatively, you could pull Polysurface lines to a plane to make this work.

This workflow will still be governed by the complexity of the Polysurface, as lots on ins&outs to the edge will need a different Alpha value.

import clr
from Autodesk.DesignScript.Geometry import *
from math import sqrt, hypot

## For removing duplicate Curves
def cleanlines(curves):
	C0 = []
	C1 = []
	for c in curves:
		if str(c) not in C1 and str(Line.Reverse(c)) not in C1:
	return C0
lines = IN[0]
line_points = []
line_lengths = []

for l in lines:

# Set the tolerance for the alpha-shape 	
alpha = (sum(line_lengths)/len(line_lengths))*1.1

points = Point.PruneDuplicates(line_points)

preout = []

pLen = len(points)
alpha2 = alpha * alpha
if pLen < 2:
    raise Exception('AlphaShape needs at least 2 points')
for i, p in enumerate(points):
    for j in xrange(i+1, pLen):
        if p.IsAlmostEqualTo(points[j]):
           raise Exception('AlphaShape needs pairwise distinct points')
        dist = hypot(p.X - points[j].X, p.Y - points[j].Y)                    
        if (dist > 2 * alpha) : continue #circle fits between points ==> p_i, p_j can't be alpha-exposed                    

        x1, y1, x2, y2 = p.X, p.Y, points[j].X, points[j].Y
        midX, midY = (x1 + x2) / 2, (y1 + y2) / 2

        #find two circles that contain p_i and p_j; note that center1 == center2 if dist == 2*alpha
        alphaDist = sqrt(alpha2 - (dist / 2) ** 2)
        deltaX, deltaY = (x2 - x1) / dist, (y1 - y2) / dist
        c1x, c1y = midX + alphaDist * deltaY, midY + alphaDist * deltaX
        c2x, c2y = midX - alphaDist * deltaY, midY - alphaDist * deltaX
        #check if one of the circles is alpha-exposed, i.e. no other point lies in it
        c1_empty = True 
        c2_empty = True
        for k in xrange(pLen):                
            if i == k or j == k: 
            if ((c1x - points[k].X) * (c1x - points[k].X) + (c1y - points[k].Y) * (c1y - points[k].Y) < alpha2):
                c1_empty = False
            if ((c2x - points[k].X) * (c2x - points[k].X) + (c2y - points[k].Y) * (c2y - points[k].Y) < alpha2):
                c2_empty = False
            if not c1_empty and not c2_empty:
        if c1_empty or c2_empty:
             preout.append(Line.ByStartPointEndPoint(p, points[j]))

result = []

# Check the original lines against the found perimeter lines
for l in lines:
	if l not in result:
		for p in preout:
			if Geometry.DoesIntersect(Line.PointAtParameter(l,0.5),p):
OUT = cleanlines(result)
1 Like

@Paul_Wintour Please do submit any Wishlist items to GitHub - DynamoDS/DynamoWishlist: This is a repository for all wishlist items for Dynamo Core so that we can track them :slight_smile: We do reviews of this space and pull in what we can amongst larger elements, or cluster a thematic together and do many at once.