SepparateCurvesByDistance — Digitteck
SepparateCurvesByDistance
dotnet·9 April 2018·3 min read

SepparateCurvesByDistance

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 its 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 it was made at the beginning of learning Python and Dynamo, but it works):

python
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);

Tags

DynamoPythonRevit
digitteck

© 2026 Digitteck