C#ATIA

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

オブジェクトとして提供されない要素を選択する3

こちらの続きです。
オブジェクトとして提供されない要素を選択する2 - C#ATIA


目的は要素の選択です。過去にダイアログに要素を設定する為にこちらを使いました。
テキストコマンド3 - C#ATIA
は未だに謎なのですが、 を取得する為に事前に選択して

    ObjectPaths.Onk

を行うしか方法が分からないのですが、今回は選択する方法が分からない為困ります。
(卵が先か?鶏が先か?問題と同じ)


テキストコマンドでも幾つか選択関連っぽいものが有りますが、素直に "Selections"
で挑戦する事にしました。
・・・忘れていましたが、過去に "Selections.List" を試していました。
Selections.List - C#ATIA
当時は全くと言って良いほど、理解出来ていませんでした。


f:id:kandennti:20201204095543p:plain
コンポーネントを一つ作りのボディのグループを作成した上で選択し "Selections.List" を
実行すると

Selections.List 
57:3:4:224:173:190:319

謎です。(数値は環境によって異なるかもしれません)

前回使用した

PEntity.Properties <EntityRef>

部分に各数字を入力するとイロイロと表示されます。(長いので割愛)
動作を確認出来たので、手間を省くためスプリクトを作成しました。
選択フィルタの関係で、事前選択して実行すると、テキストコマンドパレットに表示に
情報が表示されます。

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback
import json, neu_server

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

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

        sels :adsk.core.Selections = _ui.activeSelections
        if sels.count < 1:
            _ui.messageBox('調べる要素を事前選択して下さい')
            return
        
        dumpMsg('-- select info --')

        # paths取得
        paths :str = _app.executeTextCommand(u'Selections.List').rstrip('\n\r')
        dumpMsg('<paths> : {}\n'.format(paths))

        # 各数字に分割
        ids = paths.split(':')
        if len(ids) < 1:
            return

        # ID毎にループ
        for id in ids:

            dumpMsg('prop -> : {}'.format(id))

            # プロパティ取得
            prop_txt = neu_server.get_entity_properties(id)
            if len(prop_txt) < 1: return

            # JSON化
            prop =  json.dumps(prop_txt, indent=2)

            # テキストコマンドパレットに表示
            dumpMsg(prop + '\n')

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def dumpMsg(msg :str):
    _ui.palettes.itemById('TextCommands').writeText(str(msg))

f:id:kandennti:20201204095706p:plain

出力内容から判断して、interfaceIdだけを抜き出すと

57 : "Ns::Comp::ComponentInstance" - オカレンス
3 : "Na::FusionComponent" - コンポーネント
4 : "Ns::Comp::ComponentInstances" - オカレンスのコレクション
224 : "Ns::Comp::ComponentInstance" - オカレンス
173 : "Na::FusionComponent" - コンポーネント
190 : "Ns::BREP::SurfaceGroups" - ボディのグループのコレクションの個別entityId
319 : "Ns::BREP::SurfaceGroup" - ボディのグループの個別のID

と予測しています。脳内のイメージを画像にするとこんな感じです。
f:id:kandennti:20201204095724p:plain
赤色はGUIで選択出来る要素(主にオカレンス)で、緑色は実質表示されていない
参照元(コンポーネント)。青色も表示されていない各要素のコレクション。
ルートコンポーネントにもオカレンスが存在しているのは意外でしたが、これは
CATIAのTreeと同じ構造ですね。

最後に示されるIDが実際に選択されている要素になります。今回の目標はこの "319" を
選択状態にするのが目標なのです。これを

Selections.Add <paths>

を利用するのですが、entityIDではなくpathsを指定しなければならない為、面倒です。

イロイロと探したのですが、"319" から先頭の "57" まで辿りつくのが難しいです。
(先頭から下に降りていく方法は楽なのですが、N分木検索する必要がある)
試しにPEntity.Propertiesの結果(JSON)を上から順に探ると、

57 : "Ns::Comp::ComponentInstance" ['rTargetComponent']['entityId'] -> 3
3 : "Na::FusionComponent" ['rComponentBaseInstances']['entityId'] -> 4
4 : "Ns::Comp::ComponentInstances" ['children'][0]['entityId'] -> 244
224 : "Ns::Comp::ComponentInstance" ['rTargetComponent']['entityId'] -> 173
173 : "Na::FusionComponent" ['rSurfaceGroups']['entityId'] -> 190
190 : "Ns::BREP::SurfaceGroups" ['children'][0]['entityId'] -> 319
319 : "Ns::BREP::SurfaceGroup"

でOKです。逆が探せない・・・。

319 : "Ns::BREP::SurfaceGroup" ['rParent']['entityId'] -> 190
190 : "Ns::BREP::SurfaceGroups" ['rParent']['entityId'] -> 173
173 : "Na::FusionComponent"  -> 224不明
224 : "Ns::Comp::ComponentInstance" ['rParent']['entityId'] -> 4
4 : "Ns::Comp::ComponentInstances" ['rParent']['entityId'] -> 3
3 : "Na::FusionComponent"  -> 57不明
57 : "Ns::Comp::ComponentInstance"

基本的に'rParent'キーを探せばよいのですが、コンポーネントからオカレンスを探せない結果に。

ん~何をしているのか分からなくなってきました。どうやったら上手く伝わるのだろう?