C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

複数のボディをカットする

ちょっとボリュームありそうだと思いつつ、こちらに挑戦しました。
Cutting multiple bodies with single tool body - Autodesk Community

ボディ(ソリッド)の結合の切り取りを大量のボディで行いたいようです。
本来の機能の場合は、

赤のターゲットボディは1個で、緑のツールボディは複数個指定が可能なのですが、
望んでいるのはその逆だと判断しました。

APIフォーラムに投げていますが、こちらでも転載しておきます。
(ネタが無いので)

# Fusion360API Python script

import traceback
import adsk
import adsk.core as core
import adsk.fusion as fusion
import sys

_app: core.Application = None
_ui: core.UserInterface = None
_handlers = []

CMD_INFO = {
    "id": "kantoku_cutting_multiple_bodies_test",
    "name": "cutting multiple bodies test",
    "tooltip": "cutting multiple bodies test"
}

_targetOccIpt: core.SelectionCommandInput = None
_toolBodyIpt: core.SelectionCommandInput = None

class MyCommandCreatedHandler(core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: core.CommandCreatedEventArgs):
        try:
            global _handlers
            cmd: core.Command = core.Command.cast(args.command)
            inputs: core.CommandInputs = cmd.commandInputs

            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

            onValidateInputs = MyValidateInputsHandler()
            cmd.validateInputs.add(onValidateInputs)
            _handlers.append(onValidateInputs)

            onExecutePreview = MyExecutePreviewHandler()
            cmd.executePreview.add(onExecutePreview)
            _handlers.append(onExecutePreview)

            global _targetOccIpt
            _targetOccIpt = inputs.addSelectionInput(
                "_targetOccIptId",
                "Occurrences",
                "Select Target Occcurrence"
            )
            _targetOccIpt.addSelectionFilter("Occurrences")
            _targetOccIpt.setSelectionLimits(1,)

            global _toolBodyIpt
            _toolBodyIpt = inputs.addSelectionInput(
                "_toolBodyIptId",
                "Tool Body",
                "Select Tool Body"
            )
            _toolBodyIpt.addSelectionFilter("SolidBodies")

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


class MyExecutePreviewHandler(core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: core.CommandEventArgs):
        global _targetOccIpt
        occs = []
        for idx in range(_targetOccIpt.selectionCount):
            occs.append(_targetOccIpt.selection(idx).entity)

        global _toolBodyIpt
        exec_combines(
            occs,
            _toolBodyIpt.selection(0).entity
        )

        args.isValidResult = True


def exec_combines(
        targetOccs: list[fusion.Occurrence],
        toolBody: fusion.BRepBody,
) -> None:
    try:
        bodies = get_occurrences_has_bodies(
            targetOccs,
            get_show_bodies(),
        )
        if len(bodies) < 1: return

        exec_combine_diff(
            bodies,
            toolBody,
        )
    except:
        _ui.messageBox("Failed:\n{}".format(traceback.format_exc()))


def exec_combine_diff(
        bodies: list[fusion.BRepBody],
        toolBody: fusion.BRepBody,
) -> None:
    try:
        global _app
        des: fusion.Design = _app.activeProduct
        root: fusion.Component = des.rootComponent

        combFeats: fusion.CombineFeatures = root.features.combineFeatures
        for body in bodies:
            if body == toolBody: continue

            combIpt: fusion.CombineFeatureInput = combFeats.createInput(
                body,
                core.ObjectCollection.createWithArray(
                    [toolBody]
                ),
            )
            combIpt.operation = fusion.FeatureOperations.CutFeatureOperation
            combIpt.isKeepToolBodies = True

            combFeats.add(combIpt)

        toolBody.isLightBulbOn = False

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

def get_occurrences_has_bodies(
        targetOccs: list[fusion.Occurrence],
        bodies: list[fusion.BRepBody],
) -> list[fusion.BRepBody]:
    
    bodyLst = []
    for body in bodies:
        if body.assemblyContext in targetOccs:
            bodyLst.append(body)

    return bodyLst


def get_show_bodies() -> list[fusion.BRepBody]:
    global _app
    des: fusion.Design = _app.activeProduct
    root: fusion.Component = des.rootComponent

    showBodies = root.findBRepUsingPoint(
        core.Point3D.create(0,0,0),
        fusion.BRepEntityTypes.BRepBodyEntityType,
        sys.float_info.max,
        True,
    )

    return list(showBodies)


class MyValidateInputsHandler(core.ValidateInputsEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: core.ValidateInputsEventArgs):
        global _targetOccIpt
        if _targetOccIpt.selectionCount < 1:
            args.areInputsValid = False
            return

        global _toolBodyIpt
        if _toolBodyIpt.selectionCount < 1:
            args.areInputsValid = False
            return


class MyCommandDestroyHandler(core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: core.CommandEventArgs):
        adsk.terminate()


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

        cmdDef: core.CommandDefinition = _ui.commandDefinitions.itemById(
            CMD_INFO["id"]
        )

        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition(
                CMD_INFO["id"],
                CMD_INFO["name"],
                CMD_INFO["tooltip"]
            )

        global _handlers
        onCommandCreated = MyCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        cmdDef.execute()

        adsk.autoTerminate(False)

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

気持ち薄々なので、厳密な処理はしていないのですが(外部コンポーネントのチェック等)
ソコソコ機能するとは思っています。