Recently there has been a question asked on the Dynamo forums about placing elements on linked hosts in Revit. After some digging it occurred that it is possible with some “reference stable representation” tinkering. Actually, the reference conversion process is similar as in the case of linked element dimensioning. It has been described in detail in an earlier post: http://lubim.co/2019/02/12/dimensioning-elements-from-linked-files-with-dynamo/
In this very case the task was to place a family instance on the bottom surface of the linked ceiling. Script presented below takes every host element provided in the input and finds its bottom face. Next a linked reference to the face is constructed. And that is the entire trick. After that we are able to create the family instance in the same way as it would be on a in-document host.
import clr clr.AddReference("RevitAPI") from Autodesk.Revit.DB import * clr.AddReference("RevitServices") import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Transactions import TransactionManager def parseLinkedReference(doc, linkedRef): reps = linkedRef.ConvertToStableRepresentation(doc).split(':') res = '' first=True for i, s in enumerate(reps): t = s if "RVTLINK" in s: if(i<len(reps)-1): if reps[i+1]=="0": t = "RVTLINK" else: t = "0:RVTLINK" else: t = "0:RVTLINK" if not first: res = res + ":" + t else: res = t first = False ref = Reference.ParseFromStableRepresentation(doc,res) return ref doc = DocumentManager.Instance.CurrentDBDocument family_type = UnwrapElement(IN) hosts = UnwrapElement(IN) linked_instance = UnwrapElement(IN) output =  TransactionManager.Instance.EnsureInTransaction(doc) for h in hosts: reference = HostObjectUtils.GetBottomFaces(h) linked_reference = reference.CreateLinkReference(linked_instance) parsed_ref = parseLinkedReference(doc,linked_reference) face = h.GetGeometryObjectFromReference(reference) bb = face.GetBoundingBox() centerUV = bb.Min + (bb.Max-bb.Min)/2 p = face.Evaluate(centerUV) inst = doc.Create.NewFamilyInstance(parsed_ref,p,XYZ(0,0,0),family_type) output.append(inst) TransactionManager.Instance.TransactionTaskDone() #Assign your output to the OUT variable. OUT = output