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";
	}