<html>
<head><title>Assignment 2</title></head>
<body text="#000000" bgcolor="#ffffff" link="#0000ee" vlink="#551a8b" alink="#ff0000">
<center><IMG alt="cos426.jpg (39279 bytes)" src="../cos426.jpg"></center>
<center><h3>
<A href="../index.html">Computer Graphics, Spring 2007</a>
</h3></center>

<hr>
<center>
<h3>Assignment 2: Mesh Processing</h3>
<h4>Due on Sunday, Mar 11 at 11:59 PM</h4>
<h4><a href="results/">Results now posted</a></h4>
</center>

<hr>
<h3>Overview</h3>
<blockquote>
In this assignment you will create a simple mesh processing program. The
operations that you implement will mostly be filters that take an input
mesh, process the mesh, and produce an output mesh.
</blockquote>


<hr>
<h3>Getting Started</h3>
<blockquote>

You should use the following skeleton code (<a
href="COS426_assignment2.zip">COS426_assignment2.zip</a>) as a starting point for
your assignment. We provide you with several files, but you
should mainly change <code>R3Mesh.cpp</code>.
<ul>
	<li><code>meshpro.cpp</code>: Parses the command line arguments, and calls the appropriate mesh processing functions. 
	<li><code>meshview.cpp</code>: Interactive program for viewing meshes. 
	<li><code>R3Mesh.[cpp,h]</code>: Defines the mesh data structure and implements the mesh processing operations.
	<li><code>R2</code>: code to support operations on 2D points, vectors, lines, segments, and images
	<li><code>R3</code>: code to support operations on 3D points, vectors, lines, segments, and planes
	<li><code>jpeg</code>: code to read/write JPEG files
	<li><code>meshpro.[vcproj/sln]</code>: Project file for Visual Studio .NET 2005 on Windows.</li>
	<li><code>Makefile</code>: Make file for Linux.</li>
</ul>

<p>After you copy the provided files to your directory, the
first thing to do is compile the program. If you are developing on a
Windows machine and have Visual Studio .NET 2005 installed, use the provided project files to build the program. If you are developing on a UNIX/Linux machine,
type <code>make</code> in the assignment2 directory. In either case, two executables will be created:
<code>meshpro</code> and <code>meshview</code> (or <code>meshpro.exe</code> and <code>meshview.exe</code>).  
<code>meshpro</code> is the program that processes mesh (just like <code>imgpro</code> from assignment #1),
while <code>meshview</code> provides a way for you to visualize meshes interactively.  

<p>The skeleton R3Mesh class is able to read meshes in three simple <a href="formats.html">mesh file formats</a>.  
The first is the <a href="formats.html#RAY">COS426 file format</a>, which is indicated by the .ray file extention.
This format was created to provide the features required by this course -- it will be extended to handle 
materials, lights, etc. in Assignments 3 and 4.  The others are the <a href="formats.html#OFF">Object File Format</a> 
(.off) and the <a href="formats.html#OBJ">Wavefront file format</a> (.obj), 
which are commonly used for interchange between mesh processing programs.
We provide several <a href="../data/meshes/">sample meshes</a> that you can use to test your program.
However, you are not limited to these files.  You should be able to find .off and .obj files on the web -- in
particular, there is a large repository of 3D meshes in .off format in the 
<a href="http://shape.cs.princeton.edu/benchmark">Princeton Shape Benchmark</a>.
</blockquote>


<hr>
<h3>How the Program Works</h3>
<blockquote>

The user interface for this assignment was kept as simple as possible,
so you can concentrate on the mesh processing issues. The program runs
on the command line. It reads a mesh from a file (the first program
argument) and writes a mesh to a file (the second program argument).
In between, it processes the mesh using the filters specified by
subsequent command line arguments. For example, to scale a mesh
<code>in.ray</code> by a factor of 1.1, and save the result in the
mesh <code>out.ray</code>, you would type:
<blockquote>
<code>% meshpro in.ray out.ray -scale 1.1 1.1 1.1</code>
</blockquote>

For each available mesh filter there may be one or more optional parameters -- e.g., -scale takes three factors (sx sy sz). 
To see the complete list of filters and their parameters, type:
<blockquote>
<code>% meshpro -help </code>
</blockquote>

If you specify more than one filter on the command line, they are applied in the order that they are found. For example,
<blockquote>
<code>% meshpro in.ray out.ray -scale 0.8 0.8 0.8 -rotate 0.5  0 0 0  0 0 1</code>
</blockquote>
would first scale the mesh by 0.8 in all three dimensions and then rotate the mesh by 0.5 radians around a line through the point (0,0,0) 
and with direction vector (0,0,1) -- i.e., the z-axis.

Of course, you are welcome to create your own filters and add program
arguments for them by editing <code>meshpro.cpp</code>.  However, please do not change the program
arguments for the filters already provided. 
</blockquote>

<hr>
<h3>What You Have to Do</h3>
<blockquote>
The assignment is worth 20 points. The following is a list of features that you may implement (listed roughly from easiest to hardest within each group). The number in front of the feature corresponds to how many points the feature is worth. The features in bold face are required. The other ones are optional.  Refer to the <a href="examples/">examples web page</a> to see images of inputs and outputs for several of these filters.

	<ul>
		<li>Warps
		<ul>
			<li><b>(1) Random noise</b>: Add noise of a random amount and direction to the position of every vertex. 
			<li>(1) Translate: Translate the mesh by adding a vector (dx,dy,dz) to every vertex.
			<li>(1) Scale: Scale the mesh by increasing the distance from every vertex to the origin by a factor given for each dimension (sx, sy, sz).
			<li><b>(1) Rotate</b>: Rotate the mesh counter-clockwise by an angle (in radians) around a line specified by a point (x,y,z) and a direction vector (dx,dy,dz).
			<li>(1) Inflate: Move every vertex by a given offset along its normal direction (offsets can be negative).  
			<li><b>(2) Fun</b>: Warp a mesh using a non-linear mapping of your choice (examples are sine, bulge, swirl). 
			<li>(3) Deform according to point correspondences: Warp the mesh by a deformation defined by point correspondences provided in an ascii file with six numbers on each line: x y z  x' y' z'.  The position of every vertex in the output mesh should be determined by a Gaussian weighted average of the offsets implied by the point correspondences (x,y,z) -> (x',y',z'). Use a reasonable heuristic to choose sigma for the Gaussian.
		</ul>

		<li>Filters
		<ul>
			<li> <b>(2) Smooth</b>: Smooth the mesh by moving every vertex to a position determined by a weighted average of its immediate neighbors (with weights determined by a Gaussian function of distance).
			<li> (2) Sharpen: Accentuate details in the mesh by moving every vertex away from the position determined by a weighted average of its neighbors (with weights determined by a Gaussian function of distance).  This filter moves vertices in the direction opposite from smoothing.
			<li>(3) Truncate: For every vertex, create a new vertex a parameter t [0-1] of the way along each of its attached edges, and then "chop off" the pyramid whose base is formed by the new vertices and whose apex is the original vertex, creating a set of faces to triangulate the hole.
			<li>(3) Bevel: For every edge, create a new face whose vertices are t [0-1] of the way along each of its attached edges.  This requires first truncating all vertices by t, creating new vertices t [0-1] of the way along each of new edges, and then "chopping off" a prism for each of the original edges, creating a pair of faces to triangulate the hole.
			<li>(4) Bilateral smoothing: Smooth the mesh using a bilateral filter as in <a href="http://people.csail.mit.edu/thouis/JDD03.pdf">[Jones et al, Siggraph 2003]</a> or <a href="http://portal.acm.org/citation.cfm?id=882368">[Fleishman et al., Siggraph 2003]</a>.
		</ul>

		<li>Remeshing
		<ul>
			<li> <b>(2) Subdivide faces</b>: Replace every triangle by four new ones according to the Loop subdivision scheme.   This requires creating a new vertex at the midpoint of every edge, removing the original triangles, and creating four new triangles to replace each of the original ones.  An extra point will be given if the positions of all vertices are updated according to the Loop subdivision weights.
                        <li>(2) Split long edges: Iteratively split edges longer than a given threshold.  Note that every edge split produces a new vertex at the edge midpoint and replaces the two adjacent faces with four.  Edges should be split repeatedly until there is none longer than the given threshold.  An extra point will be given if longer edges are split first (with produces better shaped triangles).
			<li>(3) Vertex cluster: Simplify the mesh by clustering vertices residing in the same cell of a grid defined by x, y, and z spacing parameters.  All vertices within the same grid cell should be merged into a single vertex, that vertex should be placed at the centroid of the cluster vertices, and all edges and faces that collapse as a result of the vertex merging should be removed. 			  
                        <li>(4) Uniform resampling: Generate a new mesh whose vertices are evenly spaced (i.e., all edges are the same length).  One way to accomplish this is to iteratively adjust vertices so that they are at the position on the surface closest to the centroid of its neighbors. 
                        <li>(4) Regular resampling: Generate a new mesh whose vertices are on regularly spaced intervals in x, y, and z.  One way to accomplish this is to rasterize the interior of the mesh into a voxel grid with negative values inside and positive values outside and then compute the zero-set isosurface from the grid.
		</ul>

		<li>Analysis
		<ul>
			<li><b>(2) Compute normals</b>: Compute the surface normal at every vertex by taking a weighted average of the normals for the attached faces, where the weights are determined by the areas of the faces.
                        <li>(3) Compute curvatures: Compute the minimum and maximum curvatures of the surface at every vertex using the method described in <a href="http://www.cs.princeton.edu/gfx/pubs/_2004_ECA/index.php">[Rusinkiewicz, 3DPVT 2004]</a>.  Store the resulting two curvatures values in the texture coordinates for every vertex. 
                </ul>

		<li> Geometry Construction
		<ul>
			<li>(2) Surface of revolution: Create new vertices and faces by sweeping a profile curve around an axis of revolution.  The vertices representing the profile curve are provided in a mesh file (take the vertices of the mesh in order and ignore the faces).  The rotation axis and rotation step size are provided in command line arguments.  New vertices should be created by successively rotating the original vertices around the axis by the step size and new faces should be constructed by connecting adjacent vertices to create a surface of revolution.
			<li>(2) Surface sweep: Create new vertices and faces by sweeping a polygon along a curve.  The vertices representing a cross-section polygon are provided in one input mesh file, and the vertices representing the sweep centerline curve are provided in a second mesh file (for both, take the vertices of the meshes in order and ignore the faces).  New vertices should be created by successively translating and rotating the vertices of the cross-section polygon to match the position and orientation of vertices/edges in the centerline, and new faces should be constructed by connecting adjacent vertices created during the sweep.  An extra 3 points will be awarded if your implementation avoids self-intersecting polygons in all cases.
			<li>(2) Fractalize: Create fractal detail by recursively subdividing every triangle of an input mesh into four (as in the Subdivide feature above) and moving every new vertex by a random offset vector (as in the Random Noise feature above) with magnitude proportional to the original edge length.  Note that the output mesh may resemble a mountain if the input is planar.
			<li>(2) Bezier: Create a smooth mesh using cubic Bezier patches.  The input file should have M*N vertices representing control points arranged in a M by N array (M and N can be inferred from the topology of the input file or read from program arguments).  The output file should contain a fine triangular mesh rerpresenting the cubic Bezier surface implied by the control points.  Points at regular intervals of u and v on the surface should be generated using the tensor product Bezier surface construction and connnected into triangles to form a polygonal approximation of the smooth Bezier surface.
			<li>(2) B-Spline: Create a smooth mesh using cubic B-Spline patches.  The input file should have M*N vertices representing control points arranged in a M by N array (M and N can be inferred from the topology of the input file or read from program arguments).  The output file should contain a fine triangular mesh rerpresenting the cubic B-Spline surface implied by the control points.  Points at regular intervals of u and v on the surface should be generated using the tensor product B-Spline surface construction and connnected into triangles to form a polygonal approximation of the smooth B-Spline surface.		</ul>

		<li>Topological Fixup
		<ul>
			<li> (2) Fill holes: Create triangles covering the holes of a mesh by connecting vertices on the boundary of every hole.  You should completely cover the hole, while doing your best to produce well-shaped triangles (e.g., by connecting closer vertices first).  However, do not worry about triangles intersecting other parts of the mesh in your implementation.
			<li> (3) Fix cracks: Merge boundary vertices and edges within a specified distance (epsilon) of one another.  
			<li> (4) Fix self-intersections: Insert edges at face-face intersections and discard the smaller part of the mesh "pinched" off by new edge loops.  Note: this is hard.
		</ul>

		<li>Boolean Operations (note: these are very hard)
		<ul>
			<li>(4) Intersect: Compute the mesh enclosing the intersection of two meshes.  This feature requires introducing edges at every face intersection and removing parts of the mesh that lie in the exterior of the solid object implied by either of the two meshes. 
			<li>(4) Difference: compute the mesh enclosing the difference of two meshes.  This feature requires introducing edges at every face intersection and removing parts of the mesh that lie in the interior of the solid object implied by the second mesh.  
			<li>(4) Union: compute the mesh enclosing the union of two meshes.  This feature requires introducing edges at every face intersection and removing parts of the mesh that lie in the interior of the solid object implied by both of the two meshes. 
		</ul>

		<li>Miscellaneous
		<ul>
			<li>(2) Create a mesh from an image: Create a mesh by reading an image file, constructing vertices at (x,y,luminance), and connecting adjacent pixels into triangles.  For this feature, the image is interpretted as a height field, where the luminance of each pixel provides its z-coordinate.
			<li> (2) Crop: Given a plane equation (a,b,c,d), crop the input mesh to the positive side of the plane.  This feature requires clipping each polygon crossing the plane, and discarding any part of any face on the negative side of the plane.
			<li> (up to 3) Anything else: Implement any non-trivial mesh processing algorithm of your own choosing, and we will give you points according to the difficulty.</li>
		</ul>
	</ul>

	<p>By implementing all the required features, you get 10 points. There are many ways to get more points:
	<ul>
		<li>implementing the optional features listed above;
		<li>(1) submitting one or more images for the art contest, 
		<li>(1) submitting a <code>.mpeg</code> or <code>.avi</code> movie showing images generated while animating the results of one or more filters with continuously varying parameters, 
		<li>(2) winning the art contest.</li>
	</ul>
	For images or movies that you submit, you also have to submit the sequence of commands used to created them, otherwise they will not be considered valid. 
	
	<p>It is possible to get more than 20 points. However, after 20 points, each point is divided by 2,
and after 22 points, each point is divided by 4. If your raw score is 19, your final score will be 19. If
the raw score is 23, you'll get 21.25. For a raw score of 26, you'll get 22.     
  <p>Extra credit points cannot replace the required features (bold items). Your final score will be calculated by adding 13 to the number of extra credit points you achieve, applying the above formula for diminishing returns, and then subtracting the number of required points that you missed.</blockquote>


<hr>
<h3>What to Submit</h3>
<blockquote>
	You should <a href="../assignments.html#submit">submit</A><B> one 
	archive</B> (zip or tar file) containing: 
	<ul>
		<li>the complete source code, along with an updated Visual Studio project file (if you added any source files);
		<li>the <code>.mpeg</code> or <code>.avi</code> movie for the movie feature (optional);
		<li>the meshes for the art contest (optional); and 
		<li>a writeup.
	</ul>
	<p>The writeup should be a HTML document called <tt>assignment2.html</tt> which may include other documents or pictures. It should be brief, describing what you have implemented, what works and what doesn't, how you created the art contest images, and instructions on how to run the fun filters you have implemented.
</p>
	<p>NOTE: Please convert your art contest and writeup images to JPEG format before submitting them (to save space).</p>
	<p>Should you choose to create a video, there are many options for video encoders available, however we have found that FFMPEG works well and runs on both Windows and linux. MEncoder is another option.</p>
	<p>Always remember the <A href="../assignments.html#Late Policy">late policy</A> and the <A href="../assignments.html#Collaboration Policy">collaboration policy</A>.
</blockquote>


<hr>
<h3>Hints</h3>
<blockquote>
	A few hints:
	<ul>
		<li>Do the simplest filters first! 
		<li>There are functions to manipulate 3D geometric primitives in <code>R3</code>. 
		<li><a href="mailto:cos426@cs.princeton.edu">Send mail</a> to the cos426 staff.        
		<li>The code should compile and link as-is (make sure to try it out before adding your own code!).  If you have problems linking to libjpeg, you can simply remove the -DUSE_JPEG flag from the makefile (or #undef USE_JPEG in your code) to disable JPEG support.
		<li>If you should happen stumble upon anything that you suspect is a bug in the framework code (we're not perfect either!) please mail the preceptor as soon as possible so that it can be corrected.
	</ul>
</blockquote>

<hr>
<h3>FAQ</h3>
<ul>
<li><p><b><i>Can you provide ways to save an image of the screen and print positions on the mesh in meshview.cpp?</b></i><br>
A <a href="meshview.cpp">new version of meshview.cpp</a>
has been provided for assignment 2 that includes functions to: 
1) save an image of the window to a file (hitting the 'S' key saves "imageX.jpg"
in the current directory, where X starts at 1 and increments by one with every save) and 
2) select and print the coordinates of a point on the mesh
(hitting the SPACE key prints a message to stdout with the id of selected 
face and the (x,y,z) position on the mesh under the cursor and then shows the 
selected face (yellow) and position (red) in future redraws of the mesh). 
You should be able to replace your current version of meshview.cpp with this 
new version and recompile.<p>

</ul>

<hr>


</body>
</html>



