Description
When you import a sat file in Dynamo or even a cad file in Revit and then you want to grab those elements in Dynamo, you usually have to make a custom selection. Since this may be a burden, there are a set of nodes that can be implemented to ease that process.
One of them I called SepparateCurvesByDistance and it’s purpose is to make groups out of sets of selection lines from Revit or other environments.
The initial list contains all the curves in one set and the result is multiple sets with connected curves:
Solution
The implementation is below (not the most optimal since i made it when I was at the beginning of learning python and Dynamo, but it works)
import clr clr.AddReference('ProtoGeometry') from Autodesk.DesignScript.Geometry import * import re #The inputs to this node will be stored as a list in the IN variable. dataEnteringNode = IN class utils: ul = []; def __init__(self): self.ul = []; def isIterable(self, unit): t1 = t2 = False; if(isinstance(unit, (tuple, set, list, dict))): t1 = True; if(hasattr(unit, "__iter__")): iterstr = str(unit.__iter__()); if(re.search("System.Array", iterstr)): t2 = True; return (t1 or t2); def UnwrapList(self, list): self.ul = []; if(self.isIterable(list)): self.UnwrapL(list); return self.ul; else: return list; def UnwrapL(self, unit): if(self.isIterable(unit)): for item in unit: self.UnwrapL(item); else: self.ul.append(unit); ut = utils(); allnewlines = []; def sortLines(lines, maxdist): newSet = []; if(not ut.isIterable(lines)): return lines; else: lines = ut.UnwrapList(lines); idx = 0; lenL = len(lines); restarted = False; while(idx < lenL): if(len(newSet) == 0): newSet.append([lines[0]]); allnewlines.append([lines[0]]); del lines[0]; lenL -= 1; continue; if(idx == 0): restarted = True; _line = lines[idx]; sp1 = _line.StartPoint; ep1 = _line.EndPoint; found = False; for idset in range(len(newSet)): if(found): break; set = newSet[idset]; for clid in range(len(set)): if(found): break; cline = set[clid]; sp2 = cline.StartPoint; ep2 = cline.EndPoint; #checking if we have a match in the newSet if(sp1.DistanceTo(sp2) <= maxdist): found = True; if(sp1.DistanceTo(ep2) <= maxdist): found = True; if(ep1.DistanceTo(sp2) <= maxdist): found = True; if(ep1.DistanceTo(ep2) <= maxdist): found = True; if(found): newSet[idset].append(_line); allnewlines.append(_line); restarted = False; del lines[idx]; #checking if currently idx is at the end of lines array if(idx == lenL - 1): idx = -1; else: idx -= 1; lenL -= 1; if( (idx == lenL - 1) and (restarted == True) ): if(len(lines) > 0): allnewlines.append([lines[0]]); newSet.append([lines[0]]); del lines[0]; idx = -1; lenL -= 1; if(len(lines) <= 0 or lenL <= 0): break; if(idx == lenL - 1): idx = -1; idx += 1; return [newSet, lines]; __curves = IN[0]; __maxDist = IN[1]; #Assign your output to the OUT variable OUT = sortLines(__curves, __maxDist);