こちらに記載した内容とちょっと関連してます。恐らく。
解決済み: 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(0)
・・・
仮に、各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に記載して欲しい。
と言うことでサンプルです。
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)
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:
eventArgs.isSelectable = False
return
if i1.selectionCount < 1 :
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ボタンを見て頂きたいです。
(マウスカーソルが停止しているときは、クリックしまくってます)