こちらの続きです。
俺コマンドを作る2 - C#ATIA
先日の俺コマンドを清楚に実装出来るように考えたのですが、
結果としてこちらの類似したものを作ることになりそうなため
止めました・・・。
github.com
一番困っていたのは、「Fusion360CommandBase.py」で対応していない
イベント処理の追加の仕方だったのですが、普通に行ったところ
出来ることが分かったので、こちらで行くことにします。
とりあえず、こちらのサンプルを「Fusion360AddinSkeleton」で
実装することにします。こちらは未対応な「PreSelect」イベントを使っています。
GitHub - kantoku-code/Fusion360-SelectFilter_T_Sample: Fusion360API Python script
「Demo1Command.py」を修正した「OreCommand.py」はこんな感じです。
import adsk.core import adsk.fusion import traceback from .Fusion360Utilities.Fusion360Utilities import AppObjects from .Fusion360Utilities.Fusion360CommandBase import Fusion360CommandBase class OreCommand(Fusion360CommandBase): handlers = [] def on_create(self, command: adsk.core.Command, inputs: adsk.core.CommandInputs): onPreSelect = PreSelectHandler() command.preSelect.add(onPreSelect) self.handlers.append(onPreSelect) selSktCon = inputs.addSelectionInput( 'selection_input_id', 'PreSelectTest', 'スケッチ拘束を選択して!') # Extension Method register_SelectionCommandInput_ExtensionMethod() # Addition by FilterT list selSktCon.addFilterT([ 'SketchAngularDimension', 'SketchConcentricCircleDimension', 'SketchDiameterDimension', 'SketchLinearDimension', 'SketchEllipseMajorRadiusDimension', 'SketchEllipseMinorRadiusDimension']) # FilterT string addition selSktCon.addFilterT( 'SketchOffsetDimension,SketchRadialDimension,hoge') # Partial deletion of FilterT selSktCon.removeFilterT('hoge') class PreSelectHandler(adsk.core.SelectionEventHandler): def __init__(self): super().__init__() def notify(self, args): try: eventArgs = adsk.core.SelectionEventArgs.cast(args) selSktCon :adsk.core.SelectionCommandInput = eventArgs.firingEvent.activeInput try: preType :str = eventArgs.selection.entity.objectType.split('::')[-1] if not preType in selSktCon.getFilterT(): eventArgs.isSelectable = False return eventArgs.isSelectable = True except: eventArgs.isSelectable = False except: ao = AppObjects() ao.ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) # -- SelectionCommandInput Extension Method -- _filterT = {} def register_SelectionCommandInput_ExtensionMethod(): selCmdIput = adsk.core.SelectionCommandInput selCmdIput.addFilterT = addFilterT selCmdIput.getFilterT = getFilterT selCmdIput.clearFilterT = clearFilterT selCmdIput.removeFilterT = removeFilterT def addFilterT(self, filters): fType = type(filters) fs = [] if fType is str: fs = list(filters.split(',')) elif fType is list: fs = filters else: print('filters type errer') return fs global _filterT if self.id in _filterT: tmp = _filterT[self.id] tmp.extend(fs) _filterT[self.id] = list(set(tmp)) else: _filterT[self.id] = fs def getFilterT(self): global _filterT if not self.id in _filterT: return [] return _filterT[self.id] def clearFilterT(self): global _filterT if self.id in _filterT: _filterT[self.id] = [] def removeFilterT(self, filter): global _filterT if not self.id in _filterT: return _filterT[self.id].remove(filter)
ほとんどゴッゾリ削除して、コピペしただけに近いです。
試すまで分からなかったのが、「PreSelectHandler」クラスを記載する位置と
「handlers」変数(リスト)の位置です。
pythonの場合、クラス内にクラスを作成する事が可能(理解しがたい)な
様ですが、単純にクラスを作成しても大丈夫でした。
よく出てくる「handlers」ですが、正直な所役割が分かっていないのですが
恐らくガベージ コレクションで回収されるのを避ける(ハンドラを維持しておく)
だけの為の存在だと思っています。(違ったら教えてください)
続いてアドインのエントリーポイントとなる「Fusion360AddinSkeleton.py」は
不要部分を削除し以下のように修正。
from .OreCommand import OreCommand commands = [] command_definitions = [] cmd = { 'cmd_name': 'Ore Command', 'cmd_description': '俺コマンド', 'cmd_id': 'ore', 'cmd_resources': '', 'workspace': 'FusionSolidEnvironment', 'toolbar_panel_id': 'SolidScriptsAddinsPanel', 'class': OreCommand } command_definitions.append(cmd) debug = False # Don't change anything below here: for cmd_def in command_definitions: command = cmd_def['class'](cmd_def, debug) commands.append(command) def run(context): for run_command in commands: run_command.on_run() def stop(context): for stop_command in commands: stop_command.on_stop()
これ無事、Selection Filtersのバグで機能していなかった
スケッチ拘束のみが選択出来るようになりました。
こんな事だったのか。
この方が、少ないコードでギブコン'19に出したやつの続きが
実現出来そうです。ほぼコードは書き直しなんですが。