C#ATIA

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

スケッチの点の正しい座標値の取得1

ちょっと前にこちらを回答してみました。
Export World geometry of sketch points - Autodesk Community
正直に書くと半分寝かかって作ったので、何かミスがあるような
気もするのですが。

実はこちらの問題は、僕も以前に悩まされた部分でした。
あちらのコードはちょっぴりハードな感じなので少し単純なものに
してご説明します。
今後、Fusion360APIにPythonで取り組まれる方の参考になれば良いな
と思ってます。


まず、XY平面上にスケッチを作成し、点をこんな感じで作成します。
f:id:kandennti:20191028180738p:plain
3D空間上の座標値としては(10,20,0)の状態を期待しています。

続いてこのようなスプリクトを作成しました。

#Fusion360API_Python - test1
#Author-kantoku
#Description-スケッチ点の座標値の表示1

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)

        #全てのスケッチ取得
	#多重の内包表記でわかりにくいですね・・・
        skts = [skt
                for comp in des.allComponents
                for skt in comp.sketches]
        
        #1個目のスケッチ内の2個目の点座標を取得
        #スケッチの1個目の点はスケッチ原点です
        sktPnt = skts[0].sketchPoints[1]

        #点の座標値を表示する
        #本来はunitsManagerで単位を変換したりするのですが
        #今回の目的ではない為、10倍して単位をmmにします。
        pnt3d = sktPnt.geometry
        ui.messageBox('X:{}\nY:{}\nZ:{}'.format(pnt3d.x * 10, pnt3d.y * 10, pnt3d.z * 10))

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

スケッチの点の取得までは・・・まぁこんなもんだと思って下さい。涙
お伝えしたいのはスケッチ点の座標値の取得です。

SketchPointオブジェクトには、座標値を示すプロパティ・メソッドが有りません。
Fusion 360 Help
その為、geometryプロパティのPoint3Dオブジェクトを取得し座標値を取得しています。
結果はこちら
f:id:kandennti:20191028180810p:plain
良いですね。

続いてXY平面から+30mmの位置にコンストラクション平面を作成し、
先程と同様のスケッチを描きます。
(履歴をゴニョゴニョしスケッチ平面の再定義でもOKです)
f:id:kandennti:20191028180823p:plain
但し、コード的に最初のスケッチの点を取得してしまうためスケッチ自体は
一つにしておく必要があります。

ここで期待する結果は(10,20,30)です。実際にスプリクトを実行してみると
f:id:kandennti:20191028180834p:plain
おぉ残念。Zの値が違いますね。

Fusion360のスケッチは3Dな空間です。geometryプロパティはスケッチ内での
Point3Dを返してきます。僕らが知りたいのは外部から見た際のPoint3Dの
座標値です。
よく見てみるとworldGeometryプロパティが存在しており、説明からしても
こちらのPoint3Dの方が都合良さそうです。

そこでこのように修正して見ます。

#Fusion360API_Python - test2
・・・

        #点の座標値を表示する
        #本来はunitsManagerで単位を変換したりするのですが
        #今回の目的ではない為、10倍して単位をmmにします。
        pnt3d = sktPnt.worldGeometry
        ui.messageBox('X:{}\nY:{}\nZ:{}'.format(pnt3d.x * 10, pnt3d.y * 10, pnt3d.z * 10))

・・・

実行してみるとこんな感じです。
f:id:kandennti:20191028180847p:plain
今度は正しい値が表示されました。

続きます。コンポーネントを新作しその中に同等のスケッチ内に
点を作成します。
f:id:kandennti:20191028180858p:plain
赤矢印のスケッチです。
ここで先程のスプリクトを実行します。
f:id:kandennti:20191028180908p:plain
良いですね。期待した通りです。

続いて、このコンポーネントを X+10 Y+10 Z+10 移動します。
f:id:kandennti:20191028180917p:plain
赤矢印は ルートコンポーネント(未保存となっている)の
コンポーネントの原点で、青矢印が新作したコンポーネントの原点です。

ここで再度先程のスプリクトを実行した際、ルートから見た際の
座標値を期待します。つまり(20,30,40)です。
実際に実行します。
f:id:kandennti:20191028180926p:plain
残念、裏切られました。

worldGeometryプロパティの説明では(Chromeの翻訳)

返される座標は、アセンブリコンテキストとその親コンポーネント内の
スケッチの位置を考慮します。
つまり、ルートコンポーネント空間で座標が返されます。

ルートコンポーネントで見た際の座標値が取得出来そうな記載なのですが、
実際は、新作のコンポーネント内での座標値を返してきてます。

最初に記載したリンク先のトピ主も、この事について記載して
望んだ結果が得られないのでどうすれば良いのか?質問したと思います。

ではどうすれば良いのか?