views:

643

answers:

5

If I construct a shape using constructive solid geometry techniques, how can I construct a wireframe mesh for rendering? I'm aware of algorithms for directly rendering CSG shapes, but I want to convert it into a wireframe mesh just once so that I can render it "normally"

To add a little more detail. Given a description of a shape such as "A cube here, intersection with a sphere here, subtract a cylinder here" I want to be able to calculate a polygon mesh.

+2  A: 

Here are some Google Scholar links which may be of use.

From what I can tell of the abstracts, the basic idea is to generate a point cloud from the volumetric data available in the CSG model, and then use some more common algorithms to generate a mesh of faces in 3D to fit that point cloud.

Edit: Doing some further research, this kind of operation is called "conversion from CSG to B-Rep (boundary representation)". Searches on that string lead to a useful PDF:

http://www.scielo.br/pdf/jbsmse/v29n4/a01v29n4.pdf

And, for further information, the key algorithm is called the "Marching Cubes Algorithm". Essentially, the CSG model is used to create a volumetric model of the object with voxels, and then the Marching Cubes algorithm is used to create a 3D mesh out of the voxel data.

e.James
+1 for the much more useful answer. I've retracted mine.
Carl Smotricz
+5  A: 

There are two main approaches. If you have a set of polygonal shapes, it is possible to create a BSP tree for each shape, then the BSP trees can be merged. From Wikipedia,

1990 Naylor, Amanatides, and Thibault provide an algorithm for merging two bsp trees to form a new bsp tree from the two original trees. This provides many benefits including: combining moving objects represented by BSP trees with a static environment (also represented by a BSP tree), very efficient CSG operations on polyhedra, exact collisions detection in O(log n * log n), and proper ordering of transparent surfaces contained in two interpenetrating objects (has been used for an x-ray vision effect).

The paper is found here Merging BSP trees yields polyhedral set operations.

Alternatively, each shape can be represented as a function over space (for example signed distance to the surface). As long as the surface is defined as where the function is equal to zero, the functions can then be combined using (MIN == intersection), (MAX == union), and (NEGATION = not) operators to mimic the set operations. The resulting surface can then be extracted as the positions where the combined function is equal to zero using a technique like Marching Cubes. Better surface extraction methods like Dual Marching Cubes or Dual Contouring can also be used. This will, of course, result in a discrete approximation of the true CSG surface. I suggest using Dual Contouring, because it is able to reconstruct sharp features like the corners of cubes .

Joe
This sounds promising. Can you provide any links to papers about this algorithm,?
Martin
Which algorithm?
Joe
I added some links to the BSP paper and Dual Contouring and clarified the CSG operations on functions.
Joe
thanks very much!
Martin
Two extremely recent papers on CSG operations on polygon/triangle meshes:Fast, Exact, Linear Booleanshttp://www.cs.utexas.edu/~gilbo/sgpdraft.pdfExact and Robust (Self-)Intersections for Polygonal Mesheshttp://www.graphics.rwth-aachen.de/uploads/media/campen_2010_eg_02.pdfMy understanding is that the main thrust of these algorithms is that they improve on the Naylor et al. work mentioned above to be much faster while still being exact up to machine precision and robust to poor triangle quality.
batty
Also, note that Dual Contouring requires normal information, in addition to the distance function information needed by marching cubes. (Though you can compute normals by taking the gradient of the signed distance function.)
batty
To clarify about batty's comment on taking the gradient, you want to make sure that you take the gradient of the function as close to on the surface as possible. If the function is defined over all space rather than just at regular intervals, you can perform a binary search along edges to make sure that you find the surface intersection. If you don't care about sharp features, you can still use Dual Contouring and simply place dual vertices at the average of the edge intersections in a cell.
Joe
+1  A: 

You could try to triangulate (tetrahedralize) each primitive, then perform the boolean operations on the tetrahedral mesh, which is "easier" since you only need to worry about tetrahedron-tetrahedron operations. Then you can perform boundary extraction to get the B-rep. Since you know the shapes of your primitives analytically, you can construct custom tetrahedralizations of your primitives to suit your needs instead of relying on a mesh generation library.

For example, suppose your object was the union of a cube and a cylinder, and suppose you have a tetrahedralization of both objects. In order to compute the boundary representation of the resulting object, you first label all the boundary facets of the tetrahedra of each primitive object. Then, you perform the union operation: if two tetrahedra are disjoint, then nothing needs to be done; both tetrahedra must exist in the resulting polyhedron. If they intersect, then there are a number of cases (probably on the order of a dozen or so) that need to be handled. In each of these cases, the volume of the two tetrahedra needs to be re-triangulated in a way that respects the surface constraints. This is made somewhat easier by the fact that you only need to worry about tetrahedra, as opposed to more complicated shapes. The boundary facet labels need to be maintained in the process so that in the final collection of tetrahedra, the boundary facets can be extracted to form a triangle mesh of the surface.

Victor Liu
Could you explain this in a little more detail? If I understand you correctly you mean have a mesh for each basic csg shape, and then do set operations on the meshes?
Martin
The basic idea is to perform the operations in even simpler primitives (simplices) instead of the actual CSG primitives. I've added a slightly more detailed example, but the actual details of how to handle all cases of tetrahedron-tetrahedron intersection are more complicated than I can describe here (I've never implemented such a method, nor have I seen an implementation, but the idea is pretty simple).
Victor Liu
+2  A: 

These libraries seems to do what you want:

www.solidgraphics.com/SolidKit/ carve-csg.com/ gts.sourceforge.net/

Roman
Wow, I had given up on this ever being answered. Fortuitously, you answered just as I regained interest in this project. I'll go and check these out and see if they do what I need. Thanks!
Martin
the GTS library is open source and fast, look great. Now to see if I can get it running with C# ;)
Martin
Unfortunately I can't make it work with C#. I also realised that I can't use any native code libraries because this needs to be able to run on xbox, so managed code only :(
Martin
The SolidKit Library provides also version for .NET. It is not free however.
Roman
+1  A: 

See also "Constructive Solid Geometry for Triangulated Polyhedra" (1990) Philip M. Hubbard doi:10.1.1.34.9374

John Pritchard