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.
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 ControlsMiddle mouse drag | Orbit the view |
Mouse wheel | Zoom in/out |
Right mouse drag | Pan view |
Left click | Select object |
g | Grab selected object to move it |
s | Begin scaling selected object |
r | Begin rotating selected object |
c | Find/Voxelize Clean-up Regions |
. | Prints the location, rotation, scale of selected object |
w | Toggles wireframe on selected |
h | Toggles hiding geometry on/off (to see the voxel grid) |
p | Cuts against messy region boundaries |
l | Loads cylinder meshes again (resets all the cuts) |