C#ATIA

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

スプリクトで2要素間の距離測定をしたい3

こちらの続きです。
スプリクトで2要素間の距離測定をしたい2 - C#ATIA


昨日の計測コマンドの頼りなさを考えると、別の方法で考えます。
色々とHelp調べていると(Help見飽きました・・・)、
点-曲線の最短となる位置の曲線のパラメータが取得できる事がわかりました。

こちらのCurve3Dオブジェクト
Help

evaluatorプロパティがトポロジカルな情報です。それがCurveEvaluator3Dオブジェクト
Help

CATIAの場合、3Dに関してはマクロではトポロジカルな情報がほぼ提供されていない
のですが、2Dであればある程度提供されています。
r1 Curve2D (Object)

結構似ている関数があるんです。

Fusion360のCurveEvaluator3Dオブジェクトの "getParameterAtPoint" 関数
なのですが、点が曲線上にない場合は、曲線上の最も近い点のパラメータが
返ってくるような説明になっています。(本来トレランスの関係なのだろうと思います)
これを利用してみます。

#FusionAPI_python
#Author-kantoku
#Description-GetMinimumPoint ver0.01
#点-曲線間の最短部分に点を作成
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        #準備
        app = adsk.core.Application.get()
        ui = app.userInterface
        
        #点選択
        pnt = Sel(ui, '点選択/ESC-中止', 'Vertices,ConstructionPoints,SketchConstraints')
        if pnt is None: return
            
        #線選択
        edg = Sel(ui, '線選択/ESC-中止','Edges')
        if edg is None: return
        
        #最短位置取得
        minPos = GetMinimumPoint(pnt.geometry, edg.geometry)
        
        #線のコンポーネント取得
        cmp = edg.body.parentComponent
        
        #点の作成
        if IsParametric():
            baseF = cmp.features.baseFeatures.add()
            baseF.startEdit()
            pnt = CreatePnt(cmp, minPos)
            baseF.finishEdit()
        else:
            pnt = CreatePnt(cmp, minPos)
        
        #終わり
        ui.messageBox('終了')
    except:
        if ui:
            ui.messageBox('エラー\n{}'.format(traceback.format_exc()))

#点-線間の最短位置取得
def GetMinimumPoint(pnt, edg):
    try:
        eva = edg.evaluator
        
        res, prm = eva.getParameterAtPoint(pnt)
        if res is False:return None
        
        res, minPnt = eva.getPointAtParameter(prm)
        if res is False:return None
        
        return minPnt
    except:
        return None
        
#点作成
def CreatePnt(comp, pnt3d):
    pnt = comp.constructionPoints.createInput()
    pnt.setByPoint(adsk.core.Point3D.create(pnt3d.x, pnt3d.y, pnt3d.z))
    return comp.constructionPoints.add(pnt)
    
#選択
def Sel(ui, msg, selFilter):
    try:
        return ui.selectEntity(msg, selFilter).entity
    except:
        return None
        
#パラメトリックチェック
def IsParametric():
    app = adsk.core.Application.get()
    isPara = False
    design = adsk.fusion.Design.cast(app.activeProduct)
    if design.designType == adsk.fusion.DesignTypes.ParametricDesignType:
        isPara = True
    return isPara

本来きちんとコマンドダイアログにすべきなのですが、テスト段階なのでご勘弁を。

スプリクト実行後、最初に点を選択し続いて曲線を選択します。
先程の関数を利用して、曲線の点から一番近い位置に点を作成します。
実際に実行してみます。

f:id:kandennti:20160930103601p:plain
赤い印部分は、エッジ部分から少し離れた位置に作った点です。

f:id:kandennti:20160930103608p:plain
こんな感じで点が出来ます。

f:id:kandennti:20160930103616p:plain
側面から確認してみると・・・一番高いところでは無いですね。
あくまで点との距離なので仕方ないですかね。

もっと多くの点を作成し最短距離となるものを選び出せば、極値
取得できるかな? と感じています。 と言うか他に方法が見つからないんです。