Organizing/Ordering Points for Polygon

Hello,
because the script searches for the nearest point for each point

you can try this version of python code

import sys
import clr
import itertools
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)


def customIntersectAll(*args):
	if sys.implementation.name == 'ironpython':
		for curveA, curveB in itertools.product(*args):
			interResultArray = clr.Reference[IntersectionResultArray]()
			compareResult = curveA.Intersect(curveB, interResultArray)
			if compareResult == SetComparisonResult.Overlap:
				yield(interResultArray.Value[0].XYZPoint )
	else:
		for curveA, curveB in itertools.product(*args):
			outInterResultArrayout = IntersectionResultArray()
			compareResult, interResultArray = curveA.Intersect(curveB, outInterResultArrayout) 
			if compareResult == SetComparisonResult.Overlap:
				yield(interResultArray[0].XYZPoint)


def isParallelOverlap(c1, c2):
	v1 = c1.Direction.Normalize()
	v2 = c2.Direction.Normalize()
	check1 = c1.Intersect(c2) == SetComparisonResult.Equal
	check2 = v1.CrossProduct(v2).IsAlmostEqualTo(XYZ(0, 0, 0))
	return all([check1, check2]), v1
	
def allVectorsAreParallel(lstPairBool_Vect):
	"""
	check if all vector are parallel
	input Parameter -> [[bool, vector], [bool, vector], ...]
	"""
	lstVect = [v[1] for v in lstPairBool_Vect if v[0]]
	v1 = lstVect.pop(0)
	for v2 in lstVect:
		if not v1.CrossProduct(v2).IsAlmostEqualTo(XYZ(0, 0, 0)):
			return False
	return True

def sortPoint(lstPts, orderPts = []):
	"""
	sort points by intersection/overlap curves
	"""
	global lstCurveA
	if len(orderPts) == 0:
		orderPts.append(lstPts.pop(0))
	# 1st pass  
	lstPts.sort(key = lambda x : x.DistanceTo(orderPts[-1]), reverse = True)
	for idx, pta in enumerate(lstPts):
		lineAB = DB.Line.CreateBound(pta, orderPts[-1])
		lstPairBool_Vect = [isParallelOverlap(c, lineAB) for c in lstCurveA]
		if sum(c[0] for c in lstPairBool_Vect) == 1:
			orderPts.append(lstPts.pop(idx))
			lineAB.Dispose()
			return sortPoint(lstPts, orderPts)
	# 2nd pass  		
	for idx, pta in enumerate(lstPts):
		lineAB = DB.Line.CreateBound(pta, orderPts[-1])
		lstPairBool_Vect = [isParallelOverlap(c, lineAB) for c in lstCurveA]
		if sum(c[0] for c in lstPairBool_Vect)  > 1 and allVectorsAreParallel(lstPairBool_Vect):
			orderPts.append(lstPts.pop(idx))
			lineAB.Dispose()
			return sortPoint(lstPts, orderPts)

	return [x.ToPoint() for x in orderPts]
	
def toList(curves):
	curves = curves if hasattr(curves, '__iter__') else [curves]
	if isinstance(curves[0], DS.Curve):
		return [x.ToRevitType() for x in curves]
	elif hasattr(curves[0],  "Curve"):
		return [x.Curve for x in curves]
	elif hasattr(curves[0],  "Location"):
		return [x.Location.Curve for x in curves]		
	else: return []

lstCurveA = toList(UnwrapElement(IN[0]))
if lstCurveA:
	lstCurveB = lstCurveA[:]
	outPoint = []
	
	for pt in customIntersectAll( lstCurveA, lstCurveB):
		if all(not pt.IsAlmostEqualTo(x) for x in outPoint):
			outPoint.append(pt)
	#			
	OUT = sortPoint(outPoint)	
5 Likes