Elements in Room vs Elements in Space

Hi everyone!

I need to identify which element is situated in which space. I have previously done something similar using an archilab node called Elements in Room and I thought I could use the same approach but use an Elements in Space node instead. But either it is not that simple or I am doing something wrong :slight_smile:

I created a simple example with just a couple of rooms and defined Rooms and Spaces inside each of these four rooms (so four Rooms and four Spaces). I am using two simple furniture families for this example which I also placed inside some of these rooms.

When using an Elements in Room node I get the correct result - three sublists containing only these objects that are inside that particular room plus one empty list.
However when using an Elements in Space node I also get a list with four sublists, but all of the sublist, even the one that should be empty, are identical to one another and each sublist contains all the furniture objects not only the ones inside that space.

Why are the results from Elements in Space node different from the results from Elements in Room node? What should I do in order to get the correct results using Elements in Space node? I would appreciated all the help :slight_smile:

Edit: Attached are the sample Revit project file and the dynamo file.

Elements in Room vs in Space.dyn (21.0 KB)

Elements in Room vs in Space.rvt (5.5 MB)

Hello,

Did check in your families, whether your familiylocation point is activ? is that the root-cause for the intiverence?
2022-04-12_08h38_05

Sorry, but I am not quite sure what you mean. I attached my sample Revit project file as well as the dynamo file. Could you please have a look? :slight_smile:

Elements in Room vs in Space.dyn (21.0 KB)

Elements in Room vs in Space.rvt (5.5 MB)

Its true in Space furniture got muliplied… :confused:

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

# This code is based on Family.InRoom node originally created
# by Peter Kompolschek and published on Dynamo blog. Big thanks 
# to Peter for sharing his work so graciously.

import clr
import sys
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

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

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

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

def TryGetSpace(family, phase):
	try:
		inSpace = family.Space[phase]
	except:
		inSpace = None
		pass
	return inSpace

def FamiliesInSpace(_space, _families, _doc):
	outList = []
	for family in _families:
		location = family.Location
		if type(location) == LocationPoint:
			pt = location.Point
		else:
			pt = location.Curve.Evaluate(0.5, True)
		if _space.IsPointInSpace(pt):
			outList.append(family)
		else:
			for phase in _doc.Phases:
				inSpace = TryGetSpace(family, phase)
				if inSpace != None and inSpace.ToDSType(True).Name == _space.ToDSType(True).Name:
					outList.append(family)
	return outList

try:
	errorReport = None
	families = []
	for i in IN[0]:
		families.append(UnwrapElement(i))
	
	spaces = []
	for i in IN[1]:
		if UnwrapElement(i).Area > 0:
			spaces.append(UnwrapElement(i))
	
	outData = [[] for i in range(len(spaces))]
	for index, space in enumerate(spaces):
		outData[index].extend(FamiliesInSpace(space, families, doc))
except:
	# if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
	OUT = outData
else:
	OUT = errorReport

Thats code in the node!

@Kkartsep try it with CPython:


Elements in Room vs in Space.dyn (26.6 KB)
@Konrad_K_Sobon @c.poupin any idea why this behviour?

Hello
the problem is that spaces have the same name
Try this version of “Elements in Space”


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

# This code is based on Family.InRoom node originally created
# by Peter Kompolschek and published on Dynamo blog. Big thanks 
# to Peter for sharing his work so graciously.
# modified by Cyril Poupin

import clr
import sys
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

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

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

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

def FamiliesInSpace(_space, _families, _doc):
	outList = []
	for family in _families:
		location = family.Location
		bbx_e = family.get_BoundingBox(None)
		checkSpace = next((family.get_Space(ph) for ph in _doc.Phases if family.GetPhaseStatus(ph.Id) == ElementOnPhaseStatus.New), None)
		if checkSpace is not None and _space.Id == checkSpace.Id:
			outList.append(family)
		else:
			pt = location.Point if type(location) == LocationPoint else ( bbx_e.Min + bbx_e.Max ) * 0.5
			if _space.IsPointInSpace(pt):
				outList.append(family)
	return outList

try:
	errorReport = None
	families = []
	for i in IN[0]:
		families.append(UnwrapElement(i))
	
	spaces = []
	for i in IN[1]:
		if UnwrapElement(i).Area > 0:
			spaces.append(UnwrapElement(i))
	
	outData = [[] for i in range(len(spaces))]
	for index, space in enumerate(spaces):
		outData[index].extend(FamiliesInSpace(space, families, doc))

except:
	# if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
	OUT = outData
else:
	OUT = errorReport
4 Likes

Thank you so much!

Hi Cyril,

Cannot this work for elements, such as pipes or ducts?

Regards,
Atharva Purohit

Hi,

You could use the Element ToSpace or Element ToRoom nodes from the Genius Loci package.
Please note that these nodes evaluates if the middle of linear elements is in the room/space. It won’t work with duct/pipe ends.

2 Likes

Hi Alban,
Thanks for responding.
First of all, i’m a fan of Genius Loci package!

Btw, I was just communicated that the need to compute for pipe/ducts/CTs are ruled out.
But the space model will be linked in every discipline model and just needs to be computed for families and equipments.
Will this workflow work for Linked model (Space model as linked)?

Regards,
ap

1 Like

Hi Atharva,

Yes it should work with linked spaces. As I explained before the custom node has its limitations.

1 Like

Hi Alban,

Not sure if i am doing something wrong here.

It is giving null for every element.
Can you point out my mistake?
i’m using bim360 models, is it also one limitations?

Regards,
ap

Extremely sorry to nudge again.
Can anyone help me out with this? I’m in dire need of it.

Regards,

1 Like

Hi @atharva.purohit466SX ,hope all good…i see you want to know where whitch space pipes belong to …these can be in multiplle spaces…just say;)

1 Like

Hi Soren!

Actually, I’ve different models for disciplines and then a separate space model.
When we link the space model in any of the discipline model, I want to compute that which element lies in which space from the linked model.
Now no need to compute for pipe and other general system families but only just about the loaded families like fixtures and equipments.
In the above screen shot, you can see, it seems not to be working, whereas according to me, i’m not able to find any mistake from my end.

Any help would be greatly appretiated.
Regards,
Atharva Purohit

Hi…this post is already solved…could you make a new topic with you dataset…just a snip and am sure someone can fix it :wink:

2 Likes