public int getSurfacePointIndexAndFraction( float cutoff, boolean isCutoffAbsolute, int x, int y, int z, Point3i offset, int vA, int vB, float valueA, float valueB, Point3f pointA, Vector3f edgeVector, boolean isContourType, float[] fReturn) { float thisValue = getSurfacePointAndFraction( cutoff, isCutoffAbsolute, valueA, valueB, pointA, edgeVector, x, y, z, vA, vB, fReturn, ptTemp); /* * from MarchingCubes * * In the case of a setup for a Marching Squares calculation, * we are collecting just the desired type of intersection for the 2D marching * square contouring -- x, y, or z. In the case of a contoured f(x,y) surface, * we take every point. * */ if (marchingSquares != null && params.isContoured) return marchingSquares.addContourVertex(ptTemp, cutoff); int assocVertex = (assocCutoff > 0 ? (fReturn[0] < assocCutoff ? vA : fReturn[0] > 1 - assocCutoff ? vB : MarchingSquares.CONTOUR_POINT) : MarchingSquares.CONTOUR_POINT); if (assocVertex >= 0) assocVertex = marchingCubes.getLinearOffset(x, y, z, assocVertex); int n = addVertexCopy(ptTemp, thisValue, assocVertex); if (n >= 0 && params.iAddGridPoints) { marchingCubes.calcVertexPoint(x, y, z, vB, ptTemp); addVertexCopy(valueA < valueB ? pointA : ptTemp, Float.NaN, MarchingSquares.EDGE_POINT); addVertexCopy(valueA < valueB ? ptTemp : pointA, Float.NaN, MarchingSquares.EDGE_POINT); } return n; }
private void generateSurfaceData() { edgeData = ""; if (vertexDataOnly) { try { readSurfaceData(false); } catch (Exception e) { e.printStackTrace(); Logger.error("Exception in SurfaceReader::readSurfaceData: " + e.getMessage()); } return; } contourVertexCount = 0; int contourType = -1; marchingSquares = null; if (params.thePlane != null || params.isContoured) { marchingSquares = new MarchingSquares( this, volumeData, params.thePlane, params.contoursDiscrete, params.nContours, params.thisContour, params.contourFromZero); contourType = marchingSquares.getContourType(); marchingSquares.setMinMax(params.valueMappedToRed, params.valueMappedToBlue); } params.contourType = contourType; params.isXLowToHigh = isXLowToHigh; marchingCubes = new MarchingCubes(this, volumeData, params, jvxlVoxelBitSet); String data = marchingCubes.getEdgeData(); if (params.thePlane == null) edgeData = data; jvxlData.setSurfaceInfoFromBitSet(marchingCubes.getBsVoxels(), params.thePlane); jvxlData.jvxlExcluded = params.bsExcluded; if (isJvxl) edgeData = jvxlEdgeDataRead; postProcessVertices(); }
public static void marchingCubesDemo() throws MeshNotOrientedException, DanglingTriangleException, IOException { PointCloud pc = ObjReader.readAsPointCloud("objs/dragon_withNormals.obj", true); // PointCloud pc = PlyReader.readPointCloud("objs/angel_points.ply", true); pc.normalizeNormals(); HashOctree tree = new HashOctree(pc, 9, 1, 1.3f); tree.refineTree(2); LinearSystem system = SSDMatrices.ssdSystem(tree, pc, 1, 0.001f, 10); // Test Data: create an octree ArrayList<Float> functionByVertex = new ArrayList<Float>(); SCIPY.solve(system, "whatev", functionByVertex); // System.out.println(functionByVertex); MarchingCubes mc = new MarchingCubes(tree); mc.dualMC(functionByVertex); WireframeMesh mesh = mc.result; GLWireframeMesh glMesh = new GLWireframeMesh(mesh); // And show off... // visualization of the per vertex values (blue = negative, // red = positive, green = 0); MyDisplay d = new MyDisplay(); glMesh.configurePreferredShader( "shaders/trimesh_flat.vert", "shaders/trimesh_flat.frag", "shaders/trimesh_flat.geom"); d.addToDisplay(glMesh); // discrete approximation of the zero level set: render all // tree cubes that have negative values. GLHashtree gltree = new GLHashtree(tree); gltree.addFunctionValues(functionByVertex); gltree.configurePreferredShader( "shaders/octree_zro.vert", "shaders/octree_zro.frag", "shaders/octree_zro.geom"); d.addToDisplay(gltree); }