Creating nurbs surface using degree, control points, knots and weights

Can I get an example, please?
I’ve been looking at this example (on the bottom of the page):

Also, looking through the API: (NurbsSurface — rhino3dm 8.4.0 documentation)

There seems to be no SET functions only GET functions.

Also:
KnotsV.Count → no function Count
KnotsU.Count → no function Count

Here’s my unsuccessful attempt to translate this in CPython (rhino3dm)

def TST(is_rational = None, dim = None, u_degree = None, v_degree = None, u_cv_count = None, v_cv_count = None, u_knot = None, v_knot = None):
    if is_rational == None:
        is_rational = False
    if dim == None:
        dim = 3
    if u_degree == None:
        u_degree = 2
    if v_degree == None:
        v_degree = 3
    if u_cv_count == None:
        u_cv_count = 3
    if v_cv_count == None:
        v_cv_count = 5
    
    # make up a quadratic knot vector with no interior knots
    if u_knot == None:
        u_knot = [0.0, 0.0, 1.0, 1.0]
    
    # make up a cubic knot vector with one simple interior knot
    if v_knot == None:
        v_knot = [0.0, 0.0, 0.0, 1.5, 2.0, 2.0, 2.0]
    
    # Rational control points can be in either homogeneous
    # or euclidean form. Non-rational control points do not
    # need to specify a weight.
    CV = dict(((i,j),None) for i in range(2) for j in range(3))
    #print(CV)
    for i in range(0, u_cv_count):
        for j in range(0, v_cv_count):
            CV[i,j] = rhino3dm.Point3d(i, j,0)#i-j
    
    # creates internal uninitialized arrays for
    # control points and knots
    nurbs_surface = rhino3dm.NurbsSurface.Create(dim, is_rational, u_degree + 1, v_degree + 1, u_cv_count, v_cv_count)
    
    # add the knots
    for i in range(0, len(nurbs_surface.KnotsU)):
        nurbs_surface.KnotsU[i] = u_knot[i]
    for j in range(0, len(nurbs_surface.KnotsV)):
        nurbs_surface.KnotsV[j] = v_knot[j]
    
    # add the control points
    for i in range(0, nurbs_surface.Points.CountU):
        for j in range(0, nurbs_surface.Points.CountV):
            # SetControlPoint(self: NurbsSurfacePointList, u: int, v: int, cp: Point3d) -> bool
            nurbs_surface.Points.SetControlPoint(i, j, Rhino.Geometry.ControlPoint(CV[i, j]))
    
    if nurbs_surface.IsValid:
        model = rhino3dm.File3dm()
        model.Objects.AddSurface(nurbs_surface)
        #sc.doc.Views.Redraw()
        model.Write('test.3dm', 0)
    else:
        print('nurbs_surface.IsValid = False')

I’m a bit stuck here:
nurbs_surface.Points.SetControlPoint(i, j, Rhino.Geometry.ControlPoint(CV[i, j]))

SetControlPoint() function doesn’t exist in rhino3dm and there’s no object rhino3dm.ControlPoint() so I’m not sure what to do.

Hows this?

import rhino3dm

rational = False
dim = 3
u_cv_count = 6
v_cv_count = 6
u_degree = 3
v_degree = 3
u_order = u_degree + 1
v_order = v_degree + 1

ns = rhino3dm.NurbsSurface.Create(dim, rational, u_order, v_order, u_cv_count, v_cv_count)

#generate knots
ns.KnotsU.CreateUniformKnots(1.0)
ns.KnotsV.CreateUniformKnots(1.0)

#create points
for u in range(0, u_cv_count):
    for v in range(0, v_cv_count):
        pt = rhino3dm.Point4d(u,v,u+v, 1.0)
        ns.Points[(u,v)] = pt

print('Is Surface Valid: ' + str(ns.IsValid))

A thread with a similar request: Help Needed with Creating a NURBS Surface Using rhino3dm.js

Thanks for the reply @fraguada

I also achieved some progress on my side but with your code I get the same error when I try to add the nurbs surface to the model:

import rhino3dm

rational = False
dim = 3
u_cv_count = 6
v_cv_count = 6
u_degree = 3
v_degree = 3
u_order = u_degree + 1
v_order = v_degree + 1

ns = rhino3dm.NurbsSurface.Create(dim, rational, u_order, v_order, u_cv_count, v_cv_count)

#generate knots
ns.KnotsU.CreateUniformKnots(1.0)
ns.KnotsV.CreateUniformKnots(1.0)

#create points
for u in range(0, u_cv_count):
    for v in range(0, v_cv_count):
        pt = rhino3dm.Point4d(u,v,u+v, 1.0)
        ns.Points[(u,v)] = pt

if ns.IsValid:
    print('Is Surface Valid: ' + str(ns.IsValid))
    model = rhino3dm.File3dm()
    model.Objects.AddSurface(ns)
    #sc.doc.Views.Redraw()
    model.Write('test.3dm', 0)
else:
    print('Is Surface Valid: ' + str(ns.IsValid))

Try

model.Objects.Add(ns, None)

The documentation also tells you to give ob attributes with AddSurface: File3dmObjectTable — rhino3dm 8.4.0 documentation

Yeah, but what are these attributes supposed to be?
It doesn’t say.

an instance of object attributes, but you can try the None if you want to. But the object attributes are: ObjectAttributes — rhino3dm 8.4.0 documentation

This worked, thanks.

I see, yes, these are good to be entered.
But if you look just at the File3dmObjectTable class you don’t really know what is meant by attributes

here’s my final working example:

def TST():
    dimension = 3
    degreeU = 3
    degreeV = 3
    numCtrlPtsU = 4
    numCtrlPtsV = 4
    numKnotsU = 8
    numKnotsV = 8
    isRational = False
    continuity = 2
    KnotVectorU = [0.0, 0.0, 0.0, 0.0, 50.0, 50.0, 50.0, 50.0][1:-1]
    KnotVectorV = [0.0, 0.0, 0.0, 0.0, 50.0, 50.0, 50.0, 50.0][1:-1]
    ControlPtList = [[0.0, 0.0, 0.0],
                     [0.0, 15.0, 0.0],
                     [0.0, 30.0, 0.0],
                     [0.0, 45.0, 0.0],
                     [15.0, 0.0, 0.0],
                     [15.0, 15.0, -30.0],
                     [15.0, 30.0, 0.0],
                     [15.0, 45.0, 0.0],
                     [30.0, 0.0, 0.0],
                     [30.0, 15.0, 0.0],
                     [30.0, 30.0, 30.0],
                     [30.0, 45.0, 0.0],
                     [45.0, 0.0, 0.0],
                     [45.0, 15.0, 0.0],
                     [45.0, 30.0, 0.0],
                     [45.0, 45.0, 0.0]]
    WeightsList = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
    
    nurbs_surface = rhino3dm.NurbsSurface.Create(dimension, isRational, degreeU + 1, degreeV + 1, numCtrlPtsU, numCtrlPtsV)
    
    # add the knots
    for i in range(0, len(nurbs_surface.KnotsU)):
        nurbs_surface.KnotsU[i] = KnotVectorU[i]
    
    for j in range(0, len(nurbs_surface.KnotsV)):
        nurbs_surface.KnotsV[j] = KnotVectorV[j]

    point4d_list = []
    # add the control points
    for i in range(0, len(ControlPtList)):
        pt4d = [ControlPtList[i][0], ControlPtList[i][1], ControlPtList[i][2], WeightsList[i]]
        #print(pt4d)
        point4d_list.append(rhino3dm.Point4d(pt4d[0], pt4d[1], pt4d[2], pt4d[3]))
        

    i = 0
    for u in range(numCtrlPtsU):
        for v in range(numCtrlPtsV):
            #print((u, v), i)
            nurbs_surface.Points.__setitem__((u, v), point4d_list[i])
            i = i + 1
    
    #
    if nurbs_surface.IsValid:
        print('nurbs_surface.IsValid = True')
        model = rhino3dm.File3dm()
        model.Objects.Add(nurbs_surface, None)
        model.Write('test0.3dm', 0)
    else:
        print('nurbs_surface.IsValid = False')

1 Like