From: <ha...@us...> - 2006-03-12 03:18:51
|
Revision: 4570 Author: hansonr Date: 2006-03-11 19:18:39 -0800 (Sat, 11 Mar 2006) ViewCVS: http://svn.sourceforge.net/jmol/?rev=4570&view=rev Log Message: ----------- draw support for animation: (1) absolute [x,y,z] coordinates are "fixed" in space in all frames. (2) (atom sets) are calculated freshly for EACH frame unless the FIXED keyword is present. In that case, what is displayed is an average value for all frames. (3) [objectID] references are fixed or free to move, as defined in the initial "draw objectID" specification. (4) fixed coordinates and free (atom sets) can be mixed. Examples: load cyclohexane_movie.xyz draw axis1 250 (atomno=2) (atomno=5) #between two atoms draw axis2 200 (atomno=4 or atomno=3) (atomno=1 or atomno=6) #between two bonds draw axis2 200 FIXED (atomno=4 or atomno=3) (atomno=1 or atomno=6) #average position shown throughout animation draw axis2 200 [0.,0.,0.] (atomno=4 or atomno=3) (atomno=1 or atomno=6) # one fixed point and two moving points forming a triangle. animation on see http://www.stolaf.edu/people/hansonr/jmol/test/json/pmesh.htm Modified Paths: -------------- trunk/Jmol/src/org/jmol/viewer/Draw.java trunk/Jmol/src/org/jmol/viewer/DrawRenderer.java trunk/Jmol/src/org/jmol/viewer/Eval.java trunk/Jmol/src/org/jmol/viewer/Mesh.java trunk/Jmol/src/org/jmol/viewer/MeshRenderer.java trunk/Jmol/src/org/jmol/viewer/ModelManager.java trunk/Jmol/src/org/jmol/viewer/RepaintManager.java trunk/Jmol/src/org/jmol/viewer/Viewer.java Modified: trunk/Jmol/src/org/jmol/viewer/Draw.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Draw.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/Draw.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -24,25 +24,35 @@ package org.jmol.viewer; -import java.util.Hashtable; + import java.util.BitSet; -import java.util.Vector; import javax.vecmath.Point3f; import javax.vecmath.Vector3f; class Draw extends MeshCollection { - Point3f[] ptList = new Point3f[128]; + Point3f[] ptList = new Point3f[8]; + int[] ptIdentifiers = new int[8]; + BitSet[] ptBitSets = new BitSet[8]; Point3f xyz = new Point3f(); int ipt; int npoints = -1; + int nbitsets = 0; + int ncoord = 0; + int nidentifiers = 0; + boolean isFixed = false; float newScale; void setProperty(String propertyName, Object value, BitSet bs) { System.out.println("draw "+propertyName+" "+value); + if ("fixed" == propertyName) { + isFixed = ((Boolean)value).booleanValue(); + return; + } + if ("points" == propertyName) { - ipt = npoints = 0; + ipt = npoints = ncoord = nbitsets = nidentifiers = 0; newScale = ((Integer)value).floatValue()/100; if (newScale == 0) newScale = 1; @@ -52,23 +62,21 @@ if ("scale" == propertyName) { newScale = ((Integer)value).floatValue()/100; if (newScale == 0) - return; + newScale = 0.01f; //very tiny but still sizable; if (currentMesh != null) { //no points in this script statement - scaleDrawing(); + currentMesh.scaleDrawing(newScale); currentMesh.initialize(); } return; } if ("identifier" == propertyName) { - int meshIndex = getMeshIndex((String)value); + String meshID = (String)value; + int meshIndex = getMeshIndex(meshID); if (meshIndex >= 0) { - System.out.println(npoints+" lt? " + ptList.length); - System.out.println(meshIndex+" lt? " + meshes.length); - ptList[npoints++] = new Point3f(meshes[meshIndex].ptCenter); - System.out.println("OK"); - System.out.println(npoints + " " + ptList[npoints-1]); + ptIdentifiers[nidentifiers++] = meshIndex; + npoints++; } else { System.out.println("draw identifier " + value + " not found"); } @@ -83,30 +91,36 @@ xyz.y = x; } else if (ipt == 2) { xyz.z = x; - ptList[npoints++] = new Point3f(xyz); - System.out.println(npoints + " " + ptList[npoints-1]); - } + ptList[ncoord++] = new Point3f(xyz); + npoints++; + System.out.println(npoints + " " + ptList[ncoord-1]); + } ipt = (ipt + 1) % 3; return; } if ("atomSet" == propertyName) { - ptList[npoints++] = new Point3f((Point3f)value); - System.out.println(npoints + " " + ptList[npoints-1]); + if (((BitSet)value).cardinality() == 0) + return; + ptBitSets[nbitsets++] = (BitSet)value; + npoints++; + System.out.println(npoints + " " + ptBitSets[nbitsets-1]); return; } if ("set" == propertyName) { isValid = setDrawing(); if(isValid) { - scaleDrawing(); + currentMesh.scaleDrawing(newScale); currentMesh.initialize(); currentMesh.visible = true; } npoints = -1; //for later scaling return; } - if ("meshID" == propertyName) + if ("meshID" == propertyName) { npoints = -1; - + isFixed = false; + } + super.setProperty(propertyName, value, bs); } @@ -116,44 +130,78 @@ currentMesh.clear("draw"); if (npoints == 0) return false; - for (int i = 0; i < npoints; i++) - currentMesh.addVertexCopy(ptList[i]); - currentMesh.setPolygonCount(1); - int n = currentMesh.vertexCount; - currentMesh.ptCenter = centerOf(currentMesh.vertices, n); - int nPoints = n; - if (n < 3) - n = 3; - currentMesh.polygonIndexes[0] = new int[n]; - for (int i = 0; i < n; i++) - currentMesh.polygonIndexes[0][i] = (i >= nPoints ? nPoints - 1 : i); + int nPoly = 0; + int modelCount = viewer.getModelCount(); + if (nbitsets == 0 && nidentifiers == 0 || modelCount < 2) + isFixed = true; + if (isFixed) { + currentMesh.setPolygonCount(1); + currentMesh.ptCenters = null; + currentMesh.visibilityFlags = null; + nPoly = setVerticesAndPolygons(-1, nPoly); + } else { + currentMesh.setPolygonCount(modelCount); + currentMesh.ptCenters = new Point3f[modelCount]; + currentMesh.visibilityFlags = new int[modelCount]; + for (int iModel = 0; iModel < modelCount; iModel++) { + int n0 = currentMesh.vertexCount; + nPoly = setVerticesAndPolygons(iModel, nPoly); + currentMesh.setCenter(iModel); + } + } + currentMesh.setCenter(-1); return true; } - void scaleDrawing() { - if (currentMesh == null || newScale == 0 || - currentMesh.vertexCount == 0 || currentMesh.scale == newScale) - return; - Vector3f diff = new Vector3f(); - float f = newScale / currentMesh.scale; - System.out.println("scaledrawing " +f); - currentMesh.scale = newScale; - for (int i = currentMesh.vertexCount; --i >= 0;) { - diff.sub(currentMesh.vertices[i], currentMesh.ptCenter); - diff.scale(f); - diff.add(currentMesh.ptCenter); - currentMesh.vertices[i].set(diff); + int setVerticesAndPolygons(int iModel, int nPoly) { + int nPoints = ncoord; + // [x,y,z] points are already defined in ptList + if (iModel < 0) { + // add in [drawID] references as overall centers + for (int i = 0; i < nidentifiers; i++) + ptList[nPoints++] = meshes[ptIdentifiers[i]].ptCenter; + // add in (atom set) references as overall centers + for (int i = 0; i < nbitsets; i++) + ptList[nPoints++] = viewer.getAtomSetCenter(ptBitSets[i]); + } else { + // [drawID] references may be fixed or not + for (int i = 0; i < nidentifiers; i++) { + if (meshes[ptIdentifiers[i]].ptCenters == null || + meshes[ptIdentifiers[i]].ptCenters[iModel] == null) { + ptList[nPoints++] = meshes[ptIdentifiers[i]].ptCenter; + } else { + ptList[nPoints++] = meshes[ptIdentifiers[i]].ptCenters[iModel]; + } + } + // (atom set) references must be filtered for relevant model + // note that if a model doesn't have a relevant point, one may + // get a line instead of a plane, a point instead of a line, etc. + BitSet bsModel = viewer.getModelAtomBitSet(iModel); + for (int i = 0; i < nbitsets; i++) { + BitSet bs = (BitSet)ptBitSets[i].clone(); + bs.and(bsModel); + if (bs.cardinality() > 0) { + ptList[nPoints++] = viewer.getAtomSetCenter(bs); + } + } } + return currentMesh.setPolygon(ptList, nPoints, nPoly); } - - Point3f centerOf(Point3f[] points, int nPoints) { - Point3f center = new Point3f(0, 0, 0); - if (nPoints == 0) return center; - for (int i = nPoints; --i >= 0;) { - center.add(points[i]); + + void setVisibilityFlags(BitSet bs) { + /* + * set all fixed objects visible; others based on model being displayed + * note that this is NOT done with atoms and bonds, because they have mads. + * When you say "frame 0" it is just turning on all the mads. + */ + int modelCount = viewer.getModelCount(); + for (int i = meshCount; --i >= 0; ) { + if (meshes[i].visibilityFlags == null) + continue; + for (int iModel = modelCount; --iModel >= 0; ) { + meshes[i].visibilityFlags[iModel] = (bs.get(iModel) ? 1 : 0); + } } - center.scale(1.0F / nPoints); - return center; } - + } Modified: trunk/Jmol/src/org/jmol/viewer/DrawRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/DrawRenderer.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/DrawRenderer.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -26,6 +26,12 @@ class DrawRenderer extends MeshRenderer { void render() { + /* + * Each drawn object, draw.meshes[i], may consist of several + * polygons, one for each MODEL FRAME. Or, it may be "fixed" + * and only contain one single polygon. + * + */ Draw draw = (Draw)shape; if (!draw.isValid) return; Modified: trunk/Jmol/src/org/jmol/viewer/Eval.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Eval.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/Eval.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -3443,7 +3443,6 @@ data = viewer.simpleReplace(data, " ", "\n"); propertyName = "bufferedReaderOnePerLine"; } - data = viewer.simpleReplace(data, "[", " "); data = viewer.simpleReplace(data, ",", " "); data = viewer.simpleReplace(data, "]", " "); @@ -3499,7 +3498,7 @@ boolean havePoints = false; boolean isInitialized = false; int intScale = 0; - BitSet bs = null; + boolean isFixed = false; for (int i = 1; i < statementLength; ++i) { String propertyName = null; Object propertyValue = null; @@ -3528,15 +3527,18 @@ break; case Token.expressionBegin: propertyName = "atomSet"; - bs = expression(statement, i + 1); + propertyValue = expression(statement, i + 1); i = endOfExpression; havePoints = true; - propertyValue = new Point3f(viewer.getAtomSetCenter(bs)); nCoord += 3; break; case Token.identifier: propertyName = "meshID"; propertyValue = token.value; + if (((String)propertyValue).equalsIgnoreCase("FIXED")) { + isFixed = true; + continue; + } break; case Token.dots: propertyValue = Boolean.TRUE; @@ -3566,6 +3568,9 @@ if (havePoints && ! isInitialized) { viewer.setShapeProperty(JmolConstants.SHAPE_DRAW, "points", new Integer(intScale)); + if (isFixed || viewer.getModelCount() == 1) + viewer.setShapeProperty(JmolConstants.SHAPE_DRAW, + "fixed", new Boolean(true)); isInitialized = true; } viewer.setShapeProperty(JmolConstants.SHAPE_DRAW, Modified: trunk/Jmol/src/org/jmol/viewer/Mesh.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Mesh.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/Mesh.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -38,17 +38,18 @@ short colix; short[] vertexColixes; Graphics3D g3d; - int vertexCount; Point3f[] vertices; short[] normixes; int polygonCount; - int[][] polygonIndexes; + int[][] polygonIndexes = null; float scale = 1; Point3f ptCenter = new Point3f(0,0,0); + Point3f ptCenters[]; String meshType = null; + int[] visibilityFlags = null; boolean showPoints = false; boolean drawTriangles = false; @@ -61,7 +62,6 @@ this.colix = colix; } - void clear(String meshType) { vertexCount = polygonCount = 0; scale = 1; @@ -128,7 +128,8 @@ void setPolygonCount(int polygonCount) { this.polygonCount = polygonCount; - polygonIndexes = new int[polygonCount][]; + if (polygonIndexes == null || polygonCount > polygonIndexes.length) + polygonIndexes = new int[polygonCount][]; } int addVertexCopy(Point3f vertex) { @@ -169,4 +170,89 @@ Hashtable getShapeDetail() { return null; } + + boolean isPolygonDisplayable(int index) { + return (visibilityFlags == null || + visibilityFlags[index] != 0); + } + + int setPolygon(Point3f[] ptList, int nVertices, int nPoly) { + /* + * designed for Draw + * + * for now, just add all new vertices. It's simpler this way + * though a bit redundant. We could reuse the fixed ones -- no matter + * + */ + if (nVertices == 0) return nPoly; + int nVertices0 = vertexCount; + for (int i = 0; i < nVertices; i++) { + addVertexCopy(ptList[i]); + } + int npoints = (nVertices < 3 ? 3 : nVertices); + setPolygonCount(nPoly + 1); + polygonIndexes[nPoly] = new int[npoints]; + for (int i = 0; i < npoints; i++) { + polygonIndexes[nPoly][i] = nVertices0 + (i < nVertices ? i : nVertices - 1); + } + return nPoly + 1; + } + + void scaleDrawing(float newScale) { + /* + * allows for Draw to scale object + * have to watch out for double-listed vertices + * + */ + if (newScale == 0 || vertexCount == 0 || scale == newScale) + return; + Vector3f diff = new Vector3f(); + float f = newScale / scale; + scale = newScale; + int iptlast = -1; + int ipt = 0; + for (int i = polygonCount; --i >= 0;) { + Point3f center = (ptCenters == null ? ptCenter : ptCenters[i]); + iptlast = -1; + for (int iV = polygonIndexes[i].length; --iV >= 0;) { + ipt = polygonIndexes[i][iV]; + if (ipt == iptlast) + continue; + iptlast = ipt; + diff.sub(vertices[ipt], center); + diff.scale(f); + diff.add(center); + vertices[ipt].set(diff); + } + } + } + + void setCenter(int iModel) { + Point3f center = new Point3f(0, 0, 0); + int iptlast = -1; + int ipt = 0; + int n = 0; + for (int i = polygonCount; --i >= 0;) { + if (iModel >=0 && i != iModel) + continue; + iptlast = -1; + for (int iV = polygonIndexes[i].length; --iV >= 0;) { + ipt = polygonIndexes[i][iV]; + if (ipt == iptlast) + continue; + iptlast = ipt; + center.add(vertices[ipt]); + n++; + } + if (i == iModel || i == 0) { + center.scale(1.0f / n); + break; + } + } + if (iModel < 0){ + ptCenter = center; + } else { + ptCenters[iModel] = center; + } + } } Modified: trunk/Jmol/src/org/jmol/viewer/MeshRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/MeshRenderer.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/MeshRenderer.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -67,6 +67,8 @@ short colix = mesh.colix; short[] vertexColixes = mesh.vertexColixes; for (int i = mesh.polygonCount; --i >= 0; ) { + if (! mesh.isPolygonDisplayable(i)) + continue; int[] vertexIndexes = polygonIndexes[i]; if (vertexIndexes != null) { int iA = vertexIndexes[0]; @@ -82,12 +84,8 @@ } if (iB == iC) { - if (iA == iB) { - g3d.fillSphereCentered(colixA, 16, screens[iA].x, screens[iA].y, screens[iA].z); - } else { - g3d.fillCylinder(colixA, Graphics3D.ENDCAPS_SPHERICAL, 2, - screens[iA], screens[iB]); - } + g3d.fillCylinder(colixA, Graphics3D.ENDCAPS_SPHERICAL, + (iA == iB ? 6 : 2), screens[iA], screens[iB]); } else if (vertexIndexes.length == 3) { if (fill) g3d.fillTriangle(screens[iA], colixA, normixes[iA], Modified: trunk/Jmol/src/org/jmol/viewer/ModelManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/ModelManager.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/ModelManager.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -424,6 +424,16 @@ return (frame == null) ? null : frame.getVisibleSet(); } + BitSet getModelAtomBitSet(int modelIndex) { + BitSet bs = new BitSet(); + int atomCount = getAtomCount(); + Atom[] atoms = frame.atoms; + for (int i = 0; i < atomCount; i++) + if (atoms[i].modelIndex == modelIndex) + bs.set(i); + return bs; + } + void calcSelectedGroupsCount(BitSet bsSelected) { if (frame != null) frame.calcSelectedGroupsCount(bsSelected); @@ -1028,6 +1038,10 @@ boolean showHydrogens = viewer.getShowHydrogens(); int ballVisibilityFlag = viewer.getShapeVisibilityFlag(JmolConstants.SHAPE_BALLS); int haloVisibilityFlag = viewer.getShapeVisibilityFlag(JmolConstants.SHAPE_HALO); + BitSet bs = viewer.getVisibleFramesBitSet(); + Draw draw = (Draw) frame.shapes[JmolConstants.SHAPE_DRAW]; + if (draw != null) + draw.setVisibilityFlags(bs); for (int i = frame.atomCount; --i >= 0; ) { Atom atom = atoms[i]; atom.shapeVisibilityFlags &= ( Modified: trunk/Jmol/src/org/jmol/viewer/RepaintManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/RepaintManager.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/RepaintManager.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -28,17 +28,19 @@ import java.awt.Image; import java.awt.Rectangle; import java.util.Hashtable; +import java.util.BitSet; class RepaintManager { Viewer viewer; FrameRenderer frameRenderer; - + RepaintManager(Viewer viewer) { this.viewer = viewer; frameRenderer = new FrameRenderer(viewer); } + BitSet bsVisibleFrames = null; int displayModelIndex = 0; boolean setDisplayModelIndex(int modelIndex) { Frame frame = viewer.getFrame(); @@ -50,9 +52,26 @@ displayModelIndex = modelIndex; viewer.setTainted(true); viewer.setStatusFrameChanged(modelIndex); + bsVisibleFrames = getAnimationRangeVisible(); return true; } + BitSet getVisibleFramesBitSet() { + return bsVisibleFrames; + } + + BitSet getAnimationRangeVisible() { + BitSet bs = new BitSet(); + if (displayModelIndex >= 0) { + bs.set(displayModelIndex); + return bs; + } + for (int i = firstModelIndex; i != lastModelIndex; i += frameStep) + bs.set(i); + bs.set(lastModelIndex); + return bs; + } + AnimationThread animationThread; boolean wireframeRotating = false; Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Viewer.java 2006-03-11 16:46:36 UTC (rev 4569) +++ trunk/Jmol/src/org/jmol/viewer/Viewer.java 2006-03-12 03:18:39 UTC (rev 4570) @@ -1253,6 +1253,10 @@ return modelManager.frame != null; } + BitSet getModelAtomBitSet(int modelIndex) { + return modelManager.getModelAtomBitSet(modelIndex); + } + Object getClientFile() { // DEPRECATED - use getExportJmolAdapter() return null; @@ -1689,6 +1693,10 @@ void setAnimationRange(int modelIndex1, int modelIndex2) { repaintManager.setAnimationRange(modelIndex1, modelIndex2); } + + BitSet getVisibleFramesBitSet() { + return repaintManager.getVisibleFramesBitSet(); + } boolean isAnimationOn() { return repaintManager.animationOn; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |