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: 

Is it possible to use text command within a script to run the meshbody cut command

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
yosef.ali.omar
469 Views, 4 Replies

Is it possible to use text command within a script to run the meshbody cut command

Hi 

I am trying to create a script that takes in a meshbody and use the plane cut command that is available in the UI. However I am very new to the F360 API and don't know the text command for this feature. I have went through some resources in the forum but couldn't find a list of text commands where this mesh body plane cut is available. 

 

can some one guide me into this realm, oh wise shamans show us the way 

4 REPLIES 4
Message 2 of 5

I am trying to run a automated command of the meshbodycut command avaliable in the UI 

I took this code from the forum 

 

def  _MeshPlaneCutCommand (
            self,
            mesh: adsk.fusion.MeshBody,
            plane: adsk.fusion.ConstructionPlane😞

            app: adsk.core.Application = adsk.core.Application.get ()
            ui: adsk.core.UserInterface = app.userInterface
            sels: adsk.core.Selections = ui.activeSelections

            sels.clear ()
            app.executeTextCommand ( u'Commands.Start MeshPlaneCutCommand' )

            app.executeTextCommand ( u'UI.EnableCommandInput MeshPlaneCutBodySel' )
            sels.add (mesh)

            app.executeTextCommand ( u'UI.EnableCommandInput MeshPlaneCutPlaneSel' )
            sels.add (plane)

            app.executeTextCommand ( u'Commands.SetString infoCutType MeshPlaneCutSplitBody' )
            app.executeTextCommand ( u'Commands.SetString infoFillType MeshPlaneCutFillNone' )

            app.executeTextCommand ( u'NuCommands.CommitCmd' )
 
 
however the command is simply not executing, I am creating a plane using API calls then using that plane in the 
function above, but it is not executing the cut, the plane gets created and all 
Message 3 of 5
kandennti
in reply to: yosef.ali.omar

Hi @yosef.ali.omar .

 

I believe all the command IDs, etc. were changed when the mesh function switched from preview function to official function.

We have corrected this so that it will still function in Ver 2.0.12392.

 

# Fusion360API Python script
# Author-kantoku
# Description-Split Mesh and convert to BRepBody

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

        if des.designType == adsk.fusion.DesignTypes.ParametricDesignType:
            query = _ui.messageBox(
                'Switch to direct mode.\nIs it OK?',
                'Need to switch to direct mode',
                adsk.core.MessageBoxButtonTypes.OKCancelButtonType,
                adsk.core.MessageBoxIconTypes.QuestionIconType)

            if query == adsk.core.DialogResults.DialogCancel:
                return
            else:
                des.designType = adsk.fusion.DesignTypes.DirectDesignType

        msg :str = 'Please select a mesh body!'
        selFiltter :str = 'MeshBodies'
        sel :adsk.core.Selection = selectEnt(msg ,selFiltter)
        if not sel: return
        mesh = sel.entity

        fact = Mesh2BRepFactry(mesh)
        bodies = fact.toBrep()

        _ui.messageBox(f'{len(bodies)} BRep body created')

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

def selectEnt(
    msg :str, 
    filtterStr :str
    ) -> adsk.core.Selection :

    try:
        sel = _ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None


class Mesh2BRepFactry:
    def __init__(self, mesh :adsk.fusion.MeshBody):
        self.mesh = mesh

    def toBrep(self, maxCount = 10000) -> list:
        comp :adsk.fusion.Component = self.mesh.parentComponent

        if maxCount > 10000:
            maxCount = 10000

        # split
        meshLst = self._MeshsSplit(self.mesh, maxCount)

        # toBrep
        return self._Mesh2BRepCommand(meshLst)


    def _Mesh2BRepCommand(
        self,
        meshLst :list) -> list:

        app :adsk.core.Application = adsk.core.Application.get()
        ui :adsk.core.UserInterface = app.userInterface
        sels :adsk.core.Selections = ui.activeSelections
        comp :adsk.fusion.Component = self.mesh.parentComponent
        exceptionLst = [b for b in comp.bRepBodies]

        for mesh in meshLst:
            sels.clear()
            sels.add(mesh)
            app.executeTextCommand(u'Commands.Start ParaMeshConvertCommand')
            app.executeTextCommand(u'NuCommands.CommitCmd')

            adsk.doEvents()
        
        return self._list_difference([b for b in comp.bRepBodies], exceptionLst)


    def _MeshsSplit(
        self,
        mesh :adsk.fusion.MeshBody,
        maxCount) -> list:

        comp :adsk.fusion.Component = self.mesh.parentComponent

        meshLst = [self.mesh]

        exceptionLst = [m for m in comp.meshBodies]
        exceptionLst.remove(self.mesh)

        global _app
        reOpeFG = False
        while True:
            for mesh in meshLst:
                _app.log(f'{mesh.name}:{mesh.displayMesh.triangleCount}')

                if maxCount < mesh.displayMesh.triangleCount:
                    tool :adsk.fusion.ConstructionPlane = self._getSplitPlane(mesh)
                    self._MeshPlaneCutCommand(mesh, tool)
                    tool.deleteMe()
                    reOpeFG = True

                adsk.doEvents()
            
            if reOpeFG:
                meshLst = self._list_difference([m for m in comp.meshBodies], exceptionLst)
                reOpeFG = False
            else:
                break
        
        return meshLst


    def  _MeshPlaneCutCommand(
        self,
        mesh: adsk.fusion.MeshBody,
        plane: adsk.fusion.ConstructionPlane):

        app: adsk.core.Application = adsk.core.Application.get()
        ui: adsk.core.UserInterface = app.userInterface
        sels: adsk.core.Selections = ui.activeSelections

        sels.clear()
        app.executeTextCommand(u'Commands.Start ParaMeshPlaneCutCommand')

        app.executeTextCommand(u'UI.EnableCommandInput infoBodyToModify')
        sels.add(mesh)

        app.executeTextCommand(u'UI.EnableCommandInput planeSelectionInfo')
        sels.add(plane)

        app.executeTextCommand(u'Commands.SetString infoCutType infoCutTypeSplitBody')
        app.executeTextCommand(u'Commands.SetString infoFillType infoFillTypeNoFill')

        app.executeTextCommand(u'NuCommands.CommitCmd')


    def _list_difference(self, list1, list2):
        result = list1.copy()
        for value in list2:
            if value in result:
                result.remove(value)

        return result


    def _getSplitPlane(
        self,
        mesh :adsk.fusion.MeshBody) -> adsk.fusion.ConstructionPlane:

        comp :adsk.fusion.Component = mesh.parentComponent

        pnts = [p for p in mesh.displayMesh.nodeCoordinates]
        bound = adsk.core.BoundingBox3D.create(pnts[0], pnts[1])
        for p in pnts[2:]:
            bound.expand(p)

        pntMin :adsk.core.Point3D = bound.minPoint
        pntMax :adsk.core.Point3D = bound.maxPoint

        pntMid = adsk.core.Point3D.create(
            (pntMin.x + pntMax.x) * 0.5,
            (pntMin.y + pntMax.y) * 0.5,
            (pntMin.z + pntMax.z) * 0.5)

        width = [abs(pntMax.x) + abs(pntMin.x), comp.xConstructionAxis]
        length = [abs(pntMax.y) + abs(pntMin.y), comp.yConstructionAxis]
        height = [abs(pntMax.z) + abs(pntMin.z), comp.zConstructionAxis]

        direction = max([width, length, height], key=(lambda x: x[0]))

        plane = adsk.core.Plane.create(pntMid, direction[1].geometry.direction)
        conPlanes :adsk.fusion.ConstructionPlanes = comp.constructionPlanes
        planeIpt :adsk.fusion.ConstructionPlaneInput = conPlanes.createInput()
        planeIpt.setByPlane(plane)

        return conPlanes.add(planeIpt)
Message 4 of 5
yosef.ali.omar
in reply to: kandennti

@kandennti 

Thank you very much, yes after editing the text command it works fine. However, how can one know the new text commands is there a document or a github page that details the text commands for features, I have already looked at the document prepared by you "Text Commands 2" but how about the text commands inside a feature like what happened with meshbodycutplane where the problem was the text commands to specify the mesh, plane, and cut type 

 

I apologize if my English is terrible 

Message 5 of 5
kandennti
in reply to: yosef.ali.omar

@yosef.ali.omar .

 

The method for obtaining a command list of text commands is described here.

https://github.com/kantoku-code/Fusion360_Small_Tools_for_Developers/tree/master/TextCommands 

Unfortunately, we also wrote a topic called "Use TextCommands" but it seems to have been removed.

 

You can use this add-in and save the list to a file by pressing this button.

https://github.com/kantoku-code/Fusion360_Small_Tools_for_Developers/tree/master/Developers_Small_To... 

1.png

 

 

 

This is basically how to invoke a command using the command ID.

    app: adsk.core.Application = adsk.core.Application.get()
    ui: adsk.core.UserInterface = app.userInterface

    cmdDef: adsk.core.CommandDefinition = ui.commandDefinitions.itemById('**Command_ID**')
    if cmdDef:
        cmdDef.execute()

However, this method calls the commands together at the end of the script, so they cannot be called at the required timing.

 

Therefore, the following method can be used to call the commands at the necessary timing.

    app: adsk.core.Application = adsk.core.Application.get()
    app.executeTextCommand(u'Commands.Start **Command_ID**')

 

For '**Command_ID**', if you turn on the add-in here and actually operate the GUI, it will output the command name and command ID to the text command window.

1.png

 

You can also check the '**Command_ID**' by clicking this button in the add-in.

https://github.com/AutodeskFusion360/Fusion360DevTools 

1.png

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