I’m trying to get the doors from a linked curtain wall.
Previously when they weren’t in a linked file, I could use FamilyInstances.RetrieveNestedComponents
, but @john_pierson has kindly left us an error message that this doesn’t work with linked documents because it has to be able to iterate through the current document and this doesn’t work with links. I found the python on his GitHub (maybe C# would have a clue, but I haven’t found it yet) and tried to patch it for this scenario. Or maybe there’s another node I’m not aware of yet?
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
clr.ImportExtensions(Revit.Elements)
# Get the current Revit document
doc = DocumentManager.Instance.CurrentDBDocument
def GetNestedFamilies(fi, doc):
# list to hold all subcomponents
internalFamilies = []
internalFamilies.append(fi)
# list to hold nested elements
nestedList = []
# counter for internalFamilies list
flag = 0
# loop control
stopString = "keepGoing"
while stopString == "keepGoing":
# if flag != internalFamilies.Count:
if flag != len(internalFamilies):
# iterate through subcomponents
for subComponent in internalFamilies[flag].GetSubComponentIds():
# check if subcomponent is in linked doc
if subComponent.IsLinkedElementId(doc):
# get link instance for linked doc
revitLinkInstance = doc.GetElement(subComponent).GetLinkInstance()
# get unique IDs of all elements in linked doc
elementIds = revitLinkInstance.GetLinkedElementIds()
# get elements with specified IDs from active doc
elements = doc.GetElements(elementIds)
# use LINQ to filter elements and get doors nested inside linked wall
nestedDoors = [element for element in elements if element.Category.Name == "Doors" and element.Parent.Id == fi.Id]
# add nested doors to output list
nestedList.AddRange(nestedDoors)
else:
# get family instance for subcomponent
internalFamily = doc.GetElement(subComponent)
# enable further digging
internalFamilies.append(internalFamily)
# add to output list
nestedList.append(internalFamily.ToDSType(True))
# increment flag
flag += 1
stopString = "keepGoing"
else:
stopString = "stahp it"
return nestedList
def tolist(obj1):
if hasattr(obj1,"__iter__"): return obj1
else: return [obj1]
# Get the input family instance and linked document
familyInstances = tolist(UnwrapElement(IN[0]))
# familyInstance = UnwrapElement(IN[0])
linkedDocument = UnwrapElement(IN[1])
# Get the linked document object
linkedDoc = doc.GetElement(linkedDocument)
subLists = []
# iterate through the given instances
for fi in familyInstances:
subLists.append(GetNestedFamilies(fi, linkedDoc))
OUT = subLists