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