C#ATIA

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

複数面に線を描きたい5

こちらの続きです。
複数面に線を描きたい4 - C#ATIA

前回の最後に思い付いた、共有されているエッジ上の通過点を
探すことにします。と言うものの、どの様に・・・。

f:id:kandennti:20200512164936p:plain

とりあえず2点間は直線(Line3D)となるため、intersectWithCurveメソッドが
使えるのではないかな? と淡い期待をしました。
Fusion 360 Help
が、駄目でした。そりゃ交差してないものじゃ無理なはず。


悩んだ末、ひょっとしたら・・・と思い、今まで使ったことのない
MeasureManagerオブジェクト(測定用のオブジェクト)の
measureMinimumDistance(最短距離)メソッドの戻り値に
測定された際の位置(point3D)が取得出来る事を発見しました。
Fusion 360 Help


これを利用してお互いの点から共有エッジの通過点に向かって
線を描くことにしました。

#Fusion360API Python script

import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        des  :adsk.fusion.Design = _app.activeProduct
        root :adsk.fusion.Component = des.rootComponent

        # get body
        body :adsk.fusion.BRepBody = root.bRepBodies.item(0)

        # get face
        face1 :adsk.fusion.BRepFace = body.faces.item(0)
        face2 :adsk.fusion.BRepFace = body.faces.item(1)

        lps1 :adsk.fusion.BRepLoops = face1.loops
        lp1 :adsk.fusion.BRepLoop = lps1[0]
        cos1 = [co for co in lp1.coEdges if hasPartner(co)]

        lps2 :adsk.fusion.BRepLoops = face2.loops
        lp2 :adsk.fusion.BRepLoop = lps2[0]
        cos2 = [co.partner for co in lp2.coEdges if hasPartner(co)]

        # 共有エッジ取得
        rap = []
        for co1 in cos1:
            for co2 in cos2:
                if co1 == co2:
                    rap.append(co1.edge)

        # get point
        pnt1 :adsk.fusion.ConstructionPoint = root.constructionPoints.item(1)
        pnt2 :adsk.fusion.ConstructionPoint = root.constructionPoints.item(0)

        # 直線
        lin3D :adsk.core.Line3D = adsk.core.Line3D.create(pnt1.geometry, pnt2.geometry)

        # 共有エッジと直線の最短位置の共有エッジ上の点取得
        meas = _app.measureManager
        mersRes = meas.measureMinimumDistance(rap[0].geometry, lin3D)
        passPnt = mersRes.positionOne

        # add sketch
        skt :adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane)

        # 面上に線を描く
        initFaceOnCrv(face1, pnt1.geometry, passPnt, skt)
        initFaceOnCrv(face2, pnt2.geometry, passPnt, skt)

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def initFaceOnCrv(
    face :adsk.fusion.BRepFace,
    pnt1 :adsk.core.Point3D,
    pnt2 :adsk.core.Point3D,
    skt :adsk.fusion.Sketch):

    # BRepFace.evaluator
    faceEva :adsk.core.SurfaceEvaluator = face.evaluator

    # get parameter
    prm1 = adsk.core.Point2D.cast(None)
    prm2 = adsk.core.Point2D.cast(None)
    _, prm1 = faceEva.getParameterAtPoint(pnt1)
    _, prm2 = faceEva.getParameterAtPoint(pnt2)

    # init line2D
    lin2D = adsk.core.Line2D.create(prm1, prm2)

    # get BRepFace.geometry.evaluator
    geoEva :adsk.core.SurfaceEvaluator = face.geometry.evaluator

    # init curve3D list
    crvs = geoEva.getModelCurveFromParametricCurve(lin2D)

    # add sketch
    skt.isComputeDeferred = True
    sktCrvs :adsk.fusion.SketchCurves = skt.sketchCurves

    for crv in crvs:
        if hasattr(crv,'asNurbsCurve'):
            crv = crv.asNurbsCurve

        if crv.objectType == 'adsk::core::NurbsCurve3D':
            sktElm = sktCrvs.sketchFittedSplines.addByNurbsCurve(crv)

        else:
            s = crv.startPoint
            e = crv.endPoint
            sktElm = sktCrvs.sketchLines.addByTwoPoints(s,e)

    skt.isComputeDeferred = False

def hasPartner(
    coEdge :adsk.fusion.BRepCoEdge) -> bool:

    try:
        coEdge.partner
        return True
    except:
        return False

結果はこちら。
f:id:kandennti:20200512165101p:plain
紫が手動で作ったもので、青の点が表示されているものが今回のもの。
青面側は一致しているものの、赤面側は・・・お前何故曲がる。

そんなにUVが歪んでいるわけでも無いのに。
f:id:kandennti:20200512165118p:plain

駄目かなぁこの方法では。出口が見えない。