Due Friday 9/8 at 11:59 pm. You must work individually.
In this assignment, you will implement a voxelizer. Your program will take, as input, a triangulated surface mesh and the number of voxels of the requested voxelization. As output, your program will generate a voxelization, saved to an .obj file for display. Provided with this assignment is a code stub which can be compiled on macOS, Linux or Windows.
This voxelizer will be based on ray casting. We will partition the space containing the input surface into a regular voxel grid. Your code will determine whether a voxel lies inside or outside the surface mesh. For each voxel in the grid, you will cast a ray. As discussed in class, counting the number of times this ray intersects the object surface will suffice as an inside/outside test.
Download the base code from http://courses.cs.tamu.edu/sueda/CSCE689/2017F/assignments/A1/A1.zip. Browse the code to get an overall idea of the structure.
Example mesh files (.obj) are included in the base code. You can also create your own manually or using a 3D modeling package, such as Blender. In addition, there are numerous OBJ meshes on the web. To visualize the mesh, you may need to download a viewer (e.g., Meshlab). Code for mesh input (loadMesh(...)
) and output (saveVoxelsToObj(...)
) are already implemented in the base code.
The first task is to create the necessary build files using CMake. Depending on your development environment, follow the steps for Makefile, Xcode, or Visual Studio.
Makefile (Linux & macOS)
Download and install CMake. It is probably easiest to download the binaries instead of sources. You may also use homebrew or macports. If installed correctly, you should be able to call cmake
from the terminal. Follow these steps to create a makefile.
> cd <folder containing CMakeLists.txt>
> mkdir build # the folder name here is arbitrary
> cd build
> cmake ..
There should now be a file called Makefile
in the build
directory. Now, you can compile and run the code from the build
directory.
> make -j8
The -j8
flag is the optional flag that multi-threads the compilation process. After compiling, there should be an executable file named voxelizer
, which you can run.
> ./voxelizer
> Usage: voxelizer input.obj output.obj num
Xcode (macOS)
First, make sure Xcode is up-to-date by checking for software updates. Download and install CMake. It is probably easiest to download the binaries instead of sources. You may also use homebrew or macports. If installed correctly, you should be able to call cmake
from the terminal. Follow these steps to create an Xcode project.
> cd <folder containing CMakeLists.txt>
> mkdir xcode # the folder name here is arbitrary
> cd xcode
> cmake -G Xcode ..
Open voxelizer.xcodeproj
using Xcode. First, change the "scheme" to "voxelizer":
Then enter the commandline arguments:
Visual Studio (Windows)
These instructions are for Windows 10 and Visual Studio 2015. Other versions should also work similarly.
Download and install CMake. Once installed, run the CMake GUI. In the "Where is the source code" box, enter the folder that contains the CMakeLists.txt
file. In this folder, create a build
folder (naming is arbitrary), and then point "Where to build the binaries" to it.
Press "Configure" and then select the installed Visual Studio version. Then press "Generate." There should now be a file called voxelizer.sln
in the build
folder. Open this file with Visual Studio. Right click on voxelizer
in the Solution Explorer, and then select "Set as StartUp Project."
Again, right click on voxelizer
in the Solution Explorer, and then select "Properties." Add commandline arguments in the "Debugging" properties.
Add a triple for-loop to go through the voxels in X, Y, and Z directions. At each voxel, you should shoot out a ray and count the number of ray-triangle intersections. In this naive version, you will have to iterate through all the triangles for each voxel, so in the end, it will be a quadruple for-loop. (Keep the number of voxels small for testing!)
Note that the mesh is scaled so that everything fits within [0, 1] in X, Y, and Z directions (Mesh.cpp
line 344). You can set up your voxel grid so that:
(0,0,0)
and (1,1,1)
(left image below),(0,0,0)
and (1,1,1)
(right image below).Here, num
set to 2 for illustration. In the left case, all the voxels will be empty because the centers are outside the sphere, and in the right case, all the voxels will be filled because the centers are inside the sphere.
For ray-triangle intersection tests, you may download code from the web. You must include the citation in the source code and in the README. If you fail to include the citation, you will receive a zero on the assignment.
Test your code first with the sphere. Make sure the results are symmetric. Here are some images with different number of voxels.
Your code must be (relatively) efficient. Generating the 16x16x16 monkey should not take more than a couple of seconds. If it takes much longer, then there is something wrong with your code. If you know how to parallelize your code, go for it! Each voxel can be processed in parallel.
If you shoot only one ray, the voxelizer does not work well when there are holes in the mesh. Modify your code so that it shoots out 6 rays (-X, +X, -Y, +Y, -Z, +Z). Mark a voxel as being inside if 4 or more tests return inside. Test your code on monkey_holes.obj
.
Failing to follow these points may decrease your score. Make sure that your code compiles and runs by typing, for example:
> mkdir build
> cd build
> cmake ..
> make
> ./voxelizer <ARGUMENTS>
source/
, include/
, CMakeLists.txt
, and your README file.(*.~)
, or object files (*.o)
.sueda.zip
) so that when you extract it, it creates a folder called NETID/ (e.g., sueda/
) that has (ONLY) the following in it:
CMakeLists.txt
source/
folder containing all your source filesinclude/
folder containing all your include files