C#ATIA

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

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

ここ一ヶ月ぐらいで、少し知識を得たのでこちらの続きです。
曲面上を2点クリックし直線を作りたい - C#ATIA


以前のコードでは、曲面上に出来上がる直線(正しくはスプライン)の
通過点が表示された状態で、非常に邪魔でした。
が、インポートスプリクトを取り組んだおかげで、もっと簡単に処理出来る
事がわかりました。

#FusionAPI_python
#Author-kantoku
#Description-SurfaceOnCurve2
#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)
        
        #Extension
        adsk.core.NurbsCurve3D.to_skt = include_BSc  
        
        #スケッチに取り込み
        root = des.rootComponent;
        skt = comp.sketches.add(root.xYConstructionPlane)
        [lin.to_skt(skt) for lin in lin3ds]
        
        _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

def include_BSc(self, sk):
    sk_geo = sk.sketchCurves.sketchFittedSplines.addByNurbsCurve(self)
    sk_geo.isFixed = True
    sk.include(sk_geo)
    sk_geo.deleteMe()
    return

SurfaceEvaluator オブジェクトの getModelCurveFromParametricCurveメソッドを
利用すると2Dの線を3Dな面上の線として変換してくれるので(どうやってこのメソッド
見付けたのか、全く覚えていない)、そのままスケッチに取り込んでます。
前回はこの方法がわからず、1/1000トレランスで通過点を全て取得していたのですが
こちらの方が素直で処理も速いはずです。

テストした感じです。


話は外れるのですが、実はこちらに平面に描いたスケッチを曲面に反映する(ラップする)
アドインが公開されています。
GitHub - hanskellner/Fusion360WrapSketch: Wrap sketch curves around a cylinder

僕には到底思い付かないすごいものですが、制限がちょっと多いんです。
・参照スケッチはXY平面上
・投影先は円筒形状で軸はZ軸と一致
・点、直線、スプラインのみ
となっています。 インポートスプリクトで悩みまくった円・円弧は未対応なんです。
(他人事とは思えない・・・)

コードをチラッと覗いて見ると、結構ゴリゴリ計算して座標値を求めており、各制限の内容的に
納得できます。

計算せずに、上記のgetModelCurveFromParametricCurveメソッドを利用すれば
色々な制限が無くなりそうな気がしています。 どうでしょう?