Revision: 20840
          http://sourceforge.net/p/jmol/code/20840
Author:   hansonr
Date:     2015-10-20 22:41:32 +0000 (Tue, 20 Oct 2015)
Log Message:
-----------
Jmol.___JmolVersion="14.5.0_2015.10.20"

new feature: polyhedra with arbitrary center and vertices, without atom center
  -- for example:
    polyhedra ID "myid" {0 0 0} TO [{1 0 0}, {0 1 0}, {0 0 1}, {-1 -1 -1}]

bug fix: set platformSpeed 1 for pmesh fails
bug fix: polyhedron EDGES fails
bug fix: @{ {"hash":{0.1 0.1 0.1},...} } fails (attempts to turn "," into "OR")
  -- solution is to not allow "," for OR within associative arrays
  

Modified Paths:
--------------
    trunk/Jmol/src/org/jmol/render/MeshRenderer.java
    trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java
    trunk/Jmol/src/org/jmol/script/ScriptTokenParser.java
    trunk/Jmol/src/org/jmol/scriptext/CmdExt.java
    trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java
    trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java
    trunk/Jmol/src/org/jmol/viewer/JC.java
    trunk/Jmol/src/org/jmol/viewer/Jmol.properties

Modified: trunk/Jmol/src/org/jmol/render/MeshRenderer.java
===================================================================
--- trunk/Jmol/src/org/jmol/render/MeshRenderer.java    2015-10-20 22:40:08 UTC 
(rev 20839)
+++ trunk/Jmol/src/org/jmol/render/MeshRenderer.java    2015-10-20 22:41:32 UTC 
(rev 20840)
@@ -290,7 +290,7 @@
   protected void renderPoints() {
     if (!mesh.isTriangleSet || mesh.pc < 0) {
       for (int i = vertexCount; --i >= 0;)
-        if (!frontOnly || normixes == null || 
transformedVectors[normixes[i]].z >= 0)
+        if (!frontOnly || normixes == null || isVisibleNormix(normixes[i]))
           drawPoint(i, false);
       return;
     }
@@ -304,7 +304,7 @@
       if (!isPolygonDisplayable(i))
         continue;
       int[] p = polygonIndexes[i];
-      if (frontOnly && transformedVectors[normixes[i]].z < 0)
+      if (frontOnly && !isVisibleNormix(normixes[i]))
         continue;
       for (int j = p.length - 1; --j >= 0;) {
         int pt = p[j];
@@ -370,7 +370,7 @@
       int check;
       if (mesh.isTriangleSet) {
         short normix = normixes[i];
-        if (!vwr.gdata.isDirectedTowardsCamera(normix))
+        if (frontOnly && !isVisibleNormix(normix))
           continue;
         if (fill) {
           if (isPrecision)
@@ -458,6 +458,10 @@
       exportSurface(colix);
   }
 
+  private boolean isVisibleNormix(short normix) {
+    return (normix < 0 || transformedVectors[normix].z > 0);
+  }
+
   private void drawTriangleBits(P3 screenA, short colixA, P3 screenB, short 
colixB,
                                 P3 screenC, short colixC, int check, int diam) 
{
     if (!antialias && diam == 1) {

Modified: trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java
===================================================================
--- trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java        
2015-10-20 22:40:08 UTC (rev 20839)
+++ trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java        
2015-10-20 22:41:32 UTC (rev 20840)
@@ -67,11 +67,16 @@
     if (p.visibilityFlags == 0)
       return false;
     short[] colixes = ((Polyhedra) shape).colixes;
-    int iAtom = (p.id == null ? p.centralAtom.i : -1);
-    short colix = (p.id != null ? p.colix : colixes == null || iAtom >= 
colixes.length ? C.INHERIT_ALL
+    int iAtom = -1;
+    short colix;
+    if (p.id == null) {
+      iAtom = p.centralAtom.i;
+      colix = (colixes == null || iAtom >= colixes.length ? C.INHERIT_ALL
         : colixes[iAtom]);
-    if (p.centralAtom != null)
       colix =  C.getColixInherited(colix, p.centralAtom.colixAtom);
+    } else {
+      colix = p.colix;
+    }
     boolean needTranslucent = false;
     if (C.renderPass2(colix)) {
       needTranslucent = true;
@@ -115,14 +120,13 @@
     if (!needTranslucent || g3d.setC(colix))
       for (int i = planes.length; --i >= 0;) {
         int[] pl = planes[i];
-        //if (i != m)continue;
         try {
           g3d.fillTriangleTwoSided(normixes[i], sc[pl[0]], sc[pl[1]], 
sc[pl[2]]);
         } catch (Exception e) {
-          System.out.println("heorhe");
+          System.out.println("PolyhedraRendererError");
         }
-        if (pl[3] >= 0)
-          g3d.fillTriangleTwoSided(normixes[i], sc[pl[2]], sc[pl[3]], 
sc[pl[0]]);
+//        if (pl[3] >= 0)
+  //        g3d.fillTriangleTwoSided(normixes[i], sc[pl[2]], sc[pl[3]], 
sc[pl[0]]);
       }
     // edges are not drawn translucently ever
     if (bsSelected != null && bsSelected.get(iAtom))
@@ -132,18 +136,19 @@
     if (g3d.setC(C.getColixTranslucent3(colix, false, 0)))
       for (int i = planes.length; --i >= 0;) {
         int[] pl = planes[i];
-        if (pl[3] < 0) {
-          drawFace(normixes[i], sc[pl[0]], sc[pl[1]], sc[pl[2]], -pl[3]);
-        } else {
-          drawFace(normixes[i], sc[pl[0]], sc[pl[1]], sc[pl[2]], 3);
-          drawFace(normixes[i], sc[pl[0]], sc[pl[2]], sc[pl[3]], 6);
-        }
+ //       if (pl[3] < 0) {
+         drawEdges(normixes[i], sc[pl[0]], sc[pl[1]], sc[pl[2]], -pl[3]);
+//          break;
+//        } else {
+//          drawFace(normixes[i], sc[pl[0]], sc[pl[1]], sc[pl[2]], 3);
+//          drawFace(normixes[i], sc[pl[0]], sc[pl[2]], sc[pl[3]], 6);
+//        }
 
       }
     return needTranslucent;
   }
 
-  private void drawFace(short normix, P3 a, P3 b, P3 c, int edgeMask) {
+  private void drawEdges(short normix, P3 a, P3 b, P3 c, int edgeMask) {
     if (isAll || frontOnly && vwr.gdata.isDirectedTowardsCamera(normix)) {
       int d = (g3d.isAntialiased() ? 6 : 3);
       if ((edgeMask & 1) == 1)

Modified: trunk/Jmol/src/org/jmol/script/ScriptTokenParser.java
===================================================================
--- trunk/Jmol/src/org/jmol/script/ScriptTokenParser.java       2015-10-20 
22:40:08 UTC (rev 20839)
+++ trunk/Jmol/src/org/jmol/script/ScriptTokenParser.java       2015-10-20 
22:41:32 UTC (rev 20840)
@@ -422,7 +422,7 @@
   
   boolean haveString;
   
-  private boolean clauseOr(boolean allowComma) {
+  private boolean clauseOr(boolean allowCommaAsOr) {
     haveString = false;
     if (!clauseAnd())
       return false;
@@ -433,14 +433,14 @@
     //OrNot: First OR, but if that makes no change, then NOT (special toggle)
     int tok;
     while ((tok = tokPeek())== T.opOr || tok == T.opXor
-        || tok==T.opToggle|| allowComma && tok == T.comma) {
+        || tok==T.opToggle|| allowCommaAsOr && tok == T.comma) {
       if (tok == T.comma && !haveString)
         addSubstituteTokenIf(T.comma, T.tokenOr);
       else
         addNextToken();
       if (!clauseAnd())
         return false;
-      if (allowComma && (lastToken.tok == T.rightbrace || lastToken.tok == 
T.bitset))
+      if (allowCommaAsOr && (lastToken.tok == T.rightbrace || lastToken.tok == 
T.bitset))
         haveString = true;
     }
     return true;
@@ -596,7 +596,7 @@
           if (isExpressionNext()) {
             addTokenToPostfixToken(T.o(T.expressionBegin,
                 "implicitExpressionBegin"));
-            if (!clauseOr(true))
+            if (!clauseOr(false)) // changed to FALSE 10/20 because  
@({"center":{0.0 0.0 0.0}, "xxx"...}} failed
               return false;
             if (lastToken != T.tokenCoordinateEnd) {
               addTokenToPostfixToken(T.tokenExpressionEnd);

Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java
===================================================================
--- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java       2015-10-20 22:40:08 UTC 
(rev 20839)
+++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java       2015-10-20 22:41:32 UTC 
(rev 20840)
@@ -3187,13 +3187,14 @@
      * polyhedra [at most one selection set] [type-and/or-edge or 
on/off/delete]
      */
     boolean haveBonds = (slen == 1);
+    boolean haveCenter = false;
     boolean needsGenerating = haveBonds;
     boolean onOffDelete = false;
     boolean typeSeen = false;
     boolean edgeParameterSeen = false;
     //    int lighting = T.nada; // never implemented; fullyLit does nothing
     int nAtomSets = 0;
-    e.sm.loadShape(JC.SHAPE_POLYHEDRA);
+    eval.sm.loadShape(JC.SHAPE_POLYHEDRA);
     setShapeProperty(JC.SHAPE_POLYHEDRA, "init", Boolean.TRUE);
     float translucentLevel = Float.MAX_VALUE;
     int[] colorArgb = new int[] { Integer.MIN_VALUE };
@@ -3208,6 +3209,8 @@
         needsGenerating = true;
         break;
       case T.unitcell:
+        if (id != null)
+          invArg();
         propertyName = "unitCell";
         propertyValue = Boolean.TRUE;
         needsGenerating = true;
@@ -3226,13 +3229,17 @@
         onOffDelete = true;
         break;
       case T.integer:
+        if (id != null)
+          invArg();
         propertyName = "nVertices";
         propertyValue = Integer.valueOf(intParameter(i));
         needsGenerating = true;
-        if (tokAt(i + 1) == T.comma) 
+        if (tokAt(i + 1) == T.comma)
           i++;
         break;
       case T.bonds:
+        if (id != null)
+          invArg();
         if (nAtomSets > 0)
           invPO();
         needsGenerating = true;
@@ -3243,6 +3250,8 @@
         i++;
         //$FALL-THROUGH$
       case T.decimal:
+        if (id != null)
+          invArg();
         if (nAtomSets > 0)
           invPO();
         propertyName = "radius";
@@ -3267,17 +3276,14 @@
         }
         propertyValue = Float.valueOf(floatParameter(++i));
         break;
-      case T.id:
-        if (i != 1)
-          invPO();
-        setShapeProperty(JC.SHAPE_POLYHEDRA, "id", stringParameter(++i));
-        setShapeProperty(JC.SHAPE_POLYHEDRA, "center", centerParameter(++i));
-        i = eval.iToken;
-        if (tokAt(++i) != T.to)
-          invPO();
-        //$FALL-THROUGH$
+      case T.model:
+        if (id == null)
+          invArg();
+        propertyName = "model";
+        propertyValue = Integer.valueOf(intParameter(++i));
+        break;
       case T.to:
-        if (nAtomSets > 1)
+        if (nAtomSets > 1 || id != null && !haveCenter)
           invPO();
         if ((tokAt(++i) == T.bitset || tokAt(i) == T.expressionBegin)
             && !needsGenerating) {
@@ -3301,6 +3307,8 @@
           invPO();
         switch (++nAtomSets) {
         case 1:
+          if (id != null)
+            invArg();
           propertyName = "centers";
           break;
         case 2:
@@ -3340,7 +3348,7 @@
         if (edgeParameterSeen)
           error(ScriptError.ERROR_incompatibleArguments);
         edgeParameterSeen = true;
-        propertyName = T.nameOf(eval.iToken);
+        propertyName = T.nameOf(eval.theTok);
         break;
       case T.triangles:
       case T.notriangles:
@@ -3350,6 +3358,28 @@
         // never implemented or 
         //        lighting = eval.theTok;
         continue;
+      case T.id:
+      case T.times:
+      case T.identifier:
+        if (!eval.isColorParam(i)) {
+          if (i != 1)
+            invPO();
+          setShapeProperty(
+              JC.SHAPE_POLYHEDRA,
+              "thisID",
+              id = (eval.theTok == T.id ? stringParameter(++i) : eval
+                  .optParameterAsString(i)));
+          setShapeProperty(JC.SHAPE_POLYHEDRA, "model",
+              Integer.valueOf(vwr.am.cmi));
+          if (!eval.isCenterParameter(i + 1))
+            continue;
+          propertyName = "center";
+          propertyValue = centerParameter(++i);
+          i = eval.iToken;
+          haveCenter = true;
+          break;
+        }
+        //$FALL-THROUGH$
       default:
         if (eval.isColorParam(i)) {
           colorArgb[0] = eval.getArgbParam(i);
@@ -3358,7 +3388,8 @@
         }
         invArg();
       }
-      setShapeProperty(JC.SHAPE_POLYHEDRA, propertyName, propertyValue);
+      if (propertyName != null)
+        setShapeProperty(JC.SHAPE_POLYHEDRA, propertyName, propertyValue);
       if (onOffDelete)
         return false;
     }

Modified: trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java
===================================================================
--- trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java 2015-10-20 22:40:08 UTC 
(rev 20839)
+++ trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java 2015-10-20 22:41:32 UTC 
(rev 20840)
@@ -105,11 +105,13 @@
   private float planarParam;
   private Map<String, SV> info;
   private float distanceRef;
+  private int modelIndex;
 
   @SuppressWarnings("unchecked")
   @Override
   public void setProperty(String propertyName, Object value, BS bs) {
-
+    if (thisID != null)
+      bs = new BS();
     if ("init" == propertyName) {
       faceCenterOffset = DEFAULT_FACECENTEROFFSET;
       //distanceFactor = 
@@ -117,6 +119,7 @@
       radius = 0.0f;
       nVertices = 0;
       nPoints = 0;
+      modelIndex = -1;
       bsVertices = null;
       thisID = null;
       center = null;
@@ -141,13 +144,20 @@
       return;
     }
 
+    // thisID, center, and model all involve polyhedron ID ...
+
+    if ("thisID" == propertyName) {
+      thisID = (String) value;
+      return;
+    }
+
     if ("center" == propertyName) {
       center = (P3) value;
       return;
     }
 
-    if ("id" == propertyName) {
-      thisID = (String) value;
+    if ("model" == propertyName) {
+      modelIndex = ((Integer) value).intValue();
       return;
     }
 
@@ -224,7 +234,8 @@
 
     if ("info" == propertyName) {
       info = (Map<String, SV>) value;
-      centers = BSUtil.newAndSetBit(info.get("atomIndex").intValue);
+      centers = (info.containsKey("center") ? null : BSUtil.newAndSetBit(info
+          .get("atomIndex").intValue));
       iHaveCenterBitSet = true;
       return;
     }
@@ -264,23 +275,20 @@
       // but from Color we need to identify the centers.
       bs = ("colorThis" == propertyName && iHaveCenterBitSet ? centers
           : andBitSet(bs));
-      Object cvalue = ("colorPhase" == propertyName ? ((Object[]) value)[1]
-          : value);
-      short colixEdge = ("colorPhase" == propertyName ? C
-          .getColix(((Integer) ((Object[]) value)[0]).intValue())
-          : C.INHERIT_ALL);
-      for (int i = polyhedronCount; --i >= 0;) {
-        Polyhedron p = polyhedrons[i];
-        if (thisID != null) {
-          if (thisID == p.id) {
-            p.colixEdge = colixEdge;
-            isActive = true;
-            p.colix = C.getColixO(value);
-            return;
-          }
+      boolean isPhase = ("colorPhase" == propertyName);
+      Object cvalue = (isPhase ? ((Object[]) value)[1] : value);
+      short colixEdge = (isPhase ? C.getColix(((Integer) ((Object[]) value)[0])
+          .intValue()) : C.INHERIT_ALL);
+      short colix = C.getColixO(isPhase ? cvalue : value);
+      Polyhedron p;
+      BS bs1 = findPolyBS(bs);
+      for (int i = bs1.nextSetBit(0); i >= 0; i = bs1.nextSetBit(i + 1)) {
+        p = polyhedrons[i];
+        if (p.id == null) {
+          p.colixEdge = colixEdge;          
         } else {
-          if (bs.get(p.centralAtom.i))
-            p.colixEdge = colixEdge;
+          p.colixEdge = colixEdge;
+          p.colix = colix;
         }
       }
       if (thisID != null)
@@ -293,6 +301,20 @@
     if (propertyName.indexOf("translucency") == 0) {
       // from polyhedra command, we may not be using the prior select
       // but from Color we need to identify the centers.
+      boolean isTranslucent = (value.equals("translucent"));
+      if (thisID != null) {
+        BS bs1 = findPolyBS(bs);
+        Polyhedron p;
+        for (int i = bs1.nextSetBit(0); i >= 0; i = bs1.nextSetBit(i + 1)) {
+          p = polyhedrons[i];
+          p.colix = C.getColixTranslucent3(p.colix, isTranslucent,
+              translucentLevel);
+          if (p.colixEdge != 0)
+            p.colixEdge = C.getColixTranslucent3(p.colixEdge, isTranslucent,
+                translucentLevel);
+        }
+        return;
+      }
       bs = ("translucentThis".equals(value) && iHaveCenterBitSet ? centers
           : andBitSet(bs));
       if (value.equals("translucentThis"))
@@ -318,8 +340,9 @@
     if (propertyName == "deleteModelAtoms") {
       int modelIndex = ((int[]) ((Object[]) value)[2])[0];
       for (int i = polyhedronCount; --i >= 0;) {
-        polyhedrons[i].info = null;
-        int mi = polyhedrons[i].centralAtom.mi;
+        Polyhedron p = polyhedrons[i];
+        p.info = null;
+        int mi = (p.id == null ? p.centralAtom.mi : p.modelIndex);
         if (mi == modelIndex) {
           polyhedronCount--;
           polyhedrons = (Polyhedron[]) AU.deleteElements(polyhedrons, i, 1);
@@ -344,29 +367,27 @@
 
   @Override
   public boolean getPropertyData(String property, Object[] data) {
-    int iatom;
+    int iatom = (data[0] instanceof Integer ? ((Integer) data[0]).intValue()
+        : -1);
+    String id = (data[0] instanceof String ? (String) data[0] : null);
+    Polyhedron p;
+    if (property == "checkID") {
+      return checkID(id);
+    }
     if (property == "points") {
-      iatom = ((Integer) data[0]).intValue();
-      for (int i = polyhedronCount; --i >= 0;) {
-        if (polyhedrons[i].centralAtom.i == iatom) {
-          if (polyhedrons[i].collapsed)
-            break;
-          data[1] = polyhedrons[i].vertices;
-          return true;
-        }
-      }
-      return false;
+      p = findPoly(id, iatom, false);
+      if (p == null)
+        return false;
+      data[1] = p.vertices;
+      return true;
     }
     if (property == "move") {
       M4 mat = (M4) data[1];
       if (mat == null)
         return false;
-      BS bs = (BS) data[0];
-      for (int i = polyhedronCount; --i >= 0;) {
-        Polyhedron p = polyhedrons[i];
-        if (bs.get(p.centralAtom.i))
-          p.move(mat);
-      }
+      BS bs = findPolyBS((BS) data[0]);
+      for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
+        polyhedrons[i].move(mat);        
       return true;
     }
     if (property == "centers") {
@@ -382,17 +403,20 @@
       if (smiles != null && nv == 0)
         nv = Integer.MIN_VALUE;
       for (int i = polyhedronCount; --i >= 0;) {
-        if (nv > 0 && polyhedrons[i].nVertices != nv || nv > Integer.MIN_VALUE
-            && nv < 0 && polyhedrons[i].triangles.length != -nv)
+        p = polyhedrons[i];
+        if (p.id != null)
+          continue; // for now
+        if (nv > 0 && p.nVertices != nv || nv > Integer.MIN_VALUE && nv < 0
+            && p.triangles.length != -nv)
           continue;
         if (smiles == null) {
-          bs.set(polyhedrons[i].centralAtom.i);
+          bs.set(p.centralAtom.i);
         } else if (sm != null) {
-          polyhedrons[i].getSymmetry(vwr, false);
-          String smiles0 = polyhedrons[i].polySmiles;
+          p.getSymmetry(vwr, false);
+          String smiles0 = p.polySmiles;
           try {
             if (sm.areEqual(smiles, smiles0) > 0)
-              bs.set(polyhedrons[i].centralAtom.i);
+              bs.set(p.centralAtom.i);
           } catch (Exception e) {
             e.printStackTrace();
           }
@@ -404,23 +428,53 @@
     if (property == "allInfo") {
       Lst<Map<String, Object>> info = new Lst<Map<String, Object>>();
       for (int i = polyhedronCount; --i >= 0;)
-          info.addLast(polyhedrons[i].getInfo(vwr, true));
+        info.addLast(polyhedrons[i].getInfo(vwr, true));
       data[1] = info;
-      return false;
+      return true;
     }
     if (property == "info") {
-      iatom = ((Integer) data[0]).intValue();
-      for (int i = polyhedronCount; --i >= 0;) {
-        if (polyhedrons[i].centralAtom.i == iatom) {
-          data[1] = polyhedrons[i].getInfo(vwr, true);
-          return true;
-        }
-      }
-      return false;
+      p = findPoly(id, iatom, true);
+      if (p == null)
+        return false;
+      data[1] = p.getInfo(vwr, true);
+      return true;
     }
     return getPropShape(property, data);
   }
 
+  private boolean checkID(String thisID) {
+    this.thisID = thisID;
+      return (findPolyBS(null).cardinality() > 0);
+   }
+
+  private Polyhedron findPoly(String id, int iatom, boolean allowCollapsed) {
+    for (int i = polyhedronCount; --i >= 0;) {
+      Polyhedron p = polyhedrons[i]; 
+      if (p.id == null ? p.centralAtom.i == iatom : p.id.equalsIgnoreCase(id))
+        return (allowCollapsed || !polyhedrons[i].collapsed ? polyhedrons[i] : 
null);
+    }
+   return null;
+  }
+
+  private BS bsPolys = new BS();
+  
+  private BS findPolyBS(BS bsCenters) {
+    BS bs = bsPolys;
+    bs.clearAll();
+    Polyhedron p;
+    for (int i = polyhedronCount; --i >= 0;) {
+      p = polyhedrons[i];
+      if (p.id == null ? bsCenters != null && bsCenters.get(p.centralAtom.i) : 
isMatch(p.id))
+        bs.set(i);
+    }
+    return bs;
+  }
+
+  private boolean isMatch(String id) {
+    // could implement wildcards
+    return thisID != null && PT.isMatch(id.toLowerCase(), 
thisID.toLowerCase(), true, true);
+  }
+
   @Override
   public Lst<Map<String, Object>> getShapeDetail() {
     Lst<Map<String, Object>> lst = new Lst<Map<String, Object>>();
@@ -429,22 +483,13 @@
     return lst;
   }
 
-//  private void setLighting(boolean isFullyLit, BS bs) {
-//    for (int i = polyhedronCount; --i >= 0;)
-//      if (bs.get(polyhedrons[i].centralAtom.i)) {
-//        short[] normixes = polyhedrons[i].getNormixes();
-//        polyhedrons[i].isFullyLit = isFullyLit;
-//        for (int j = normixes.length; --j >= 0;) {
-//          if (normixes[j] < 0 != isFullyLit)
-//            normixes[j] = (short) ~normixes[j];
-//        }
-//      }
-//  }
-
   private BS andBitSet(BS bs) {
     BS bsCenters = new BS();
-    for (int i = polyhedronCount; --i >= 0;)
-      bsCenters.set(polyhedrons[i].centralAtom.i);
+    for (int i = polyhedronCount; --i >= 0;) {
+      Polyhedron p = polyhedrons[i];
+      if (p.id == null)
+        bsCenters.set(p.centralAtom.i);
+    }
     bsCenters.and(bs);
     return bsCenters;
   }
@@ -452,13 +497,15 @@
   private void deletePolyhedra() {
     int newCount = 0;
     byte pid = PAL.pidOf(null);
+    BS bs = findPolyBS(centers);
     for (int i = 0; i < polyhedronCount; ++i) {
       Polyhedron p = polyhedrons[i];
-      int iAtom = p.centralAtom.i;
-      if (centers.get(iAtom))
-        setColixAndPalette(C.INHERIT_ALL, pid, iAtom);
-      else
-        polyhedrons[newCount++] = p;
+      if (bs.get(i)) {
+        if (p.id == null)
+          setColixAndPalette(C.INHERIT_ALL, pid, p.centralAtom.i);
+        continue;
+      }
+      polyhedrons[newCount++] = p;
     }
     for (int i = newCount; i < polyhedronCount; ++i)
       polyhedrons[i] = null;
@@ -466,58 +513,63 @@
   }
 
   private void setVisible(boolean visible) {
-    for (int i = polyhedronCount; --i >= 0;) {
-      Polyhedron p = polyhedrons[i];
-      if (p != null && centers.get(p.centralAtom.i))
-        p.visible = visible;
-    }
+    BS bs = findPolyBS(centers);
+    for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
+      polyhedrons[i].visible = visible;
   }
 
   private void buildPolyhedra() {
     Polyhedron p = null;
-    if (center != null) {
-      p = validatePolyhedron(center, nPoints);
+    if (thisID != null) {
+      if (PT.isWild(thisID))
+        return;
+      if (center != null)
+        p = validatePolyhedron(center, nPoints);
+    } else if (info != null && info.containsKey("id")) {
+      thisID = info.get("id").asString();
+      p = new Polyhedron().setInfo(info, vwr.ms.at);
+    }
+    if (p != null) {
+      addPolyhedron(p);
+      return;
+    }
+    boolean useBondAlgorithm = radius == 0 || bondedOnly;
+    int buildMode = (info != null ? MODE_INFO : nPoints > 0 ? MODE_POINTS
+        : haveBitSetVertices ? MODE_BITSET : useUnitCell ? MODE_UNITCELL
+            : useBondAlgorithm ? MODE_BONDING : MODE_RADIUS);
+    AtomIndexIterator iter = (buildMode == MODE_RADIUS ? ms
+        .getSelectedAtomIterator(null, false, false, false, false) : null);
+    for (int i = centers.nextSetBit(0); i >= 0; i = centers.nextSetBit(i + 1)) 
{
+      Atom atom = atoms[i];
+      p = null;
+      switch (buildMode) {
+      case MODE_BITSET:
+        p = constructBitSetPolyhedron(atom);
+        break;
+      case MODE_UNITCELL:
+        p = constructUnitCellPolygon(atom, useBondAlgorithm);
+        break;
+      case MODE_BONDING:
+        p = constructBondsPolyhedron(atom, 0);
+        break;
+      case MODE_RADIUS:
+        vwr.setIteratorForAtom(iter, i, radius);
+        p = constructRadiusPolyhedron(atom, iter);
+        break;
+      case MODE_INFO:
+        p = new Polyhedron().setInfo(info, vwr.ms.at);
+        break;
+      case MODE_POINTS:
+        p = validatePolyhedron(atom, nPoints);
+        break;
+      }
       if (p != null)
         addPolyhedron(p);
-    } else {
-      boolean useBondAlgorithm = radius == 0 || bondedOnly;
-      int buildMode = (info != null ? MODE_INFO : nPoints > 0 ? MODE_POINTS
-          : haveBitSetVertices ? MODE_BITSET : useUnitCell ? MODE_UNITCELL
-              : useBondAlgorithm ? MODE_BONDING : MODE_RADIUS);
-      AtomIndexIterator iter = (buildMode == MODE_RADIUS ? ms
-          .getSelectedAtomIterator(null, false, false, false, false) : null);
-      for (int i = centers.nextSetBit(0); i >= 0; i = centers.nextSetBit(i + 
1)) {
-        Atom atom = atoms[i];
-        p = null;
-        switch (buildMode) {
-        case MODE_BITSET:
-          p = constructBitSetPolyhedron(atom);
-          break;
-        case MODE_UNITCELL:
-          p = constructUnitCellPolygon(atom, useBondAlgorithm);
-          break;
-        case MODE_BONDING:
-          p = constructBondsPolyhedron(atom, 0);
-          break;
-        case MODE_RADIUS:
-          vwr.setIteratorForAtom(iter, i, radius);
-          p = constructRadiusPolyhedron(atom, iter);
-          break;
-        case MODE_INFO:
-          p = new Polyhedron().setInfo(info, vwr.ms.at);
-          break;
-        case MODE_POINTS:
-          p = validatePolyhedron(atom, nPoints);
-          break;
-        }
-        if (p != null)
-          addPolyhedron(p);
-        if (haveBitSetVertices)
-          break;
-      }
-      if (iter != null)
-        iter.release();
+      if (haveBitSetVertices)
+        break;
     }
+    if (iter != null)
+      iter.release();
   }
 
   private void addPolyhedron(Polyhedron p) {
@@ -731,7 +783,7 @@
         Logger.info("Polyhedron " + PT.toJSON("face[" +i + "]", triangles[i]));
     }
     //System.out.println(PT.toJSON(null, htEdgeMap));
-    return new Polyhedron().set(thisID, atomOrPt, points, nPoints, vertexCount,
+    return new Polyhedron().set(thisID, modelIndex, atomOrPt, points, nPoints, 
vertexCount,
         triangles, triangleCount, getFaces(triangles, triangleCount, 
htNormMap), normals, bsCenterPlanes, collapsed, distanceRef);
   }
   
@@ -813,8 +865,6 @@
     }
     V3 norm = normals[index];
     Integer normix = Integer.valueOf(Normix.getNormixV(norm, bsTemp));
-    //if (normix != 629)
-      //return  false;
     Object[] o = htNormMap.get(normix);
     //System.out.println(PT.toJSON(null, p1) + " " + normix);
     if (o == null) {
@@ -875,7 +925,6 @@
     String edge = normix + s + s1;
     if (htEdgeMap.containsKey(edge))
       return false;
-    //    System.out.println(edge);
     //reverse maps are in
     String edge0 = normix + s1 + s;
     Object o = htEdgeMap.get(edge0);
@@ -995,9 +1044,7 @@
     */
     for (int i = polyhedronCount; --i >= 0;) {
       Polyhedron p = polyhedrons[i];
-      if (p.id != null) {
-        p.visibilityFlags = (p.visible ? vf : 0);
-      } else {
+      if (p.id == null) {
         if (ms.at[p.centralAtom.i].isDeleted())
           p.isValid = false;
         p.visibilityFlags = (p.visible && bsModels.get(p.centralAtom.mi)
@@ -1005,6 +1052,8 @@
             && !ms.at[p.centralAtom.i].isDeleted() ? vf : 0);
         if (p.visibilityFlags != 0)
           setShapeVisibility(atoms[p.centralAtom.i], true);
+      } else {
+        p.visibilityFlags = (p.visible && (p.modelIndex < 0 || 
bsModels.get(p.modelIndex)) ? vf : 0);
       }
     }
   }

Modified: trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java
===================================================================
--- trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java        2015-10-20 
22:40:08 UTC (rev 20839)
+++ trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java        2015-10-20 
22:41:32 UTC (rev 20840)
@@ -28,6 +28,11 @@
 
 public class Polyhedron {
 
+  Map<String, Object> info;
+
+  public String id;
+  P3 center;
+
   public Atom centralAtom;
   public P3[] vertices;
   public int[][] triangles;
@@ -48,18 +53,21 @@
   public boolean isValid = true;
   public short colixEdge = C.INHERIT_ALL;
   public int visibilityFlags = 0;
-  P3 center;
-  public String id;
 
+  public short colix = C.GOLD;
+  public int modelIndex = Integer.MIN_VALUE;
+  
+
   Polyhedron() {  
   }
   
-  Polyhedron set(String id, P3 atomOrPt, P3[] points, int nPoints, int 
vertexCount,
+  Polyhedron set(String id, int modelIndex, P3 atomOrPt, P3[] points, int 
nPoints, int vertexCount,
       int[][] triangles, int triangleCount, int[][] faces, V3[] normals, BS 
bsFlat, boolean collapsed, float distanceRef) {
     
     this.distanceRef = distanceRef;
     centralAtom = (id == null  ? (Atom) atomOrPt : null);
     center = (centralAtom == null ? (P3) atomOrPt : null);
+    this.modelIndex = (centralAtom == null ? modelIndex : centralAtom.mi);
     this.id = id;
     this.nVertices = vertexCount;
     this.vertices = new P3[nPoints + 1];
@@ -81,10 +89,14 @@
   Polyhedron setInfo(Map<String, SV> info, Atom[] at) {
     try {
       collapsed = info.containsKey("collapsed");
-      center = (info.containsKey("center") ? P3.newP(SV.ptValue(info
-          .get("center"))) : null);
-      if (center == null) {
+      id = info.get("id").asString();
+      if (id == null) {
         centralAtom = at[info.get("atomIndex").intValue];
+      } else {
+        center = P3.newP(SV.ptValue(info.get("center")));
+        modelIndex = info.get("modelIndex").intValue;
+        colix = C.getColixS(info.get("color").asString());
+        colixEdge = C.getColixS(info.get("colorEdge").asString());
       }
       Lst<SV> lst = info.get("vertices").getList();
       SV vc = info.get("vertexCount");
@@ -149,23 +161,20 @@
     return ai;
   }
 
-  Map<String, Object> info;
-  public short colix;
-  
   Map<String, Object> getInfo(Viewer vwr, boolean isAll) {
     if (isAll && this.info != null && !Logger.debugging)
       return this.info;
     Map<String, Object> info = new Hashtable<String, Object>();
+    int mi = (id == null ? centralAtom.mi : modelIndex);
     if (isAll) {
       this.info = info;
-      info.put("modelIndex", Integer.valueOf(centralAtom.mi));
-      info.put("modelNumber", Integer.valueOf(centralAtom.getModelNumber()));
-      info.put("center", P3.newP(centralAtom));
-      if (center == null) {
+      if (id == null) {
+        info.put("center", P3.newP(centralAtom));
+        info.put("modelNumber", Integer.valueOf(centralAtom.getModelNumber()));
         info.put("atomNumber", Integer.valueOf(centralAtom.getAtomNumber()));
         info.put("atomName", centralAtom.getInfo());
+        info.put("element", centralAtom.getElementSymbol());
       }
-      info.put("element", centralAtom.getElementSymbol());
       info.put("triangleCount", Integer.valueOf(triangles.length));
       info.put("volume", getVolume());
       String[] names = new String[nVertices];
@@ -190,6 +199,12 @@
       if (energy != null)
         info.put("energy", energy);
     }
+    if (id != null) {
+      info.put("id", id);
+      info.put("modelIndex", Integer.valueOf(mi));
+      info.put("color", C.getHexCode(colix));
+      info.put("colorEdge", C.getHexCode(colixEdge == 0 ? colix : colixEdge));
+    }
     if (faces != null)
       info.put("faces", faces);
     if (!isAll || Logger.debugging) {
@@ -281,7 +296,7 @@
 
   String getState(Viewer vwr) {
     String ident = (id == null ? "({"+centralAtom.i+"})" : "ID " + 
Escape.e(id));
-    return "  polyhedron @{" + Escape.e(getInfo(vwr, false)) + "} " 
+    return "  polyhedron" + " @{" + Escape.e(getInfo(vwr, false)) + "} " 
         + (isFullyLit ? " fullyLit" : "") + ";"
         + (visible ? "" : "polyhedra " + ident + " off;") + "\n";
   }

Modified: trunk/Jmol/src/org/jmol/viewer/JC.java
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/JC.java      2015-10-20 22:40:08 UTC (rev 
20839)
+++ trunk/Jmol/src/org/jmol/viewer/JC.java      2015-10-20 22:41:32 UTC (rev 
20840)
@@ -689,11 +689,10 @@
 
   public final static int SHAPE_MAX_SIZE_ZERO_ON_RESTRICT = 21; //////////
   
-  public final static int SHAPE_POLYHEDRA  = 21;  // for restrict, uses 
setProperty(), not setSize()
+  public final static int SHAPE_MIN_HAS_ID  = 21; //////////
 
-  public final static int SHAPE_MIN_HAS_ID          = 22; //////////
-  public final static int SHAPE_MIN_MESH_COLLECTION = 22; //////////
-  
+  public final static int SHAPE_POLYHEDRA   = 21;  // for restrict, uses 
setProperty(), not setSize()
+
   public final static int SHAPE_DRAW        = 22;
   
   public final static int SHAPE_MAX_SPECIAL = 23; //////////

Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-10-20 22:40:08 UTC 
(rev 20839)
+++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-10-20 22:41:32 UTC 
(rev 20840)
@@ -64,8 +64,19 @@
 
 TODO: working on ID for polyhedra without atom refs
 
-Jmol.___JmolVersion="14.5.0_2015.10.18"
+Jmol.___JmolVersion="14.5.0_2015.10.20"
 
+new feature: polyhedra with arbitrary center and vertices, without atom center
+  -- for example:
+    polyhedra ID "myid" {0 0 0} TO [{1 0 0}, {0 1 0}, {0 0 1}, {-1 -1 -1}]
+
+bug fix: set platformSpeed 1 for pmesh fails
+bug fix: polyhedron EDGES fails
+bug fix: @{ {"hash":{0.1 0.1 0.1},...} } fails (attempts to turn "," into "OR")
+  -- solution is to not allow "," for OR within associative arrays
+  
+JmolVersion="14.5.0_2015.10.18"
+
 new feature: x = within(0.01, [array of points])
  -- cleans points of duplicates with a tolerance of 0.001 Angstroms
  -- allows multiple pmesh faces to be turned into polyhedra using:
@@ -85,7 +96,6 @@
 
 new feature: resolution 0.001 with PMESH and ISOSURFACE planes
  -- allows for minimum number of triangles.
- 
 
 
 bug fix: Polyhedra can have missing triangle for hexagonal faces
@@ -94,7 +104,7 @@
 
 JmolVersion="14.5.0_2015.10.17"
 
-bug fix: if (...) \n { .... not working
+bug fix: if (...) \n { .... not working (where brace is on next line)
 bug fix: CIF reader will read empty second model for IUCr files with terminal 
data_global block
 bug fix: polyhedra bonds unitcell can cause error in HTML5
 bug fix: nucleic backbone should include O atoms on P and C

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