Record RVT link position using python

Hi all,

I need to record the position of my revit links using python or any Dynamo node, like the image bellow:

Then I have to duplicate the positions and create the same number of buildings.

So, after all, I’ll have all my buildings matching name with positions
image

I tried to find any way to do this using Dynamo nodes, but I didn’t find any.

I tried to find a way to write a python script to solve this, but, as I’m not a programmer, I’m getting a bit confused with the translation from C# API methods, found on API’s documentation, to Python scripting.

I found out this method that may solve my issue, but I’m not understanding how to use it. It requires an instance of ISaveSharedCoordinatesCallback, and I have no idea of how to set this.
https://www.revitapidocs.com/2015/2bfb9cc1-5a29-a195-0892-92bef673ab66.htm

If someone knows how to use this method or any other method that halps me, I would be thank for good.

My graph:
image

By the way, I stated this python code:

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 *

#Get current document
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

#setting variables
linkins = UnwrapElement(IN[0])

salvos = []

#start transaction
TransactionManager.Instance.EnsureInTransaction(doc)

for link in linkins:
	linkDoc = link.GetLinkDocument()
	type = doc.GetElement(link.GetTypeId())
	opt = SaveModifiedLinksOptions.SaveLinks
	
	type.SavePositions(opt)
	
	salvos.append(type)
	
#end transaction
TransactionManager.Instance.TransactionTaskDone()


OUT = salvos

Hi @mayconrfreitas,

You need to create a class which inherits from the ISaveSharedCoordinatesCallback interface. This class should contain the definition (GetSaveModifiedLinksOption(self,RevitLinkType)) as specified in the interface methods. This takes an instance of this class and the RevitLinkType and you use this in the RevitLinkType.SavePositions() method. See the code below…

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 *

#Get current document
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

# Class inherited from ISaveSharedCoordinatesCallback interface...
class SaveSharedCoordinatesCallback (ISaveSharedCoordinatesCallback):
	def GetSaveModifiedLinksOption(self,revitLinkType):
		pass

#setting variables
linkins = FilteredElementCollector(doc).OfClass(RevitLinkInstance).ToElements()

salvos = []

#start transaction
TransactionManager.Instance.EnsureInTransaction(doc)

for link in linkins:
	linkDoc = link.GetLinkDocument()
	type = doc.GetElement(link.GetTypeId())
	opt = SaveModifiedLinksOptions.SaveLinks
	
	#Create instance of callback class	
	cBack = SaveSharedCoordinatesCallback
	# Use callback class GetSaveModifiedLinksOption method passing class instance and Revit Link Type...
	t = type.SavePositions(cBack.GetSaveModifiedLinksOption(cBack(),type))
	
	if t:	
		salvos.append(type)
	else:
		salvos.append(None)
	
#end transaction
TransactionManager.Instance.TransactionTaskDone()


OUT = salvos

Hope this helps…

Cheers,
Dan

2 Likes

Hi @Daniel_Woodcock1, thanks for you reply, but it didn’t work. It runned no errors, but my link instances kept not shared

Hi @mayconrfreitas,

I’m not sure this is possible with the API. I have been digging around about how to set the shared site or the RevitLinkInstance and saw this quite recent post on the Revit API Forums…

https://forums.autodesk.com/t5/revit-api-forum/how-to-set-quot-shared-site-quot-for-linked-revit-model/m-p/8637780#M37211

I’ve tried various things all to no avail…unless someone else knows of a way, I don’t think this is possible yet.

Cheers,
Dan