opening/exporting nested linked components
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I'm working on a plugin to export data about a given design, including stls of each component. This was simple enough to make, and works well... unless some of the components are linked. Exporting stls of linked components doesn't seem to work correctly, so I tried to work around it by opening the original document containing the linked part, and exporting it from there. This works well... unless the linked component is nested in another linked component, then I get the following error:
RuntimeError: 3 : Cannot get allDocumentReferences of a non-top-level document.
To work around that, I wrote a recursive function to find the highest level linked component above the one I want, activate it's doc, then repeat until I've directly opened the component I want and exported its stl from its own file. In theory. In practice, even when I'm referencing a linked component from a file in which it is a top level component, I still get the same error from above. At this point I'm at my wits end. I've posted the code below, if anyone can find my error I'd appreciate it greatly.
Thanks
# This takes a given occurence and outputs all of it's associated bodies as a single stl
def export_as_stl(occ, path, uuid, exportMgr, label):
if os.path.exists(path+"/design-package/payload/components/" + uuid) == False:
os.mkdir(path+"/design-package/payload/components/" + uuid)
os.mkdir(path+"/design-package/payload/components/" + uuid + "/models")
if occ.isReferencedComponent:
occ = open_linked_components(occ, occ, path, uuid, exportMgr, label)
else:
fileName = path + "/design-package/payload/components/" + uuid + "/models/" + label
stlExportOptions = exportMgr.createSTLExportOptions(occ, fileName)
stlExportOptions.sendToPrintUtility = False
exportMgr.execute(stlExportOptions)
# recursively open any linked components up the tree chain
def open_linked_components(current_occ, target_occ, path, uuid, exportMgr, label):
# get the relevant data to my current active doc
app: adsk.core.Application = adsk.core.Application.get()
des: adsk.fusion.Design = app.activeProduct
root: adsk.fusion.Component = des.rootComponent
ui = app.userInterface
ui.messageBox("context: "+root.name+"\ncurrent_occ: "+current_occ.name+"\ntarget_occ: "+target_occ.name)
# update current_occ to make sure it's pulling from the current root
current_occ = root.allOccurrences.itemByName(current_occ.name)
# find the parent of the current_occ
parent = current_occ.assemblyContext
if parent != None:
ui.messageBox("parent: "+parent.name)
else:
ui.messageBox("parent: None")
if parent != None and parent.isReferencedComponent:
# if the parent is a reference recurse up the tree with the parent as the current_occ
ui.messageBox("parent is a reference, time to recurse up the tree!")
if parent.component.id == root.id:
ui.messageBox("somehow the parent is the root component, but also a reference. What?")
if root.isReferencedComponent:
ui.messageBox("root is a reference. I'm ****ing lost")
raise "nothing makes sense"
else:
open_linked_components(root, target_occ, path, uuid, exportMgr, label)
else:
open_linked_components(parent, target_occ, path, uuid, exportMgr, label)
else:
ui.messageBox("Parent isn't a reference, time to recurse down!")
# if the parent isn't a reference, it's time to recurse down, opening the file of this top-level reference
# save the parent so I can get back where I came from
des: adsk.fusion.Design = app.activeProduct
p_doc = des.parentDocument
# open the source document for the referenced component, and activate the root
doc = current_occ.documentReference.referencedDocument
doc.activate()
app: adsk.core.Application = doc.parent
des: adsk.fusion.Design = app.activeProduct
root: adsk.fusion.Component = des.rootComponent
ui.messageBox("current_occ:"+root.id+", "+root.name + "\ntarget_occ:"+target_occ.component.id+", "+target_occ.name)
# check if the root is the target_occ
if root.id == target_occ.component.id:
# if it is, export the stl
# turn off subcomponents so we only get the stl for the one we're looking at
lightStateList = []
for subcomp in root.allOccurrences:
lightStateList.append((subcomp, subcomp.isLightBulbOn))
subcomp.isLightBulbOn = False
fileName = path + "/design-package/payload/components/" + uuid + "/models/" + label
stlExportOptions = exportMgr.createSTLExportOptions(current_occ, fileName)
stlExportOptions.sendToPrintUtility = False
exportMgr.execute(stlExportOptions)
# turn the subcomponents back on
restore_light_state(lightStateList)
else:
# in the context of the parent document, I reset to target_occ in both fields. This resets
# the search, so I'll recurse up the new tree in the new doc, just like I did the first
open_linked_components(target_occ, target_occ, path, uuid, exportMgr, label)
# once that's resolved, I close the document I just opened and reactivate it's parent to clean up after myself
doc.close(False)
p_doc.activate()