C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA(最近はPMillマクロとFusion360APIが多い)

マウスカーソルの座標値を取得する

先日、ちょこっとFusion360APIやった際に色々と調べていたら
発見したので記載。

よく探してみたら、同様のことをこちらでやってました…。
MouseMoveEvent サンプル - C#ATIA

前回やった際は、ディスプレイ上のマウスカーソル位置座標(左上が0,0)の取得しか
出来なかったのですが、今回はメソッドやプロパティが増えていたのでFusion360
ウィンドウ上の座標値が取得できました。

#FusionAPI_python
#Author-kantoku
#Description-MouseMoveTest
import adsk.core, traceback

_app = None
_ui  = None
_inputs  = None
_handlers = []

#このコマンドのイベント・ダイアログ作成
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            global _inputs, _handlers
            cmd = adsk.core.Command.cast(args.command)

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

            onMouseMove = MyMouseMoveHandler()
            cmd.mouseMove.add(onMouseMove)
            _handlers.append(onMouseMove)

            _inputs = cmd.commandInputs
            
            _inputs.addTextBoxCommandInput('Vp_Pos', 'Fusion360画面上の座標値', '-', 1, True)
            _inputs.addTextBoxCommandInput('Sc_Pos', 'ディスプレイ上の座標値', '-', 1, True)
        except:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
            
#このコマンドの破棄
class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            adsk.terminate()
        except:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

#MouseMoveイベント
class MyMouseMoveHandler(adsk.core.MouseEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        eventArgs = adsk.core.MouseEventArgs.cast(args)
        
        global _ui, _inputs
        vppos = eventArgs.viewportPosition
        ui_vp = _inputs.itemById('Vp_Pos')
        ui_vp.text = "x:[%d] y:[%d]"%(vppos.x, vppos.y)
        
        scrpos = eventArgs.viewport.viewToScreen(vppos)
        ui_sc = _inputs.itemById('Sc_Pos')
        ui_sc.text = "x:[%d] y:[%d]"%(scrpos.x, scrpos.y)
        
def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface

        cmdDef = _ui.commandDefinitions.itemById('Mouse_Move_Test')
        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition('Mouse_Move_Test', 'Mouse_Move_Test', 'Mouse_Move_Test')

        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()))

MouseMoveイベントからダイアログのテキストに座標値を書き込んでるのですが、
どうやったらダイアログを取得できるのだろう?と悩んだ末、[_inputs](ダイアログ自体)
のスコープを大きくするぐらいしか思いつかなかったのですが、前回の
コードを見たら・・・同じようにしてました。良いのか不安。

本当は、3Dの座標値が欲しかったのですが、上手くいきませんでした。
Help
こちらのViewportオブジェクトに 「viewToModelSpace」メソッドがあるのですが
例外にも引っかからないし…。
画面の奥行きに対しての座標値が定まらないので、無理なのはわかっているのですが。
cameraオブジェクトから計算したりするのかな?