Open GL Super Bible

Previous Table of Contents Next


Trimming

Trimming means creating cutout sections from NURBS surfaces. This is often used for literally trimming sharp edges of a NURBS surface. You can also create holes in your surface just as easily. The output from the NURBT program is shown in Figure 17-10. This is the same NURBS surface used in the preceding sample (without the control points shown), with a triangular region removed. This program, too, is on the CD


Figure 17-10  Output from the NURBT program

Listing 17-3 is the code that was added to the NURBS example program to produce this trimming effect. Within the gluBeginSurface/gluEndSurface delimiters, we call gluBeginTrim and specify a trimming curve with gluPwlCurve, and finish the trimming curve with gluEndTrim.

Listing 17-3 Modifications to NURBS to produce trimming

// Outside trimming points to include entire surface
GLfloat outsidePts[5][2] = /* counter clockwise */
       {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}};

// Inside trimming points to create triangle shaped hole in surface
GLfloat insidePts[4][2] = /* clockwise */
    {{0.25f, 0.25f}, {0.5f, 0.5f}, {0.75f, 0.25f}, { 0.25f, 0.25f}};
…
…
…

// Render the NURB
// Begin the NURB definition
gluBeginSurface(pNurb);

// Evaluate the surface
gluNurbsSurface(pNurb,      // pointer to NURBS renderer
   8, Knots,                // No. of knots and knot array u direction
   8, Knots,                // No. of knots and knot array v direction
   4 * 3,                   // Distance between control points in u dir.
   3,                       // Distance between control points in v dir.
   &ctrlPoints[0][0][0],    // Control points
   4, 4,                    // u and v order of surface
   GL_MAP2_VERTEX_3);       // Type of surface

// Outer area, include entire curve
gluBeginTrim (pNurb);
gluPwlCurve (pNurb, 5, &outsidePts[0][0], 2, GLU_MAP1_TRIM_2);
gluEndTrim (pNurb);

// Inner triangluar area
gluBeginTrim (pNurb);
gluPwlCurve (pNurb, 4, &insidePts[0][0], 2, GLU_MAP1_TRIM_2);
gluEndTrim (pNurb);

// Done with surface
gluEndSurface(pNurb);

Within the gluBeginTrim/gluEndTrim delimiters, you can specify any number of curves as long as they form a closed loop in a piecewise fashion. You can also use gluNurbsCurve to define a trimming region or part of a trimming region. These trimming curves must, however, be in terms of the unit parametric u and v space. This means the entire u/v domain is scaled from 0.0 to 1.0.

The gluPwlCurve defines a piecewise linear curve—nothing more than a list of points connected end to end. In this scenario, the inner trimming curve forms a triangle, but with many points you could create an approximation of any curve needed.

Trimming a curve trims away surface area that is to the right of the curve’s winding. Thus a clockwise-wound trimming curve will discard its interior. Typically an outer trimming curve is specified, which encloses the entire NURBS parameter space. Then smaller trimming regions are specified within this region with clockwise winding. Figure 17-11 illustrates this relationship.


Figure 17-11  Area inside clockwise-wound curves is trimmed away

Summary

This chapter could easily have been the most intimidating in the entire book. As you have seen, however, the concepts that lie behind these curves and surfaces are not at all difficult to understand. Appendix B suggests further reading if you want in-depth mathematical information.

The examples from this chapter give you a good starting point for experimenting with NURBS. Try adjusting the control points and knot sequences to create warped or rumpled surfaces. Also try some quadratic surfaces and some with higher order than the cubic surfaces. Additional examples can also be found on the accompanying CD.

Watch out—one pitfall to avoid as you play with these curves is trying too hard to create one complex surface out of a single NURB. You’ll find greater power and flexibility if you compose complex surfaces out of several smaller and easy-to-handle NURBS or Bazier surfaces.

Reference Section

glEvalCoord

Purpose
Evaluates 1D and 2D maps that have been previously enabled.
Include File
<gl.h>
Variations
void glEvalCoord1d(GLdouble u);
void glEvalCoord1f(GLfloat u);
void glEvalCoord2d(GLdouble u, GLdouble v);
void glEvalCoord2f(GLfloat u, GLfloat v);
void glEvalCoord1dv(const GLdouble *u);
void glEvalCoord1fv(const GLfloat *u);
void glEvalCoord2dv(const GLdouble *u);
void glEvalCoord2fv(const GLfloat *u);
Description
This function uses a previously enabled evaluator (set up with glMap) to produce vertex, color, normal, or texture values based on the parametric u/v values. The type of data and function calls simulated are specified by the glMap1 and glMap2 functions.

Parameters

u,v
These parameters specify the v and/or u parametric value that is to be evaluated along the curve or surface.
Returns
None.

Example

The following code from the BEZIER example program produces equivalent calls to glVertex3f each time glEvalCoord1f is called. The exact vertex produced is from the equation for the curve at the parametric value i.

    // Use a line strip to "connect the dots"
    glBegin(GL_LINE_STRIP);
            for(i = 0; i <= 100; i++)
                    {
                    // Evaluate the curve at this point
                    glEvalCoord1f((GLfloat) i);
                    }
    glEnd();
See Also
glEvalMesh, glEvalPoint, glMap1, glMap2, glMapGrid


Previous Table of Contents Next