こちらの続きです。
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