Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Python API - Export STL from bRepBody fails (InternalValidationError)

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
raju
1384 Views, 2 Replies

Python API - Export STL from bRepBody fails (InternalValidationError)

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

 

 

2 REPLIES 2
Message 2 of 3
ekinsb
in reply to: raju

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
Message 3 of 3
raju
in reply to: ekinsb

Works great! Thanks. 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report