C#ATIA

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

製造モデルにアクセスする1

Fusion360の製造(CAM)には、"製造モデル"と言う項目があります。

メニューの"設定"パレットに"製造モデルを作成"を押すと、
ブラウザツリーに"製造モデル"が出来上がります。
中身はデザインと同じもので、デザイン側での変更は製造モデルでも
反映されます。

個人的なイメージとして、製造モデルは設計時には不要で、加工時に
使用したいもの(治具・クランプ等)や、加工上に必要なダミー面等を
作成するスペースとの認識です。
Help

しかし、加工するために加工対象となるモデルの向きを変える と言う
発想は正直ありませんでした。正直驚きました。


"製造モデル"をあまり扱わなかった最大の理由は、過去にAPIフォーラムで
"アクセスする方法が無い" との記載があったためです。

しかし、試してみると制限があるものの、全く扱えない訳では無い事が
分かりました。

まず、この様なデータを用意しました。

上は、デザインで作った際の形状です。原点のZ軸(青色)で
確認してください。
下の二つが、製造モデルで向きを変更したモデルです。

この状態のままでは、APIでモデルにアクセスする方法が未だに
分かりません。

二つの製造モデルを元に、二つのセットアップを作成しておきます。

実は、このセットアップの"モデル"から、製造モデルにアクセス出来る
事が分かりました。

次のスクリプトは、アクティブなセットアップのモデルから
3軸を想定して穴の軸の向きから、加工可能な方向の穴の面を
選択した状態で終了します。

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.fusion as fusion
import adsk.cam as cam

def run(context):
    ui: core.UserInterface = None
    try:
        app: core.Application = core.Application.get()
        ui = app.userInterface

        # CAM環境取得
        camObj: cam.CAM = get_cam_product()

        # セットアップの取得
        setup: cam.Setup = get_active_setup(camObj)
        if not setup:
            return
        
        # セットアップの'モデル'で設定されているボディを取得
        prm = setup.parameters.itemByName("job_model")
        bodies = list(prm.value.value)
        if len(bodies) < 1:
            return

        # 穴面の取得
        holeFaces: list[fusion.BRepFace] = find_hole_faces(
            bodies[0],
            core.Vector3D.create(0,0,1)
        )

        # 穴面選択
        sels: core.Selections = ui.activeSelections
        sels.clear()
        [sels.add(f) for f in holeFaces]

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


def find_hole_faces(
    body: fusion.BRepBody,
    axisZ: core.Vector3D,
) -> list[fusion.BRepFace]:
    '''
    穴面を探し出す
    '''
    # 円筒面のみ
    f: fusion.BRepFace = None
    faces = [f for f in body.faces
        if f.geometry.objectType == core.Cylinder.classType()]

    # 主軸の向きは逆
    axisZRev: core.Vector3D = axisZ.copy()
    axisZRev.scaleBy(-1)

    # 円筒面の軸が、Z軸と一致するもののみ
    faces = [f for f in faces
        if axisZRev.isEqualTo(f.geometry.axis)]

    # ボスの円筒面は除去
    faces = [f for f in faces if f.isParamReversed]

    return faces


def get_active_setup(camObj: cam.CAM) -> cam.Setup:
    """
    アクティブなセットアップを取得
    """
    setups: cam.Setups = camObj.setups
    for setup in setups:
        if setup.isActive:
            return setup

    return None


def get_cam_product() -> cam.CAM:
    '''
    CAMの取得
    '''
    app: core.Application = core.Application.get()
    activete_cam_env()

    return app.activeProduct


def activete_cam_env() -> None:
    '''
    CAMアクティブ
    '''
    app: core.Application = core.Application.get()
    ui: core.UserInterface = app.userInterface

    camWS: core.Workspace = ui.workspaces.itemById('CAMEnvironment') 
    camWS.activate()

これを実行してみると、画像ではわかりにくいのですが、
加工可能な穴面を選択状態にしていますが、横の穴面は
選択されていません。

Z軸と一致する向きの穴面だけを探し出し、選択出来る
と言う事は、製造モデルにアクセス出来ている と判断して
良いと思っています。

もう一つアクセスする方法を見つけてはいるのですが、
何れにしても、ユーザーが何かアクション(セットアップを事前に
作成しておく等)が必要で、モデリングが終わった状態で
自動的に製造モデルを作成し、セットアップを作成し・・・
と言うのはちょっと出来そうにありません。


余談ですが、API的に製造モデルはちょっと不思議な感じがします。
デザインのオカレンスのような気もしますが、それとも
ちょっと異なる感じもしてます。
ボディからコンポーネントが取得出来るのですが、コンポーネント名が
製造モデルを作った時の古い名前だったり、それでいてデザインの
変更を行うと、同期して変更されたり・・・。