Revision: 20547
          http://sourceforge.net/p/jmol/code/20547
Author:   hansonr
Date:     2015-06-04 16:54:12 +0000 (Thu, 04 Jun 2015)
Log Message:
-----------
Jmol.___JmolVersion="14.3.14_2015.06.04"

new feature: load "...." FILL BOUNDBOX
new feature: load "...." FILL UNITCELL
new feature: load "...." FILL UNITCELL [o a b c]
new feature: load "...." FILL BOUNDBOX [o a b c]

 -- in development
 -- loads a crystal structure such that a given volume is packed
 -- volume can be the current boundbox or the current unitcell or a specified 
origin and a,b,c vectors
 -- if BOUNDBOX, sets the current boundbox after loading to be current boundbox

Modified Paths:
--------------
    trunk/Jmol/src/org/jmol/adapter/readers/aflow/AFLOWReader.java
    trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
    trunk/Jmol/src/org/jmol/adapter/smarter/XtalSymmetry.java
    trunk/Jmol/src/org/jmol/modelset/ModelSet.java
    trunk/Jmol/src/org/jmol/script/ScriptEval.java
    trunk/Jmol/src/org/jmol/script/ScriptParam.java
    trunk/Jmol/src/org/jmol/scriptext/CmdExt.java
    trunk/Jmol/src/org/jmol/scriptext/IsoExt.java
    trunk/Jmol/src/org/jmol/thread/MoveToThread.java
    trunk/Jmol/src/org/jmol/util/BoxInfo.java
    trunk/Jmol/src/org/jmol/viewer/Jmol.properties
    trunk/Jmol/src/org/jmol/viewer/TransformManager.java

Modified: trunk/Jmol/src/org/jmol/adapter/readers/aflow/AFLOWReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/aflow/AFLOWReader.java      
2015-06-04 04:57:46 UTC (rev 20546)
+++ trunk/Jmol/src/org/jmol/adapter/readers/aflow/AFLOWReader.java      
2015-06-04 16:54:12 UTC (rev 20547)
@@ -113,6 +113,7 @@
     readPRE = checkFilterKey("PRE");
 //    readPOST = !checkFilterKey("NOPOST");
     String s = getFilter("CA=");
+    forcePacked = !checkFilterKey("NOPACK");
     if (s != null)
       fracA = parseFloatStr(s.substring(1));
     s = getFilter("LIST=");

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java        
2015-06-04 04:57:46 UTC (rev 20546)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java        
2015-06-04 16:54:12 UTC (rev 20547)
@@ -46,6 +46,7 @@
 import javajs.util.OC;
 import javajs.util.PT;
 import javajs.util.Quat;
+import javajs.util.T3;
 import javajs.util.V3;
 import javajs.util.Lst;
 import javajs.util.SB;
@@ -159,6 +160,7 @@
 
   // protected/public state variables
   public int[] latticeCells;
+  public T3[] fillRange;
   public boolean doProcessLines;
   public boolean iHaveUnitCell;
   public boolean iHaveSymmetryOperators;
@@ -375,36 +377,40 @@
   protected void finalizeReaderASCR() throws Exception {
     isFinalized = true;
     if (asc.atomSetCount > 0) {
-      if (asc.atomSetCount == 1) 
+      if (asc.atomSetCount == 1)
         asc.setCurrentModelInfo("dbName", htParams.get("dbName"));
       applySymmetryAndSetTrajectory();
       asc.finalizeStructures();
       if (doCentralize)
         asc.centralize();
+      if (fillRange != null)
+        asc.setInfo("boundbox", fillRange);
       Map<String, Object> info = asc.getAtomSetAuxiliaryInfo(0);
-      if (domains != null && info != null) {
-        asc.setGlobalBoolean(AtomSetCollection.GLOBAL_DOMAINS);
-        String s = ((SV) domains).getMapKeys(2, true);
-        int pt = s.indexOf("{ ", 2);
-        if (pt >= 0)
-          s = s.substring(pt + 2);
-        pt = s.indexOf("_metadata");
-        if (pt < 0)
-          pt = s.indexOf("metadata");
-        if (pt >= 0)
-          s = s.substring(0, pt);
-        s = PT.rep(PT.replaceAllCharacters(s, "{}", "").trim(), "\n", "\n  ")
-            + "\n\nUse SHOW DOMAINS for details.";
-        appendLoadNote("\nDomains loaded:\n   " + s);
-        for (int i = asc.atomSetCount; --i >= 0;) {
-          info = asc.getAtomSetAuxiliaryInfo(i);
-          info.put("domains", domains);
+      if (info != null) {
+        if (domains != null) {
+          asc.setGlobalBoolean(AtomSetCollection.GLOBAL_DOMAINS);
+          String s = ((SV) domains).getMapKeys(2, true);
+          int pt = s.indexOf("{ ", 2);
+          if (pt >= 0)
+            s = s.substring(pt + 2);
+          pt = s.indexOf("_metadata");
+          if (pt < 0)
+            pt = s.indexOf("metadata");
+          if (pt >= 0)
+            s = s.substring(0, pt);
+          s = PT.rep(PT.replaceAllCharacters(s, "{}", "").trim(), "\n", "\n  ")
+              + "\n\nUse SHOW DOMAINS for details.";
+          appendLoadNote("\nDomains loaded:\n   " + s);
+          for (int i = asc.atomSetCount; --i >= 0;) {
+            info = asc.getAtomSetAuxiliaryInfo(i);
+            info.put("domains", domains);
+          }
         }
-      }
-      if (validation != null && info != null) {
-        for (int i = asc.atomSetCount; --i >= 0;) {
-          info = asc.getAtomSetAuxiliaryInfo(i);
-          info.put("validation", validation);
+        if (validation != null) {
+          for (int i = asc.atomSetCount; --i >= 0;) {
+            info = asc.getAtomSetAuxiliaryInfo(i);
+            info.put("validation", validation);
+          }
         }
       }
     }
@@ -543,7 +549,7 @@
       strSupercell = (String) o;
     else
       ptSupercell = (P3) o;
-
+    fillRange = (T3[]) htParams.get("fillRange");
     // ptFile < 0 indicates just one file being read
     // ptFile >= 0 indicates multiple files are being loaded
     // if the file is not the first read in the LOAD command, then

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/XtalSymmetry.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/XtalSymmetry.java   2015-06-04 
04:57:46 UTC (rev 20546)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/XtalSymmetry.java   2015-06-04 
16:54:12 UTC (rev 20547)
@@ -223,7 +223,7 @@
         if (readerSymmetry != null)
           symmetry.setSpaceGroupFrom(readerSymmetry);
         //parameters are counts of unit cells as [a b c]
-        applySymmetryLattice(acr.ms, acr.strSupercell);
+        applySymmetryLattice();
         if (readerSymmetry != null && filterSymop == null)
           setAtomSetSpaceGroupName(readerSymmetry.getSpaceGroupName());
       }
@@ -247,12 +247,11 @@
     asc.setCurrentModelInfo("spaceGroup", spaceGroupName + "");
   }
 
-  private void applySymmetryLattice(MSInterface ms, String supercell)
+  private void applySymmetryLattice()
       throws Exception {
-
     if (!asc.coordinatesAreFractional || symmetry.getSpaceGroup() == null)
       return;
-
+    
     int maxX = latticeCells[0];
     int maxY = latticeCells[1];
     int maxZ = Math.abs(latticeCells[2]);
@@ -260,16 +259,18 @@
     BS bsAtoms = null;
     rminx = rminy = rminz = Float.MAX_VALUE;
     rmaxx = rmaxy = rmaxz = -Float.MAX_VALUE;
-    T3[] oabc = null;
+    T3[] oabc = acr.fillRange;
     P3 offset = null;
     P3 pt0 = null;
     nVib = 0;
     T3 va = null, vb = null, vc = null;
     baseSymmetry = symmetry;
-    if (supercell != null && supercell.indexOf(",") >= 0) {
+    String supercell = acr.strSupercell;
+    if (oabc != null || supercell != null && supercell.indexOf(",") >= 0) {
       // expand range to accommodate this alternative cell
       // oabc will be cartesian
-      oabc = symmetry.getV0abc(supercell);
+      if (oabc == null)
+        oabc = symmetry.getV0abc(supercell);
       if (oabc != null) {
         // set the bounds for atoms in the new unit cell
         // in terms of the old unit cell
@@ -376,7 +377,7 @@
       if (asc.bsAtoms == null)
         asc.bsAtoms = BSUtil.setAll(asc.ac);
       bsAtoms = asc.bsAtoms;
-      applyAllSymmetry(ms, null);
+      applyAllSymmetry(acr.ms, null);
       doPackUnitCell = doPack0;
 
       
@@ -394,7 +395,7 @@
       symmetry = getSymmetry();
       setUnitCell(new float[] { 0, 0, 0, 0, 0, 0, va.x, va.y, va.z,
           vb.x, vb.y, vb.z, vc.x, vc.y, vc.z }, null, offset);
-      setAtomSetSpaceGroupName(oabc == null ? "P1" : "cell=" + supercell);
+      setAtomSetSpaceGroupName(oabc == null || supercell == null ? "P1" : 
"cell=" + supercell);
       symmetry.setSpaceGroup(doNormalize);
       symmetry.addSpaceGroupOperation("x,y,z", 0);
 
@@ -421,7 +422,7 @@
     if (oabc == null) {
       minXYZ = new P3i();
       maxXYZ = P3i.new3(maxX, maxY, maxZ);
-      applyAllSymmetry(ms, bsAtoms);      
+      applyAllSymmetry(acr.ms, bsAtoms);      
     } else if (acr.forcePacked || doPackUnitCell) {
       // trim atom set based on original unit cell
       symmetry.setMinMaxLatticeParameters(minXYZ, maxXYZ);
@@ -439,6 +440,10 @@
     // but we leave matSupercell, because we might need it for vibrations in 
CASTEP
   }
 
+  /**
+   * range minima and maxima -- cartesians?
+   * 
+   */
   private float rminx, rminy, rminz, rmaxx, rmaxy, rmaxz;
 
   private void setSymmetryMinMax(P3 c) {
@@ -456,11 +461,6 @@
       rmaxz = c.z;
   }
 
-  private boolean isInSymmetryRange(P3 c) {
-    return (c.x >= rminx && c.y >= rminy && c.z >= rminz && c.x <= rmaxx
-        && c.y <= rmaxy && c.z <= rmaxz);
-  }
-
   private final P3 ptOffset = new P3();
 
   private P3 unitCellOffset;
@@ -806,13 +806,13 @@
         }
         if (acr.fixJavaFloat)
           PT.fixPtFloats(ptAtom, PT.FRACTIONAL_PRECISION);
-        P3 cartesian = P3.newP(ptAtom);
-        symmetry.toCartesian(cartesian, false);
+        P3 c = P3.newP(ptAtom); // cartesian position
+        symmetry.toCartesian(c, false);
         if (doPackUnitCell) {
           // note that COmmensurate structures may need 
           // modulation at this point.
-          symmetry.toUnitCell(cartesian, ptOffset);
-          ptAtom.setT(cartesian);
+          symmetry.toUnitCell(c, ptOffset);
+          ptAtom.setT(c);
           symmetry.toFractional(ptAtom, false);
           if (acr.fixJavaFloat)
             PT.fixPtFloats(ptAtom, PT.FRACTIONAL_PRECISION);
@@ -821,7 +821,7 @@
             continue;
         }
         if (checkSymmetryMinMax)
-          setSymmetryMinMax(cartesian);
+          setSymmetryMinMax(c);
         Atom special = null;
         if (checkDistances) {
 
@@ -829,7 +829,8 @@
            * same cartesian position.  
            */
           float minDist2 = Float.MAX_VALUE;
-          if (checkSymmetryRange && !isInSymmetryRange(cartesian))
+          if (checkSymmetryRange && (c.x < rminx || c.y < rminy || c.z < rminz 
+              || c.x > rmaxx || c.y > rmaxy || c.z > rmaxz))
             continue;
           int j0 = (checkAll ? asc.ac : pt0);
           String name = a.atomName;
@@ -838,7 +839,7 @@
             P3 pc = cartesians[j];
             if (pc == null)
               continue;
-            float d2 = cartesian.distanceSquared(pc);
+            float d2 = c.distanceSquared(pc);
             if (checkSpecial && d2 < 0.0001) {
               special = asc.atoms[firstSymmetryAtom + j];
               if ((special.atomName == null || special.atomName.equals(name))
@@ -878,7 +879,7 @@
           atom1.bsSymmetry = BSUtil.newAndSetBit(iCellOpPt + iSym);
           atom1.bsSymmetry.set(iSym);
           if (addCartesian)
-            cartesians[pt++] = cartesian;
+            cartesians[pt++] = c;
           Lst<Object> tensors = a.tensors;
           if (tensors != null) {
             atom1.tensors = null;
@@ -960,8 +961,10 @@
   }
 
   public T3 getOverallSpan() {
-    return  V3.newVsub(maxXYZ0, minXYZ0);
+    return (maxXYZ0 == null ? V3.new3(maxXYZ.x - minXYZ.x, maxXYZ.y - minXYZ.y,
+        maxXYZ.z - minXYZ.z) : V3.newVsub(maxXYZ0, minXYZ0));
   }
+  
   private int dtype = 3;
   private V3[] unitCellTranslations;
   private int latticeOp;

Modified: trunk/Jmol/src/org/jmol/modelset/ModelSet.java
===================================================================
--- trunk/Jmol/src/org/jmol/modelset/ModelSet.java      2015-06-04 04:57:46 UTC 
(rev 20546)
+++ trunk/Jmol/src/org/jmol/modelset/ModelSet.java      2015-06-04 16:54:12 UTC 
(rev 20547)
@@ -489,6 +489,9 @@
   }
 
   private SymmetryInterface pointGroup;
+
+  private BoxInfo defaultBBox;
+  
   private Object calculatePointGroupForFirstModel(BS bsAtoms,
                                                   boolean doAll,
                                                   boolean asDraw,
@@ -1028,9 +1031,7 @@
   }
 
   public P3 getBoundBoxCenter(int modelIndex) {
-    if (isJmolDataFrameForModel(modelIndex))
-      return new P3();
-    return boxInfo.getBoundBoxCenter();
+    return (isJmolDataFrameForModel(modelIndex) ? new P3() : 
boxInfo.getBoundBoxCenter());
   }
 
   public V3 getBoundBoxCornerVector() {
@@ -1041,7 +1042,7 @@
     return boxInfo.getBoundBoxVertices();
   }
 
-  public void setBoundBox(P3 pt1, P3 pt2, boolean byCorner, float scale) {
+  public void setBoundBox(T3 pt1, T3 pt2, boolean byCorner, float scale) {
     isBbcageDefault = false;
     bboxModels = null;
     bboxAtoms = null;
@@ -1090,11 +1091,13 @@
     return true;
   }
 
-  public float calcRotationRadius(int modelIndex, P3 center) {
+  public float calcRotationRadius(int modelIndex, P3 center, boolean 
useBoundBox) {
     if (isJmolDataFrameForModel(modelIndex)) {
       float r = am[modelIndex].defaultRotationRadius;
       return (r == 0 ? 10 : r);
     }
+    if (useBoundBox && getDefaultBoundBox() != null)
+      return defaultBBox.getMaxDim() / 2 * 1.2f;
     float maxRadius = 0;
     for (int i = ac; --i >= 0;) {
       if (isJmolDataFrameForAtom(at[i])) {
@@ -1117,16 +1120,35 @@
       bs = null;
     if (bs == null && isBbcageDefault || ac == 0)
       return;
-    bboxModels = getModelBS(bboxAtoms = BSUtil.copy(bs), false);
-    if (calcAtomsMinMax(bs, boxInfo) == ac)
-      isBbcageDefault = true;
-    if (bs == null) { // from modelLoader or reset
-      if (unitCells != null)
-        calcUnitCellMinMax();
+    if (getDefaultBoundBox() == null) {
+      bboxModels = getModelBS(bboxAtoms = BSUtil.copy(bs), false);
+      if (calcAtomsMinMax(bs, boxInfo) == ac)
+        isBbcageDefault = true;
+      if (bs == null) { // from modelLoader or reset
+        if (unitCells != null)
+          calcUnitCellMinMax();
+      }
+    } else {
+      P3[] vertices = defaultBBox.getBoundBoxVertices();
+      boxInfo.reset();
+      for (int j = 0; j < 8; j++)
+        boxInfo.addBoundBoxPoint(vertices[j]);      
     }
     boxInfo.setBbcage(scale);
   }
 
+  private BoxInfo getDefaultBoundBox() {
+    T3[] bbox = (T3[]) getInfoM("boundbox");
+    if (bbox == null)
+      defaultBBox = null;
+    else {
+      if (defaultBBox == null)
+        defaultBBox = new BoxInfo();
+      defaultBBox.setBoundBoxFromCriticalPoints(bbox);
+    }
+    return defaultBBox;
+  }
+
   public BoxInfo getBoxInfo(BS bs, float scale) {
     if (bs == null)
       return boxInfo;

Modified: trunk/Jmol/src/org/jmol/script/ScriptEval.java
===================================================================
--- trunk/Jmol/src/org/jmol/script/ScriptEval.java      2015-06-04 04:57:46 UTC 
(rev 20546)
+++ trunk/Jmol/src/org/jmol/script/ScriptEval.java      2015-06-04 16:54:12 UTC 
(rev 20547)
@@ -23,16 +23,30 @@
  */
 package org.jmol.script;
 
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Map;
+
 import javajs.awt.Font;
+import javajs.util.A4;
+import javajs.util.AU;
+import javajs.util.BArray;
+import javajs.util.Base64;
 import javajs.util.Lst;
+import javajs.util.M3;
+import javajs.util.M4;
+import javajs.util.Measure;
+import javajs.util.OC;
+import javajs.util.P3;
+import javajs.util.P4;
+import javajs.util.PT;
+import javajs.util.Quat;
 import javajs.util.SB;
+import javajs.util.T3;
+import javajs.util.V3;
 
-import java.util.Arrays;
-import java.util.Hashtable;
-
-import java.util.Map;
-
 import org.jmol.api.Interface;
+import org.jmol.api.JmolParallelProcessor;
 import org.jmol.api.JmolScriptFunction;
 import org.jmol.api.SymmetryInterface;
 import org.jmol.atomdata.RadiusData;
@@ -46,37 +60,19 @@
 import org.jmol.modelset.Atom;
 import org.jmol.modelset.BondSet;
 import org.jmol.modelset.Group;
+import org.jmol.modelset.TickInfo;
 import org.jmol.shape.MeshCollection;
 import org.jmol.shape.Shape;
 import org.jmol.thread.JmolThread;
 import org.jmol.util.BSUtil;
 import org.jmol.util.ColorEncoder;
+import org.jmol.util.Edge;
+import org.jmol.util.Elements;
 import org.jmol.util.Escape;
-import org.jmol.util.Elements;
-import org.jmol.util.Edge;
 import org.jmol.util.Logger;
+import org.jmol.util.Parser;
 import org.jmol.util.SimpleUnitCell;
 import org.jmol.util.Txt;
-
-import javajs.util.PT;
-import org.jmol.util.Parser;
-
-import javajs.util.A4;
-import javajs.util.AU;
-import javajs.util.BArray;
-import javajs.util.Base64;
-import javajs.util.Measure;
-import javajs.util.OC;
-import javajs.util.M3;
-import javajs.util.M4;
-import javajs.util.P3;
-import javajs.util.P4;
-import javajs.util.Quat;
-import javajs.util.T3;
-
-import javajs.util.V3;
-import org.jmol.modelset.TickInfo;
-import org.jmol.api.JmolParallelProcessor;
 import org.jmol.viewer.ActionManager;
 import org.jmol.viewer.FileManager;
 import org.jmol.viewer.JC;
@@ -4442,7 +4438,7 @@
         tok = tokAt(i = ++iToken);
         break;
       }
-      i = getLoadSymmetryParams(i, sOptions, htParams);
+      i = getCmdExt().getLoadSymmetryParams(i, sOptions, htParams);
 
       // .... APPEND DATA "appendedData" .... end "appendedData"
       // option here to designate other than "appendedData"
@@ -4740,6 +4736,9 @@
     // SUPERCELL {i j k}
     case T.supercell:
     // RANGE x.x or RANGE -x.x
+    case T.fill:  // new in Jmol 14.3.14
+    // FILL BOUNDBOX
+    // FILL UNITCELL
     case T.range:
     // SPACEGROUP "nameOrNumber" 
     // or SPACEGROUP "IGNOREOPERATORS" 
@@ -4793,193 +4792,6 @@
     }
   }
 
-  private int getLoadSymmetryParams(int i, SB sOptions,
-                                    Map<String, Object> htParams) throws 
ScriptException {
-    // {i j k}
-
-    P3 lattice = null;
-    int tok = tokAt(i);
-    if (tok == T.leftbrace || tok == T.point3f) {
-      lattice = getPoint3f(i, false);
-      i = iToken + 1;
-      tok = tokAt(i);
-    }
-
-    // default lattice {555 555 -1} (packed) 
-    // for PACKED, CENTROID, SUPERCELL, RANGE, SPACEGROUP, UNITCELL
-
-    switch (tok) {
-    case T.packed:
-    case T.centroid:
-    case T.supercell:
-    case T.range:
-    case T.spacegroup:
-    case T.unitcell:
-      if (lattice == null)
-        lattice = P3.new3(555, 555, -1);
-      iToken = i - 1;
-    }
-    P3 offset = null;
-    if (lattice != null) {
-      htParams.put("lattice", lattice);
-      i = iToken + 1;
-      sOptions.append( " {" + (int) lattice.x + " " + (int) lattice.y + " "
-          + (int) lattice.z + "}");
-
-      // {i j k} PACKED, CENTROID -- either or both; either order
-
-      i = checkPacked(i, htParams, sOptions);
-      if (tokAt(i) == T.centroid) {
-        htParams.put("centroid", Boolean.TRUE);
-        sOptions.append(" CENTROID");
-        i = checkPacked(++i, htParams, sOptions);
-      }
-
-      // {i j k} ... SUPERCELL {i' j' k'}
-
-      if (tokAt(i) == T.supercell) {
-        Object supercell;
-        sOptions.append(" SUPERCELL ");
-        if (isPoint3f(++i)) {
-          P3 pt = getPoint3f(i, false);
-          if (pt.x != (int) pt.x || pt.y != (int) pt.y || pt.z != (int) pt.z
-              || pt.x < 1 || pt.y < 1 || pt.z < 1) {
-            iToken = i;
-            invArg();
-          }
-          supercell = pt;
-          i = iToken;
-        } else {
-          supercell = stringParameter(i);
-        }
-        sOptions.append(Escape.e(supercell));
-        htParams.put("supercell", supercell);
-        i = checkPacked(++i, htParams, sOptions);
-      }
-
-      // {i j k} ... RANGE x.y  (from full unit cell set)
-      // {i j k} ... RANGE -x.y (from non-symmetry set)
-
-      float distance = 0;
-      if (tokAt(i) == T.range) {
-        /*
-         * # Jmol 11.3.9 introduces the capability of visualizing the close
-         * contacts around a crystalline protein (or any other cyrstal
-         * structure) that are to atoms that are in proteins in adjacent unit
-         * cells or adjacent to the protein itself. The option RANGE x, where x
-         * is a distance in angstroms, placed right after the braces containing
-         * the set of unit cells to load does this. The distance, if a positive
-         * number, is the maximum distance away from the closest atom in the {1
-         * 1 1} set. If the distance x is a negative number, then -x is the
-         * maximum distance from the {not symmetry} set. The difference is that
-         * in the first case the primary unit cell (555) is first filled as
-         * usual, using symmetry operators, and close contacts to this set are
-         * found. In the second case, only the file-based atoms ( 
Jones-Faithful
-         * operator x,y,z) are initially included, then close contacts to that
-         * set are found. Depending upon the application, one or the other of
-         * these options may be desirable.
-         */
-        i++;
-        distance = floatParameter(i++);
-        sOptions.append( " range " + distance);
-      }
-      htParams.put("symmetryRange", Float.valueOf(distance));
-
-      // {i j k} ... SPACEGROUP "nameOrNumber"
-      // {i j k} ... SPACEGROUP "IGNOREOPERATORS"
-      // {i j k} ... SPACEGROUP ""
-
-      String spacegroup = null;
-      SymmetryInterface sg;
-      int iGroup = Integer.MIN_VALUE;
-      if (tokAt(i) == T.spacegroup) {
-        ++i;
-        spacegroup = PT.rep(paramAsStr(i++), "''", "\"");
-        sOptions.append( " spacegroup " + PT.esc(spacegroup));
-        if (spacegroup.equalsIgnoreCase("ignoreOperators")) {
-          iGroup = -999;
-        } else {
-          if (spacegroup.length() == 0) {
-            sg = vwr.getCurrentUnitCell();
-            if (sg != null)
-              spacegroup = sg.getSpaceGroupName();
-          } else {
-            if (spacegroup.indexOf(",") >= 0) // Jones Faithful
-              if ((lattice.x < 9 && lattice.y < 9 && lattice.z == 0))
-                spacegroup += "#doNormalize=0";
-          }
-          htParams.put("spaceGroupName", spacegroup);
-          iGroup = -2;
-        }
-      }
-
-      // {i j k} ... UNITCELL [a b c alpha beta gamma]
-      // {i j k} ... UNITCELL [ax ay az bx by bz cx cy cz] 
-      // {i j k} ... UNITCELL ""  // same as current
-
-      float[] fparams = null;
-      if (tokAt(i) == T.unitcell) {
-        ++i;
-        if (optParameterAsString(i).length() == 0) {
-          // unitcell "" -- use current unit cell
-          sg = vwr.getCurrentUnitCell();
-          if (sg != null) {
-            fparams = sg.getUnitCellAsArray(true);
-            offset = sg.getCartesianOffset();
-          }
-        } else {
-          fparams = floatParameterSet(i, 6, 9);
-        }
-        if (fparams == null || fparams.length != 6 && fparams.length != 9)
-          invArg();
-        sOptions.append( " unitcell {");
-        for (int j = 0; j < fparams.length; j++)
-          sOptions.append( (j == 0 ? "" : " ") + fparams[j]);
-        sOptions.append( "}");
-        htParams.put("unitcell", fparams);
-        if (iGroup == Integer.MIN_VALUE)
-          iGroup = -1;
-        i = iToken + 1;
-      }
-      if (iGroup != Integer.MIN_VALUE)
-        htParams.put("spaceGroupIndex", Integer.valueOf(iGroup));
-    }
-
-    // OFFSET {x y z} (fractional or not) (Jmol 12.1.17)
-
-    if (offset != null)
-      coordinatesAreFractional = false;
-    else if (tokAt(i) == T.offset)
-      offset = getPoint3f(++i, true);
-    if (offset != null) {
-      if (coordinatesAreFractional) {
-        offset.setT(fractionalPoint);
-        htParams.put("unitCellOffsetFractional",
-            (coordinatesAreFractional ? Boolean.TRUE : Boolean.FALSE));
-        sOptions.append( " offset {" + offset.x + " " + offset.y + " " + 
offset.z
-            + "/1}");
-      } else {
-        sOptions.append( " offset " + Escape.eP(offset));
-      }
-      htParams.put("unitCellOffset", offset);
-      i = iToken + 1;
-    }
-    return i;
-  }
-
-  private int checkPacked(int i, Map<String, Object> htParams, SB sOptions) 
throws ScriptException {
-    if (tokAt(i) == T.packed) {
-      htParams.put("packed", Boolean.TRUE);
-      sOptions.append(" PACKED");
-      if (isFloatParameter(++i)) {
-        float f = floatParameter(i++);
-        htParams.put("packingError", Float.valueOf(f));
-        sOptions.append(" " + f);
-      }
-    }
-    return i;
-  }
-
   private void finalizeLoad(boolean isAppend, boolean appendNew,
                             boolean isConcat, boolean doOrient,
                             int nFiles, int ac0, int modelCount0) throws 
ScriptException {
@@ -7912,142 +7724,7 @@
       vwr.undoMoveAction(tokAt(0), n);
   }
 
-  private void cmdUnitcell(int i) throws ScriptException {
-    int icell = Integer.MAX_VALUE;
-    int mad = Integer.MAX_VALUE;
-    T3 pt = null;
-    TickInfo tickInfo = tickParamAsStr(i, true, false, false);
-    i = iToken;
-    String id = null;
-    T3[] oabc = null;
-    Object newUC = null;
-    String ucname = null;
-    boolean isOffset = false;
-    boolean isReset = false;
-    int tok = tokAt(++i);
-    switch (tok) {
-    case T.restore:
-    case T.reset:
-      isReset = true;
-      pt = P4.new4(0, 0, 0, -1); // reset offset and range
-      iToken++;
-      break;
-    case T.string:
-    case T.identifier:
-      String s = paramAsStr(i).toLowerCase();
-      ucname = s;
-      if (s.indexOf(",") < 0 && !chk) {
-        // parent, standard, conventional
-        setCurrentCagePts(null, null);
-        if (PT.isOneOf(s, ";parent;standard;primitive;")) {
-          newUC = vwr.ms.getInfo(vwr.am.cmi, "unitcell_conventional");
-          if (newUC != null)
-            setCurrentCagePts(vwr.getV0abc(newUC), "" + newUC);
-        }
-        s = (String) vwr.ms.getInfo(vwr.am.cmi, "unitcell_" + s);
-        showString(s);
-      }
-      newUC = s;
-      break;
-    case T.isosurface:
-    case T.dollarsign:
-      id = objectNameParameter(++i);
-      break;
-    case T.boundbox:
-      P3 o = P3.newP(vwr.getBoundBoxCenter());
-      pt = vwr.getBoundBoxCornerVector();
-      o.sub(pt);
-      oabc = new P3[] {o, P3.new3(pt.x * 2, 0, 0), P3.new3(0, pt.y * 2, 0), 
P3.new3(0, 0, pt.z * 2) };
-      pt = null;
-      iToken = i;
-      break;
-    case T.matrix3f:
-    case T.matrix4f:
-      newUC = getToken(i).value;
-      break;
-    case T.center:
-      switch (tokAt(++i)) {
-      case T.bitset:
-      case T.expressionBegin:
-        pt = P3.newP(vwr.ms.getAtomSetCenter(atomExpressionAt(i)));
-        vwr.toFractional(pt, true);
-        i = iToken;
-        break;
-      default:
-        if (isCenterParameter(i)) {
-          pt = centerParameter(i);
-          i = iToken;
-          break;
-        }
-        invArg();
-      }
-      pt.x -= 0.5f;
-      pt.y -= 0.5f;
-      pt.z -= 0.5f;
-      break;
-    case T.bitset:
-    case T.expressionBegin:
-      int iAtom = atomExpressionAt(i).nextSetBit(0);
-      if (!chk)
-        vwr.am.cai = iAtom;
-      if (iAtom < 0)
-        return;
-      i = iToken;
-      break;
-    case T.offset:
-      isOffset = true;
-      //$FALL-THROUGH$
-    case T.range:
-      pt = (P3) getPointOrPlane(++i, false, true, false, true, 3, 3);
-      pt = P4.new4(pt.x, pt.y, pt.z, (isOffset ? 1 : 0));
-      i = iToken;
-      break;
-    case T.decimal:
-    case T.integer:
-      float f = floatParameter(i);
-      if (f < 111) {
-        // diameter
-        i--;
-        break;
-      }
-      icell = intParameter(i);
-      break;
-    default:
-      if (isArrayParameter(i)) {
-        // Origin vA vB vC
-        // these are VECTORS, though
-        oabc = getPointArray(i, 4, false);
-        i = iToken;
-      } else if (slen > i + 1) {
-        pt = (P3) getPointOrPlane(i, false, true, false, true, 3, 3);
-        i = iToken;
-      } else {
-        // backup for diameter
-        i--;
-      }
-    }
-    mad = getSetAxesTypeMad(++i);
-    checkLast(iToken);
-    if (chk || mad == Integer.MAX_VALUE)
-      return;
-    if (mad == Integer.MAX_VALUE)
-      vwr.am.cai = -1;
-    if (newUC != null)
-      oabc = vwr.getV0abc(newUC);
-    if (icell != Integer.MAX_VALUE)
-      vwr.ms.setUnitCellOffset(vwr.getCurrentUnitCell(), null, icell);
-    else if (id != null)
-      vwr.setCurrentCage(id);
-    else if (isReset || oabc != null)
-      setCurrentCagePts(oabc, ucname);
-    setObjectMad(JC.SHAPE_UCCAGE, "unitCell", mad);
-    if (pt != null)
-      vwr.ms.setUnitCellOffset(vwr.getCurrentUnitCell(), pt, 0);
-    if (tickInfo != null)
-      setShapeProperty(JC.SHAPE_UCCAGE, "tickInfo", tickInfo);
-  }
-
-  private void setCurrentCagePts(T3[] originABC, String name) {
+  public void setCurrentCagePts(T3[] originABC, String name) {
     SymmetryInterface sym = Interface.getSymmetry(vwr, "eval");
     if (sym == null && vwr.async)
       throw new NullPointerException();
@@ -8059,6 +7736,9 @@
     }
   }
 
+  private void cmdUnitcell(int i) throws ScriptException {
+    getCmdExt().dispatch(T.unitcell, i == 2, null);
+  }
 
   private void cmdVector() throws ScriptException {
     EnumType type = EnumType.SCREEN;
@@ -8870,7 +8550,7 @@
     return data;
   }
 
-  private int getSetAxesTypeMad(int index) throws ScriptException {
+  public int getSetAxesTypeMad(int index) throws ScriptException {
     if (index == slen)
       return 1;
     switch (getToken(checkLast(index)).tok) {

Modified: trunk/Jmol/src/org/jmol/script/ScriptParam.java
===================================================================
--- trunk/Jmol/src/org/jmol/script/ScriptParam.java     2015-06-04 04:57:46 UTC 
(rev 20546)
+++ trunk/Jmol/src/org/jmol/script/ScriptParam.java     2015-06-04 16:54:12 UTC 
(rev 20547)
@@ -52,8 +52,8 @@
 
   // passed back as globals
   
-  protected P3 fractionalPoint;
-  protected boolean coordinatesAreFractional;
+  public P3 fractionalPoint;
+  public boolean coordinatesAreFractional;
   public boolean isBondSet;
   public Object expressionResult;
 
@@ -385,7 +385,7 @@
     return Measure.getPlaneThroughPoints(pt1,  pt2, pt3, new V3(), new V3(), 
new P4());
   }
 
-  protected Object getPointOrPlane(int index, boolean integerOnly,
+  public Object getPointOrPlane(int index, boolean integerOnly,
                                  boolean allowFractional, boolean doConvert,
                                  boolean implicitFractional, int minDim,
                                  int maxDim) throws ScriptException {
@@ -585,7 +585,7 @@
   /**
    * may return null values in some cases
    * @param i
-   * @param nPoints
+   * @param nPoints -1 for unspecified number of points
    * @param allowNull if allowing null values (as in setting atom properties 
such as vxyz or xyz)
    * @return array of P3, with possible null values
    * @throws ScriptException

Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java
===================================================================
--- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java       2015-06-04 04:57:46 UTC 
(rev 20546)
+++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java       2015-06-04 16:54:12 UTC 
(rev 20547)
@@ -31,6 +31,7 @@
 import org.jmol.api.Interface;
 import org.jmol.api.JmolDataManager;
 import org.jmol.api.MinimizerInterface;
+import org.jmol.api.SymmetryInterface;
 import org.jmol.atomdata.RadiusData;
 import org.jmol.c.STER;
 import org.jmol.c.VDW;
@@ -56,6 +57,7 @@
 import org.jmol.script.ScriptParam;
 import org.jmol.script.T;
 import org.jmol.util.BSUtil;
+import org.jmol.util.BoxInfo;
 import org.jmol.util.C;
 import org.jmol.util.Elements;
 import org.jmol.util.Escape;
@@ -76,8 +78,10 @@
 import javajs.util.M4;
 import javajs.util.Measure;
 import javajs.util.P3;
+import javajs.util.P4;
 import javajs.util.PT;
 import javajs.util.Quat;
+import javajs.util.T3;
 import javajs.util.V3;
 
 import org.jmol.viewer.FileManager;
@@ -164,6 +168,9 @@
     case T.stereo:
       stereo();
       break;
+    case T.unitcell:
+      unitcell(b ? 2 : 1);
+      break;
     case T.write:
       return write(b ? st : null);
     case JC.SHAPE_MEASURES:
@@ -192,6 +199,8 @@
    */
   public boolean evalParallel(ScriptContext context,
                                   ShapeManager shapeManager) {
+    chk = e.chk;
+    slen = e.slen;
     ScriptEval se = new ScriptEval().setViewer(vwr);
     se.historyDisabled = true;
     se.compiler = new ScriptCompiler(vwr);
@@ -274,6 +283,227 @@
     return nmax == 1 && !isExplicitlyAll ? sout[0] : (Object) sout;
   }
 
+  
+  public int getLoadSymmetryParams(int i, SB sOptions,
+                                   Map<String, Object> htParams) throws 
ScriptException {
+   // {i j k}
+   ScriptEval eval = e;
+   chk = eval.chk;
+   slen = eval.slen;
+   P3 lattice = null;
+   int tok = tokAt(i);
+   if (tok == T.leftbrace || tok == T.point3f) {
+     lattice = getPoint3f(i, false);
+     i = eval.iToken + 1;
+     tok = tokAt(i);
+   }
+
+   // default lattice {555 555 -1} (packed) 
+   // for PACKED, CENTROID, SUPERCELL, RANGE, SPACEGROUP, UNITCELL
+
+   switch (tok) {
+   case T.fill:
+   case T.packed:
+   case T.centroid:
+   case T.supercell:
+   case T.range:
+   case T.spacegroup:
+   case T.unitcell:
+     if (lattice == null)
+       lattice = P3.new3(555, 555, -1);
+     // re-read this token
+     eval.iToken = i - 1;
+   }
+   
+   P3 offset = null;
+   if (lattice != null) {
+     htParams.put("lattice", lattice);
+     i = eval.iToken + 1;
+     sOptions.append( " {" + (int) lattice.x + " " + (int) lattice.y + " "
+         + (int) lattice.z + "}");
+
+     // {i j k} PACKED, CENTROID -- either or both; either order
+
+     i = checkPacked(i, htParams, sOptions);
+     if (tokAt(i) == T.centroid) {
+       htParams.put("centroid", Boolean.TRUE);
+       sOptions.append(" CENTROID");
+       i = checkPacked(++i, htParams, sOptions);
+     }
+
+     // {i j k} ... SUPERCELL {i' j' k'}
+
+     if (tokAt(i) == T.supercell) {
+       Object supercell;
+       sOptions.append(" SUPERCELL ");
+       if (eval.isPoint3f(++i)) {
+         P3 pt = getPoint3f(i, false);
+         if (pt.x != (int) pt.x || pt.y != (int) pt.y || pt.z != (int) pt.z
+             || pt.x < 1 || pt.y < 1 || pt.z < 1) {
+           eval.iToken = i;
+           invArg();
+         }
+         supercell = pt;
+         i = eval.iToken;
+       } else {
+         supercell = stringParameter(i);
+       }
+       sOptions.append(Escape.e(supercell));
+       htParams.put("supercell", supercell);
+       i = checkPacked(++i, htParams, sOptions);
+     }
+
+     // {i j k} ... RANGE x.y  (from full unit cell set)
+     // {i j k} ... RANGE -x.y (from non-symmetry set)
+
+     float distance = 0;
+     if (tokAt(i) == T.range) {
+       /*
+        * # Jmol 11.3.9 introduces the capability of visualizing the close
+        * contacts around a crystalline protein (or any other crystal
+        * structure) that are to atoms that are in proteins in adjacent unit
+        * cells or adjacent to the protein itself. The option RANGE x, where x
+        * is a distance in angstroms, placed right after the braces containing
+        * the set of unit cells to load does this. The distance, if a positive
+        * number, is the maximum distance away from the closest atom in the {1
+        * 1 1} set. If the distance x is a negative number, then -x is the
+        * maximum distance from the {not symmetry} set. The difference is that
+        * in the first case the primary unit cell (555) is first filled as
+        * usual, using symmetry operators, and close contacts to this set are
+        * found. In the second case, only the file-based atoms ( Jones-Faithful
+        * operator x,y,z) are initially included, then close contacts to that
+        * set are found. Depending upon the application, one or the other of
+        * these options may be desirable.
+        */
+       i++;
+       distance = floatParameter(i++);
+       sOptions.append( " range " + distance);
+     }
+     htParams.put("symmetryRange", Float.valueOf(distance));
+
+     // {i j k} ... SPACEGROUP "nameOrNumber"
+     // {i j k} ... SPACEGROUP "IGNOREOPERATORS"
+     // {i j k} ... SPACEGROUP ""
+
+     String spacegroup = null;
+     SymmetryInterface sg;
+     int iGroup = Integer.MIN_VALUE;
+     if (tokAt(i) == T.spacegroup) {
+       ++i;
+       spacegroup = PT.rep(paramAsStr(i++), "''", "\"");
+       sOptions.append( " spacegroup " + PT.esc(spacegroup));
+       if (spacegroup.equalsIgnoreCase("ignoreOperators")) {
+         iGroup = -999;
+       } else {
+         if (spacegroup.length() == 0) {
+           sg = vwr.getCurrentUnitCell();
+           if (sg != null)
+             spacegroup = sg.getSpaceGroupName();
+         } else {
+           if (spacegroup.indexOf(",") >= 0) // Jones Faithful
+             if ((lattice.x < 9 && lattice.y < 9 && lattice.z == 0))
+               spacegroup += "#doNormalize=0";
+         }
+         htParams.put("spaceGroupName", spacegroup);
+         iGroup = -2;
+       }
+     }
+
+     // {i j k} ... UNITCELL [a b c alpha beta gamma]
+     // {i j k} ... UNITCELL [ax ay az bx by bz cx cy cz] 
+     // {i j k} ... UNITCELL ""  // same as current
+
+     float[] fparams = null;
+     if (tokAt(i) == T.unitcell) {
+       ++i;
+       if (eval.optParameterAsString(i).length() == 0) {
+         // unitcell "" -- use current unit cell
+         sg = vwr.getCurrentUnitCell();
+         if (sg != null) {
+           fparams = sg.getUnitCellAsArray(true);
+           offset = sg.getCartesianOffset();
+         }
+       } else {
+         fparams = eval.floatParameterSet(i, 6, 9);
+       }
+       if (fparams == null || fparams.length != 6 && fparams.length != 9)
+         invArg();
+       sOptions.append( " unitcell {");
+       for (int j = 0; j < fparams.length; j++)
+         sOptions.append( (j == 0 ? "" : " ") + fparams[j]);
+       sOptions.append( "}");
+       htParams.put("unitcell", fparams);
+       if (iGroup == Integer.MIN_VALUE)
+         iGroup = -1;
+       i = eval.iToken + 1;
+     }
+     if (iGroup != Integer.MIN_VALUE)
+       htParams.put("spaceGroupIndex", Integer.valueOf(iGroup));
+   }
+
+   // OFFSET {x y z} (fractional or not) (Jmol 12.1.17)
+
+   if (offset != null)
+     eval.coordinatesAreFractional = false;
+   else if (tokAt(i) == T.offset)
+     offset = getPoint3f(++i, true);
+   if (offset != null) {
+     if (eval.coordinatesAreFractional) {
+       offset.setT(eval.fractionalPoint);
+       htParams.put("unitCellOffsetFractional",
+           (eval.coordinatesAreFractional ? Boolean.TRUE : Boolean.FALSE));
+       sOptions.append( " offset {" + offset.x + " " + offset.y + " " + 
offset.z
+           + "/1}");
+     } else {
+       sOptions.append( " offset " + Escape.eP(offset));
+     }
+     htParams.put("unitCellOffset", offset);
+     i = eval.iToken + 1;
+   }
+   return i;
+ }
+
+  /**
+   * Process FILL and PACKED and all their variants.
+   * 
+   * @param i
+   * @param htParams
+   * @param sOptions
+   * @return new token position
+   * @throws ScriptException
+   */
+  private int checkPacked(int i, Map<String, Object> htParams, SB sOptions)
+      throws ScriptException {
+    switch (tokAt(i)) {
+    case T.fill:
+      int tok = tokAt(++i);
+      e.iToken = i;
+      SymmetryInterface unitCell = null;
+      boolean isArray = e.isArrayParameter(i + 1);
+      T3[] pts = (isArray ? e.getPointArray(++i, 4, false) : null);
+      if (!isArray && tok == T.unitcell) {
+        unitCell = vwr.getCurrentUnitCell();
+        if (unitCell != null)
+          pts = BoxInfo.getUnitCellPoints(unitCell.getUnitCellVertices(),
+              unitCell.getCartesianOffset());
+      }
+      if (pts == null)
+        pts = BoxInfo.getUnitCellPoints(vwr.ms.getBBoxVertices(), null);
+      return ++e.iToken;
+    case T.packed:
+      htParams.put("packed", Boolean.TRUE);
+      sOptions.append(" PACKED");
+      if (isFloatParameter(++i)) {
+        float f = floatParameter(i++);
+        htParams.put("packingError", Float.valueOf(f));
+        sOptions.append(" " + f);
+      }
+      break;
+    }
+    return i;
+  }
+
+
   ///////////////// Jmol script commands ////////////
   
   private void cache() throws ScriptException {
@@ -4275,8 +4505,144 @@
     return true;
   }
 
+  private void unitcell(int i) throws ScriptException {
+    ScriptEval eval = e;
+    int icell = Integer.MAX_VALUE;
+    int mad = Integer.MAX_VALUE;
+    T3 pt = null;
+    TickInfo tickInfo = eval.tickParamAsStr(i, true, false, false);
+    i = eval.iToken;
+    String id = null;
+    T3[] oabc = null;
+    Object newUC = null;
+    String ucname = null;
+    boolean isOffset = false;
+    boolean isReset = false;
+    int tok = tokAt(++i);
+    switch (tok) {
+    case T.restore:
+    case T.reset:
+      isReset = true;
+      pt = P4.new4(0, 0, 0, -1); // reset offset and range
+      eval.iToken++;
+      break;
+    case T.string:
+    case T.identifier:
+      String s = paramAsStr(i).toLowerCase();
+      ucname = s;
+      if (s.indexOf(",") < 0 && !chk) {
+        // parent, standard, conventional
+        eval.setCurrentCagePts(null, null);
+        if (PT.isOneOf(s, ";parent;standard;primitive;")) {
+          newUC = vwr.ms.getInfo(vwr.am.cmi, "unitcell_conventional");
+          if (newUC != null)
+            eval.setCurrentCagePts(vwr.getV0abc(newUC), "" + newUC);
+        }
+        s = (String) vwr.ms.getInfo(vwr.am.cmi, "unitcell_" + s);
+        showString(s);
+      }
+      newUC = s;
+      break;
+    case T.isosurface:
+    case T.dollarsign:
+      id = eval.objectNameParameter(++i);
+      break;
+    case T.boundbox:
+      P3 o = P3.newP(vwr.getBoundBoxCenter());
+      pt = vwr.getBoundBoxCornerVector();
+      o.sub(pt);
+      oabc = new P3[] {o, P3.new3(pt.x * 2, 0, 0), P3.new3(0, pt.y * 2, 0), 
P3.new3(0, 0, pt.z * 2) };
+      pt = null;
+      eval.iToken = i;
+      break;
+    case T.matrix3f:
+    case T.matrix4f:
+      newUC = getToken(i).value;
+      break;
+    case T.center:
+      switch (tokAt(++i)) {
+      case T.bitset:
+      case T.expressionBegin:
+        pt = P3.newP(vwr.ms.getAtomSetCenter(atomExpressionAt(i)));
+        vwr.toFractional(pt, true);
+        i = eval.iToken;
+        break;
+      default:
+        if (eval.isCenterParameter(i)) {
+          pt = centerParameter(i);
+          i = eval.iToken;
+          break;
+        }
+        invArg();
+      }
+      pt.x -= 0.5f;
+      pt.y -= 0.5f;
+      pt.z -= 0.5f;
+      break;
+    case T.bitset:
+    case T.expressionBegin:
+      int iAtom = atomExpressionAt(i).nextSetBit(0);
+      if (!chk)
+        vwr.am.cai = iAtom;
+      if (iAtom < 0)
+        return;
+      i = eval.iToken;
+      break;
+    case T.offset:
+      isOffset = true;
+      //$FALL-THROUGH$
+    case T.range:
+      pt = (P3) eval.getPointOrPlane(++i, false, true, false, true, 3, 3);
+      pt = P4.new4(pt.x, pt.y, pt.z, (isOffset ? 1 : 0));
+      i = eval.iToken;
+      break;
+    case T.decimal:
+    case T.integer:
+      float f = floatParameter(i);
+      if (f < 111) {
+        // diameter
+        i--;
+        break;
+      }
+      icell = intParameter(i);
+      break;
+    default:
+      if (eval.isArrayParameter(i)) {
+        // Origin vA vB vC
+        // these are VECTORS, though
+        oabc = eval.getPointArray(i, 4, false);
+        i = eval.iToken;
+      } else if (slen > i + 1) {
+        pt = (P3) eval.getPointOrPlane(i, false, true, false, true, 3, 3);
+        i = eval.iToken;
+      } else {
+        // backup for diameter
+        i--;
+      }
+    }
+    mad = eval.getSetAxesTypeMad(++i);
+    eval.checkLast(eval.iToken);
+    if (chk || mad == Integer.MAX_VALUE)
+      return;
+    if (mad == Integer.MAX_VALUE)
+      vwr.am.cai = -1;
+    if (newUC != null)
+      oabc = vwr.getV0abc(newUC);
+    if (icell != Integer.MAX_VALUE)
+      vwr.ms.setUnitCellOffset(vwr.getCurrentUnitCell(), null, icell);
+    else if (id != null)
+      vwr.setCurrentCage(id);
+    else if (isReset || oabc != null)
+      eval.setCurrentCagePts(oabc, ucname);
+    eval.setObjectMad(JC.SHAPE_UCCAGE, "unitCell", mad);
+    if (pt != null)
+      vwr.ms.setUnitCellOffset(vwr.getCurrentUnitCell(), pt, 0);
+    if (tickInfo != null)
+      setShapeProperty(JC.SHAPE_UCCAGE, "tickInfo", tickInfo);
+  }
 
 
+
   ///////// private methods used by commands ///////////
 
   
@@ -4523,5 +4889,4 @@
     return data;
   }
 
-
 }

Modified: trunk/Jmol/src/org/jmol/scriptext/IsoExt.java
===================================================================
--- trunk/Jmol/src/org/jmol/scriptext/IsoExt.java       2015-06-04 04:57:46 UTC 
(rev 20546)
+++ trunk/Jmol/src/org/jmol/scriptext/IsoExt.java       2015-06-04 16:54:12 UTC 
(rev 20547)
@@ -3380,7 +3380,7 @@
       break;
     case T.boundbox:
       eval.iToken = i + 1;
-      data = BoxInfo.getCriticalPoints(vwr.ms.getBBoxVertices(), null);
+      data = BoxInfo.getUnitCellPoints(vwr.ms.getBBoxVertices(), null);
       break;
     //case Token.slicebox:
     // data = 
BoxInfo.getCriticalPoints(((JmolViewer)(vwr)).slicer.getSliceVert(), null);
@@ -3394,7 +3394,7 @@
         if (tok == T.unitcell)
           invArg();
       } else {
-        pts = BoxInfo.getCriticalPoints(unitCell.getUnitCellVertices(),
+        pts = BoxInfo.getUnitCellPoints(unitCell.getUnitCellVertices(),
             unitCell.getCartesianOffset());
         int iType = (int) unitCell
             .getUnitCellInfoType(SimpleUnitCell.INFO_DIMENSIONS);

Modified: trunk/Jmol/src/org/jmol/thread/MoveToThread.java
===================================================================
--- trunk/Jmol/src/org/jmol/thread/MoveToThread.java    2015-06-04 04:57:46 UTC 
(rev 20546)
+++ trunk/Jmol/src/org/jmol/thread/MoveToThread.java    2015-06-04 16:54:12 UTC 
(rev 20547)
@@ -207,7 +207,7 @@
     yTrans = newSlider(transformManager.getTranslationYPercent(), f[3]);
     rotationRadius = newSlider(transformManager.modelRadius,
         (center == null || Float.isNaN(f[4]) ? transformManager.modelRadius
-            : f[4] <= 0 ? vwr.ms.calcRotationRadius(vwr.am.cmi, center) : 
f[4]));
+            : f[4] <= 0 ? vwr.ms.calcRotationRadius(vwr.am.cmi, center, false) 
: f[4]));
     pixelScale = newSlider(transformManager.scaleDefaultPixelsPerAngstrom, 
f[5]);
     if (f[6] != 0) {
       navCenter = (P3) options[2];

Modified: trunk/Jmol/src/org/jmol/util/BoxInfo.java
===================================================================
--- trunk/Jmol/src/org/jmol/util/BoxInfo.java   2015-06-04 04:57:46 UTC (rev 
20546)
+++ trunk/Jmol/src/org/jmol/util/BoxInfo.java   2015-06-04 16:54:12 UTC (rev 
20547)
@@ -36,6 +36,11 @@
 import javajs.util.V3;
 import javajs.util.T3;
 
+/**
+ * The BoxInfo class holds critical information about boundboxes. 
+ * These are simple tetragonal spaces lined up with x,y,z.
+ * 
+ */
 public class BoxInfo {
 
  
@@ -43,6 +48,11 @@
   public final P3 bbCorner1 = new P3();
   private final P3 bbCenter = new P3();
   private final V3 bbVector = new V3();
+  
+  /**
+   * The ordering of these vertices is given below. Do not mess with that.
+   * 
+   */
   private final Point3fi[] bbVertices = new Point3fi[8];
   private boolean isScaleSet;
   private float margin;
@@ -125,17 +135,7 @@
     P3 vb = new P3();
     P3 vc = new P3();
     
-    P3[] vertices = new P3[8];
-    for (int i = 0; i < 8; i++) {
-      vertices[i] = P3.newP(points[0]);
-      if ((i & 1) == 1)
-        vertices[i].add(points[1]);
-      if ((i & 2) == 2)
-        vertices[i].add(points[2]);
-      if ((i & 4) == 4)
-        vertices[i].add(points[3]);
-    }
-
+    P3[] vertices = getVerticesFromCriticalPoints(points);
     for (int i = 0; i < 6; i++) {
       va.setT(vertices[facePoints[i].x]);
       vb.setT(vertices[facePoints[i].y]);
@@ -198,7 +198,28 @@
     P3i.new3(0, 1, 1)  //7 pt + z + 1 
   };
 
-  public final static P3[] getCriticalPoints(P3[] bbVertices, T3 offset) {
+  public static P3[] getVerticesFromCriticalPoints(P3[] points) {
+    P3[] vertices = new P3[8];
+    for (int i = 0; i < 8; i++) {
+      vertices[i] = P3.newP(points[0]);
+      if ((i & 1) == 1)
+        vertices[i].add(points[1]);
+      if ((i & 2) == 2)
+        vertices[i].add(points[2]);
+      if ((i & 4) == 4)
+        vertices[i].add(points[3]);
+    }
+    return vertices;
+  }
+
+  /**
+   * Delivers [center a b c] for generation of unit cells from a boundbox
+   * 
+   * @param bbVertices
+   * @param offset
+   * @return [center a b c]
+   */
+  public final static P3[] getUnitCellPoints(P3[] bbVertices, T3 offset) {
     P3 center = P3.newP(bbVertices[0]);
     P3 a = P3.newP(bbVertices[1]);
     P3 b = P3.newP(bbVertices[2]);
@@ -231,6 +252,13 @@
     return bbVector;
   }
 
+  /**
+   * Return basic info on boundbox in the form of an array.
+   *  
+   * @param isAll to include center and diagonal
+   * @return isAll: [(0.5 0.5 0.5), diagonal, (0 0 0), (1 1 1)], otherwise 
just [(0 0 0), (1 1 1)]
+   * 
+   */
   public P3[] getBoundBoxPoints(boolean isAll) {
     if (!isScaleSet)
       setBbcage(1);
@@ -244,7 +272,15 @@
     return bbVertices;
   }
   
-  public void setBoundBox(P3 pt1, P3 pt2, boolean byCorner, float scale) {
+  public void setBoundBoxFromCriticalPoints(T3[] points) {
+    P3 origin = P3.newP(points[0]);
+    P3 pt111 = new P3();
+    for (int i = 0; i < 4; i++)
+      pt111.add(points[i]);
+    setBoundBox(origin, pt111, true, 1);
+  }
+  
+  public void setBoundBox(T3 pt1, T3 pt2, boolean byCorner, float scale) {
     if (pt1 != null) {
       if (scale == 0)
         return;
@@ -342,4 +378,8 @@
        && pt.z >= bbCorner0.z && pt.z <= bbCorner1.z); 
   }
 
+  public float getMaxDim() {
+    return bbVector.length() * 2;
+  }
+
 }

Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-06-04 04:57:46 UTC 
(rev 20546)
+++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-06-04 16:54:12 UTC 
(rev 20547)
@@ -14,8 +14,21 @@
 
 TODO: remove HTML5 dependency on synchronous file loading (check SCRIPT 
command for problems)
 
-Jmol.___JmolVersion="14.3.14_2015.06.03"
+Jmol.___JmolVersion="14.3.14_2015.06.04"
 
+new feature: load "...." FILL BOUNDBOX
+new feature: load "...." FILL UNITCELL
+new feature: load "...." FILL UNITCELL [o a b c]
+new feature: load "...." FILL BOUNDBOX [o a b c]
+
+ -- in development
+ -- loads a crystal structure such that a given volume is packed
+ -- volume can be the current boundbox or the current unitcell or a specified 
origin and a,b,c vectors
+ -- if BOUNDBOX, sets the current boundbox after loading to be current boundbox
+
+
+JmolVersion="14.3.14_2015.06.03"
+
 new feature: AFLOW binary alloy file reader centers unit cells in all frames 
at the same point
 
 new feature; AFLOW binary alloy file reader can filter "list=xx" to produce a 
list of values start with xx. 

Modified: trunk/Jmol/src/org/jmol/viewer/TransformManager.java
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/TransformManager.java        2015-06-04 
04:57:46 UTC (rev 20546)
+++ trunk/Jmol/src/org/jmol/viewer/TransformManager.java        2015-06-04 
16:54:12 UTC (rev 20547)
@@ -129,6 +129,7 @@
     rotationCenterDefault.setT(vwr.getBoundBoxCenter());
     setFixedRotationCenter(rotationCenterDefault);
     rotationRadiusDefault = setRotationRadius(0, true);
+    System.out.println("TM rotraddef=" +rotationRadiusDefault);
     windowCentered = true;
     setRotationCenterAndRadiusXYZ(null, true);
     resetRotation();
@@ -2284,7 +2285,7 @@
 
   public float setRotationRadius(float angstroms, boolean doAll) {
     angstroms = (modelRadius = (angstroms <= 0 ? vwr.ms.calcRotationRadius(
-        vwr.am.cmi, fixedRotationCenter) : angstroms));
+        vwr.am.cmi, fixedRotationCenter, true) : angstroms));
     if (doAll)
       vwr.setRotationRadius(angstroms, false);
     return angstroms;
@@ -2300,7 +2301,7 @@
     }
     setFixedRotationCenter(newCenterOfRotation);
     if (andRadius && windowCentered)
-      modelRadius = vwr.ms.calcRotationRadius(vwr.am.cmi, fixedRotationCenter);
+      modelRadius = vwr.ms.calcRotationRadius(vwr.am.cmi, fixedRotationCenter, 
true);
   }
 
   void setNewRotationCenter(P3 center, boolean doScale) {

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to