Working with NURBS

3DS Max Plug-In SDK

Working with NURBS

See Also: Class NURBSObject, Class NURBSSurface, Class NURBSSet, Class NURBSControlVertex, Class NURBSPoint, Class NURBSCurve, Class NURBSFuseSurfaceCV, Class NURBSFuseCurveCV, Class TessApprox, Class Object, Class ShapeObject, Class Matrix3, Class Point3.

Overview

This section presents an overview of working with NURBS using the SDK. It defines some terms and concepts related to NURBS, describes the main classes used, provides an overview of some key concepts when using NURBS, and discusses the sample code available in the SDK. There is also a section of reference information for some global functions available.

The NURBS API

The NURBS API provides an interface into the NURBS objects used by MAX. Unlike much of the 3ds max API, the NURBS objects 3ds max provides don't use this API. Rather, the NURBS API has been added to allow developers to access the NURBS objects 3ds max uses internally. Using the API developer can create new NURBS objects or modify existing ones.

ClassIDs of the NURBS Objects

Developers can check if an object is a NURBS object by checking it ClassID(). If it matches any of the following

#define EDITABLE_SURF_CLASS_ID Class_ID(0x76a11646, 0x12a822fb)

#define FITPOINT_PLANE_CLASS_ID Class_ID(0x76a11646, 0xbadbeef)

#define EDITABLE_CVCURVE_CLASS_ID Class_ID(0x76a11646, 0x12a82144)

#define EDITABLE_FPCURVE_CLASS_ID Class_ID(0x76a11646, 0x12a82142)

then it's a NURBS object and the NURBS API may be used to manipulate it.

Necessary Include File

The main NURBS include file is \MAXSDK\INCLUDE\SURF_API.H. This is not included by default by MAX.H so you need to specifically include it via the following statement:

#include "surf_api.h"

Reference Information on NURBS Mathematics

Developers who wish to understand the mathematics of NURBS should see:

The NURBS Book: Les Piegl, Wayne Tiller, The NURBS Book (Berlin Heidelberg New York: Springer-Verlag, 1995). ISBN: 3-540-55069-0.

Providing Valid Data to the NURBS Methods

The NURBS API is not intended to be bomb proof, i.e. it is possible to pass values to the methods than can cause a crash. It is up to the developer to insure that valid data is provided. As with the rest of the SDK it is easy to write a piece of code that will crash 3ds max if improper values are supplied.

Definition of Terms

This section provides definitions of various terms used later in this topic and in the NURBS classes.

NURBS

The term NURBS stands for Non-Uniform Rational B-Splines. Specifically:

Non-Uniform means that the extent of a control vertex’s influence can vary. This is useful when modeling irregular surfaces.

Rational means that the equation used to represent the curve or surface is expressed as a ratio of two polynomials, rather than a single summed polynomial. The rational equation provides a better model of some important curves and surfaces, especially conic sections, cones, spheres, and so on.

A B-spline (for basis spline) is a way to construct a curve that is interpolated between three or more points. Shape curves you create in 3ds max using the Line tool and other Shape tools are Bézier curves, which are a special case of B-splines.

Point

A point in three-space. A Point Curve or Point Surface is constrained to pass through it’s points. Points behave somewhat like vertices for 3ds max spline objects, but their behavior is not identical and they are a distinct object type.

Curve

This is a NURBS Curve. There are two kinds of NURBS curves in MAX. A Point Curve is controlled by points, which always lie on the curve. A CV Curve is controlled by control vertices (CVs), which don’t necessarily lie on the curve.

CV

This is a Control Vertex of a NURBS Curve or NURBS Surface. It's a vertex that controls a CV Curve or CV Surface. The 3D location of each CV affects the shape of the curve or surface. CVs aren’t constrained to lie on the curve or surface. Each CV has a rational weight that can be used to adjust the influence of the CV on the curve’s or surface’s shape.

Point Curve

A NURBS curve defined by points. The points are constrained to lie on the curve.

CV Curve

A NURBS curve defined by CVs. The CVs don’t necessarily lie on the curve. Instead, they form a control lattice that affects the curvature of the curve.

Surface

This is an individual quadrilateral NURBS Surface. NURBS surfaces have essentially the same properties as NURBS curves, extended from a one-dimensional parameter space to two dimensions.

There are two kinds of NURBS surfaces: A Point Surface is controlled by points, which always lie on the surface. A CV Surface is controlled by control vertices (CVs). Instead of lying on the surface, CVs form a control lattice that surrounds the surface.

Point Surface

A NURBS surface defined by points. The points are constrained to lie on the surface. More than one NURBS solution is possible for a Point Surface.

CV Surface

A surface defined by CVs. Instead of lying on the surface, CVs form a control lattice that surrounds the surface.

Independent <object>

This is an object (point, curve, surface) that is not dependent on any other object.

Dependent <object>

This is an object (point, curve, surface) that depends on another object to define what it is. For example, a Blend Curve depends on the two curves that it blends between (as well as its own two tension parameters).

Constrained point

Another term for a dependent point. A NURBS Point that is dependent on either another Point, Curve, or Surface, and that exists either on the object or relative to it. The relative cases are XYZ-relative, along a normal, or along a tangent (or set of tangents for a surface-dependent constrained point).

Continuity

A curve is continuous if it is unbroken. There are different levels of continuity. A curve with an angle or cusp in it is C0 continuous¾that is, the curve is continuous but has no derivative at the cusp. A curve with no such cusps but whose curvature changes is C1 continuous. Its derivative is also continuous, but its second derivative is not. A curve with uninterrupted, unchanging curvature is C2 continuous. Both its first and second derivatives are also continuous.

A curve can have still higher levels of continuity, but for computer modeling these three are adequate. Usually the eye can’t distinguish between a C2 continuous curve and one with higher continuity.

Continuity and degree are related. A degree 3 equation can generate a C2 continuous curve. This is why higher-degree curves aren’t generally needed in NURBS modeling. Higher-degree curves are also less stable numerically, so using them isn’t recommended.

Different segments of a NURBS curve can have different levels of continuity. In particular, by placing CVs at the same location or very close together, you reduce the continuity level. Two coincident CVs sharpen the curvature. Three coincident CVs create an angular cusp in the curve. This property of NURBS curves is known as multiplicity. In effect, the additional one or two CVs combine their influence in that vicinity of the curve.

By moving one of the CVs away from the other, you increase the curve’s continuity level again. In MAX, multiplicity also applies when you fuse CVs. Fused CVs create a sharper curvature or a cusp in the curve. Again, the effect goes away if you unfuse the CVs and move one away from the other.

Multiplicity

The property that coincident or nearly coincident CVs reduce the continuity level of the curve or surface. Two coincident CVs locally increase curvature. Three coincident CVs (or more) create an angular cusp. Fusing CVs shows the effect of multiplicity.

Degree

The degree of a curve is highest exponent in the equation used to represent it. A linear equation is degree 1, a quadratic equation degree 2. NURBS curves typically are represented by cubic equations and have a degree of 3.

Order

The order of a curve refers to its mathematical order. For instance a cubic curve is order 4, a quadratic curve is order 3, a linear curve is order 2. This is one more than the degree of polynomial of any segment of the curve.

Iso Line

This is short for isoparametric line. It's a line of constant parameter value, similar to a contour line. Iso lines can be used to display a NURBS surface.

Segment

The portion of a curve between two of its controlling points or CVs.

Knot

This is a mathematical construct that helps define the span of control of CVs and blending functions that define NURBS Curves and Surfaces. The knots are an array of double precision values that determines the parameterization of a curve. . Values in the knot vector are nondecreasing. The knots specify the region of influence of the CVs on the curve. It is a way of partitioning the parameter space up into different segments. A B spline curve or a NURBS curve is a curve that is defined by a series of segments. On each one of the segments the curve is like a polynomial, or in the case of a rational one, it's like the ratio of polynomials. The knot vector describes how to partition the parameter space of the curve up for each of the different pieces of the polynomial.

Parameter space

In addition to their existence in 3D space, NURBS objects have a parameter space that includes the array of knot values. NURBS curves have a single U dimension in parameter space. NURBS surfaces have two dimensions, UV, in parameter space.

Refine

To increase the number of CVs on a curve or surface.

B-spline

Short for basis spline. A kind of spline generated by so-called basis functions. The advantage of B-splines over Bézier curves (which are a special case of B-splines) is that the control vertices (CVs) of a B-spline affect only their local region of the curve or surface.

Bézier curve

A curve modeled using a parametric polynomial technique. Bézier curves were developed by P. Bézier for computer modeling in automobile design. They are a special case of B-splines.

Overview of the Principal Classes

The following diagram shows the inheritance tree of the principal classes in the NURBS API. The base classes are shown at the top, and the inheritance hierarchy proceeds toward the bottom and to the right. NURBSObject is the main base class, with NURBSPoint, NURBSCurve and NURBSSurface also functioning as base classes.

Class Hierarchy

image\nurbs1_wmf.gif

The Base Class for NURBS Points, Curves and Surfaces:

Class NURBSObject

This is the base class for many of the other NURBS classes. It provides a set of methods that are common to the other classes such as getting and setting the name of the item, returning error messages, and determining the specific type of NURBS object. It also has a method to return a NURBSId which is an ID used to specify a particular object in communication between the NURBS classes.

Sets of NURBS Objects:

Class NURBSSet

This is the class used when developers want to create 3ds max NURBS objects, or retrieve data from existing 3ds max NURBS objects. The NURBSSet acts as a container for the other objects.

This class contains a table of the various NURBSObject derived entities (points, curves, surfaces) used to make up the set. Additionally it has two 'fuse' tables: one for fuse curves and one for fuse surfaces. These are used to allow the CVs in the curves or surfaces to be 'stitched' or 'fused' together so that if one curve or surface moves the other moves with it. This class also has information required to tessellate the objects to triangle meshes for use in the viewports and the production renderer.

Independent Points:

Independent Points are those that don't rely on other objects to define their location. This is different than the dependent (or constrained) points described later.

Class NURBSPoint

This class describes a point in 3 space. It is used as a base class for many of the dependent points in the API. It has methods to set and get the point position in various formats and floating point precisions. This is an abstract base class so only objects that are subclasses of this class can be created.

Class NURBSIndependentPoint

This class is derived from NURBSPoint. It is used to create an independent, free-standing point. There are methods to set the position of the point in various floating point formats and operators to compare points.

Class NURBSControlVertex

This is a Control Vertex of a NURBS Curve or NURBS Surface. This class shares may of the same properties as a NURBSPoint and has the added property of a rational weight. The weight value of a CV is rational. That is, it is relative to other CVs in the curve or surface. Changing the weight of all CVs at once has no effect, because this doesn’t change the ratio between weights.

Class NURBSTrimPoint

This class defines a point on a curve used to trim a portion of the curve from the point towards one of the ends of the curve.

Dependent (Constrained) Points:

The following classes provide the ability to create dependent points. Dependent points are related to the objects they depend on such that the relationship established initially remains if the point, curve or surface moves. For example, a point can be created such that it always remains a certain distance from another point. The options are XYZ-relative, along a normal, or along a tangent (or set of tangents for a surface-dependent constrained point).

All the following classes are derived from NURBSPoint.

Class NURBSPointConstPoint

This class is used to create a dependent point that lies at a point or relative to it. It is a point constrianed relative to another point. This can be a point used to define a point surface or point curve, it can be a trim point, or just a point in space.

Class NURBSCurveConstPoint

This class is used to create a dependent point that lies on a curve or relative to it.

Class NURBSCurveCurveIntersectionPoint

This class is used to create a dependent point at the intersection of two curves.

Class NURBSSurfConstPoint

This class is used to create a dependent point on a surface or related to it.

Independent Curves:

The following classes provide the ability to create independent curves.

Class NURBSCurve

This base class describes the properties of a NURBS curve. This includes its open/closed state, and number of trim points. The Evaluate() method is used to compute points and tangents on the curve.

Class NURBSPointCurve

This class is derived from NURBSCurve. It defines a curve that uses points to describe its shape. All the points lie on the curve itself. There are methods to get/set the number of points in the curve, get/set the points themselves, refine the curve (add points without changing its shape), and to get/set the transformation matrix used by the curve to position it within a NURBSSet.

Class NURBSCVCurve

This class is derived from NURBSCurve. It defines a curve that uses control vertices (CVs) to describe its shape. The CVs define a control lattice which surrounds the curve. This class has methods to close the curve, set its order, number of knots and number of CVs, and get/set the knots and CVs. There is also a method to add additional CVs to the curve.

Dependent Curves:

The following classes are used to create dependent curves. A dependent curve is an object that depends on one or more other objects to define what it is. For example, a Blend Curve depends on the two parent curves that it blends between when it was created (as well as on its two tension parameters).

All the following classes are derived from NURBSCurve.

Class NURBSBlendCurve

This class defines a dependent blend curve. A blend curve connects the specified end of one curve to the specified end of another, blending the curvature of the parents to create a smooth curve between them.

Class NURBSOffsetCurve

This class defines a dependent offset curve. An offset curve is offset from the original, parent curve. It lies in the same plane as its parent, and is normal to the original.

Class NURBSXFormCurve

This class defines a dependent transform (xform) curve. A transform curve is a copy of the original curve with a different position, rotation, or scale

Class NURBSMirrorCurve

This class defines a dependent mirror curve. A mirror curve is similar to a mirror object that you create using the Mirror tool (on the 3ds max toolbar) or the Mirror modifier. It is the original curve relfected about one or two axes.

Class NURBSFilletCurve

This class defines a dependent fillet curve. A fillet is a curve that creates a circular arc corner between two parent curves.

Class NURBSChamferCurve

This class defines a dependent chamfer curve. A chamfer is a curve that creates a straight line corner between two parent curves.

Class NURBSIsoCurve

This class defines a dependent iso curve. U and V iso curves are dependent curves created along lines of constant parameter value of a NURBS surface. Note the difference between "Iso Lines", which are a display artifact, and "Iso Curves" which are the dependent objects.

Independent Surface:

Class NURBSSurface

This base class describes the properties of a NURBS surface. This includes its material ID, texture/tiling options, renderable state, and open/closed state, and normal inverted state. The Evaluate() method is used to compute points and tangents on the surface.

Class NURBSPointSurface

This class is derived from NURBSSurface. It defines a surface that uses points to describe its shape. This class has methods to close the surface in U and V, set the number of points in U and V, and get/set the points in U and V. There is also a method to add additional points to the surface. The point surface has a transformation matrix used to set the position of the surface within a NURBSSet.

Class NURBSCVSurface

This class is derived from NURBSSurface. It defines a surface that uses control vertices (CVs) to describe its shape. The CVs define a control lattice which surrounds the surface. This class has methods to close the surface in U and V, set its order in U and V, set the number of knots and CVs in U and V, and get/set the knots and CVs in U and V. There is also a method to add additional CVs to the surface. The CV surface has a transformation matrix used to position the surface within a NURBSSet.

Dependent Surfaces:

Dependent surfaces are surface sub-objects whose geometry depends on other surfaces or curves in the NURBS model. When you change the geometry of the original parent surface or curve, the dependent surface changes as well.

Class NURBSBlendSurface

This class defines a dependent blend surface. A blend surface connects the edge of one surface to the edge of another, blending the curvature of the parents to create a smooth surface between them.

Class NURBSOffsetSurface

This class defines a dependent offset surface. An Offset surface is offset a specified distance from the original along the parent surface’s normals.

Class NURBSXFormSurface

This class defines a dependent transform (xform) surface. A transform surface is a copy of the original surface with a different position, rotation, or scale

Class NURBSMirrorSurface

This class defines a dependent mirror surface. A mirror surface is similar to a mirror object that you create using the Mirror tool (on the 3ds max toolbar) or the Mirror modifier. It is the original surface relfected about one or two axes.

Class NURBSRuledSurface

This class defines a dependent ruled surface. A ruled surface is generated from two curve sub-objects. It lets you use curves to design the two opposite borders of a surface.

Class NURBSULoftSurface

This class defines a dependent U Loft surface. A U Loft surface interpolates a surface across multiple curve sub-objects. The curves become U-axis contours of the surface.

Class NURBSExtrudeSurface

This class defines a dependent extrude surface. An extrude surface is extruded from a curve sub-object. It is similar to a surface created with the Extrude modifier. The advantage is that an extrude sub-object is part of the NURBS model, so you can use it to construct other curve and surface sub-objects

Class NURBSLatheSurface

This class defines a dependent lathe surface. A lathe surface is generated from a curve sub-object. It is similar to a surface created with the Lathe modifier. The advantage is that a lathe sub-object is part of the NURBS model, so you can use it to construct other curve and surface sub-objects.

Class NURBSCurveSurfaceIntersectionPoint

This class is used to create a dependent point at the intersection of a curve and a surface.

Class NURBSProjectNormalCurve

This class provides access to the Normal Proejcted Curve. A Normal Projected curve lies on a surface. It is based on an existing curve, which is projected onto the surface in the direction of the surface's normals

Class NURBSProjectVectorCurve

This class provides access to the Vector Projected Curve. A Vector Projected curve lies on a surface. This is almost the same as a Normal Projected curve, except that the projection from the existing curve to the surface is in the direction of a vector that you can control. Vector projected curves may be used for trimming.

Class NURBSSurfaceNormalCurve

This provides access to the Surface Normal Curve. This is a curve created at a specified distance from a surface and normal to it.

Class NURBSSurfSurfIntersectionCurve

This class provides access to the Surface-Surface Intersection Curve. This is a curve that is defined by the intersection of two surfaces. You can use surface-surface intersection curves for trimming.

Class NURBSCurveOnSurface

This class provides access to the CV curve on surface parameters. These curves can be used for trimming the surface they lie on.

Class NURBSPointCurveOnSurface

This class provides access to the point curve on surface parameters. These curves can be used for trimming the surface they lie on.

Class NURBSUVLoftSurface

This class provides access to the UV Loft Surface. This surface is similar to the U Loft surface, but has a set of curves in the V dimension as well as the U dimension.

Class NURBSNBlendSurface

This class provides access to the Multisided Blend surface. A Multisided Blend surface is a surface that "fills in" the edges defined by three or four other curve or surfaces. Unliked a regular, two-sided Blend surface, the curves or surfaces edges must form a closed loop¾that is, they must completely surround the opening the Multisided Blend will cover.

Class NURBS1RailSweepSurface

This class provides access to the 1-Rail Sweep Surface. A 1-Rail Sweep Surface uses at least two curves. One curve, the "rail," defines one edge of the surface. The other curves define the surface's cross sections. The cross-section curves should intersect the rail curve. If the cross sections don't intersect the rail, the resulting surface is unpredicable.

Class NURBS2RailSweepSurface

This class provides access to the 2-Rail Sweep Surface. A 2-Rail Sweep surface uses at least three curves. Two curves, the "rails," define the two edges of the surface. The other curves define the surface's cross sections. A 2-Rail Sweep surface is similar to a 1-Rail sweep. The additional rail gives you more control over the shape of the surface.

Class NURBSCapSurface

This class provides access to the Cap Surface. A Cap Surface is a surface that caps a closed curve or the edge of a closed surface. Caps are especially useful with extruded surfaces.

Class NURBSMultiCurveTrimSurface

This class provides access to the Multicurve Trim Surface which is a surface that is trimmed by multiple curves forming a loop.

Texture Mapping:

The following classes are those involved in texture mapping NURBS surfaces. In 3ds max 3.0 and later there may be 99 texture channels assigned to each surface.

Class NURBSSurface

This class (also described above) has a NURBSTextureChannelSet which is a table of pointers to all the mapping channels used by this surface. This class also has methods to return a reference to the NURBSTextureSurface associated with a specific channel.

Class NURBSTextureChannelSet

This class holds a table of pointers to all the NURBSTextureChannel data for a surface. There are methods to returns the table data by channel or by index and a method to add a new texture channel

Class NURBSTextureChannel

This class holds and provides access to a single texture channel. It holds the NURBSTextureSurface instance associated with the channel. It also holds the channel number (a number in the range 0 to 98), the tiling, offset, and angle parameters as well as the Generate UV flag.

Class NURBSTextureSurface

A texture surface is a surface associated with the surface sub-object. 3ds max uses the texture surface to control how materials are mapped. In effect, changing the texture surface stretches or otherwise changes the UV coordinates for the surface, altering the mapping. This class maintains a mapper type which controls how the texture surface generates the mapping. This class also provides access to the individual UV mapping coordinates. These coordinates are NURBSTexturePoint objects.

Class NURBSTexturePoint

This class holds and provides access to a single UV mapping coordinate.

NURBSIds and Indexes

An important concept to understand when working with NURBSSets and the other NURBS classes is the way you identify component items that are in the set. Before a NURBSet is instantiated in the scene as a NURBS object, the individual points, curves, and surfaces are identified by an index number. As you append objects to the set they are assigned successive indexes, starting at 0. When you want to refer to a particular item, say to specify the parent surfaces in a blend surface, you use this index. Once an object has been added to a NURBSSet, its index can retrieved using.

However, once a NURBSSet is associated with a scene object, either by being instantiated or because it was directly created from an existing scene object, this index is no longer valid. Instead, a different number, called a NURBSId, is assigned to each item and you must use that Id when referring to items from then on. The NURBSId of any item in an instantiated NURBSSet can be obtained through the NURBSObject::GetId() method of that object.

Seed Value Parameters

Seed Value Parameters

Some kinds of dependent objects depend on geometry that might have more than one solution. For example, if you want to create a surface-curve intersection point but the curve intersects the surface more than once, 3ds max must decide which intersection is to be the location of the point.

For these kinds of objects, seed value parameters control the decision. The seed location is a location on a parent object, and the location nearest to the seed value that satisfies the creation condition is the one that 3ds max chooses.

For example, the seed location for a surface-curve intersection point is a U position along the length of the parent curve. The surface-curve intersection closest to the seed is chosen as the location of the dependent point.

For a surface, the seed location is a pair of UV coordinates in the surface's parameter space.

Using the API to Create and Modify MAX NURBS Models

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:

Creating New NURBS Objects

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.

Modifying Existing NURBS Objects

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.

Accessing Details of NURBS Objects

Developers that need to access that internal of 3ds max NURBS objects can see the following methods to get at details such as knot counts, CV counts, order, weight and position data. The main call is:

BOOL GetNURBSSet(Object *object, TimeValue t, NURBSSet &nset, BOOL Relational);

with Relational set to FALSE. This will fill in the NURBSSet with the surfaces, curves and independent points of the object passed. The surfaces will all be NURBSCVSurface's and the curves will all be NURBSCVCurve's. These can be gotten from the NURBSSet with:

int GetNumObjects();

NURBSObject* GetNURBSObject(int index);

The following can be called to get the knots (for surfaces, there is an equivalent for curves, of course):

int GetNumUKnots(void);

int GetNumVKnots(void);

double GetUKnot(int index);

double GetVKnot(int index);

and the CVs can be retrieved with:

int GetNumUCVs(void);

int GetNumVCVs(void);

NURBSControlVertex* GetCV(int u, int v);

The order of the surface can be determined with:

int GetUOrder(void);

int GetVOrder(void);

Finally, given a NURBSControlVertex the position and weights can be retreived via member functions:

Point3 GetPosition(TimeValue t);

void GetWeight(TimeValue t, double& wt);

Parameter Ranges for Curves and Surfaces

Methods that deal with points in the parameter space of a curve work with arguments in U. Methods that deal with points in the parameter space of surfaces deal with arguments in U and V. For example, the function NURBSSurfConstPoint::SetUParam() sets the position of a dependent point in the parent surface's U parameter space. The valid U and V values that may be passed to this method must be obtained by calling NURBSSurface::GetParameterRange() on the parent surface. This methods retrieves the minimum and maximum values for U and V that may be used. For curves there is a similar function for getting the valid range for U. This is NURBSCurve::GetParameterRange().

Developers should be aware that a curve or surface needs to be instantiated in the 3ds max data base before it is okay to call these methods (for example by calling CreateNURBSObject()). Prior to the object existing in the data base these calls will fail.

Generally, when CV curves and surfaces are created, the valid parameter range is known because they were specified in the beginning and ending knot values. In cases where they are not known, one can instantiate a NURBSSet that has just the base curves or surfaces. Once instantiated GetParameterRange() can be used. Then one can build the rest of the parametric model by making additions and/or modifiications to the already instantiated object. The global function AddNURBSObjects() makes this easy to do.

Materials Assignment and Texture Coordinates

Materials and NURBS

Each NURBS surface has its own material ID. If you assign a Multi-SubObject material you can apply a different material to each surface in a NURBS object. The method to do this is NURBSSurface::MatID(). In release 3.0 and later each NURBSCurve can have an associated material. This is used by the Lathe and Extrude modifiers for example.

Texture Coordinates and NURBS

Texture coordinates are assigned to each of the four corners of a NURBS surface. On the standard 3ds max primitives for example most are assigned to use (0,0) to (1,1) across the surface. Some primitive, such as the Prism, don't use (0,0) to (1,1) because of the way they wrap. Developers may of course assign any values using the API. The method to do this is NURBSSurface::SetTextureUVs().

Sample Code

There is a demonstration utility plug-in that exercises the NURBS API. This is available in \MAXSDK\SAMPLES\UTILITIES\NURBS\SDK_TEST.CPP. This is an excellent place to look for simple, clear sample code.

The standard 3ds max primitives also use the NURBS API. See this code in the various primitive objects in directory \MAXSDK\SAMPLES\OBJECTS. Additionally, the Lathe and Extrude use the API. Developers can review this code in \MAXSDK\SAMPLES\MODIFIERS\EXTRUDE.CPP and SURFREV.CPP.

Additional Functions for Working with NURBS

The following global functions are available for working with NURBS. The hyperlinks below take you to the start of groups of related functions:

Creating and Retrieving MAX NURBS Objects

Creating Primitive NURBS Objects (Spheres, Cylinders, etc.)

Modifying Existing NURBS Objects

Creating and Retrieving MAX NURBS Objects

Prototype:

Object *CreateNURBSObject(IObjParam* ip, NURBSSet *nset, Matrix3& mat);

Remarks:

This function is available in release 2.0 and later only.

This function takes a NURBSSet as input and outputs a pointer to an editable NURBS object. For example, this is what all the standard 3ds max primitives do when they implement Object::ConvertToType(). If you want to make a node in the scene reference a NURBS object, put the objects into a NURBSSet and use this function to create the NURBS object. Then pass this object to Interface::CreateObjectNode().

Parameters:

IObjParam* ip

The 3ds max interface pointer. If non-NULL, this is used to get at the 3ds max function to do unique naming. If a NULL is specified the names are not made unique.

NURBSSet *nset

Points to the set of input objects to create. These are defined in object space. The matrix below is used to transform these. For instance, the NURBSSet could be defined in a unit cube and the mat parameter could be used to scale it up.

Note: The NURBSIds and parent NURBSIds in this NURBS set are filled in the process of doing the creation. Thus, you pass this set in, and the function modifies it so you can work with the set immediately (you don't have to later call GetNURBSSet() to get an appropriate one to work with). For example, say you create a NURBSCVSurface using this API and then want to animate some of the CVs on the surface. You'd pass in this set, then when the object is created the CVs on the surface will have the parent ids filled in so you can actually manipulate the surface in the scene.

Matrix3& mat

This is a transformation applied to all of the objects.

Return Value:

A pointer to an editable NURBS object whose Class_ID is EDITABLE_SURF_CLASS_ID.

Prototype:

BOOL GetNURBSSet(Object *object, TimeValue t, NURBSSet &nset, BOOL Relational);

Remarks:

This function is available in release 2.0 and later only.

This function is used to retrieve a NURBSSet that corresponds to the specified NURBS object. This allows a developer to access the internal objects inside a 3ds max editable NURBS object.

If the Relational parameter is FALSE the NURBSSet will contain CV curves and CV surfaces. So for example, if you pass an object that has a relational model (perhaps two CV surfaces and a dependent blend surface) it will decompose them into three CV surfaces. This will be the CV surfaces that represent the two surfaces and the blend, but you won't have the blend relational data. If Relational is TRUE, you'd get back two CV surfaces and a NURBS blend surface. If you get back a relational model, check the type of object using the base class method NURBSObject::GetType() and then cast the object to the appropriate type. Then you may call that classes methods on the object to work with it.

If you were using this API as part of an export plug-in, you'd probably want to set Relational to FALSE because getting back a relational blend surface would not be useful, but having CV surface data you could export would. On the other hand, if you simply wanted to animate the tension parameters on the blend surface you'd set Relational to TRUE and then call the methods of the blend surface object to change the tension parameters (NURBSBlendSurface::SetTension()).

Important Note: Developers must use the method NURBSSet::DeleteObjects() when done with the NURBSSet to free the memory used.

Parameters:

Object *object

The input object. This need to be a NURBS object (Class_ID EDITABLE_SURF_CLASS_ID).

TimeValue t

The time at which the object is evaluated and converted.

NURBSSet &nset

A NURBSSet that corresponds to the specified object is returned here.

BOOL Relational

If TRUE the NURBSSet will contain relational data; if FALSE the NURBSSet will contain a CV curve or CV surface equivalent of the object.

Creating primitive NURBS Objects (spheres, cylinders, etc.)

Prototype:

NURBSResult GenNURBSLatheSurface(NURBSCurve& curve, Point3& origin, Point3& north, float start, float end, NURBSSurface& surf);

Remarks:

This function is available in release 2.0 and later only.

This function generates a NURBS surface of revolution given an input curve, origin, up axis, and start and end angles. The output of this function is a NURBS Surface. Note that this is a CV surface that matches the definition, not a relational surface.

Parameters:

NURBSCurve& curve

This is the NURBS curve that is revolved.

Point3& origin

Specifies the origin of the revolution.

Point3& north

This is the axis that specified the up direction.

float start

This is the start angle of the revolution in radians.

float end

This is the end angle of the revolution in radians.

NURBSSurface& surf

The surface definition is returned here.

Return Value:

See List of NURBS Results.

Prototype:

NURBSResult GenNURBSSphereSurface(float radius, Point3& center, Point3& northAxis, Point3& refAxis, float startAngleU, float endAngleU, float startAngleV, float endAngleV, NURBSSurface& surf);

Remarks:

This function is available in release 2.0 and later only.

This function generates a NURBS sphere. The output of this function is a NURBS Surface. Note that this is a CV surface that matches the definition, not a relational surface.

Note: This surface is not closed surface.

Parameters:

float radius

The radius of the sphere.

Point3& center

The center point of origin of the sphere.

Point3& northAxis

This specifies the up axis. Use Point3(0,0,1) for the Z axis for example.

Point3& refAxis

This is the direction of the seam. The sphere primitive uses Point3(0,-1,0) as this value.

float startAngleU

The start angle for the sphere in the U direction, specified in radians.

float endAngleU

The end angle for the sphere in the U direction, specified in radians.

float startAngleV

The start angle for the sphere in the V direction, specified in radians.

float endAngleV

The end angle for the sphere in the V direction, specified in radians.

NURBSSurface& surf

The surface definition is returned here. This is a CV surface that matches the definition, not a relational surface.

Return Value:

See List of NURBS Results.

Prototype:

NURBSResult GenNURBSCylinderSurface(float radius, float height, Point3& origin, Point3& symAxis, Point3& refAxis, float startAngle, float endAngle, NURBSSurface& surf);

Remarks:

This function is available in release 2.0 and later only.

This function generates a NURS cylinder. The output of this function is a NURBS Surface. Note that this is a CV surface that matches the definition, not a relational surface.

Note: This surface is not closed surface.

Parameters:

float radius

The radius of the cylinder.

float height

The height of the cylinder.

Point3& origin

The origin of the cylinder.

Point3& symAxis

The axis of symetry. The standard cylinder primitive specifies Point3(0,0,1).

Point3& refAxis

This is the direction of the seam. The standard cylinder primitive specifies Point3(0,1 ,0).

float startAngle

The start angle in radians.

float endAngle

The end angle in radians.

NURBSSurface& surf

The surface definition is returned here.

Return Value:

See List of NURBS Results.

Prototype:

NURBSResult GenNURBSConeSurface(float radius1, float radius2, float height, Point3& origin, Point3& symAxis, Point3& refAxis, float startAngle, float endAngle, NURBSSurface& surf);

Remarks:

This function is available in release 2.0 and later only.

This function generates a NURBS cone surface. The output of this function is a NURBS Surface. Note that this is a CV surface that matches the definition, not a relational surface.

Note: This surface is not closed surface.

Parameters:

float radius1

One of the radii of the cone.

float radius2

The other radius of the cone.

float height

The height of the cone.

Point3& origin

The origin of the cone.

Point3& symAxis

The axis of symmetry.

Point3& refAxis

This is the direction of the seam.

float startAngle

The start angle in radians.

float endAngle

The end angle in radians.

NURBSSurface& surf

The surface definition is returned here.

Return Value:

See List of NURBS Results.

Prototype:

NURBSResult GenNURBSTorusSurface(float majorRadius, float minorRadius, Point3& origin, Point3& symAxis, Point3& refAxis, float startAngleU, float endAngleU, float startAngleV, float endAngleV, NURBSSurface& surf);

Remarks:

This function is available in release 2.0 and later only.

This function generates a NURBS torus surface. The output of this function is a NURBS Surface. Note that this is a CV surface that matches the definition, not a relational surface.

Note: This surface is not closed surface.

Parameters:

float majorRadius

This is the radius of the entire 'donut' shape.

float minorRadius

The is the radius of the 'tube'.

Point3& origin

The origin of the cone.

Point3& symAxis

The axis of symmetry.

Point3& refAxis

This is the direction of the seam.

float startAngleU

The start angle of the torus in the U direction.

float endAngleU

The end angle of the torus in the U direction.

float startAngleV

The start angle of the torus in the V direction.

float endAngleV

The end angle of the torus in the V direction.

NURBSSurface& surf

The surface definition is returned here.

Return Value:

See List of NURBS Results.

Prototype:

Object *CreateNURBSLatheShape(IObjParam* ip, TSTR name, TimeValue t, ShapeObject *shape, Matrix3& axis, float degrees, int capStart, int capEnd, int capType, BOOL weldCore, BOOL flipNormals, BOOL texturing, int segs, BOOL matIds, BOOL shapeIDs);

Remarks:

This function is available in release 2.0 and later only.

This function generates a NURBS object based on the specified lathe (surface of revolution) definition and returns a pointer to it. This is used by the lathe modifier.

Parameters:

IObjParam* ip

The 3ds max interface pointer. If non-NULL, this is used to get at the 3ds max function to do unique naming. If a NULL is specified the names are not made unique.

TSTR name

The name for the object. If the pointer above is non-NULL this name is made unique.

TimeValue t

The time at which to revolve the shape.

ShapeObject *shape

Points to the shape object to revolve. Note that if the ShapeObject pointed to is a bezier spline then capping won't work properly.

Matrix3& axis

This specifies the axis of revolution.

float degrees

The angle for the surface of revolution in degrees.

int capStart

Specifies if the surface should be capped at the beginning: TRUE to cap; FALSE to leave open. Note that this is only used if the ShapeObject is a NURBS curve.

int capEnd

Specifies if the surface should be capped at the ending: TRUE to cap; FALSE to leave open. Note that this is only used if the ShapeObject is a NURBS curve.

int capType

This parameter is not currently used and the value passed is ignored.

BOOL weldCore

TRUE to collapse any coincident vertices at the center of the surface; otherwise FALSE.

BOOL flipNormals

TRUE to invert the orientation of surface normals; otherwise FALSE.

BOOL texturing

TRUE to generate mapping coordinates; otherwise FALSE.

int segs

This parameter is not currently used and the value passed is ignored.

BOOL matIds

If TRUE special material Ids are assigned to the surfaces and caps.

BOOL shapeIDs

This parameter is available in release 3.0 and later only.

If TRUE shape IDs are used. When on, this function uses the material ID values assigned to segments in the spline to be lathed, or curve sub-objects in the NURBS curve to be lathed. This is available only when matIds is TRUE.

Prototype:

Object *CreateNURBSExtrudeShape(IObjParam* ip, TSTR name, TimeValue t, ShapeObject *shape, float amount, int capStart, int capEnd, int capType, BOOL texturing, BOOL matIDs, BOOL shapeIDs);

Remarks:

This function is available in release 2.0 and later only.

This function generates a NURBS object based on the specified extrusion definition and returns a pointer to it. This is used by the extrude modifier.

Parameters:

IObjParam* ip

The 3ds max interface pointer. If non-NULL, this is used to get at the 3ds max function to do unique naming. If a NULL is specified the names are not made unique.

TSTR name

The name for the surface. If the pointer above is non-NULL this name is made unique.

TimeValue t

The time at which to extrude the shape.

ShapeObject *shape

Points to the shape object to extrude. Note that if the ShapeObject pointed to is a bezier spline then capping won't work properly.

float amount

Specifies the height of the extrusion.

int capStart

Specifies if the surface should be capped at the bottom: TRUE to cap; FALSE to leave open. Note that this is only used if the ShapeObject is a NURBS curve.

int capEnd

Specifies if the surface should be capped at the top: TRUE to cap; FALSE to leave open. Note that this is only used if the ShapeObject is a NURBS curve.

int capType

This parameter is not currently used and the value passed is ignored.

BOOL texturing

If TRUE texture coordinates are assigned; otherwise they are not.

BOOL matIds

If TRUE special material Ids are assigned to the surfaces and caps.

BOOL shapeIDs

This parameter is available in release 3.0 and later only.

If TRUE shape IDs are used. When on, this function uses the material ID values assigned to segments in the spline to be extruded, or curve sub-objects in the NURBS curve to be extruded. This is available only when matIds is TRUE.

Modifying Existing NURBS Objects

Prototype:

int AddNURBSObjects(Object* obj, IObjParam* ip, NURBSSet *nset);

Remarks:

This function is available in release 2.0 and later only.

This function adds the specified NURBSSet to the specified object.

Parameters:

Object* obj

Points to the object to have the specified NURBSSet added to. This object must be a NURBS object (otherwise it will simply return 0).

IObjParam* ip

The 3ds max interface pointer. If non-NULL, this is used to get at the 3ds max function to do unique naming. If a NULL is specified the names are not made unique.

NURBSSet *nset

Points to the NURBS set that is added to the object.

Return Value:

Nonzero if the object was added; otherwise zero.

Prototype:

NURBSResult SetSurfaceApprox(Object* obj, BOOL viewport, TessApprox *tess, BOOL clearSurfs=FALSE);

Remarks:

This function is available in release 3.0 and later only.

This function sets the surface approximation characteristics of an existing NURBS object.

Parameters:

Object* obj

The NURBS object to modifiy.

BOOL viewport

TRUE to set the viewport approximation settings; FALSE to set the rendering settings.

TessApprox *tess

Specifies the properties of the tesselation approximation to the mathematical surface.

BOOL clearSurfs=FALSE

This tells the NURBS object to clear any over-ridden values on individual surfaces. The NURBS UI lets users set surface approximation value on individual surfaces that over-ride the values for the whole object. When this is TRUE, then these are cleared out.

Return Value:

See List of NURBS Results.

Function:

NURBSResult SetCurveApprox(Object* obj, BOOL viewport, TessApprox *tess, BOOL clearSurfs);

Remarks:

This function is available in release 3.0 and later only.

This function sets the curve approximation characteristics of an existing NURBS object.

Parameters:

Object* obj

The NURBS object to modifiy.

BOOL viewport

TRUE to set the viewport approximation settings; FALSE to set the rendering settings.

TessApprox *tess

Specifies the properties of the tesselation approximation to the mathematical curve.

BOOL clearSurfs

This tells the NURBS object to clear any over-ridden values on individual curves. The NURBS UI lets users set surface approximation value on individual surfaces that over-ride the values for the whole object. When this is TRUE, then these are cleared out.

Return Value:

See List of NURBS Results.

Function:

NURBSResult SetDispApprox(Object* obj, TessApprox *tess, BOOL clearSurfs);

Remarks:

This function is available in release 3.0 and later only.

This function sets the displacement mapping approximation characteristics of an existing NURBS object.

Parameters:

Object* obj

The NURBS object to modifiy.

TessApprox *tess

Specifies the properties of the tesselation approximation to the mathematical curve.

BOOL clearSurfs

This tells the NURBS object to clear any over-ridden values on individual surfaces. The NURBS UI lets users set surface approximation value on individual surfaces that over-ride the values for the whole object. When this is TRUE, then these are cleared out.

Return Value:

See List of NURBS Results.

Function:

NURBSResult SetSurfaceDisplaySettings(Object* obj, NURBSDisplay& disp);

Remarks:

This function is available in release 3.0 and later only.

This function sets the display properties of an existing NURBS object.

Parameters:

Object* obj

The NURBS object to modifiy.

NURBSDisplay& disp

The display properties to use. See Class NURBSDisplay.

Return Value:

See List of NURBS Results.

Function:

NURBSResult GetSurfaceDisplaySettings(Object* obj, NURBSDisplay& disp);

Remarks:

This function is available in release 3.0 and later only.

This function retrieves the display properties of an existing NURBS object.

Parameters:

Object* obj

The NURBS object to check.

NURBSDisplay& disp

The display properties are returned here. See Class NURBSDisplay.

Return Value:

See List of NURBS Results.

Prototype:

NURBSResult Transform(Object* obj, NURBSIdTab& ids, SetXFormPacket& xPack, Matrix3& mat, TimeValue t);

Remarks:

This function is available in release 2.0 and later only.

This function transforms the specified sub-objects within the NURBS object passed. Note that the parameter xPack is used for the transformation when Animate mode is on, and mat is used when Animate is off. This stems from the fact that 3ds max delays creation of controlers on NURBS sub-objects until they are animated.

Parameters:

Object* obj

The NURBS object whose sub-objects are modified.

NURBSIdTab& ids

The table of NURBS Ids of the sub-objects to transform. These are the sub-objects within the 3ds max NURBS object obj that are transformed.

SetXFormPacket& xPack

When Animate mode is on, this matrix is used for the transformation. See Class SetXFormPacket.

Matrix3 mat

When not in Animate mode, this matrix is used for the transformation.

TimeValue t

The time at which to do the transformation.

Return Value:

See List of NURBS Results.

Prototype:

NURBSResult BreakCurve(Object* obj, NURBSId id, double u, TimeValue t);

Remarks:

This function is available in release 2.0 and later only.

This function takes the specified NURBS curve sub-object and generates two curves from it.

Parameters:

Object* obj

The NURBS object whose curve sub-object is broken.

NURBSId id

The id of the curve sub-object to break.

double u

The point along the curve at which the break is made.

TimeValue t

The time at which the curve is broken. The u parameter is relative to the state of the curve at this time (for instance if it's animated).

Return Value:

See List of NURBS Results.

Prototype:

NURBSResult BreakSurface(Object* obj, NURBSId id, BOOL breakU, double param, TimeValue t);

Remarks:

This function is available in release 2.0 and later only.

This function takes the specified NURBS surface sub-object and generates two surfaces from it.

Parameters:

Object* obj

The NURBS object whose surface sub-object is broken.

NURBSId id

The id of the surface sub-object to break.

BOOL breakU

If TRUE the break occurs along a constant U parameter; otherwise along a constant V parameter.

double param

The distance in U or V space that the break should happen in.

TimeValue t

The time at which the surface is broken. The u parameter is relative to the state of the surface at this time (for instance if it's animated).

Return Value:

See List of NURBS Results.

Prototype:

NURBSId JoinCurves(Object* obj, NURBSId id1, NURBSId id2, BOOL begin1, BOOL begin2, double tolerance, double ten1, double ten2, TimeValue t);

Remarks:

This function is available in release 3.0 and later only.

This function takes two curves and joins them together and makes a single curve out of them. That is, the endpoints of the two curve objects are connected by new segments, and the two original curves are replaced by a single curve.

Parameters:

Object* obj

The NURBS object whose curve sub-objects are joined.

NURBSId id1

The id of the first curve sub-object.

NURBSId id2

The id of the second curve sub-object.

BOOL begin1

Specifies if the beginning or the end of curve 1 if joined. If TRUE the beginning is used; otherwise the end is used. The beginning of the curve is the point of minimum parameter value.

BOOL begin2

Specifies if the beginning or the end of curve 2 if joined. If TRUE the beginning is used; otherwise the end is used. The beginning of the curve is the point of minimum parameter value.

double tolerance

A distance in 3ds max units. If the gap between the curves you are joining is greater than this value, this function creates the join by first creating a blend curve and then joining the three parts. If the gap is less than this value, or if the curves are overlapping or coincident, no blend is created.

Creating a blend and then joining the three curves into a single curve is the better technique. The result matches the parent curves well. Without the blend step, the resulting curve can deviate from the parent curves, in order to maintain smoothness. (The amount of deviation depends on how far from tangent the two input curves were at the join.)

A problem arises when there is a gap but it is too small. In this case, this function generates the blend but because there isn’t enough room for it, the resulting curve has a loop in it. To avoid this loop, set this parameter higher than the gap distance.

If you use a value of 0.0, the function chooses a value to use for the tolerance.

double ten1

Specifies the tension of the new curve at the end of the first curve sub-object.

double ten2

Specifies the tension of the new curve at the end of the second curve sub-object.

TimeValue t

The time at which the curves are joined.

Return Value:

The NURBSId of the newly joined curve.

Prototype:

NURBSId JoinSurfaces(Object* obj, NURBSId id1, NURBSId id2, int edge1, int edge2, double tolerance, double ten1, double ten2, TimeValue t);

Remarks:

This function is available in release 2.0 and later only.

This function takes two surfaces and joins them together and makes a single surface out of them. That is, the specified edges of the two surface objects are connected by a new surface, and the two original surfaces are replaced by a single surface.

Parameters:

Object* obj

The NURBS object whose surface sub-objects are joined.

NURBSId id1

The id of the first surface sub-object.

NURBSId id2

The id of the second surface sub-object.

int edge1

The index of the edge of surface 1 to join.

int edge2

The index of the edge of surface 2 to join.

double tolerance

A distance in 3ds max units. If the gap between the surfaces you are joining is greater than this value, this function creates the join by first creating a blend surface. If the gap is less than this value, or if the surfaces are overlapping or coincident, 3ds max doesn’t create the blend.

Creating a blend and then joining the three surfaces into a single surface is the better technique. The result matches the parent surfaces well. Without the blend step, the resulting surface can deviate from the parent surfaces, in order to maintain smoothness. (The amount of deviation depends on how far from tangent the two input surfaces were at the join.)

A problem arises when there is a gap but it is too small. In this case, this function generates the blend but because there isn’t enough room for it, the resulting surface has a loop in it. To avoid this loop, set the tolerance parameter higher than the gap distance.

If you set the tolerance to 0.0, the function chooses a value to use for the tolerance.

double ten1

Specifies the tension of the new surface at the edge of the first surface sub-object.

double ten2

Specifies the tension of the new surface at the edge of the second surface sub-object.

TimeValue t

The time at which the surfaces are joined.

Return Value:

The NURBSId of the newly joined surface.

Function:

NURBSResult ZipCurves(Object* obj, NURBSId id1, NURBSId id2, BOOL begin1, BOOL begin2, double tolerance, TimeValue t);

Remarks:

This function is available in release 3.0 and later only.

This method 'zips' two curves. Zipping concatenates the CV lattices of the two original curves. Zipping can change the shape of the original curves, but usually it produces a better result than joining. If both curves are untrimmed point curves, the result is a point curve. In all other cases, the result of zipping is a CV curve.

Parameters:

The NURBS object whose curve sub-objects are zipped.

NURBSId id1

The id of the first curve sub-object.

NURBSId id2

The id of the second curve sub-object.

BOOL begin1

Specifies if the beginning or the end of curve 1 if joined. If TRUE the beginning is used; otherwise the end is used. The beginning of the curve is the point of minimum parameter value.

BOOL begin2

Specifies if the beginning or the end of curve 2 if joined. If TRUE the beginning is used; otherwise the end is used. The beginning of the curve is the point of minimum parameter value.

double tolerance

A distance in 3ds max units. If the gap between the curves you are zipping is greater than this value, this function creates the join by first creating a blend curve and then joining the three parts. If the gap is less than this value, or if the curves are overlapping or coincident, no blend is created.

If you use a value of 0.0, the function chooses a value to use for the tolerance.

TimeValue t

The time at which the surfaces are joined.

Return Value:

See List of NURBS Results.

Function:

NURBSResult ZipSurfaces(Object* obj, NURBSId id1, NURBSId id2, int edge1, int edge2, double tolerance, TimeValue t);

Remarks:

This function is available in release 3.0 and later only.

This method 'zips' two surface. Zipping concatenates the CV lattices of the two original surfaces. Zipping can change the shape of the original surfaces, but compared to joining it usually produces a simpler surface that is easier to edit.

Parameters:

Object* obj

The NURBS object whose surface sub-objects are zipped.

NURBSId id1

The id of the first surface sub-object.

NURBSId id2

The id of the second surface sub-object.

int edge1

The index of the edge of surface 1 to join.

int edge2

The index of the edge of surface 2 to join.

double tolerance

A distance in 3ds max units. If the gap between the surfaces you are zipping is greater than this value, this function creates the join by first creating a blend surface. If the gap is less than this value, or if the surfaces are overlapping or coincident, 3ds max doesn’t create the blend.

If you set the tolerance to 0.0, the function chooses a value to use for the tolerance.

double ten1

Specifies the tension of the new surface at the edge of the first surface sub-object.

double ten2

Specifies the tension of the new surface at the edge of the second surface sub-object.

TimeValue t

The time at which the surfaces are joined.

Return Value:

See List of NURBS Results.

Prototype:

NURBSId MakeIndependent(Object* obj, NURBSId id, TimeValue t);

Remarks:

This function is available in release 2.0 and later only.

This function takes a dependent sub-object (fillet, offset, blend, etc.) and turns it into a CV variant of itself such that it is independent (no longer dependent on a parent).

Parameters:

Object* obj

The NURBS object whose sub-object is made independent.

NURBSId id

The id of the dependent sub-object.

TimeValue t

The time at which the sub-object is made independent.

Return Value:

The NURBSId of the resulting object or zero if it could not be done.

Function:

NURBSId MakeRigid(Object* obj, NURBSId id, TimeValue t);

Remarks:

This function is available in release 3.0 and later only.

To improve performance, you can make any kind of surface sub-object into a rigid surface. Once you have made a surface rigid, the only editing allowed is to transform it at the Surface sub-object level. You can't move a rigid surface's points or CVs, or change the number of points or CVs.

Rigid surfaces reduce the amount of memory used by the NURBS model. Making surfaces rigid improves performance, especially for large and complex models.

Parameters:

Object* obj

The NURBS object whose surface sub-objects is made rigid.

NURBSId id

The id of the sub-object who is made rigid.

TimeValue t

The time at which to make it rigid.

Return Value:

The NURBSId of the rigid surface.

Function:

void SetApproxPreset(Object* pObj, int i);

Remarks:

This function is available in release 3.0 and later only.

This allows choosing one of the Tesselation Presets which appear in the 3ds max UI in the Surface Approximation rollup. These are the Low, Medium and High buttons. See GetTessPreset() and SetTessPreset() below.

Parameters:

Object* pObj

The objects whose specified Tesselation Preset is set.

int i

Specifies which preset to make active. One of the following values:

0: Low

1: Medium

2: High

Function:

void ToggleShadedLattice(Object* pObj);

Remarks:

This function is available in release 3.0 and later only.

Inverts the state of the Shaded Lattice setting for the object. This goes between 'Tesselated Mesh' and 'Shaded Lattice' surface display mode.

Parameters:

Object* pObj

The object whose Shaded Lattice setting is toggled.

Function:

TessApprox* GetTessPreset(int which, int preset);

Remarks:

This function is available in release 3.0 and later only.

Returns a pointer to the tesselation object corresponding to the specified type of tesselation preset.

Parameters:

int which

Determines which type of tesselation is set. One of the following values:

0: Curve tesselation in the viewports.

1: Curve tesselation by the production renderer.

2: Surface tesselation in the viewports.

3: Surface tesselation by the production renderer.

4: Displacement mapping (by the production renderer).

int preset

Specifies which preset to get. One of the following values:

0: Low

1: Medium

2: High

Return Value:

See Class TessApprox.

Function:

void SetTessPreset(int which, int preset, TessApprox& tess);

Remarks:

This function is available in release 3.0 and later only.

Sets the tesselation object corresponding to the specified type of tesselation preset.

Parameters:

int which

Determines which type of tesselation is set. One of the following values:

0: Curve tesselation in the viewports.

1: Curve tesselation by the production renderer.

2: Surface tesselation in the viewports.

3: Surface tesselation by the production renderer.

4: Displacement mapping (by the production renderer).

int preset

Specifies which preset to get. One of the following values:

0: Low

1: Medium

2: High

TessApprox& tess

The tesselation object to set. See Class TessApprox.

Function:

Object *BuildEMObjectFromLofterObject(Object *loftObject, double tolerance);

Remarks:

This function is available in release 3.0 and later only.

Generates a new NURBS object from the specified loft object at the current time. This is a special call used in internally in the lofter to convert a loft object to a NURBS surface.

Parameters:

Object *loftObject

Points to the source loft object.

double tolerance

This parameter is the maximum deviation of the NURBS approximation to the true loft surface.

Return Value:

A pointer to the new NURBS object.

Function:

Object *BuildEMObjectFromPatchObject(Object *patchObject);

Remarks:

This function is available in release 3.0 and later only.

Generates a new NURBS object from the specified patch object at the current time.

Parameters:

Object *patchObject

Points to the source patch object.

Return Value:

A pointer to the new NURBS object.

Function:

Object *DetachObjects(TimeValue t, INode *pNode, Object* pobj, NURBSIdList list, char *newObjName, BOOL copy, BOOL relational);

Remarks:

This global function is available in release 3.0 and later only.

Creates a NURBS object in the scene named newObjName respecting the copy and relational flags like the 3ds max Detach operation.

Parameters:

TimeValue t

The time at which to detach the object.

INode *pNode

The node of the existing object.

Object* pobj

Points to the NURBS object whose sub-objects are detached.

NURBSIdList list

The list of objects to detach. Note: typedef Tab<NURBSId> NURBSIdList. See Template Class Tab.

char *newObjName

The name for the new node created.

BOOL copy

TRUE to create a copy for the detached objects leaving the original; FALSE to remove the originals.

BOOL relational

If TRUE the object will contain relational data; if FALSE the object will contain a CV curve or CV surface equivalent of the object.

Return Value:

A pointer to the new object created by the detach. If an error occurs, NULL is returned.

Function:

NURBSSubObjectLevel GetSelectionLevel(Object* pObj);

Remarks:

This global function is available in release 3.0 and later only.

Returns the current sub-object selection level for the specified NURBS object.

Parameters:

Object* pObj

The object to check.

Return Value:

The sub-object level. See List of NURBSSubObjectLevel Options.

Function:

NURBSResult SetSelectionLLevel(Object* pObj, NURBSSubObjectLevel level);

Remarks:

This global function is available in release 3.0 and later only.

Sets the current sub-object selection level for the specified NURBS object.

Parameters:

Object* pObj

Points to the object whose sub-object selection state is set.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

Return Value:

See List of NURBS Results .

Function:

NURBSResult GetSelection(Object* pObj, NURBSSubObjectLevel level, BitArray& selset);

Remarks:

This global function is available in release 3.0 and later only.

Returns a BitArray containing the sub-object selection state of the NURBS object passed.

Parameters:

Object* pObj

Points to the object whose sub-object selection data is retrieved.

NURBSSubObjectLevel level

The sub-object level data to get. See List of NURBSSubObjectLevel Options.

BitArray& selset

The BitArray for the result. Bits set are selected components. See Class BitArray.

Return Value:

See List of NURBS Results .

Function:

NURBSResult SetSelection(Object* pObj, NURBSSubObjectLevel level, BitArray& selset);

Remarks:

This global function is available in release 3.0 and later only.

Sets the specified sub-object selection state of the NURBS object passed.

Parameters:

Object* pObj

Points to the object whose sub-object selection state is set.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

BitArray& selset

The BitArray with the selection data. Bits which are set indicate items to select.

Return Value:

See List of NURBS Results .

Function:

NURBSResult MoveCurrentSelection(Object* pObj, NURBSSubObjectLevel level, TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin);

Remarks:

This global function is available in release 3.0 and later only.

Moves the current sub-object selection at the specified level.

Parameters:

Object* pObj

The object whose components are transformed.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

TimeValue t

The time to transform the sub-objects.

Matrix3& partm

The 'parent' transformation matrix.

Matrix3& tmAxis

The axis system about which the selection is transformed.

Point3& val

The amount of the transformation relative to the axis system.

BOOL localOrigin

If TRUE the transformation takes place about the nodes local origin; otherwise about the world origin.

Return Value:

See List of NURBS Results .

Function:

NURBSResult RotateCurrentSelection(Object* pObj, NURBSSubObjectLevel level, TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin);

Remarks:

This global function is available in release 3.0 and later only.

Rotates the current sub-object selection at the specified level.

Parameters:

Object* pObj

The object whose components are transformed.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

TimeValue t

The time to transform the sub-objects.

Matrix3& partm

The 'parent' transformation matrix.

Matrix3& tmAxis

The axis system about which the selection is transformed.

Quat& val

The amount of the transformation relative to the axis system.

BOOL localOrigin

If TRUE the transformation takes place about the nodes local origin; otherwise about the world origin.

Return Value:

See List of NURBS Results .

Function:

NURBSResult ScaleCurrentSelection(Object* pObj, NURBSSubObjectLevel level, TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin);

Remarks:

This global function is available in release 3.0 and later only.

Scales the current sub-object selection at the specified level.

Parameters:

Object* pObj

The object whose components are transformed.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

TimeValue t

The time to transform the sub-objects.

Matrix3& partm

The 'parent' transformation matrix.

Matrix3& tmAxis

The axis system about which the selection is transformed.

Point3& val

The amount of the transformation relative to the axis system.

BOOL localOrigin

If TRUE the transformation takes place about the nodes local origin; otherwise about the world origin.

Return Value:

See List of NURBS Results .

Function:

int SubObjectCount(Object* pObj, NURBSSubObjectLevel level);

Remarks:

This global function is available in release 3.0 and later only.

Returns the number of sub-objects at the specified level.

Parameters:

Object* pObj

Points to the object to check.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

Function:

int NamedSelSetCount(Object* pObj, NURBSSubObjectLevel level);

Remarks:

This global function is available in release 3.0 and later only.

Returns the number of named selection sets at the specified level

Parameters:

Object* pObj

Points to the object to check.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

Function:

TCHAR* GetNamedSelSetName(Object* pObj, NURBSSubObjectLevel level, int i);

Remarks:

This global function is available in release 3.0 and later only.

Returns the name of the 'i-th' named selection set of the specified sub-object level.

Parameters:

Object* pObj

Points to the object to check.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

int i

The zero based index of the selection set (between 0 and NamedSelSetCount()-1).

Function:

NURBSResult GetNamedSelSet(Object* pObj, NURBSSubObjectLevel level, TCHAR* name, BitArray& selSet);

Remarks:

This global function is available in release 3.0 and later only.

Retrieves the name of, and BitArray holding, the named selelction set for the specified sub-object level.

Parameters:

Object* pObj

Points to the object whose named selection set is retrieved.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

TCHAR* name

The retrieved name of the set.

BitArray& selSet

The retrieved selection set data. See Class BitArray.

Return Value:

See List of NURBS Results .

Function:

NURBSResult SetNamedSelSet(Object* pObj, NURBSSubObjectLevel level, TCHAR* name, BitArray& sel);

Remarks:

This global function is available in release 3.0 and later only.

Set the specified named selection set. The set must exist. To add a new set see AppendNamedSelSet().

Parameters:

Object* pObj

Points to the object whose named selection set is stored.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

TCHAR* name

The name of the set.

BitArray& sel

The selection data. See Class BitArray.

Return Value:

See List of NURBS Results .

Function:

NURBSResult AppendNamedSelSet(Object* pObj, NURBSSubObjectLevel level, TCHAR* name, BitArray& sel);

Remarks:

This global function is available in release 3.0 and later only.

Adds a new named selection set to the specified object.

Parameters:

Object* pObj

Points to the object whose named selection set list is appended.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

TCHAR* name

The name for the set.

BitArray& sel

The selection data. See Class BitArray.

Return Value:

See List of NURBS Results .

Function:

NURBSResult DeleteCurrentSelection(Object* pObj, NURBSSubObjectLevel level);

Remarks:

This global function is available in release 3.0 and later only.

Deletes the current sub-object selection.

Parameters:

Object* pObj

Points to the object whose current selection is deleted.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

Return Value:

See List of NURBS Results .

Function:

NURBSResult MapNURBSIdToSelSetIndex(Object* pObj, NURBSId id, int& index, NURBSSubObjectLevel& level);

Remarks:

This global function is available in release 3.0 and later only.

Returns the index into a sub-object selection set of the sub-object component whose NURBSId is passed.

Parameters:

Object* pObj

Points to the object whose sub-object component selection set index is returned.

NURBSId id

The ID of the sub-object to find.

int& index

The zero based selection set index is returned here.

NURBSSubObjectLevel& level

The sub-object level. See List of NURBSSubObjectLevel Options.

Return Value:

See List of NURBS Results .

Function:

NURBSResult MapSelSetIndexToNURBSId(Object* pObj, int index, NURBSSubObjectLevel level, NURBSId& id);

Remarks:

This global function is available in release 3.0 and later only.

Returns the NURBSId of the sub-object component whose selection set index is passed.

Parameters:

Object* pObj

Points to the object whose sub-object component NURBSId is returned.

int index

The zero based index into the selection set.

NURBSSubObjectLevel level

The sub-object level. See List of NURBSSubObjectLevel Options.

NURBSId& id

The ID is returned here.

Return Value:

See List of NURBS Results .

Function:

void ApplyUVWMapAsTextureSurface(Object* pObj, int type, float utile, float vtile, float wtile, int uflip, int vflip, int wflip, int cap, const Matrix3 &tm,int channel);

Remarks:

This global function is not currently supported as of 3ds max release 3.1.

Function:

void UpdateSurfaceMapper(Modifier* pMod);

Remarks:

This global function is available in release 3.0 and later only.

When called, passing in an instance of a NURBS Surface Mapper WSM, this has the effect of pressing the "Update" button. If any other modifier is passed in, the function does nothing.

Parameters:

Modifier* pMod

Points to the NURBS Surface Mapper WSM.