Hello I am trying to get the elements of a link by input list of Revit IDs as Integer number and input list of Revit link instances, so if I got a list of 10 IDs, I also got a list of 10 Revit link instances, so I am indicating the ID is located in the specific Revit link instance. I tried all the package nodes to do this task and they only worked if the Revit link instance of Document is a single item, but not a list. Tried Clockwork but I get null, I tried Archilab but says ID is invalid.
If list levels don’t solve the problem then you may have to write your own code in Python. You could use any of those custom nodes as a starting point (if their code is available) or you could start from scratch. It could also be that those nodes need the ElementId type and won’t convert integers.
well the beast mode would be get absolutely all elements of documents and ask which ID is same of my given list, but I hope I can avoid that
I meant to satisfy the above… if you can’t force the correct pairings with list structure and levels.
it worked if grouping IDs by Document and long lacing in the custom node, but I do not want to use a package node because they do not work in future
Ok, that’s a different ask. In that case you’ll definitely have to use python. Again, you can use those custom nodes as a starting point. You’ll just need to make it work for your specific list structure.
that is the question about in a nutsell, I need help to do it
You’ll have to show us what you have before we can answer how to fix it.
@ruben.romero Something like this?
I have posted this as a screenshot only, so you can work through the python step-by-step as you type up the code, to build an understanding of what the workflow is doing.
It is likely that you will be building further functionality based on this code, so as @Nick_Boyts has mentioned in other posts over the years Learn Python for Dynamo: The Dynamo Python Primer - #4 by Nick_Boyts , it is important to start small when introducing yourself to what python coding can do, review tutorials, search the forum and always ask when in need of assistance, as we are a community who like to help you help yourself.
WHen they stop working it’s usually because the underlaying APIs change; This means you will also have to update your python, but as you’re coding that it’ll be on you to maintain it, and because you’re not packaging it it’ll be on you to track down every .dyn using that Python and build the Revit 2023 version thereof…
The idea that avoiding packages will save you headaches is a fallacy; at best it makes it a bigger problem you’ll have to solve on another day.
No, I got the Element IDs and I want the Elements of the corresponding Links or Documents that also I know
dependency that someone creates a package updated which do not necessarily resolves the task, memory RAM a full of use and computer not resoponding and switches off it is the reality
hello @Ewan_Opie many thanks for sharing it. I tested it and I get a warning Type Error: expected Reference, got Int64. I am feeding the node with Revit Ids, not GUIDs.
hello @Nick_Boyts
I am taking as reference the node Element.ById of Clockwork package node to do this.
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
def ElementById(item, doc):
try:
return doc.GetElement(item).ToDSType(True)
except:
try:
return doc.GetElement(ElementId(item)).ToDSType(True)
except:
return None
items = UnwrapElement(IN[0])
inputdoc = UnwrapElement(IN[1])
if not inputdoc: doc = DocumentManager.Instance.CurrentDBDocument
elif inputdoc.GetType().ToString() == "Autodesk.Revit.DB.RevitLinkInstance": doc = inputdoc.GetLinkDocument()
elif inputdoc.GetType().ToString() == "Autodesk.Revit.DB.Document": doc = inputdoc
else: doc = DocumentManager.Instance.CurrentDBDocument
if isinstance(IN[0], list): OUT = [ElementById(x, doc) for x in items]
else: OUT = ElementById(items, doc)
@ruben.romero If you are feeding in Element IDs as Integers then you will need to include this conversation in the code.
But my previous comment will still apply, quite unlikely but still, that elements can exist within different models but have the same Id, so might be picked incorrectly.
That is why I provide the link associated to the ID because I already know it, I do not want script searches the Id in all links, just in the one indicated.
I tried to modify the script sample you provided but I do not understand the warning I got now, the modification is this element_GUIDs=ElementId(IN[1])
:
import clr
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import ElementId
doc=DocumentManager.Instance.CurrentDBDocument
elements=[]
links=[]
link_instances=UnwrapElement(IN[0])
element_GUIDs=ElementId(IN[1])
for e in element_GUIDs:
for li in link_instances:
linkDoc=li.GetLinkDocument()
if linkDoc is not None:
linkId=li.Id
el=linkDoc.GetElement(e)
if el is not None:
elements.append(el.ToDSType(True))
links.append(li)
break
OUT=elements, links
You have the code from the custom node. It takes an Element
and a Document
. You’re starting with the ElementId
and the LinkInstance
. All you have to do is translate your ElementId
to an Element
and your LinkInstance
to a Document
.
Edit: It looks like you’ve already done this in the above code, but you’re searching all instances for all IDs. You want to zip those two values together so that you use the existing ElementId, LinkInstance
pairs. You may also have to post the specific line that’s giving you that error as it’s not clear from looking at your code.
Nearly there @ruben.romero
Try typing up this section of code