Finding Joined elements, indirectly joined to eachother

The Get Joined Elements node in GeniusLoci and JoinedElements in Rhythm only return directly joined elements.

I am trying to write a python script to find all indirectly joined elements (eg. element 1 is joined to element 2, element 2 is joined to element 3 and 1, element 3 is joined to element 4 and 2 and element 4 is joined to element 3)

I tried to use recursion to work through all the elements and append them to a list if they are not already in it. once there are no more joined elements that are not in the list (base case) the recursive loop breaks.
at least that is how it is supposed to work.

this is as far as i have gotten:

import clr
import sys

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

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *

clr.AddReference('System')
from System.Collections.Generic import List

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

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument


#Preparing input from dynamo to revit
elements = UnwrapElement(IN[0])

def notInList(item, List):
	if item not in List:
		return True
	else:
		return False

def getJoin(element):
	global sublist
	#check if element is already in the sublist

	#to break an infinite loop between the first and the second element
	if (len(sublist) > 10):
		return
		sys.exit("too many loops") 
		
	elif (notInList(element, sublist)):
		sublist.append(element)
		jointed_icol = JoinGeometryUtils.GetJoinedElements(doc, element)
		jointed = []
		#getting elements out of the iCollection
		for i in jointed_icol:
			jointed.append(Document.GetElement(doc, i))
		
		#recursive function
		for i in jointed:
			getJoin(i)
	else:
		return

totallist = []

for i in elements:
	sublist = []
	getJoin(i)
	totallist.append(sublist)

OUT = totallist

It keeps looping between the first and second element, I build in a hardstop at a list length >10 so revit won’t crash.

can anyone spot what I did wrong?

1 Like

Hi @timhevel ,

The Springs Package has a node “GroupByDistance” to do exactly this but for Dynamo geometry. Maybe you could look into the internal Python code to see how they did it.

If I would adapt this to using JoinGeometryUtils.GetJoinedElements it would result in the same outcome as the two nodes I mentioned earlier, Which is not what im after. The buildin node Point.closest would be a closer match since that uses the outcome of the first loop as the starting point of the next to find the shortest path through the points. To stay in this analogy: my script keeps looping through points 1 and 2
(point 2 is closest to point 1, point 1 is closest to point 2, point 2 is closest to point 1 etc etc)

I suspect the problem is the list isn’t written to the global varialble “sublist” untill after the definitions are all finished and thus I’m essentially comparing to an empty list to determinine if the function should continue.

but i dont know how to fix it.

I fixed it by using the element id instead of the element itself, and later converted them back to elements.