C#ATIA

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

曲面上を2点クリックし直線を作りたい

今後の事を考え、スプリクトで曲面上に線を作成したいと思っていました。

Fusion360の3D空間で点・線・面を表現するには、"コンストラクション" が
一番相応しい気がしているのですが、"コンストラクション" で表現できるのは
こちらの選択フィルタを見ても
Help

"点" "軸" "平面" だけなのだろうと思います。 要は "構築" コマンドで作成
出来る物だけなのでしょう。
f:id:kandennti:20161010181239p:plain

自分でこちらの回答をしておきながら、どのように曲線を表現しているのか
よくわかっていませんでした。
解決済み: 計算式による曲線の定義 - Autodesk Community

調べてみると、スケッチで曲線を表現しているのですね。
スケッチで3D曲線・・・、個人的な常識を覆す発想で戸惑います。

結局スケッチを利用する以外の選択肢はなさそうです。
クリックした際の座標は、過去に試したこちらの方法を利用します。
クリックした位置に点を作成する - C#ATIA


毎度ながらイマイチですが、コードです。

#FusionAPI_python
#Author-kantoku
#Description-SurfaceOnCurve
#2点クリックして線を作成

import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.get()
_ui = _app.userInterface

def run(context):
    try:
        global _app, _ui
        des = adsk.fusion.Design.cast(_app.activeProduct)
        comp = des.rootComponent
        
        #始点クリック
        selFilters = 'Faces'
        sel1 = Sel('始点クリック/ESC-中止', selFilters )
        if sel1 is None: return
        sel1Ent = sel1.entity
        sel1 = sel1.point
        
        #終点クリック
        sel2 = Sel('終点クリック/ESC-中止', selFilters )
        if sel2 is None: return
        sel2Ent = sel2.entity
        sel2 = sel2.point
        
        if not sel1Ent == sel2Ent:
            _ui.messageBox('始点と終点は合一面を指定してください')
        surf = sel1Ent
        
        #始点終点のパラメータ(UV)取得
        eva =surf.evaluator
        
        res,prm1 = eva.getParameterAtPoint(sel1)
        if res is False: return
            
        res,prm2 = eva.getParameterAtPoint(sel2)
        if res is False: return
        
        #パラメータ(UV)を元にLine2Dを作成
        lin = adsk.core.Line2D.create(prm1,prm2)
        
        #Line2Dを面に割り当て
        lin3ds = eva.getModelCurveFromParametricCurve(lin)
        
        #通過点を取得
        lin0eva=lin3ds[0].evaluator
        (res,sprm,eprm) = lin0eva.getParameterExtents()
        (res,pnts) = lin0eva.getStrokes(sprm,eprm,0.001)
        points = adsk.core.ObjectCollection.create()
        [points.add(pnt) for pnt in pnts]
        
        #スケッチに取り込み
        root = des.rootComponent;
        skt = comp.sketches.add(root.xYConstructionPlane)
        skt.sketchCurves.sketchFittedSplines.add(points);
        
        _ui.messageBox('done')
    except:
        if _ui:
            _ui.messageBox('エラー\n{}'.format(traceback.format_exc()))

#選択
#param: msg-string, selFilter-SelectionFilters
#return: selection
def Sel(msg, selFilter):
    global _ui
    try:
        return _ui.selectEntity(msg, selFilter)
    except:
        return None

スプリクト実行後、始点と終点とする部分をクリックします。(事前に点を作成する
必要は有りません)
但し、始点と終点は同一面上である必要が有ります。


実際に実行してみます。この辺りをクリックします。
f:id:kandennti:20161010181250p:plain

こんな感じです。
f:id:kandennti:20161010181257p:plain
点が羅列しているだけに見えるのですが

f:id:kandennti:20161010181304p:plain
一応、青いラインで曲線は作成されています。
・・・汚いんですよ、この方法だと。


上のコード手順は
・クリックした2点からサーフェス上のパラメータ(UとV)を取得
 ↓
・パラメータを平面上の2点として直線を作成
 ↓
・直線をサーフェス上に割り当て
 ↓
・XY平面をサポートとするスケッチを作成し割り当て
と言う感じです。

スケッチに割り当てる直前までは、adsk.coreライブラリの要素で
かなり自由に扱うことが出来そうです。
f:id:kandennti:20161010181315p:plain
問題は画面上に表示させる方法なんです。

最初はこんな方法では無く、こんなコードを書いたんです。

・・・
        #Line2Dを面に割り当て
        lin3ds = eva.getModelCurveFromParametricCurve(lin)

        #スケッチに取り込み
        root = des.rootComponent;
        skt = comp.sketches.add(root.xYConstructionPlane)
        for lin3d in lin3ds:
            res = skt.include(lin3d) #ここがNG

Sketchオブジェクトにあるinclude関数の存在に気が付きました。
Help

今回試したものの場合、スケッチに割り当てる直前の曲線は
"NurbsCurve3D" オブジェクトだったのですが、そのままinclude関数に
突っ込めば良いのかな? と思っていたのですがエラーになっちゃいました。

他に方法があるのかな?