もう3年ぐらい前のものですが、フォーラムに投げたスクリプトです。
こちらに投げたもので、偶に需要がありその都度探すのが大変なのでブログにも転載です。
https://forums.autodesk.com/t5/fusion-api-and-scripts/is-it-possible-to-use-text-command-within-a-script-to-run-the/m-p/10995389/highlight/true#M16058
メッシュ->BRep変換はメッシュの面数が10000枚を超えると警告が出てスクリプトが止まってしまう為、
一個のメッシュボディが10000枚以下になるまで分割し、メッシュ->BRep変換処理してます。
# 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)