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.
-
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.
-
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:
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
|