C#ATIA

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

CommandInputsの表示不具合っぽい時の対処

タイトルが異なりますが、こちらの続きです。
TSMファイル6 - C#ATIA

何とか、この不具合のような状況を回避策を見付けてから
宿題に取り掛かりたいです。


コマンドを自作しダイアログを表示させる場ですが、
Helpのサンプルコードを見ても結構長いです。

そこで何も処理は行いませんが、最低限なコードを作成しました。

#FusionAPI_python_script
#Author-kantoku
#Description-CommandTest

import adsk.core, adsk.fusion, traceback

_app = None
_ui  = None
_handlers = []

class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            cmd = adsk.core.Command.cast(args.command)
            inputs = cmd.commandInputs
            
            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

            selectionInput = inputs.addSelectionInput('HOGE', 'PIYO', 'HUGA')
            print('piyo') #ここにブレークポイント
            
        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()))

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

        cmdDef = _ui.commandDefinitions.itemById('HOGE')

        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition('HOGE', 'PIYO', 'HUGA')

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

今の知識の範囲で最低限にしたつもりですが、結構長いです。
実行するとこんな感じです。
f:id:kandennti:20191116163103p:plain
要素の選択とか出来ますが、OKを押しても何も起きません。
取りあえず、OKかキャンセルでダイアログを閉じます。


続いてMyCommandCreatedHandlerクラスのコメントを付けた部分に
ブレークポイントを設置して、デバッグを実行します。

class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
	・・・
            selectionInput = inputs.addSelectionInput('HOGE', 'PIYO', 'HUGA')
            print('piyo') #ここにブレークポイント

        ・・・

f:id:kandennti:20191116162921p:plain
この様な状態で、赤印部を押しデバッグを終了します。

Fusion360上では、先程同様のダイアログが出ていますが、これも
終了させます。


問題は次です。再度デバッグを実行します。すると以下の状態に
なります。
f:id:kandennti:20191116162940p:plain
残念。「選択」が2個になってしまいました。
しかし、問題の再現は出来ました。



エントリーポイントのrun関数をよく見ると

	・・・

        #自作commandDefinitionを取得
        cmdDef = _ui.commandDefinitions.itemById('HOGE')

        if not cmdDef:
            #見付からない場合は作成
            cmdDef = _ui.commandDefinitions.addButtonDefinition('HOGE', 'PIYO', 'HUGA')

        #自作commandDefinitionにハンドル類を登録
        onCommandCreated = MyCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

	・・・

まず、commandDefinitionをIDから取得し、見つからない場合は
作成しています。
その後commandDefinitionにハンドル類を登録し自作コマンドを
作成・実行しています。
この手順は、Helpのサンプル等で必ず記載されています。

色々と試した結果、この部分の処理方法が上記の不具合原因だと
わかりました。


意図的にデバッグを終了したり、エラーが出て終了した場合は、
自作コマンドの破棄が正しく行われない事が原因だと言う事の
様な為、サンプルに見られる方法の逆を行う様に修正しました。

・・・
def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        
        cmdDef = _ui.commandDefinitions.itemById('HOGE')
        if cmdDef:
            cmdDef.deleteMe()
        cmdDef = _ui.commandDefinitions.addButtonDefinition('HOGE', 'PIYO', 'HUGA')

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

commandDefinitionをIDから取得し、見つかった場合は一度破棄して
しまい、毎回新たに作成してしまいます。

これにより、毎回クリーンな状態で自作コマンドが作成され
不具合的な表示を避ける事が出来るようになりました。
他にも方法があると思うし、これはこれで良くない部分もあるのは
確かなのですが(ダイアログ表示中に再度コマンドを実行するとエラー)
一番簡単な対処方法かなぁ と思ってます。