Wall finishes on linked model

Hi,
Cannot get the linked elements from linked model by the following code…Got null for all values.
Does anyone have any idea?
linkedDoc.GetElement(sf.SpatialBoundaryElement.HostElementId)
seems does not work and return null.

import clr

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

#The inputs to this node will be stored as a list in the IN variables.
rooms = UnwrapElement(IN[0])
linkInstance = UnwrapElement(IN[1])
linkedDoc = linkInstance.GetLinkDocument()

options = SpatialElementBoundaryOptions()
options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish

calculator = SpatialElementGeometryCalculator(linkedDoc,options)
output = []

for r in rooms:
	try:
		results = calculator.CalculateSpatialElementGeometry(r)
		solid = results.GetGeometry()
		elements = []
		for f in solid.Faces:
			#faces.append(f)
			subfaces = results.GetBoundaryFaceInfo(f)
			for sf in subfaces:
				e = linkedDoc.GetElement(sf.SpatialBoundaryElement.HostElementId)
				elements.append(e)
		output.append(elements)
	except:
		output.append(None)	

#Assign your output to the OUT variable.
OUT = elements

Hello…here is a way with nodes…

3 Likes

hello,

Yours rooms are local “Spatial Element” (in current model) or they are in the linked model ?

4 Likes

Hi,
My rooms are in local model.
Walls which are bounding the rooms are from link.
Do I have to make a new SpatialElementBoundaryOptions for the link model also?

thanks! Let me try this also!

Here is an example (without input) to get linkedElement

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

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

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument


#The inputs to this node will be stored as a list in the IN variables.
#rooms = UnwrapElement(IN[0])
#linkInstance = UnwrapElement(IN[0])
#linkedDoc = linkInstance.GetLinkDocument()

local_room_spaces = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_MEPSpaces).WhereElementIsNotElementType().ToElements()

options = SpatialElementBoundaryOptions()
options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish

calculator = SpatialElementGeometryCalculator(doc,options)
output = {}

for r in local_room_spaces:
	if calculator.CanCalculateGeometry(r):
		try:
			results = calculator.CalculateSpatialElementGeometry(r)
			solid = results.GetGeometry()
		except:
			solid = None
		if solid is not None:
			elements = []
			filter_elementIds = [] # make a filter
			for f in solid.Faces:
				subfaces = results.GetBoundaryFaceInfo(f)
				for sf in subfaces:
					linkedinstance = doc.GetElement(sf.SpatialBoundaryElement.LinkInstanceId)
					if linkedinstance is not None:
						linkedDoc = linkedinstance.GetLinkDocument()
						# check if element is not already in elements
						if sf.SpatialBoundaryElement.LinkedElementId not in filter_elementIds:
							e = linkedDoc.GetElement(sf.SpatialBoundaryElement.LinkedElementId )
							elements.append(e)
							filter_elementIds.append(sf.SpatialBoundaryElement.LinkedElementId )
			output[r.Level.Name + "-" + Element.Name.GetValue(r) + "-" + r.Number] = elements
			solid.Dispose()

#Assign your output to the OUT variable.
OUT = output

variant to get linked Materials

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

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

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument


#The inputs to this node will be stored as a list in the IN variables.
#rooms = UnwrapElement(IN[0])
#linkInstance = UnwrapElement(IN[0])
#linkedDoc = linkInstance.GetLinkDocument()

local_room_spaces = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_MEPSpaces).WhereElementIsNotElementType().ToElements()

options = SpatialElementBoundaryOptions()
options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish

calculator = SpatialElementGeometryCalculator(doc,options)
output = {}

for r in local_room_spaces:
	if calculator.CanCalculateGeometry(r):
		try:
			results = calculator.CalculateSpatialElementGeometry(r)
			solid = results.GetGeometry()
		except:
			solid = None
		if solid is not None:
			mats = []
			filter_matIds = [] # make a filter
			for f in solid.Faces:
				subfaces = results.GetBoundaryFaceInfo(f)
				for sf in subfaces:
					linkedinstance = doc.GetElement(sf.SpatialBoundaryElement.LinkInstanceId)
					if linkedinstance is not None:
						linkedDoc = linkedinstance.GetLinkDocument()
						lnk_elem = linkedDoc.GetElement(sf.SpatialBoundaryElement.LinkedElementId )				
						boundingElement = sf.GetBoundingElementFace()
						materialId = boundingElement.MaterialElementId
						mat = linkedDoc.GetElement(materialId)	
						# check if material i not already in elements
						if materialId not in filter_matIds:
							mats.append(mat)
							filter_matIds.append(materialId)
			output[r.Level.Name + "-" + Element.Name.GetValue(r) + "-" + r.Number] = mats
			solid.Dispose()

#Assign your output to the OUT variable.
OUT = output
3 Likes

Thanks! I will try it!

sorry, got an empty list :frowning:
BuiltInCategory.OST_MEPSpaces ← I dont have this in my model

try

BuiltInCategory.OST_Rooms