};
/** march iterates over the entire dataset, calling vMarchCube on each cube */
- public static void march(SampledField sampledField, double threshold, int iDataSetSize, double fStepSize, Mesh mesh) {
- int iX, iY, iZ;
+ public static void march(VoxelData voxels, Mesh mesh) { march(voxels, 0, mesh); }
+ public static void march(VoxelData voxels, double threshold, Mesh mesh) {
int initialTriangles = mesh.numTriangles();
- for(iX = 0; iX < iDataSetSize; iX++) {
+ double scaleX = (voxels.getMaxX() - voxels.getMinX()) / (double)voxels.getNumSamplesX();
+ double scaleY = (voxels.getMaxY() - voxels.getMinY()) / (double)voxels.getNumSamplesY();
+ double scaleZ = (voxels.getMaxZ() - voxels.getMinZ()) / (double)voxels.getNumSamplesZ();
+ for(int iX = 0; iX < voxels.getNumSamplesX(); iX++) {
System.out.print("\r");
for(int i=0; i<78; i++) System.out.print(' ');
System.out.print("\r");
- System.out.print(Math.ceil((iX/((double)iDataSetSize))*100) + "% marched, " +
+ System.out.print(Math.ceil((iX/((double)voxels.getNumSamplesX()))*100) + "% marched, " +
(mesh.numTriangles()-initialTriangles) + " triangles");
- for(iY = 0; iY < iDataSetSize; iY++)
- for(iZ = 0; iZ < iDataSetSize; iZ++)
- march(sampledField, mesh, threshold, iX*fStepSize, iY*fStepSize, iZ*fStepSize, fStepSize);
+ for(int iY = 0; iY < voxels.getNumSamplesY(); iY++)
+ for(int iZ = 0; iZ < voxels.getNumSamplesZ(); iZ++)
+ march(voxels, mesh, threshold,
+ iX*scaleX + voxels.getMinX(),
+ iY*scaleY + voxels.getMinY(),
+ iZ*scaleZ + voxels.getMinZ(),
+ scaleX, scaleY, scaleZ);
}
System.out.print("\r");
for(int i=0; i<78; i++) System.out.print(' ');
}
/** performs the Marching Cubes algorithm on a single cube */
- static void march(SampledField sampledField, Mesh mesh, double threshold, double fX, double fY, double fZ, double fScale) {
+ static void march(VoxelData voxels, Mesh mesh, double threshold,
+ double fX, double fY, double fZ,
+ double scaleX, double scaleY, double scaleZ) {
int iCorner, iVertex, iVertexTest, iEdge, iTriangle, iFlagIndex, iEdgeFlags;
double fOffset;
GLvector sColor;
// Make a local copy of the values at the cube's corners
for(iVertex = 0; iVertex < 8; iVertex++)
- afCubeValue[iVertex] = sampledField.getSample(new Point(fX + a2fVertexOffset[iVertex][0]*fScale,
- fY + a2fVertexOffset[iVertex][1]*fScale,
- fZ + a2fVertexOffset[iVertex][2]*fScale));
+ afCubeValue[iVertex] = voxels.getSample(new Point(fX + a2fVertexOffset[iVertex][0]*scaleX,
+ fY + a2fVertexOffset[iVertex][1]*scaleY,
+ fZ + a2fVertexOffset[iVertex][2]*scaleZ));
// Find which vertices are inside of the surface and which are outside
iFlagIndex = 0;
fOffset = fGetOffset(afCubeValue[ a2iEdgeConnection[iEdge][0] ],
afCubeValue[ a2iEdgeConnection[iEdge][1] ],
threshold,
- fScale * 0.1);
+ Math.min(Math.min(scaleX, scaleY), scaleZ) * 0.1);
- asEdgeVertex[iEdge].fX = fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0] + fOffset * a2fEdgeDirection[iEdge][0]) * fScale;
- asEdgeVertex[iEdge].fY = fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1] + fOffset * a2fEdgeDirection[iEdge][1]) * fScale;
- asEdgeVertex[iEdge].fZ = fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2] + fOffset * a2fEdgeDirection[iEdge][2]) * fScale;
+ asEdgeVertex[iEdge].fX = fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0] + fOffset * a2fEdgeDirection[iEdge][0]) * scaleX;
+ asEdgeVertex[iEdge].fY = fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1] + fOffset * a2fEdgeDirection[iEdge][1]) * scaleY;
+ asEdgeVertex[iEdge].fZ = fZ + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][2] + fOffset * a2fEdgeDirection[iEdge][2]) * scaleZ;
- vGetNormal(sampledField, asEdgeNorm[iEdge], asEdgeVertex[iEdge].fX, asEdgeVertex[iEdge].fY, asEdgeVertex[iEdge].fZ);
+ vGetNormal(voxels, asEdgeNorm[iEdge], asEdgeVertex[iEdge].fX, asEdgeVertex[iEdge].fY, asEdgeVertex[iEdge].fZ);
}
// Draw the triangles that were found. There can be up to five per cube
* This gradient can be used as a very accurate vertx normal for
* lighting calculations
*/
- static void vGetNormal(SampledField sampledField, GLvector rfNormal, double fX, double fY, double fZ) {
+ static void vGetNormal(VoxelData voxels, GLvector rfNormal, double fX, double fY, double fZ) {
rfNormal.fX =
- sampledField.getSample(new Point(fX-0.01, fY, fZ)) -
- sampledField.getSample(new Point(fX+0.01, fY, fZ));
+ voxels.getSample(new Point(fX-0.01, fY, fZ)) -
+ voxels.getSample(new Point(fX+0.01, fY, fZ));
rfNormal.fY =
- sampledField.getSample(new Point(fX, fY-0.01, fZ)) -
- sampledField.getSample(new Point(fX, fY+0.01, fZ));
+ voxels.getSample(new Point(fX, fY-0.01, fZ)) -
+ voxels.getSample(new Point(fX, fY+0.01, fZ));
rfNormal.fZ =
- sampledField.getSample(new Point(fX, fY, fZ-0.01)) -
- sampledField.getSample(new Point(fX, fY, fZ+0.01));
+ voxels.getSample(new Point(fX, fY, fZ-0.01)) -
+ voxels.getSample(new Point(fX, fY, fZ+0.01));
vNormalizeVector(rfNormal, rfNormal);
}