Revision: 20837 http://sourceforge.net/p/jmol/code/20837 Author: hansonr Date: 2015-10-19 06:22:30 +0000 (Mon, 19 Oct 2015) Log Message: ----------- Jmol.___JmolVersion="14.4.0_2015.10.18"
bug fix: Polyhedra can have missing triangle for hexagonal faces bug fix: calculate symmetry can break Jmol if unit cell has been changed bug fix: DRAW POLYGON front/back nature of winding was reversed. Modified Paths: -------------- trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java trunk/Jmol/src/org/jmol/scriptext/CmdExt.java trunk/Jmol/src/org/jmol/scriptext/MathExt.java trunk/Jmol/src/org/jmol/shape/Echo.java trunk/Jmol/src/org/jmol/shape/Mesh.java trunk/Jmol/src/org/jmol/shape/MeshCollection.java trunk/Jmol/src/org/jmol/shape/Shape.java trunk/Jmol/src/org/jmol/shapecgo/CGO.java trunk/Jmol/src/org/jmol/shapespecial/Dipoles.java trunk/Jmol/src/org/jmol/shapespecial/Draw.java trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java trunk/Jmol/src/org/jmol/shapesurface/Isosurface.java trunk/Jmol/src/org/jmol/shapesurface/IsosurfaceMesh.java trunk/Jmol/src/org/jmol/shapesurface/MolecularOrbital.java trunk/Jmol/src/org/jmol/shapesurface/Pmesh.java trunk/Jmol/src/org/jmol/symmetry/Symmetry.java trunk/Jmol/src/org/jmol/util/MeshCapper.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/PropertyManager.java Modified: trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/renderspecial/PolyhedraRenderer.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -67,10 +67,11 @@ if (p.visibilityFlags == 0) return false; short[] colixes = ((Polyhedra) shape).colixes; - int iAtom = p.centralAtom.i; - short colix = (colixes == null || iAtom >= colixes.length ? C.INHERIT_ALL + int iAtom = (p.id == null ? p.centralAtom.i : -1); + short colix = (p.id != null ? p.colix : colixes == null || iAtom >= colixes.length ? C.INHERIT_ALL : colixes[iAtom]); - colix = C.getColixInherited(colix, p.centralAtom.colixAtom); + if (p.centralAtom != null) + colix = C.getColixInherited(colix, p.centralAtom.colixAtom); boolean needTranslucent = false; if (C.renderPass2(colix)) { needTranslucent = true; Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -3197,6 +3197,7 @@ setShapeProperty(JC.SHAPE_POLYHEDRA, "init", Boolean.TRUE); float translucentLevel = Float.MAX_VALUE; int[] colorArgb = new int[] { Integer.MIN_VALUE }; + String id = null; for (int i = 1; i < slen; ++i) { String propertyName = null; Object propertyValue = null; @@ -3266,6 +3267,15 @@ } 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.to: if (nAtomSets > 1) invPO(); Modified: trunk/Jmol/src/org/jmol/scriptext/MathExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -1435,7 +1435,7 @@ * * @param mp * @param args - * @param tok0 + * @param tok0 * @param isAtomProperty * @return true if no syntax problems * @throws ScriptException @@ -1452,7 +1452,9 @@ return mp.addXObj(vwr.extractProperty(args[0].value, args[1].value.toString(), -1)); } - String propertyName = (args.length > 0 ? SV.sValue(args[pt++]) : ""); + BS bsSelect = (isAtomProperty && args.length == 1 && args[0].tok == T.bitset ? SV.bsSelectVar(args[0]) : null); + String pname = (bsSelect == null && args.length > 0 ? SV.sValue(args[pt++]) : ""); + String propertyName = pname; String lc = propertyName.toLowerCase(); if (!isSelect && lc.indexOf("[select ") < 0) propertyName = lc; @@ -1464,9 +1466,48 @@ SV x = null; if (isAtomProperty) { x = mp.getX(); - if (x.tok != T.bitset) { + switch (x.tok) { + case T.bitset: + break; + case T.string: + String name = (String) x.value; + Object[] data = new Object[3]; + int shapeID; + if (name.startsWith("$")) { + // "P4".getProperty.... + name = name.substring(1); + shapeID = vwr.shm.getShapeIdFromObjectName(name); + if (shapeID >= 0) { + data[0] = name; + vwr.shm.getShapePropertyData(shapeID, "index", data); + if (data[1] != null && !pname.equals("index")) { + int index = ((Integer) data[1]).intValue(); + data[1] = vwr.shm.getShapePropertyIndex(shapeID, + pname.intern(), index); + } + } + } else { + shapeID = JC.shapeTokenIndex(T.getTokFromName(name)); + if (shapeID >= 0) { + // "isosurface".getProperty... + data[0] = pname; + data[1] = Integer.valueOf(-1); + vwr.shm.getShapePropertyData(shapeID, pname.intern(), data); + } + } + return (data[1] == null ? mp.addXStr("") : mp.addXObj(data[1])); + case T.varray: + if (bsSelect != null) { + Lst<SV> l0 = x.getList(); + Lst<SV> lst = new Lst<SV>(); + for (int i = bsSelect.nextSetBit(0); i >= 0; i = bsSelect.nextSetBit(i + 1)) + lst.addLast(l0.get(i)); + return mp.addXList(lst); + } + //$FALL-THROUGH$ + default: if (isSelect) - propertyName = "[SELECT " + propertyName + "]"; + propertyName = "[SELECT " + propertyName + "]"; return mp.addXObj(vwr.extractProperty(x, propertyName, -1)); } } @@ -3121,9 +3162,9 @@ plane = e.getHklPlane(pt); break; case T.varray: - if (last != 2) + pt = (last == 2 ? SV.ptValue(args[1]) : last == 1 ? P3.new3(Float.NaN, 0, 0) : null); + if (pt == null) return false; - pt = SV.ptValue(args[1]); break; } if (last > 0 && plane == null && pt == null @@ -3142,13 +3183,42 @@ if (pt != null) { if (args[last].tok == T.varray) { // within(dist, pt, [pt1, pt2, pt3...]) - Lst<SV> sv = args[2].getList(); + Lst<SV> sv = args[last].getList(); Lst<T3> pts = new Lst<T3>(); Bspt bspt = new Bspt(3, 0); - for (int i = sv.size(); --i >= 0;) { + CubeIterator iter; + if (Float.isNaN(pt.x)) { + // internal comparison + Point3fi p; + Point3fi[] pt3 = new Point3fi[sv.size()]; + for (int i = pt3.length; --i >= 0;) { + p = new Point3fi(); + p.setT(SV.ptValue(sv.get(i))); + p.i = i; + pt3[i] = p; + bspt.addTuple(p); + } + iter = bspt.allocateCubeIterator(); + BS bsp = BSUtil.newBitSet2(0, sv.size()); + for (int i = pt3.length; --i >= 0;) { + iter.initialize(p = pt3[i], distance, false); + float d2 = distance * distance; + int n = 0; + while (iter.hasMoreElements()) { + Point3fi pt2 = (Point3fi) iter.nextElement(); + if (bsp.get(pt2.i) && pt2.distanceSquared(p) <= d2 + && (++n > 1)) + bsp.clear(pt2.i); + } + } + for (int i = bsp.nextSetBit(0); i >= 0; i = bsp.nextSetBit(i + 1)) + pts.addLast(P3.newP(pt3[i])); + return mp.addXList(pts); + + } + for (int i = sv.size(); --i >= 0;) bspt.addTuple(SV.ptValue(sv.get(i))); - } - CubeIterator iter = bspt.allocateCubeIterator(); + iter = bspt.allocateCubeIterator(); iter.initialize(pt, distance, false); float d2 = distance * distance; while (iter.hasMoreElements()) { Modified: trunk/Jmol/src/org/jmol/shape/Echo.java =================================================================== --- trunk/Jmol/src/org/jmol/shape/Echo.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shape/Echo.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -190,7 +190,7 @@ } return false; } - return false; + return getPropShape(property, data); } @Override Modified: trunk/Jmol/src/org/jmol/shape/Mesh.java =================================================================== --- trunk/Jmol/src/org/jmol/shape/Mesh.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shape/Mesh.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -503,12 +503,20 @@ info.put("polygonCount", Integer.valueOf(pc)); info.put("haveQuads", Boolean.valueOf(haveQuads)); info.put("haveValues", Boolean.valueOf(vvs != null)); - if (vc > 0 && isAll) - info.put("vertices", AU.arrayCopyPt(vs, vc)); - if (vvs != null && isAll) - info.put("vertexValues", AU.arrayCopyF(vvs, vc)); - if (pc > 0 && isAll) - info.put("polygons", AU.arrayCopyII(pis, pc)); + if (isAll) { + if (vc > 0) { + info.put("vertices", AU.arrayCopyPt(vs, vc)); + if (bsSlabDisplay != null) + info.put("bsVertices", getVisibleVBS()); + } + if (vvs != null) + info.put("vertexValues", AU.arrayCopyF(vvs, vc)); + if (pc > 0) { + info.put("polygons", AU.arrayCopyII(pis, pc)); + if (bsSlabDisplay != null) + info.put("bsPolygons", bsSlabDisplay); + } + } return info; } Modified: trunk/Jmol/src/org/jmol/shape/MeshCollection.java =================================================================== --- trunk/Jmol/src/org/jmol/shape/MeshCollection.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shape/MeshCollection.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -379,6 +379,13 @@ @SuppressWarnings("unchecked") protected boolean getPropDataMC(String property, Object[] data) { + if (property == "keys") { + Lst<String> keys = (data[1] instanceof Lst<?> ? (Lst<String>) data[1] : new Lst<String>()); + data[1] = keys; + keys.addLast("count"); + keys.addLast("getCenter"); + // will continue on to getPropertyIndex + } if (property == "getNames") { Map<String, T> map = (Map<String, T>) data[0]; boolean withDollar = ((Boolean) data[1]).booleanValue(); @@ -404,6 +411,11 @@ data[1] = list.get(0).thisID; return true; } + if (property == "index") { + Mesh m = getMesh((String) data[0]); + data[1] = Integer.valueOf(m == null ? -1 : m.index); + return true; + } if (property == "getCenter") { String id = (String) data[0]; int index = ((Integer) data[1]).intValue(); @@ -416,7 +428,7 @@ data[2] = m.vs[m.getVertexIndexFromNumber(index)]; return true; } - return false; + return getPropShape(property, data); } /** @@ -445,8 +457,11 @@ return list; } - protected Object getPropMC(String property) { - Mesh m; + protected Object getPropMC(String property, int index) { + Mesh m = currentMesh; + if (index >= 0 + && (index >= meshCount || (m = meshes[index]) == null)) + return null; if (property == "count") { int n = 0; for (int i = 0; i < meshCount; i++) @@ -454,26 +469,34 @@ n++; return Integer.valueOf(n); } + if (property == "bsVertices") { + if (m == null) + return null; + Lst<Object> lst = new Lst<Object>(); + lst.addLast(m.vs); + lst.addLast(m.getVisibleVBS()); + return lst; + } if (property == "ID") - return (currentMesh == null ? null : currentMesh.thisID); + return (m == null ? null : m.thisID); if (property.startsWith("list")) { - clean(); - SB sb = new SB(); + clean(); + SB sb = new SB(); int k = 0; boolean isNamed = property.length() > 5; - String id = (property.equals("list") ? null : isNamed ? property.substring(5) : currentMesh == null ? null : currentMesh.thisID); + String id = (property.equals("list") ? null : isNamed ? property + .substring(5) : m == null ? null : m.thisID); for (int i = 0; i < meshCount; i++) { m = meshes[i]; if (id != null && !id.equalsIgnoreCase(m.thisID)) continue; - sb.appendI((++k)).append(" id:" + m.thisID).append( - "; model:" + vwr.getModelNumberDotted(m.modelIndex)).append( - "; vertices:" + m.vc).append( - "; polygons:" + m.pc) + sb.appendI((++k)).append(" id:" + m.thisID) + .append("; model:" + vwr.getModelNumberDotted(m.modelIndex)) + .append("; vertices:" + m.vc).append("; polygons:" + m.pc) .append("; visible:" + m.visible); float[] range = (float[]) getProperty("dataRange", 0); if (range != null) - sb.append("; dataRange:").append(Escape.eAF(range)); + sb.append("; dataRange:").append(Escape.eAF(range)); if (m.title != null) { String s = ""; for (int j = 0; j < m.title.length; j++) @@ -492,11 +515,11 @@ return sb.toString(); } if (property == "vertices") - return getVertices(currentMesh); - if (property == "getInfo") - return (currentMesh == null ? null : currentMesh.getInfo(false)); - if (property == "getData") - return (currentMesh == null ? null : currentMesh.getInfo(true)); + return getVertices(m); + if (property == "info") + return (m == null ? null : m.getInfo(false)); + if (property == "data") + return (m == null ? null : m.getInfo(true)); return null; } Modified: trunk/Jmol/src/org/jmol/shape/Shape.java =================================================================== --- trunk/Jmol/src/org/jmol/shape/Shape.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shape/Shape.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -212,17 +212,6 @@ // balls, dots, other atomshapes } - /** - * - * @param property - * @param data - * @return true if serviced - */ - public boolean getPropertyData(String property, Object[] data) { - return false; - } - - @SuppressWarnings("unchecked") protected void setPropS(String propertyName, Object value, BS bsSelected) { if (propertyName == "setProperties") { @@ -250,6 +239,25 @@ /** * * @param property + * @param data + * @return true if serviced + */ + public boolean getPropertyData(String property, Object[] data) { + return getPropShape(property, data); + } + + protected boolean getPropShape(String property, Object[] data) { + if (data[1] instanceof Integer) { + int index = ((Integer) data[1]).intValue(); + data[1] = getProperty(property, index); + return (data[1] != null); + } + return false; + } + + /** + * + * @param property * @param index * @return true if serviced */ Modified: trunk/Jmol/src/org/jmol/shapecgo/CGO.java =================================================================== --- trunk/Jmol/src/org/jmol/shapecgo/CGO.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapecgo/CGO.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -108,7 +108,14 @@ } @Override + @SuppressWarnings("unchecked") public boolean getPropertyData(String property, Object[] data) { + if (property == "keys") { + Lst<String> keys = (data[1] instanceof Lst<?> ? (Lst<String>) data[1] : new Lst<String>()); + data[1] = keys; + keys.addLast("data"); + // will continue on to getPropertyIndex + } if (property == "data") return CGOMesh.getData(data); return getPropDataMC(property, data); Modified: trunk/Jmol/src/org/jmol/shapespecial/Dipoles.java =================================================================== --- trunk/Jmol/src/org/jmol/shapespecial/Dipoles.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapespecial/Dipoles.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -423,7 +423,7 @@ } return false; } - return false; + return getPropShape(property, data); } @Override Modified: trunk/Jmol/src/org/jmol/shapespecial/Draw.java =================================================================== --- trunk/Jmol/src/org/jmol/shapespecial/Draw.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapespecial/Draw.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -478,8 +478,15 @@ } } + @SuppressWarnings("unchecked") @Override public boolean getPropertyData(String property, Object[] data) { + if (property == "keys") { + Lst<String> keys = (data[1] instanceof Lst<?> ? (Lst<String>) data[1] : new Lst<String>()); + data[1] = keys; + keys.addLast("getSpinAxis"); + // will continue on to super + } if (property == "getCenter") { String id = (String) data[0]; int index = ((Integer) data[1]).intValue(); @@ -498,11 +505,14 @@ @Override public Object getProperty(String property, int index) { + DrawMesh m = this.thisMesh; + if (index >= 0 && (index >= meshCount || (m = (DrawMesh) meshes[index]) == null)) + return null; if (property == "command") - return getCommand(thisMesh); + return getCommand(m); if (property == "type") - return Integer.valueOf(thisMesh == null ? EnumDrawType.NONE.id : thisMesh.drawType.id); - return getPropMC(property); + return Integer.valueOf(m == null ? EnumDrawType.NONE.id : m.drawType.id); + return getPropMC(property, index); } private T3 getSpinCenter(String axisID, int vertexIndex, int modelIndex) { Modified: trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java =================================================================== --- trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -117,7 +117,7 @@ if (property == "checkID") { return (checkID((String) data[0])); } - return false; + return getPropShape(property, data); } Modified: trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java =================================================================== --- trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -95,6 +95,8 @@ private boolean haveBitSetVertices; private BS centers; + private String thisID; + private P3 center; private BS bsVertices; private BS bsVertexCount; @@ -116,6 +118,8 @@ nVertices = 0; nPoints = 0; bsVertices = null; + thisID = null; + center = null; useUnitCell = false; centers = null; info = null; @@ -137,6 +141,16 @@ return; } + if ("center" == propertyName) { + center = (P3) value; + return; + } + + if ("id" == propertyName) { + thisID = (String) value; + return; + } + if ("collapsed" == propertyName) { isCollapsed = ((Boolean) value).booleanValue(); return; @@ -250,14 +264,28 @@ // 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;) - if (bs.get(polyhedrons[i].centralAtom.i)) - polyhedrons[i].colixEdge = colixEdge; - if ("colorPhase" == propertyName) - value = ((Object[]) value)[1]; + 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; + } + } else { + if (bs.get(p.centralAtom.i)) + p.colixEdge = colixEdge; + } + } + if (thisID != null) + return; + value = cvalue; propertyName = "color"; //allow super } @@ -272,15 +300,15 @@ //allow super } -// if ("token" == propertyName) { -// int tok = ((Integer) value).intValue(); -// Swit -// if (tok == T.triangles && tok == T.notriangles) { -// } else { -// setLighting(tok == T.fullylit, bs); -// } -// return; -// } + // if ("token" == propertyName) { + // int tok = ((Integer) value).intValue(); + // Swit + // if (tok == T.triangles && tok == T.notriangles) { + // } else { + // setLighting(tok == T.fullylit, bs); + // } + // return; + // } if ("radius" == propertyName) { radius = ((Float) value).floatValue(); @@ -390,7 +418,7 @@ } return false; } - return false; + return getPropShape(property, data); } @Override @@ -445,51 +473,59 @@ } } - private int buildMode; - private void buildPolyhedra() { - boolean useBondAlgorithm = radius == 0 || bondedOnly; - 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]; - Polyhedron 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; + Polyhedron p = null; + if (center != null) { + p = validatePolyhedron(center, nPoints); + 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 (p != null) { - if (polyhedronCount == polyhedrons.length) - polyhedrons = (Polyhedron[]) AU.doubleLength(polyhedrons); - polyhedrons[polyhedronCount++] = p; - } - if (haveBitSetVertices) - break; + if (iter != null) + iter.release(); } - if (iter != null) - iter.release(); } + private void addPolyhedron(Polyhedron p) { + if (polyhedronCount == polyhedrons.length) + polyhedrons = (Polyhedron[]) AU.doubleLength(polyhedrons); + polyhedrons[polyhedronCount++] = p; + } + private Polyhedron constructBondsPolyhedron(Atom atom, int otherAtomCount) { if (otherAtomCount == 0) { Bond[] bonds = atom.bonds; @@ -593,7 +629,7 @@ otherAtomCount)); } - private Polyhedron validatePolyhedron(Atom centralAtom, int vertexCount) { + private Polyhedron validatePolyhedron(P3 atomOrPt, int vertexCount) { P3[] points = otherAtoms; boolean collapsed = isCollapsed; int triangleCount = 0; @@ -603,8 +639,8 @@ float planarParam = (Float.isNaN(this.planarParam) ? DEFAULT_PLANAR_PARAM : this.planarParam); - points[vertexCount] = centralAtom; - P3 ptAve = P3.newP(centralAtom); + points[vertexCount] = atomOrPt; + P3 ptAve = P3.newP(atomOrPt); for (int i = 0; i < vertexCount; i++) ptAve.add(points[i]); ptAve.scale(1f / (vertexCount + 1)); @@ -674,7 +710,7 @@ bsCenterPlanes.set(triangleCount++); } else if (collapsed) { ptRef.setT(points[nPoints] = new P3()); - points[nPoints].scaleAdd2(offset, normal, centralAtom); + points[nPoints].scaleAdd2(offset, normal, atomOrPt); addFacet(i, j, k, ptRef, points, normals, triangles, triangleCount++, nPoints, isWindingOK, vAC); addFacet(k, i, j, ptRef, points, normals, triangles, triangleCount++, nPoints, @@ -695,7 +731,7 @@ Logger.info("Polyhedron " + PT.toJSON("face[" +i + "]", triangles[i])); } //System.out.println(PT.toJSON(null, htEdgeMap)); - return new Polyhedron().set(centralAtom, points, nPoints, vertexCount, + return new Polyhedron().set(thisID, atomOrPt, points, nPoints, vertexCount, triangles, triangleCount, getFaces(triangles, triangleCount, htNormMap), normals, bsCenterPlanes, collapsed, distanceRef); } @@ -777,6 +813,8 @@ } 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) { @@ -837,6 +875,7 @@ 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); @@ -867,6 +906,8 @@ } else { // set mask to exclude both of these. int[] p10 = (int[]) ((Object[]) o)[0]; + if (p10 == null) + return false; // already seen int i0 = ((Integer) ((Object[]) o)[1]).intValue(); p10[3] = -((-p10[3]) ^ (1 << i0)); p1[3] = -((-p1[3]) ^ (1 << i)); @@ -879,6 +920,8 @@ } } // not supported for JavaScript faceList.removeObj(b); + htEdgeMap.put(edge, new Object[] {null}); + htEdgeMap.put(edge0, new Object[] {null}); } return true; } @@ -952,13 +995,17 @@ */ for (int i = polyhedronCount; --i >= 0;) { Polyhedron p = polyhedrons[i]; - if (ms.at[p.centralAtom.i].isDeleted()) - p.isValid = false; - p.visibilityFlags = (p.visible && bsModels.get(p.centralAtom.mi) - && !ms.isAtomHidden(p.centralAtom.i) - && !ms.at[p.centralAtom.i].isDeleted() ? vf : 0); - if (p.visibilityFlags != 0) - setShapeVisibility(atoms[p.centralAtom.i], true); + if (p.id != null) { + p.visibilityFlags = (p.visible ? vf : 0); + } else { + if (ms.at[p.centralAtom.i].isDeleted()) + p.isValid = false; + p.visibilityFlags = (p.visible && bsModels.get(p.centralAtom.mi) + && !ms.isAtomHidden(p.centralAtom.i) + && !ms.at[p.centralAtom.i].isDeleted() ? vf : 0); + if (p.visibilityFlags != 0) + setShapeVisibility(atoms[p.centralAtom.i], true); + } } } @@ -977,7 +1024,7 @@ s.append(vwr.getAtomShapeState(this)); for (int i = 0; i < polyhedronCount; i++) { Polyhedron p = polyhedrons[i]; - if (p.isValid && p.colixEdge != C.INHERIT_ALL + if (p.isValid && p.id == null && p.colixEdge != C.INHERIT_ALL && bsColixSet.get(p.centralAtom.i)) appendCmd( s, Modified: trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java =================================================================== --- trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapespecial/Polyhedron.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -48,14 +48,19 @@ public boolean isValid = true; public short colixEdge = C.INHERIT_ALL; public int visibilityFlags = 0; + P3 center; + public String id; Polyhedron() { } - Polyhedron set(Atom centralAtom, P3[] points, int nPoints, int vertexCount, + Polyhedron set(String id, 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; - this.centralAtom = centralAtom; + centralAtom = (id == null ? (Atom) atomOrPt : null); + center = (centralAtom == null ? (P3) atomOrPt : null); + this.id = id; this.nVertices = vertexCount; this.vertices = new P3[nPoints + 1]; this.normals = new V3[triangleCount]; @@ -76,7 +81,11 @@ Polyhedron setInfo(Map<String, SV> info, Atom[] at) { try { collapsed = info.containsKey("collapsed"); - centralAtom = at[info.get("atomIndex").intValue]; + center = (info.containsKey("center") ? P3.newP(SV.ptValue(info + .get("center"))) : null); + if (center == null) { + centralAtom = at[info.get("atomIndex").intValue]; + } Lst<SV> lst = info.get("vertices").getList(); SV vc = info.get("vertexCount"); if (vc == null) { @@ -141,6 +150,7 @@ } Map<String, Object> info; + public short colix; Map<String, Object> getInfo(Viewer vwr, boolean isAll) { if (isAll && this.info != null && !Logger.debugging) @@ -151,8 +161,10 @@ info.put("modelIndex", Integer.valueOf(centralAtom.mi)); info.put("modelNumber", Integer.valueOf(centralAtom.getModelNumber())); info.put("center", P3.newP(centralAtom)); - info.put("atomNumber", Integer.valueOf(centralAtom.getAtomNumber())); - info.put("atomName", centralAtom.getInfo()); + if (center == null) { + info.put("atomNumber", Integer.valueOf(centralAtom.getAtomNumber())); + info.put("atomName", centralAtom.getInfo()); + } info.put("element", centralAtom.getElementSymbol()); info.put("triangleCount", Integer.valueOf(triangles.length)); info.put("volume", getVolume()); @@ -193,7 +205,12 @@ info.put("triangles", AU.arrayCopyII(triangles, triangles.length)); } info.put("vertexCount", Integer.valueOf(nVertices)); - info.put("atomIndex", Integer.valueOf(centralAtom.i)); + if (center == null) { + info.put("atomIndex", Integer.valueOf(centralAtom.i)); + } else { + info.put("id", id); + info.put("center", P3.newP(center)); + } info.put("vertices", AU.arrayCopyPt(vertices, (isAll ? nVertices : vertices.length))); int[] elemNos = new int[nVertices]; @@ -207,6 +224,8 @@ } String getSymmetry(Viewer vwr, boolean withPointGroup) { + if (id != null) + return ""; info = null; SmilesMatcherInterface sm = vwr.getSmilesMatcher(); try { @@ -261,9 +280,10 @@ } String getState(Viewer vwr) { + String ident = (id == null ? "({"+centralAtom.i+"})" : "ID " + Escape.e(id)); return " polyhedron @{" + Escape.e(getInfo(vwr, false)) + "} " + (isFullyLit ? " fullyLit" : "") + ";" - + (visible ? "" : "polyhedra ({"+centralAtom.i+"}) off;") + "\n"; + + (visible ? "" : "polyhedra " + ident + " off;") + "\n"; } public void move(M4 mat) { @@ -289,4 +309,5 @@ } return normixes; } + } Modified: trunk/Jmol/src/org/jmol/shapesurface/Isosurface.java =================================================================== --- trunk/Jmol/src/org/jmol/shapesurface/Isosurface.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapesurface/Isosurface.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -222,7 +222,7 @@ return; String id = currentMesh.thisID; int imodel = currentMesh.modelIndex; - vwr.cachePut("cache://isosurface_" + id, getPropI("jvxlDataXml")); + vwr.cachePut("cache://isosurface_" + id, getPropI("jvxlDataXml", -1)); deleteMeshI(currentMesh.index); setPropI("init", null, null); setPropI("thisID", id, null); @@ -782,18 +782,24 @@ sg.setJvxlData(jvxlData); } + @SuppressWarnings("unchecked") @Override public boolean getPropertyData(String property, Object[] data) { + if (property == "keys") { + Lst<String> keys = (data[1] instanceof Lst<?> ? (Lst<String>) data[1] : new Lst<String>()); + data[1] = keys; + keys.addLast("info"); + keys.addLast("data"); + // will continue on to super + } if (property == "colorEncoder") { IsosurfaceMesh mesh = (IsosurfaceMesh) getMesh((String) data[0]); - if (mesh == null || (data[1] = mesh.colorEncoder) == null) - return false; - return true; + return (mesh != null && (data[1] = mesh.colorEncoder) != null); } if (property == "intersectPlane") { IsosurfaceMesh mesh = (IsosurfaceMesh) getMesh((String) data[0]); - if (mesh == null) + if (mesh == null || data.length < 4) return false; data[3] = Integer.valueOf(mesh.modelIndex); mesh.getMeshSlicer().getIntersection(0, (P4) data[1], null, (Lst<P3[]>) data[2], null, null, null, false, false, T.plane, false); @@ -847,13 +853,16 @@ @Override public Object getProperty(String property, int index) { - return getPropI(property); + return getPropI(property, index); } - protected Object getPropI(String property) { - Object ret = getPropMC(property); + protected Object getPropI(String property, int index) { + IsosurfaceMesh thisMesh = this.thisMesh; + if (index >= 0 && (index >= meshCount || (thisMesh = isomeshes[index]) == null)) + return null; + Object ret = getPropMC(property, index); if (ret != null) - return ret; + return ret; if (property == "message") { String s = ""; if (shapeID == JC.SHAPE_ISOSURFACE) @@ -861,13 +870,13 @@ if (jvxlData.dataMin != Float.MAX_VALUE) s += " min=" + jvxlData.dataMin + " max=" + jvxlData.dataMax; s += "; " + JC.shapeClassBases[shapeID].toLowerCase() + " count: " - + getPropMC("count"); - return s + getPropI("dataRangeStr") + jvxlData.msg; + + getPropMC("count", index); + return s + getPropI("dataRangeStr", index) + jvxlData.msg; } if (property == "dataRange") - return getDataRange(); + return getDataRange(thisMesh); if (property == "dataRangeStr") { - float[] dataRange = getDataRange(); + float[] dataRange = getDataRange(thisMesh); return (dataRange != null && dataRange[0] != Float.MAX_VALUE && dataRange[0] != dataRange[1] ? "\nisosurface" + " full data range " + dataRange[0] + " to " + dataRange[1] @@ -881,9 +890,9 @@ if (property == "nSets") return Integer.valueOf(thisMesh == null ? 0 : thisMesh.nSets); if (property == "area") // could be Float or double[] - return (thisMesh == null ? Float.valueOf(Float.NaN) : calculateVolumeOrArea(true)); + return (thisMesh == null ? Float.valueOf(Float.NaN) : calculateVolumeOrArea(thisMesh, true)); if (property == "volume") // could be Float or double[] - return (thisMesh == null ? Float.valueOf(Float.NaN) : calculateVolumeOrArea(false)); + return (thisMesh == null ? Float.valueOf(Float.NaN) : calculateVolumeOrArea(thisMesh, false)); if (thisMesh == null) return null;//"no current isosurface"; if (property == "cutoff") @@ -899,7 +908,7 @@ jvxlData.slabInfo = null; if (property == "jvxlMeshXml" || jvxlData.vertexDataOnly || thisMesh.bsSlabDisplay != null && thisMesh.bsSlabGhost == null) { meshData = new MeshData(); - fillMeshData(meshData, MeshData.MODE_GET_VERTICES, null); + fillMeshData(meshData, MeshData.MODE_GET_VERTICES, thisMesh); meshData.polygonColorData = getPolygonColorData(meshData.pc, meshData.pcs, (meshData.colorsExplicit ? meshData.pis : null), meshData.bsSlabDisplay); } else if (thisMesh.bsSlabGhost != null) { jvxlData.slabInfo = thisMesh.slabOptions.toString(); @@ -915,7 +924,7 @@ } if (property == "command") { SB sb = new SB(); - Lst<Mesh> list = getMeshList(previousMeshID, false); + Lst<Mesh> list = getMeshList((index < 0 ? previousMeshID : thisMesh.thisID), false); for (int i = list.size(); --i >= 0;) getMeshCommand(sb, i); return sb.toString(); @@ -923,41 +932,34 @@ return null; } - private float[] getDataRange() { - return (thisMesh == null || jvxlData.jvxlPlane != null - && thisMesh.colorEncoder == null ? null : new float[] { - jvxlData.mappedDataMin, - jvxlData.mappedDataMax, - (jvxlData.isColorReversed ? jvxlData.valueMappedToBlue - : jvxlData.valueMappedToRed), - (jvxlData.isColorReversed ? jvxlData.valueMappedToRed - : jvxlData.valueMappedToBlue) }); + private float[] getDataRange(IsosurfaceMesh mesh) { + return (mesh == null ? null : mesh.getDataRange()); } - private Object calculateVolumeOrArea(boolean isArea) { + private Object calculateVolumeOrArea(IsosurfaceMesh mesh, boolean isArea) { if (isArea) { - if (thisMesh.calculatedArea != null) - return thisMesh.calculatedArea; + if (mesh.calculatedArea != null) + return mesh.calculatedArea; } else { - if (thisMesh.calculatedVolume != null) - return thisMesh.calculatedVolume; + if (mesh.calculatedVolume != null) + return mesh.calculatedVolume; } MeshData meshData = new MeshData(); - fillMeshData(meshData, MeshData.MODE_GET_VERTICES, null); - meshData.nSets = thisMesh.nSets; - meshData.vertexSets = thisMesh.vertexSets; - if (!isArea && thisMesh.jvxlData.colorDensity) { - float f = thisMesh.jvxlData.voxelVolume; - f *= (thisMesh.bsSlabDisplay == null ? thisMesh.vc : thisMesh.bsSlabDisplay.cardinality()); - return thisMesh.calculatedVolume = Float.valueOf(f); + fillMeshData(meshData, MeshData.MODE_GET_VERTICES, mesh); + meshData.nSets = mesh.nSets; + meshData.vertexSets = mesh.vertexSets; + if (!isArea && mesh.jvxlData.colorDensity) { + float f = mesh.jvxlData.voxelVolume; + f *= (mesh.bsSlabDisplay == null ? mesh.vc : mesh.bsSlabDisplay.cardinality()); + return mesh.calculatedVolume = Float.valueOf(f); } - Object ret = MeshData.calculateVolumeOrArea(meshData, thisMesh.jvxlData.thisSet, isArea, false); - if (thisMesh.nSets <= 0) - thisMesh.nSets = -meshData.nSets; + Object ret = MeshData.calculateVolumeOrArea(meshData, mesh.jvxlData.thisSet, isArea, false); + if (mesh.nSets <= 0) + mesh.nSets = -meshData.nSets; if (isArea) - thisMesh.calculatedArea = ret; + mesh.calculatedArea = ret; else - thisMesh.calculatedVolume = ret; + mesh.calculatedVolume = ret; return ret; } Modified: trunk/Jmol/src/org/jmol/shapesurface/IsosurfaceMesh.java =================================================================== --- trunk/Jmol/src/org/jmol/shapesurface/IsosurfaceMesh.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapesurface/IsosurfaceMesh.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -1003,4 +1003,15 @@ recalcAltVertices = true; } + float[] getDataRange() { + return (jvxlData.jvxlPlane != null + && colorEncoder == null ? null : new float[] { + jvxlData.mappedDataMin, + jvxlData.mappedDataMax, + (jvxlData.isColorReversed ? jvxlData.valueMappedToBlue + : jvxlData.valueMappedToRed), + (jvxlData.isColorReversed ? jvxlData.valueMappedToRed + : jvxlData.valueMappedToBlue) }); + } + } Modified: trunk/Jmol/src/org/jmol/shapesurface/MolecularOrbital.java =================================================================== --- trunk/Jmol/src/org/jmol/shapesurface/MolecularOrbital.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapesurface/MolecularOrbital.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -315,11 +315,11 @@ @SuppressWarnings("unchecked") @Override - public Object getProperty(String propertyName, int param) { + public Object getProperty(String propertyName, int index) { if (propertyName.startsWith("list")) { String s = ""; if (propertyName.equals("list")) { - s = (String) getPropI("list"); + s = (String) getPropI("list", index); if (s.length() > 1) s += "cutoff = " + jvxlData.cutoff + "\n"; s = "\n" + s; @@ -335,7 +335,7 @@ Lst<Map<String, Object>> mos = (Lst<Map<String, Object>>) (sg.params.moData .get("mos")); int nOrb = (mos == null ? 0 : mos.size()); - int thisMO = param; + int thisMO = index; int currentMO = moNumber; boolean isShowCurrent = (thisMO == Integer.MIN_VALUE); if (thisMO == Integer.MAX_VALUE) { @@ -374,7 +374,7 @@ true, 0, null, null)); return str.toString(); } - return getPropI(propertyName); + return getPropI(propertyName, index); } @SuppressWarnings("unchecked") Modified: trunk/Jmol/src/org/jmol/shapesurface/Pmesh.java =================================================================== --- trunk/Jmol/src/org/jmol/shapesurface/Pmesh.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/shapesurface/Pmesh.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -24,10 +24,106 @@ package org.jmol.shapesurface; +import java.util.Hashtable; +import java.util.Map; + +import org.jmol.shape.Mesh; + +import javajs.util.Measure; +import javajs.util.P3; +import javajs.util.T3; +import javajs.util.V3; + public class Pmesh extends Isosurface { @Override public void initShape() { super.initShape(); myType = "pmesh"; } + + @Override + public Object getProperty(String property, int index) { + if (property == "face") { + Mesh m = currentMesh; + if (index >= 0 + && (index >= meshCount || (m = meshes[index]) == null)) + return null; + return m == null ? null : getFace(m); + } + return getPropI(property, index); + } + + /** + * return a cycle of points generating this face + * used after slabbing + * + * @param m + * @return set of points constituting this face + */ + private P3[] getFace(Mesh m) { + if (m.haveQuads) + return null; + T3[] vs = m.vs; + Map<String, int[]> htEdges = new Hashtable<String, int[]>(); + int v1 = 0; + int n = 0; + for (int i = m.pc; --i >= 0;) { + if (m.bsSlabDisplay != null && !m.bsSlabDisplay.get(i)) + continue; + int[] face = m.pis[i]; + int mask = face[3]; + for (int j = 0; j < 3; j++) + if ((mask & (1 << j)) != 0) { + v1 = face[j]; + int v2 = face[(j + 1) % 3]; + String key = v2 + "_" + v1; + if (htEdges.containsKey(key)) { + htEdges.remove(key); + n--; + } else { + n++; + htEdges.put(v1 + "_" + v2, new int[] { v1, v2 }); + htEdges.put("" + v1, new int[] { v1, v2 }); + } + } + } + if (n == 0) + return null; + int[][] a = new int[n][2]; + for (String e : htEdges.keySet()) { + a[0] = htEdges.get(e); + break; + } + V3 vectorBA = new V3(); + V3 vectorBC = new V3(); + int v0 = a[0][0]; + int v01 = v0; + v1 = a[0][1]; + int pt = 0; + while (v1 != v0) { + int[] edge = htEdges.get("" + v1); + if (edge == null) + break; + float angle = Measure.computeAngle(vs[v01], vs[v1], vs[edge[1]], + vectorBA, vectorBC, true); + v1 = edge[1]; + if (angle < 179) { + a[++pt] = edge; + v01 = edge[0]; + } else { + a[pt][1] = v1; + } + } + if (Measure.computeAngle(vs[v01], vs[v1], vs[a[0][1]], + vectorBA, vectorBC, true) >= 179) { + a[0][0] = a[pt--][0]; + } + n = ++pt; + P3[] pts = new P3[n]; + for (int i = 0; i < n; i++) + pts[i] = P3.newP(vs[a[i][0]]); + return pts; + } + + } Modified: trunk/Jmol/src/org/jmol/symmetry/Symmetry.java =================================================================== --- trunk/Jmol/src/org/jmol/symmetry/Symmetry.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/symmetry/Symmetry.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -318,12 +318,12 @@ @Override public int[] getCellRange() { - return symmetryInfo.cellRange; + return symmetryInfo == null ? null : symmetryInfo.cellRange; } @Override public String getSymmetryInfoStr() { - return symmetryInfo.infoStr; + return (symmetryInfo == null ? "" : symmetryInfo.infoStr); } @Override Modified: trunk/Jmol/src/org/jmol/util/MeshCapper.java =================================================================== --- trunk/Jmol/src/org/jmol/util/MeshCapper.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/util/MeshCapper.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -85,6 +85,8 @@ private Lst<int[]> lstTriangles; + private int nPoints; + /////////////// initialization ////////////////// /** @@ -107,21 +109,22 @@ * generic entry for a polygon * * @param points - * @return int[][i j k 7] + * @return int[][i j k mask] */ public int[][] triangulatePolygon(P3[] points) { clear(); - - int n = points.length; + // this is winding backward + nPoints = points.length; CapVertex v0 = null; - for (int i = 0; i < n; i++) { + for (int i = 0; i < nPoints; i++) { CapVertex v = new CapVertex(points[i], i); vertices.addLast(v); - if (v0 != null) - v.link(v0); + if (v0 != null) { + v0.link(v); + } v0 = v; } - vertices.get(0).link(v0); + v0.link(vertices.get(0)); lstTriangles = new Lst<int[]>(); createCap(null); int[][] a = AU.newInt2(lstTriangles.size()); @@ -188,12 +191,24 @@ * @param ipt3 */ private void outputTriangle(int ipt1, int ipt2, int ipt3) { - if (slicer == null) - lstTriangles.addLast(new int[] { ipt1, ipt2, ipt3, 7 }); - else + if (slicer == null) { + int mask = 0; + if (isEdge(ipt1, ipt2)) + mask |= 1; + if (isEdge(ipt2, ipt3)) + mask |= 2; + if (isEdge(ipt3, ipt1)) + mask |= 4; + lstTriangles.addLast(new int[] { ipt1, ipt2, ipt3, mask }); + } else { slicer.addTriangle(ipt1, ipt2, ipt3); + } } + private boolean isEdge(int i, int j) { + return (j == (i + 1) % nPoints); + } + private CapVertex[] test(CapVertex[] vs) { // dumping = testing = true; // int n = 0; @@ -242,7 +257,7 @@ V3 vab = V3.newVsub(vertices.get(0), vertices.get(1)); V3 vac; if (norm == null) { - vac = V3.newVsub(vertices.get(vertices.size() - 1), vertices.get(0)); + vac = V3.newVsub(vertices.get(0), vertices.get(vertices.size() - 1)); } else { vac = V3.newV(norm); vac.cross(vac, vab); Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-10-19 06:22:30 UTC (rev 20837) @@ -62,8 +62,16 @@ TODO: consider if models with no atoms will cause issues in relation to model.firstAtomIndex -Jmol.___JmolVersion="14.5.0_2015.10.17" +TODO: working on ID for polyhedra without atom refs +Jmol.___JmolVersion="14.4.0_2015.10.18" + +bug fix: Polyhedra can have missing triangle for hexagonal faces +bug fix: calculate symmetry can break Jmol if unit cell has been changed +bug fix: DRAW POLYGON front/back nature of winding was reversed. + +JmolVersion="14.5.0_2015.10.17" + bug fix: if (...) \n { .... not working 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 Modified: trunk/Jmol/src/org/jmol/viewer/PropertyManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/PropertyManager.java 2015-10-17 23:45:49 UTC (rev 20836) +++ trunk/Jmol/src/org/jmol/viewer/PropertyManager.java 2015-10-19 06:22:30 UTC (rev 20837) @@ -779,9 +779,9 @@ params.indexOf("g64") < 0 && params.indexOf("base64") < 0 && (returnType == null || returnType.equalsIgnoreCase("java"))); case PROP_ISOSURFACE_INFO: - return vwr.getShapeProperty(JC.SHAPE_ISOSURFACE, "getInfo"); + return vwr.getShapeProperty(JC.SHAPE_ISOSURFACE, "info"); case PROP_ISOSURFACE_DATA: - return vwr.getShapeProperty(JC.SHAPE_ISOSURFACE, "getData"); + return vwr.getShapeProperty(JC.SHAPE_ISOSURFACE, "data"); case PROP_NMR_INFO: return vwr.getNMRCalculation().getInfo(myParam.toString()); case PROP_VAR_INFO: 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