Flattened control point arrays in scripting use U-V ordering:
(0,0)...(0,cntV-1), (1,0)....(1,cntV-1),(cntU-1,0)...(cntU-1,cntV-1)
However, for the C++ API, control point arrays are ordered inversely (V-U):
(0,0)...(cntU-1,0), (0,1)....(cntU-1,1)...(0,cntV-1)...(cntU-1,cntV-1)
This means that if you are working with control point arrays in scripting, you can get and set control point arrays without any conversion issues. However, if you are working with the C++ API, you must invert the ordering of the array before passing control point arrays to functions like NurbsSurface::Set and X3DObject::AddNurbsSurface.
C++ API Example: Convert Control Point Array from U-V to V-U Ordering
This function is typically used to prepare the data for creating a nurbs surface mesh with X3DObject::AddNurbsSurface or NurbsSurfaceMesh::Set. The size of the resulting array is in_nbU x in_nbV and the U-V points are converted to V-U order to match the behavior of the nurbs surface in scripting.
// Convert a CDoubleArray containing xyzw UV coordinates to a CVector4Array void ConvertDoubleArrayToVector4Array ( CDoubleArray& in_array, LONG in_nbU, LONG in_nbV, CVector4Array& out_array ) { LONG nSize = in_nbU * in_nbV; if ( in_array.GetCount() < 4 * nSize ) { Assert( in_array.GetCount() >= 4 * nSize ) ; nSize = in_array.GetCount()/4; } out_array.Resize( nSize ); // e.g. Original data is UV (0,0)...(0,cntV-1), (1,0)....(1,cntV-1),(cntU-1,0)...(cntU-1,cntV-1) // and we return data as (0,0)...(cntU-1,0), (0,1)....(cntU-1,1)...(0,cntV-1)...(cntU-1,cntV-1) LONG l = 0; for ( LONG i=0; i<in_nbU; i++ ) // U { for ( LONG j=0; j<in_nbV; j++ ) // V { LONG k = i + j*in_nbU; double x = in_array[l++]; double y = in_array[l++]; double z = in_array[l++]; double w = in_array[l++]; CVector4 v4(x*w,y*w,z*w,w); out_array[k] = v4; } } }