X-Git-Url: http://git.megacz.com/?p=anneal.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fqfat%2Fvoxel%2FMarchingCubes.java;h=46b83b6c0b80570b9b5896dc0d51a67089c7de76;hp=a36558524493a4b00eb6249b76b0a4c607ce8dbc;hb=daed1206997768114d9a7ab5d8603e206c0b4a52;hpb=12b9790a8286085423bb649e7632644f31142d24 diff --git a/src/edu/berkeley/qfat/voxel/MarchingCubes.java b/src/edu/berkeley/qfat/voxel/MarchingCubes.java index a365585..46b83b6 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++) + /*marchCubes*/marchTetrahedrons(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 marchCubes(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,15 +101,17 @@ 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); } + System.out.println(); + // Draw the triangles that were found. There can be up to five per cube for(iTriangle = 0; iTriangle < 5; iTriangle++) { if(a2iTriangleConnectionTable[iFlagIndex][3*iTriangle] < 0) @@ -123,7 +134,124 @@ public class MarchingCubes { points[1].equals(points[2])) continue; - mesh.newT(points[0], points[1], points[2], norm.norm().times(-1)); + System.out.println("creating triangle: " + points[0] + " " + points[1] + " " + points[2]); + try { + Mesh.T t = mesh.newT(points[0], points[1], points[2], norm.norm().times(-1)); + System.out.println(" created " + t); + } catch (Throwable t) { } + } + } + + /** + * marchTetrahedron performs the Marching Tetrahedrons algorithm + * on a single tetrahedron + */ + static void marchTetrahedron(VoxelData voxels, Mesh mesh, double threshold, + GLvector[] pasTetrahedronPosition, + float[] pafTetrahedronValue, + double scaleX, double scaleY, double scaleZ) { + + int iEdge, iVert0, iVert1, iEdgeFlags, iTriangle, iCorner, iVertex, iFlagIndex = 0; + double fOffset, fInvOffset, fValue = 0.0; + GLvector[] asEdgeVertex = new GLvector[6]; + GLvector[] asEdgeNorm = new GLvector[6]; + GLvector sColor = new GLvector(); + for(int i=0; i