Create Instances of linked Revit model on specified locations

Hello!
I want to create instances of a linked model on several points. I have my points and the linked model, but i need help creating new instances of the model on each point. Is there a node or a function that does what i want?
Any help is appreciated!

Hi @magnus
MEPover has a node called Copy element to location. Try using that.

thanks for quick reply.
that node does not do anything. it just returns zero

im thinking that it would be something similar to .create.PlaceGroup, but for linked model.
Or maybe something similar to the nodes for creating and placing a familyinstance.
However i can’t find anything.

I think I have found the correct function in Revit API Docs, but i’m not sure how to implement it.
This is the function in C#:

public static RevitLinkInstance Create(
	Document document,
	ElementId revitLinkTypeId
)

With an example:

public void CreateLinkInstances(Document doc, ElementId linkTypeId)
{
// Create revit link instance at origin
RevitLinkInstance.Create(doc, linkTypeId);
RevitLinkInstance instance2 = RevitLinkInstance.Create(doc, linkTypeId);
Location location = instance2.Location;
// Create a second instance of the link and offset it by 100 feet.
location.Move(new XYZ(0, -100, 0));
}

This is how i’ve started:

doc = DocumentManager.Instance.CurrentDBDocument
link = IN[0][0]
inst = IN[0][1]
location = IN[1]
instance = UnwrapElement(inst)
uLink = UnwrapElement(link)
path = instance.GetLinkDocument().PathName
uLink.Create(doc,path,location)

I don’t know if i am at the right track, i suspect that the third input is not a location, but currently i have an error with the second input that says “TypeError: expected ModelPath, got str”

I am eternally grateful if someone could:

  1. explain that TypeError
  2. Tell me if i am on the right track

Edit:
So i figured out how to create a new instance at origin, now i need to place it where i want to

link = IN[0][0]
inst = IN[0][1]
location = IN[1]
instance = UnwrapElement(inst)
uLink = UnwrapElement(link)
id=uLink.Id

TransactionManager.Instance.EnsureInTransaction(doc)

RevitLinkInstance.Create(doc,id,ImportPlacement.Origin)

TransactionManager.Instance.TransactionTaskDone()

I am getting close, it’s not entirely stable, but it works ok
The last thing that i am missing, is the ability to rotate the linked instances.
I was hoping ElementTransformUtils.RotateElement would do the trick, but it does not do anything.
Is there an easy way to rotate the linked instances?
Thanks a lot!

doc = DocumentManager.Instance.CurrentDBDocument
link = IN[0][0]
location = IN[1]
uLink = UnwrapElement(link)
id=uLink.Id
xyz = location.ToXyz()

TransactionManager.Instance.EnsureInTransaction(doc)

newInstance = RevitLinkInstance.Create(doc,id,ImportPlacement.Origin)
loc = newInstance.Location
new2 = loc.Move(xyz)

#Rotate instance:
axis = Line.CreateBound(xyz, XYZ(location.X,location.Y,location.Z +1))
ElementTransformUtils.RotateElement(doc,uLink.Id,axis,math.pi)

TransactionManager.Instance.TransactionTaskDone()

Hi @magnus,

I am having the same situation and i am trying to place , rotate the links in multiple points , it would be so helpful for my if you can help in this matter .

The problem is simply you are rotating the linked element using the revitLinkTypeId
You need to use the placed instance id

Simply change the following :
From
ElementTransformUtils.RotateElement(doc,uLink.Id,axis,math.pi)

To
ElementTransformUtils.RotateElement(doc,newInstance.Id,axis,math.pi)

Also you need to use the X and Y and Z from the converted XYZ, not from the location input
So change the following too :
From
axis = Line.CreateBound(xyz, XYZ(location.X,location.Y,location.Z +1))

To
axis = Line.CreateBound(xyz, XYZ(xyz.X,xyz.Y,xyz.Z +1))

As for multiple inputs of locations and rotations :

doc = DocumentManager.Instance.CurrentDBDocument
link = IN[0]
location = IN[1]
rotations = IN[2]
uLink = UnwrapElement(link)
id=uLink.Id
xyz = []
result = []

for e in location:
	xyz.append(e.ToXyz())
	
TransactionManager.Instance.EnsureInTransaction(doc)


for eachpoint in xyz:
	newInstance = RevitLinkInstance.Create(doc,id,ImportPlacement.Origin)
	loc = newInstance.Location
	new2 = loc.Move(eachpoint)
	result.append(newInstance)
	instanceid = newInstance.Id
	axis = Line.CreateBound(eachpoint, XYZ(eachpoint.X,eachpoint.Y,eachpoint.Z +1))
	ElementTransformUtils.RotateElement(doc,instanceid,axis,rotations[xyz.index(eachpoint)]*math.pi/180)

TransactionManager.Instance.TransactionTaskDone()

OUT = result

Hope that help

1 Like

Hi all, I have recently begun writing a script that amongst other things is trying to create multiple instances of revit links. Unfortunately it’s falling a little flat, and the python code blocks developed here are not working for me.

If someone could upload a node that creates an instance of a revit link/links from the id input that would be awesome.

Cheers!!!

I would like to do the same, but still not found any solution.
We are working on a large masterplan in which we are placing mass families. After finishing with masses we would like to place linked models (typical buildings) on the same location of the masses.
That would be an effective workflow, because placing masses instead of links is extremely faster; furthermore, mass families can be hosted by the topography, so there’s no need to adjust the elevation manually.
I just tried @Karam_Baki’s python node, but I got some problems with the first line.

Can someone help? Thank you.

2019-09-15%2018_18_02-Dynamo

Ok, I just found out that I had to import the RevitServices module. I just added the following lines at the beginning:

import clr

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

Anyway, I’m still having some other problems to make it work, as you can see from the image below:

2019-09-15%2019_19_41-Dynamo

Hey @Cristiano,

By the looks of it, you’re missing more imports to get that python script to work.

Try this:

import clr

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

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

#Import ToDSType(bool) extensions method
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

#Reference the active Document and application
doc = DocumentManager.Instance.CurrentDBDocument
2 Likes

Hello @Cristiano

Sorry, I posted the script without the services.
Regarding to that workflow, it’s actually nice.

Please allow me to suggest a more flexible workflow,
First install Synthesize Toolkit Package, and navigate to the extra folder.
You will see for links :
Links.K-Array With Curves Selection.dyn

Also for groups :
Groups.K-Array With Curves Selection.dyn

Those contains the following workflow in youtube video but applied for links and groups


This might help you in some other cases or in your own case for complex arraying.

You can see the python scripts and the nodes of the above dyn files.
The node for links is called : Revit Links Batch Placement
The node for groups is called : Groups Batch Placement

But listen to me,
I would suggest the following :
Place an instance of the link, then create a model group of it.
You can change the origin point of the group easily.

Then use the K-Array or your own workflow by matching with points of your desire in your masses.

In this case, you will not have to modify the base point nor shared point nor even thinking of them because your origin would be from the group it self.

Everything in Synthesize Toolkit works with all dynamo versions starting from 1.3 and above up to 2.2

1 Like

Finally I got it.
I put a sequence of nodes for translation, rotation and mirroring.
For links rotation I used @Kulkul’s python script from here. I just made some changes to make it work with lists.

place links on mass locations.dyn (55.8 KB) place links on mass locations.dyn (55.8 KB)

Thanks @MartinSpence.
Thanks @Karam_Baki, your K-array tools are impressive!

getting an error in line 31 line object is not is not subscriptable.

nevermind got it