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)