JoinGeometryUtils.JoinGeometry issue - Elements cannot be joined

Hi, guys! I am writing a script, meant to place walls by the contours of a room and join them after. My test files and the script itself can be downloaded from the following link: https://we.tl/t-jP0dfH5HQL

Here is the logic behind it:

  • create walls for every curve from a room boundary, change its core location, height, etc.
  • check for room bounding elements, belonging to a linked file. If found, their indices are removed from both lists - boundary and finishing walls (for the purpose of this example, the script is oversimplified - there are many other checks - columns in the interior of the room, columns and walls from linked files in the interior, filter out curtain walls, etc. )
  • finally, join the newly created walls with the existing ones - this is when the script fails

I found that “Element.JoinGeometry” node wouldn’t work in my case, which is why I have created a simple python script for the purpose. However, it seems like it would still not join the walls:

I have checked multiple times the Ids of the walls, just to make sure they are given in the proper order and they are.

Here is the code:

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

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

#The inputs to this node will be stored as a list in the IN variables.

list_a = UnwrapElement(IN[0])
list_b = UnwrapElement(IN[1])

doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)

output = []

for a,b in zip(list_a,list_b):
	try:
		JoinGeometryUtils.JoinGeometry(doc,a,b)
		output.append("OK")
	except Exception,e:
		output.append(str(e))


TransactionManager.Instance.TransactionTaskDone()

#Assign your output to the OUT variable.

OUT = output

Thanks in advance for any support on the issue, cheers!

Have you tried using the Element.JoinGeometry node from Dynamo for Revit 2021 and beyond?

Info here: https://github.com/DynamoDS/DynamoRevit/pull/2456

Hello @danail.momchilov
try this
Home2.dyn (65.1 KB)

I modified the last Python node and the node “Room.Boundaries” (a little bit) from @Konrad_K_Sobon

# Copyright(c) 2015, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net

# This node was an update to Wall.Boundaries node
# that can be found in Clockwork package. Thanks
# to Andreas Dieckmann for making the original one.
# modify by Cyril POUPIN

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

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

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

def Unwrap(item):
	return UnwrapElement(item)

def ProcessList(_func, _list):
    return map( lambda x: ProcessList(_func, x) if type(x)==list else _func(x), _list )

def GetRoomBoundary(doc, item, options):
	global calculator
	eList = []
	cList = []

	results = calculator.CalculateSpatialElementGeometry(item)
	for face in results.GetGeometry().Faces:
		for bface in results.GetBoundaryFaceInfo(face):
			if bface.SubfaceType == SubfaceType.Side: 
				# get Wall Element
				wallElem = doc.GetElement(bface.SpatialBoundaryElement.HostElementId)
				eList.append(wallElem)
				# get Curve from EdgeLoop
				arrArrayLoop  = face.EdgeLoops 
				lstCurve = [edge.AsCurve() for edge in arrArrayLoop[0]]
				# get horizontal curves
				lstCurveH = [[c, c.GetEndPoint(0).Z] for c in lstCurve if c.GetEndPoint(0).Z == c.GetEndPoint(1).Z] 
				lstCurveH.sort(key = lambda x : x[1])
				cList.append(lstCurveH[0][0].ToProtoType())	

	return [eList, cList]

if isinstance(IN[0], list):
	items = ProcessList(Unwrap, IN[0])
else:
	items = [Unwrap(IN[0])]

options = SpatialElementBoundaryOptions()

boundloc = AreaVolumeSettings.GetAreaVolumeSettings(doc).GetSpatialElementBoundaryLocation(SpatialElementType.Room)
options.SpatialElementBoundaryLocation = boundloc
calculator = SpatialElementGeometryCalculator(doc)

elementList = []
curveList = []

try:
	errorReport = None
	if isinstance(items, list):
		for item in items:
			elementList.append(GetRoomBoundary(doc, item, options)[0])
			curveList.append(GetRoomBoundary(doc, item, options)[1])
	else:
		elementList = GetRoomBoundary(doc, items, options)[0]
		curveList = GetRoomBoundary(doc, items, options)[1]
except:
	# if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

# Release calculator to avoid get the new finish walls  in result after this node
calculator.Dispose()
#Assign your output to the OUT variable
if errorReport == None:
	OUT = [elementList, curveList]
else:
	OUT = errorReport

Hi, Jacob. Yes, I have. It didn’t work

This partially works, thanks a lot! :slight_smile: However, I noticed now the lists of walls (Existing and new ones) are not in the correct order, as a result some of them are joined, while others are not. This also generates multiple warnings in the model. For a large - scale project, there would be thousands of them:

An update from me - I only used the Room.CoreBoundary node to get the boundary curves and that already narowed the warnings down to 1 (and it’s about two adjacent walls anyway, so needs investigating). The rest is the same as in your script:

I will easily take over from here, thx once again :wink:

1 Like