I have been able to reproduce a problem and will be filing a bug for it. However, there is a workaround that you can use for now. I also don't believe that you want to take the approach that you're currently using of iterating through all of the occurrences. The reason for this is that more than one occurrence can reference the same component. For example if you have an assembly that has 40 instances of the same bolt, there will be a single component and 40 occurrences. The way you're building up the filename, it will be the same for each occurrence so you'll end up with one stl file because each save will overwrite the previous one, but it's a lot of wasted processing to save out 39 stl files that get overwritten.
A better approach is to get all of the components and write out each component. Something as simple as the code below should work, (but doesn't because of the problem described below).
def exportCompBodyAsSTL():
app = adsk.core.Application.get()
ui = app.userInterface
try:
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
exportMgr = design.exportManager
outDir = "c:/temp/fusion1"
for comp in design.allComponents:
for body in comp.bRepBodies:
fileName = outDir + "/" + comp.name.replace(" ","_" ) + body.name
# create stl exportOptions
stlExportOptions = exportMgr.createSTLExportOptions(body, fileName)
stlExportOptions.sendToPrintUtility = False
exportMgr.execute(stlExportOptions)
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
However, there's a problem with the createSTLExportOptions method that it expects the body to be in the context of the root component. In most cases the context does matter for the same reason I discussed above where you can have multiple instances of the body where the body exists in a component and the component can be referenced any number of times by an occurrence. It appears in the UI that the body exists multiple times, once in each occurrence, but it's really one body being referenced multiple times. The BRepBody object you're getting is a reference to the real body. In the API, the BRepBody object represents the real body in the component and also the body being displayed by the occurrence. This is referred to as a "proxy" object because the body doesn't really exist but the proxy BRepBody is representing the body as if it does exist. The proxy represents that body in the context of the root component. The createSTLExportOptions method is expecting the body to be in the context of the root component so any bodies not directly in the root need to be proxy bodies. It shouldn't have this requirement because it doesn't need any of the extra information that a proxy would have to write out the stl so it should work on any body regardless of its context.
I wrote a small sample that works around this by getting all of the components and then finds any occurrence that references the component and then uses that to create a proxy.
def exportCompBodyAsSTL2():
app = adsk.core.Application.get()
ui = app.userInterface
try:
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
root = design.rootComponent
exportMgr = design.exportManager
outDir = "c:/temp/fusion1"
for comp in design.allComponents:
if comp != root:
# Find any occurrence using this component.
occs = root.allOccurrencesByComponent(comp)
if occs.count > 0:
occ = occs.item(0)
for body in comp.bRepBodies:
if comp != root:
# Create a body proxy.
body = body.createForAssemblyContext(occ)
fileName = outDir + "/" + comp.name.replace(" ","_" ) + body.name
# create stl exportOptions
stlExportOptions = exportMgr.createSTLExportOptions(body, fileName)
stlExportOptions.sendToPrintUtility = False
exportMgr.execute(stlExportOptions)
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))