Making a NURBS surface that is periodic in U

Making a NURBS surface that is periodic in U

ginavenolia
Contributor Contributor
546 Views
2 Replies
Message 1 of 3

Making a NURBS surface that is periodic in U

ginavenolia
Contributor
Contributor

I'm trying to make a (roughly) cylindrical shape where the barrel of the cylinder is a NURBS surface. The cylinder endcaps appear but the barrel doesn't.

ginavenolia_0-1709664894279.png

Something is so wrong with the NURBS surface - so much so that it crashes Fusion when I try to examine it in the debugger. What is wrong with my code - in particular the call to NurbsSurface.create?

 

 

 

 

    uCount = 12
    vCount = 12

    def getPoint(u: int, v: int) -> Point3D:
        angle = 2.0 * math.pi * u / uCount
        x = 5.0 * math.cos(angle)
        y = 5.0 * math.sin(angle)
        z = v
        return Point3D.create(x, y, z)

    surface = NurbsSurface.create(
        degreeU=1,
        degreeV=1,
        controlPointCountU=uCount + 1,
        controlPointCountV=vCount,
        controlPoints=[
            getPoint(u, v)
            for v in range(vCount)
            for u in range(uCount + 1)
        ],
        knotsU=[float(i) for i in range(uCount + 1)],
        knotsV=[float(i) for i in range(vCount + 2)],
        weights=[],
        propertiesU=NurbsSurfaceProperties.ClosedNurbsSurface + NurbsSurfaceProperties.PeriodicNurbsSurface,
        propertiesV=NurbsSurfaceProperties.OpenNurbsSurface,
    )

    # Putting a breakpoint here and examining surface in the debugger CRASHES Fusion

    botCurve = NurbsCurve3D.createNonRational(
        controlPoints=[getPoint(u, 0) for u in range(uCount + 1)],
        degree=1,
        knots=[float(i) for i in range(uCount + 1)],
        isPeriodic=True,
    )

    topCurve = NurbsCurve3D.createNonRational(
        controlPoints=[getPoint(u, vCount - 1) for u in range(uCount + 1)],
        degree=1,
        knots=[float(i) for i in range(uCount + 1)],
        isPeriodic=True,
    )

    midCurve = NurbsCurve3D.createNonRational(
        controlPoints=[getPoint(0, v) for v in range(vCount)],
        degree=1,
        knots=[float(i) for i in range(vCount + 2)],
        isPeriodic=False,
    )

    botPoint = getPoint(0, 0)
    topPoint = getPoint(0, vCount - 1)

    bodyDefinition = BRepBodyDefinition.create()
    lumpDefinition = bodyDefinition.lumpDefinitions.add()
    shellDefinition = lumpDefinition.shellDefinitions.add()

    botVertex = bodyDefinition.createVertexDefinition(botPoint)
    topVertex = bodyDefinition.createVertexDefinition(topPoint)

    botPlane = Plane.create(
        Point3D.create(0.0, 0.0, botPoint.z),
        Vector3D.create(0.0, 0.0, -1.0)
    )

    topPlane = Plane.create(
        Point3D.create(0.0, 0.0, topPoint.z),
        Vector3D.create(0.0, 0.0, 1.0)
    )

    botEdge = bodyDefinition.createEdgeDefinitionByCurve(botVertex, botVertex, botCurve)
    topEdge = bodyDefinition.createEdgeDefinitionByCurve(topVertex, topVertex, topCurve)
    midEdge = bodyDefinition.createEdgeDefinitionByCurve(topVertex, botVertex, midCurve)

    botFace = shellDefinition.faceDefinitions.add(botPlane, False)
    botLoop = botFace.loopDefinitions.add()
    botLoop.bRepCoEdgeDefinitions.add(botEdge, True)

    topFace = shellDefinition.faceDefinitions.add(topPlane, False)
    topLoop = topFace.loopDefinitions.add()
    topLoop.bRepCoEdgeDefinitions.add(topEdge, False)

    midFace = shellDefinition.faceDefinitions.add(surface, False)
    midLoop = midFace.loopDefinitions.add()
    midLoop.bRepCoEdgeDefinitions.add(topEdge, False)
    midLoop.bRepCoEdgeDefinitions.add(midEdge, False)
    midLoop.bRepCoEdgeDefinitions.add(botEdge, True)
    midLoop.bRepCoEdgeDefinitions.add(midEdge, True)

    bodyDefinition.doFullHealing = False
    body = bodyDefinition.createBody()

    print(f"Is valid: {bodyDefinition.isValid}")

    for outcome in bodyDefinition.outcomeInfo:
        print(f"Outcome: {outcome}")

    app = Application.get()
    designProduct = Design.cast(app.activeProduct)
    component = designProduct.activeComponent
    baseFeatures = component.features.baseFeatures

    baseFeature = baseFeatures.add()
    baseFeature.startEdit()
    component.bRepBodies.add(body, baseFeature)
    baseFeature.finishEdit()

 

 

 

0 Likes
Accepted solutions (1)
547 Views
2 Replies
Replies (2)
Message 2 of 3

MichaelT_123
Advisor
Advisor
Accepted solution

Hi Mr/Mrs  Ginavenolia,

 

Consider checking your code:

 

        knotsU=[float(i) for i in range(uCount + 1)],       

        knotsV=[float(i) for i in range(vCount + 2)],

 

based on:

 

knots

double[]

An array of numbers that define the knot vector of the spline.

The knots is an array of (>=degree + N + 1) numbers,

where N is the number of control points

 

Regards

MichaelT

MichaelT
0 Likes
Message 3 of 3

ginavenolia
Contributor
Contributor

I see now that's true. I was mislead because NurbsCurve3D.create requires fewer knots when isPeriodic is True, and by the parameter validation on NurbsSurface.create accepting both numbers of knots (though returning a poisoned object at the smaller number).

0 Likes