C#ATIA

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

3D曲線のパイプの中心線を求める3

こちらの続きです。
3D曲線のパイプの中心線を求める2 - C#ATIA

無事アドイン化出来ました。

前回は、中心になる点群の取得まで出来ていたのですが
曲線化することが出来ずに終わってました。

ちょっと時間が無いため、説明は次回にしますが、
中心の点群取得と曲線化を行うサンプルです。

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core
import sys
import pathlib

# nurbs-pythonのインポート
# https://nurbs-python.readthedocs.io/en/5.x/index.html
parent_dir = pathlib.Path(__file__).resolve().parent
target_dir = parent_dir / 'Modules'
sys.path.append(str(target_dir))
from geomdl import fitting
del sys.path[-1]


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

        # 選択
        msg: str = 'Select'
        selFilter: str = 'Faces'
        sel: adsk.core.Selection = selectEnt(msg, selFilter)
        if not sel:
            return

        # 選択面
        face: adsk.fusion.BRepFace = sel.entity

        # surface evaluator取得
        surfEva: adsk.core.SurfaceEvaluator = face.evaluator

        # 面上の点からパラメータ取得
        refPrm: adsk.core.Point2D = None
        _, refPrm = surfEva.getParameterAtPoint(
            face.pointOnFace
        )

        # アイソメトリック曲線のV方向取得
        isoCrvLst = surfEva.getIsoCurve(refPrm.y, False)
        isoCrv: adsk.core.NurbsCurve3D = isoCrvLst[0]

        # アイソメトリックV曲線 evaluator取得
        crvEva: adsk.core.CurveEvaluator3D = isoCrv.evaluator

        # 曲線のパラメータ範囲取得
        _, sPrm, ePrm = crvEva.getParameterExtents()

        # トレランス以内で曲線上の点群を取得
        _, points = crvEva.getStrokes(sPrm, ePrm, 0.01)

        # 点群の面上のパラメータ群を取得
        _, prms = surfEva.getParametersAtPoints(points)

        # パラメータ群の曲率を取得
        _, _, crvTures, _ = surfEva.getCurvatures(prms)

        # パラメータ群の法線ベクトルを取得 これは単位ベクトル
        _, normals = surfEva.getNormalsAtParameters(prms)

        # 曲率からRサイズを取得 Rサイズは曲率の逆数
        radius = [1/c for c in crvTures]

        # 法線ベクトルをRサイズ分考慮する 中心方向・サイズのベクトル
        [n.scaleBy(r) for n, r in zip(normals, radius)]

        # 面上の点群を中心方向に移動 この時点で点群は中心を示す
        [p.translateBy(v) for p, v in zip(points, normals)]

        # --- ここからNURBS-Python(geomdl)向け ---
        # Point3Dの座標値をリスト化
        p: adsk.core.Point3D = None
        aryList = [p.asArray() for p in points]

        # 点群を通過するNurbs曲線を取得
        crv: 'curve' = fitting.interpolate_curve(aryList, 3)
        # --- ここまで このNurbs曲線をそのままFusion360には取り込めない!!---

        # NURBS-PythonのコントロールポイントをPoint3D化
        pnt3D: adsk.core.Point3D = adsk.core.Point3D
        controlPoints = [pnt3D.create(c[0], c[1], c[2]) for c in crv.ctrlpts]

        # 他の要素はそのまま流用可
        degree = crv.degree
        knots = crv.knotvector
        isPeriodic = crv.rational

        # Fusion360用のNurbs曲線作成
        nurbs: adsk.core.NurbsCurve3D = adsk.core.NurbsCurve3D.createNonRational(
            controlPoints,
            degree,
            knots, 
            isPeriodic
        )

        dumpCurves3D([nurbs])


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


# 曲線をスケッチに書き出し
def dumpCurves3D(curves, name = ''):
    app: adsk.core.Application = adsk.core.Application.get()
    des: adsk.fusion.Design = app.activeProduct
    root: adsk.fusion.Component = des.rootComponent

    skt: adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane)
    if len(name) > 0:
        skt.name = name

    skt.isComputeDeferred = True
    for c in curves:
        if hasattr(c, 'asNurbsCurve'):
            c = c.asNurbsCurve
        skt.sketchCurves.sketchFittedSplines.addByNurbsCurve(c)
    skt.isComputeDeferred = False


def selectEnt(
        msg: str,
        filterStr: str) -> adsk.core.Selection:

    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        sel = ui.selectEntity(msg, filterStr)
        return sel
    except:
        return None

チェックが甘いので、場合によってはエラーになっちゃうと
思いますが、左図のような感じの曲面を選択すると右図の
曲線を作ります。 ・・・ん、カエルの卵感が半端ない。


これらの処理を行う為にはSurfaceEvaluatorとCurveEvaluator3Dを
利用するのですが、恐らくAPIフォーラムを利用する方でも
数名しかいないと思います。マニアックですね・・・。
help.autodesk.com
help.autodesk.com