C#ATIA

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

俺コマンドを作る3

こちらの続きです。
俺コマンドを作る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に出したやつの続きが
実現出来そうです。ほぼコードは書き直しなんですが。