Hi
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…
KR
Andreas
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.
3 Likes
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
@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
clr.AddReference('ProtoGeometry')
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:
C0.append(c)
C1.append(str(c))
return C0
lines = IN[0]
line_points = []
line_lengths = []
for l in lines:
line_points.append(l.StartPoint)
line_points.append(l.EndPoint)
line_lengths.append(l.Length)
# 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:
continue
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:
break
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):
result.append(l)
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 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.