Revision: 5185
Author: hansonr
Date: 2006-05-27 20:37:57 -0700 (Sat, 27 May 2006)
ViewCVS: http://svn.sourceforge.net/jmol/?rev=5185&view=rev
Log Message:
-----------
bob200603 isosurface upgrade includes color X~nnn compression
and vertex normal grouping. Still a few bugs relating to
isosurface delete not really doing the job. I'm forgetting to
clear out one or more global settings in Isosurface.java, I think.
Modified Paths:
--------------
branches/bob200603/Jmol/src/org/jmol/viewer/ColorManager.java
branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java
branches/bob200603/Jmol/src/org/jmol/viewer/MeshCollection.java
branches/bob200603/Jmol/src/org/jmol/viewer/MeshRenderer.java
Modified: branches/bob200603/Jmol/src/org/jmol/viewer/ColorManager.java
===================================================================
--- branches/bob200603/Jmol/src/org/jmol/viewer/ColorManager.java
2006-05-28 03:35:37 UTC (rev 5184)
+++ branches/bob200603/Jmol/src/org/jmol/viewer/ColorManager.java
2006-05-28 03:37:57 UTC (rev 5185)
@@ -29,7 +29,6 @@
Viewer viewer;
Graphics3D g3d;
-
int[] argbsCpk;
ColorManager(Viewer viewer, Graphics3D g3d) {
@@ -227,6 +226,46 @@
}
int quantize(float val, float lo, float hi, int segmentCount) {
+ /* oy! Say you have an array with 10 values, so segmentCount=10
+ * then we expect 0,1,2,...,9 EVENLY
+ * If f = fractional distance from lo to hi, say 0.0 to 10.0 again,
+ * then one might expect 10 even placements. BUT:
+ * (int) (f * segmentCount + 0.5) gives
+ *
+ * 0.0 ---> 0
+ * 0.5 ---> 1
+ * 1.0 ---> 1
+ * 1.5 ---> 2
+ * 2.0 ---> 2
+ * ...
+ * 8.5 ---> 9
+ * 9.0 ---> 9
+ * 9.5 ---> 10 --> 9
+ *
+ * so the first bin is underloaded, and the last bin is overloaded.
+ * With integer quantities, one would not notice this, because
+ * 0, 1, 2, 3, .... --> 0, 1, 2, 3, .....
+ *
+ * but with fractional quantities, it will be noticeable.
+ *
+ * What we really want is:
+ *
+ * 0.0 ---> 0
+ * 0.5 ---> 0
+ * 1.0 ---> 1
+ * 1.5 ---> 1
+ * 2.0 ---> 2
+ * ...
+ * 8.5 ---> 8
+ * 9.0 ---> 9
+ * 9.5 ---> 9
+ *
+ * that is, no addition of 0.5.
+ * Instead, I add 0.0001, just for discreteness sake.
+ *
+ * Bob Hanson, 5/2006
+ *
+ */
float range = hi - lo;
if (range <= 0 || Float.isNaN(val))
return segmentCount / 2;
@@ -234,7 +273,7 @@
if (t <= 0)
return 0;
float quanta = range / segmentCount;
- int q = (int)(t / quanta + 0.5f);
+ int q = (int)(t / quanta + 0.0001f); //was 0.5f!
if (q >= segmentCount)
q = segmentCount - 1;
return q;
Modified: branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java
===================================================================
--- branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java 2006-05-28
03:35:37 UTC (rev 5184)
+++ branches/bob200603/Jmol/src/org/jmol/viewer/Isosurface.java 2006-05-28
03:37:57 UTC (rev 5185)
@@ -88,11 +88,12 @@
class Isosurface extends MeshCollection {
final static boolean logMessages = false;
+ final static boolean logCompression = false;
final float ANGSTROMS_PER_BOHR = JmolConstants.ANGSTROMS_PER_BOHR;
- final static char defaultEdgeFractionBase = 35; //#$%.......
+ final static int defaultEdgeFractionBase = 35; //#$%.......
final static float defaultEdgeFractionRange = 90f;
- final static char defaultColorFractionBase = 35;
+ final static int defaultColorFractionBase = 35;
final static float defaultColorFractionRange =
JmolConstants.argbsRoygbScale.length;
final Point3f volumetricOrigin = new Point3f();
@@ -112,9 +113,7 @@
final Matrix3f volumetricMatrix = new Matrix3f();
float[][][] voxelData;
- int edgePointCount = 0;
int fileIndex = 0; //one-based
- Point3f[] edgePoints;
float cutoff = 0.02f;
boolean rangeDefined = false;
@@ -126,6 +125,8 @@
boolean endOfData;
BufferedReader br;
+ int testCount;
+
void setProperty(String propertyName, Object value, BitSet bs) {
System.out.println("isosurface setProperty: " + propertyName + " = "
@@ -164,19 +165,19 @@
System.out
.println("For grid points, use: isosurface delete; isosurface myiso
gridpoints \"\"");
- associateNormals = ! viewer.getTestFlag2();
-
+ associateNormals = !viewer.getTestFlag2();
+
br = (BufferedReader) value;
if (currentMesh == null)
allocMesh(null);
currentMesh.clear("isosurface");
- if (addGridPoints)
+ if (addGridPoints) {
currentMesh.showPoints = true;
-
+ currentMesh.hasGridPoints = true;
+ }
readData(false);
calcVoxelVertexVectors();
- thePlane = null;
- constructTessellatedSurface();
+ generateSurfaceData();
currentMesh.colix = getDefaultColix();
initializeMesh(viewer.getTestFlag1()); // see below
currentMesh.visible = true;
@@ -187,7 +188,6 @@
}
if ("plane" == propertyName) {
thePlane = (Point4f) value;
- cutoff = 0f;
return;
}
if ("cutoff" == propertyName) {
@@ -215,7 +215,6 @@
minRange = getMinMappedValue();
maxRange = getMaxMappedValue();
}
- System.out.println(" minRange=" + minRange + " maxRange=" + maxRange);
applyColorScale(minRange, maxRange, "roygb");
discardTempData();
System.out.println("\n" + getJvxlFile(currentMesh, "mapped"));
@@ -225,10 +224,19 @@
}
boolean isJvxl;
+ int[][] edgeInfo;
+ int edgeCount;
void readData(boolean isMapData) {
isJvxl = false;
endOfData = false;
+ if (!isMapData) {
+ currentMesh.surfaceData = "";
+ currentMesh.edgeData = "";
+ edgeInfo = null;
+ edgeCount = 0;
+ }
+
int nSurfaces = readVolumetricHeader();
if (nSurfaces < fileIndex) {
System.out
@@ -246,8 +254,6 @@
}
void discardTempData() {
- edgePointCount = 0;
- edgePoints = null;
voxelData = null;
assocGridPointMap = null;
assocGridPointNormals = null;
@@ -301,6 +307,7 @@
void readTitleLines() throws Exception {
jvxlFileHeader = br.readLine() + "\n";
jvxlFileHeader += br.readLine() + "\n";
+ System.out.println(jvxlFileHeader);
}
int atomCount;
@@ -318,9 +325,9 @@
atomCount = -atomCount;
int jvxlAtoms = (atomCount == 0 ? -1 : -atomCount);
- volumetricOrigin.x = parseFloat(line, ichNextParse);
- volumetricOrigin.y = parseFloat(line, ichNextParse);
- volumetricOrigin.z = parseFloat(line, ichNextParse);
+ volumetricOrigin.x = parseFloat();
+ volumetricOrigin.y = parseFloat();
+ volumetricOrigin.z = parseFloat();
volumetricOrigin.scale(ANGSTROMS_PER_BOHR);
jvxlFileHeader += jvxlAtoms + " " + atomLine + "\n";
}
@@ -335,9 +342,9 @@
jvxlFileHeader += line + "\n";
Vector3f voxelVector = volumetricVectors[voxelVectorIndex];
voxelCounts[voxelVectorIndex] = parseInt(line);
- voxelVector.x = parseFloat(line, ichNextParse);
- voxelVector.y = parseFloat(line, ichNextParse);
- voxelVector.z = parseFloat(line, ichNextParse);
+ voxelVector.x = parseFloat();
+ voxelVector.y = parseFloat();
+ voxelVector.z = parseFloat();
voxelVector.scale(ANGSTROMS_PER_BOHR);
volumetricVectorLengths[voxelVectorIndex] = voxelVector.length();
unitVolumetricVectors[voxelVectorIndex].normalize(voxelVector);
@@ -349,10 +356,10 @@
/*
Atom atom = atomSetCollection.addNewAtom();
atom.elementNumber = (byte)parseInt(line);
- atom.partialCharge = parseFloat(line, ichNextParse);
- atom.x = parseFloat(line, ichNextParse) * ANGSTROMS_PER_BOHR;
- atom.y = parseFloat(line, ichNextParse) * ANGSTROMS_PER_BOHR;
- atom.z = parseFloat(line, ichNextParse) * ANGSTROMS_PER_BOHR;
+ atom.partialCharge = parseFloat();
+ atom.x = parseFloat() * ANGSTROMS_PER_BOHR;
+ atom.y = parseFloat() * ANGSTROMS_PER_BOHR;
+ atom.z = parseFloat() * ANGSTROMS_PER_BOHR;
*/
}
if (atomCount == 0)
@@ -369,23 +376,24 @@
if (negativeAtomCount) {
nSurfaces = parseInt(line = br.readLine());
- System.out.println("Reading extra orbital information line: " + line);
+ System.out
+ .println("Reading extra orbital/JVXL information line: " + line);
isJvxl = (nSurfaces < 0);
if (isJvxl) {
nSurfaces = -nSurfaces;
System.out.println("jvxl file surfaces: " + nSurfaces);
- int ich = parseInt(line, ichNextParse);
+ int ich = parseInt();
if (ich == Integer.MIN_VALUE) {
System.out.println("using default edge fraction base and range");
} else {
edgeFractionBase = (char) ich;
- edgeFractionRange = parseFloat(line, ichNextParse);
+ edgeFractionRange = parseFloat();
}
if (ich == Integer.MIN_VALUE) {
System.out.println("using default color fraction base and range");
} else {
colorFractionBase = (char) ich;
- colorFractionRange = parseFloat(line, ichNextParse);
+ colorFractionRange = parseFloat();
}
}
} else {
@@ -393,11 +401,10 @@
}
jvxlFileHeader += "-1 " + (int) edgeFractionBase + " "
+ (int) edgeFractionRange + " " + (int) colorFractionBase + " "
- + (int) colorFractionRange + " Jmol voxel format version 0.9b\n";
+ + (int) colorFractionRange + " Jmol voxel format version 0.9c\n";
return nSurfaces;
}
- String line;
int nBytes;
int nDataPoints;
String surfaceData;
@@ -413,7 +420,7 @@
strFractionTemp = "";
fractionData = "";
iHaveColorData = false;
- thisInside = true;
+ thisInside = (!isJvxl || thePlane == null);
nDataPoints = 0;
int nPointsX = voxelCounts[0];
int nPointsY = voxelCounts[1];
@@ -433,7 +440,9 @@
thePlane.z = 1; //{0 0 0 w} becomes {0 0 1 w}
vTemp.set(thePlane.x, thePlane.y, thePlane.z);
vTempMag = vTemp.length();
+ cutoff = 0f;
}
+ System.out.println("cutoff = " + cutoff);
for (int x = 0; x < nPointsX; ++x) {
float[][] plane = new float[nPointsY][];
voxelData[x] = plane;
@@ -442,11 +451,11 @@
plane[y] = strip;
for (int z = 0; z < nPointsZ; ++z) {
float voxelValue = getNextVoxelValue();
- if (thePlane != null)
+ if (!isMapData && thePlane != null)
voxelValue = calcVoxelPlaneDistance(x, y, z);
strip[z] = voxelValue;
++nDataPoints;
- if (isJvxl || isMapData)
+ if (isJvxl && thePlane == null || isMapData)
continue;
boolean isInside = ((cutoff > 0 && voxelValue >= cutoff) || (cutoff
<= 0 && voxelValue <= cutoff));
if (inside == isInside) {
@@ -462,10 +471,12 @@
}
if (!isJvxl)
surfaceData += " " + dataCount + "\n";
- if (!isMapData)
- currentMesh.surfaceData = surfaceData;
+ if (!isMapData) {
+ currentMesh.surfaceData = (thePlane == null ? surfaceData : "");
+ currentMesh.jvxlPlane = thePlane;
+ }
System.out.println("Successfully read " + nPointsX + " x " + nPointsY
- + " x " + nPointsZ + " data points");
+ + " x " + nPointsZ + " data points; " + edgeCount + " edges");
}
float calcVoxelPlaneDistance(int x, int y, int z) {
@@ -493,9 +504,21 @@
if (showMsg)
System.out.println("reading jvxl data set: " + line);
jvxlCutoff = parseFloat(line);
- nStructureData = parseInt(line, ichNextParse); //nStructure
- nEdgeData = parseInt(line, ichNextParse); //nEdgeData
- nColorData = parseInt(line, ichNextParse);
+ nStructureData = parseInt(); //nStructure
+ nEdgeData = parseInt(); //nEdgeData
+ nColorData = parseInt();
+ if (nStructureData < 0) {
+ nEdgeData = -1;
+ try {
+ thePlane = new Point4f(parseFloat(), parseFloat(), parseFloat(),
+ parseFloat());
+ } catch (Exception e) {
+ System.out
+ .println("Error reading 4 floats for PLANE definition -- setting
to 0 0 1 0 (z=0)");
+ thePlane = new Point4f(0, 0, 1, 0);
+ }
+ System.out.println("plane read: " + thePlane);
+ }
iHaveColorData = (nColorData > 0);
}
@@ -505,8 +528,10 @@
float getNextVoxelValue() throws Exception {
if (isJvxl) {
+ if (nStructureData <= 0)
+ return 0f; //unnecessary -- probably a plane
if (nThisValue == 0) {
- nThisValue = parseInt(line, ichNextParse);
+ nThisValue = parseInt();
if (nThisValue == Integer.MIN_VALUE) {
line = br.readLine();
if (line == null
@@ -527,7 +552,7 @@
--nThisValue;
return (thisInside ? 1f : 0f);
}
- float voxelValue = parseFloat(line, ichNextParse);
+ float voxelValue = parseFloat();
if (Float.isNaN(voxelValue)) {
line = br.readLine();
if (line == null || Float.isNaN(voxelValue = parseFloat(line))) {
@@ -538,40 +563,42 @@
line = "0 0 0 0 0 0 0 0 0 0";
//throw new NullPointerException();
}
- if (ntest++ < 3) {
- System.out.println("READING " + nBytes + " " + voxelValue + " " +
line);
- }
+ //if (ntest++ < 3) {
+ //System.out.println("READING " + nBytes + " " + voxelValue + " " +
line);
+ // }
nBytes += line.length() + 1;
}
return voxelValue;
}
- int ntest = 100;
+ //int ntest = 100;
void skipData(int n, int nPoints) throws Exception {
- ntest = 100;
- if (n == 0)
+ //ntest = 100;
+ if (n <= 0)
return;
System.out.println("skipping " + n + " data sets, " + nPoints
+ " points each");
- for (int i = 0; i < n; i++) {
- if (isJvxl)
+ for (int i = 0; i < n; i++)
+ if (isJvxl) {
readJvxlDefinitionLine(false);
- skipData(nPoints, true);
- if (isJvxl) {
- skipData(nEdgeData, false);
+ if (nStructureData > 0)
+ skipData(nPoints, true);
+ if (nEdgeData > 0)
+ skipData(nEdgeData, false);
if (iHaveColorData)
skipData(nColorData, false);
+ } else {
+ skipData(nPoints, true);
}
- }
}
void skipData(int nPoints, boolean isInt) throws Exception {
int iV = 0;
while (iV < nPoints) {
line = br.readLine();
- if (iV < 1000 || nPoints - iV < 1000)
- System.out.println(iV + " skip " + nPoints + " " + line);
+ //if (iV < 1000 || nPoints - iV < 1000)
+ //System.out.println(iV + " skip " + nPoints + " " + line);
iV += (isInt ? countData(line) : line.length());
}
}
@@ -614,23 +641,19 @@
final int[] surfacePointIndexes = new int[12];
int voxelCountX, voxelCountY, voxelCountZ;
+ float minMappedValue;
+ float maxMappedValue;
- void constructTessellatedSurface() {
+ void generateSurfaceData() {
voxelCountX = voxelData.length - 1;
voxelCountY = voxelData[0].length - 1;
voxelCountZ = voxelData[0][0].length - 1;
strFractionTemp = "";
+ fractionPtr = 0;
int[][] isoPointIndexes = new int[voxelCountY * voxelCountZ][12];
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]);
- */
try {
-
int insideCount = 0, outsideCount = 0, surfaceCount = 0;
for (int x = voxelCountX; --x >= 0;) {
for (int y = voxelCountY; --y >= 0;) {
@@ -645,13 +668,6 @@
|| (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));
- */
-
if (insideMask == 0) {
++outsideCount;
continue;
@@ -665,7 +681,6 @@
int[] voxelPointIndexes = propogateNeighborPointIndexes(x, y, z,
isoPointIndexes);
processOneVoxel(insideMask, cutoff, voxelPointIndexes, x, y, z);
-
}
}
}
@@ -673,12 +688,12 @@
fractionData += "\n";
currentMesh.nBytes = nBytes;
}
+ currentMesh.jvxlFileHeader = jvxlFileHeader;
+ currentMesh.cutoff = (isJvxl ? jvxlCutoff : cutoff);
+ currentMesh.colorData = "";
currentMesh.edgeData = fractionData;
- currentMesh.jvxlFileHeader = jvxlFileHeader;
fractionData = "";
strFractionTemp = "";
- currentMesh.cutoff = (isJvxl ? jvxlCutoff : cutoff);
- currentMesh.colorData = "";
System.out.println("volumetric=" + voxelCountX + "," + voxelCountY + ","
+ voxelCountZ + "," + " total="
+ (voxelCountX * voxelCountY * voxelCountZ) + "\n" + " insideCount="
@@ -686,6 +701,7 @@
+ surfaceCount + " total="
+ (insideCount + outsideCount + surfaceCount));
if (iHaveColorData) {
+ fractionPtr = 0;
setJvxlColixes(currentMesh, "roygb");
currentMesh.colorData = fractionData;
}
@@ -693,24 +709,8 @@
e.printStackTrace();
throw new NullPointerException();
}
-
}
- String getJvxlFile(Mesh mesh, String msg) {
- String data = mesh.jvxlFileHeader;
- data += "# " + msg + "\n" + mesh.cutoff + " " + mesh.surfaceData.length()
- + " " + (mesh.edgeData.length() - 1) + " "
- + (mesh.colorData.length() - 1);
- if (!isJvxl)
- data += " compressionRatio="
- + (mesh.nBytes * 1f / (mesh.surfaceData.length()
- + mesh.edgeData.length() + mesh.colorData.length()));
- data += "\n" + mesh.surfaceData + mesh.edgeData + mesh.colorData;
- if (msg != null)
- data += "#-------end of jvxl file " + msg + " data-------\n";
- return data;
- }
-
final int[] nullNeighbor = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
int[] propogateNeighborPointIndexes(int x, int y, int z,
@@ -784,17 +784,18 @@
float valueA = vertexValues[vertexA];
float valueB = vertexValues[vertexB];
calcVertexPoints(vertexA, vertexB);
- addEdgePoint(pointA);
- addEdgePoint(pointB);
- int assocVertex = calcSurfacePoint(cutoff, valueA, valueB,
+ addEdgeInfo(x, y, z, vertexA, vertexB);
+ float fraction = calcSurfacePoint(cutoff, valueA, valueB,
surfacePoints[iEdge]);
+ int assocVertex = (fraction < assocCutoff ? -1
+ : fraction > 1 - assocCutoff ? 1 : 0);
String sKey = (assocVertex == 0 ? "" : calcDataKey(x, y, z,
assocVertex < 0 ? vertexA : vertexB));
voxelPointIndexes[iEdge] = addVertexCopy(surfacePoints[iEdge],
(assocVertex != 0), sKey);
if (addGridPoints) {
- addVertexCopy(pointA, false, "");
- addVertexCopy(pointB, false, "");
+ addVertexCopy(valueA < valueB ? pointA : pointB, false, "");
+ addVertexCopy(valueA < valueB ? pointB : pointA, false, "");
}
}
@@ -811,19 +812,25 @@
return (x + offset.x) + "_" + (y + offset.y) + "_" + (z + offset.z);
}
- char edgeFractionBase;
+ int edgeFractionBase;
float edgeFractionRange;
- char colorFractionBase;
+ int colorFractionBase;
float colorFractionRange;
int fractionPtr;
+ int edgePtr;
+ Point3i[] edgesA;
+ Point3i[] edgesB;
+
String strFractionTemp = "";
String fractionData = "";
- float getNextFraction(char base, float range) throws Exception {
+ float getNextFraction(int base, float range, float fracOffset)
+ throws Exception {
if (strFractionTemp == null)
return 0;
if (fractionPtr >= strFractionTemp.length()) {
strFractionTemp = br.readLine();
+ System.out.println(strFractionTemp);
if (strFractionTemp == null) {
if (!endOfData)
System.out
@@ -832,26 +839,24 @@
endOfData = true;
strFractionTemp = "" + base;
//throw new NullPointerException();
+ } else {
+ strFractionTemp = uncompressString(strFractionTemp);
}
fractionData += strFractionTemp + "\n";
+ System.out.println(fractionData);
fractionPtr = 0;
}
- int ich = (int) strFractionTemp.charAt(fractionPtr++);
- if (ich < base)
- ich = 92; // ! --> \
- float fraction = (ich - base + 0.5f) / range;
- if (logMessages)
- System.out.println(fraction + " <-- " + ich + " " + (char) ich);
- return fraction;
+ return fractionFromCharacter((int) strFractionTemp.charAt(fractionPtr++),
+ base, range, fracOffset);
}
final static float assocCutoff = 0.3f;
- int calcSurfacePoint(float cutoff, float valueA, float valueB,
- Point3f surfacePoint) throws Exception {
+ float calcSurfacePoint(float cutoff, float valueA, float valueB,
+ Point3f surfacePoint) throws Exception {
float fraction;
- if (isJvxl) {
- fraction = getNextFraction(edgeFractionBase, edgeFractionRange);
+ if (isJvxl && nEdgeData > 0) {
+ fraction = getNextFraction(edgeFractionBase, edgeFractionRange, 0.5f);
} else {
float diff = valueB - valueA;
fraction = (cutoff - valueA) / diff;
@@ -860,53 +865,76 @@
+ " cutoff=" + cutoff + " A:" + valueA + " B:" + valueB);
fraction = 0;
}
- if (!isJvxl) {
- int ich = (int) (fraction * edgeFractionRange + edgeFractionBase);
- if (ich == 92)
- ich = 33; // \ --> !
- if (logMessages)
- System.out.println(fraction + " --> " + ich + " " + (char) ich);
- fractionData += (char) (ich);
- }
+ if (!isJvxl)
+ fractionData += fractionAsCharacter(fraction, edgeFractionBase,
+ edgeFractionRange);
}
edgeVector.sub(pointB, pointA);
surfacePoint.scaleAdd(fraction, edgeVector, pointA);
- return (fraction < assocCutoff ? -1 : fraction > 1 - assocCutoff ? 1 : 0);
+ return fraction;
}
+ float fractionFromCharacter(int ich, int base, float range, float
fracOffset) {
+ if (ich < base)
+ ich = 92; // ! --> \
+ float fraction = (ich - base + fracOffset) / range;
+ if (fraction < 0f)
+ fraction = 0f;
+ if (fraction >= 1f)
+ fraction = 0.999999f;
+ if (logMessages)
+ System.out.println("ffc: " + fraction + " <-- " + ich + " " + (char)
ich);
+ return fraction;
+ }
+
+ char valueAsCharacter(float value, float min, float max, int base, float
range) {
+ float fraction = (min == max ? 0.5f : (value - min) / (max - min));
+ return fractionAsCharacter(fraction, base, range);
+ }
+
+ char fractionAsCharacter(float fraction, int base, float range) {
+ if (fraction > 0.9999f)
+ fraction = 0.9999f;
+ int ich = (int) (fraction * range + base);
+ if (ich < base)
+ ich = base;
+ if (ich == 92)
+ ich = 33; // \ --> !
+ if (logMessages)
+ System.out.println("fac: " + fraction + " --> " + ich + " " + (char)
ich);
+ return (char) ich;
+ }
+
final Point3f voxelOrigin = new Point3f();
final Point3f voxelT = new Point3f();
final Point3f pointA = new Point3f();
final Point3f pointB = new Point3f();
- // edgeVector should be a table lookup based upon edge number
- // vectors should be derived from the volumetric vectors in the file
final Vector3f edgeVector = new Vector3f();
void calcVertexPoints(int vertexA, int vertexB) {
pointA.add(voxelOrigin, voxelVertexVectors[vertexA]);
pointB.add(voxelOrigin, voxelVertexVectors[vertexB]);
- /*
- System.out.println("calcVertexPoints(" + vertexA + "," + vertexB + ")\n" +
- " pointA=" + pointA +
- " pointB=" + pointB);
- */
}
void calcVoxelOrigin(int x, int y, int z) {
voxelOrigin.scaleAdd(x, volumetricVectors[0], volumetricOrigin);
voxelOrigin.scaleAdd(y, volumetricVectors[1], voxelOrigin);
voxelOrigin.scaleAdd(z, volumetricVectors[2], voxelOrigin);
- /*
- System.out.println("voxelOrigin=" + voxelOrigin);
- */
}
- void addEdgePoint(Point3f point) {
- if (edgePoints == null)
- edgePoints = new Point3f[256];
- else if (edgePointCount == edgePoints.length)
- edgePoints = (Point3f[]) Util.doubleLength(edgePoints);
- edgePoints[edgePointCount++] = new Point3f(point);
+ void addEdgeInfo(int x, int y, int z, int vertexA, int vertexB) {
+ if (edgeInfo == null)
+ edgeInfo = new int[256][];
+ else if (edgeCount == edgeInfo.length)
+ edgeInfo = (int[][]) Util.doubleLength(edgeInfo);
+ int i = edgeCount++;
+ edgeInfo[i] = new int[6];
+ edgeInfo[i][0] = x + cubeVertexOffsets[vertexA].x;
+ edgeInfo[i][1] = y + cubeVertexOffsets[vertexA].y;
+ edgeInfo[i][2] = z + cubeVertexOffsets[vertexA].z;
+ edgeInfo[i][3] = x + cubeVertexOffsets[vertexB].x;
+ edgeInfo[i][4] = y + cubeVertexOffsets[vertexB].y;
+ edgeInfo[i][5] = z + cubeVertexOffsets[vertexB].z;
}
final static Point3i[] cubeVertexOffsets = { new Point3i(0, 0, 0),
@@ -1135,9 +1163,183 @@
{ 1, 3, 8, 9, 1, 8 }, { 0, 9, 1 }, { 0, 3, 8 }, null };
////////////////////////////////////////////////////////////////
- // color scale stuff
+ // JVXL colors and normalization
////////////////////////////////////////////////////////////////
+ void setJvxlColixes(Mesh mesh, String scaleName) throws Exception {
+ int vertexCount = mesh.vertexCount;
+ short[] colixes = mesh.vertexColixes;
+ System.out.println("setting colors: minRange=" + minRange + " maxRange="
+ + maxRange);
+ fractionData = "";
+ fractionPtr = 0;
+ if (colixes == null)
+ mesh.vertexColixes = colixes = new short[vertexCount];
+ for (int i = 0; i < vertexCount; i++) {
+ float fraction = getNextFraction(colorFractionBase, colorFractionRange,
+ 0.5f);
+ colixes[i] = viewer.getColixFromPalette(fraction, 0f, 1f, scaleName);
+
+ //System.out.println("setJvxlColixes " + fraction + " "
+ // +" "+viewer.colorManager.quantize(fraction,0f,
1f,(int)colorFractionRange));
+ if (mesh.hasGridPoints) {
+ colixes[++i] = viewer.getColixFromPalette(0.2f, 0f, 1f, scaleName);
+ colixes[++i] = viewer.getColixFromPalette(0.8f, 0f, 1f, scaleName);
+ }
+ }
+ }
+
+ void initializeMesh(boolean use2Sided) {
+ int vertexCount = currentMesh.vertexCount;
+ Vector3f[] vectorSums = new Vector3f[vertexCount];
+
+ /*
+ * OK, so if there is an associated grid point (because the
+ * point is so close to one), we now declare that associated
+ * point to be used for the vectorSum instead of a new,
+ * independent one for the point itself.
+ *
+ * Bob Hanson, 05/2006
+ *
+ * 2-sided normixes don't seem to be necessary
+ *
+ */
+
+ for (int i = vertexCount; --i >= 0;) {
+ vectorSums[i] = (assocGridPointMap.containsKey("" + i) ? (Vector3f)
assocGridPointNormals
+ .get((String) assocGridPointMap.get("" + i))
+ : new Vector3f());
+ }
+ currentMesh.sumVertexNormals(vectorSums);
+ short[] norm = currentMesh.normixes = new short[vertexCount];
+ if (use2Sided)
+ for (int i = vertexCount; --i >= 0;)
+ norm[i] = g3d.get2SidedNormix(vectorSums[i]);
+ else
+ for (int i = vertexCount; --i >= 0;)
+ norm[i] = g3d.getNormix(vectorSums[i]);
+ }
+
+ Hashtable assocGridPointMap;
+ Hashtable assocGridPointNormals;
+
+ int addVertexCopy(Point3f vertex, boolean iHaveAssociation, String sKey) {
+ int vPt = currentMesh.addVertexCopy(vertex);
+ if (vPt == 0) {
+ assocGridPointMap = new Hashtable();
+ assocGridPointNormals = new Hashtable();
+ }
+ if (associateNormals && iHaveAssociation) {
+ assocGridPointMap.put("" + vPt, sKey);
+ if (!assocGridPointNormals.containsKey(sKey))
+ assocGridPointNormals.put(sKey, new Vector3f(0, 0, 0));
+ }
+ return vPt;
+ }
+
+ ////////// JVXL FILE WRITING ////////////
+
+ String getJvxlFile(Mesh mesh, String msg) {
+ String data = mesh.jvxlFileHeader;
+ data += "# " + msg + "\n" + mesh.cutoff + " ";
+ String compressedData = "";
+ if (thePlane == null) {
+ compressedData = mesh.edgeData + mesh.colorData;
+ data += mesh.surfaceData.length() + " " + (mesh.edgeData.length() - 1)
+ + " " + (mesh.colorData.length() - 1);
+ } else {
+ data += "-1 -1 " + (mesh.colorData.length() - 1) + " " + thePlane.x + " "
+ + thePlane.y + " " + thePlane.z + " " + thePlane.w + " PLANE "
+ + thePlane;
+ compressedData = compressString(mesh.colorData);
+ }
+ if (!isJvxl)
+ data += " compressionRatio="
+ + (int) (mesh.nBytes * 1f / (mesh.surfaceData.length() +
compressedData
+ .length())) + ":1";
+ data += "\n" + (thePlane == null ? mesh.surfaceData : "") + compressedData;
+ if (msg != null)
+ data += "#-------end of jvxl file " + msg + " data-------\n";
+ return data;
+ }
+
+ String compressString(String data) {
+ /* just a simple compression, but allows 2000-6000:1 CUBE:JVXL for planes!
+ *
+ * "X~nnn " means "nnn copies of character X"
+ *
+ * ########## becomes "#~10 "
+ * ~ becomes "~~"
+ *
+ */
+ if (logCompression)
+ System.out.println(data.length() + " compressing\n" + data);
+ String dataOut = "";
+ String dataBuffer = "";
+ char chLast = '\0';
+ data += '\0';
+ int nLast = 0;
+ for (int i = 0; i < data.length(); i++) {
+ char ch = data.charAt(i);
+ if (ch == chLast) {
+ ++nLast;
+ dataBuffer += ch;
+ if (ch != '~')
+ ch = '\0';
+ } else if (nLast > 0) {
+ dataOut += (nLast < 4 || chLast == '~' || chLast == ' '
+ || chLast == '\t' ? dataBuffer : "~" + nLast + " ");
+ dataBuffer = "";
+ nLast = 0;
+ }
+ if (ch != '\0') {
+ dataOut += ch;
+ chLast = ch;
+ }
+ }
+ if (logCompression) {
+ System.out.println(dataOut.length() + "\n" + dataOut);
+ data = uncompressString(dataOut);
+ System.out.println(data.length() + " uncompressing\n" + data);
+ }
+ return dataOut;
+ }
+
+ String uncompressString(String data) {
+ if (data.indexOf("~") < 0)
+ return data;
+ if (logCompression)
+ System.out.println(data.length() + " uncompressing\n" + data);
+ String dataOut = "";
+ char chLast = '\0';
+ for (int i = 0; i < data.length(); i++) {
+ char ch = data.charAt(i);
+ if (ch == '~') {
+ int nChar = parseInt(data, ++i);
+ if (nChar == Integer.MIN_VALUE) {
+ if (chLast == '~') {
+ dataOut += '~';
+ while ((ch = data.charAt(++i)) == '~')
+ dataOut += '~';
+ } else {
+ System.out.println("Error uncompressing string "
+ + data.substring(0, i) + "?");
+ }
+ } else {
+ for (int c = 0; c < nChar; c++)
+ dataOut += chLast;
+ i = ichNextParse;
+ }
+ } else {
+ dataOut += ch;
+ chLast = ch;
+ }
+ }
+ if (logCompression)
+ System.out.println(dataOut.length() + "\n" + dataOut);
+ return dataOut;
+ }
+
void applyColorScale(float min, float max, String scaleName) {
if (currentMesh != null)
applyColorScale(currentMesh, min, max, scaleName);
@@ -1171,23 +1373,6 @@
return max;
}
- void setJvxlColixes(Mesh mesh, String scaleName) throws Exception {
- int vertexCount = mesh.vertexCount;
- short[] colixes = mesh.vertexColixes;
- strFractionTemp = "";
- fractionData = "";
- if (colixes == null)
- mesh.vertexColixes = colixes = new short[vertexCount];
- for (int i = 0; i < vertexCount; i++) {
- float fraction = getNextFraction(colorFractionBase, colorFractionRange);
- colixes[i] = viewer.getColixFromPalette(fraction, 0f, 1f, scaleName);
- if (addGridPoints) {
- colixes[++i] = viewer.getColixFromPalette(0.2f, 0f, 1f, scaleName);
- colixes[++i] = viewer.getColixFromPalette(0.8f, 0f, 1f, scaleName);
- }
- }
- }
-
void applyColorScale(Mesh mesh, float min, float max, String scaleName) {
int vertexCount = mesh.vertexCount;
Point3f[] vertexes = mesh.vertices;
@@ -1204,9 +1389,12 @@
if (value >= max) {
value = min + diff * 0.9999f;
}
- int ich = (int) ((value - min) / diff * colorFractionRange +
colorFractionBase);
+ float fraction = (value - min) / diff;
+ int ich = colorFractionBase + (int) (fraction * colorFractionRange);
list += (char) ich;
colixes[i] = viewer.getColixFromPalette(value, min, max, scaleName);
+ //System.out.println("applycolor " + fraction + " " +
(((int)ich)-colorFractionBase)
+ // +"
"+viewer.colorManager.quantize(value,min,max,(int)colorFractionRange));
}
mesh.colorData = list + "\n";
}
@@ -1308,53 +1496,6 @@
delta = 0.5f;
}
return valueDown + delta * valueDelta;
- }
- void initializeMesh(boolean use2Sided) {
- int vertexCount = currentMesh.vertexCount;
- Vector3f[] vectorSums = new Vector3f[vertexCount];
-
- /*
- * OK, so if there is an associated grid point (because the
- * point is so close to one), we now declare that associated
- * point to be used for the vectorSum instead of a new,
- * independent one for the point itself.
- *
- * Bob Hanson, 05/2006
- *
- * 2-sided normixes don't seem to be necessary
- *
- */
-
- for (int i = vertexCount; --i >= 0;) {
- vectorSums[i] = (assocGridPointMap.containsKey("" + i) ? (Vector3f)
assocGridPointNormals
- .get((String) assocGridPointMap.get("" + i))
- : new Vector3f());
- }
- currentMesh.sumVertexNormals(vectorSums);
- short[] norm = currentMesh.normixes = new short[vertexCount];
- if (use2Sided)
- for (int i = vertexCount; --i >= 0;)
- norm[i] = g3d.get2SidedNormix(vectorSums[i]);
- else
- for (int i = vertexCount; --i >= 0;)
- norm[i] = g3d.getNormix(vectorSums[i]);
}
-
- Hashtable assocGridPointMap;
- Hashtable assocGridPointNormals;
-
- int addVertexCopy(Point3f vertex, boolean iHaveAssociation, String sKey) {
- int vPt = currentMesh.addVertexCopy(vertex);
- if (vPt == 0) {
- assocGridPointMap = new Hashtable();
- assocGridPointNormals = new Hashtable();
- }
- if (associateNormals && iHaveAssociation) {
- assocGridPointMap.put("" + vPt, sKey);
- if (!assocGridPointNormals.containsKey(sKey))
- assocGridPointNormals.put(sKey, new Vector3f(0, 0, 0));
- }
- return vPt;
- }
}
Modified: branches/bob200603/Jmol/src/org/jmol/viewer/MeshCollection.java
===================================================================
--- branches/bob200603/Jmol/src/org/jmol/viewer/MeshCollection.java
2006-05-28 03:35:37 UTC (rev 5184)
+++ branches/bob200603/Jmol/src/org/jmol/viewer/MeshCollection.java
2006-05-28 03:37:57 UTC (rev 5185)
@@ -36,11 +36,11 @@
Mesh[] meshes = new Mesh[4];
Mesh currentMesh;
boolean isValid = false;
-
+
void initShape() {
colix = Graphics3D.ORANGE;
}
-
+
void setProperty(String propertyName, Object value, BitSet bs) {
/*
@@ -177,8 +177,13 @@
currentMesh = meshes[meshCount++] = new Mesh(viewer, meshID, g3d, colix);
}
+ String line;
int ichNextParse;
+ float parseFloat() {
+ return parseFloat(line, ichNextParse);
+ }
+
float parseFloat(String str) {
return parseFloatChecked(str, 0, str.length());
}
@@ -260,6 +265,10 @@
return value;
}
+ int parseInt() {
+ return parseInt(line, ichNextParse);
+ }
+
int parseInt(String str) {
return parseIntChecked(str, 0, str.length());
}
Modified: branches/bob200603/Jmol/src/org/jmol/viewer/MeshRenderer.java
===================================================================
--- branches/bob200603/Jmol/src/org/jmol/viewer/MeshRenderer.java
2006-05-28 03:35:37 UTC (rev 5184)
+++ branches/bob200603/Jmol/src/org/jmol/viewer/MeshRenderer.java
2006-05-28 03:37:57 UTC (rev 5185)
@@ -38,7 +38,6 @@
if (vertexCount == 0)
return;
Point3f[] vertices = mesh.vertices;
-
Point3i[] screens = viewer.allocTempScreens(vertexCount);
for (int i = vertexCount; --i >= 0;)
@@ -48,6 +47,8 @@
if (mesh.showPoints)
renderPoints(mesh, screens, vertexCount);
+ if (iShowNormals)
+ renderNormals(mesh, screens, vertexCount);
if (mesh.drawTriangles)
renderTriangles(mesh, screens, false);
if (mesh.fillTriangles)
@@ -56,16 +57,26 @@
viewer.freeTempScreens(screens);
}
- final Point3f ptTemp = new Point3f();
- final Point3i ptTempi = new Point3i();
void renderPoints(Mesh mesh, Point3i[] screens, int vertexCount) {
short colix = mesh.colix;
short[] vertexColixes = mesh.vertexColixes;
- //System.out.println("mesh renderPoints: " + vertexCount);
- for (int i = vertexCount; --i >= 0;) {
+ for (int i = vertexCount; --i >= 0;)
g3d.fillSphereCentered(vertexColixes != null ? vertexColixes[i] : colix,
4, screens[i]);
- if (iShowNormals && (i % 3) == 0) { //investigate vertex normixes
+ if (mesh.hasGridPoints) {
+ for (int i = 1; i < vertexCount; i+=3)
+ g3d.fillCylinder(Graphics3D.GRAY, Graphics3D.ENDCAPS_SPHERICAL, 1,
+ screens[i], screens[i + 1]);
+ }
+ }
+
+
+ final Point3f ptTemp = new Point3f();
+ final Point3i ptTempi = new Point3i();
+ void renderNormals(Mesh mesh, Point3i[] screens, int vertexCount) {
+ //System.out.println("mesh renderPoints: " + vertexCount);
+ for (int i = vertexCount; --i >= 0;)
+ if ((i % 3) == 0) { //investigate vertex normixes
ptTemp.set(mesh.vertices[i]);
short n = mesh.normixes[i];
if (n < 0)
@@ -78,9 +89,6 @@
} catch (Exception e) {
}
}
-
- }
-
}
void renderTriangles(Mesh mesh, Point3i[] screens, boolean fill) {
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
_______________________________________________
Jmol-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jmol-commits