FOX/ObjCryst++  1.10.X (development)
MC.h
1 // FileName: MarchingCubes.cpp
3 // Author : Michael Y. Polyakov
4 // email : myp@andrew.cmu.edu or mikepolyakov@hotmail.com
5 // website : www.angelfire.com/linux/myp
6 // date : July 2002
7 //
8 // Description: 'Straight' and Recursive Marching Cubes Algorithms
9 // Normal vectors are defined for each vertex as a gradients
10 // For function definitions see MarchingCubes.h
11 // For a tutorial on Marching Cubes please visit www.angelfire.com/myp/linux
12 //
13 // Please email me with any suggestion/bugs.
15 
16 #ifndef MARCHINGCUBES_H_
17 #define MARCHINGCUBES_H_
18 
19 #include "ObjCryst/wxCryst/mpVector.h"
20 
21 //struct for storing triangle information - 3 vertices and 3 normal vectors for each vertex
22 typedef struct {
23  mpVector p[3];
24  mpVector norm[3];
25 } TRIANGLE;
26 
27 //does Linear Interpolation between points p1 and p2 (they already contain their computed values)
28 mpVector LinearInterp(mp4Vector p1, mp4Vector p2, float value);
29 
31 //POINTERS TO FUNCTIONS
32 //pointer to function which computes the value at point p
33 typedef float (*FORMULA)(mpVector);
35 
39 
40 // 'STRAIGHT' Marching Cubes Algorithm //////////////////////////////////////////////////
41 //takes number of cells (ncellsX, ncellsY, ncellsZ) to subdivide on each axis
42 // minValue used to pass into LinearInterp
43 // gradFactor for each axis (multiplies each component of gradient vector by 1/(2*gradFactor) ).
44 // Should be set to the length of a side (or close to it)
45 // array of length (ncellsX+1)(ncellsY+1)(ncellsZ+1) of mp4Vector points containing coordinates and values
46 //returns pointer to triangle array and the number of triangles in numTriangles
47 //note: array of points is first taken on z axis, then y and then x. So for example, if you iterate through it in a
48 // for loop, have indexes i, j, k for x, y, z respectively, then to get the point you will have to make the
49 // following index: i*(ncellsY+1)*(ncellsZ+1) + j*(ncellsZ+1) + k .
50 // Also, the array starts at the minimum on all axes.
51 TRIANGLE* MC(int ncellsX, int ncellsY, int ncellsZ, float gradFactorX, float gradFactorY, float gradFactorZ,
52  float minValue, mp4Vector * points, int &numTriangles);
54 
55 
56 // RECURSIVE Marching Cubes /////////////////////////////////////////////////////////////
57 //DrawBacks: must know how many objects are drawn
58 
59 //This function starts the Recursive Marching Cubes
60 // numCubes: number of intersecting cubes passed as starting points
61 // ii, jj, kk: arrays of size numCubes. Contain respective indexes of cubes that are intersected
62 TRIANGLE* MarchingCubesRec(int ncellsX, int ncellsY, int ncellsZ,
63  float gradFactorX, float gradFactorY, float gradFactorZ,
64  int numCubes, int *ii, int *jj, int *kk,
65  float minValue, mp4Vector * points, int &numTriangles);
66 
67 //Next 6 functions are called by the corresponding face of each cube (e.g. face 0 calls MCFace0 etc...)
68 // Each function accepts the following information as arguments:
69 // First 3 arguments: number of cells to subdivide on each axis
70 // gradFactor: factor to scale the gradient vectors (multiplies by 1/(2*gradFactor) )
71 // ind: index of this cube in the points array (this is so it doesnt have to be computed again)
72 // i,j,k: indexes of the this cube on x,y,z axis respectively
73 // minValue: minimum used in LinearInterp
74 // points: array of type mp4Vector and size (ncellsX+1)*(ncellsY+1)*(ncellsZ+1) that contains
75 // coordinates and values at each point
76 // triangle: array of triangles which is being built and returned at the end of recursion
77 // numTriangles: number of triangles formed
78 // prevVerts: adjacent 4 vertices of the previous cube, passed in the special order which the correspoding
79 // MCFace function recognizes. For specificatino on which indexes passed from the last cube go to
80 // which vertexes of the current cube visit my website at www.angelfire.com/linux/myp
81 // prevIntVerts: array of 4 linearly interpolated vertices on 4 adjacent edges
82 // edgeIndex: integer, bits of which correspond to the edges of the current cube which have been computed
83 // from the previous cube
84 // prevGradVerts: array of 4 gradient vectors at 4 adjacent vertices
85 // prevGrads: linearly interpolated gradient vectors on 4 adjacent edges
86 // gradIndex: integer bits of which correspond to already computed vertices of the current cube
87 // marchedCubes: bool array of size ncellsX*ncellsY*ncellsZ which stores which cubes already have been marched
88 // through. Initialized to FALSE. This is not the most effective way in terms of memory management, but
89 // faster than using STLs vector<bool> which stores booleans as bits.
90 //* NOTE *: Each of these 6 functions run marching cubes on the 'next'cube adjacent to the surface number
91 // that is specified in their names (for numbering see my webpage). Each assigns the previous computed
92 // values to the face 'opposite' of that specified. Then each one runs Marching Cubes for the current cube.
93 // It returns doing nothing if the cube is not intersected, however, if it is then other recursive
94 // functions are called using macros MC_FACE defined for each face. See MarchingCubes.cpp
95 // For example MCFace0 will initialize surface 2 using the previous values that are passed to it. Then if
96 // the current cube is intersected it will run MC_FACE0, MC_FACE1, MC_FACE3, MC_FACE4, and MC_FACE5. Each
97 // returnes the pointer to the array of formed triangles.
98 
99 //FACE 0 Marching Cubes
100 TRIANGLE* MCFace0(int ncellsX, int ncellsY, int ncellsZ,
101  float gradFactorX, float gradFactorY, float gradFactorZ,
102  int ind, int i, int j, int k,
103  float minValue, mp4Vector * points, TRIANGLE *triangles, int &numTriangles,
104  mp4Vector prevVerts[4], mpVector prevIntVerts[4], int edgeIndex,
105  mp4Vector prevGradVerts[4], mpVector prevGrads[4], int gradIndex, bool* marchedCubes);
106 //FACE 1 Marching Cubes
107 TRIANGLE* MCFace1(int ncellsX, int ncellsY, int ncellsZ,
108  float gradFactorX, float gradFactorY, float gradFactorZ,
109  int ind, int i, int j, int k,
110  float minValue, mp4Vector * points, TRIANGLE *triangles, int &numTriangles,
111  mp4Vector prevVerts[4], mpVector prevIntVerts[4], int edgeIndex,
112  mp4Vector prevGradVerts[4], mpVector prevGrads[4], int gradIndex, bool* marchedCubes);
113 //FACE 2 Marching Cubes
114 TRIANGLE* MCFace2(int ncellsX, int ncellsY, int ncellsZ,
115  float gradFactorX, float gradFactorY, float gradFactorZ,
116  int ind, int i, int j, int k,
117  float minValue, mp4Vector * points, TRIANGLE *triangles, int &numTriangles,
118  mp4Vector prevVerts[4], mpVector prevIntVerts[4], int edgeIndex,
119  mp4Vector prevGradVerts[4], mpVector prevGrads[4], int gradIndex, bool* marchedCubes);
120 //FACE 3 Marching Cubes
121 TRIANGLE* MCFace3(int ncellsX, int ncellsY, int ncellsZ,
122  float gradFactorX, float gradFactorY, float gradFactorZ,
123  int ind, int i, int j, int k,
124  float minValue, mp4Vector * points, TRIANGLE *triangles, int &numTriangles,
125  mp4Vector prevVerts[4], mpVector prevIntVerts[4], int edgeIndex,
126  mp4Vector prevGradVerts[4], mpVector prevGrads[4], int gradIndex, bool* marchedCubes);
127 //FACE 4 Marching Cubes
128 TRIANGLE* MCFace4(int ncellsX, int ncellsY, int ncellsZ,
129  float gradFactorX, float gradFactorY, float gradFactorZ,
130  int ind, int i, int j, int k,
131  float minValue, mp4Vector * points, TRIANGLE *triangles, int &numTriangles,
132  mp4Vector prevVerts[4], mpVector prevIntVerts[4], int edgeIndex,
133  mp4Vector prevGradVerts[4], mpVector prevGrads[4], int gradIndex, bool* marchedCubes);
134 //FACE 5 Marching Cubes
135 TRIANGLE* MCFace5(int ncellsX, int ncellsY, int ncellsZ,
136  float gradFactorX, float gradFactorY, float gradFactorZ,
137  int ind, int i, int j, int k,
138  float minValue, mp4Vector * points, TRIANGLE *triangles, int &numTriangles,
139  mp4Vector prevVerts[4], mpVector prevIntVerts[4], int edgeIndex,
140  mp4Vector prevGradVerts[4], mpVector prevGrads[4], int gradIndex, bool* marchedCubes);
141 
142 
143 
144 //Does Marching Cubes on cube (i, j, k) in points
145 // Requirements: needs index ind which specifies which cube it is (its 0th point in points array)
146 // If cube is intersected the triangles are added to triangles array passed to it, and numTriangles is
147 // incremented appropriately. verts, array of vertices of this cube should be initialized.
148 // intVerts, interpolated vertices on edges, gradVerts, gradients on vertices, and grads, interpolated
149 // gradient vectors on edges dont have to be initialized, but if they are corresponding bits in edgeIndex
150 // and indGrad index should show it. (for numbering see my web page)
151 // Global variables YtimeZ should be initialized to (ncellsZ+1)*(ncellsY+1) and pointsZ should be ncellsZ+1
152 TRIANGLE* MarchOneCube(int ncellsX, int ncellsY, int ncellsZ,
153  float gradFactorX, float gradFactorY, float gradFactorZ,
154  int ind, int i, int j, int k,
155  float minValue, mp4Vector * points, TRIANGLE *triangles, int &numTriangles,
156  mp4Vector verts[8], mpVector intVerts[12], int &edgeIndex,
157  mp4Vector gradVerts[8], mpVector grads[12], int &indGrad);
158 
159 
160 //Find the first intersecting cube (if it exists).
161 //Starts at (i,j,k)=(0,0,0) at the minimum x,y,z and then goes linearly searching for an intersecting cube.
162 //Returns array of indices i,j,k of the first found cube or -1,-1,-1 if cube was not found
163 float* MCFind(int ncellsX, int ncellsY, int ncellsZ, float minValue, mp4Vector * points);
164 
165 //Calls the MCFind and if found calls MarchingCubesRec with the returned indices
166 //If not found NULL is returned and numTriangles is set to ZERO.
167 TRIANGLE* MCRecFind(int ncellsX, int ncellsY, int ncellsZ,
168  float gradFactorX, float gradFactorY, float gradFactorZ,
169  float minValue, mp4Vector * points, int &numTriangles);
170 
171 #endif
Definition: MC.h:22