Mel Script - Nurbs Surface Data [API]

 NURBS surfaces are mathematically calculated using parametric equations and a set of control points ordered into a patch. NURBS surfaces are able to be dynamically tessellated, unlike polygons. This gives them certain advantages since they offer precise surface information at any point on the surface. The degree of NURBS curves indicates the highest power of the polynomial equation used to generate it. For example, a curve with degree 1 will basically use linear interpolation between the control points, ie, it will generate straight lines between all control points. Normally we use cubic curves since they give us curve continuity and are computationally cheaper than higher degree curves.

 Creating NURBS Surface Primitives The following example creates all of the Nurbs Primitives available within Maya. Normally if you are creating NURBS Surfaces, if you are not using a primitive object, then often you use sets of curves to create Lofts or Birail surfaces.

 ```  // create a sphere sphere -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 4 -ch 1; xform -t -7 0 0; // create a nurbs cube nurbsCube -p 0 0 0 -ax 0 1 0 -w 1 -lr 1 -hr 1 -d 3 -u 1 -v 1 -ch 1; xform -t -5 0 0; // create a cylinder cylinder -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -hr 2 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 1 -ch 1; xform -t -3 0 0; // create a cone cone -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -hr 2 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 1 -ch 1; xform -t -1 0 0; // create a plane nurbsPlane -p 0 0 0 -ax 0 1 0 -w 1 -lr 1 -d 3 -u 1 -v 1 -ch 1; xform -t 1 0 0; // create a torus torus -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -msw 360 -r 1 -hr 0.5 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 4 -ch 1; xform -t 3 0 0; // create a NURBS circle circle -c 0 0 0 -nr 0 1 0 -sw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -ch 1; xform -t 5 0 0; // create a NURBS square nurbsSquare -c 0 0 0 -nr 0 1 0 -sl1 1 -sl2 1 -sps 1 -d 3 -ch 1; xform -t 7 0 0; ```

 Finding All Nurbs Surfaces in a Scene Using ls we can retrieve a list of all NURBS surfaces.

 ``` // get a list of all surfaces in the scene \$surfaces = `ls -type "nurbsSurface"`; // loop through each surface for( \$surface in \$surfaces ) { // print the name of the surface print( \$surface + "\n" ); } ```

 Accessing Nurbs CV's The control vertices of a NURBS surface are arranged in a 2D grid layout. We need to bit of math to determine how many CV's we have, after that the easiet way to get to the point values is to use xform.

 ``` proc getNurbsSurfaceData( string \$nurb ) { // get U information \$degreeU = `getAttr (\$nurb+ ".degreeU")`; \$spansU = `getAttr (\$nurb+ ".spansU")`; \$numCVsU = \$spansU + \$degreeU; // get V information \$degreeV = `getAttr (\$nurb+ ".degreeV")`; \$spansV = `getAttr (\$nurb+ ".spansV")`; \$numCVsV = \$spansV + \$degreeV; // output the weighting data for a nurbs surface for(\$i=0;\$i<\$numCVsU;\$i++) { for(\$k=0;\$k<\$numCVsV;\$k++) { // select the CV to query select -r (\$nurb+".cv["+\$i+"]["+\$k+"]"); // use xform to get it's position. Remove the -worldSpace // flag if you want the values in local space \$cv = `xform -worldSpace -q -t`; // print CV print( \$cv[0] +" "+ \$cv[1] +" "+ \$cv[2] +"\n"); } } } ```

 Accessing Nurbs Knot Vectors Knot vectors are used by the Cox-De-Boor algorithm, the core of NURBS surface calculation.

 ``` proc int getSurfaceKnots(string \$nurb,float \$uKnots[],float \$vKnots[]) { // create info Node. string \$infoNode ; if( catch( \$infoNode = `createNode surfaceInfo` ) ) { return 0; // failed } // connect surface on to the info node. string \$outAttr = \$nurb + ".local" ; string \$inAttr = \$infoNode + ".is" ; connectAttr \$outAttr \$inAttr ; // read the knots. \$uKnots = `getAttr (\$infoNode + ".knotsU")`; \$vKnots = `getAttr (\$infoNode + ".knotsV")`; // delete surface info node. delete \$infoNode ; // worked return 1; } ```

 Accessing Nurbs Surface Info It's often useful to know how many spans a surface has, or whether it is periodic. This can be done by querying the values from a curve Info node.

 ``` proc int getSurfaceInfo(string \$nurb) { // Curve Type \$formU = `getAttr (\$nurb + ".formU")`; \$formV = `getAttr (\$nurb + ".formV")`; print("U_Type: " + \$formU + "\nV_Type: " + \$formV + "\n\n"); // Curve Degree \$degreeU = `getAttr (\$nurb + ".degreeU")`; \$degreeV = `getAttr (\$nurb + ".degreeV")`; print("DegreeU: " + \$degreeU + "\nDegreeV: " + \$degreeV + "\n\n"); // Surface Spans in U and V \$nspansU = `getAttr (\$nurb + ".spansU")`; \$nspansV = `getAttr (\$nurb + ".spansV")`; print("SpansU: "+ \$nspansU +"\nSpansV: "+ \$nspansV +"\n\n"; } ```