Convert All Selected Linked Elements to Parts

I’m able to select all of the elements in the link. How do I convert all of these elements to Parts? Python? I know nothing about Python as of now. Any help would be GREATLY appreciated!

Excuse me if I do not understand but what do you mean with “convert to parts”?

@David3 If you mean component surfaces, you first need to extract the geometry of the elements by using the Element.Geometry node before attempting to explode

Create parts will create parts from the layers or sub-components of selected elements.

Vikram-I don’t know think component surfaces is what I’m looking for. I could be wrong?

@David3 Parts won’t be possible in Dynamo OOTB, not sure if there might be a Python/API approach

What happens if you create the parts in the linked file? Can you see them in your file? I’m afraid that if they are not created in the linked file you should copy/control them to be able to modify them

Why do you want to convert parts in a linked file? As I understand, the advantage of manipulating parts is that you have more control over the way the layers of a component (wall, floor, etc.) are made or join with other parts/components. However, if you have those parts in a linked Revit file, you cannot manipulate them, you can only see them.

Can you explain more in detail why you want this? Perhaps there is a different solution for what you want.

Our workflow on this project is different than most. We’re working in C4R (collaboration for Revit) so have access to all building files. I work for a GC and we’re self performing all concert on the job. We’re still in design but are to a point that we can start breaking out the concrete into pours. We’ve created a file which we’re linking the design model into. I can create parts from the elements in the model which have a direct link to those items in the original model. With a long stretch of wall, for example, I can break those parts into our different pours. Right now, in order to create parts from the elements I have to tab through the link and select each of the elements I want to convert to a part. With Dynamo I can quickly select all elements in the link. What I can’t figure out how to do yet is to then convert that selection into Parts.

Parting out a linked file is, I believe, the original intention of the tool allowing GCs to divide the model for their own purposes study. I’ve also explored the idea for finishes since you can modify the material of the part in the host model. Interesting possibilities… made stronger if I could automate the Parting process.

im glad i came across this topic. We’ve been trying something like this too as a linked file in order to isolate any issues that come from making parts.

The steamnodes package provides nodes that allow you to select certain elements from a link, and another that allows you to create parts from a selected element.

However, we came to a halt when the create parts node did not accept elements from the link. It seemed like the create parts node was meant only for non-link elements. Im not sure if this is still the case, since i last played with this idea quite a while ago.

However, there is a method in the api for specifically creating parts from elements that belong to a link called CreateParts(Document, ICollection(LinkElementId)) that i hope can be used to batch create parts from a link.

Im currently doing some house cleaning for the new revit update, but ill post again after a bit of tinkering.

I did a quick test and it looks like this is working all right:

partsFromLink.dyn (3.1 KB)

import clr

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

clr.AddReference('System')
from System.Collections.Generic import List

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

#Preparing input from dynamo to revit
link = UnwrapElement(IN[0])
category = UnwrapElement(IN[1])
linkDoc = link.GetLinkDocument()

elements = FilteredElementCollector(linkDoc).OfCategoryId(category.Id).WhereElementIsNotElementType()

#Create a genereic list for the elements
eList = List[LinkElementId]()
for e in elements:
	eList.Add(LinkElementId(link.Id,e.Id))

#All actions that makes changes to the Revit database needs to be inside a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

createparts = PartUtils.CreateParts(doc, eList)

TransactionManager.Instance.TransactionTaskDone()

OUT = elements
1 Like

Oh wow look at that!
I was just having some trouble with the linkids

my python is almost non-existent so excuse my ignorance but your script seems to collect and acquire the linkids in one go. I would like to create a node that simply accepts a list of linked elements and create parts for them only.

If you had to filter the walls by type name, for example, how would you do it?
below is my attempt at modifying Julien Benoits(credits to him for the original script) MakePartsNode with your implementation of createparts for linked elements. and I am totally lost. Where are the parts stored? Why did you choose elements as the output?

#python nodes in dynamo 1.0
#proposed by Julien Benoit @jbenoit44 
#http://aecuandme.wordpress.com/
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

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

#feed IN[0] with elements
link = UnwrapElement(IN[1])
elements = []
#Ids = []
#Parts=[]
#IDS = List[LinkElementId]()

for i in IN[0]:
	elements.append(UnwrapElement(i))
	
eList = List[LinkElementId]()
for e in elements:
	eList.Add(LinkElementId(link.Id,e.Id))
	


# Start Transaction tt
TransactionManager.Instance.EnsureInTransaction(doc)

a=PartUtils.CreateParts(doc, eList)
doc.Regenerate()

# End Transaction
TransactionManager.Instance.TransactionTaskDone()

OUT = elements

It was just random for debugging purposes. I believe the CreateParts method returns null. If you need to return the parts, I think you have to use PartUtils.GetAssociatedParts()

Yes, the script would be even easier if you can get the elements from an IN-port. Just replace the filtered element collector with IN[1] or something similar. Here is a modified version of the script:

import clr

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

clr.AddReference('System')
from System.Collections.Generic import List

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

#Preparing input from dynamo to revit
link = UnwrapElement(IN[0])
elements = UnwrapElement(IN[1])

#Create a genereic list for the elements
eList = List[LinkElementId]()
for e in elements:
	eList.Add(LinkElementId(link.Id,e.Id))

#All actions that makes changes to the Revit database needs to be inside a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

createparts = PartUtils.CreateParts(doc, eList)
doc.Regenerate()
TransactionManager.Instance.TransactionTaskDone()

OUT = []

for id in eList:
	partIDs=PartUtils.GetAssociatedParts(doc, id, 0, 0)
	OUT.append(partIDs)

Check out the free addin! https://partslab.pcl.com/

3 Likes

thanks alot! i have a much better understanding now. :slight_smile:
However I tried to use your script with a filtered list of elements, and I get an error.

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed. 
Traceback (most recent call last):
  File "<string>", line 28, in <module>
AttributeError: 'List[object]' object has no attribute 'Id'

I was looking at the LinkElementID class, and im quite confused if I need to feed the doc or the instance. Actually Im just lost. Is it the way in which the input was generated from the other nodes that is causing the problem?

EDIT: nvm, I did what u did earlier and used select model element to feed the doc and it works perfectly!!! Im about to have some real fun with this and navisworks. thank you.

Tchunoo-What package is Get Documents node from?

Thank you for everyone’s help! I’ve yet to get something to work, but I’m excited as I am catching up on all of the responses!

@Einar_Raknes I downloaded the graph and I’m getting the following error when trying to run:

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 27, in
TypeError: iteration over non-sequence of type Category

I’m not sure where to start?

Its from the archilab_grimshaw package. This topic was something I really enjoyed playing with awhile ago and forgot. Im so glad I came across your post and found answers thanks to @Einar_Raknes .

Odd…I opened an ran on a different model and it worked!

I’ll have to take a closer look as to why the other file failed. Might be because it is hosted on A360?