C#ATIA

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

NativeObjectとProxyの理解とモロモロ3

こちらの続きです。
NativeObjectとProxyの理解とモロモロ2 - C#ATIA

前回は、主にコンポーネントとオカレンスの説明となってしまいました。 が、この説明無しでは
お話が進まない為、ご勘弁を。

前回の最後の疑問として
"オカレンスにはスケッチが無いためコンポーネントから取得したのに、オカレンスの状態を考慮
してないじゃん"
と言う事になります。
オカレンスの状態を考慮しているかどうかを確認する為、nativeObjectプロパティを確認する
ことで判断出来るとわかりましたが、肝心なオカレンスを考慮したものをどうやって取得するか?
と言う事になります。

それが、createForAssemblyContextメソッドです。
Fusion 360 Help
これは、nativeObjectプロパティ同様に色々なオブジェクトに実装されています。

所属しているオカレンスを引数として実行すると、呼び出したインスタンスと同じ型のインスタンス
返されますが、戻ってきたものはオカレンスを考慮したものとなっています。
これをFusion360APIでは、タイトルにしたもう一つの言葉 "Proxy" と呼ぶようです。

これを考慮して先程の物をこの様に修正すると

・・・
        # コンポーネント内の1個目のスケッチ
        skt :adsk.fusion.Sketch = comp.sketches[0]

        # proxyとして取得
        skt_proxy :adsk.fusion.Sketch = skt.createForAssemblyContext(occ) #<-ここ追加

        msg = 'ではありません!' if skt_proxy.nativeObject else 'です!' #<-ここ修正
        ui.messageBox(skt_proxy.name + 'は、nativeObject' + msg) #<-ここ修正
・・・

実行結果はこちら。
f:id:kandennti:20201128093755p:plain
”nativeObjectではありません!” は、オカレンス情報を考慮していると言う意味です。

これを考慮し前回の最後のコードを修正するとこんな感じになります。

# Fusion360API Python script
# sample2-2
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        # おまじない
        app :adsk.core.Application = adsk.core.Application.get()
        ui :adsk.core.UserInterface = app.userInterface
        des :adsk.fusion.Design = app.activeDocument.design

        # ルートコンポーネント
        root :adsk.fusion.Component = des.rootComponent

        # ルートコンポーネント内のオカレンスの1個目
        occs :adsk.fusion.Occurrences = root.allOccurrences
        occ :adsk.fusion.Occurrence = occs[0]

        # オカレンスのコンポーネント
        # オカレンスにはスケッチが無く、参照元のコンポーネントに有り
        comp :adsk.fusion.Component = occ.component

        # コンポーネント内の1個目のスケッチ
        skt :adsk.fusion.Sketch = comp.sketches[0]

        # proxyとして取得
        skt_proxy :adsk.fusion.Sketch = skt.createForAssemblyContext(occ)

        # スケッチ内の1個目の円 - 目的の円
        curvrs :adsk.fusion.SketchCurves = skt_proxy.sketchCurves
        circle :adsk.fusion.SketchCircle = curvrs.sketchCircles[0]

        # SketchCircleには中心点情報が無いので、geometryを取得
        geo :adsk.core.Circle3D = circle.worldGeometry

        # 単位を正しくしたい為、係数取得
        unitsMgr :adsk.core.UnitsManager = des.unitsManager
        defLenUnit :str = unitsMgr.defaultLengthUnits
        covunit :float = unitsMgr.convert(1, unitsMgr.internalUnits, defLenUnit)

        # 中心座標表示
        ctr :adsk.core.Point3D = geo.center
        ui.messageBox('X: {1}{0}\nY: {2}{0}\nZ: {3}{0}'.format(
            defLenUnit, ctr.x * covunit, ctr.y * covunit, ctr.z * covunit))

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

f:id:kandennti:20201128093818p:plain

無事、ルートコンポーネントからの中心座標を取得出来ました。
もう、大丈夫ですね! と言いたいところですが、まだ罠があるんです。
それは次回に・・・。