こちらの続きです。
3D曲線のパイプの中心線を求める1 - C#ATIA
前回は惨敗だったので作戦変えます。
・・・細かな事は省力しますが、忘れちゃいそうなので
書き残しておきたいことがあるので、そっちがメインなお話です。
こんな感じで、パイプ形状から中心線を作る為の大量の点を
取得する事には成功しました。
問題はここからです。大量の点⇒大量の通過点を持つスプライン
を行えば中心線の完成なのですが、通過点からスプラインの生成は
スケッチを経由して作るしか方法を知りません。
スケッチの処理は時間がかかるので避けたいのですが、他の方法が
無いため、スケッチ経由でスプラインを生成しました。
単調なスクリプトで開発しているのですが、スクリプト上では
問題ありません。
しかし、アドインに組み込むと思うような動作をしてくれません
でした。推測ですが、inputChangedイベント内でスケッチを
作成したり削除したりを行う事が悪いのだろうと思います。
・・・諦めれば良いのですが、通過点から3DのNurbs曲線を
作成出来るものを探してみたところ、こちらを見つけました。
GitHub - orbingol/NURBS-Python: Object-oriented pure Python B-Spline and NURBS library
有難い事に、他のモジュール類に依存していなさそうです。
問題は、Fusion360APIで外部モジュールの利用方法です。
pipでインストールするとFusion360APIで利用されるPython
フォルダにモジュールがインストールされると思うのですが、
Updateの際に対応出来なくなると思われます。
その為、ローカルの別の場所(スクリプトフォルダ内等)に
モジュールを置き呼び出したいのです。
で、手順。vscodeでスクリプトの編集を行っている状態です。
・pipをupdate。(これを行わなかった為、一回目は失敗しました)
・vscodeのターミナルで、"pip install geomdl" (--user あった方が良いのかな・・・)
"pip3 install --user geomdl" としました。
これでインストール完了。
但し、良く調べたらFusion360でインストールされたpythonとは
異なるところにインストールされました・・・。
・vscodeのターミナルで、"pip show geomdl" でインストールフォルダを探す。
pipでインストールしたパッケージの場所を調べる - Qiita
・”geomdl” フォルダをコピーし任意のフォルダにペーストする。
”geomdl” と ”geomdl-5.3.1.dist-info” フォルダをコピーし
任意のフォルダにペーストする。
これで取りあえずの目的は達成です。
・vscodeのターミナルで、"pip uninstall geomdl" でアンインストール。
配布時を考慮するとパスの通っている位置のモジュールを
削除して開発・テストを行いたいので。
で、大丈夫そうです。多分。
※どのモジュールでもこの方法で出来るわけでは無いと思います。
実際にテストするためにこちらを作成しました。
# 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 BSpline from geomdl import utilities 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 curve = BSpline.Curve() curve.degree = 7 curve.ctrlpts = [ [1, 0, 0], [1, 5, 0], [2, -1, 3], [1, 1, 0], [3, 0, 1], [5, 1, 2], [7, -6, 1], [9, 1, 2], ] curve.knotvector = utilities.generate_knot_vector( curve.degree, len(curve.ctrlpts) ) crv: adsk.core.NurbsCurve3D = toNurbsCurve(curve) dumpCurves3D([crv]) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def toNurbsCurve( crv: 'curve') -> adsk.core.NurbsCurve3D: 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 nurbs: adsk.core.NurbsCurve3D = adsk.core.NurbsCurve3D.createNonRational( controlPoints, degree, knots, isPeriodic ) return nurbs 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.sketchFixedSplines.addByNurbsCurve(c) skt.isComputeDeferred = False
最初に "NURBS-Python"(geomdl)のモジュールをインポート
しなければならないのですが、sys.pathにパスを追加して
から行ってます。
処理的には、"NURBS-Python" でnurbsカーブを作成し、
その情報からFusion360用のnurbsカーブを作成し
スケッチに書き出しています。
実際に実行したところ出来ました。
”・・・はぁ?で?” と言うレベルな事は分かってます。
これはコントロールポイントでNurbsカーブを作成して
いるのですが、通過点では無いため目的を果たしていません。
でも、こちらにフィッティングの例があるので
出来るような気がしてます。
Curve & Surface Fitting — NURBS-Python 5.3.1 documentation
新たな武器を手に入れちゃったな。
スケッチ経由より速そうだし。