Getting Inner Perimeter Curves from a surfaces

Hello everyone,
So im trying to getting Inner Perimeter Curves from a surfaces.

Ive known Surface.OuterPerimeterCurves nodes from spring nodes. it works pretty well getting that curves.


But unfortunately its just outer while what i wanted is inner perimeter

I wonder if thats node i modify it and can i get the Inner Perimeter?

Ive tried the Surface.InnerPerimeterCurves but sometimes its getting error empty list with polycurve branched errors. and its output as a polycurve.

Trying for guidance here instead of writing this out for you, try adding one word, specifically not, to line 17. It likely goes where you think it should.

Hmm ive already tried it but its says error “List Index Out of Range”

This The original code

# Copyright(c) 2020, Dimitar Venkov
# @5devene, dimitar.ven@gmail.com
# www.badmonkeys.net

import clr
clr.AddReference('ProtoGeometry')
import Autodesk.DesignScript.Geometry as DS

def tolist(x):
    if hasattr(x,'__iter__'): return x
    return [x]

surfaces = tolist(IN[0])

def dropSurfaceOpenings(srf):
	face = srf.Faces[0]
	extLoop = [lp for lp in srf.Faces[0].Loops if lp.IsExternal][0]
	return [ce.Edge.CurveGeometry for ce in extLoop.CoEdges]

OUT = map(dropSurfaceOpenings, surfaces)

Remove the [0].

Are you sure all surfaces have an inner loop?

Yes, im sure it has inner loop


this the removed [0] but still errors

Edit: Ive tried too just removes it the last ones. its still getting errors but it says "List has no attributes CoEdges

Because you’ve removed pulling the item from the list at line 17 you’ve got a list of loops instead of a single loop. A surface can have many internal loops but only one external loop by definition. So an extra layer of list comprehension is required.

This verbose code will out line the process. Note this works for the faces of a solid as well, as this is built upon the Faces class of Dynamo’s Topology library.

Get Surface Loops
########################################
############## Properties ##############
########################################
__author__ = 'Jacob Small'
__version__ = '0.1.0'
__description__ = "Extracts the curve loop from the faces of a geometry"
__DynamoBuilds__ = "2.18"
__ReleaseNotes__ = "Not completely tested, test thuroughly before implementation."
__Dependancies__ = "None"
__Copyright__ = "2024, Autodesk Inc."
__license__ = "Apache 2"



########################################
### Configure the Python environment ###
########################################
### standard imports ###
import sys #add the sys class to the Python environment so we can work with the sys objects
import clr #add the CLR (common language runtime) class to the Python environment so we can work with .net libraries

### basic Dynamo imports ###
clr.AddReference('ProtoGeometry') #add the Dynamo geometry library to the CLR
from Autodesk.DesignScript import Geometry as DG #add the Dynamo geometry class using the alias DG, to ensure no overlap between class calls in integrations




#########################################
###### Global variables and inputs ######
#########################################
geometries = IN[0] #surfaces from the IN[0] port of the Dynamo environment
if geometries.__class__ != list: geometries = [geometries] #ensure the geometries variable from Dynamo is a list
resultsDict = {"Internal Edges":[], "External Edges": []} #setup the resultsdict with keys for internal and external edges



#########################################
## Get the inner and outer curve loops ##
#########################################
for geo in geometries: #for each geometry in the input
    internalLoops = [] #set up an empty list for the internal loops
    for face in geo.Faces: #for each face in the geometry's faces
        loops = face.Loops #get the loops which define the face
        for loop in loops: #for each loop in the loops
            coEdges = loop.CoEdges #get the coedges
            curves = [] #build an empty list to hold the curves
            for coEdge in coEdges: #for each coedge in the list of coedges
                edge = coEdge.Edge #get the edge
                curve = edge.CurveGeometry #get the curve geometry from the edge
                curves.append(curve) #append the curve to the curves list
            polycurve = DG.PolyCurve.ByJoinedCurves(curves) #generate a polycurve from the curves
            if loop.IsExternal: #if the loop is external
                externalLoop = polycurve #set externalLoop to the polycurve
            else: #otherwise
                internalLoops.append(polycurve) #append the polycurve to the internal loops list
    resultsDict["Internal Edges"].append(internalLoops) #append the internal edges to the results dict
    resultsDict["External Edges"].append(externalLoop) #append the external edge to the results dict


#########################################
##### Return the results to Dynamo ######
#########################################
OUT = resultsDict["External Edges"], resultsDict["Internal Edges"] #pull the external edges and internal edges from the results dict

And the simplified definition based method:

Get Surface Loops
########################################
############## Properties ##############
########################################
__author__ = 'Jacob Small'
__version__ = '0.1.0'
__description__ = "Extracts the curve loop from the faces of a geometry"
__DynamoBuilds__ = "2.18"
__ReleaseNotes__ = "Not completely tested, test thuroughly before implementation."
__Dependancies__ = "None"
__Copyright__ = "2024, Autodesk Inc."
__license__ = "Apache 2"

########################################
### Configure the Python environment ###
########################################
### standard imports ###
import sys #add the sys class to the Python environment so we can work with the sys objects
import clr #add the CLR (common language runtime) class to the Python environment so we can work with .net libraries
### basic Dynamo imports ###
clr.AddReference('ProtoGeometry') #add the Dynamo geometry library to the CLR
from Autodesk.DesignScript import Geometry as DG #add the Dynamo geometry class using the alias DG, to ensure no overlap between class calls in integrations

#########################################
######## Classes and Definitions ########
#########################################
def GetCurveLoops(geometry):
    internalLoops = [] #set up an empty list for the internal loops
    for face in geometry.Faces: #for each face in the geometry's faces
        loops = face.Loops #get the loops which define the face
        for loop in loops: #for each loop in the loops
            polycurve = DG.PolyCurve.ByJoinedCurves([coEdge.Edge.CurveGeometry for coEdge in loop.CoEdges]) #build a polycurve from the loop
            if loop.IsExternal: externalLoop = polycurve #if the loop is external set externalLoop to the polycurve
            else: internalLoops.append(polycurve) #otherwise append the polycurve to the internal loops list
    return externalLoop, internalLoops

#########################################
###### Global variables and inputs ######
#########################################
geometries = IN[0] #surfaces from the IN[0] port of the Dynamo environment
if geometries.__class__ != list: geometries = [geometries] #ensure the geometries variable from Dynamo is a list
resultsDict = {"Internal Edges":[], "External Edges": []} #setup the resultsdict with keys for internal and external edges

#########################################
## Get the inner and outer curve loops ##
#########################################
for geo in geometries: #for each geometry in the input
    loops = GetCurveLoops(geo)
    resultsDict["Internal Edges"].append(loops[1]) #append the internal edges to the results dict
    resultsDict["External Edges"].append(loops[0]) #append the external edge to the results dict

#########################################
##### Return the results to Dynamo ######
#########################################
OUT = resultsDict["External Edges"], resultsDict["Internal Edges"] #pull the external edges and internal edges from the results dict
3 Likes

It works! but with warning. at some of my surfaces is null, due to Failed to construct polycurves from the input curves. Polycurves branched. scaling already set at large settings.

I dont know whats causing this issue, well its by logically inner perimeters is a closed curves. but in my case its says polycurves branched.

Is it possible to output as a curves?

Leave it at medium and ignore the ‘large coordinates’ message.

Alternatively append the list of curves instead of the polycuves to the results lists.