STL Export: Are body exports component and not occurrence based?

STL Export: Are body exports component and not occurrence based?

lichtzeichenanlage
Advisor Advisor
1,501 Views
8 Replies
Message 1 of 9

STL Export: Are body exports component and not occurrence based?

lichtzeichenanlage
Advisor
Advisor
  • The standard Fusion 360 STL export (UI not API) can export bodies in components by keeping the position created by a joint. So in theory it should work, but the UI creates a number of duplicates and useless files.
  • The API STL export keeps position in exports of bodies in the root component regardless if they where moved around.
  • The API STL export fails to export bodies in an occurrence of an component, because it always uses the original occurrence.

Are there other solutions which retain the positions in the exports besides switching off and on more ore less all light bulbs (dirty hack)? Am I making a mistake?

0 Likes
Accepted solutions (1)
1,502 Views
8 Replies
Replies (8)
Message 2 of 9

lichtzeichenanlage
Advisor
Advisor

Any hint?

0 Likes
Message 3 of 9

kandennti
Mentor
Mentor

Hi @lichtzeichenanlage .

 

I noticed a few months ago.
If you use the copy method of TemporaryBRepManager Object, you can get the body as seen from the root component.
It is possible even in deep occurrences.
 
I haven't gotten a lot of confirmation, but I made a simple sample.
#Fusion360API Python script
import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        des :adsk.fusion.Design = _app.activeProduct
        root :adsk.fusion.Component = des.rootComponent

        # get occ body
        occ :adsk.fusion.Occurrence = root.allOccurrences[0]
        body :adsk.fusion.BRepBody = occ.bRepBodies[0]

        # get clone body
        tmpBrepMng = adsk.fusion.TemporaryBRepManager.get()
        cloneBrep = tmpBrepMng.copy(body)

        # create export Doc - DirectDesign
        fusionDocType = adsk.core.DocumentTypes.FusionDesignDocumentType
        expDoc :adsk.fusion.FusionDocument = _app.documents.add(fusionDocType)
        expDes :adsk.fusion.Design = expDoc.design
        expDes.designType = adsk.fusion.DesignTypes.DirectDesignType

        # get export rootComponent
        expRoot :adsk.fusion.Component = expDes.rootComponent

        # paste clone body
        pasteCloneBody = expRoot.bRepBodies.add(cloneBrep)

        # export stl
        exportPath = r'C:\temp\hoge.stl'

        exportMgr = des.exportManager
        
        # error
        # stlOpts = exportMgr.createSTLExportOptions(cloneBrep, exportPath) 

        # File cannot be created with ParametricDesign
        # stlOpts = exportMgr.createSTLExportOptions(pasteCloneBody, exportPath)

        # Both ParametricDesign and DirectDesign are OK
        stlOpts = exportMgr.createSTLExportOptions(expRoot.bRepBodies[0], exportPath)

        exportMgr.execute(stlOpts)

        # remove export Doc
        expDoc.close(False)

        # finish
        _ui.messageBox('Exported the STL file.\n' + exportPath)

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

0 Likes
Message 4 of 9

lichtzeichenanlage
Advisor
Advisor

Thanks for this interesting approach. I have to check this. 

0 Likes
Message 5 of 9

lichtzeichenanlage
Advisor
Advisor

Exporting occurrences instead of bodies doesn't solve the problem either...

0 Likes
Message 6 of 9

kandennti
Mentor
Mentor
Accepted solution

I may not understand correctly.
Do you want this kind of processing?

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback
import os, re

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        des :adsk.fusion.Design = _app.activeProduct
        root :adsk.fusion.Component = des.rootComponent

        showBodies = []
        body = adsk.fusion.BRepBody.cast(None)
        if root.isBodiesFolderLightBulbOn:
            lst = [body for body in root.bRepBodies if body.isLightBulbOn]
            if len(lst) > 0:
                showBodies.append(['root', lst])
        
        occ = adsk.fusion.Occurrence.cast(None)
        for occ in root.allOccurrences:
            if not occ.isLightBulbOn: continue
            if not occ.component.isBodiesFolderLightBulbOn: continue

            lst = [body for body in occ.bRepBodies if body.isLightBulbOn]
            if len(lst) > 0:
                showBodies.append([occ.name, lst])

        # get clone body
        tmpBrepMng = adsk.fusion.TemporaryBRepManager.get()
        tmpBodies = []
        for name,bodies in showBodies:
            lst = [tmpBrepMng.copy(body) for body in bodies]
            if len(lst) > 0:
                tmpBodies.append([name, lst])

        # create export Doc - DirectDesign
        fusionDocType = adsk.core.DocumentTypes.FusionDesignDocumentType
        expDoc :adsk.fusion.FusionDocument = _app.documents.add(fusionDocType)
        expDes :adsk.fusion.Design = expDoc.design
        expDes.designType = adsk.fusion.DesignTypes.DirectDesignType

        # get export rootComponent
        expRoot :adsk.fusion.Component = expDes.rootComponent

        # paste clone body
        mat0 = adsk.core.Matrix3D.create()
        for name,bodies in tmpBodies:
            occ = expRoot.occurrences.addNewComponent(mat0)
            comp = occ.component
            comp.name = name
            for body in bodies:
                comp.bRepBodies.add(body)

        # export stl
        exportFolder = r'C:\temp'

        exportMgr = des.exportManager
        for occ in expRoot.allOccurrences:
            expName = re.sub(r'[\\|/|:|?|.|"|<|>|\|]', '-', occ.name)
            expPath = os.path.join(exportFolder, '{}.stl'.format(expName))
            stlOpts = exportMgr.createSTLExportOptions(occ, expPath)
            exportMgr.execute(stlOpts)

        # remove export Doc
        expDoc.close(False)

        # finish
        _ui.messageBox('Exported the STL file.\n' + exportFolder)

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes
Message 7 of 9

lichtzeichenanlage
Advisor
Advisor

@kandennti: Thanks for your reply and all the effort. I tried some different stuff first, because I had the hope to somehow get the data from the assembled data (e.g. using body.createForAssemblyContext(occurrence) but it didn't worked out. I some had the hope to do the trick without creating a 2nd document.

I just tried your script (It's a script, right?) but I'm always getting this error:

 

10-06-2020 17-23-48.png

 

Any idea why?

0 Likes
Message 8 of 9

kandennti
Mentor
Mentor

It's a script, as mentioned in the comment at the beginning of the code.

 

The error part is just creating a new document.
Was it executed as is?
Does this code alone cause an error?

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface

        fusionDocType = adsk.core.DocumentTypes.FusionDesignDocumentType
        expDoc :adsk.fusion.FusionDocument = _app.documents.add(fusionDocType)
    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes
Message 9 of 9

lichtzeichenanlage
Advisor
Advisor

Thanks for all the effort. It looks like my installation was broken. After a clean installation it works without any problems.

It feels still a bit odd that wie can't export the occurrences but this kind of workaround should do the job. And don't get me wrong: I don't want to downgrade the solution. 

0 Likes