C#ATIA

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

APIサンプルを我流にかみ砕く1

モチベーション回復の為のリハビリです。

一年以上前にこちらを書いたのですが、続きを書いてません。
押し出しを押し出さずに掘り下げる1 - C#ATIA
継続しなかった最大の理由は、アクセスが伸びなかったのでw


今回はもう少し手前の処理、スケッチを扱おうかと考えています。

念の為ですが、テストしている環境です。
Fusion360 Ver2.0.13377
・Win10Pro(Home)
・ms-python.python v2022.4.2

元となるサンプルはこちらのものです。
Fusion 360 Help


まずは、型ヒント付きで書き直してみました。スクリプトです。

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        # Fusion360取得
        app: adsk.core.Application = adsk.core.Application.get()

        # ユーザーインターフェース取得
        ui = app.userInterface

        # 新たなドキュメント作成
        doc: adsk.fusion.FusionDocument = app.documents.add(
            adsk.core.DocumentTypes.FusionDesignDocumentType)
        
        # デザイン取得
        design: adsk.fusion.Design = app.activeProduct

        # アクティブなデザインのルートコンポーネントを取得
        rootComp: adsk.fusion.Component = design.rootComponent

        # xy平面に新しいスケッチを作成
        sketches: adsk.fusion.Sketches = rootComp.sketches
        xyPlane: adsk.fusion.ConstructionPlane = rootComp.xYConstructionPlane
        sketch: adsk.fusion.Sketch = sketches.add(xyPlane)

        # 円を描く
        circles: adsk.fusion.SketchCircles = sketch.sketchCurves.sketchCircles
        circle1: adsk.fusion.SketchCircle = circles.addByCenterRadius(
            adsk.core.Point3D.create(0, 0, 0),
            2
        )

         # もういっちょ円を描く
        circle2: adsk.fusion.SketchCircle = circles.addByCenterRadius(
            adsk.core.Point3D.create(8, 3, 0),
            3
        )

        # circle2の中心と共通の中心点を持つ円を描く
        circle3: adsk.fusion.SketchCircle  = circles.addByCenterRadius(
            circle2.centerSketchPoint,
            4
        )
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

念の為、サンプルを作った方の名誉を守ると、Fusion360APIのPython
バージョンアップしてきており、サンプルを作った当時のバージョンでは
型ヒントが未対応だった と思います。恐らく・・・。

"型ヒントって何??" と言う方は、こちらが参考になるかも知れません。
Python 型ヒント 入門
"型チェックツール" なんて使ってないや・・・。
個人的にはインテリセンスを機能させたいので書くようにしてます。
python的な事は、世間の凄腕の方々にお任せします。



さて、Fusion360API的な事に移りましょう。

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        # Fusion360取得
        app: adsk.core.Application = adsk.core.Application.get()

        # ユーザーインターフェース取得
        ui = app.userInterface

通常pythonのエントリポイント(最初に実行される関数)は "main" ですが、
Fusion360APIの場合は "run" がエントリポイントになります。

Applicationは文字通りアプリケーション=Fusion360全体で、
UserInterfaceは表示されてるFusion360自体です。多分・・・。


        # 新たなドキュメント作成
        doc: adsk.fusion.FusionDocument = app.documents.add(
            adsk.core.DocumentTypes.FusionDesignDocumentType
        )

新たなドキュメントを作っているのですが、GUI(手動)で行った場合の
"新規デザイン" を押して新たにタブを付くている事と同じです。

念の為ですが、GUI同様保存されるわけではありません。

また、変数 "doc" に代入されていますが、今回は後の処理で直接利用
されている訳ではないので、戻り値を受け取らなくても同じ動作です。

        app.documents.add(
            adsk.core.DocumentTypes.FusionDesignDocumentType
        )

引数の "DocumentTypes" については今の所 "FusionDesignDocumentType"
しか用意されていませんでした。
Fusion 360 Help


        # デザイン取得
        design: adsk.fusion.Design = app.activeProduct

こちらはワークスペースの "デザイン" を取得しています。

その為、他のワークスペースで実行した際はここでエラーになります。


        # アクティブなデザインのルートコンポーネントを取得
        rootComp: adsk.fusion.Component = design.rootComponent

ルートコンポーネントはツリーの一番上のドキュメント名が
表示されている部分です。

ツリーに直接ぶら下がっている "スケッチ" 内にあるスケッチは、
ルートコンポーネントに所属しているスケッチになります。


        # xy平面に新しいスケッチを作成
        sketches: adsk.fusion.Sketches = rootComp.sketches
        xyPlane: adsk.fusion.ConstructionPlane = rootComp.xYConstructionPlane
        sketch: adsk.fusion.Sketch = sketches.add(xyPlane)

新たなスケッチを作っている部分です。

"sketches” ですが、こちらは画像の赤矢印部分です。
Fusion 360 Help
こちらはスケッチの親分ですね。これはルートコンポーネントも含め、
全てのコンポーネントにあります。
こちらのオブジェクトを利用し新たなスケッチを作成したり、各スケッチに
アクセスします。

"xYConstructionPlane" は原点のXY平面で、緑矢印部分です。
こちらも各コンポーネントに存在しています。

最終的にはaddメソッドを使用して、スケッチを作成しています。

各変数を再利用しないのであれば、こんな書き方でも同等です。(好みの問題)

        sketch: adsk.fusion.Sketch = rootComp.sketches.add(
            rootComp.xYConstructionPlane
        )

 
 
 

        # 円を描く
        circles: adsk.fusion.SketchCircles = sketch.sketchCurves.sketchCircles
        circle1: adsk.fusion.SketchCircle = circles.addByCenterRadius(
            adsk.core.Point3D.create(0, 0, 0),
            2
        )

スケッチに円を描いています。
"sketchCircles" は、スケッチ円の親分です。先程の "sketches” と同じような存在です。
ちょっと不思議だったのは "sketch.sketchCircles" では無く
"sketch.sketchCurves.sketchCircles" なんですよね。
Fusion 360 Help
"sketchCurves" はスケッチ内の線にアクセスする為に用意されているんでしょう。

"addByCenterRadius" メソッドはGUIのこちらのコマンドです。

引数については、こちらを参照すると分かりますが、第一引数は中心点で、
第二引数は半径(単位Cm)です。
Fusion 360 Help

中心点は "SketchPoint" または "Point3D" となっています。
・・・わかりにくいですね。
"SketchPoint" はこちらの様に画面上に表示されているものです。

一方 "Point3D" は、画面上には表示されません。
ん~これをどの様に表現すれば良いのかな?

Fusion360GUIで "点" は2種類あります。一つはスケッチの点でもう一つは
コンストラクションの点です。

API的にも、別のオブジェクトです。
Fusion 360 Help
Fusion 360 Help

別オブジェクトですが、それぞれgeometryプロパティも持っており、両方とも
"Point3D" オブジェクトです。
Fusion 360 Help
Fusion 360 Help

要は "Point3D" は、裏方さんです。
例えば、"SketchPoint" の座標値を知りたくても、座標値に関する
プロパティ・メソッドを直接持っていません。
その為、geometryプロパティの "Point3D" プロパティ・メソッドを
利用して取得することになります。
Fusion 360 Help

こちらのプロパティは読み取り専用の為、変更は出来ません。
例えば、点の位置を変更したい場合、この様なコードを書いても
円は移動しません。

        circle1: adsk.fusion.SketchCircle = circles.addByCenterRadius(
            adsk.core.Point3D.create(0, 0, 0),
            2
        )
        circle1.centerSketchPoint.geometry.x = 1 # X座標を変更してみる

ん! 移動しませんが、例外も発生しないの良いのかな・・・これ。

本題と話が反れますが、上記の円を移動させたいのであればこの様にします。

        sktPnt: adsk.fusion.SketchPoint = circle1.centerSketchPoint
        sktPnt.move(
            adsk.core.Vector3D.create(
                1, 0, 0
            )
        )



        # circle2の中心と共通の中心点を持つ円を描く
        circle3: adsk.fusion.SketchCircle  = circles.addByCenterRadius(
            circle2.centerSketchPoint,
            4
        )

"circle2" については "circle1" と座標値の違いの為、割愛。
"circle3" は中心の指定で "circle2" の中心点を利用しています。
実際にスプリクト実行後、 二重円の中心をドラッグすると両方一緒に移動することが
分かります。

試しに、"circle3" は中心を "circle2" と同じ座標値に修正してみます。

        circle3: adsk.fusion.SketchCircle  = circles.addByCenterRadius(
            # circle2.centerSketchPoint,
            adsk.core.Point3D.create(8, 3, 0),
            4
        )

これを実行し、再度中心点をドラッグすると片方の円しか移動しない事が分かります。

中心点を共通の "SketchPoint" にした場合と "Point3D" にした場合との違いを
実感できると思います。