<!--#set var="name" value="Programming Assignment 1" -->
<!--#include virtual="header.html" -->
<!--
<head><title>COS 526, Fall 2004: Programming Assignment 1</title></head>
<body bgcolor="#ffffff" text="#000000">
<center><h2>COS 526 - Advanced Computer Graphics</h2></center>
-->


<h2>Programming Assignment 1: Progressive Meshes</h2>
<b>Due Tuesday, Oct. 10</b>

<p>
<h3>Overview</h3>
<p>
For this assignment, you will implement a mesh simplification system
based on the techniques described by <a href="papers/hoppe96.pdf">Hoppe 96</a>
and <a href="papers/garland97.pdf">Garland 97</a>.  Your program must
be able to perform a series of simplifications based on the edge
collapse operation, then reconstruct a mesh at any desired level of detail
via vertex splits.

<p>
<h3>0. Starter code</h3>
<p>
Download the starter code as a <a href="asgn1/assn1.zip">zip file</a>
or as a <a href="asgn1/assn1.tar.gz">gzipped tar file</a> and get it to compile
(type make).  You'll need to install a GLUT library, as well, to get
the offviewer program to work -- if your computer does not already have
GLUT, you can download and install the freeglut library from 
http://freeglut.sourceforge.net/

<p>
Now, <a href="asgn1/models/">download a few sample meshes</a>
(in ".off" format, documented
<a href="http://shape.cs.princeton.edu/benchmark/documentation/off_format.html">here</a>)
and start the provided offviewer on one of them.  The model file should be
provided on the command line or, under some systems, you might be able to
drag 'n drop the model file on the executable.
<p>
The mouse/key functions are as follows:
<ul>
<li> Left mouse button: rotate
<li> Middle mouse button (or left and right held together): scale
<li> Right mouse button: translate
<li> 'f' key: toggle drawing mesh faces
<li> 'e' key: toggle drawing mesh edges
<li> 'v' key: toggle drawing mesh vertices
<li> 'q' or 'Esc' key: quit
</ul>

<p>
If you have existing mesh viewing code, feel free to use that instead.

<p>
<h3>1. Mesh Decimation (60%)</h3>
<p>
<ul>
<li> Write code to build up a mesh connectivity data structure of your choice.
Use it to write an "Edge Collapse" function.  A single edge collapse should
take O(1) time (or, at worst, O(<i>d</i>), where <i>d</i> is the maximum
degree of the vertices being collapsed).  Be sure to make your data structure
robust for non-manifolds.
<p>
<img align="right" src="asgn1/patch.png">
When you collapse an edge, be sure to remove any degenerate faces that are
produced.  For example, in the example at right (available as
<a href="asgn1/models/2-simple-with-boundary/testpatch.off">testpatch.off</a>), collapsing
the edge between <i>v0</i> and <i>v1</i> will cause faces <i>X</i> and <i>Y</i>
to be degenerate (i.e., have two vertices that are really the same point).
In addition, you should remove any "fins" (pairs of mirror-image polygons)
produced by the collapse.  In this example, you should remove faces
<i>Z</i> and <i>W</i>.

<li> Write code to compute the quadric error metric for a candidate edge
collapse.  Use it to create a priority queue of edge collapses, and apply
them in order until the mesh can't be simplified any more.  The
<a href="papers/garland97.pdf">Garland 97 paper</a> and Diego Nehab's
<a href="http://www.cs.princeton.edu/courses/archive/fall02/cs526/snipets/quadric.pdf">notes
on quadric error metrics</a> may be useful.  The sample code in 
apps/heaptest might be useful if you want to use the heap library
provided.

<li> Adapt your code to place the vertex resulting from an edge collapse at
the location that minimizes the error quadric.
</ul>

<p>
<h3>2. Progressive Meshes (20%)</h3>
<p>
<ul>
<li> Store data about the edge collapses in a data structure of your choice.
The <a href="papers/hoppe96.pdf">Hoppe 96 paper</a> may be a useful reference.
<li> Adapt the viewer to include an interactive control over the resolution
of the displayed mesh.  This doesn't have to be fancy - a simple keyboard
control where 'up arrow' and 'down arrow' increase/decrease polygon count by 
10% is fine. 
</ul>

<p>
<h3>3. Bells 'n whistles (10%)</h3>
<p>
Implement one of the following (additional options may be implemented for
additional credit).
<ol>
<li> Write out the edge collapses to a file, in a format of your choosing,
then adapt your viewer to read just the base mesh and edge collapses,
instead of the original mesh.
<li> Implement a visualization of the error quadrics as ellipsoids
<li> Implement geomorphs for smooth transitions between levels of detail.
<li> Augment your system to perform "pair collapses" in addition to simple
edge collapses.  Experiment with models with many separate components and
show that your program joins them into one over the course of simplification.
<li> Experiment with different error metrics.  For example, implement a
system that tries to preserve high-frequency detail at the expense of
greater low-frequency deformation in areas with less detail.
<li> Implement a view-dependent progressive mesh viewer based on
<a href="papers/hoppe97.pdf">Hoppe 97</a>.  (Big time extra credit for this one!)
</ol>

<p>
<h3>4. Writeup and analysis (10%)</h3>
<p>
Please submit your source code together with a writeup (as plain text,
HTML, or PDF) that contains a description of the design decisions you made,
options you implemented, and results.  At a minimum, you should include
a screenshot of the bunny model
(from <a href="asgn1/models/3-classic/">here</a>) decimated to 500 faces,
together with information about how long it took to simplify.

<p>
<h3>Models</h3>
<p>
There is a small collection of models suitable for this project <a href="asgn1/models/">here</a>.
There is also a large <a href="http://shape.cs.princeton.edu/benchmark/">database
of models</a> here, although many of the models will have a small number of faces 
and/or disconnected components and therefore be poor for this project.

<p>
<h3>Hints</h3>
<p>
<ul>
<li> The choice of mesh data structure is critical - think through your
algorithms before settling on a final choice.  An indexed face set plus
a vertex-to-face adjacency list can lead to relatively simple, though
perhaps slightly inefficient, algorithms, while winged-edge or half-edge,
despite their greater efficiency, can lead to complex algorithms
with lots of special cases, especially since you need to reject edge collapses
that would result in non-manifold topology.
<li> Take advantage of the STL container classes and GAPs support packages - depending
on your needs, using a <tt>vector</tt>, <tt>list</tt>, <tt>set</tt>,
<tt>priority_queue</tt>, or <tt>pair</tt> from the STL might make your life 
easier.  Alternatively, RNArray and RNHeap classes of the RNBasics package
with GAPS might be useful.  Simple geometric operations involving points, 
planes, distances, etc.are supported by the R3Shapes package within GAPS.
<li> Keep in mind the cost of performing each operation on each data structure
(e.g., <tt>insert</tt> and <tt>erase</tt> are <i>O(n)</i> for a
<tt>vector</tt>, but <tt>push_back</tt> and <tt>pop_back</tt> are amortized
constant time).  Note that the cost of removing an entry from an RNArray 
is linear in the size of the array.
</ul>

<p>
<h3> Submitting </h3>
<p>
Please make your writeup and code accessible via the web, and send the URL
to <tt>funk@princeton.edu</tt> with "COS526" in the subject line.  Please
see the <a href="assignments.html#submitting">general notes on submitting
your assignments</a>, as well as the
<a href="assignments.html#late">late policy</a> and the
<a href="assignments.html#collaboration">collaboration policy</a>.


<!--#include virtual="footer.html" -->
