Mesh Merging and Cleanup Report

The Problem

Manifold meshes are useful in several areas. However, there are several models that are much easier to build using several individual pieces. Also, some models may have manifold mesh representations, but they self intersect which can cause machining tools and some boundary-based algorithms to not work properly. Since these situations are fairly common, it could be useful to have a tool that can take arbitrary geometry (or multiple pieces) and combine them into a clean, non- intersecting, manifold mesh.

Background

There are several people who have tried to tackle this and related problems in the past. Boolean operations have been worked on for years. Though recently they have done fairly well, they can still fall apart in extreme situations. Other attempts (Implicits that blend, chen shen's thing) have involved creating an implicit representation of each component and summing them together. This works well, but adds a lot of unnecessary detail and is computationally costly.

Solution and Difficulties

The first plan was: find regions of intersection, get an implicit representation of that area, and then somehow reconnect that to the rest of the mesh.

This, conceptually, seems fairly straightforward: Optionally use some sort of Heirarchical structure to sort all the different objects and triangles and then find all the intersecting faces. Then, group the intersections into problem areas defined by Axis-Aligned bounding boxes. For each area, voxelize at some user-specified resolution. Use marching-cubes or another meshing scheme to generate a smooth mesh over the previously messy region. Then connect the non-messy geometry to the border of the (now-cleaned-up) messy region.

Unfortunately, coding this is harder. Finding messy regions is straightforward. Voxelizing those regions requires another data structure and A method of converting from boundary rep to voxels -- I used a simple intersection counting test. To make this a reasonable speed, I create a AABB hierarchy first. The first roadblock was finding working marching cubes code (so that doesn't have to be rebuilt) and getting it to work with this code. I found marching cubes code, however it has a couple of problems: I've only got it half-way adapted to my codebase and it just spits out triangle soup (rather than an interconnected triangle mesh).

Another large hurdle is how to actually sew the clean mesh and the cleaned-up mesh together. It basically requires a boolean operation with the region boundary. Once the marching-cubes polygonization works, It should be possible to connect the two together.

Currently

The plan hasn't changed much except for implementation details.

For all pairs overlapping objects, I find all the intersection points. The AABB of these points is considered a messy-region. Then, I voxelize the messy-regions (using an intersection counting ray test) to get a volume representation. Next, I intersect each object with the messy-regions they are on and subdivide triangles as necessary to get boundaries. After that, all faces that are within the messy region are removed to be replaced by nicer geometry generated from the volume representation.

This is where I have gotten. The next steps are to finish the marching-cubes implementation and then connect thing together.

Images

Here are some pictures. You can click on them to enlarge them.


Here is everything performed on a set of four cylinders. The messy regions are in a volume representation and the clean regions have been cut against the messy regions.

This is a close up of a complicated area that will be handled by a nice,clean implicit surface.
 

This is another close up of a complicated region.

Here is just the volume rep for the region to the left.
 

Another clean-up region.

Here's an unforseen problem: It doesn't pick up the non-intersecting, but internal part of a cylinder. Anyways, this shot shows wireframes for the chopped part.
 

This is a picture of handling the intersection against the region's corner.

Usage(for what works so far)

The program code is basically whatever framework I've been able to conjure up over this semester. Its been kind of messy because I used it for all of the semester's graphics projects which have spanned several areas. I've cleaned things up a lot though so right now when you run the program, it'll load 4 cylinders in some funny arrangement. Then it finds all the intersection regions and voxelizes them.

The Controls
Middle mouse dragOrbit the view
Mouse wheelZoom in/out
Right mouse dragPan view
Left clickSelect object
gGrab selected object to move it
sBegin scaling selected object
rBegin rotating selected object
cFind/Voxelize Clean-up Regions
.Prints the location, rotation, scale of selected object
wToggles wireframe on selected
hToggles hiding geometry on/off (to see the voxel grid)
pCuts against messy region boundaries
lLoads cylinder meshes again (resets all the cuts)

Code

Here is the Source Code: needs SDL and OpenGL.