From: megacz Date: Sun, 1 Mar 2009 03:55:08 +0000 (-0800) Subject: change MarchingCubes.march() to take a VoxelData rather than a SampledField X-Git-Url: http://git.megacz.com/?p=anneal.git;a=commitdiff_plain;h=76e9f9a721c31fc8c2ed671ebda1640534ac2f1b change MarchingCubes.march() to take a VoxelData rather than a SampledField --- diff --git a/src/edu/berkeley/qfat/Main.java b/src/edu/berkeley/qfat/Main.java index f5a1344..56eeb83 100644 --- a/src/edu/berkeley/qfat/Main.java +++ b/src/edu/berkeley/qfat/Main.java @@ -295,18 +295,25 @@ public class Main extends InteractiveMeshViewer { public void marchingCubes() { Mesh mesh = new Mesh(false); mesh.coalesce = true; - MarchingCubes.march(new SampledField() { - public float getSample(Point p) { - double x = p.x; - double y = p.y; - double z = p.z; - x-=1.1; - y-=1.1; - z-=1.1; - return (float)(0.8-Math.sqrt(x*x+y*y+z*z)); - } - }, - 0, 30, 0.1, mesh); + MarchingCubes.march(new VoxelData() { + float radius = 1.0f; + public float getMaxX() { return 1.0f; } + public float getMinX() { return -1.0f; } + public int getNumSamplesX() { return 10; } + public float getMaxY() { return 1.0f; } + public float getMinY() { return -1.0f; } + public int getNumSamplesY() { return 10; } + public float getMaxZ() { return 1.0f; } + public float getMinZ() { return -1.0f; } + public int getNumSamplesZ() { return 10; } + public float getSample(Point p) { + double x = p.x; + double y = p.y; + double z = p.z; + return (float)(radius-Math.sqrt(x*x+y*y+z*z)); + } + }, + mesh); setTile(mesh); //fixupTile(); } diff --git a/src/edu/berkeley/qfat/voxel/MarchingCubes.java b/src/edu/berkeley/qfat/voxel/MarchingCubes.java index a365585..3112d8d 100644 --- a/src/edu/berkeley/qfat/voxel/MarchingCubes.java +++ b/src/edu/berkeley/qfat/voxel/MarchingCubes.java @@ -35,18 +35,25 @@ public class MarchingCubes { }; /** 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(' '); @@ -55,7 +62,9 @@ public class MarchingCubes { } /** 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; @@ -68,9 +77,9 @@ public class MarchingCubes { // 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; @@ -92,13 +101,13 @@ public class MarchingCubes { 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 @@ -132,16 +141,16 @@ public class MarchingCubes { * 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); }