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)