Assignment 2: 3D Modeling - Due September 28th.

Overview

For this assignment, you will write a program that reads two files, and writes to a third. The first file that your program will read is a 3D object model file. It will contain a set of named objects, each of which is defined as a set of polygons, each of which is in terms of 3D vertices. The second file is a command file; it contains instructions to apply geometric transformations to objects in the model file. Your program should read the contents of the model into memory, apply the commands from the command file to the named objects in memory, and then write out the transformed objects to the output file, using the same format as in the original model file.

Model File Format

The model file format we will be using is a limited subset of the .obj format originally introduced by Wavefront. It is an ASCII format with one statement per line. There are four types of statements: comments, vertices, faces and groups (a.k.a. objects). The first non-­‐whitespace character on any line defines the statement type as follows:

  • #. If the first non-­‐whitespace character on a line is ‘#’, the statement is a comment statement. Comment statements are no‐ops, and should be ignored.
  • v. If the first non-­‐whitespace character is a lowercase ‘v’, the statement is a vertex statement. The syntax of a vertex statement is: v x y z [w], where v is the character used to signal a vertex statement, x y z are floating point numbers indicating the 3D position of the vertex, and w is an optional homogeneous coordinate value. If no homogeneous coordinate value is given, your parser should provide the default homogeneous value of 1.0.
  • f. If the first non-­‐whitespace character is a lowercase ‘f’, the statement is a face statement. The syntax of a face statement is: f v1 v2 v3 ... where f is the character used to signal a face statement, and v1, v2, v3 ... are three or more integers denoting the vertices that define the face. Vertices are numbered according to their order of appearance in the model file. The first vertex statement defines vertex #1, the second defines vertex #2, and so forth. Note that the ordering of the vertices is significant.
  • g. If the first non-­‐whitespace character is a lowercase ‘g’, then the statement is a group (a.k.a. object) statement. Group statements give a name to a set of polygons that are to be treated as a group, so you can think of a group as a named object. The syntax of a group statement is: g [name1 ...], where g is the character used to signal a group statement, name1 is the name to be given to the faces and vertices in a group, name2 is an optional second name, and so forth. If no name is provided, the group should be named default. Group statements are context setting. Vertices and faces defined before the first group statement should be place in the default group. All other vertices and faces should be placed in the most recently defined group.

The format above is a limited subset of the .obj graphics format. This means that there are many viewers available for looking at models in this format, including mm3d on the department linux machines. On Mac OS TNGViewer seems to work well. However, there are many more .obj format statements than the set above. Therefore, any line which is not one of the four statement types above (including blank lines) should simply be ignored.

Here is a simple example of a file that conforms to specifications above along with a page showing it being animated in 3D. Here is a sphere example file and its related animation page.. You are also being provided a Hollow Cube model and its related animation. Finally, here is a Monkey example file whose origins are described on Wikipedia and which was used to illustrate the JavaScript animation used here.

Command File Format

The second file you will read is a file of commands. Once again, it is an ASCII file with one command per line. This time the commands are geometric transformations. In particular, there are five types of transformation commands: rotate, translate, scale, and arbitrary. Each command specifies a geometric transformation to be applied to a named group from the model file. The syntax of the five statement types is:

  • Rotate: r name amount x y z, where r is the character ‘r’ used to signal a rotation command, name is any group name from the model file, amount is the magnitude of the rotation measured in radians, and x y z specifies the axis of rotation. For example, the command to rotate the default group 180° around the x axis is: r default 3.141592 1.0 0.0 0.0.
  • Translate: t name x y z, where t is the character ‘t’ used to signal a translation command, name is any group name from the model file, and x y z is the amount to translate the group by in x, y and z, respectively. For example, t foo 1.0 -­1.0 0.0 is the command to translate the group foo one unit in the positive x dimension and one unit in the negative y dimension, but leave the z values unchanged.
  • Scale: s name x y z, where s is the character ‘s’ used to signal a scale command, name is the name of any group in the model file, and x y z is the amount to scale in each of the three dimensions. (To uniformly scale an object, just set x y z to be the same constant.) For example, s foo 2.0 2.0 2.0 is the command to uniformly scale group foo by a factor of 2.0 in all dimensions.
  • Arbitrary: a name v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16, where a is the character ‘a’ used to signal an arbitrary transformation, and v1 through v16 are the 16 floating point number in a 4x4 matrix, listed in row-­major order. For example, a foo 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 is the command to apply an identity operation, and therefore would have no effect at all.

Here are two example comand files: command_cube.txt and command_sphere.txt that will be useful for testing your code.

Assignment Details

Your assignment is to build a program that reads a model file into an internal memory structure with groups, faces and vertices (more on that below). It should then read the command file, and apply the specified transformations to the groups named therein. Finally, your program should write out a new file in the same format as the model file, showing the model after the transformations have been applied.

For the purposes of your ray tracer, you will want to read the model into a three level structure. At the bottom level are vertices, each of which is a four-­‐tuple (x, y, z, w) of floating point numbers specifying the location of the vertex in homogeneous coordinates. At the next level are polygons, for which I strongly recommend implementing an object class. In this assignment, polygons only have to contain a set of vertices (or a set of pointers to vertices), but in future assignments they will also need to contain surface normals, material properties and related data. Finally, an object or group is a set of related polygons plus a name. These, too, will acquire additional properties in later assignments.

For assignment #1, your program needs to read a model file into an internal structure with objects (groups), polygons and vertices. In the process, it should check the validity of the model. In particular, the following are errors:

  1. A vertex with fewer than 3 or more than 4 coordinates.
  2. A face with fewer than 3 vertices.
  3. A face with significantly non-­‐coplanar vertices.
  4. A vertex that belongs to more than one group.

If any of these errors occur, your program should print out an error statement to the terminal and then exit. Hint: be careful about vertices belonging to more than one group. If two faces reference the same vertex, both faces and the vertex all need to be in the same group.

Once your program has read the model, the next step is to read the command file and apply the specified geometric transformations. Once again, you need to check for errors. There are only four legal commands; anything else is an error. Every command has a specified number of numeric arguments; missing or extra arguments are errors. Most importantly, every command includes a group name. This name must match the name of one of the groups in memory (i.e. one of the group names in the model file). Once again, it the command file contains an error, print out an error message and exit.

If a command is legal, apply the specified transformation to the named model. Note that this will change the coordinates of the vertices in the group.

Finally, after every transformation has been applied, write the (transformed) model to the output file. Syntactically, the output file should use the same syntax as the input model file. The vertices, etc., do not have to be in the same order, nor do comments have to be retained. However, it should be possible to run your program using the previous output file as the new input.

Mechanics of Grading

Certain parts of the grading process are automated using scripts. This automation is necessary to get the assignments graded in a timely manner. The scripts do three things: (1) extract the archive, (2) compile the program, and (3) run the program with test cases. The process of checking output for correctness is not done by a script. The scripts also keep log all important events, called logfile.txt in my examples.

Students taking this course on campus, CS410, must adhere to all of the requirements outlined below. Students taking this course online, CS410LD, are requested to try to adhere when possible, but are asked to contact the instructor to discuss alternative arrangements if needed.

Extracting:

All assignments must be submitted as .tar archives (compression optional). See and follow the above criteria for naming the tar file. If you submit a file called “ross.tar”, here is the exact command that would be used to extract the file: tar -xvf ross.tar

It is required that this operation result in a directory named the same as the tar file. So in this example it must result in a directory called “ross”. To achieve this, start with a properly named directory and use it to make the tar archive.

Compiling:

All assignments will be compiled on a Linux lab machine using make. Makefiles are required for all assignments, even if they are written in Java. Name the make file either “makefile” or “Makefile”. The exact command that will be run to compile your assignment is:

make &>> logfile.txt

This runs the make program and redirects all terminal output (from stdout and stderr streams) to a file called logfile.txt. The “&>> logfile.txt” part of the command is the redirect.

Note that the make program does not actually care what language it is compiling, it simply runs the terminal commands specified in the make file. Therefore makefiles can be used to compile Java programs.

Running:

All assignments will be run on a Linux lab machine. The naming of your executable file is very important. This executable file is the file that will be run to test your program. Here is how executable files must be named:

  • C++ files: HW1
  • Java files: HW1.class

This assignment requires your program to take three command line arguments: two input files and one output file. If I have two input files named “model.obj” and “transforms”, and one output file named “output.obj”, here are the exact terminal commands that will be used to run your program:

For Java programs:

java HW1 model.obj transforms output.obj &>> logfile.txt

For C++ programs:

HW1 model.obj transforms output.obj &>> logfile.txt

Just like the compile command all terminal output is redirected to logfile.txt. These are example file names, your program will be tested with multiple input files and output file names. Do not hard code input and output file names. When doing file output, you can assume the file does not exist and create or overwrite it.

Submission Instructions

Use the RamCT assignment 2 to submit your work for this assignment. Here are further instructions:

  • All assignments must be submitted as a .tar archive.
  • Name that archive the same as your CS dept user name.
  • For example my CS user name is: ross, so I would name my archive: ross.tar
  • This assignment’s name is: HW1