C#ATIA

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

接続された複数のスケッチ線を単一のスプラインにする

APIフォーラムのこちらに取り組んだのですが、完敗です。
Solved: Convert multiple lines into a single spline - Autodesk Community

NurbsCurve3Dオブジェクトにmergeメソッドが存在していたことを
完全に見落としていました。
Fusion 360 Help

但し、選択方法は僕の方が便利そうなので、Ekins氏のコードを一部修正し
2個1にしてみました。

# Fusion360API Python script
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app :adsk.fusion.Application = adsk.core.Application.get()
        ui = app.userInterface

        # select sketch curve
        msg :str = 'Select'
        selFiltter :str = 'SketchCurves'
        sel :adsk.core.Selection = selectEnt(msg ,selFiltter)
        if not sel: return

        # get sketch curve
        sktCrv :adsk.fusion.SketchEntity = sel.entity
        refSkt: adsk.fusion.Sketch = sktCrv.parentSketch

        # get path
        comp: adsk.fusion.Component = refSkt.parentComponent
        path: adsk.fusion.Path = comp.features.createPath(sktCrv)

        # get Sketch Curves
        pathEnt: adsk.fusion.PathEntity
        sketchCurves = [pathEnt.entity for pathEnt in path]

        # get Single Spline
        crv: adsk.core.NurbsCurve3D = getSingleSpline(sketchCurves)

        # create curve
        skt: adsk.fusion.Sketch = comp.sketches.add(comp.xYConstructionPlane)
        skt.arePointsShown = False # hide sketch points
        skt.isComputeDeferred = True
        skt.sketchCurves.sketchFixedSplines.addByNurbsCurve(crv)
        skt.isComputeDeferred = False

        ui.messageBox('Done')

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

def getSingleSpline(
    sketchCurves: list) -> adsk.core.NurbsCurve3D:

    ui = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui  = app.userInterface

        curves = []
        sketchCurve: adsk.fusion.SketchCurve
        for sketchCurve in sketchCurves:
            nurbs: adsk.core.NurbsCurve3D
            if sketchCurve.geometry.objectType == adsk.core.NurbsCurve3D.classType():
                nurbs = sketchCurve.worldGeometry
            else:
                nurbs = sketchCurve.worldGeometry.asNurbsCurve

            if len(curves) == 1:
                firstCurve: adsk.core.NurbsCurve3D = curves[0]
                newCurve: adsk.core.NurbsCurve3D = nurbs

                firstStart: adsk.core.Point3D = firstCurve.controlPoints[0]

                newStart: adsk.core.Point3D = newCurve.controlPoints[0]
                newEnd: adsk.core.Point3D = newCurve.controlPoints[len(newCurve.controlPoints) - 1]
                
                if firstStart.isEqualTo(newStart) or firstStart.isEqualTo(newEnd):
                    curves[0] = reverseNurbsCurve(curves[0])

            if len(curves) > 0:
                previousCurve: adsk.core.NurbsCurve3D = curves[len(curves) - 1]
                newCurve: adsk.core.NurbsCurve3D = nurbs

                existingEnd: adsk.core.Point3D = previousCurve.controlPoints[len(previousCurve.controlPoints) - 1]
                newStart: adsk.core.Point3D = newCurve.controlPoints[0]

                if not existingEnd.isEqualTo(newStart):
                    nurbs = reverseNurbsCurve(nurbs)

            curves.append(nurbs)

        bigCurve: adsk.core.NurbsCurve3D = None
        nurb: adsk.core.NurbsCurve3D
        for nurb in curves:
            if bigCurve is None:
                bigCurve = nurb
            else:
                bigCurve = bigCurve.merge(nurb)

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

def reverseNurbsCurve(
    curve: adsk.core.NurbsCurve3D) -> adsk.core.NurbsCurve3D:

    (_, points, degree, knots, isRational, weights, isPeriodic) = curve.getData()
    points = points[::-1]
    weights = weights[::-1]

    if isRational:
        return adsk.core.NurbsCurve3D.createRational(points, degree, knots, weights, isPeriodic)
    else:
        return adsk.core.NurbsCurve3D.createNonRational(points, degree, knots, isPeriodic)

def selectEnt(
    msg :str, 
    filtterStr :str) -> adsk.core.Selection :

    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        sel = ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None

正直、"複数のスケッチ線を単一のスプラインにするのは無理" と
示すために取り組んだのですが、結果的に出来る事が分かりました。
これ、需要があると思う。