As mentioned above, 3ds Max itself uses a different internal representation of NURBS objects than the API does. The API is simply a means to access these internal 3ds Max NURBS objects and allow them to be manipulated.
The object used in communication between the internal 3ds Max NURBS objects and the classes in the SDK available to work with these objects is the NURBSSet. There are also two global functions used in this communication. These are CreateNURBSObject() and GetNURBSSet(). How these are used is described below:
The API can be used to create new NURBS objects. This is done by adding the objects (points, curves and surfaces) to an item called a NURBS 'set' and calling the global function CreateNURBSObject(). The NURBSSet is a container for the objects. Then the global function CreateNURBSObject() makes an internal 3ds Max NURBS object out of the set.
As an example, consider the following code fragment that creates a NURBSCVCurve object (with NURBSControlVertex sub-objects) and puts it in the scene:
// Create an empty NURBSSet object NURBSSet nset; // Allocate a new NURBSCVCurve and set the knots and CVs NURBSCVCurve *c = new NURBSCVCurve(); c->SetName(_T("CV Curve")); c->SetNumCVs(4); c->SetOrder(4); c->SetNumKnots(8); for (int k = 0; k < 4; k++) { c->SetKnot(k, 0.0); c->SetKnot(k+4, 1.0); } NURBSControlVertex cv; cv.SetPosition(0, Point3(0, 0, 50)); c->SetCV(0, cv); cv.SetPosition(0, Point3(-100, 0, 50)); c->SetCV(1, cv); cv.SetPosition(0, Point3(-100, 100, 50)); c->SetCV(2, cv); cv.SetPosition(0, Point3(0, 100, 50)); c->SetCV(3, cv); // Add the NURBSCVCurve object to the set nset.AppendObject(c); // Create the NURBS object from the NURBSSet Matrix3 mat(1); Object *obj = CreateNURBSObject(ip, &nset, mat); // Create the node in the scene and point it at the NURBS object INode *node = ip->CreateObjectNode(obj); node->SetName(_T("NURBS Set 1"));
The NURBS object created (obj) will have the Class_ID: EDITABLE_SURF_CLASS_ID.
The API can also be used to modify the properties of existing NURBS objects in the scene. To gain access to an internal 3ds Max NURBS object you must have the data copied into a NURBSSet. This is done using the global function GetNURBSSet(). You can then use the methods of the NURBSSet to access the objects. After checking the type of the object you can cast it to the appropriate class and use that class's methods to alter the item.
For example, the following sample code attempts to grab the first NURBS sub-object from the first node in the current selection set. It then checks if it's a blend surface and if so adjust one of the tension parameters.
// Get the first selected node INode* node = ip->GetSelNode(0); if (!node) return; // Get the object reference of the node Object* obj = node->GetObjectRef(); // Make sure it's a NURBS object if (obj->ClassID() == EDITABLE_SURF_CLASS_ID) { NURBSSet getSet; BOOL okay = GetNURBSSet(obj, ip->GetTime(), getSet, TRUE); if (okay) { NURBSObject *nObj; nObj = getSet.GetNURBSObject(0), ip->GetTime()); if (nObj->GetType() == kNBlendSurface) { // It's a blend, adjust the tension NURBSBlendSurface *bSurf = ( NURBSBlendSurface *)nObj; bSurf->SetTension(ip->GetTime(), 0, 2.0); } } }
There are other global functions that may be used to modify NURBS objects. These functions are documented at the end of this topic. For instance, developers can use the function BreakSurface() to take an existing NURBS surface and break it into two separate surfaces.