private double interpolate_value( final StructuredVolumeObject volume, final Vector3f vertex0, final Vector3f vertex1) throws KVSException { Buffer buf = volume.values(); final int line_size = volume.nnodesPerLine(); final int slice_size = volume.nnodesPerSlice(); final float value0 = this.substitute_plane_equation(vertex0); final float value1 = this.substitute_plane_equation(vertex1); final float ratio = kvs.core.util.Math.abs(value0 / (value1 - value0)); final int index0 = (int) (vertex0.getX() + vertex0.getY() * line_size + vertex0.getZ() * slice_size); final int index1 = (int) (vertex1.getX() + vertex1.getY() * line_size + vertex1.getZ() * slice_size); if (buf instanceof ByteBuffer) { ByteBuffer values = (ByteBuffer) buf; return (values.get(index0) + ratio * (values.get(index1) - values.get(index0))); } else if (buf instanceof ShortBuffer) { ShortBuffer values = (ShortBuffer) buf; return (values.get(index0) + ratio * (values.get(index1) - values.get(index0))); } else if (buf instanceof IntBuffer) { IntBuffer values = (IntBuffer) buf; return (values.get(index0) + ratio * (values.get(index1) - values.get(index0))); } else if (buf instanceof LongBuffer) { LongBuffer values = (LongBuffer) buf; return (values.get(index0) + ratio * (values.get(index1) - values.get(index0))); } else if (buf instanceof FloatBuffer) { FloatBuffer values = (FloatBuffer) buf; return (values.get(index0) + ratio * (values.get(index1) - values.get(index0))); } else if (buf instanceof DoubleBuffer) { DoubleBuffer values = (DoubleBuffer) buf; return (values.get(index0) + ratio * (values.get(index1) - values.get(index0))); } else if (buf instanceof CharBuffer) { CharBuffer values = (CharBuffer) buf; return (values.get(index0) + ratio * (values.get(index1) - values.get(index0))); } else { throw new KVSException("Unsupported data type"); } }
private void extract_plane(final StructuredVolumeObject volume) throws KVSException { // Calculated the coordinate data array and the normal vector array. ArrayList<Float> coords = new ArrayList<Float>(); ArrayList<Float> normals = new ArrayList<Float>(); ArrayList<Integer> colors = new ArrayList<Integer>(); // Calculate min/max values of the node data. if (!volume.hasMinMaxValues()) { volume.updateMinMaxValues(); } // Calculate a normalize_factor. double min_value = volume.minValue(); double max_value = volume.maxValue(); double normalize_factor = 255.0 / (max_value - min_value); Vector3i ncells = volume.resolution().sub(new Vector3i(1)); int line_size = volume.nnodesPerLine(); ColorMap color_map = transferFunction().colorMap(); // Extract surfaces. int index = 0; for (int z = 0; z < ncells.getZ(); ++z) { for (int y = 0; y < ncells.getY(); ++y) { for (int x = 0; x < ncells.getX(); ++x) { // Calculate the index of the reference table. int table_index = this.calculate_table_index(x, y, z); if (table_index == 0) { continue; } if (table_index == 255) { continue; } // Calculate the triangle polygons. for (int i = 0; MarchingCubesTable.TriangleID[table_index][i] != -1; i += 3) { // Refer the edge IDs from the TriangleTable by using the table_index. int e0 = MarchingCubesTable.TriangleID[table_index][i]; int e1 = MarchingCubesTable.TriangleID[table_index][i + 2]; int e2 = MarchingCubesTable.TriangleID[table_index][i + 1]; // Determine vertices for each edge. Vector3f v0 = new Vector3f( x + MarchingCubesTable.VertexID[e0][0][0], y + MarchingCubesTable.VertexID[e0][0][1], z + MarchingCubesTable.VertexID[e0][0][2]); Vector3f v1 = new Vector3f( x + MarchingCubesTable.VertexID[e0][1][0], y + MarchingCubesTable.VertexID[e0][1][1], z + MarchingCubesTable.VertexID[e0][1][2]); Vector3f v2 = new Vector3f( x + MarchingCubesTable.VertexID[e1][0][0], y + MarchingCubesTable.VertexID[e1][0][1], z + MarchingCubesTable.VertexID[e1][0][2]); Vector3f v3 = new Vector3f( x + MarchingCubesTable.VertexID[e1][1][0], y + MarchingCubesTable.VertexID[e1][1][1], z + MarchingCubesTable.VertexID[e1][1][2]); Vector3f v4 = new Vector3f( x + MarchingCubesTable.VertexID[e2][0][0], y + MarchingCubesTable.VertexID[e2][0][1], z + MarchingCubesTable.VertexID[e2][0][2]); Vector3f v5 = new Vector3f( x + MarchingCubesTable.VertexID[e2][1][0], y + MarchingCubesTable.VertexID[e2][1][1], z + MarchingCubesTable.VertexID[e2][1][2]); // Calculate coordinates of the vertices which are composed // of the triangle polygon. Vector3f vertex0 = this.interpolate_vertex(v0, v1); coords.add(vertex0.getX()); coords.add(vertex0.getY()); coords.add(vertex0.getZ()); final Vector3f vertex1 = this.interpolate_vertex(v2, v3); coords.add(vertex1.getX()); coords.add(vertex1.getY()); coords.add(vertex1.getZ()); final Vector3f vertex2 = this.interpolate_vertex(v4, v5); coords.add(vertex2.getX()); coords.add(vertex2.getY()); coords.add(vertex2.getZ()); final double value0 = this.interpolate_value(volume, v0, v1); final double value1 = this.interpolate_value(volume, v2, v3); final double value2 = this.interpolate_value(volume, v4, v5); final int color0 = (int) (normalize_factor * (value0 - min_value)); colors.add(color_map.getAt(color0).getRed()); colors.add(color_map.getAt(color0).getGreen()); colors.add(color_map.getAt(color0).getBlue()); final int color1 = (int) (normalize_factor * (value1 - min_value)); colors.add(color_map.getAt(color1).getRed()); colors.add(color_map.getAt(color1).getGreen()); colors.add(color_map.getAt(color1).getBlue()); final int color2 = (int) (normalize_factor * (value2 - min_value)); colors.add(color_map.getAt(color2).getRed()); colors.add(color_map.getAt(color2).getGreen()); colors.add(color_map.getAt(color2).getBlue()); // Calculate a normal vector for the triangle polygon. final Vector3f normal = (vertex2.sub(vertex0)).cross(vertex1.sub(vertex0)); normals.add(normal.getX()); normals.add(normal.getY()); normals.add(normal.getZ()); } // end of loop-triangle } // end of loop-x ++index; } // end of loop-y index += line_size; } // end of loop-z m_object.setCoords(Utility.ListToFloatArray(coords)); m_object.setColors(Utility.ListToIntArray(colors)); m_object.setNormals(Utility.ListToFloatArray(normals)); m_object.setOpacity((byte) 255); m_object.setPolygonType(PolygonObject.PolygonType.Triangle); m_object.setColorType(PolygonObject.ColorType.VertexColor); m_object.setNormalType(PolygonObject.NormalType.PolygonNormal); }