Divide a list of curves into groups based on the fact they are forming a poligon or not

I have a list of curves that come from CAD, when I read them in Dynamo they are just a list so the problem is how to recognize that say those points are representing a polygon, which is a Building and the next point is in another set of point that belongs to another building footprint…
I cannot install the package lunchbox at the moment


I think I found the condition to check for a list of points.
It requires to
represent a surface of the triangle included for point n, n-1 and 1, than to the next triangle and
see if there is a crossing surface
If there is crossing surface means that the n point belongs to another set of points, (a Building plan).
I thought to share this as probably as been already solved by known algorythms,
so if anybody has a hint about it would be great.
I am planning to solve this with pyhton anyway.
This was a nice post a subject slightly nearby,

Depending on your data set you could try some design script grouping of curves.

Are your points or curves all located in the same flat plane? Are you just looking to sort radially from base points at first? Would you be able to post an image of your workspace or what you have tried? As well as a test file?

There are a few statistical outliers removal algorithms out there (mainly for pointclouds) but your workflow probably only requires a simple recursive algorithm.

Thanks for the reply.
Yes I am talking for 2D flat plane.
The input is a list of points but they are sequentially correct to locate footplan one after another.
I am working on my first attempt.
Yes it could be an easy case for a recursive solution
but I prefer to with normal loop first to get a feedback on
calling Revit Api for surface.
Thanks for pointing the Vikram Solution I will take a look.

Ah, already being in sequence will help loads! :+1:

Good luck, it will be good to see your progress :slight_smile:

I am keen to help, but am away from the PC till tomorrow.

After a series of errors I managed to fix, I got this
“Type” object has not attribute ByPerimeterPoints error.


Today I am done, tomorrow I will continue,
the script is here below but I am not able to keep the origina preformatted…
Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference(‘RevitAPI’)
from Autodesk.Revit.DB import *
from System.Collections.Generic import *

clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

A = IN[0]

def mSurf(a,b,c):
# this take 3 points an make a surface
LL=[]
LL.append(a)
LL.append(b)
LL.append(c)
return Surface.ByPerimeterPoints(LL)

def CheckI (a,b):
# this take 2 geometries,
# and return True if intersect
# or False if not intersect
return Geometry.DoesIntersect(a,b)
i=0
OUTP=[];

doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
while i < (len(A)-1) :
m=i;
f=m;
while f < (len(A)-2) :
k=m;
f=m+1;
A1= mSurf(A[k],A[f],A[f+1])
f=f+1
A2 = mSurf(A[k],A[f],A[f+1])
if CheckI(A1,A2) == True :
for j in range(m,f) :
OUTP.append(A[j]);
i=f+1;
else :
f=f+1;
i=f
TransactionManager.Instance.TransactionTaskDone()

OUT = OUTP

1 Like

Is that for Floor Creation?

Try to use Surface by Patch
A = IN[0]

A = UnwrapElement(IN[0])

def SURbyPA(Cur) :
" Create a surface by patch"
return Surface.ByPatch(Cur)

def CurPts(a,b,c) :
# Close a curve with 3 points
LL=[]
LL.append(a)
LL.append(b)
LL.append(c)
return PolyCurve.ByPoints(LL,True)

def CheckI (a,b):
" this take 2 geometries, and return True if intersect or False if not intersect"
return Geometry.DoesIntersect(a,b)
i=0
OUTP=[];

while i < (len(A)-1) :
m=i;
f=m;
while f < (len(A)-2) :
k=m;
f=m+1;
A1= SURbyPA(CurPts(A[k],A[f],A[f+1]))
f=f+1
A2 = SURbyPA(CurPts(A[k],A[f],A[f+1]))
if CheckI(A1,A2) == True :
for j in range(m,f) :
OUTP.append(A[j]);
i=f+1;
else :
f=f+1;
i=f

OUT = OUTP

I believe that there is a ‘GroupCurves’ node in the Archilab package which will do this quite effectively.

I had a similar situation and this is what I came up with. Given a list of points that represent multiple closed polygons, and the points are in correct order, this will break the list into sub lists for the separate polygons. The begin and end point for each polygon must be in the list and identical (meaning the polygons must close). Note that in my case, I wanted to removed the last point (same as the beginning point) for each polygon.

list = IN[0]

repeats = []
for i in list:
	repeats.append([index for index, element in enumerate(list) if element == i])

breaks = repeats[0][:2]

for i in range(len(repeats)-1):
	if i == breaks[-1]:
		breaks.append(i+1)
		for j in repeats[i+1]:
			if j > i+1:
				breaks.append(j)
				break

newList = []
count = 0
for i in range(len(breaks)-1):
	try:
		newList.append(list[breaks[i+count]:breaks[i+count + 1]])
		count += 1
	except:
		break
		
OUT = newList
2 Likes

Thanks a lot.
I will try your solution it looks like it is exactly what I was aiming for.
very clean.
@JacobSmall I used that node, still Sowinksi solution is the solution as the list of points comes from CAD and that node does not group unless they are kind of already grouped, surely there is a way to make it.