こちらに記載した内容とちょっと関連してます。恐らく。
解決済み: Re: ValidateInputsEventHandlerのイベントによる呼び出しについて - Autodesk Community
本家のAPIフォーラムで質問した際のものは、
SelectionCommandInput(要素を選択するやつ)が2個有り、希望としては
”2個共何かが選択された際にOKボタンが機能するようにしたい”
と言うことです。
何か処理する際に片方だけでは処理出来ないので、OKボタンは
押せない状態にしておくのが自然な事ですよね?
でもAPIフォーラムに記載した最初のコードでは実現できず、
さらに2個目でうまく行くと思ったのにそれでもNGだったのです。
教えて頂いたのは、SelectionCommandInputの選択制限数を
無制限にすれば機能するよ って事でした。
Fusion 360 Help
・・・ i1 = inputs.addSelectionInput(_input1ID, _input1ID, _input1ID) #i1.setSelectionLimits(1,1) #NG i1.setSelectionLimits(0) #OKだけど無制限に選択出来ちゃう ・・・
仮に、各SelectionCommandInputで1個づつでなければ処理出来ない場合は、
当然、選択数が無制限では困っちゃう場合があるので、他の何らかの方法で
防ぐ必要に迫られる事になります。
それを考えるとsetSelectionLimitsメソッド(プロパティじゃ無いんだな…)は、
1個の時のみ簡単に実装するための機能なんだなぁ と感じます。
つまり、そこまで拘るなら お前が頑張れ! って受け止めました。
と、ここまでが前置きです。
選択を防ぐ方法としては幾つか有りそうなのですが、恐らくCommandオブジェクトの
preSelectイベントが良さそうです。
Fusion 360 Help
・・・Helpの説明がやたらと長い。
記載によれば、2個を選択出来るようにして平面を選択フィルタとし、
お互いが並行でなければならなければ と言う条件の場合は
Fusion 360 Help
こちらだけでは不足してます。
OKボタンを押した後に、 "お前が選択した平面は平行じゃないから、中止するね" と
メッセージを出すのは、表示させる言葉をいくら丁寧にしても不親切。
preSelectイベントは選択直前の処理なのですが、マウスカーソルの下の面等の取得が
可能です。選択させたくない場合は、、、、Helpの説明がやたらと長い割には
そこの説明が抜け落ちてる。
class PreSelectHandler(adsk.core.SelectionEventHandler): def __init__(self): super().__init__() def notify(self, args): eventArgs = adsk.core.SelectionEventArgs.cast(args)
こんな感じのイベントハンドラを作った場合、argsはSelectionEventArgsオブジェクトなので、
Fusion 360 Help
eventArgs.isSelectable = False
こんな感じにすると選択出来なくなります。これは対象となるオブジェクトを
選択不可にするわけじゃなく、一時的な事の様です。
なるほど、是非ともHelpに記載して欲しい。
と言うことでサンプルです。
#Fusion360API Python script #Author-kantoku #Description-PreSelectイベントサンプル import adsk.core, adsk.fusion, traceback _commandId = 'PreSelectionEvent' _SelIpt1ID = 'Selectioninput1' _handlers = [] _app = None _ui = None class CommandDestroyHandler(adsk.core.CommandEventHandler): def __init__(self): super().__init__() def notify(self, args): try: adsk.terminate() except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class ValidateInputHandler(adsk.core.ValidateInputsEventHandler): def __init__(self): super().__init__() def notify(self, args): try: eventArgs = adsk.core.ValidateInputsEventArgs.cast(args) inputs = eventArgs.inputs i1 :adsk.core.SelectionCommandInput = inputs.itemById(_SelIpt1ID) # 選択が2個ならOKボタンを有効に if i1.selectionCount == 2: eventArgs.areInputsValid = True else: eventArgs.areInputsValid = False except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class PreSelectHandler(adsk.core.SelectionEventHandler): def __init__(self): super().__init__() def notify(self, args): try: eventArgs = adsk.core.SelectionEventArgs.cast(args) i1 :adsk.core.SelectionCommandInput = eventArgs.firingEvent.activeInput if i1.selectionCount == 2: # 既に選択が2個なら許さない eventArgs.isSelectable = False return if i1.selectionCount < 1 : # 選択が0個なら問題なし return selGeo :adsk.core.Plane = i1.selection(0).entity.geometry preGeo :adsk.core.Plane = eventArgs.selection.entity.geometry # お互いが平面か確認して判断 eventArgs.isSelectable = selGeo.isParallelToPlane(preGeo) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class CommandCreatedHandler(adsk.core.CommandCreatedEventHandler): def __init__(self): super().__init__() def notify(self, args): try: cmd = args.command onDestroy = CommandDestroyHandler() cmd.destroy.add(onDestroy) _handlers.append(onDestroy) onValidateInput = ValidateInputHandler() cmd.validateInputs.add(onValidateInput) _handlers.append(onValidateInput) onPreSelect = PreSelectHandler() cmd.preSelect.add(onPreSelect) _handlers.append(onPreSelect) inputs = cmd.commandInputs i1 = inputs.addSelectionInput(_SelIpt1ID, _SelIpt1ID, _SelIpt1ID) i1.setSelectionLimits(0) # 平面のみ filters = ['PlanarFaces','ConstructionPlanes'] [i1.addSelectionFilter(s) for s in filters] except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def run(context): try: global _app, _ui _app = adsk.core.Application.get() _ui = _app.userInterface cmdDefs = _ui.commandDefinitions cmdDef = cmdDefs.itemById(_commandId) if cmdDef: cmdDef.deleteMe() cmdDef = cmdDefs.addButtonDefinition(_commandId, _commandId, _commandId) onCmdCreated = CommandCreatedHandler() cmdDef.commandCreated.add(onCmdCreated) _handlers.append(onCmdCreated) cmdDef.execute() adsk.autoTerminate(False) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
こんな感じで動作します。選択数とOKボタンを見て頂きたいです。
(マウスカーソルが停止しているときは、クリックしまくってます)