C#ATIA

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

名前付きビューのクリックイベント

先日、こちらにレスしましたので転載です。

Re: Is there a better way to detect when user picks a named view? - Autodesk Community

名前付きビューはこちらの機能です。英語でごめん・・・

クリックすると設定時の画面の状態(視点や方向や倍率等)を再現する
機能です。
これらのどれかをクリックした際のイベントが欲しかったようです。

#FusionAPI_python addin
import traceback
import adsk.core as core
import adsk.fusion as fusion

_app = core.Application.cast(None)
_ui  = core.UserInterface.cast(None)
_handlers = []

_cmdInfo = {
    "id": "kantoku_DumpPickNamedViewTest",
    "name": "DumpPickNamedViewTest",
    "tooltip": "DumpPickNamedViewTest",
    "workSpace": "FusionSolidEnvironment",
    "panelId": "SolidScriptsAddinsPanel",
}


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

        cmdDefs: core.CommandDefinitions = _ui.commandDefinitions

        global _cmdInfo
        cmdDef: core.CommandDefinition = cmdDefs.itemById(_cmdInfo["id"])
        if cmdDef:
            cmdDef.deleteMe()

        cmdDef = cmdDefs.addButtonDefinition(
            _cmdInfo["id"],
            _cmdInfo["name"],
            _cmdInfo["tooltip"])

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

        workSpace: core.Workspace = _ui.workspaces.itemById(_cmdInfo["workSpace"])
        targetpanel :core.ToolbarPanel = workSpace.toolbarPanels.itemById(_cmdInfo["panelId"])

        controls :core.ToolbarControls = targetpanel.controls
        cmdControl :core.ToolbarPanel = controls.addCommand(cmdDef)

        cmdControl.isVisible = True

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


class CommandCreatedHandler(core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            global _app, _ui, _handlers
            cmd = core.Command.cast(args.command)
            des :fusion.Design = _app.activeDocument

            core.Camera.isEqual = isEqual

            # event
            onCommandTerminated = MyCommandTerminatedHandler()
            _ui.commandTerminated.add(onCommandTerminated)
            _handlers.append(onCommandTerminated)

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


class MyCommandTerminatedHandler(core.ApplicationCommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: core.ApplicationCommandEventArgs):
        if not _ui.activeCommand == "RestoreCameraCommand": return

        stateCam: core.Camera = _app.activeViewport.camera

        des: fusion.Design = _app.activeProduct
        views: core.NamedViews = des.namedViews
        view: core.NamedView = None
        for view in views:
            if stateCam.isEqual(view.camera):
                _app.log(f"Pick NamedView {view.name}!!")
                return


def isEqual(self: core.Camera, cam: core.Camera) -> bool:
    if not self.cameraType == cam.cameraType:
        return False
    if not self.eye.isEqualTo(cam.eye):
        return False
    if not self.target.isEqualTo(cam.target):
        return False
    if not self.upVector.isEqualTo(cam.upVector):
        return False
    if abs(self.perspectiveAngle - cam.perspectiveAngle) > 0.001:
        return False

    return True


def stop(context):
    try:
        global _cmdInfo
        workSpace: core.Workspace = _ui.workspaces.itemById(_cmdInfo["workSpace"])
        panel: core.ToolbarPanel = workSpace.toolbarPanels.itemById(_cmdInfo["panelId"])

        if panel:
            panel.controls.itemById(_cmdInfo["id"]).deleteMe()

        cmdDefs: core.CommandDefinitions = _ui.commandDefinitions
        cmdDef: core.CommandDefinition = cmdDefs.itemById(_cmdInfo["id"])
        if cmdDef:
            cmdDef.deleteMe()

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

念の為、元から入っている4個(ホーム等)をイベントとして感知する為には
事前にカメラ情報を控えておく必要がある と思っていたのですが、
モデルのサイズに依存してカメラの数値が変わってしまう事に気が付きました。
(未確認ですが、直感的にです)
その為、お互いのeyeとtarget間のベクトルを単位化し、一致した場合を
ホーム等がクリックされたと判断すれば良いように感じています。