CPSC 589 - Modeling for Computer Graphics   TA PAGE


Teaching Assistants:

Luke Olsen olsenl at cpsc ... Tutorial 01 (MW)


     News & Notes
     Grades
     Links


Submission procedure for assignments:

  • Written portion: Hand in to 589 drop box on the 2nd floor of Math-Sciences.

  • Coding portion: E-mail your code (no executables or objects) to me. ZIP/TAR the files together before submitting.
    You must use either Windows or Linux environments for your code. You must also include a makefile that compiles on the graphics lab machines (Linux) or include a MS Visual C++ or Visual Studio .NET project file (Windows).
  • Bear in mind that you must do the assignments individually.


News & Notes

04-07-06

Distance functions for implicit primitives.

  • Sphere (point primitive).
  • Hotbar (line primitive).
  • Hot triangle (triangle primitive).

The first two were covered in lecture. The triangle primitive requires a ray-plane intersection and inside/outside test for the intersection point. In the case that the intersection is outside the triangle, the line primitive distance function can be used along the closest edge.

04-08-06

Marks for Assignment 3 have been posted. You can collect your assignments in Wednesday's lab.

04-07-06

Covered in lab today:

Marching squares/cubes for rendering implicit surfaces.

03-29-06

Important note on Assignment 3 - Coding Portion

It is not necessary to use OpenGL or any 3D rendering technique for the coding part of Assignment 3. The ImgWidget code I presented in lab is a 2D image widget that works in a similar fashion to the QGLWidget, but not in conjunction with it. With a QGLWidget, you have two functions of interest:

  • paintGL() - displays your 3D geometry
  • updateGL() - tells Qt that you want to redraw the screen
With the ImgWidget class, there are two similar functions:
  • paintEvent() - displays your 2D image
  • update() - tells Qt that you want to redraw the screen


To display an image in OpenGL, you might render the image over a quad as a texture map. However, this will not respect the original pixels of your image for a couple of reasons. First, all textures must have dimensions that are powers of 2, eg. 512x512. Second, the texture will then be sampled according to how OpenGL interpolates between the texture coordinates that you specify for your quad. Thus, the pixels of the original image are being interpolated twice, once to resize to a 2k dimension and again in the polygon-fill routine.

If you have used OpenGLn texture mapping to implement this assignment, you will at the least have to come up with a way to specify the texture and your projection/viewport transformations such that the impact of these interpolations are minimized. For example, the image should not be scaled to a 2k boundary, it should be padded with black pixels.

Also, take a look at glWritePixels() for an alternative approach.


This raises a larger issue, which is that if you're not sure about something, you should clarify with me before heading down a potentially-wrong path. I'm always happy to answer questions related to the assignment. But if you don't ask, then I am left to just guess at possible points of confusion.

03-29-06

Covered in lab today:

Tips on implementing subdivision, including:

  • Definition of a half-edge data structure.
  • How to populate a half-edge data structure when loading an OBJ file.
  • How to traverse faces and vertex neighborhoods.
  • How to modify the traditional half-edge structure to accomodate subdivision.
  • How to apply subdivision masks and where to store the new vertices created during subdivision.
  • How to create the new face structure after subdivision.

03-20-06

Covered in lab today:

Implementation tips for Assignment 3, from a Qt-centric perspective.

Qt provides two main image classes: QImage and QPixmap.

  • QImage provides the image-loading interface, and is optimized for I/O and pixel access/manipulation. Supported formats vary depending on the Qt configuration, but the machines in the graphics lab claim to support the popular formats: JPEG, GIF, BMP, PPM, etc.
  • QPixmap is optimized for drawing.
Neither of these classes inherits from QWidget, meaning that neither can simply be instantiated and added to a GUI. You need to do some more work for that, but not much.

Here is some code that implements a class that inherits from QWidget and can then be instantiated and added to a GUI layout.

[imgwidget.h | imgwidget.cpp]

If you have a severe aversion to Qt, I would suggest looking into the CImg library. That can be used in conjunction with ImageMagick to load more file types.

http://cimg.sourceforge.net
http://www.imagemagick.org
If you go that route, or any other, I will be less able to help you. And the regular submission rules apply, so any external libraries for loading images must be submitted and configured to build properly.

03-20-06

Here is a good resource on the various mesh data structures presented in class (half-edge, quad-edge, winged edge).
[Mesh data structure paper]

03-17-06

If you are working with meshes for your project, the OBJ format is a popular mesh file format.

At this site, there are some great tutorial programs that work with OBJ meshes, along with the source code. Take a look at the source if you need to write an OBJ parser for your project.

03-13-06

Covered in lab today:

I talked about how to apply subdivision to images. The main issue is how to handle the boundaries. There are three main approaches: a) use special boundary masks that interpolate the boundaries; b) wrap around the image for missing samples; c) use symettric extension (mirror the samples about the boundaries).

03-08-06

Here are some code snippets for putting lighting into your OpenGL applications. [Lighting Code]

03-08-06

Covered in lab today:

Solution to Question 4 from the sample midterm. Because it deals with subdivision, I didn't cover it pre-midterm.

03-06-06

Covered in lab today:

I covered solutions to the midterm exam.

03-03-06

For Assignment 2, you may find the point-picking code previously discussed in lab to be useful. [Point-picking Code]

03-01-06

Covered in lab today:

I presented some sample code for 3D mouse viewing. The necessary code chunks are here: [Mouse-viewing code]

02-27-06

Covered in lab today:

Solutions to the sample midterm from 2005.

02-15-06

Covered in lab today:

Midterm review.

02-15-06

The second assignment has been posted. It is due on Friday, March 10 at 11:59pm Monday, March 13th at noon.

02-13-06

Covered in lab today:

Sample midterm questions.

  1. Let S(u) be an order-k spline function over the knot sequence {u0, u1, ..., um+k} with no multiple knots. We know S(u) must have Ck-2 continuity over the knot sequence. Prove that if S(u) has more than Ck-2 continuity, it is a polynomial.

  2. Show that NURBS surfaces have local control.

02-08-06

More important! The due date of Assignment 1 is now Feb. 13th at 11:59pm.

Make sure your code is in my Inbox by the deadline, and that the written portion is in the drop-box before I empty it at 9:00am on Tuesday. Since this is already a fairly liberal deadline, there will be no late submissions accepted.

02-08-06

Important! There is a small bug in the original barebones application. A corrected version has been posted [barebones.tar.gz], but it may be easier to make the change to your current code. Here is the offending portion (corrections in red):

void Renderer::resizeGL( int w, int h )
{
  glViewport( 0, 0, w, h );
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();

  if(w >= h) {
    double fc = w/(double)h;
    glFrustum( -1.0*fc, 1.0*fc, -1.0, 1.0, 2.0, 1000.0 );
  }
  else if(h>w) {
    double fc = h/(double)w;
    glFrustum( -1.0, 1.0, -1.0*fc, 1.0*fc, 2.0, 1000.0 );
  }

  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();
}
Whoops! My apologies for letting this slip through. If you are not seeing anything in your OpenGL widget, this is probably the reason.

02-08-06

Covered in lab today:

  • Projective vs. Affine space

    Affine transformations are expressed with 4x4 matrices whose last row is [0 0 0 1]. This leaves the 4th coordinate (the homogenous coordinate) unchanged, so points and vectors are preserved.

    A projective transformation, on the other hand, is specified by an arbitrary 4x4 matrix; there is no constraint on the last row. Thus, the homogeneous coordinate can take on values other than 0 and 1. A point in projective space is specified by [wx wy wz w]T. The "real" coordinate is recovered by dividing through by w.


  • Observations on NURBS

    An n-dimensional NURBS curve is equivalent to an n+1-dimensional B-spline curve projected to a lower dimension. The weights in the NURBS specification determine the projection.

    This is how NURBS can exactly produce conic sections. For instance, a 2D NURBS circle is a 3D B-spline that becomes a cirlce when projected into 2D.


  • Invariance of NURBS under projective transformations

    I gave a sketch proof of this property. The weights wi applied to the control points must change based on the last row of the transformation.

    This property means that only the control points need to be projected, and then the normal NURBS algorithm can be used to generate the curve, rather than projecting the entire curve.

02-06-06

Covered in lab today:

  • Brief introductions to later course topics.

    Including implicit surfaces, CSG, procedural modeling, physically-based modeling, sketch-based modeling, and subdivision.

    The point was to give you a glimpse of what sort of topics are fair game for the course project.

02-01-06

Covered in lab today:

  • 3rd-degree Bezier curve example.

    Given three control points -- P0, P1, and P3 -- and the value of the curve at some u value, Q(u), what is the missing control point P2?


  • Sketch proof that 3rd-degree Beziers are a special case of order-4 B-splines.

    Proof follows from deBoor's recursive B-spline basis function definition and a knot sequence of U = {0,0,0,0,1,1,1,1}.


  • B-spline properties.

    Unit summation, positivity, compact support, and convex hull properties. These are good fodder for exam or assignment questions.

01-31-06

Covered in lab yesterday:

  • Hints on Assignment 1.

    For Q1, assume the 2D case.

    For Q2, remember that a spline of degree d must have Cd-1 continuity.


  • Derived the formula of a 3rd-order B-spline over a uniform integer knot sequence, starting from deBoor's recursive formula.

    First we derived N0,3(u). The remaining basis functions are just shifted versions of that: Ni,3(u) = N0,3(u-i).

    That's way too much tedious math to typeset, so just ask me in lab if you have any questions regarding this!

01-25-06

Covered in lab today:

  • The barebones Qt application. [barebones.tar.gz]

    Discussion of the purpose of each file, where to insert GUI and rendering code, and how to connect each with signals and slots.

    Feel free to use this code in your assignments and projects. Everything is stubbed out. You can also use Designer, but I'm not very familiar with it; I found it got in the way more than it helped.


  • A little bit about layout managers in Qt.

  • Adding a slider to the barebones app.

    Requires changes to three files: renderer.h, renderer.cpp, window.cpp.

    In renderer.h:

    signals:
        void yRotChanged (int);
    public slots:
        void set_yRot (int); private:
        float yRot;   // Don't forget to initialize in constructor

    In renderer.cpp:

    void Renderer::set_yRot (int degrees)
    {
        yRot = float(degree%360);
        emit(yRotChanged(degree%360));
        updateGL();
    }
    You'd also have to add a call to glRotatef() in your paintGL() function ;).

    In window.cpp (before creation of glWidget):

    QGroupBox *rotBox = new QGroupBox(3, Qt::Horizontal, "Rotation Controls", leftBox, "rot box");
      QLabel *yRotLabel = new QLabel("Y Rotation", rotBox, "y rot label");
      QLCDNumber *yRotLCD = new QLCDNumber(3, rotBox, "y rot lcd");
        yRotLCD.display(0);
      QSlider *yRot = new QSlider(0, 360, 10, 0, Qt::Horizontal, rotBox, "y rot slider");

    // Now connect the GUI controls to the OpenGL widget
    connect(yRot, SIGNAL(valueChanged(int)), glWidget, SLOT(set_yRot(int)));
    connect(glWidget, SIGNAL(yRotChanged(int)), yRotLCD, SLOT(display(int)));
    I find that using indentation to organize the GUI elements is helpful, as in the above example (children of rotBox are indented one level more). Of course, YMMV.

01-25-06

Here is some code for a barebones Qt/OpenGL application: [barebones.tar.gz]

01-24-06

Seems that Trolltech has changed their distribution policy for Qt. They now have a cross-platform open-source version for v. 4.1.0, but it claims to not integrate with MSVC++6.0 or .NET. I haven't tried it myself, so if anyone has tried, let me know how it works.

I had an old (really old!) version of 2.30 kicking around, which used to be distributed as the "non-commercial" version. I think it's safe to post here, so here it is: [Qt 2.3] If you have trouble with the newer versions, give this one a shot.

01-24-06

Here is a good vector/matrix library: [libgm.tar.gz]

Feel free to use it in your assignments, and save the hassle of implementing one yourself. Basic usage is:

gmVector3 v, w(0.0, 0.0, 0.0); // Default and initialization constructors
v.assign(1.0, 2.0, 2.0); // Assign values to each component
v[2] = 3.0; // Use [] to access elements individually
w = 2.0*v; // Scalar-vector multiplication
float mag = w.length(); // Member function for getting vector length
float dp = dot(v, w) // Dot product; also cross(v, w), distance(v, w) (for points)
w = normalize(v); // Normalize to length = 1
The class also overrides the following operators: =, +, -, *, /, +=, -=, *=, /=, ==, and !=.

Usage is similar for the matrix classes.

01-23-06

Covered in lab today:

  • Finished John's point-picking code example.

    Sample code for selecting a 3D control point nearest to a mouse-click event. This involves projecting the control point from world coordinates to window coordinates. [Point-picking Code]


  • GLU primitives.

    The GLU library provides some simple primitives; namely cylinders, disks, and spheres. [GLU Code]

    Using the transformation matrix stack (glPushMatrix() and glPopMatrix()), you can reuse the same display list for a primitive.


  • Loading texture maps in Qt.

    Leverage Qt's image-loading libraries and avoid writing parsers yourself, because they're not very much fun! Here is some code that loads an image from disk, converts to the OpenGL format, and transfers the texture to OpenGL. [Image/texture-loading Code]

01-23-06

The first assignment has been posted. It is due three weeks from today (Feb. 12).

01-23-06

Submission procedure for assignments:

  • Written portion: Hand in to 589 drop box on the 2nd floor of Math-Sciences.

  • Coding portion: E-mail your code (no executables, please!) to me. ZIP/TAR the files together before submitting.

    You may use either Windows or Linux environments for your code. Just make sure that you include a makefile that works on the graphics lab machines (Linux) or include a MS Visual C++ or Visual Studio .NET project file (Windows).

Bear in mind that you must do the assignments individually.

01-10-06

Labs begin on Jan. 16. I will be away for the first week, so John Brosz will be covering the first two tutorials.

Grades

Only the last 4 digits of your ID number are shown.

ID # A1
/ 120
A2
/ 140
A3
/ 140
Final
/ 15%
0617 142 159 108 15.45
1149 150 173 157 18.04
1205 78 112 127 11.79
2086 118 115 140 14.02
2154 112 94 124 12.45
2529 114 115 141 13.89
2617 132 128 128 14.64
2712 122 115 73 11.80
3112 98 129 146 13.90
3837 122 154 150 15.94
5062 47 29 45 4.60
5363 143 172 154 17.60
6706 0 92 0 3.29
7063 94 122 132 12.99
7317 126 117 90 12.64
7349 87 104 112 11.34
7894 140 140 160 16.55
8229 0 101 117 7.79
9374 118 92 109 12.10
Average 85.22% 85.08% 83.20%

Links


© Luke Olsen 2012 All Rights Reserved.
Last Modified 02/11/07 01:39pm