Help Needed with Creating a NURBS Surface Using rhino3dm.js

Hello everyone,

I’m currently facing a challenge while trying to create a NURBS surface using rhino3dm.js based on control points, but unfortunately, I haven’t been successful so far. I’ve attempted to adapt examples from various sources, including C# and Python, to my situation. However, I keep encountering errors, and nothing seems to work as expected.

Could anyone please provide me with a simple example of how to achieve this? Below is my code, which results in an invalid surface, and my 3dm file appears to be empty. I’m not sure what I’m missing or doing wrong. Any guidance or suggestions would be greatly appreciated.

javascriptCopy code

const is_rational = false;
const number_of_dimensions = 3;
const u_degree = 3;
const v_degree = 3;
const u_control_point_count = 4;
const v_control_point_count = 5;

var nurbs_surface = rhino.NurbsSurface.create(number_of_dimensions, is_rational, u_degree, v_degree, u_control_point_count, v_control_point_count);

let u_knots = [0, 0, 0, 20];
let v_knots = [0, 0, 0, 10, 20];

for (let u = 0; u < u_control_point_count; u++) nurbs_surface.knotsU().set(u, u_knots[u]);
for (let v = 0; v < v_control_point_count; v++) nurbs_surface.knotsV().set(v, v_knots[v]);

let points = [
    [0, 0, 0, 1],
    [0, 3.3333333333333326, 5, 1],
    [0, 10, 5, 1],
    [0, 16.66666666666667, 0, 1],
    [0, 20, 0, 1],
    [6.666666666666666, 0, 10, 1],
    [6.666666666666666, 3.333333333333334, 0, 1],
    [6.666666666666664, 9.999999999999988, 10, 1],
    [6.66666666666667, 16.66666666666667, 0, 1],
    [6.666666666666666, 19.99999999999999, 0, 1],
    [13.333333333333332, 0, 0, 1],
    [13.333333333333321, 3.3333333333333317, 7, 1],
    [13.333333333333336, 10.000000000000016, 7, 1],
    [13.333333333333325, 16.66666666666665, 0, 1],
    [13.333333333333332, 20.000000000000004, 0, 1],
    [20, 0, 10, 1],
    [20, 3.3333333333333326, 0, 1],
    [19.999999999999996, 10, 10, 1],
    [20.00000000000001, 16.66666666666667, 0, 1],
    [20, 20, 10, 1],
];

let surfPoint = nurbs_surface.points();

for (let u = 0; u < u_control_point_count; u++) {
    for (let v = 0; v < v_control_point_count; v++) {
        surfPoint.set(u, v, points[u + v * u_control_point_count]);
    }
}
nurbs_surface.setDomain(0, [0, 20]);
nurbs_surface.setDomain(1, [0, 20]);

console.log(nurbs_surface.isValid);
let doc = new rhino.File3dm();
doc.objects().add(nurbs_surface.toNurbsSurface(), null);
const options = new rhino.File3dmWriteOptions();
options.version = 7;
let bufferWrite = doc.toByteArrayOptions(options);

fs.writeFileSync("./test.3dm", bufferWrite);

Thank you in advance for any help you can provide. I’m really looking forward to getting past this roadblock with your assistance.

I’m trying this out and am seeing some issues with the NurbsSurface knot lists in js. They are null, and you cannot add anything to them. This isn’t the case in python. I just mention python since the js and py versions are based on the same binding code. I am investigating: Cannot build a valid NurbsSurface in js · Issue #588 · mcneel/rhino3dm · GitHub

@Nicolas_LABLAINE
check out this example to see if it helps: rhino-developer-samples/rhino3dm/js/node/SampleNurbsSurface/index.js at 8 · mcneel/rhino-developer-samples · GitHub

perfect, I just tested it and it works.
A big thank-you

1 Like

Thank you. I learned some tricks about creating surfaces!

btw, I wrapped another method: CommonObject.IsValidWithLog which returns an object in js in this format:

{bool: isValid, string: errorLog}

This is a general property on objects, and for surfaces it can help understand what might be wrong like wrong knot values, etc.

You can try it by using a build from our ci system, otherwise it will be included when rhino3dm 8.6.0 comes out in a few weeks.