Revision: 5159 Author: hansonr Date: 2006-05-22 14:30:32 -0700 (Mon, 22 May 2006) ViewCVS: http://svn.sourceforge.net/jmol/?rev=5159&view=rev
Log Message: ----------- bob200603 10.x_05 implements Jmol Voxel Format (JVXL) file reading for highly compressed CUBE file-based orbitals and surfaces. See http://www.stolaf.edu/people/hansonr/jmol/test/proto/new.htm http://www.stolaf.edu/people/hansonr/jmol/test/proto/ch3cl.jvxl Modified Paths: -------------- branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java branches/bob200603/Jmol/src/org/jmol/viewer/JmolConstants.java Modified: branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java =================================================================== --- branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java 2006-05-22 18:01:11 UTC (rev 5158) +++ branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java 2006-05-22 21:30:32 UTC (rev 5159) @@ -42,6 +42,36 @@ * Dec 1 1987 + 17 yrs = Dec 1 2004 */ +/* + * Bob Hanson May 22, 2006 + * + * inventing "Jmol Voxel File" format, *.jvxl + * + * lines through through coordinates are identical to CUBE files + * after that, we have: + * + * line1: (int)-nSurfaces (int)edgeFractionBase (int)edgeFractionRange + * (nSurface lines): (float)cutoff (int)nBytesData (int)nBytesFractions + * data1 + * fractions1 + * data2 + * fractions2 + * .... + * + * data: a list of the count of vertices ouside and inside the cutoff, whatever + * that may be, ordered by nested for loops for(x){for(y){for(z)}}}. + * + * nOutside nInside nOutside nInside... + * + * fractions: an ascii list of characters represting the fraction of distance each + * encountered surface point is along each voxel cube edge found to straddle the + * surface. The order written is dictated by the reader algorithm and is not trivial + * to describe. Each ascii character is constructed by taking a base character and + * adding onto it the fraction times a range. This gives a character that can be + * quoted EXCEPT for backslash, which MAY be substituted for by '!'. + * + */ + package org.jmol.viewer; import org.jmol.g3d.*; @@ -55,7 +85,11 @@ class Isosurface extends MeshCollection { + final static boolean logMessages = false; + final float ANGSTROMS_PER_BOHR = JmolConstants.ANGSTROMS_PER_BOHR; + final static char defaultEdgeFractionBase = 35; //#$%....... + final static float defaultEdgeFractionRange = 90f; final Point3f volumetricOrigin = new Point3f(); final Vector3f[] volumetricVectors = new Vector3f[3]; @@ -81,6 +115,7 @@ float cutoff = 0.02f; boolean rangeDefined = false; float minRange, maxRange; + BufferedReader br; void setProperty(String propertyName, Object value, BitSet bs) { if ("init" == propertyName) { @@ -94,11 +129,11 @@ return; } if ("bufferedReader" == propertyName) { - BufferedReader br = (BufferedReader)value; + br = (BufferedReader)value; if (currentMesh == null) allocMesh(null); currentMesh.clear("isosurface"); - readData(br); + readData(); calcVoxelVertexVectors(); constructTessellatedSurface(); currentMesh.colix = getDefaultColix(); @@ -127,8 +162,8 @@ } if ("colorReader" == propertyName) { System.out.println("colorReader seen!"); - BufferedReader br = (BufferedReader)value; - readData(br); + br = (BufferedReader)value; + readData(); if (! rangeDefined) { minRange = getMinMappedValue(); maxRange = getMaxMappedValue(); @@ -142,14 +177,14 @@ super.setProperty(propertyName, value, bs); } - void readData(BufferedReader br) { - int nSurfaces = readVolumetricHeader(br); + void readData() { + int nSurfaces = readVolumetricHeader(); if (nSurfaces < fileIndex) { System.out.println("not enough surfaces in file -- resetting fileIndex to " + nSurfaces); fileIndex = nSurfaces; } calcVolumetricMatrix(); - readVolumetricData(br); + readVolumetricData(); } void calcVolumetricMatrix() { @@ -206,39 +241,40 @@ // file reading stuff //////////////////////////////////////////////////////////////// - int readVolumetricHeader(BufferedReader br) { + int readVolumetricHeader() { try { - readTitleLines(br); - readAtomCountAndOrigin(br); - readVoxelVectors(br); - readAtoms(br); - return readExtraLine(br); + readTitleLines(); + readAtomCountAndOrigin(); + readVoxelVectors(); + readAtoms(); + return readExtraLine(); } catch (Exception e) { e.printStackTrace(); throw new NullPointerException(); } } - void readVolumetricData(BufferedReader br) { + void readVolumetricData() { try { - readVoxelData(br); + readVoxelData(); } catch (Exception e) { e.printStackTrace(); throw new NullPointerException(); } } - void readTitleLines(BufferedReader br) throws Exception { - String title; - title = br.readLine().trim() + " - "; - title += br.readLine().trim(); + String JvxlHeader = ""; + void readTitleLines() throws Exception { + JvxlHeader = br.readLine() + "\n"; + JvxlHeader += br.readLine() + "\n"; } int atomCount; boolean negativeAtomCount; - void readAtomCountAndOrigin(BufferedReader br) throws Exception { - String line = br.readLine(); + void readAtomCountAndOrigin() throws Exception { + line = br.readLine(); + JvxlHeader += line + "\n"; atomCount = parseInt(line); volumetricOrigin.x = parseFloat(line, ichNextParse); volumetricOrigin.y = parseFloat(line, ichNextParse); @@ -250,14 +286,14 @@ } } - void readVoxelVectors(BufferedReader br) throws Exception { + void readVoxelVectors() throws Exception { for (int i = 0; i < 3; ++i) - readVoxelVector(br, i); + readVoxelVector(i); } - void readVoxelVector(BufferedReader br, int voxelVectorIndex) - throws Exception { - String line = br.readLine(); + void readVoxelVector(int voxelVectorIndex) throws Exception { + line = br.readLine(); + JvxlHeader += line + "\n"; Vector3f voxelVector = volumetricVectors[voxelVectorIndex]; voxelCounts[voxelVectorIndex] = parseInt(line); voxelVector.x = parseFloat(line, ichNextParse); @@ -268,9 +304,10 @@ unitVolumetricVectors[voxelVectorIndex].normalize(voxelVector); } - void readAtoms(BufferedReader br) throws Exception { + void readAtoms() throws Exception { for (int i = 0; i < atomCount; ++i) { - /*String line = */br.readLine(); + JvxlHeader += br.readLine() + "\n"; + /* Atom atom = atomSetCollection.addNewAtom(); atom.elementNumber = (byte)parseInt(line); @@ -282,25 +319,48 @@ } } - int readExtraLine(BufferedReader br) throws Exception { - return (negativeAtomCount ? parseInt(br.readLine()) : 1); + boolean isJvxl = false; + int readExtraLine() throws Exception { + if (!negativeAtomCount) + return 1; + int nSurfaces = parseInt(line = br.readLine()); + isJvxl = (nSurfaces < 0); + createJvxl = ! isJvxl; + if (isJvxl) { + nSurfaces = -nSurfaces; + edgeFractionBase = (char) parseInt(line, ichNextParse); + edgeFractionRange = parseFloat(line, ichNextParse); + System.out.println("JVXL reading base: " + edgeFractionBase + " range: " + + edgeFractionRange); + for (int i = 0; i < nSurfaces; i++) + br.readLine(); // for now, skip definition line + } + return nSurfaces; } - boolean collectData = true; - void readVoxelData(BufferedReader br) throws Exception { + boolean createJvxl = true; // for now + String line = ""; + int nBytes = 0; + int nDataPoints = 1; + String data = ""; + + void readVoxelData() throws Exception { System.out.println("entering readVoxelData for fileIndex = " + fileIndex); - String line = ""; ichNextParse = 0; + line = ""; + thisValue = Integer.MIN_VALUE; + nThisValue = 0; boolean inside = false; int dataCount = 0; - String data = ""; - int nBytes = 0; - int nDataPoints = 1; + data = ""; + nBytes = 0; + thisInside = true; + nDataPoints = 1; int voxelCountX = voxelCounts[0]; int voxelCountY = voxelCounts[1]; int voxelCountZ = voxelCounts[2]; voxelData = new float[voxelCountX][][]; - skipData(br, (fileIndex - 1) * voxelCountX * voxelCountY * voxelCountZ); + skipData((fileIndex - 1) * voxelCountX * voxelCountY * voxelCountZ); for (int x = 0; x < voxelCountX; ++x) { float[][] plane = new float[voxelCountY][]; voxelData[x] = plane; @@ -308,17 +368,9 @@ float[] strip = new float[voxelCountZ]; plane[y] = strip; for (int z = 0; z < voxelCountZ; ++z) { - float voxelValue = parseFloat(line, ichNextParse); - if (Float.isNaN(voxelValue)) { - line = br.readLine(); - if (line == null || Float.isNaN(voxelValue = parseFloat(line))) { - System.out.println("end of file in CubeReader?"); - throw new NullPointerException(); - } - nBytes += line.length() + 1; - } + float voxelValue = getNextVoxelValue(); strip[z] = voxelValue; - if (collectData) { + if (createJvxl) { boolean isInside = ((cutoff > 0 && voxelValue >= cutoff) || (cutoff < 0 && voxelValue <= cutoff)); if (inside == isInside) { @@ -333,16 +385,46 @@ } } } - if (collectData) { + if (createJvxl) { data += " " + dataCount; - System.out.println("cutoff " + cutoff + " bytes " + data.length() - + " compressionRatio " + (nBytes * 1f / data.length()) + "\n" + nDataPoints + data); } System.out.println("Successfully read " + voxelCountX + " x " + voxelCountY + " x " + voxelCountZ + " voxels"); } - void skipData(BufferedReader br, int n) throws Exception { + int thisValue; + int nThisValue; + boolean thisInside; + float getNextVoxelValue() throws Exception { + if (isJvxl) { + if (nThisValue == 0) { + nThisValue = parseInt(line, ichNextParse); + if (nThisValue == Integer.MIN_VALUE) { + line = br.readLine(); + if (line == null || (nThisValue = parseInt(line)) == Integer.MIN_VALUE) { + System.out.println("end of file in JvxlReader? (x,y,z,line):"+ line); + throw new NullPointerException(); + } + nBytes += line.length() + 1; + } + thisInside = !thisInside; + } + --nThisValue; + return (thisInside ? 1f : 0f); + } + float voxelValue = parseFloat(line, ichNextParse); + if (Float.isNaN(voxelValue)) { + line = br.readLine(); + if (line == null || Float.isNaN(voxelValue = parseFloat(line))) { + System.out.println("end of file in CubeReader? (line):" + line); + throw new NullPointerException(); + } + nBytes += line.length() + 1; + } + return voxelValue; + } + + void skipData(int n) throws Exception { if (n == 0) return; System.out.println("skipping " + n + " datapoints"); @@ -353,11 +435,21 @@ int c = countData(line); i += c; } + if (isJvxl) + br.readLine(); } int countData(String str) { + int count = 0; + if (isJvxl) { + int n = parseInt(str); + while (n != Integer.MIN_VALUE) { + count += n; + n = parseInt(str, ichNextParse); + } + return count; + } int ich = 0; - int count = 0; int ichMax = str.length(); char ch; while (ich < ichMax) { @@ -390,38 +482,35 @@ voxelCountZ = voxelData[0][0].length - 1; edgeFractions = ""; int[][] isoPointIndexes = new int[voxelCountY * voxelCountZ][12]; - for (int i = voxelCountY * voxelCountZ; --i >= 0; ) + for (int i = voxelCountY * voxelCountZ; --i >= 0;) isoPointIndexes[i] = new int[12]; - /* - for (int x = 0; x < voxelCountX; ++x) - for (int y = 0; y < voxelCountY; ++y) - for (int z = 0; z < voxelCountZ; ++z) - System.out.println("" + x + "," + y + "," + z + " = " + - voxelData[x][y][z]); - */ + /* + * for (int x = 0; x < voxelCountX; ++x) for (int y = 0; y < voxelCountY; + * ++y) for (int z = 0; z < voxelCountZ; ++z) System.out.println("" + x + + * "," + y + "," + z + " = " + voxelData[x][y][z]); + */ int insideCount = 0, outsideCount = 0, surfaceCount = 0; - for (int x = voxelCountX; --x >= 0; ) { - for (int y = voxelCountY; --y >= 0; ) { - for (int z = voxelCountZ; --z >= 0; ) { + for (int x = voxelCountX; --x >= 0;) { + for (int y = voxelCountY; --y >= 0;) { + for (int z = voxelCountZ; --z >= 0;) { int insideMask = 0; - for (int i = 8; --i >= 0; ) { + for (int i = 8; --i >= 0;) { Point3i offset = cubeVertexOffsets[i]; - float vertexValue = - voxelData[x + offset.x][y + offset.y][z + offset.z]; + float vertexValue = voxelData[x + offset.x][y + offset.y][z + + offset.z]; vertexValues[i] = vertexValue; - if ((cutoff > 0 && vertexValue >= cutoff) || - (cutoff < 0 && vertexValue <= cutoff)) + if ((cutoff > 0 && vertexValue >= cutoff) + || (cutoff < 0 && vertexValue <= cutoff)) insideMask |= 1 << i; } /* - for (int i = 0; i < 8; ++i ) - System.out.println("vertexValues[" + i + "]=" + - vertexValues[i]); - System.out.println("insideMask=" + Integer.toHexString(insideMask)); - */ + * for (int i = 0; i < 8; ++i ) System.out.println("vertexValues[" + i + + * "]=" + vertexValues[i]); System.out.println("insideMask=" + + * Integer.toHexString(insideMask)); + */ if (insideMask == 0) { ++outsideCount; @@ -433,14 +522,20 @@ } ++surfaceCount; calcVoxelOrigin(x, y, z); - int[] voxelPointIndexes = - propogateNeighborPointIndexes(x, y, z, isoPointIndexes); - processOneVoxel(insideMask, cutoff, voxelPointIndexes); + int[] voxelPointIndexes = propogateNeighborPointIndexes(x, y, z, + isoPointIndexes); + try { + processOneVoxel(insideMask, cutoff, voxelPointIndexes); + } catch (Exception e) { + e.printStackTrace(); + throw new NullPointerException(); + } + } } } - if (collectData) - System.out.println(edgeFractions.length()+" "+edgeFractions); + if (createJvxl) + dumpJvxlData(); System.out.println("volumetric=" + voxelCountX + "," + voxelCountY + "," + @@ -456,6 +551,17 @@ outsideCount+surfaceCount)); } + void dumpJvxlData() { + System.out.print(JvxlHeader); + System.out.println("-1 " + (int)edgeFractionBase + " " + (int) edgeFractionRange + + " Jmol voxel format version 0.9" + + "\n" + cutoff + " " + data.length() + " " + edgeFractions.length() + + " compressionRatio=" + + (nBytes * 1f / (data.length() + edgeFractions.length())) + + "\n" + data + + "\n" + edgeFractions); + } + final int[] nullNeighbor = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; int[] propogateNeighborPointIndexes(int x, int y, int z, @@ -514,7 +620,7 @@ } void processOneVoxel(int insideMask, float cutoff, - int[] voxelPointIndexes) { + int[] voxelPointIndexes) throws Exception { int edgeMask = edgeMaskTable[insideMask]; for (int iEdge = 12; --iEdge >= 0; ) { if ((edgeMask & (1 << iEdge)) == 0) @@ -541,21 +647,51 @@ } String edgeFractions = ""; + char edgeFractionBase = defaultEdgeFractionBase; + float edgeFractionRange = defaultEdgeFractionRange; + int edgeFractionPtr; + float getNextFraction() throws Exception { + if (edgeFractions == null) + return 0; + if (edgeFractionPtr >= edgeFractions.length()) { + edgeFractions = br.readLine(); + if (edgeFractions == null) { + System.out.println("end of file reading edgeFractions"); + throw new NullPointerException(); + } + edgeFractionPtr = 0; + } + int ich = (int) edgeFractions.charAt(edgeFractionPtr++); + if (ich < edgeFractionBase) + ich = 92; // ! --> \ + float fraction = (ich - edgeFractionBase + 0.5f) / edgeFractionRange; + if (logMessages) + System.out.println(fraction +" <-- " + ich + " " + (char)ich); + return fraction; + } + void calcSurfacePoint(float cutoff, float valueA, float valueB, - Point3f surfacePoint) { - float diff = valueB - valueA; - float fraction = (cutoff - valueA) / diff; - if (collectData) - edgeFractions += (int)(fraction * 8); - - if (Float.isNaN(fraction) || fraction < 0 || fraction > 1) { - System.out.println("fraction=" + fraction + - " cutoff=" + cutoff + - " A:" + valueA + - " B:" + valueB); - throw new IndexOutOfBoundsException(); + Point3f surfacePoint) throws Exception { + float fraction; + if (isJvxl) { + fraction = getNextFraction(); + } else { + float diff = valueB - valueA; + fraction = (cutoff - valueA) / diff; + if (createJvxl) { + int ich = (int)(fraction * edgeFractionRange + edgeFractionBase); + if (ich == 92) + ich = 33; // \ --> ! + if (logMessages) + System.out.println(fraction +" --> " + ich + " " + (char)ich); + edgeFractions += (char) (ich); + } + if (Float.isNaN(fraction) || fraction < 0 || fraction > 1) { + System.out.println("fraction=" + fraction + " cutoff=" + cutoff + " A:" + + valueA + " B:" + valueB); + throw new IndexOutOfBoundsException(); + } } - edgeVector.sub(pointB, pointA); surfacePoint.scaleAdd(fraction, edgeVector, pointA); } Modified: branches/bob200603/Jmol/src/org/jmol/viewer/JmolConstants.java =================================================================== --- branches/bob200603/Jmol/src/org/jmol/viewer/JmolConstants.java 2006-05-22 18:01:11 UTC (rev 5158) +++ branches/bob200603/Jmol/src/org/jmol/viewer/JmolConstants.java 2006-05-22 21:30:32 UTC (rev 5159) @@ -42,7 +42,7 @@ // for now, just update this by hand // perhaps use ant filter later ... but mth doesn't like it :-( public final static String copyright = "(C) 2006 Jmol Development"; - public final static String version = "10.x.04(branch bob200603)"; + public final static String version = "10.x.05(branch bob200603)"; public final static String cvsDate = "$Date$"; public final static String date = cvsDate.substring(7, 23); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Jmol-commits mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/jmol-commits
