Quarry multiple linked document along with active one to find instance of an element with its element Id

I am trying to create a script to quarry multiple linked documents [along with the active one] from an active document to find an instance of an element with its element Id. It will be the same as the built-in function “Element by Id” but it will also be able to quarry all the linked models along with the active docu. I have made some progress but I am still unable to run the iteration through all the linked docs.

import clr

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

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

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

id = ElementId(IN[0])
lnkdocs = []
linkedElement = []
c = 0
try:
	c = len(IN[1])
except:
	c = 1

if c > 1:
	for lnkdoc in (IN[1]):
		lnkdocs.append(lnkdoc)
else:
	lnkdocs.append(IN[1])

for lnkdoc in lnkdocs:
	linkedElement.Add(lnkdoc.GetElement(id).ToDSType(True))
	
OUT = linkedElement,lnkdocs
1 Like

I don’t have a solution, but how are you planning on dealing with conditions where the same element ID exists in two models?

Yes, that’s the same thing I was also thinking about. Up to this point I can think of a list output which will show all the elements [with same Id] along with the linked documents name. For starter getting first element as output and its linked document name is enough. I will deal with the rest later on.

From what I can tell you can’t query an element by either element id or LinkElementId without opening the document(s).

This may mean you have to not be in the main document, feed in a list of documents and a list of IDs, open each document, check the doc for the id and append the element to the list. This makes downstream uses a bit difficult. What is your intended use once you have these associations?

as @jacob.small mentioned, you can find the elements by opening each doc as a loop, feeding the ids.
If your intention is to mark out all such elements in one view of revit, get the location of that element in each link and draw a model curve like circle out of it and do a reload all at once.

Sorry for the late reply. My intention is to find an element [irrespective of linked or active document] with a specific element id and create a 3D view with a bounding box around it. When I share my Navis work clash report with my team, [as we work with multiple linked models] it gets hard for them to locate elements that are not in the active document or to understand which link it belongs to. So I am looking for an all-in-one option where we can put the element Id without worrying about the linked or active documents and locate it in the view. Example: The guy who is working on a Structural model if he needs to find an element that belongs to any MEP trade. And he doesn’t even know which trade it belongs to. The element id should take him to that particular element in his active document with a section box around it.

1 Like

A thought: it might be easier to pull the element’s bounding box in the Navisworks model and append to the report. This would likely be faster (no need to open every model when they run the tool) and it would ensure you have the right element (the element IDs can’t conflict in the Navis report).

Yes, that might work as well. Let me try it out, if the first thing does not work in that case I will either append the bounding box in the report or will try to place a pointer family on clash coordinates.

You guys were right regarding looping through the linked document being a bad idea I prepared a custom node out of it and now it’s working as expected. Here is the final script.

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

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

item = UnwrapElement(IN[0])
inputdoc = UnwrapElement(IN[1])

inputdoc.GetType().ToString() == "Autodesk.Revit.DB.Document" 
if inputdoc != 0:
	element=inputdoc.GetElement(ElementId(item)).ToDSType(True)
	
	OUT = element, inputdoc.Title
	
else:
	doc = DocumentManager.Instance.CurrentDBDocument
	element=doc.GetElement(ElementId(item)).ToDSType(True)
	
	OUT = elementinputdoc.Title