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

Reply via email to