(Python) The goal of the code was to create an extension that tags all rooms from linked models. This is as far as I got:
def tagViewsinLinkedElements():
# getLinkedInstances returns a dict: {"Name": string, "Document" : Document, "Instance: RevitLinkInstance}
# getElementsfromLinkedInstances returns a list of [Element]
# roomcat = BuiltInCategory.OST_Rooms
# getViewPlans returns all of Category ViewPlan
# get CoordinatesforLinkedElements returns [int, int, int] representing xyz coords, with transformation
linkedinst = getLinkedInstances()[0]
elements = getElementsfromLinkedInstance(linkedinst["Document"], roomcat)
viewplans = getViewPlans()
elementlocations = [getCoordinatesforLinkedElements(linkedinst["Instance"], el) for el in elements]
t = Transaction(doc, "Tag Rooms in Linked Models")
t.Start()
for view in viewplans:
for i in range(len(elements)):
if isinstance(view, (ViewSection, ViewPlan)):
el = elements[i]
r_center = elementlocations[i]
rtag = doc.Create.NewRoomTag(
LinkElementId(el.Id),
UV(r_center[0], r_center[1]),
view.Id
)
t.Commit()
As far as I am aware, the code between the Transform is the issue. The Room Tags are being created, as it is found in a FilteredElementCollector in RPS, but it is not visible in the main document.
I have also tried transforming the points according to the origin of the linked model within the primary model, as suggested by other forum posts, but this hasn't seem to be of much use either.
Do you have any other suggestions?
Tested the code in RevitPythonShell, Revit Version 2021
Code I changed previously (Transform coordinates by the linked document coordinates):
# Converts an element into a list of XYZ Coords
def convertElementtoLoc (element):
strloc = element.Location.Point.ToString()
return [float(st) for st in list(strloc[1:-1].Split(","))]
# Returns the coordinates off where the origin of the linked isntance is located
def linkedInstOrigin (linkedinst):
orig = linkedinst.GetTotalTransform().Origin
return [orig.X, orig.Y, orig.Z]
# Returns the coordinates of an element from a linked view in relation to the current document
def getCoordinatesforLinkedElements(linkedinst, element):
return [val1 + val2 for val1, val2 in zip(linkedInstOrigin(linkedinst), convertElementtoLoc(element))]
Have you explored the optimal workflow and best practices to achieve your goal manually through the end user interface and ensured that that works as you expect? If it does not work in the UI, you can struggle as hard as you will in the API, but the result will probably not be better. It is normally a lot more effective to discover and resolve all problems manually in the UI before struggling with the programming side of things.
We've considered several options, including a working Dynamo Script. The issue being, some of the documents could have several linked revit models with way too many views to individually click on each. Since its a function we use regularly, it would be handy to have a button that does this. The end goal too is to add an interface that could select views and revit models too.
If you already have a working Dynamo script, it can be converted to a Revit API add-in and includes all the code you need.
That was the plan, but apart from setting the tag family type, the code is almost identical. Not sure where to go from here.
Try getting the transform from the linked instance:
transform = Linkinstance.GetTransform()
Then use the 'OfPoint' method: Transform Members (revitapidocs.com)
point = transform.OfPoint(LinkedRoom.Location.Point)
tagPoint = UV(point.X, point.Y)
Also, use this constructor to get the linked element id: LinkElementId Class (revitapidocs.com)
roomId = LinkElementId(Linkinstance.Id, LinkedRoom.Id)
NewTag = doc.Create.NewRoomTag(roomId, tagPoint, View.Id)
Can't find what you're looking for? Ask the community or share your knowledge.