40 if(fabs(p1.val - p2.val) > 0.00001)
51 #define CALC_GRAD_VERT_0(verts) mp4Vector(points[ind-YtimeZ].val-(verts[1]).val,points[ind-pointsZ].val-(verts[4]).val,points[ind-1].val-(verts[3]).val, (verts[0]).val);
52 #define CALC_GRAD_VERT_1(verts) mp4Vector((verts[0]).val-points[ind+2*YtimeZ].val,points[ind+YtimeZ-pointsZ].val-(verts[5]).val,points[ind+YtimeZ-1].val-(verts[2]).val, (verts[1]).val);
53 #define CALC_GRAD_VERT_2(verts) mp4Vector((verts[3]).val-points[ind+2*YtimeZ+1].val,points[ind+YtimeZ-ncellsZ].val-(verts[6]).val,(verts[1]).val-points[ind+YtimeZ+2].val, (verts[2]).val);
54 #define CALC_GRAD_VERT_3(verts) mp4Vector(points[ind-YtimeZ+1].val-(verts[2]).val,points[ind-ncellsZ].val-(verts[7]).val,(verts[0]).val-points[ind+2].val, (verts[3]).val);
55 #define CALC_GRAD_VERT_4(verts) mp4Vector(points[ind-YtimeZ+ncellsZ+1].val-(verts[5]).val,(verts[0]).val-points[ind+2*pointsZ].val,points[ind+ncellsZ].val-(verts[7]).val, (verts[4]).val);
56 #define CALC_GRAD_VERT_5(verts) mp4Vector((verts[4]).val-points[ind+2*YtimeZ+ncellsZ+1].val,(verts[1]).val-points[ind+YtimeZ+2*pointsZ].val,points[ind+YtimeZ+ncellsZ].val-(verts[6]).val, (verts[5]).val);
57 #define CALC_GRAD_VERT_6(verts) mp4Vector((verts[7]).val-points[ind+2*YtimeZ+ncellsZ+2].val,(verts[2]).val-points[ind+YtimeZ+2*ncellsZ+3].val,(verts[5]).val-points[ind+YtimeZ+ncellsZ+3].val, (verts[6]).val);
58 #define CALC_GRAD_VERT_7(verts) mp4Vector(points[ind-YtimeZ+ncellsZ+2].val-(verts[6]).val,(verts[3]).val-points[ind+2*ncellsZ+3].val,(verts[4]).val-points[ind+ncellsZ+3].val, (verts[7]).val);
72 TRIANGLE* MC(
int ncellsX,
int ncellsY,
int ncellsZ,
73 float gradFactorX,
float gradFactorY,
float gradFactorZ,
74 float minValue,
mp4Vector * points,
int &numTriangles)
78 numTriangles = int(0);
81 YtimeZ = (ncellsY+1)*pointsZ;
95 mpVector factor(1.0/(2.0*gradFactorX), 1.0/(2.0*gradFactorY), 1.0/(2.0*gradFactorZ));
98 for(
int i=0; i < lastX; i++) {
100 for(
int j=0; j < lastY; j++) {
102 for(
int k=0; k < lastZ; k++, ind++)
106 verts[0] = &points[ind];
107 verts[1] = &points[ind + YtimeZ];
108 verts[4] = &points[ind + pointsZ];
109 verts[5] = &points[ind + YtimeZ + pointsZ];
110 verts[2] = &points[ind + YtimeZ + 1];
111 verts[3] = &points[ind + 1];
112 verts[6] = &points[ind + YtimeZ + pointsZ + 1];
113 verts[7] = &points[ind + pointsZ + 1];
117 for(
int n=0; n < 8; n++)
118 if(verts[n]->val <= minValue) cubeIndex |= (1 << n);
121 if(!edgeTable[cubeIndex])
continue;
124 edgeIndex = edgeTable[cubeIndex];
127 intVerts[0] = LinearInterp(*verts[0], *verts[1], minValue);
128 if(i != 0 && j != 0 && k != 0) gradVerts[0] = CALC_GRAD_VERT_0(*verts)
129 else gradVerts[0] =
mp4Vector(1.0, 1.0, 1.0, 1.0);
130 if(i != lastX-1 && j != 0 && k != 0) gradVerts[1] = CALC_GRAD_VERT_1(*verts)
131 else gradVerts[1] = mp4Vector(1.0, 1.0, 1.0, 1.0);
133 grads[0] = LinearInterp(gradVerts[0], gradVerts[1], minValue);
134 grads[0].x *= factor.x; grads[0].y *= factor.y; grads[0].z *= factor.z;
137 intVerts[1] = LinearInterp(*verts[1], *verts[2], minValue);
138 if(! (indGrad & 2)) {
139 if(i != lastX-1 && j != 0 && k != 0) gradVerts[1] = CALC_GRAD_VERT_1(*verts)
140 else gradVerts[1] = mp4Vector(1.0, 1.0, 1.0, 1.0);
143 if(i != lastX-1 && j != 0 && k != 0) gradVerts[2] = CALC_GRAD_VERT_2(*verts)
144 else gradVerts[2] = mp4Vector(1.0, 1.0, 1.0, 1.0);
146 grads[1] = LinearInterp(gradVerts[1], gradVerts[2], minValue);
147 grads[1].x *= factor.x; grads[1].y *= factor.y; grads[1].z *= factor.z;
150 intVerts[2] = LinearInterp(*verts[2], *verts[3], minValue);
151 if(! (indGrad & 4)) {
152 if(i != lastX-1 && j != 0 && k != 0) gradVerts[2] = CALC_GRAD_VERT_2(*verts)
153 else gradVerts[2] = mp4Vector(1.0, 1.0, 1.0, 1.0);
156 if(i != 0 && j != 0 && k != lastZ-1) gradVerts[3] = CALC_GRAD_VERT_3(*verts)
157 else gradVerts[3] = mp4Vector(1.0, 1.0, 1.0, 1.0);
159 grads[2] = LinearInterp(gradVerts[2], gradVerts[3], minValue);
160 grads[2].x *= factor.x; grads[2].y *= factor.y; grads[2].z *= factor.z;
163 intVerts[3] = LinearInterp(*verts[3], *verts[0], minValue);
164 if(! (indGrad & 8)) {
165 if(i != 0 && j != 0 && k != lastZ-1) gradVerts[3] = CALC_GRAD_VERT_3(*verts)
166 else gradVerts[3] = mp4Vector(1.0, 1.0, 1.0, 1.0);
169 if(! (indGrad & 1)) {
170 if(i != 0 && j != 0 && k != 0) gradVerts[0] = CALC_GRAD_VERT_0(*verts)
171 else gradVerts[0] = mp4Vector(1.0, 1.0, 1.0, 1.0);
174 grads[3] = LinearInterp(gradVerts[3], gradVerts[0], minValue);
175 grads[3].x *= factor.x; grads[3].y *= factor.y; grads[3].z *= factor.z;
178 intVerts[4] = LinearInterp(*verts[4], *verts[5], minValue);
180 if(i != 0 && j != lastY-1 && k != 0) gradVerts[4] = CALC_GRAD_VERT_4(*verts)
181 else gradVerts[4] = mp4Vector(1.0, 1.0, 1.0, 1.0);
183 if(i != lastX-1 && j != lastY-1 && k != 0) gradVerts[5] = CALC_GRAD_VERT_5(*verts)
184 else gradVerts[5] = mp4Vector(1.0, 1.0, 1.0, 1.0);
187 grads[4] = LinearInterp(gradVerts[4], gradVerts[5], minValue);
188 grads[4].x *= factor.x; grads[4].y *= factor.y; grads[4].z *= factor.z;
191 intVerts[5] = LinearInterp(*verts[5], *verts[6], minValue);
192 if(! (indGrad & 32)) {
193 if(i != lastX-1 && j != lastY-1 && k != 0) gradVerts[5] = CALC_GRAD_VERT_5(*verts)
194 else gradVerts[5] = mp4Vector(1.0, 1.0, 1.0, 1.0);
198 if(i != lastX-1 && j != lastY-1 && k != lastZ-1) gradVerts[6] = CALC_GRAD_VERT_6(*verts)
199 else gradVerts[6] = mp4Vector(1.0, 1.0, 1.0, 1.0);
201 grads[5] = LinearInterp(gradVerts[5], gradVerts[6], minValue);
202 grads[5].x *= factor.x; grads[5].y *= factor.y; grads[5].z *= factor.z;
205 intVerts[6] = LinearInterp(*verts[6], *verts[7], minValue);
206 if(! (indGrad & 64)) {
207 if(i != lastX-1 && j != lastY-1 && k != lastZ-1) gradVerts[6] = CALC_GRAD_VERT_6(*verts)
208 else gradVerts[6] = mp4Vector(1.0, 1.0, 1.0, 1.0);
212 if(i != 0 && j != lastY-1 && k != lastZ-1) gradVerts[7] = CALC_GRAD_VERT_7(*verts)
213 else gradVerts[7] = mp4Vector(1.0, 1.0, 1.0, 1.0);
215 grads[6] = LinearInterp(gradVerts[6], gradVerts[7], minValue);
216 grads[6].x *= factor.x; grads[6].y *= factor.y; grads[6].z *= factor.z;
218 if(edgeIndex & 128) {
219 intVerts[7] = LinearInterp(*verts[7], *verts[4], minValue);
220 if(! (indGrad & 128)) {
221 if(i != 0 && j != lastY-1 && k != lastZ-1) gradVerts[7] = CALC_GRAD_VERT_7(*verts)
222 else gradVerts[7] = mp4Vector(1.0, 1.0, 1.0, 1.0);
225 if(! (indGrad & 16)) {
226 if(i != 0 && j != lastY-1 && k != 0) gradVerts[4] = CALC_GRAD_VERT_4(*verts)
227 else gradVerts[4] = mp4Vector(1.0, 1.0, 1.0, 1.0);
230 grads[7] = LinearInterp(gradVerts[7], gradVerts[4], minValue);
231 grads[7].x *= factor.x; grads[7].y *= factor.y; grads[7].z *= factor.z;
233 if(edgeIndex & 256) {
234 intVerts[8] = LinearInterp(*verts[0], *verts[4], minValue);
235 if(! (indGrad & 1)) {
236 if(i != 0 && j != 0 && k != 0) gradVerts[0] = CALC_GRAD_VERT_0(*verts)
237 else gradVerts[0] = mp4Vector(1.0, 1.0, 1.0, 1.0);
240 if(! (indGrad & 16)) {
241 if(i != 0 && j != lastY-1 && k != 0) gradVerts[4] = CALC_GRAD_VERT_4(*verts)
242 else gradVerts[4] = mp4Vector(1.0, 1.0, 1.0, 1.0);
245 grads[8] = LinearInterp(gradVerts[0], gradVerts[4], minValue);
246 grads[8].x *= factor.x; grads[8].y *= factor.y; grads[8].z *= factor.z;
248 if(edgeIndex & 512) {
249 intVerts[9] = LinearInterp(*verts[1], *verts[5], minValue);
250 if(! (indGrad & 2)) {
251 if(i != lastX-1 && j != 0 && k != 0) gradVerts[1] = CALC_GRAD_VERT_1(*verts)
252 else gradVerts[1] = mp4Vector(1.0, 1.0, 1.0, 1.0);
255 if(! (indGrad & 32)) {
256 if(i != lastX-1 && j != lastY-1 && k != 0) gradVerts[5] = CALC_GRAD_VERT_5(*verts)
257 else gradVerts[5] = mp4Vector(1.0, 1.0, 1.0, 1.0);
260 grads[9] = LinearInterp(gradVerts[1], gradVerts[5], minValue);
261 grads[9].x *= factor.x; grads[9].y *= factor.y; grads[9].z *= factor.z;
263 if(edgeIndex & 1024) {
264 intVerts[10] = LinearInterp(*verts[2], *verts[6], minValue);
265 if(! (indGrad & 4)) {
266 if(i != lastX-1 && j != 0 && k != 0) gradVerts[2] = CALC_GRAD_VERT_2(*verts)
267 else gradVerts[5] = mp4Vector(1.0, 1.0, 1.0, 1.0);
270 if(! (indGrad & 64)) {
271 if(i != lastX-1 && j != lastY-1 && k != lastZ-1) gradVerts[6] = CALC_GRAD_VERT_6(*verts)
272 else gradVerts[6] = mp4Vector(1.0, 1.0, 1.0, 1.0);
275 grads[10] = LinearInterp(gradVerts[2], gradVerts[6], minValue);
276 grads[10].x *= factor.x; grads[10].y *= factor.y; grads[10].z *= factor.z;
278 if(edgeIndex & 2048) {
279 intVerts[11] = LinearInterp(*verts[3], *verts[7], minValue);
280 if(! (indGrad & 8)) {
281 if(i != 0 && j != 0 && k != lastZ-1) gradVerts[3] = CALC_GRAD_VERT_3(*verts)
282 else gradVerts[3] = mp4Vector(1.0, 1.0, 1.0, 1.0);
285 if(! (indGrad & 128)) {
286 if(i != 0 && j != lastY-1 && k != lastZ-1) gradVerts[7] = CALC_GRAD_VERT_7(*verts)
287 else gradVerts[7] = mp4Vector(1.0, 1.0, 1.0, 1.0);
290 grads[11] = LinearInterp(gradVerts[3], gradVerts[7], minValue);
291 grads[11].x *= factor.x; grads[11].y *= factor.y; grads[11].z *= factor.z;
295 for (
int n=0; triTable[cubeIndex][n] != -1; n+=3) {
296 int index[3] = {triTable[cubeIndex][n+2], triTable[cubeIndex][n+1], triTable[cubeIndex][n]};
297 for(
int h=0; h < 3; h++) {
298 triangles[numTriangles].p[h] = intVerts[index[h]];
299 triangles[numTriangles].norm[h] = grads[index[h]];
309 for(
int i=0; i < numTriangles; i++)
310 retTriangles[i] = triangles[i];
333 if(! marchedCubes[ind - 1]) { \
335 if(gradIndex & 1) passGradIndex |= 8; \
336 if(gradIndex & 2) passGradIndex |= 4; \
337 if(gradIndex & 32) passGradIndex |= 64; \
338 if(gradIndex & 16) passGradIndex |= 128; \
340 if(edgeIndex & 1) passEdgeIndex |= 4; \
341 if(edgeIndex & 512) passGradIndex |= 1024; \
342 if(edgeIndex & 16) passEdgeIndex |= 64; \
343 if(edgeIndex & 256) passGradIndex |= 2048; \
344 prevVerts[0] = verts[0]; prevVerts[1] = verts[1]; prevVerts[2] = verts[5]; prevVerts[3] = verts[4]; \
345 prevIntVerts[0] = intVerts[0]; prevIntVerts[1] = intVerts[9]; \
346 prevIntVerts[2] = intVerts[4]; prevIntVerts[3] = intVerts[8]; \
347 prevGradVerts[0] = gradVerts[0]; prevGradVerts[1] = gradVerts[1]; \
348 prevGradVerts[2] = gradVerts[5]; prevGradVerts[3] = gradVerts[4]; \
349 prevGrads[0] = grads[0]; prevGrads[1] = grads[9]; prevGrads[2] = grads[4]; prevGrads[3] = grads[8]; \
350 triangles = MCFace0(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, \
351 ind-1, i, j, k-1, minValue, points, triangles, numTriangles, \
352 prevVerts, prevIntVerts, passEdgeIndex, \
353 prevGradVerts, prevGrads, passGradIndex, marchedCubes); \
359 if(! marchedCubes[ind + YtimeZ]) { \
361 if(gradIndex & 4) passGradIndex |= 8; \
362 if(gradIndex & 2) passGradIndex |= 1; \
363 if(gradIndex & 32) passGradIndex |= 16; \
364 if(gradIndex & 64) passGradIndex |= 128; \
366 if(edgeIndex & 2) passEdgeIndex |= 8; \
367 if(edgeIndex & 512) passEdgeIndex |= 256; \
368 if(edgeIndex & 32) passEdgeIndex |= 128; \
369 if(edgeIndex & 1024) passEdgeIndex |= 2048; \
370 prevVerts[0] = verts[2]; prevVerts[1] = verts[1]; prevVerts[2] = verts[5]; prevVerts[3] = verts[6]; \
371 prevIntVerts[0] = intVerts[1]; prevIntVerts[1] = intVerts[9]; \
372 prevIntVerts[2] = intVerts[5]; prevIntVerts[3] = intVerts[10]; \
373 prevGradVerts[0] = gradVerts[2]; prevGradVerts[1] = gradVerts[1]; \
374 prevGradVerts[2] = gradVerts[5]; prevGradVerts[3] = gradVerts[6]; \
375 prevGrads[0] = grads[1]; prevGrads[1] = grads[9]; prevGrads[2] = grads[5]; prevGrads[3] = grads[10]; \
376 triangles = MCFace1(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, \
377 ind+YtimeZ, i+1, j, k, minValue, points, triangles, numTriangles, \
378 prevVerts, prevIntVerts, passEdgeIndex, \
379 prevGradVerts, prevGrads, passGradIndex, marchedCubes); \
385 if(! marchedCubes[ind + 1]) { \
387 if(gradIndex & 8) passGradIndex |= 1; \
388 if(gradIndex & 4) passGradIndex |= 2; \
389 if(gradIndex & 64) passGradIndex |= 32; \
390 if(gradIndex & 128) passGradIndex |= 16; \
392 if(edgeIndex & 4) passEdgeIndex |= 1; \
393 if(edgeIndex & 1024) passEdgeIndex |= 512; \
394 if(edgeIndex & 64) passEdgeIndex |= 16; \
395 if(edgeIndex & 2048) passEdgeIndex |= 256; \
396 prevVerts[0] = verts[3]; prevVerts[1] = verts[2]; prevVerts[2] = verts[6]; prevVerts[3] = verts[7]; \
397 prevIntVerts[0] = intVerts[2]; prevIntVerts[1] = intVerts[10]; \
398 prevIntVerts[2] = intVerts[6]; prevIntVerts[3] = intVerts[11]; \
399 prevGradVerts[0] = gradVerts[3]; prevGradVerts[1] = gradVerts[2]; \
400 prevGradVerts[2] = gradVerts[6]; prevGradVerts[3] = gradVerts[7]; \
401 prevGrads[0] = grads[2]; prevGrads[1] = grads[10]; prevGrads[2] = grads[6]; prevGrads[3] = grads[11]; \
402 triangles = MCFace2(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, \
403 ind+1, i, j, k+1, minValue, points, triangles, numTriangles, \
404 prevVerts, prevIntVerts, passEdgeIndex, \
405 prevGradVerts, prevGrads, passGradIndex, marchedCubes); \
411 if(! marchedCubes[ind - YtimeZ]) { \
413 if(gradIndex & 8) passGradIndex |= 4; \
414 if(gradIndex & 1) passGradIndex |= 2; \
415 if(gradIndex & 128) passGradIndex |= 64; \
416 if(gradIndex & 16) passGradIndex |= 32; \
418 if(edgeIndex & 8) passEdgeIndex |= 2; \
419 if(edgeIndex & 256) passEdgeIndex |= 512; \
420 if(edgeIndex & 128) passEdgeIndex |= 32; \
421 if(edgeIndex & 2048) passEdgeIndex |= 1024; \
422 prevVerts[0] = verts[3]; prevVerts[1] = verts[0]; prevVerts[2] = verts[4]; prevVerts[3] = verts[7]; \
423 prevIntVerts[0] = intVerts[3]; prevIntVerts[1] = intVerts[8]; \
424 prevIntVerts[2] = intVerts[7]; prevIntVerts[3] = intVerts[11]; \
425 prevGradVerts[0] = gradVerts[3]; prevGradVerts[1] = gradVerts[0]; \
426 prevGradVerts[2] = gradVerts[4]; prevGradVerts[3] = gradVerts[7]; \
427 prevGrads[0] = grads[3]; prevGrads[1] = grads[8]; prevGrads[2] = grads[7]; prevGrads[3] = grads[11]; \
428 triangles = MCFace3(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, \
429 ind-YtimeZ, i-1, j, k, minValue, points, triangles, numTriangles, \
430 prevVerts, prevIntVerts, passEdgeIndex, \
431 prevGradVerts, prevGrads, passGradIndex, marchedCubes); \
438 if(! marchedCubes[ind + pointsZ]) { \
440 if(gradIndex & 128) passGradIndex |= 8; \
441 if(gradIndex & 64) passGradIndex |= 4; \
442 if(gradIndex & 32) passGradIndex |= 2; \
443 if(gradIndex & 16) passGradIndex |= 1; \
445 if(edgeIndex & 128) passEdgeIndex |= 8; \
446 if(edgeIndex & 64) passEdgeIndex |= 4; \
447 if(edgeIndex & 32) passEdgeIndex |= 2; \
448 if(edgeIndex & 16) passEdgeIndex |= 1; \
449 prevVerts[0] = verts[7]; prevVerts[1] = verts[6]; prevVerts[2] = verts[5]; prevVerts[3] = verts[4]; \
450 prevIntVerts[0] = intVerts[6]; prevIntVerts[1] = intVerts[5]; \
451 prevIntVerts[2] = intVerts[4]; prevIntVerts[3] = intVerts[7]; \
452 prevGradVerts[0] = gradVerts[7]; prevGradVerts[1] = gradVerts[6]; \
453 prevGradVerts[2] = gradVerts[5]; prevGradVerts[3] = gradVerts[4]; \
454 prevGrads[0] = grads[6]; prevGrads[1] = grads[5]; prevGrads[2] = grads[4]; prevGrads[3] = grads[7]; \
455 triangles = MCFace4(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, \
456 ind+pointsZ, i, j+1, k, minValue, points, triangles, numTriangles, \
457 prevVerts, prevIntVerts, passEdgeIndex, \
458 prevGradVerts, prevGrads, passGradIndex, marchedCubes); \
464 if(! marchedCubes[ind - ncellsZ - 1]) { \
465 passGradIndex = (gradIndex << 4) & 240; \
466 passEdgeIndex = (edgeIndex << 4) & 240; \
467 prevVerts[0] = verts[3]; prevVerts[1] = verts[2]; prevVerts[2] = verts[1]; prevVerts[3] = verts[0]; \
468 prevIntVerts[0] = intVerts[2]; prevIntVerts[1] = intVerts[1]; \
469 prevIntVerts[2] = intVerts[0]; prevIntVerts[3] = intVerts[3]; \
470 prevGradVerts[0] = gradVerts[3]; prevGradVerts[1] = gradVerts[2]; \
471 prevGradVerts[2] = gradVerts[1]; prevGradVerts[3] = gradVerts[0]; \
472 prevGrads[0] = grads[2]; prevGrads[1] = grads[1]; prevGrads[2] = grads[0]; prevGrads[3] = grads[3]; \
473 triangles = MCFace5(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, \
474 ind-ncellsZ-1, i, j-1, k, minValue, points, triangles, numTriangles, \
475 prevVerts, prevIntVerts, passEdgeIndex, \
476 prevGradVerts, prevGrads, passGradIndex, marchedCubes); \
487 TRIANGLE* MarchingCubesRec(
int ncellsX,
int ncellsY,
int ncellsZ,
488 float gradFactorX,
float gradFactorY,
float gradFactorZ,
489 int numCubes,
int *ii,
int *jj,
int *kk,
490 float minValue, mp4Vector * points,
int &numTriangles)
493 numTriangles = int(0);
495 for(
int n=0; n < numCubes; n++) {
496 if(ii[n] <= 0 || ii[n] >= ncellsX-1)
return NULL;
497 if(jj[n] <= 0 || jj[n] >= ncellsY-1)
return NULL;
498 if(kk[n] <= 0 || kk[n] >= ncellsZ-1)
return NULL;
501 int all = ncellsX*ncellsY*ncellsZ;
502 bool* marchedCubes =
new bool[all];
503 for(
int i=0; i < all; i++) marchedCubes[i] = FALSE;
508 mp4Vector gradVerts[8];
513 YtimeZ = (ncellsY+1)*pointsZ;
515 mp4Vector prevVerts[4];
517 mp4Vector prevGradVerts[4];
521 int passEdgeIndex, passGradIndex;
525 for(
int n=0; n < numCubes; n++) {
527 i = ii[n]; j = jj[n]; k = kk[n];
528 int ind = i*YtimeZ + j*pointsZ + k;
529 verts[0] = points[ind];
530 verts[1] = points[ind + YtimeZ];
531 verts[2] = points[ind + YtimeZ + 1];
532 verts[3] = points[ind + 1];
533 verts[4] = points[ind + pointsZ];
534 verts[5] = points[ind + YtimeZ + pointsZ];
535 verts[6] = points[ind + YtimeZ + pointsZ + 1];
536 verts[7] = points[ind + pointsZ + 1];
539 if(! marchedCubes[ind]) {
541 gradIndex = edgeIndex = 0;
542 triangles = MarchOneCube(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ,
543 ind, i, j, k, minValue, points, triangles, numTriangles,
544 verts, intVerts, edgeIndex, gradVerts, grads, gradIndex);
546 marchedCubes[ind] = TRUE;
558 for(
int i=0; i < numTriangles; i++) retTriangles[i] = triangles[i];
560 delete [] marchedCubes;
565 TRIANGLE* MCFace0(
int ncellsX,
int ncellsY,
int ncellsZ,
566 float gradFactorX,
float gradFactorY,
float gradFactorZ,
567 int ind,
int i,
int j,
int k,
568 float minValue, mp4Vector * points,
TRIANGLE *triangles,
int &numTriangles,
569 mp4Vector prevVerts[4],
mpVector prevIntVerts[4],
int edgeIndex,
570 mp4Vector prevGradVerts[4],
mpVector prevGrads[4],
int gradIndex,
bool* marchedCubes)
573 if(i <= 0 || i >= ncellsX-1 || j <= 0 || j >= ncellsY-1 || k <= 0 || k >= ncellsZ-1)
576 marchedCubes[ind] = TRUE;
579 verts[0] = points[ind];
580 verts[1] = points[ind + YtimeZ];
581 verts[2] = prevVerts[1];
582 verts[3] = prevVerts[0];
583 verts[4] = points[ind + ncellsZ + 1];
584 verts[5] = points[ind + YtimeZ + ncellsZ + 1];
585 verts[6] = prevVerts[2];
586 verts[7] = prevVerts[3];
589 intVerts[2] = prevIntVerts[0]; intVerts[10] = prevIntVerts[1];
590 intVerts[6] = prevIntVerts[2]; intVerts[11] = prevIntVerts[3];
592 mp4Vector gradVerts[8];
593 gradVerts[3] = prevGradVerts[0]; gradVerts[2] = prevGradVerts[1];
594 gradVerts[6] = prevGradVerts[2]; gradVerts[7] = prevGradVerts[3];
597 grads[2] = prevGrads[0]; grads[10] = prevGrads[1]; grads[6] = prevGrads[2]; grads[11] = prevGrads[3];
599 int oldNumTriangles = numTriangles;
601 triangles = MarchOneCube(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, ind, i, j, k,
602 minValue, points, triangles, numTriangles, verts, intVerts, edgeIndex,
603 gradVerts, grads, gradIndex);
605 if(numTriangles == oldNumTriangles)
608 int passEdgeIndex, passGradIndex;
619 TRIANGLE* MCFace1(
int ncellsX,
int ncellsY,
int ncellsZ,
620 float gradFactorX,
float gradFactorY,
float gradFactorZ,
621 int ind,
int i,
int j,
int k,
622 float minValue, mp4Vector * points,
TRIANGLE *triangles,
int &numTriangles,
623 mp4Vector prevVerts[4],
mpVector prevIntVerts[4],
int edgeIndex,
624 mp4Vector prevGradVerts[4],
mpVector prevGrads[4],
int gradIndex,
bool* marchedCubes)
627 if(i <= 0 || i >= ncellsX-1 || j <= 0 || j >= ncellsY-1 || k <= 0 || k >= ncellsZ-1)
630 marchedCubes[ind] = TRUE;
633 verts[0] = prevVerts[1];
634 verts[1] = points[ind + YtimeZ];
635 verts[2] = points[ind + YtimeZ + 1];
636 verts[3] = prevVerts[0];
637 verts[4] = prevVerts[2];
638 verts[5] = points[ind + YtimeZ + ncellsZ + 1];
639 verts[6] = points[ind + YtimeZ + ncellsZ + 2];
640 verts[7] = prevVerts[3];
643 intVerts[3] = prevIntVerts[0]; intVerts[8] = prevIntVerts[1];
644 intVerts[7] = prevIntVerts[2]; intVerts[11] = prevIntVerts[3];
646 mp4Vector gradVerts[8];
647 gradVerts[3] = prevGradVerts[0]; gradVerts[0] = prevGradVerts[1];
648 gradVerts[4] = prevGradVerts[2]; gradVerts[7] = prevGradVerts[3];
651 grads[3] = prevGrads[0]; grads[8] = prevGrads[1]; grads[7] = prevGrads[2]; grads[11] = prevGrads[3];
653 int oldNumTriangles = numTriangles;
655 triangles = MarchOneCube(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, ind, i, j, k,
656 minValue, points, triangles, numTriangles, verts, intVerts, edgeIndex,
657 gradVerts, grads, gradIndex);
659 if(numTriangles == oldNumTriangles)
662 int passEdgeIndex, passGradIndex;
673 TRIANGLE* MCFace2(
int ncellsX,
int ncellsY,
int ncellsZ,
674 float gradFactorX,
float gradFactorY,
float gradFactorZ,
675 int ind,
int i,
int j,
int k,
676 float minValue, mp4Vector * points,
TRIANGLE *triangles,
int &numTriangles,
677 mp4Vector prevVerts[4],
mpVector prevIntVerts[4],
int edgeIndex,
678 mp4Vector prevGradVerts[4],
mpVector prevGrads[4],
int gradIndex,
bool* marchedCubes)
681 if(i <= 0 || i >= ncellsX-1 || j <= 0 || j >= ncellsY-1 || k <= 0 || k >= ncellsZ-1)
684 marchedCubes[ind] = TRUE;
687 verts[0] = prevVerts[0];
688 verts[1] = prevVerts[1];
689 verts[2] = points[ind + YtimeZ + 1];
690 verts[3] = points[ind + 1];
691 verts[4] = prevVerts[3];
692 verts[5] = prevVerts[2];
693 verts[6] = points[ind + YtimeZ + ncellsZ + 2];
694 verts[7] = points[ind + ncellsZ + 2];
697 intVerts[0] = prevIntVerts[0]; intVerts[9] = prevIntVerts[1];
698 intVerts[4] = prevIntVerts[2]; intVerts[8] = prevIntVerts[3];
700 mp4Vector gradVerts[8];
701 gradVerts[0] = prevGradVerts[0]; gradVerts[1] = prevGradVerts[1];
702 gradVerts[5] = prevGradVerts[2]; gradVerts[4] = prevGradVerts[3];
705 grads[0] = prevGrads[0]; grads[9] = prevGrads[1]; grads[4] = prevGrads[2]; grads[8] = prevGrads[3];
707 int oldNumTriangles = numTriangles;
709 triangles = MarchOneCube(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, ind, i, j, k,
710 minValue, points, triangles, numTriangles, verts, intVerts, edgeIndex,
711 gradVerts, grads, gradIndex);
713 if(numTriangles == oldNumTriangles)
716 int passEdgeIndex, passGradIndex;
727 TRIANGLE* MCFace3(
int ncellsX,
int ncellsY,
int ncellsZ,
728 float gradFactorX,
float gradFactorY,
float gradFactorZ,
729 int ind,
int i,
int j,
int k,
730 float minValue, mp4Vector * points,
TRIANGLE *triangles,
int &numTriangles,
731 mp4Vector prevVerts[4],
mpVector prevIntVerts[4],
int edgeIndex,
732 mp4Vector prevGradVerts[4],
mpVector prevGrads[4],
int gradIndex,
bool* marchedCubes)
735 if(i <= 0 || i >= ncellsX-1 || j <= 0 || j >= ncellsY-1 || k <= 0 || k >= ncellsZ-1)
738 marchedCubes[ind] = TRUE;
741 verts[0] = points[ind];
742 verts[1] = prevVerts[1];
743 verts[2] = prevVerts[0];
744 verts[3] = points[ind + 1];
745 verts[4] = points[ind + ncellsZ + 1];
746 verts[5] = prevVerts[2];
747 verts[6] = prevVerts[3];
748 verts[7] = points[ind + ncellsZ + 2];
751 intVerts[1] = prevIntVerts[0]; intVerts[9] = prevIntVerts[1];
752 intVerts[5] = prevIntVerts[2]; intVerts[10] = prevIntVerts[3];
754 mp4Vector gradVerts[8];
755 gradVerts[2] = prevGradVerts[0]; gradVerts[1] = prevGradVerts[1];
756 gradVerts[5] = prevGradVerts[2]; gradVerts[6] = prevGradVerts[3];
759 grads[1] = prevGrads[0]; grads[9] = prevGrads[1]; grads[5] = prevGrads[2]; grads[10] = prevGrads[3];
761 int oldNumTriangles = numTriangles;
763 triangles = MarchOneCube(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, ind, i, j, k,
764 minValue, points, triangles, numTriangles, verts, intVerts, edgeIndex,
765 gradVerts, grads, gradIndex);
767 if(numTriangles == oldNumTriangles)
770 int passEdgeIndex, passGradIndex;
781 TRIANGLE* MCFace4(
int ncellsX,
int ncellsY,
int ncellsZ,
782 float gradFactorX,
float gradFactorY,
float gradFactorZ,
783 int ind,
int i,
int j,
int k,
784 float minValue, mp4Vector * points,
TRIANGLE *triangles,
int &numTriangles,
785 mp4Vector prevVerts[4],
mpVector prevIntVerts[4],
int edgeIndex,
786 mp4Vector prevGradVerts[4],
mpVector prevGrads[4],
int gradIndex,
bool* marchedCubes)
789 if(i <= 0 || i >= ncellsX-1 || j <= 0 || j >= ncellsY-1 || k <= 0 || k >= ncellsZ-1)
792 marchedCubes[ind] = TRUE;
795 verts[0] = prevVerts[3];
796 verts[1] = prevVerts[2];
797 verts[2] = prevVerts[1];
798 verts[3] = prevVerts[0];
799 verts[4] = points[ind + ncellsZ + 1];
800 verts[5] = points[ind + YtimeZ + ncellsZ + 1];
801 verts[6] = points[ind + YtimeZ + ncellsZ + 2];
802 verts[7] = points[ind + ncellsZ + 2];
805 intVerts[2] = prevIntVerts[0]; intVerts[1] = prevIntVerts[1];
806 intVerts[0] = prevIntVerts[2]; intVerts[3] = prevIntVerts[3];
808 mp4Vector gradVerts[8];
809 gradVerts[3] = prevGradVerts[0]; gradVerts[2] = prevGradVerts[1];
810 gradVerts[1] = prevGradVerts[2]; gradVerts[0] = prevGradVerts[3];
813 grads[2] = prevGrads[0]; grads[1] = prevGrads[1]; grads[0] = prevGrads[2]; grads[3] = prevGrads[3];
815 int oldNumTriangles = numTriangles;
817 triangles = MarchOneCube(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, ind, i, j, k,
818 minValue, points, triangles, numTriangles, verts, intVerts, edgeIndex,
819 gradVerts, grads, gradIndex);
821 if(numTriangles == oldNumTriangles)
824 int passEdgeIndex, passGradIndex;
835 TRIANGLE* MCFace5(
int ncellsX,
int ncellsY,
int ncellsZ,
836 float gradFactorX,
float gradFactorY,
float gradFactorZ,
837 int ind,
int i,
int j,
int k,
838 float minValue, mp4Vector * points,
TRIANGLE *triangles,
int &numTriangles,
839 mp4Vector prevVerts[4],
mpVector prevIntVerts[4],
int edgeIndex,
840 mp4Vector prevGradVerts[4],
mpVector prevGrads[4],
int gradIndex,
bool* marchedCubes)
843 if(i <= 0 || i >= ncellsX-1 || j <= 0 || j >= ncellsY-1 || k <= 0 || k >= ncellsZ-1)
846 marchedCubes[ind] = TRUE;
849 verts[0] = points[ind];
850 verts[1] = points[ind + YtimeZ];
851 verts[2] = points[ind + YtimeZ + 1];
852 verts[3] = points[ind + 1];
853 verts[4] = prevVerts[3];
854 verts[5] = prevVerts[2];
855 verts[6] = prevVerts[1];
856 verts[7] = prevVerts[0];
859 intVerts[6] = prevIntVerts[0]; intVerts[5] = prevIntVerts[1];
860 intVerts[4] = prevIntVerts[2]; intVerts[7] = prevIntVerts[3];
862 mp4Vector gradVerts[8];
863 gradVerts[7] = prevGradVerts[0]; gradVerts[6] = prevGradVerts[1];
864 gradVerts[5] = prevGradVerts[2]; gradVerts[4] = prevGradVerts[3];
867 grads[6] = prevGrads[0]; grads[5] = prevGrads[1]; grads[4] = prevGrads[2]; grads[7] = prevGrads[3];
869 int oldNumTriangles = numTriangles;
871 triangles = MarchOneCube(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ, ind, i, j, k,
872 minValue, points, triangles, numTriangles, verts, intVerts, edgeIndex,
873 gradVerts, grads, gradIndex);
875 if(numTriangles == oldNumTriangles)
878 int passEdgeIndex, passGradIndex;
891 TRIANGLE* MarchOneCube(
int ncellsX,
int ncellsY,
int ncellsZ,
892 float gradFactorX,
float gradFactorY,
float gradFactorZ,
893 int ind,
int i,
int j,
int k,
894 float minValue, mp4Vector * points,
TRIANGLE *triangles,
int &numTriangles,
895 mp4Vector verts[8],
mpVector intVerts[12],
int &edgeIndex,
896 mp4Vector gradVerts[8],
mpVector grads[12],
int &indGrad)
899 mpVector factor(1.0/(2.0*gradFactorX), 1.0/(2.0*gradFactorY), 1.0/(2.0*gradFactorZ));
901 int cubeIndex = int(0);
902 for(
int n=0; n < 8; n++)
if(verts[n].val <= minValue) cubeIndex |= (1 << n);
904 if(!edgeTable[cubeIndex])
return triangles;
906 int prevEdgeIndex = edgeIndex;
907 edgeIndex = edgeTable[cubeIndex];
909 if((edgeIndex & 1) && !(prevEdgeIndex & 1)) {
910 intVerts[0] = LinearInterp(verts[0], verts[1], minValue);
911 if(! (indGrad & 1)) {
912 gradVerts[0] = CALC_GRAD_VERT_0(verts)
915 if(! (indGrad & 2)) {
916 gradVerts[1] = CALC_GRAD_VERT_1(verts)
919 grads[0] = LinearInterp(gradVerts[0], gradVerts[1], minValue);
920 grads[0].x *= factor.x; grads[0].y *= factor.y; grads[0].z *= factor.z;
922 if((edgeIndex & 2) && !(prevEdgeIndex & 2)) {
923 intVerts[1] = LinearInterp(verts[1], verts[2], minValue);
924 if(! (indGrad & 2)) {
925 gradVerts[1] = CALC_GRAD_VERT_1(verts)
928 if(! (indGrad & 4)) {
929 gradVerts[2] = CALC_GRAD_VERT_2(verts)
932 grads[1] = LinearInterp(gradVerts[1], gradVerts[2], minValue);
933 grads[1].x *= factor.x; grads[1].y *= factor.y; grads[1].z *= factor.z;
936 intVerts[2] = LinearInterp(verts[2], verts[3], minValue);
937 if(! (indGrad & 4)) {
938 gradVerts[2] = CALC_GRAD_VERT_2(verts)
941 if(! (indGrad & 8)) {
942 gradVerts[3] = CALC_GRAD_VERT_3(verts)
945 grads[2] = LinearInterp(gradVerts[2], gradVerts[3], minValue);
946 grads[2].x *= factor.x; grads[2].y *= factor.y; grads[2].z *= factor.z;
948 if((edgeIndex & 8) && !(prevEdgeIndex & 8)) {
949 intVerts[3] = LinearInterp(verts[3], verts[0], minValue);
950 if(! (indGrad & 8)) {
951 gradVerts[3] = CALC_GRAD_VERT_3(verts)
954 if(! (indGrad & 1)) {
955 gradVerts[0] = CALC_GRAD_VERT_0(verts)
958 grads[3] = LinearInterp(gradVerts[3], gradVerts[0], minValue);
959 grads[3].x *= factor.x; grads[3].y *= factor.y; grads[3].z *= factor.z;
961 if((edgeIndex & 16) && !(prevEdgeIndex & 16)) {
962 intVerts[4] = LinearInterp(verts[4], verts[5], minValue);
963 if(! (indGrad & 16)) {
964 gradVerts[4] = CALC_GRAD_VERT_4(verts)
967 if(! (indGrad & 32)) {
968 gradVerts[5] = CALC_GRAD_VERT_5(verts)
971 grads[4] = LinearInterp(gradVerts[4], gradVerts[5], minValue);
972 grads[4].x *= factor.x; grads[4].y *= factor.y; grads[4].z *= factor.z;
974 if((edgeIndex & 32) && !(prevEdgeIndex & 32)) {
975 intVerts[5] = LinearInterp(verts[5], verts[6], minValue);
976 if(! (indGrad & 32)) {
977 gradVerts[5] = CALC_GRAD_VERT_5(verts)
980 if(! (indGrad & 64)) {
981 gradVerts[6] = CALC_GRAD_VERT_6(verts)
984 grads[5] = LinearInterp(gradVerts[5], gradVerts[6], minValue);
985 grads[5].x *= factor.x; grads[5].y *= factor.y; grads[5].z *= factor.z;
987 if((edgeIndex & 64) && !(prevEdgeIndex & 64)) {
988 intVerts[6] = LinearInterp(verts[6], verts[7], minValue);
989 if(! (indGrad & 64)) {
990 gradVerts[6] = CALC_GRAD_VERT_6(verts)
993 if(! (indGrad & 128)) {
994 gradVerts[7] = CALC_GRAD_VERT_7(verts)
997 grads[6] = LinearInterp(gradVerts[6], gradVerts[7], minValue);
998 grads[6].x *= factor.x; grads[6].y *= factor.y; grads[6].z *= factor.z;
1000 if((edgeIndex & 128) && !(prevEdgeIndex & 128)) {
1001 intVerts[7] = LinearInterp(verts[7], verts[4], minValue);
1002 if(! (indGrad & 128)) {
1003 gradVerts[7] = CALC_GRAD_VERT_7(verts)
1006 if(! (indGrad & 16)) {
1007 gradVerts[4] = CALC_GRAD_VERT_4(verts)
1010 grads[7] = LinearInterp(gradVerts[7], gradVerts[4], minValue);
1011 grads[7].x *= factor.x; grads[7].y *= factor.y; grads[7].z *= factor.z;
1013 if((edgeIndex & 256) && !(prevEdgeIndex & 256)) {
1014 intVerts[8] = LinearInterp(verts[0], verts[4], minValue);
1015 if(! (indGrad & 1)) {
1016 gradVerts[0] = CALC_GRAD_VERT_0(verts)
1019 if(! (indGrad & 16)) {
1020 gradVerts[4] = CALC_GRAD_VERT_4(verts)
1023 grads[8] = LinearInterp(gradVerts[0], gradVerts[4], minValue);
1024 grads[8].x *= factor.x; grads[8].y *= factor.y; grads[8].z *= factor.z;
1026 if((edgeIndex & 512) && !(prevEdgeIndex & 512)) {
1027 intVerts[9] = LinearInterp(verts[1], verts[5], minValue);
1028 if(! (indGrad & 2)) {
1029 gradVerts[1] = CALC_GRAD_VERT_1(verts)
1032 if(! (indGrad & 32)) {
1033 gradVerts[5] = CALC_GRAD_VERT_5(verts)
1036 grads[9] = LinearInterp(gradVerts[1], gradVerts[5], minValue);
1037 grads[9].x *= factor.x; grads[9].y *= factor.y; grads[9].z *= factor.z;
1039 if((edgeIndex & 1024) && !(prevEdgeIndex & 1024)) {
1040 intVerts[10] = LinearInterp(verts[2], verts[6], minValue);
1041 if(! (indGrad & 4)) {
1042 gradVerts[2] = CALC_GRAD_VERT_2(verts)
1045 if(! (indGrad & 64)) {
1046 gradVerts[6] = CALC_GRAD_VERT_6(verts)
1049 grads[10] = LinearInterp(gradVerts[2], gradVerts[6], minValue);
1050 grads[10].x *= factor.x; grads[10].y *= factor.y; grads[10].z *= factor.z;
1052 if((edgeIndex & 2048) && !(prevEdgeIndex & 2048)) {
1053 intVerts[11] = LinearInterp(verts[3], verts[7], minValue);
1054 if(! (indGrad & 8)) {
1055 gradVerts[3] = CALC_GRAD_VERT_3(verts)
1058 if(! (indGrad & 128)) {
1059 gradVerts[7] = CALC_GRAD_VERT_7(verts)
1062 grads[11] = LinearInterp(gradVerts[3], gradVerts[7], minValue);
1063 grads[11].x *= factor.x; grads[11].y *= factor.y; grads[11].z *= factor.z;
1066 for (
int n=0; triTable[cubeIndex][n] != -1; n+=3) {
1067 int index[3] = {triTable[cubeIndex][n+2], triTable[cubeIndex][n+1], triTable[cubeIndex][n]};
1068 for(
int h=0; h < 3; h++) {
1069 triangles[numTriangles].p[h] = intVerts[index[h]];
1070 triangles[numTriangles].norm[h] = grads[index[h]];
1080 float* MCFind(
int ncellsX,
int ncellsY,
int ncellsZ,
float minValue, mp4Vector * points)
1082 pointsZ = ncellsZ+1;
1083 YtimeZ = (ncellsY+1)*pointsZ;
1084 int lastX = ncellsX - 1, lastY = ncellsY - 1, lastZ = ncellsZ - 1;
1085 mp4Vector *verts[8];
1086 int cubeIndex, ind, ni;
1087 float *found =
new float[3];
1088 found[0] = -1; found[0] = -1; found[0] = -1;
1090 for(
int i=1; i < lastX; i++) {
1092 for(
int j=1; j < lastY; j++) {
1094 ind = ni + j*pointsZ + 1;
1095 verts[3] = &points[ind];
1096 verts[2] = &points[ind + YtimeZ];
1097 verts[7] = &points[ind + pointsZ];
1098 verts[6] = &points[ind + YtimeZ + pointsZ];
1099 for(
int k=1; k < lastZ; k++, ind++) {
1101 verts[0] = verts[3];
1102 verts[1] = verts[2];
1103 verts[4] = verts[7];
1104 verts[5] = verts[6];
1105 verts[4] = &points[ind + pointsZ];
1106 verts[5] = &points[ind + YtimeZ + pointsZ];
1107 verts[6] = &points[ind + YtimeZ + ncellsZ + 2];
1108 verts[7] = &points[ind + ncellsZ + 2];
1111 for(
int n=0; n < 8; n++)
if(verts[n]->val <= minValue) cubeIndex |= (1 << n);
1112 if(edgeTable[cubeIndex]) {
1113 found[0] = i; found[1] = j; found[2] = k;
1123 TRIANGLE* MCRecFind(
int ncellsX,
int ncellsY,
int ncellsZ,
1124 float gradFactorX,
float gradFactorY,
float gradFactorZ,
1125 float minValue, mp4Vector * points,
int &numTriangles)
1127 float *found = MCFind(ncellsX, ncellsY, ncellsZ, minValue, points);
1128 if(found[0] == -1) {
1132 int i[1] = {(int)found[0]}, j[1] = {(int)found[1]}, k[1] = {(int)found[2]};
1134 return MarchingCubesRec(ncellsX, ncellsY, ncellsZ, gradFactorX, gradFactorY, gradFactorZ,
1135 1, i, j, k, minValue, points, numTriangles);