i currently writing a program to implement Marching Cube using C++ and Opengl.
However, my best reference is only from http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
in the web, the provided codes are written in C.
my problem here is that i don't understand the triTable and edgeTable
and how they are related.
can anyone help me on the explanation or guide me on converting the algorithm into codes?
The marching cubes algorithm [136] was developed to approximate an iso-valued surface with a triangle mesh. The algorithm breaks down the ways in which a surface can pass through a grid cell into 256 cases, based on the B(v) membership of the 8 voxels that form the cell's vertices.
Marching cubes (MC) algorithm was proposed by Lorensen and Cline in 1987 [LC87]. It analyzes the binary pattern of eight vertices of a cube to construct a surface that approx- imates the underlying surface. Considering rotations and symmetries, they reduce the original 256 patterns to a total of 15 configurations.
We first demonstrate that the marching cubes algorithm is not differentiable and propose an alternative differentiable formulation which we insert as a final layer into a 3D convolutional neural network. We further propose a set of loss functions which allow for training our model with sparse point supervision.
The unity project is a implementation of the algorithm Marching Cubes for the generation of a voxel engine for generate a random and infinite terrain. The idea is try to offer a flexible solution for developers that want integrate a free Voxel engine in his game or give a base for develop your own Marching Cube engine.
These Tables are used for finding out how to tesselate the surface:
The first table gives you the necessary edges to interpolate. The second table gives you the way you have to tesselate, meaning, which triangles you have to make inside the cube.
A little example:
let's assume, vertex one and 2 are below the iso level, the cubeindex should be 3.
The whole intersection should look like a wedge.
If you think about it, you have to interpolate values on the edges: 0 and 9 , and 2 and 10. If you enter this into a bitfield, each bit corresponding to "is edge intersected?" you would end up with something like this:
10 9 8 7 6 5 4 3 2 1 edge 1 1 0 0 0 0 1 0 1 0 intersected?
wouldn't you?
Which is exactly the value from edgeTable[3] in binary ;) 0x30A = 1100001010
Now you can write a function that linearly interpolates the points on those edges to fit your isolevel. These points will become your surface inside this cell.
But how to tesselate this cell/surface?
if you look into triTable[3] a smile should creep over your face :)
Addit after statement of residual puzzlement in comment: ;-)
What Marching Cubes does: Imagine you have a dark room with one point light source in it. It is the center of a volumetric light intensity field of scalar intensity values. You can go to point (x,y,z) and measure the intensity there, e.g. 3 candela.
You now want to render a surface through all points that have a certain light intensity. You can Imagine that this Isosurface would look like a sphere around the point light source. That is what we hope that Marching cubes will provide us with.
Now running through all points in the room and marking every point as a vertex that has roughly the iso value, will be algorithmically very complex and would result in a hughe number of vertices. Which we would then have to tesselate somehow.
So: First Marching cubes disects the whole volume into cubes of equal size. If the underlying data has some kind of underlying discreteness, multiples of that are used. I will not go into the other case, since that is rare. For instance we put a grid with the density of 1mm into a 2mx5mx5m room
We use cubes of 5mmx5mmx5mm. Running through them should be much cheaper.
You can imagine now, that the edges of some of the cubes intersect the isosurface. These are the interesting ones. This code identifies them:
cubeindex = 0; if (grid.val[0]
if cubeindex stays zero, this particular cube is not intersected by the isosurface. If cubeindex is > 0 you now know that the isosurface goes through this cube and you want to render the piece of the isosurface that is inside it.
Please picture this in your mind. See http://en.wikipedia.org/wiki/Marching_cubes for examples of intersected cubes.
The vertices that you could get easily are those on the edges of the cube. Just interpolate linearly between 2 corner points to find the position of the isovalue and put a vertex there. But which edges are intersected??? That is the information in edgeTable[cubeindex]. That is the big piece of code with all the ifs, that stores the interpolated points as vertices in an array of xyz points: vertlist[]. This piece reads as follows:
get the bitfield = edgeTable[cubeindex] if edge 1 is marked in bitfield (bit 1 set to 1 in bitfield) vertlist[0] = interpolated point, somewhere on edge 1 ... and so on.
You now have an array full of vertices, but how to connect them to triangles? That's an info that tritable provides.
The rest is pretty much what I explained above.
Well should there still be problems, please be specific about the piece of code that gives you trouble.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With