Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SER431 Lecture 19

SER431 Lecture 19

Advanced Graphics
NURBS
(201810)

B546a9b97d993392e4b22b74b99b91fe?s=128

Javier Gonzalez

October 31, 2018
Tweet

Transcript

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

    Splines Javier Gonzalez-Sanchez javiergs@asu.edu 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.
  4. jgs Surfaces From Scratch

  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
  13. jgs Surfaces using OpenGL Support First, Let us review Curves

  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
  17. jgs Surfaces using OpenGL Support

  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)
  24. jgs Surfaces using OpenGL Support Solid Shape with Materials and

    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 javiergs@asu.edu 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.