C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA

スケッチをサーフェスにラップする別の方法を考える1

タイトル違いますが、こちらの続きです。
曲面上を2点クリックし直線を作りたい2 - C#ATIA

前回の最後の方に、"ゴリゴリ計算しないで簡単に出来そう"
のような事を書きましたが、思うように行かないです・・・。

最大の原因がスケッチに書かれた曲線が、2Dではなく3Dなんです。
3D → 2Dに変換する関数を探しているのですが、見つかりません。

線種毎にゴリゴリやらないとダメかなぁ。

曲面上を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メソッドを利用すれば
色々な制限が無くなりそうな気がしています。 どうでしょう?

Upし忘れた動画

こちらで上手くUp出来なかった動画
3DCAD中間ファイルの3Dな点・曲線をインポートするスプリクト - Autodesk Community

これです。

点・曲線をインポートするスプリクト 修正2

こちらの続きです。
点・曲線をインポートするスプリクト 修正1 - C#ATIA


円弧に続いて円も! と思っているのですが、上手くいかないです。
スケッチ内の円は
sketch
 ┗sketchCurves
   ┗sketchCircles
Help

に属しているのですが、sketchCircles オブジェクトの sketchCircleのインスタンス
・addByCenterRadius
・addByThreePoints
・addByThreeTangents
・addByTwoPoints
・addByTwoTangents
と存在しているのですが、全てスケッチサポート平面上か、平面に平行な状態でしかNGと
なっており、3D空間上に傾いた状態では作成出来ない様なんです。
(3点通過ですら、Z値は0の必要があるっぽいです)

ここまでは薄々気が付いていたので、次の手段を。

sketchCircleオブジェクトには、移動等出来そうなメソッド類はなさそう
なのですが、
http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-f19ed86c-4c9f-45a2-a5bb-03403c2962fa
geometryプロパティとなっている Circle3D オブジェクトには、 "transformBy" メソッドがあり
Helpを見る限り、破壊的なメソッドっぽい感じがします。
これを利用すれば、任意の位置に円が作成できるかな? と思ったので、
こんな感じの関数作ってみました。

・・・
def include_Cri(geo, skt):
    sktCir = skt.sketchCurves.sketchCircles.addByCenterRadius(geo.center, geo.radius)
    geo = sktCir.geometry
    vec = adsk.core.Vector3D.create(0,0,1)
    mat = adsk.core.Matrix3D.create()
    mat.setToRotateTo(vec,geo.normal)
    geo.transformBy(mat)
    return sktCir
・・・

結論から書くと、結局任意の位置にはなりませんでした。
ん~甘かった。 2つの円弧に分割しようかとも思うのですが、
手動だと円も1本の線で表現可能なんですよね。 困ったなぁ

点・曲線をインポートするスプリクト 修正1

先日、何とか3DCAD中間ファイルの3Dな点・曲線をインポートするスプリクトを
Upしました。
3DCAD中間ファイルの3Dな点・曲線をインポートするスプリクト - Autodesk Community


多数ある問題点の一つなのですが、円・円弧をNurbs曲線として
インポートしている部分の修正を考えています。

#FusionAPI_python
#Author-kantoku
#Description-ArcTest

import adsk.core, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        #円弧作成
        center = [1107.3813777445, -361.18476278735, 87.096588591886]
        normal = [-0.54635392414872, -0.83754953013075, -0.00285904618013]
        referenceVector = [0.83755440991454, -0.54635074096564, -0.00186501447709]
        radius = 5.0881512938029 * 0.1
        startAngle = 3.138255565834
        endAngle = 6.2798482194238
        
        arc = adsk.core.Arc3D.createByCenter(
            create_Point(center), 
            create_Vector(normal), 
            create_Vector(referenceVector), 
            radius, 
            startAngle, 
            endAngle)
        
        #スケッチ作成
        des = adsk.fusion.Design.cast(app.activeProduct)
        comp = des.rootComponent
        skt = comp.sketches.add(comp.xYConstructionPlane)
        skt.name = "NurbsCurve"
        
        #円弧取り込み-NurbsCurve
        sfs = include_BSc(arc.asNurbsCurve, skt)
        skt.include(sfs)
        sfs.deleteMe()
        
        
        #スケッチ作成
        skt = comp.sketches.add(comp.xYConstructionPlane)
        skt.name = "Arc"
        
        #円弧取り込み-Arc
        ac = include_Arc(arc, skt)
        skt.include(ac)
        ac.deleteMe()
        
        
        ui.messageBox('Done')
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def create_Vector(lst):
    return adsk.core.Vector3D.create(
        lst[0], lst[1], lst[2])
        
def create_Point(lst):
    return adsk.core.Point3D.create(
        lst[0] * 0.1, lst[1] * 0.1, lst[2] * 0.1)
        
def include_BSc(geo, skt):
    fs = skt.sketchCurves.sketchFittedSplines.addByNurbsCurve(geo)
    fs.isFixed = True
    return fs
    
def include_Arc(geo, skt):
    eva = geo.evaluator
    (reValue, sParam, eParam) = eva.getParameterExtents()
    (reValue, midpnt) = eva.getPointAtParameter((sParam + eParam) * 0.5)
    ac = skt.sketchCurves.sketchArcs.addByThreePoints(
        geo.startPoint, midpnt, geo.endPoint)
        
    return ac

1つのArc3Dオブジェクトを
最初は、今までの方法でNurbs曲線として取り込み
後では、3点通過の円弧として取り込みます。

最初のものをマウスでクリックすると
f:id:kandennti:20170912154021p:plain
右下に曲線の長さが表示されます。

後のものをマウスでクリックすると
f:id:kandennti:20170912154042p:plain
右下には半径が表示され、中心部分に点が作成されました。

と言う事で、円弧に関しては何とかなりそうです。

図脳RAPID3D

僕は "図脳RAPID3D" と言うCADは見たことも触れたことも
無いのですが次期バージョンUpからカーネル
独自(大元がDESIGNBASE?)だったものを、CGM(CATIAと同じ)に
切り替えるようです。
図脳CAD3D - 新3DCADプロジェクト始動! -

どの位の価格になるのだろうか?

Igesファイルの3D曲線のインポートに挑む6

こちらの続きです。
Igesファイルの3D曲線のインポートに挑む5 - C#ATIA

機能的に足りない部分もあるのですが、公開出来そうなレベルに
なってきました。

今更なのですが、Stepファイルが失敗してました…。
何とか今週中には公開したい(希望)