C#ATIA

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

スカルプト産ボディからフューチャーを取得したい2

こちらの続きです。
スカルプト産ボディからフューチャーを取得したい1 - C#ATIA

色々とHelpを調べ何となくですがわかりました。
こんなコードです。

#Fusion360 python

import adsk.core, adsk.fusion, traceback
def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        des = adsk.fusion.Design.cast(app.activeProduct)
        
        sel = Sel('ボディを選択してください','Bodies')
        if sel is None:
            return
        
        print('-- start --')
        bdy = sel.entity
        
        fm = GetParentFormFeature(bdy, des)
        
        if fm is None:
            msg = 'スカルプトで作ったのボディではありません'
        else:
            msg = 'スカルプトで作ったのボディです!!'
        
        ui.messageBox(msg)

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

def GetParentFormFeature(bdy, des):
    pa_fm = None

    for cmp in des.allComponents:
        print('comp:{}'.format(cmp.name))
        for fm in cmp.features.formFeatures:
            print('  form:{}'.format(fm.name))
            for bd in fm.bodies:
                print('    {}:{}'.format(bd.name,bdy == bd))
                if (bdy == bd):
                    pa_fm = fm
    return pa_fm

def Sel(msg, selFilter):
    app = adsk.core.Application.get()
    ui  = app.userInterface
    try:
        return ui.selectEntity(msg, selFilter)
    except:
        return None

ボディから直接フォームフューチャーを取得出来る方法が無さそうな為、
全てのフォームフューチャー内に狙ったボディが含まれているか?
を調べまくりました。
GetParentFormFeature関数のげっそりするような3重ループ・・・。
本来であれば、内包表現かFlattenを利用すべきでしょう。

こんな感じでテストです。
f:id:kandennti:20190425174229p:plain
結果的に一部しか上手くいきません。
・ルートコンポーネントで作成したスカルプト産ボディ - OK
・ルートコンポーネントで作成したスカルプト産ボディを
 「ボディからコンポーネントを作成」で移動したボディ - NG
・ルートコンポーネント以外で作成したスカルプト産ボディ - NG
何でかな? フォームの編集モード時のみ動くようにすれば大丈夫なのかな・・・。