Python API - Export STL from bRepBody fails (InternalValidationError)

Python API - Export STL from bRepBody fails (InternalValidationError)

Anonymous
Not applicable
1,782 Views
2 Replies
Message 1 of 3

Python API - Export STL from bRepBody fails (InternalValidationError)

Anonymous
Not applicable

Hi, 

   I'm writing a simple python script to walk through the component hierarchy and export each bRepBody as a separate STL as shown below

 

import adsk.core, adsk.fusion, traceback

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"
    
    # Get the root component of the active design.
    rootComp = design.rootComponent
    
    # Iterate over any bodies in the root component.
    for j in range(0, rootComp.bRepBodies.count):
        body = rootComp.bRepBodies.item(j)
    
        fileName = outDir + "/" + "root_" + body.name
        # create stl exportOptions
        stlExportOptions = exportMgr.createSTLExportOptions(body, fileName)
        stlExportOptions.sendToPrintUtility = False
        
        exportMgr.execute(stlExportOptions)
    
    # Iterate through all of the occurrences in the assembly.
    for i in range(0, rootComp.allOccurrences.count):
        occ = rootComp.allOccurrences.item(i)
        
        # Get the associated component.
        comp = occ.component
        
        for k in range(0,comp.bRepBodies.count):
            brbody = comp.bRepBodies.item(k)
            fileName = outDir + "/" + comp.name.replace(" ","_" ) + brbody.name
            # create stl exportOptions
            stlExportOptions = exportMgr.createSTLExportOptions(brbody,fileName)   # <--- HERE IT FAILS with InternalValidationError: bRet
            stlExportOptions.sendToPrintUtility = False
            
            exportMgr.execute(stlExportOptions)
                
except:
    if ui:
        ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

But the script fails in the line where "createSTLExportOptions" is called with an error message "InternalValidationError : bRet".

error.png

 

Any help is appreciated.

 

Thanks in advance,

 

Raju

 

 

0 Likes
Accepted solutions (1)
1,783 Views
2 Replies
Replies (2)
Message 2 of 3

ekinsb
Alumni
Alumni
Accepted solution

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()))

 

 


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
0 Likes
Message 3 of 3

Anonymous
Not applicable

Works great! Thanks. 

0 Likes