250

# SER431 Lecture 19

NURBS
(201810)

October 31, 2018

## Transcript

1. ### jgs SER 431 Advanced Graphics Lecture 19: Non-Uniform Rational Basis

Splines Javier Gonzalez-Sanchez [email protected] PERALTA 230U Office Hours: By appointment
2. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 1 jgs

NURBS § Non-Uniform Rational Basis Splines § They are generalizations of B-Splines - are defined by some control points and a knot vector, § Rational – ratio of two polynomials (spline functions) § Non-Uniform – Use knot multiplicity to produce variations in curve § Control points are specified in homogeneous coordinates. § NURBS rendering is part of the OpenGL Utilities library of functions (prefixed with “glu”).
3. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 2 jgs

Definition § They reduce the memory consumption when storing shapes (compared to simpler methods). They can be evaluated reasonably quickly by numerically stable and accurate algorithms.

5. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 4 jgs

Screenshot https://github.com/javiergs/SER431/blob/master/Lecture19/surface_bezier.cpp
6. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 5 jgs

Screenshot 4 Bezier Curves with 4 Control Points Each https://github.com/javiergs/SER431/blob/master/Lecture19/surface_bezier.cpp
7. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 6 jgs

Code // a structure to hold a control point of the surface struct Point { float x; float y; float z; }; // 4x4 grid of points that will define the surface Point points[4][4] = { { { 20, 0, 10 }, { 0, 0, 10 }, { -5, 0, 10 }, { -10, 0, 10 } }, { { 20, 0, 5 }, { 0, 15, 5 }, { -5, 15, 5 }, { -10, 0, 5 } }, { { 20, 0, -5 }, { 0, 10, -5 }, { -5, 10, -5 }, { -10, 0, -5 } }, { { 20, 0, -10 }, { 0, 0, -10 }, { -5, 0, -10 }, { -10, 0, -10 } } };
8. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 7 jgs

// display void display() { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glLoadIdentity(); gluLookAt(30, 20, -30, 0, 0, 0, 0, 1, 0); glColor3f(0, 1, 0); glPointSize(3); // curves glBegin(GL_POINTS); for (int i = 0; i != N; ++i) { float u = (float)i / (N - 1); for (int j = 0; j != N; ++j) { float v = (float)j / (N - 1); Point p = calculate(u, v); glVertex3f(p.x, p.y, p.z); } } glEnd(); // more... }
9. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 8 jgs

Point calculate(float u, float v) { Point temp[4]; // calculate each point on our final v curve temp[0] = CalculateU(u, 0); temp[1] = CalculateU(u, 1); temp[2] = CalculateU(u, 2); temp[3] = CalculateU(u, 3); // integrate curves as a surface (in columns) return CalculateV(v, temp); }
10. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 9 jgs

// calculate each point on our final v curve Point CalculateU(float t, int row) { Point p; float it = 1.0f - t; // blending functions float b0 = t * t*t; float b1 = 3 * t*t*it; float b2 = 3 * t*it*it; float b3 = it * it*it; // curve p.x = b0 * points[row][0].x + b1 * points[row][1].x + b2 * points[row][2].x + b3 * points[row][3].x; p.y = b0 * points[row][0].y + b1 * points[row][1].y + b2 * points[row][2].y + b3 * points[row][3].y; p.z = b0 * points[row][0].z + b1 * points[row][1].z + b2 * points[row][2].z + b3 * points[row][3].z; return p; }
11. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 10 jgs

// integrate curves as a surface (in columns) Point CalculateV(float t, Point* pnts) { Point p; float it = 1.0f - t; // calculate blending functions float b0 = t * t*t; float b1 = 3 * t*t*it; float b2 = 3 * t*it*it; float b3 = it * it*it; // blending functions p.x = b0 * pnts[0].x + b1 * pnts[1].x + b2 * pnts[2].x + b3 * pnts[3].x; p.y = b0 * pnts[0].y + b1 * pnts[1].y + b2 * pnts[2].y + b3 * pnts[3].y; p.z = b0 * pnts[0].z + b1 * pnts[1].z + b2 * pnts[2].z + b3 * pnts[3].z; return p; }
12. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 11 jgs

Screenshot 4 Bezier Curves with 4 Control Points Each https://github.com/javiergs/SER431/blob/master/Lecture19/surface_bezier.cpp

14. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 13 jgs

Screenshot https://github.com/javiergs/SER431/blob/master/Lecture16/bspline_connected.cpp https://github.com/javiergs/SER431/blob/master/Lecture19/nurbs_curve.cpp
15. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 14 jgs

display() GLUnurbs* nurb = gluNewNurbsRenderer(); GLfloat ctlpoints[7][3] = { { 10, 10, 0 }, { 5, 10, 0 }, { 0, 0, 0 }, { -5, -5, 0 }, { -10, 0, 0 }, { -5, 10, 0 }, { 0, 5, 0 } }; GLfloat knots[11] = {0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 6.0 }; gluBeginCurve(nurb); gluNurbsCurve(nurb, 11, // how many knots knots, 3, //offset between consecutive control points in ctlpoints &ctlpoints[0][0], 4, // order is the degree + 1 GL_MAP1_VERTEX_3); // type gluEndCurve(nurb); // display method continues here…
16. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 15 jgs

void gluBeginCurve(GLUnurbsObj * nobj) Start NURBS curve rendering. void gluEndCurve(GLUnurbsObj * nobj) Stop NURBS curve rendering. void gluNurbsCurve(GLUnurbsObj * nobj, GLint nknots, GLfloat * knot, GLint stride, GLfloat * ctlpoints, GLint order, GLenum type) nobj: Pointer to NURBS object nknots: Number of knot values knot: Array of knot values stride: Offset between consecutive control point data in ctlpoints ctlpoints: Array of control point coordinates order: Blending function degree plus one. type: Any valid one-dimensional evaluator types. Such as GL_MAP1_VERTEX_3, GL_MAP1_COLOR_4, etc. gluBeginCurve, gluNurbsCurve, gluEndCurve

18. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 17 jgs

Screenshot https://github.com/javiergs/SER431/blob/master/Lecture19/surface_bezier.cpp https://github.com/javiergs/SER431/blob/master/Lecture19/nurbs_surface_grid.cpp
19. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 18 jgs

Code // control points GLfloat ctlpoints[4][4][3] = { { { 20, 0, 10 },{ 0, 0, 10 },{ -5, 0, 10 },{ -10, 0, 10 } }, { { 20, 0, 5 },{ 0, 15, 5 },{ -5, 15, 5 },{ -10, 0, 5 } }, { { 20, 0, -5 },{ 0, 10, -5 },{ -5, 10, -5 },{ -10, 0, -5 } }, { { 20, 0, -10 },{ 0, 0, -10 },{ -5, 0, -10 },{ -10, 0, -10 } } }; GLfloat knots[8] = { 0.0, 0.0, 0.0, 0.0, 3.0, 3.0, 3.0, 3.0 }; GLUnurbsObj *theNurb; // init void init(void) { theNurb = gluNewNurbsRenderer(); gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0); gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON); }
20. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 19 jgs

// display void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gluLookAt(2, 2, -6.5, 0, 0, 0, 0, 1, 0); glPushMatrix(); glScalef(0.125, 0.125, 0.125); // NURBS glColor3f(0, 1, 0); gluBeginSurface(theNurb); gluNurbsSurface(theNurb, 8, knots, 8, knots, // knots u and v 4 * 3, 3, // offset u and v &ctlpoints[0][0][0], 4, 4, // function degree u and v GL_MAP2_VERTEX_3); gluEndSurface(theNurb); // more ... }
21. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 20 jgs

void gluNurbsProperty( GLUnurbsObj *nobj, GLenum property, TYPE value) property = GLU_DISPLAY_MODE Specify how NURBS surface is rendered. value Meaning GLU_FILL The surface is rendered as filled polygons. (Default value) GLU_OUTLINE_POLYGON Only render outlines of the polygons. GLU_OUTLINE_PATCH Only render outlines of patches and trimming curves. gluNurbsProperty property = GLU_SAMPLING_METHOD Specify how NURBS surface is tessellated. Value Meaning GLU_PATH_LENGTH Specify the maximum length, in pixels, of the edges of the tessellated polygons. (Default value) GLU_PARAMETRIC_ERROR Specify the maximum distance, in pixels, between the tessellated polygons and the true NURBS surface. GLU_DOMAIN_DISTANCE Specify, in parametric coordinates, how many sample points per unit length in u and v directions.
22. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 21 jgs

property = GLU_SAMPLING_TOLERANCE Specify the maximum length, in pixels, to be used when the sampling method is set to GLU_PATH_LENGTH. Default value is 50.0. property = GLU_PARAMETRIC_TOLERANCE Specify the maximum length, in pixels, to be used when the sampling method is set to GLU_PARAMETRIC_ERROR. Default value is 0.5. property = GLU_U_STEP Specify the number of sample points per unit length in u direction when sampling method is set to GLU_DOMAIN_DISTANCE. Default value is 100. property = GLU_V_STEP Specify the number of sample points per unit length in v direction when sampling method is set to GLU_DOMAIN_DISTANCE. Default value is 100.
23. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 22 jgs

void gluBeginSurface(GLUnurbsObj * nobj) Start NURBS surface rendering. void gluEndSurface(GLUnurbsObj * nobj) Stop NURBS surface rendering. gluBeginCurve, gluNurbsCurve, gluEndCurve nobj: Pointer to NURBS object uknot_count: Number of knot values in u direction uknot: Array of knot values in u direction vknot_count: Number of knot values in v direction vknot: Array of knot values in v direction ustride: Offset between consecutive control point data in ctlpoints in u direction vstride: Offset between consecutive control point data in ctlpoints in v direction ctlpoints: 2D Array of control point coordinates uorder: Blending function degree plus one for u direction. vorder: Blending function degree plus one for v direction. type: Any valid two-dimensional evaluator types. void gluNurbsSurface(GLUnurbsObj * nobj, GLint uknot_count, GLfloat * uknot, GLint vknot_count, GLfloat * vknot, GLint ustride, GLint vstride, GLfloat * ctlpoints, GLint uorder, GLint vorder, GLenum type)

Light
25. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 24 jgs

Screenshot https://github.com/javiergs/SER431/blob/master/Lecture19/nurbs_surface_grid.cpp https://github.com/javiergs/SER431/blob/master/Lecture19/nurbs_surface_solid.cpp
26. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 25 jgs

Code // same control points and knots that before GLUnurbsObj *theNurb; // init void init(void) { // Materials and Light GLfloat mat_diffuse[] = { 1.0f, 0.5f, 0.31f, 1. }; GLfloat mat_specular[] = { 0.5f, 0.5f, 0.5f, 1. }; GLfloat mat_ambient[] = { 1.0f, 0.5f, 0.31f, 1. }; GLfloat mat_shininess[] = { 100.0 }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); // We need normals glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); theNurb = gluNewNurbsRenderer(); gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0); gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON); }
27. ### Javier Gonzalez-Sanchez | SER431 | Fall 2018 | 26 jgs

Homework § Review the source codes posted on GitHub
28. ### jgs SER431 Advanced Graphics Javier Gonzalez-Sanchez [email protected] Fall 2018 Disclaimer.

These slides can only be used as study material for the class SER431 at ASU. They cannot be distributed or used for another purpose.