1 /* $RCSfile$ 2 * $Author: hansonr $ 3 * $Date: 2006-03-05 12:22:08 -0600 (Sun, 05 Mar 2006) $ 4 * $Revision: 4545 $ 5 * 6 * Copyright (C) 2002-2005 The Jmol Development Team 7 * 8 * Contact: jmol-developers@lists.sf.net 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 25 package org.jmol.scriptext; 26 27 import java.util.Map; 28 29 import javajs.util.AU; 30 import javajs.util.Lst; 31 import javajs.util.M4; 32 import javajs.util.P3; 33 import javajs.util.P4; 34 import javajs.util.PT; 35 import javajs.util.Quat; 36 import javajs.util.SB; 37 import javajs.util.T3; 38 import javajs.util.V3; 39 40 import org.jmol.adapter.readers.quantum.GenNBOReader; 41 import org.jmol.api.Interface; 42 import org.jmol.api.JmolDataManager; 43 import org.jmol.api.SymmetryInterface; 44 import org.jmol.atomdata.RadiusData; 45 import org.jmol.atomdata.RadiusData.EnumType; 46 import org.jmol.c.VDW; 47 import javajs.util.BS; 48 import org.jmol.modelset.Atom; 49 import org.jmol.quantum.MepCalculation; 50 import org.jmol.script.SV; 51 import org.jmol.script.ScriptError; 52 import org.jmol.script.ScriptEval; 53 import org.jmol.script.ScriptException; 54 import org.jmol.script.ScriptInterruption; 55 import org.jmol.script.T; 56 import org.jmol.shape.MeshCollection; 57 import org.jmol.util.BSUtil; 58 import org.jmol.util.BoxInfo; 59 import org.jmol.util.C; 60 import org.jmol.util.ColorEncoder; 61 import org.jmol.util.Escape; 62 import org.jmol.util.Logger; 63 import org.jmol.util.MeshCapper; 64 import org.jmol.util.Parser; 65 import org.jmol.util.SimpleUnitCell; 66 import org.jmol.util.TempArray; 67 import org.jmol.util.Triangulator; 68 import org.jmol.viewer.JC; 69 import org.jmol.viewer.JmolAsyncException; 70 71 public class IsoExt extends ScriptExt { 72 IsoExt()73 public IsoExt() { 74 // used by Reflection 75 } 76 77 @Override dispatch(int iTok, boolean b, T[] st)78 public String dispatch(int iTok, boolean b, T[] st) throws ScriptException { 79 chk = e.chk; 80 slen = e.slen; 81 this.st = st; 82 83 switch (iTok) { 84 case JC.SHAPE_CGO: 85 cgo(); 86 break; 87 case JC.SHAPE_CONTACT: 88 contact(); 89 break; 90 case JC.SHAPE_DIPOLES: 91 dipole(); 92 break; 93 case JC.SHAPE_DRAW: 94 draw(); 95 break; 96 case JC.SHAPE_ISOSURFACE: 97 case JC.SHAPE_PLOT3D: 98 case JC.SHAPE_PMESH: 99 isosurface(iTok); 100 break; 101 case JC.SHAPE_LCAOCARTOON: 102 lcaoCartoon(); 103 break; 104 case JC.SHAPE_MO: 105 case JC.SHAPE_NBO: 106 mo(b, iTok); 107 break; 108 } 109 return null; 110 } 111 dipole()112 private void dipole() throws ScriptException { 113 ScriptEval eval = e; 114 // dipole intWidth floatMagnitude OFFSET floatOffset {atom1} {atom2} 115 String propertyName = null; 116 Object propertyValue = null; 117 boolean iHaveAtoms = false; 118 boolean iHaveCoord = false; 119 boolean idSeen = false; 120 boolean getCharges = false; 121 BS bsSelected = null; 122 123 eval.sm.loadShape(JC.SHAPE_DIPOLES); 124 if (tokAt(1) == T.list && listIsosurface(JC.SHAPE_DIPOLES)) 125 return; 126 setShapeProperty(JC.SHAPE_DIPOLES, "init", null); 127 if (slen == 1) { 128 setShapeProperty(JC.SHAPE_DIPOLES, "thisID", null); 129 return; 130 } 131 for (int i = 1; i < slen; ++i) { 132 propertyName = null; 133 propertyValue = null; 134 switch (getToken(i).tok) { 135 case T.all: 136 propertyName = "all"; 137 getCharges = true; 138 break; 139 case T.on: 140 propertyName = "on"; 141 break; 142 case T.off: 143 propertyName = "off"; 144 break; 145 case T.delete: 146 propertyName = "delete"; 147 break; 148 case T.integer: 149 case T.decimal: 150 propertyName = "value"; 151 propertyValue = Float.valueOf(floatParameter(i)); 152 break; 153 case T.bitset: 154 if (tokAt(i + 1) == T.bitset) { 155 // fix for atomno2 < atomno1 156 setShapeProperty(JC.SHAPE_DIPOLES, "startSet", atomExpressionAt(i++)); 157 } else { 158 // early Jmol 159 propertyName = "atomBitset"; 160 } 161 //$FALL-THROUGH$ 162 case T.expressionBegin: 163 if (propertyName == null) 164 propertyName = (iHaveAtoms || iHaveCoord ? "endSet" : "startSet"); 165 propertyValue = bsSelected = atomExpressionAt(i); 166 i = eval.iToken; 167 if (tokAt(i + 1) == T.nada && propertyName == "startSet") 168 propertyName = "atomBitset"; 169 iHaveAtoms = true; 170 getCharges = true; 171 break; 172 case T.leftbrace: 173 case T.point3f: 174 // {X, Y, Z} 175 P3 pt = getPoint3f(i, true); 176 i = eval.iToken; 177 propertyName = (iHaveAtoms || iHaveCoord ? "endCoord" : "startCoord"); 178 propertyValue = pt; 179 iHaveCoord = true; 180 break; 181 case T.bonds: 182 propertyName = "bonds"; 183 getCharges = true; 184 break; 185 case T.calculate: 186 getCharges = true; 187 propertyName = "calculate"; 188 if (eval.isAtomExpression(i + 1)) { 189 propertyValue = bsSelected = atomExpressionAt(++i); 190 i = eval.iToken; 191 } 192 break; 193 case T.id: 194 setShapeId(JC.SHAPE_DIPOLES, ++i, idSeen); 195 i = eval.iToken; 196 break; 197 case T.cross: 198 propertyName = "cross"; 199 propertyValue = Boolean.TRUE; 200 break; 201 case T.nocross: 202 propertyName = "cross"; 203 propertyValue = Boolean.FALSE; 204 break; 205 case T.offset: 206 if (isFloatParameter(i + 1)) { 207 float v = floatParameter(++i); 208 if (eval.theTok == T.integer) { 209 propertyName = "offsetPercent"; 210 propertyValue = Integer.valueOf((int) v); 211 } else { 212 propertyName = "offset"; 213 propertyValue = Float.valueOf(v); 214 } 215 } else { 216 propertyName = "offsetPt"; 217 propertyValue = centerParameter(++i); 218 i = eval.iToken; 219 } 220 break; 221 case T.offsetside: 222 propertyName = "offsetSide"; 223 propertyValue = Float.valueOf(floatParameter(++i)); 224 break; 225 case T.val: 226 propertyName = "value"; 227 propertyValue = Float.valueOf(floatParameter(++i)); 228 break; 229 case T.width: 230 propertyName = "width"; 231 propertyValue = Float.valueOf(floatParameter(++i)); 232 break; 233 default: 234 if (eval.theTok == T.times || T.tokAttr(eval.theTok, T.identifier)) { 235 setShapeId(JC.SHAPE_DIPOLES, i, idSeen); 236 i = eval.iToken; 237 break; 238 } 239 invArg(); 240 } 241 idSeen = (eval.theTok != T.delete && eval.theTok != T.calculate); 242 if (getCharges) { 243 // ensures that we do have charges and catch the Script interruption if asynchronous 244 if (!chk) 245 eval.getPartialCharges(bsSelected); 246 getCharges = false; 247 } 248 if (propertyName != null) 249 setShapeProperty(JC.SHAPE_DIPOLES, propertyName, propertyValue); 250 } 251 if (iHaveCoord || iHaveAtoms) 252 setShapeProperty(JC.SHAPE_DIPOLES, "set", null); 253 } 254 draw()255 private void draw() throws ScriptException { 256 ScriptEval eval = e; 257 eval.sm.loadShape(JC.SHAPE_DRAW); 258 switch (tokAt(1)) { 259 case T.list: 260 if (listIsosurface(JC.SHAPE_DRAW)) 261 return; 262 break; 263 case T.helix: 264 case T.quaternion: 265 case T.ramachandran: 266 e.getCmdExt().dispatch(T.plot, false, st); 267 return; 268 } 269 boolean havePoints = false; 270 boolean isInitialized = false; 271 boolean isSavedState = false; 272 boolean isIntersect = false; 273 boolean isFrame = false; 274 P4 plane; 275 int tokIntersect = 0; 276 float translucentLevel = Float.MAX_VALUE; 277 int[] colorArgb = new int[] { Integer.MIN_VALUE }; 278 int intScale = 0; 279 String swidth = ""; 280 int iptDisplayProperty = 0; 281 P3 center = null; 282 String thisId = initIsosurface(JC.SHAPE_DRAW); 283 boolean idSeen = (thisId != null); 284 boolean isWild = (idSeen && getShapeProperty(JC.SHAPE_DRAW, "ID") == null); 285 int[] connections = null; 286 int iConnect = 0; 287 int iArray = -1; 288 SymmetryInterface uc = null; 289 for (int i = eval.iToken; i < slen; ++i) { 290 String propertyName = null; 291 Object propertyValue = null; 292 int tok = getToken(i).tok; 293 switch (tok) { 294 case T.pointgroup: 295 // draw pointgroup [array of points] CENTER xx 296 // draw pointgroup SPACEGROUP 297 // draw pointgroup [C2|C3|Cs|Ci|etc.] [n] [scale x] 298 P3[] pts = (eval.isArrayParameter(++i) 299 ? eval.getPointArray(i, -1, false) 300 : null); 301 if (pts != null) { 302 i = eval.iToken + 1; 303 if (tokAt(i) == T.center) { 304 center = eval.centerParameter(++i, null); 305 i = eval.iToken + 1; 306 } 307 } 308 String type; 309 switch (tokAt(i)) { 310 case T.scale: 311 type = ""; 312 break; 313 case T.chemicalshift: 314 type = "Cs"; 315 break; 316 case T.dollarsign: 317 Object[] data = new Object[] { eval.objectNameParameter(++i), null }; 318 if (chk) 319 return; 320 vwr.shm.getShapePropertyData(JC.SHAPE_POLYHEDRA, "points", data); 321 pts = (P3[]) data[1]; 322 if (pts == null) 323 invArg(); 324 type = ""; 325 break; 326 case T.polyhedra: 327 type = ":poly"; 328 break; 329 case T.spacegroup: 330 if (center == null) 331 center = new P3(); 332 Lst<P3> crpts = vwr.ms.generateCrystalClass(vwr.bsA().nextSetBit(0), 333 P3.new3(Float.NaN, Float.NaN, Float.NaN)); 334 if (pts != null) 335 invArg(); 336 pts = new P3[crpts.size()]; 337 for (int j = crpts.size(); --j >= 0;) 338 pts[j] = crpts.get(j); 339 i++; 340 type = ""; 341 break; 342 default: 343 type = eval.optParameterAsString(i); 344 break; 345 } 346 float scale = (intScale == 0 ? 1 : intScale/100f); 347 int index = 0; 348 if (type.length() > 0) { 349 if (isFloatParameter(++i)) 350 index = intParameter(i++); 351 } 352 if (tokAt(i) == T.scale) 353 scale = floatParameter(++i); 354 if (!chk) 355 eval.runScript(vwr.ms.getPointGroupAsString(vwr.bsA(), type, index, 356 scale, pts, center, thisId == null ? "" : thisId)); 357 return; 358 case T.unitcell: 359 case T.boundbox: 360 if (chk) 361 break; 362 if (tok == T.boundbox && tokAt(i + 1) == T.best) { 363 tok = T.unitcell; 364 } 365 if (tok == T.unitcell) { 366 if (eval.isArrayParameter(i + 1)) { 367 P3[] oabc = eval.getPointArray(i + 1, -1, false); 368 uc = vwr.getSymTemp().getUnitCell(oabc, false, null); 369 i = eval.iToken; 370 } else if (tokAt(i + 1) == T.best) { 371 i++; 372 uc = vwr.getSymTemp().getUnitCell( 373 (P3[]) vwr.getOrientationText(T.unitcell, "array", null), false, 374 null); 375 } else { 376 uc = vwr.getCurrentUnitCell(); 377 } 378 if (uc == null) 379 invArg(); 380 } 381 Lst<Object> vp = getPlaneIntersection(tok, null, uc, intScale / 100f, 382 0); 383 intScale = 0; 384 propertyName = "polygon"; 385 propertyValue = vp; 386 havePoints = true; 387 break; 388 case T.connect: 389 connections = new int[4]; 390 iConnect = 4; 391 float[] farray = eval.floatParameterSet(++i, 4, 4); 392 i = eval.iToken; 393 for (int j = 0; j < 4; j++) 394 connections[j] = (int) farray[j]; 395 havePoints = true; 396 break; 397 case T.bonds: 398 case T.atoms: 399 if (connections == null 400 || iConnect > (eval.theTok == T.bondcount ? 2 : 3)) { 401 iConnect = 0; 402 connections = new int[] { -1, -1, -1, -1 }; 403 } 404 connections[iConnect++] = atomExpressionAt(++i).nextSetBit(0); 405 i = eval.iToken; 406 connections[iConnect++] = (eval.theTok == T.bonds 407 ? atomExpressionAt(++i).nextSetBit(0) 408 : -1); 409 i = eval.iToken; 410 havePoints = true; 411 break; 412 case T.slab: 413 switch (getToken(++i).tok) { 414 case T.dollarsign: 415 propertyName = "slab"; 416 propertyValue = eval.objectNameParameter(++i); 417 i = eval.iToken; 418 havePoints = true; 419 break; 420 default: 421 invArg(); 422 } 423 break; 424 case T.intersection: 425 switch (getToken(i + 1).tok) { 426 case T.unitcell: 427 case T.boundbox: 428 tokIntersect = eval.theTok; 429 isIntersect = true; 430 continue; 431 case T.dollarsign: 432 propertyName = "intersect"; 433 propertyValue = eval.objectNameParameter(++i); 434 i = eval.iToken; 435 isIntersect = true; 436 havePoints = true; 437 break; 438 default: 439 invArg(); 440 } 441 break; 442 case T.polyhedra: 443 case T.point: 444 case T.polygon: 445 tok = eval.theTok; 446 boolean isPoints = (tok == T.point); 447 propertyName = "polygon"; 448 havePoints = true; 449 Lst<Object> v = new Lst<Object>(); 450 int nVertices = 0; 451 int nTriangles = 0; 452 P3[] points = null; 453 Lst<SV> vpolygons = null; 454 int[][] polygons = null; 455 if (eval.isArrayParameter(++i)) { 456 // draw POLYGON [points] 457 points = eval.getPointArray(i, -1, true); 458 if (points.length > 0 && points[0] == null) { 459 int[][] faces; 460 if (tok == T.polyhedra) { 461 faces = getIntArray2(i); 462 } else { 463 faces = AU.newInt2(1); 464 faces[0] = (int[]) eval.expandFloatArray( 465 eval.floatParameterSet(i, -1, Integer.MAX_VALUE), -1, false); 466 } 467 points = getAllPoints(e.iToken + 1, 3); 468 try { 469 polygons = ((MeshCapper) Interface 470 .getInterface("org.jmol.util.MeshCapper", vwr, "script")) 471 .set(null).triangulateFaces(faces, points, null); 472 } catch (Throwable e) { 473 invArg(); 474 } 475 } 476 nVertices = points.length; 477 } 478 479 if (tok == T.polyhedra) { 480 // draw POLYHEDRA @x @y 481 // where x is [[0,3,4][4,5,6] ...] where numbers are atom indices 482 // and optional y is an atom bitset or a list of points 483 nVertices = points.length; 484 } 485 486 if (points == null) { 487 // draw POLYGON nPoints pt1 pt2 pt3... 488 nVertices = Math.max(0, intParameter(i)); 489 points = new P3[nVertices]; 490 for (int j = 0; j < nVertices; j++) 491 points[j] = centerParameter(++eval.iToken); 492 } 493 i = eval.iToken; 494 switch (tokAt(i + 1)) { 495 case T.matrix3f: 496 case T.matrix4f: 497 // draw POLYGON <points> [[0,1,2],[1,2,3]...] 498 vpolygons = SV.newT(getToken(++i)).toArray().getList(); 499 nTriangles = vpolygons.size(); 500 break; 501 case T.varray: 502 // draw POLYGON <points> [[0,1,2],[1,2,3]...] 503 vpolygons = ((SV) getToken(++i)).getList(); 504 nTriangles = vpolygons.size(); 505 break; 506 case T.integer: 507 // draw POLYGON <points> nTriangles 508 nTriangles = intParameter(++i); 509 if (nTriangles < 0) 510 isPoints = true; 511 break; 512 default: 513 // get triangles from a list of points 514 if (polygons == null && !isPoints && !chk) 515 polygons = ((MeshCapper) Interface 516 .getInterface("org.jmol.util.MeshCapper", vwr, "script")) 517 .set(null).triangulatePolygon(points, -1); 518 } 519 if (polygons == null && !isPoints) { 520 // read array of arrays of triangle vertex pointers 521 polygons = AU.newInt2(nTriangles); 522 for (int j = 0; j < nTriangles; j++) { 523 float[] f = (vpolygons == null 524 ? eval.floatParameterSet(++eval.iToken, 3, 4) 525 : SV.flistValue(vpolygons.get(j), 0)); 526 if (f.length < 3 || f.length > 4) 527 invArg(); 528 polygons[j] = new int[] { (int) f[0], (int) f[1], (int) f[2], 529 (f.length == 3 ? 7 : (int) f[3]) }; 530 } 531 } 532 if (nVertices > 0) { 533 v.addLast(points); 534 v.addLast(polygons); 535 } else { 536 v = null; 537 } 538 propertyValue = v; 539 i = eval.iToken; 540 break; 541 case T.spacegroup: 542 case T.symop: 543 String xyz = null; 544 int iSym = Integer.MAX_VALUE; 545 plane = null; 546 P3 target = null; 547 BS bsAtoms = null; 548 int options = 0; 549 P3 trans = null; 550 if (tok == T.symop) { 551 iSym = 0; 552 switch (tokAt(++i)) { 553 case T.string: 554 xyz = stringParameter(i); 555 break; 556 case T.matrix4f: 557 xyz = SV.sValue(getToken(i)); 558 break; 559 case T.integer: 560 default: 561 if (!eval.isCenterParameter(i)) { 562 iSym = intParameter(i++); 563 if (eval.isArrayParameter(i)) { 564 trans = P3.newA(eval.floatParameterSet(i, 3, 3)); 565 i = ++eval.iToken; 566 } 567 } 568 Object[] ret = new Object[] { null, vwr.getFrameAtoms() }; 569 if (eval.isCenterParameter(i)) 570 center = eval.centerParameter(i, ret); 571 if (eval.isCenterParameter(eval.iToken + 1)) 572 target = eval.centerParameter(++eval.iToken, ret); 573 if (chk) 574 return; 575 i = eval.iToken; 576 } 577 } 578 if (center == null && i + 1 < slen) { 579 center = centerParameter(++i); 580 // draw ID xxx symop [n or "x,-y,-z"] [optional {center}] 581 // so we also check here for the atom set to get the right model 582 bsAtoms = (eval.isAtomExpression(i) ? atomExpressionAt(i) : null); 583 i = eval.iToken; 584 } 585 int nth = (target != null && tokAt(i + 1) == T.integer 586 ? eval.getToken(++i).intValue 587 : -1); 588 if (tokAt(i + 1) == T.unitcell) { 589 target = new P3(); 590 options = T.offset; 591 i++; 592 eval.iToken = i; 593 } else if (tokAt(i + 1) == T.offset) { 594 i++; 595 target = getPoint3f(i + 1, false); 596 options = T.offset; 597 i = eval.iToken; 598 } 599 600 eval.checkLast(eval.iToken); 601 if (!chk) { 602 String s = ""; 603 if (bsAtoms == null && vwr.am.cmi >= 0) 604 bsAtoms = vwr.getModelUndeletedAtomsBitSet(vwr.am.cmi); 605 if (bsAtoms != null) { 606 s = null; 607 int iatom = bsAtoms.nextSetBit(0); 608 if (options != 0) { 609 // options is T.offset, and target is an {i j k} offset from cell 555 610 Object o = vwr.getSymmetryInfo(iatom, xyz, iSym, trans, center, 611 target, T.point, null, intScale / 100f, nth, options); 612 if (o instanceof P3) 613 target = (P3) o; 614 else 615 s = ""; 616 } 617 if (thisId == null) 618 thisId = "sym"; 619 if (s == null) 620 s = (String) vwr.getSymmetryInfo(iatom, xyz, iSym, trans, center, 621 target, T.draw, thisId, intScale / 100f, nth, options); 622 } 623 eval.runBufferedSafely( 624 s.length() > 0 ? s : "draw ID \"" + thisId + "_*\" delete", 625 eval.outputBuffer); 626 } 627 return; 628 case T.frame: 629 isFrame = true; 630 // draw ID xxx frame {center} {q1 q2 q3 q4} 631 continue; 632 case T.leftbrace: 633 case T.point4f: 634 case T.point3f: 635 // {X, Y, Z} 636 if (eval.theTok == T.point4f || !eval.isPoint3f(i)) { 637 propertyValue = eval.getPoint4f(i); 638 if (isFrame) { 639 eval.checkLast(eval.iToken); 640 if (!chk) 641 eval.runScript(Escape.drawQuat(Quat.newP4((P4) propertyValue), 642 (thisId == null ? "frame" : thisId), " " + swidth, 643 (center == null ? new P3() : center), intScale / 100f)); 644 return; 645 } 646 propertyName = "planedef"; 647 } else { 648 propertyValue = center = getPoint3f(i, true); 649 propertyName = "coord"; 650 } 651 i = eval.iToken; 652 havePoints = true; 653 break; 654 case T.hkl: 655 case T.plane: 656 if (!havePoints && !isIntersect && tokIntersect == 0) { 657 if (eval.theTok == T.hkl) { 658 havePoints = true; 659 setShapeProperty(JC.SHAPE_DRAW, "plane", null); 660 plane = eval.hklParameter(++i, true); 661 i = eval.iToken; 662 propertyName = "coords"; 663 Lst<P3> list = new Lst<P3>(); 664 list.addLast(P3.newP(eval.pt1)); 665 list.addLast(P3.newP(eval.pt2)); 666 list.addLast(P3.newP(eval.pt3)); 667 propertyValue = list; 668 } else { 669 propertyName = "plane"; 670 iArray = i + 1; 671 } 672 break; 673 } 674 if (eval.theTok == T.plane) { 675 plane = eval.planeParameter(i); 676 } else { 677 plane = eval.hklParameter(++i, false); 678 } 679 i = eval.iToken; 680 if (tokIntersect != 0) { 681 if (chk) 682 break; 683 Lst<Object> vpc = getPlaneIntersection(tokIntersect, plane, uc, 684 intScale / 100f, 0); 685 intScale = 0; 686 propertyName = "polygon"; 687 propertyValue = vpc; 688 } else { 689 propertyValue = plane; 690 propertyName = "planedef"; 691 } 692 havePoints = true; 693 break; 694 case T.linedata: 695 propertyName = "lineData"; 696 propertyValue = eval.floatParameterSet(++i, 0, Integer.MAX_VALUE); 697 i = eval.iToken; 698 havePoints = true; 699 break; 700 case T.define: 701 case T.bitset: 702 case T.expressionBegin: 703 propertyName = "atomSet"; 704 propertyValue = atomExpressionAt(i); 705 if (isFrame) 706 center = centerParameter(i); 707 i = eval.iToken; 708 havePoints = true; 709 break; 710 case T.varray: 711 havePoints = true; 712 propertyName = (iArray == i ? "coords" : "modelBasedPoints"); 713 propertyValue = eval.theToken.value; 714 break; 715 case T.spacebeforesquare: 716 case T.comma: 717 break; 718 case T.leftsquare: 719 // [x y] or [x y %] 720 propertyValue = eval.xypParameter(i); 721 if (propertyValue != null) { 722 i = eval.iToken; 723 propertyName = "coord"; 724 havePoints = true; 725 break; 726 } 727 if (isSavedState) 728 invArg(); 729 isSavedState = true; 730 break; 731 case T.rightsquare: 732 if (!isSavedState) 733 invArg(); 734 isSavedState = false; 735 break; 736 case T.reverse: 737 propertyName = "reverse"; 738 break; 739 case T.string: 740 propertyValue = stringParameter(i); 741 propertyName = "title"; 742 break; 743 case T.vector: 744 propertyName = "vector"; 745 break; 746 case T.length: 747 propertyValue = Float.valueOf(floatParameter(++i)); 748 propertyName = "length"; 749 break; 750 case T.decimal: 751 // $drawObject 752 propertyValue = Float.valueOf(floatParameter(i)); 753 propertyName = "length"; 754 break; 755 case T.modelindex: 756 propertyName = "modelIndex"; 757 propertyValue = Integer.valueOf(intParameter(++i)); 758 break; 759 case T.integer: 760 if (isSavedState) { 761 propertyName = "modelIndex"; 762 propertyValue = Integer.valueOf(intParameter(i)); 763 } else { 764 intScale = intParameter(i); 765 } 766 break; 767 case T.scale: 768 intScale = Math.round( 769 floatParameter(++i) * (getToken(i).tok == T.integer ? 1 : 100)); 770 continue; 771 case T.id: 772 thisId = setShapeId(JC.SHAPE_DRAW, ++i, idSeen); 773 isWild = (getShapeProperty(JC.SHAPE_DRAW, "ID") == null); 774 i = eval.iToken; 775 break; 776 case T.modelbased: 777 propertyName = "fixed"; 778 propertyValue = Boolean.FALSE; 779 break; 780 case T.fixed: 781 propertyName = "fixed"; 782 propertyValue = Boolean.TRUE; 783 break; 784 case T.offset: 785 P3 pt = getPoint3f(++i, true); 786 i = eval.iToken; 787 propertyName = "offset"; 788 propertyValue = pt; 789 break; 790 case T.crossed: 791 propertyName = "crossed"; 792 break; 793 case T.width: 794 propertyValue = Float.valueOf(floatParameter(++i)); 795 propertyName = "width"; 796 swidth = propertyName + " " + propertyValue; 797 break; 798 case T.line: 799 propertyName = "line"; 800 propertyValue = Boolean.TRUE; 801 iArray = i + 1; 802 break; 803 case T.curve: 804 propertyName = "curve"; 805 iArray = i + 1; 806 break; 807 case T.arc: 808 propertyName = "arc"; 809 iArray = i + 1; 810 break; 811 case T.arrow: 812 propertyName = "arrow"; 813 iArray = i + 1; 814 break; 815 case T.vertices: 816 propertyName = "vertices"; 817 iArray = i + 1; 818 break; 819 case T.circle: 820 propertyName = "circle"; 821 break; 822 case T.cylinder: 823 propertyName = "cylinder"; 824 break; 825 case T.nohead: 826 propertyName = "nohead"; 827 break; 828 case T.barb: 829 propertyName = "isbarb"; 830 break; 831 case T.rotate45: 832 propertyName = "rotate45"; 833 break; 834 case T.perpendicular: 835 propertyName = "perp"; 836 break; 837 case T.radius: 838 case T.diameter: 839 boolean isRadius = (eval.theTok == T.radius); 840 float f = floatParameter(++i); 841 if (isRadius) 842 f *= 2; 843 propertyValue = Float.valueOf(f); 844 propertyName = (isRadius || tokAt(i) == T.decimal ? "width" 845 : "diameter"); 846 swidth = propertyName 847 + (tokAt(i) == T.decimal ? " " + f : " " + ((int) f)); 848 break; 849 case T.dollarsign: 850 // $drawObject[m] 851 if ((tokAt(i + 2) == T.leftsquare || isFrame)) { 852 P3 pto = center = centerParameter(i); 853 i = eval.iToken; 854 propertyName = "coord"; 855 propertyValue = pto; 856 havePoints = true; 857 break; 858 } 859 // $drawObject 860 propertyValue = eval.objectNameParameter(++i); 861 propertyName = "identifier"; 862 havePoints = true; 863 break; 864 case T.color: 865 case T.translucent: 866 case T.opaque: 867 idSeen = true; 868 translucentLevel = getColorTrans(eval, i, false, colorArgb); 869 i = eval.iToken; 870 continue; 871 default: 872 if (!eval.setMeshDisplayProperty(JC.SHAPE_DRAW, 0, eval.theTok)) { 873 if (eval.theTok == T.times || T.tokAttr(eval.theTok, T.identifier)) { 874 thisId = setShapeId(JC.SHAPE_DRAW, i, idSeen); 875 i = eval.iToken; 876 break; 877 } 878 invArg(); 879 } 880 if (iptDisplayProperty == 0) 881 iptDisplayProperty = i; 882 i = eval.iToken; 883 continue; 884 } 885 idSeen = (eval.theTok != T.delete); 886 if (havePoints && !isInitialized && !isFrame) { 887 setShapeProperty(JC.SHAPE_DRAW, "points", Integer.valueOf(intScale)); 888 isInitialized = true; 889 intScale = 0; 890 } 891 if (havePoints && isWild) 892 invArg(); 893 if (propertyName != null) 894 setShapeProperty(JC.SHAPE_DRAW, propertyName, propertyValue); 895 } 896 finalizeObject(JC.SHAPE_DRAW, colorArgb[0], translucentLevel, intScale, 897 havePoints, connections, iptDisplayProperty, null); 898 } 899 mo(boolean isInitOnly, int iShape)900 private void mo(boolean isInitOnly, int iShape) throws ScriptException { 901 ScriptEval eval = e; 902 int offset = Integer.MAX_VALUE; 903 boolean isNegOffset = false; 904 String nboType = null; 905 BS bsModels = vwr.getVisibleFramesBitSet(); 906 Lst<Object[]> propertyList = new Lst<Object[]>(); 907 boolean isBeta = false; 908 boolean isNBO = (tokAt(0) == T.nbo); 909 int i0 = 1; 910 if (isNBO) { 911 // NBO command by itself starts the NBO Server Interface panel 912 // NBO OPTIONS include "NOZAP;VIEW" 913 boolean isViewOnly = e.optParameterAsString(1).equals("view"); 914 if (e.slen == 1 || isViewOnly 915 || e.optParameterAsString(1).equals("options")) { 916 if (!chk) { 917 String options = (isViewOnly ? "VIEW" : e.optParameterAsString(2)); 918 vwr.startNBO(options); 919 } 920 return; 921 } 922 } 923 if (tokAt(1) == T.model || tokAt(1) == T.frame) { 924 i0 = eval.modelNumberParameter(2); 925 if (i0 < 0) 926 invArg(); 927 bsModels.clearAll(); 928 bsModels.set(i0); 929 i0 = 3; 930 } 931 eval.sm.loadShape(iShape); 932 for (int iModel = bsModels.nextSetBit(0); iModel >= 0; iModel = bsModels 933 .nextSetBit(iModel + 1)) { 934 int i = i0; 935 if (tokAt(i) == T.list && listIsosurface(iShape)) 936 return; 937 setShapeProperty(iShape, "init", Integer.valueOf(iModel)); 938 if (isInitOnly) 939 return;// (moNumber != 0); 940 String title = null; 941 int moNumber = ((Integer) getShapeProperty(iShape, "moNumber")) 942 .intValue(); 943 float[] linearCombination = (float[]) getShapeProperty(iShape, 944 "moLinearCombination"); 945 Boolean squared = (Boolean) getShapeProperty(iShape, "moSquareData"); 946 Boolean linearSquared = (linearCombination == null ? null 947 : (Boolean) getShapeProperty(iShape, "moSquareLinear")); 948 if (moNumber == 0) 949 moNumber = Integer.MAX_VALUE; 950 String propertyName = null; 951 Object propertyValue = null; 952 boolean ignoreSquared = false; 953 String nboName = null; 954 switch (getToken(i).tok) { 955 case T.type: 956 if (iShape == T.mo) { 957 mo(isInitOnly, JC.SHAPE_NBO); 958 return; 959 } 960 nboType = paramAsStr(++i).toUpperCase(); 961 if (eval.tokAt(i + 1) == T.string) { 962 nboName = paramAsStr(++eval.iToken); 963 // NBO "C1-C2" 964 } 965 break; 966 case T.cap: 967 case T.slab: 968 propertyName = (String) eval.theToken.value; 969 propertyValue = getCapSlabObject(i, false); 970 i = eval.iToken; 971 break; 972 case T.density: 973 linearSquared = Boolean.TRUE; 974 linearCombination = new float[] { 1 }; 975 offset = moNumber = 0; 976 break; 977 case T.integer: 978 moNumber = intParameter(i); 979 if (tokAt(i + 1) == T.beta) { 980 isBeta = true; 981 i++; 982 } 983 linearCombination = moCombo(propertyList); 984 if (linearCombination == null && moNumber < 0) 985 linearCombination = new float[] { -100, -moNumber }; 986 ignoreSquared = true; 987 break; 988 case T.minus: 989 switch (tokAt(++i)) { 990 case T.homo: 991 case T.lumo: 992 break; 993 default: 994 invArg(); 995 } 996 isNegOffset = true; 997 //$FALL-THROUGH$ 998 case T.homo: 999 case T.lumo: 1000 if ((offset = moOffset(i)) == Integer.MAX_VALUE) 1001 invArg(); 1002 moNumber = 0; 1003 linearCombination = moCombo(propertyList); 1004 ignoreSquared = true; 1005 break; 1006 case T.next: 1007 moNumber = T.next; 1008 isBeta = false; 1009 linearCombination = moCombo(propertyList); 1010 ignoreSquared = true; 1011 break; 1012 case T.prev: 1013 moNumber = T.prev; 1014 isBeta = false; 1015 linearCombination = moCombo(propertyList); 1016 ignoreSquared = true; 1017 break; 1018 case T.color: 1019 setColorOptions(null, i + 1, iShape, 2); 1020 break; 1021 case T.plane: 1022 propertyName = "plane"; 1023 propertyValue = (tokAt(e.iToken = ++i) == T.none ? null 1024 : eval.planeParameter(i)); 1025 break; 1026 case T.point: 1027 addShapeProperty(propertyList, "randomSeed", 1028 tokAt(i + 2) == T.integer ? Integer.valueOf(intParameter(i + 2)) 1029 : null); 1030 propertyName = "monteCarloCount"; 1031 propertyValue = Integer.valueOf(intParameter(i + 1)); 1032 break; 1033 case T.scale: 1034 propertyName = "scale"; 1035 propertyValue = Float.valueOf(floatParameter(i + 1)); 1036 break; 1037 case T.cutoff: 1038 if (tokAt(i + 1) == T.plus) { 1039 propertyName = "cutoffPositive"; 1040 propertyValue = Float.valueOf(floatParameter(i + 2)); 1041 } else { 1042 propertyName = "cutoff"; 1043 propertyValue = Float.valueOf(floatParameter(i + 1)); 1044 } 1045 break; 1046 case T.debug: 1047 propertyName = "debug"; 1048 break; 1049 case T.noplane: 1050 propertyName = "plane"; 1051 break; 1052 case T.pointsperangstrom: 1053 case T.resolution: 1054 propertyName = "resolution"; 1055 propertyValue = Float.valueOf(floatParameter(i + 1)); 1056 break; 1057 case T.squared: 1058 if (linearCombination == null) 1059 squared = Boolean.TRUE; 1060 else 1061 linearSquared = Boolean.TRUE; 1062 ignoreSquared = false; 1063 break; 1064 case T.titleformat: 1065 if (i + 1 < slen && tokAt(i + 1) == T.string) { 1066 propertyName = "titleFormat"; 1067 propertyValue = paramAsStr(i + 1); 1068 } 1069 break; 1070 case T.identifier: 1071 invArg(); 1072 break; 1073 case T.string: 1074 if (isNBO && i == 1) { 1075 nboName = eval.stringParameter(i); 1076 // NBO "C1-C2" 1077 break; 1078 } 1079 //$FALL-THROUGH$ 1080 default: 1081 if (isNBO && eval.tokAt(i) == T.string) { 1082 nboName = paramAsStr(i++); 1083 // NBO "C1-C2" 1084 } 1085 if (eval.isArrayParameter(i)) { 1086 linearCombination = eval.floatParameterSet(i, 1, Integer.MAX_VALUE); 1087 if (tokAt(eval.iToken + 1) == T.squared) { 1088 ignoreSquared = false; 1089 linearSquared = Boolean.TRUE; 1090 eval.iToken++; 1091 } 1092 break; 1093 } 1094 int ipt = eval.iToken; 1095 if (!eval.setMeshDisplayProperty(iShape, 0, eval.theTok)) 1096 invArg(); 1097 setShapeProperty(iShape, "setProperties", propertyList); 1098 eval.setMeshDisplayProperty(iShape, ipt, tokAt(ipt)); 1099 return; 1100 } 1101 if (propertyName != null) 1102 addShapeProperty(propertyList, propertyName, propertyValue); 1103 boolean haveMO = (moNumber != Integer.MAX_VALUE 1104 || linearCombination != null); 1105 if (chk) 1106 return; 1107 if (nboType != null || nboName != null || haveMO) { 1108 if (haveMO && tokAt(eval.iToken + 1) == T.string) { 1109 title = paramAsStr(++eval.iToken); 1110 } 1111 eval.setCursorWait(true); 1112 if (nboType != null || nboName != null) 1113 nboType = nboType + ":" + nboName; 1114 setMoData(propertyList, moNumber, linearCombination, offset, 1115 isNegOffset, iModel, title, nboType, isBeta); 1116 if (haveMO) { 1117 addShapeProperty(propertyList, "finalize", null); 1118 } 1119 } 1120 if (!ignoreSquared) { 1121 setShapeProperty(iShape, "squareLinear", linearSquared); 1122 setShapeProperty(iShape, "squareData", squared); 1123 } 1124 if (propertyList.size() > 0) 1125 setShapeProperty(iShape, "setProperties", propertyList); 1126 if (haveMO && !eval.tQuiet) { 1127 String moLabel = ""; 1128 if (isNBO) { 1129 moLabel = (String) getShapeProperty(iShape, "moLabel"); 1130 } else { 1131 moNumber = ((Integer) getShapeProperty(iShape, "moNumber")) 1132 .intValue(); 1133 moLabel = "" + moNumber; 1134 } 1135 showString(T.nameOf(tokAt(0)) + " " + moLabel + " " 1136 + (isBeta ? "beta " : "") + getShapeProperty(iShape, "message")); 1137 } 1138 1139 propertyList.clear(); 1140 } 1141 } 1142 1143 @SuppressWarnings({ "static-access", "unchecked" }) setNBOType(Map<String, Object> moData, String type)1144 private int setNBOType(Map<String, Object> moData, String type) 1145 throws ScriptException { 1146 1147 int nboNumber = -1; 1148 String name = null; 1149 int pt = type.indexOf(":"); 1150 if (pt > 0) { 1151 name = type.substring(pt + 1); 1152 type = type.substring(0, pt); 1153 if (type.equals("null")) 1154 type = null; 1155 if (name.equals("null")) 1156 name = null; 1157 } 1158 if ((type == null ? 0 : JC.getNBOTypeFromName(type)) < 0) 1159 invArg(); 1160 if (!moData.containsKey("nboLabels")) 1161 error(ScriptError.ERROR_moModelError); 1162 if (chk) 1163 return -1; 1164 if (type != null && !((GenNBOReader) Interface.getInterface( 1165 "org.jmol.adapter.readers.quantum.GenNBOReader", vwr, "script")) 1166 .readNBOCoefficients(moData, type, vwr)) 1167 error(ScriptError.ERROR_moModelError); 1168 1169 Lst<String> auxFiles = (Lst<String>) moData.get("auxFiles"); 1170 Lst<String> auxFiles0 = (Lst<String>) vwr.getCurrentModelAuxInfo() 1171 .get("auxFiles"); 1172 if (auxFiles0 == null) { 1173 vwr.getCurrentModelAuxInfo().put("auxFiles", auxFiles); 1174 } else { 1175 auxFiles0.addAll(auxFiles); 1176 } 1177 if (name != null) { 1178 pt = name.indexOf("."); 1179 if (pt > 0) { 1180 int ipt = PT.parseInt(name.substring(pt + 1)); 1181 name = name.substring(0, pt); 1182 pt = ipt; 1183 } 1184 String[] labels = (String[]) moData.get("nboLabels"); 1185 for (int i = 0, n = labels.length; i < n; i++) { 1186 if (name.equals(labels[i])) { 1187 if (pt < 0 || --pt == 0) { 1188 nboNumber = i + 1; 1189 break; 1190 } 1191 } 1192 } 1193 if (nboNumber < 0) 1194 error(ScriptError.ERROR_moModelError); 1195 } 1196 return nboNumber; 1197 } 1198 moCombo(Lst<Object[]> propertyList)1199 private float[] moCombo(Lst<Object[]> propertyList) { 1200 if (tokAt(e.iToken + 1) != T.squared) 1201 return null; 1202 addShapeProperty(propertyList, "squareLinear", Boolean.TRUE); 1203 e.iToken++; 1204 return new float[0]; 1205 } 1206 moOffset(int index)1207 private int moOffset(int index) throws ScriptException { 1208 boolean isHomo = (getToken(index).tok == T.homo); 1209 int offset = (isHomo ? 0 : 1); 1210 int tok = tokAt(++index); 1211 if (tok == T.integer && ((String) e.st[index].value).charAt(0) == '-') // could be '-0' 1212 offset += intParameter(index); 1213 else if (tok == T.plus) 1214 offset += intParameter(++index); 1215 else if (tok == T.minus) // - <space> n 1216 offset -= intParameter(++index); 1217 return offset; 1218 } 1219 1220 @SuppressWarnings("unchecked") setMoData(Lst<Object[]> propertyList, int moNumber, float[] lc, int offset, boolean isNegOffset, int modelIndex, String title, String nboType, boolean isBeta)1221 private void setMoData(Lst<Object[]> propertyList, int moNumber, float[] lc, 1222 int offset, boolean isNegOffset, int modelIndex, 1223 String title, String nboType, boolean isBeta) 1224 throws ScriptException { 1225 ScriptEval eval = e; 1226 if (modelIndex < 0) { 1227 modelIndex = vwr.am.cmi; 1228 if (modelIndex < 0) 1229 eval.errorStr(ScriptError.ERROR_multipleModelsDisplayedNotOK, 1230 "MO isosurfaces"); 1231 } 1232 Map<String, Object> moData = (Map<String, Object>) vwr.ms 1233 .getInfo(modelIndex, "moData"); 1234 if (moData == null) 1235 error(ScriptError.ERROR_moModelError); 1236 vwr.checkMenuUpdate(); 1237 if (nboType != null) { 1238 int nboNumber = setNBOType(moData, nboType); 1239 int nOrbitals = ((String[]) moData.get("nboLabels")).length; 1240 eval.showString(nOrbitals + " orbitals of type " + nboType.substring(0, nboType.indexOf(":") + 1) + " modelIndex=" + vwr.getModelNumberDotted(modelIndex)); 1241 if (nboNumber > 0) 1242 moNumber = nboNumber; 1243 if (lc == null && moNumber == Integer.MAX_VALUE) 1244 return; 1245 } 1246 Lst<Map<String, Object>> mos = null; 1247 Map<String, Object> mo; 1248 int nOrb = 0; 1249 Float f = null; 1250 if (lc == null || lc.length < 2) { 1251 if (lc != null && lc.length == 1) 1252 offset = 0; 1253 else if (isBeta && moData.containsKey("firstBeta")) 1254 offset = ((Integer) moData.get("firstBeta")).intValue(); 1255 int lastMoNumber = (moData.containsKey("lastMoNumber") 1256 ? ((Integer) moData.get("lastMoNumber")).intValue() 1257 : 0); 1258 int lastMoCount = (moData.containsKey("lastMoCount") 1259 ? ((Integer) moData.get("lastMoCount")).intValue() 1260 : 1); 1261 if (moNumber == T.prev) 1262 moNumber = lastMoNumber - 1; 1263 else if (moNumber == T.next) 1264 moNumber = lastMoNumber + lastMoCount; 1265 mos = (Lst<Map<String, Object>>) (moData.get("mos")); 1266 nOrb = (mos == null ? 0 : mos.size()); 1267 if (nOrb == 0) 1268 error(ScriptError.ERROR_moCoefficients); 1269 if (nOrb == 1 && moNumber > 1) 1270 error(ScriptError.ERROR_moOnlyOne); 1271 if (offset != Integer.MAX_VALUE) { 1272 // 0: HOMO; 1273 if (isBeta) { 1274 } else if (moData.containsKey("HOMO")) { 1275 moNumber = ((Integer) moData.get("HOMO")).intValue() + offset; 1276 offset = 0; 1277 } else { 1278 moNumber = nOrb; 1279 for (int i = 0; i < nOrb; i++) { 1280 mo = mos.get(i); 1281 if ((f = (Float) mo.get("occupancy")) != null) { 1282 if (f.floatValue() < 0.5f) { 1283 // go for LUMO = first unoccupied 1284 moNumber = i; 1285 break; 1286 } 1287 continue; 1288 } else if ((f = (Float) mo.get("energy")) != null) { 1289 if (f.floatValue() > 0) { 1290 // go for LUMO = first positive 1291 moNumber = i; 1292 break; 1293 } 1294 continue; 1295 } 1296 break; 1297 } 1298 if (f == null) 1299 error(ScriptError.ERROR_moOccupancy); 1300 } 1301 moNumber += offset; 1302 if (!chk) 1303 Logger.info("MO " + moNumber); 1304 } 1305 if (moNumber < 1 || moNumber > nOrb) 1306 eval.errorStr(ScriptError.ERROR_moIndex, "" + nOrb); 1307 } 1308 moNumber = Math.abs(moNumber); 1309 moData.put("lastMoNumber", Integer.valueOf(moNumber)); 1310 moData.put("lastMoCount", Integer.valueOf(1)); 1311 if (isNegOffset && lc == null) 1312 lc = new float[] { -100, moNumber }; 1313 if (lc != null && lc.length < 2) { 1314 mo = mos.get(moNumber - 1); 1315 if ((f = (Float) mo.get("energy")) == null) { 1316 lc = new float[] { 100, moNumber }; 1317 } else { 1318 1319 // constuct set of equivalent energies and square this 1320 1321 float energy = f.floatValue(); 1322 BS bs = BS.newN(nOrb); 1323 int n = 0; 1324 boolean isAllElectrons = (lc.length == 1 && lc[0] == 1); 1325 for (int i = 0; i < nOrb; i++) { 1326 if ((f = (Float) mos.get(i).get("energy")) == null) 1327 continue; 1328 float e = f.floatValue(); 1329 if (isAllElectrons ? e <= energy : e == energy) { 1330 bs.set(i + 1); 1331 n += 2; 1332 } 1333 } 1334 lc = new float[n]; 1335 for (int i = 0, pt = 0; i < n; i += 2) { 1336 lc[i] = 1; 1337 lc[i + 1] = (pt = bs.nextSetBit(pt + 1)); 1338 } 1339 moData.put("lastMoNumber", Integer.valueOf(bs.nextSetBit(0))); 1340 moData.put("lastMoCount", Integer.valueOf(n / 2)); 1341 } 1342 addShapeProperty(propertyList, "squareLinear", Boolean.TRUE); 1343 } 1344 addShapeProperty(propertyList, "moData", moData); 1345 if (title != null) 1346 addShapeProperty(propertyList, "title", title); 1347 addShapeProperty(propertyList, "molecularOrbital", 1348 lc != null ? lc : Integer.valueOf(Math.abs(moNumber))); 1349 addShapeProperty(propertyList, "clear", null); 1350 } 1351 isosurface(int iShape)1352 private void isosurface(int iShape) throws ScriptException { 1353 // also called by lcaoCartoon 1354 ScriptEval eval = e; 1355 eval.sm.loadShape(iShape); 1356 if (tokAt(1) == T.list && listIsosurface(iShape)) 1357 return; 1358 int iptDisplayProperty = 0; 1359 boolean isDisplay = false; 1360 boolean isIsosurface = (iShape == JC.SHAPE_ISOSURFACE); 1361 boolean isPmesh = (iShape == JC.SHAPE_PMESH); 1362 boolean isPlot3d = (iShape == JC.SHAPE_PLOT3D); 1363 boolean isLcaoCartoon = (iShape == JC.SHAPE_LCAOCARTOON); 1364 boolean isSilent = (isLcaoCartoon || tokAt(1) == T.delete 1365 || eval.isStateScript); 1366 boolean surfaceObjectSeen = false; 1367 boolean planeSeen = false; 1368 boolean isMapped = false; 1369 boolean isBicolor = false; 1370 boolean isPhased = false; 1371 boolean doCalcArea = false; 1372 boolean doCalcVolume = false; 1373 boolean isBeta = false; 1374 boolean isCavity = false; 1375 boolean haveRadius = false; 1376 boolean toCache = false; 1377 boolean isFxy = false; 1378 boolean haveSlab = false; 1379 boolean haveIntersection = false; 1380 boolean isFrontOnly = false; 1381 String nbotype = null; 1382 float[] data = null; 1383 String cmd = null; 1384 BS thisSet = null; 1385 int nFiles = 0; 1386 int nX, nY, nZ, ptX, ptY; 1387 float sigma = Float.NaN; 1388 float cutoff = Float.NaN; 1389 int ptWithin = 0; 1390 Boolean smoothing = null; 1391 int smoothingPower = Integer.MAX_VALUE; 1392 BS bs = null; 1393 BS bsSelect = null; 1394 BS bsIgnore = null; 1395 SB sbCommand = new SB(); 1396 P3 pt; 1397 P4 plane = null; 1398 P3 lattice = null; 1399 boolean fixLattice = false; 1400 P3[] pts = null; 1401 int color = 0; 1402 String str = null; 1403 int modelIndex = (chk ? 0 : Integer.MIN_VALUE); 1404 eval.setCursorWait(true); 1405 boolean idSeen = (initIsosurface(iShape) != null); 1406 boolean isWild = (idSeen && getShapeProperty(iShape, "ID") == null); 1407 boolean isColorSchemeTranslucent = false; 1408 boolean isInline = false; 1409 boolean isSign = false; 1410 Object onlyOneModel = null; 1411 Object[] filesData = null; 1412 String translucency = null; 1413 String colorScheme = null; 1414 String mepOrMlp = null; 1415 M4[] symops = null; 1416 short[] discreteColixes = null; 1417 Lst<Object[]> propertyList = new Lst<Object[]>(); 1418 boolean defaultMesh = false; 1419 if (isPmesh || isPlot3d) 1420 addShapeProperty(propertyList, "fileType", "Pmesh"); 1421 1422 for (int i = eval.iToken; i < slen; ++i) { 1423 String propertyName = null; 1424 Object propertyValue = null; 1425 int tok = getToken(i).tok; 1426 if (tok == T.identifier) { 1427 str = paramAsStr(i); 1428 if (str.equalsIgnoreCase("map")) 1429 tok = T.mapproperty; 1430 } 1431 switch (tok) { 1432 // settings only 1433 case T.silent: 1434 isSilent = true; 1435 sbCommand.append(" silent"); 1436 propertyName = "silent"; 1437 break; 1438 case T.isosurfacepropertysmoothing: 1439 smoothing = (getToken(++i).tok == T.on ? Boolean.TRUE 1440 : eval.theTok == T.off ? Boolean.FALSE : null); 1441 if (smoothing == null) 1442 invArg(); 1443 continue; 1444 case T.isosurfacepropertysmoothingpower: 1445 smoothingPower = intParameter(++i); 1446 continue; 1447 // offset, rotate, and scale3d don't need to be saved in sbCommand 1448 // because they are display properties 1449 case T.move: // Jmol 13.0.RC2 -- required for state saving after coordinate-based translate/rotate 1450 // but this will not work for MO calculations, which have to be 1451 // generated in their original atom-based frame 1452 propertyName = "moveIsosurface"; 1453 if (tokAt(++i) != T.matrix4f) 1454 invArg(); 1455 propertyValue = getToken(i++).value; 1456 break; 1457 case T.symop: 1458 float[][] ff = floatArraySet(i + 2, intParameter(i + 1), 16); 1459 symops = new M4[ff.length]; 1460 for (int j = symops.length; --j >= 0;) 1461 symops[j] = M4.newA16(ff[j]); 1462 i = eval.iToken; 1463 break; 1464 case T.symmetry: 1465 if (modelIndex < 0) 1466 modelIndex = Math.min(vwr.am.cmi, 0); 1467 boolean needIgnore = (bsIgnore == null); 1468 if (bsSelect == null) 1469 bsSelect = BSUtil.copy(vwr.bsA()); 1470 // and in symop=1 1471 bsSelect.and(vwr.ms.getAtoms(T.symop, Integer.valueOf(1))); 1472 if (!needIgnore) 1473 bsSelect.andNot(bsIgnore); 1474 addShapeProperty(propertyList, "select", bsSelect); 1475 if (needIgnore) { 1476 bsIgnore = BSUtil.copy(bsSelect); 1477 BSUtil.invertInPlace(bsIgnore, vwr.ms.ac); 1478 isFrontOnly = true; 1479 addShapeProperty(propertyList, "ignore", bsIgnore); 1480 sbCommand.append(" ignore ").append(Escape.eBS(bsIgnore)); 1481 } 1482 sbCommand.append(" symmetry"); 1483 if (color == 0) 1484 addShapeProperty(propertyList, "colorRGB", Integer.valueOf(T.symop)); 1485 symops = vwr.ms.getSymMatrices(modelIndex); 1486 break; 1487 case T.offset: 1488 propertyName = "offset"; 1489 propertyValue = centerParameter(++i); 1490 i = eval.iToken; 1491 break; 1492 case T.rotate: 1493 propertyName = "rotate"; 1494 propertyValue = (tokAt(eval.iToken = ++i) == T.none ? null 1495 : eval.getPoint4f(i)); 1496 i = eval.iToken; 1497 break; 1498 case T.scale3d: 1499 propertyName = "scale3d"; 1500 propertyValue = Float.valueOf(floatParameter(++i)); 1501 break; 1502 case T.period: 1503 sbCommand.append(" periodic"); 1504 propertyName = "periodic"; 1505 break; 1506 case T.origin: 1507 case T.step: 1508 case T.point: 1509 propertyName = eval.theToken.value.toString(); 1510 sbCommand.append(" ").appendO(eval.theToken.value); 1511 propertyValue = centerParameter(++i); 1512 sbCommand.append(" ").append(Escape.eP((P3) propertyValue)); 1513 i = eval.iToken; 1514 break; 1515 case T.boundbox: 1516 if (eval.fullCommand.indexOf("# BBOX=") >= 0) { 1517 String[] bbox = PT 1518 .split(PT.getQuotedAttribute(eval.fullCommand, "# BBOX"), ","); 1519 pts = new P3[] { (P3) Escape.uP(bbox[0]), (P3) Escape.uP(bbox[1]) }; 1520 } else if (eval.isCenterParameter(i + 1)) { 1521 pts = new P3[] { getPoint3f(i + 1, true), 1522 getPoint3f(eval.iToken + 1, true) }; 1523 i = eval.iToken; 1524 } else { 1525 pts = vwr.ms.getBBoxVertices(); 1526 } 1527 sbCommand.append(" boundBox " + Escape.eP(pts[0]) + " " 1528 + Escape.eP(pts[pts.length - 1])); 1529 propertyName = "boundingBox"; 1530 propertyValue = pts; 1531 break; 1532 case T.pmesh: 1533 isPmesh = true; 1534 sbCommand.append(" pmesh"); 1535 propertyName = "fileType"; 1536 propertyValue = "Pmesh"; 1537 break; 1538 case T.intersection: 1539 // isosurface intersection {A} {B} VDW.... 1540 // isosurface intersection {A} {B} function "a-b" VDW.... 1541 bsSelect = atomExpressionAt(++i); 1542 if (chk) { 1543 bs = new BS(); 1544 } else if (tokAt(eval.iToken + 1) == T.expressionBegin 1545 || tokAt(eval.iToken + 1) == T.bitset) { 1546 bs = atomExpressionAt(++eval.iToken); 1547 bs.and(vwr.ms.getAtomsWithinRadius(5.0f, bsSelect, false, null)); 1548 } else { 1549 // default is "within(5.0, selected) and not within(molecule,selected)" 1550 bs = vwr.ms.getAtomsWithinRadius(5.0f, bsSelect, true, null); 1551 bs.andNot(vwr.ms.getAtoms(T.molecule, bsSelect)); 1552 } 1553 bs.andNot(bsSelect); 1554 sbCommand.append(" intersection ").append(Escape.eBS(bsSelect)) 1555 .append(" ").append(Escape.eBS(bs)); 1556 i = eval.iToken; 1557 if (tokAt(i + 1) == T.function) { 1558 i++; 1559 String f = (String) getToken(++i).value; 1560 sbCommand.append(" function ").append(PT.esc(f)); 1561 if (!chk) 1562 addShapeProperty(propertyList, "func", 1563 (f.equals("a+b") || f.equals("a-b") ? f 1564 : createFunction("__iso__", "a,b", f))); 1565 } else { 1566 haveIntersection = true; 1567 } 1568 propertyName = "intersection"; 1569 propertyValue = new BS[] { bsSelect, bs }; 1570 break; 1571 case T.display: 1572 case T.within: 1573 isDisplay = (tok == T.display); 1574 if (isDisplay) { 1575 sbCommand.append(" display"); 1576 iptDisplayProperty = i; 1577 tok = tokAt(i + 1); 1578 if (tok == T.nada) 1579 continue; 1580 i++; 1581 addShapeProperty(propertyList, "token", Integer.valueOf(T.on)); 1582 if (tok == T.bitset || tok == T.all) { 1583 propertyName = "bsDisplay"; 1584 if (tok == T.all) { 1585 sbCommand.append(" all"); 1586 } else { 1587 propertyValue = st[i].value; 1588 sbCommand.append(" ").append(Escape.eBS((BS) propertyValue)); 1589 } 1590 eval.checkLast(i); 1591 break; 1592 } else if (tok != T.within) { 1593 eval.iToken = i; 1594 invArg(); 1595 } 1596 } else { 1597 ptWithin = i; 1598 } 1599 float distance; 1600 P3 ptc = null; 1601 bs = null; 1602 Object[] ret = new Object[1]; 1603 if (tokAt(i + 1) == T.expressionBegin) { 1604 // within ( x.x , .... ) 1605 distance = floatParameter(i + 3); 1606 if (eval.isPoint3f(i + 4)) { 1607 ptc = eval.centerParameter(i + 4, null); 1608 eval.iToken += 2; 1609 } else if (eval.isPoint3f(i + 5)) { 1610 ptc = eval.centerParameter(i + 5, null); 1611 eval.iToken += 2; 1612 } else { 1613 bs = eval.atomExpression(st, i + 5, slen, true, false, ret, true); 1614 if (bs == null) 1615 invArg(); 1616 } 1617 } else { 1618 distance = floatParameter(++i); 1619 ptc = eval.centerParameter(++i, ret); 1620 bs = (ret[0] instanceof BS ? (BS) ret[0] : null); 1621 } 1622 if (isDisplay) 1623 eval.checkLast(eval.iToken); 1624 i = eval.iToken; 1625 if (eval.fullCommand.indexOf("# WITHIN=") >= 0) 1626 bs = BS.unescape(PT.getQuotedAttribute(eval.fullCommand, "# WITHIN")); 1627 if (!chk) { 1628 if (bs != null && modelIndex >= 0) { 1629 bs.and(vwr.getModelUndeletedAtomsBitSet(modelIndex)); 1630 } 1631 if (ptc == null) 1632 ptc = (bs == null ? new P3() : vwr.ms.getAtomSetCenter(bs)); 1633 pts = getWithinDistanceVector(propertyList, distance, ptc, bs, 1634 isDisplay); 1635 sbCommand.append(" within ").appendF(distance).append(" ") 1636 .append(bs == null ? Escape.eP(ptc) : Escape.eBS(bs)); 1637 } 1638 continue; 1639 case T.parameters: 1640 propertyName = "parameters"; 1641 // if > 1 parameter, then first is assumed to be the cutoff. 1642 float[] fparams = eval.floatParameterSet(++i, 1, 10); 1643 i = eval.iToken; 1644 propertyValue = fparams; 1645 sbCommand.append(" parameters ").append(Escape.eAF(fparams)); 1646 break; 1647 case T.property: 1648 case T.variable: 1649 onlyOneModel = eval.theToken.value; 1650 boolean isVariable = (tok == T.variable); 1651 int tokProperty = tokAt(i + 1); 1652 if (mepOrMlp == null) { // not mlp or mep 1653 if (!surfaceObjectSeen && !isMapped && !planeSeen) { 1654 addShapeProperty(propertyList, "sasurface", Float.valueOf(0)); 1655 //if (surfaceObjectSeen) 1656 sbCommand.append(" vdw"); 1657 surfaceObjectSeen = true; 1658 } 1659 propertyName = "property"; 1660 if (smoothing == null) { 1661 boolean allowSmoothing = T.tokAttr(tokProperty, T.floatproperty); 1662 smoothing = (allowSmoothing 1663 && vwr.getIsosurfacePropertySmoothing(false) == 1 ? Boolean.TRUE 1664 : Boolean.FALSE); 1665 } 1666 addShapeProperty(propertyList, "propertySmoothing", smoothing); 1667 sbCommand.append(" isosurfacePropertySmoothing " + smoothing); 1668 if (smoothing == Boolean.TRUE) { 1669 if (smoothingPower == Integer.MAX_VALUE) 1670 smoothingPower = vwr.getIsosurfacePropertySmoothing(true); 1671 addShapeProperty(propertyList, "propertySmoothingPower", 1672 Integer.valueOf(smoothingPower)); 1673 sbCommand 1674 .append(" isosurfacePropertySmoothingPower " + smoothingPower); 1675 } 1676 if (vwr.g.rangeSelected) 1677 addShapeProperty(propertyList, "rangeSelected", Boolean.TRUE); 1678 } else { 1679 propertyName = mepOrMlp; 1680 } 1681 str = paramAsStr(i); 1682 // if (surfaceObjectSeen) 1683 sbCommand.append(" ").append(str); 1684 1685 if (str.toLowerCase().indexOf("property_") == 0) { 1686 data = new float[vwr.ms.ac]; 1687 if (chk) 1688 continue; 1689 data = (float[]) vwr.getDataObj(str, null, 1690 JmolDataManager.DATA_TYPE_AF); 1691 if (data == null) 1692 invArg(); 1693 addShapeProperty(propertyList, propertyName, data); 1694 continue; 1695 } 1696 1697 int ac = vwr.ms.ac; 1698 data = new float[ac]; 1699 1700 if (isVariable) { 1701 String vname = paramAsStr(++i); 1702 if (vname.length() == 0) { 1703 data = eval.floatParameterSet(i, ac, ac); 1704 } else { 1705 data = new float[ac]; 1706 if (!chk) 1707 Parser.parseStringInfestedFloatArray( 1708 "" + eval.getParameter(vname, T.string, true), null, data); 1709 } 1710 if (!chk/* && (surfaceObjectSeen)*/) 1711 sbCommand.append(" \"\" ").append(Escape.eAF(data)); 1712 } else { 1713 getToken(++i); 1714 if (!chk) { 1715 sbCommand.append(" " + eval.theToken.value); 1716 Atom[] atoms = vwr.ms.at; 1717 vwr.autoCalculate(tokProperty, null); 1718 if (tokProperty != T.color) { 1719 pt = new P3(); 1720 for (int iAtom = ac; --iAtom >= 0;) 1721 data[iAtom] = atoms[iAtom].atomPropertyFloat(vwr, tokProperty, 1722 pt); 1723 } 1724 } 1725 if (tokProperty == T.color) 1726 colorScheme = "inherit"; 1727 if (tokAt(i + 1) == T.within) { 1728 float d = floatParameter(i = i + 2); 1729 sbCommand.append(" within " + d); 1730 addShapeProperty(propertyList, "propertyDistanceMax", 1731 Float.valueOf(d)); 1732 } 1733 } 1734 propertyValue = data; 1735 break; 1736 case T.modelindex: 1737 case T.model: 1738 if (surfaceObjectSeen) 1739 invArg(); 1740 modelIndex = (tok == T.modelindex ? intParameter(++i) 1741 : eval.modelNumberParameter(++i)); 1742 sbCommand.append(" modelIndex " + modelIndex); 1743 if (modelIndex < 0) { 1744 propertyName = "fixed"; 1745 propertyValue = Boolean.TRUE; 1746 break; 1747 } 1748 propertyName = "modelIndex"; 1749 propertyValue = Integer.valueOf(modelIndex); 1750 break; 1751 case T.select: 1752 // in general, vwr.getCurrentSelection() is used, but we may 1753 // override that here. But we have to be careful that 1754 // we PREPEND the selection to the command if no surface object 1755 // has been seen yet, and APPEND it if it has. 1756 propertyName = "select"; 1757 BS bs1 = atomExpressionAt(++i); 1758 propertyValue = bs1; 1759 i = eval.iToken; 1760 boolean isOnly = (tokAt(i + 1) == T.only); 1761 if (isOnly) { 1762 i++; 1763 bsIgnore = BSUtil.copy(bs1); 1764 BSUtil.invertInPlace(bsIgnore, vwr.ms.ac); 1765 addShapeProperty(propertyList, "ignore", bsIgnore); 1766 sbCommand.append(" ignore ").append(Escape.eBS(bsIgnore)); 1767 isFrontOnly = true; 1768 } 1769 if (surfaceObjectSeen || isMapped) { 1770 sbCommand.append(" select " + Escape.eBS(bs1)); 1771 } else { 1772 bsSelect = (BS) propertyValue; 1773 if (modelIndex < 0 && bsSelect.nextSetBit(0) >= 0) 1774 modelIndex = vwr.ms.at[bsSelect.nextSetBit(0)].mi; 1775 } 1776 break; 1777 case T.subset: 1778 if (eval.getToken(++i).tok == T.bitset) { 1779 thisSet = (BS) eval.theToken.value; 1780 } else { 1781 thisSet = (BS) eval.expandFloatArray( 1782 eval.floatParameterSet(i, 1, Integer.MAX_VALUE), 1, true); 1783 } 1784 i = eval.iToken; 1785 break; 1786 case T.set: 1787 int ns = intParameter(++i); 1788 if (ns > 0) 1789 thisSet = BSUtil.newAndSetBit(ns - 1); 1790 else 1791 thisSet = new BS(); 1792 break; 1793 case T.center: 1794 propertyName = "center"; 1795 propertyValue = centerParameter(++i); 1796 sbCommand.append(" center " + Escape.eP((P3) propertyValue)); 1797 i = eval.iToken; 1798 break; 1799 case T.sign: 1800 case T.color: 1801 idSeen = true; 1802 if (tok == T.sign) { 1803 isSign = true; 1804 sbCommand.append(" sign"); 1805 addShapeProperty(propertyList, "sign", Boolean.TRUE); 1806 } else { 1807 if (tokAt(i + 1) == T.density) { 1808 i++; 1809 propertyName = "colorDensity"; 1810 sbCommand.append(" color density"); 1811 if (isFloatParameter(i + 1)) { 1812 float ptSize = floatParameter(++i); 1813 sbCommand.append(" " + ptSize); 1814 propertyValue = Float.valueOf(ptSize); 1815 } 1816 break; 1817 } 1818 /* 1819 * "color" now is just used as an equivalent to "sign" and as an 1820 * introduction to "absolute" any other use is superfluous; it has 1821 * been replaced with MAP for indicating "use the current surface" 1822 * because the term COLOR is too general. 1823 */ 1824 1825 if (getToken(i + 1).tok == T.string) { 1826 colorScheme = paramAsStr(++i); 1827 if (colorScheme.indexOf(" ") > 0) { 1828 discreteColixes = C.getColixArray(colorScheme); 1829 if (discreteColixes == null) 1830 error(ScriptError.ERROR_badRGBColor); 1831 } 1832 } else if (eval.theTok == T.mesh) { 1833 i++; 1834 sbCommand.append(" color mesh"); 1835 color = eval.getArgbParam(++i); 1836 addShapeProperty(propertyList, "meshcolor", Integer.valueOf(color)); 1837 sbCommand.append(" ").append(Escape.escapeColor(color)); 1838 i = eval.iToken; 1839 continue; 1840 } 1841 if ((eval.theTok = tokAt(i + 1)) == T.translucent 1842 || eval.theTok == T.opaque) { 1843 sbCommand.append(" color"); 1844 translucency = setColorOptions(sbCommand, i + 1, 1845 JC.SHAPE_ISOSURFACE, -2); 1846 i = eval.iToken; 1847 continue; 1848 } 1849 switch (tokAt(i + 1)) { 1850 case T.absolute: 1851 case T.range: 1852 getToken(++i); 1853 sbCommand.append(" color range"); 1854 addShapeProperty(propertyList, "rangeAll", null); 1855 if (tokAt(i + 1) == T.all) { 1856 i++; 1857 sbCommand.append(" all"); 1858 continue; 1859 } 1860 float min = floatParameter(++i); 1861 float max = floatParameter(++i); 1862 addShapeProperty(propertyList, "red", Float.valueOf(min)); 1863 addShapeProperty(propertyList, "blue", Float.valueOf(max)); 1864 sbCommand.append(" ").appendF(min).append(" ").appendF(max); 1865 continue; 1866 } 1867 if (eval.isColorParam(i + 1)) { 1868 color = eval.getArgbParam(i + 1); 1869 if (tokAt(i + 2) == T.to) { 1870 colorScheme = eval.getColorRange(i + 1); 1871 i = eval.iToken; 1872 break; 1873 } 1874 } 1875 sbCommand.append(" color"); 1876 } 1877 if (eval.isColorParam(i + 1)) { 1878 color = eval.getArgbParam(++i); 1879 sbCommand.append(" ").append(Escape.escapeColor(color)); 1880 i = eval.iToken; 1881 addShapeProperty(propertyList, "colorRGB", Integer.valueOf(color)); 1882 idSeen = true; 1883 if (eval.isColorParam(i + 1)) { 1884 color = eval.getArgbParam(++i); 1885 i = eval.iToken; 1886 addShapeProperty(propertyList, "colorRGB", Integer.valueOf(color)); 1887 sbCommand.append(" ").append(Escape.escapeColor(color)); 1888 isBicolor = true; 1889 } else if (isSign) { 1890 invPO(); 1891 } 1892 } else if (!isSign && discreteColixes == null && colorScheme == null) { 1893 invPO(); 1894 } 1895 continue; 1896 case T.cache: 1897 if (!isIsosurface) 1898 invArg(); 1899 toCache = !chk; 1900 continue; 1901 case T.file: 1902 if (tokAt(i + 1) != T.string) 1903 invPO(); 1904 continue; 1905 case T.bondingradius: 1906 case T.vanderwaals: 1907 //if (surfaceObjectSeen) 1908 sbCommand.append(" ").appendO(eval.theToken.value); 1909 RadiusData rd = eval.encodeRadiusParameter(i, false, true); 1910 if (rd == null) 1911 return; 1912 //if (surfaceObjectSeen) 1913 sbCommand.append(" ").appendO(rd); 1914 if (Float.isNaN(rd.value)) 1915 rd.value = 100; 1916 propertyValue = rd; 1917 propertyName = "radius"; 1918 haveRadius = true; 1919 if (isMapped) 1920 surfaceObjectSeen = false; 1921 i = eval.iToken; 1922 break; 1923 case T.plane: 1924 // plane {X, Y, Z, W} 1925 planeSeen = true; 1926 propertyName = "plane"; 1927 propertyValue = eval.planeParameter(i); 1928 i = eval.iToken; 1929 //if (surfaceObjectSeen) 1930 sbCommand.append(" plane ").append(Escape.eP4((P4) propertyValue)); 1931 break; 1932 case T.scale: 1933 propertyName = "scale"; 1934 propertyValue = Float.valueOf(floatParameter(++i)); 1935 sbCommand.append(" scale ").appendO(propertyValue); 1936 break; 1937 case T.all: 1938 if (idSeen) 1939 invArg(); 1940 propertyName = "thisID"; 1941 break; 1942 case T.ellipsoid: 1943 // ellipsoid {xc yc zc f} where a = b and f = a/c 1944 // NOT OR ellipsoid {u11 u22 u33 u12 u13 u23} 1945 surfaceObjectSeen = true; 1946 ++i; 1947 // ignoreError = true; 1948 // try { 1949 propertyValue = eval.getPoint4f(i); 1950 propertyName = "ellipsoid"; 1951 i = eval.iToken; 1952 sbCommand.append(" ellipsoid ").append(Escape.eP4((P4) propertyValue)); 1953 break; 1954 // } catch (Exception e) { 1955 // } 1956 // try { 1957 // propertyName = "ellipsoid"; 1958 // propertyValue = eval.floatParameterSet(i, 6, 6); 1959 // i = eval.iToken; 1960 // sbCommand.append(" ellipsoid ").append( 1961 // Escape.eAF((float[]) propertyValue)); 1962 // break; 1963 // } catch (Exception e) { 1964 // } 1965 // ignoreError = false; 1966 // bs = atomExpressionAt(i); 1967 // sbCommand.append(" ellipsoid ").append(Escape.eBS(bs)); 1968 // int iAtom = bs.nextSetBit(0); 1969 // if (iAtom < 0) 1970 // return; 1971 // Atom[] atoms = vwr.modelSet.atoms; 1972 // Tensor[] tensors = atoms[iAtom].getTensors(); 1973 // if (tensors == null || tensors.length < 1 || tensors[0] == null 1974 // || (propertyValue = vwr.getQuadricForTensor(tensors[0], null)) == null) 1975 // return; 1976 // i = eval.iToken; 1977 // propertyName = "ellipsoid"; 1978 // if (!chk) 1979 // addShapeProperty(propertyList, "center", vwr.getAtomPoint3f(iAtom)); 1980 // break; 1981 case T.hkl: 1982 // miller indices hkl 1983 planeSeen = true; 1984 propertyName = "plane"; 1985 propertyValue = eval.hklParameter(++i, false); 1986 i = eval.iToken; 1987 sbCommand.append(" plane ").append(Escape.eP4((P4) propertyValue)); 1988 break; 1989 case T.lcaocartoon: 1990 surfaceObjectSeen = true; 1991 String lcaoType = paramAsStr(++i); 1992 addShapeProperty(propertyList, "lcaoType", lcaoType); 1993 sbCommand.append(" lcaocartoon ").append(PT.esc(lcaoType)); 1994 switch (getToken(++i).tok) { 1995 case T.define: 1996 case T.bitset: 1997 case T.expressionBegin: 1998 // automatically selects just the model of the first atom in the set. 1999 propertyName = "lcaoCartoon"; 2000 bs = atomExpressionAt(i); 2001 i = eval.iToken; 2002 if (chk) 2003 continue; 2004 int atomIndex = bs.nextSetBit(0); 2005 if (atomIndex < 0) 2006 error(ScriptError.ERROR_expressionExpected); 2007 sbCommand.append(" ({").appendI(atomIndex).append("})"); 2008 modelIndex = vwr.ms.at[atomIndex].mi; 2009 addShapeProperty(propertyList, "modelIndex", 2010 Integer.valueOf(modelIndex)); 2011 V3[] axes = { new V3(), new V3(), V3.newV(vwr.ms.at[atomIndex]), 2012 new V3() }; 2013 if (!lcaoType.equalsIgnoreCase("s") 2014 && vwr.getHybridizationAndAxes(atomIndex, axes[0], axes[1], 2015 lcaoType) == null) 2016 return; 2017 propertyValue = axes; 2018 break; 2019 default: 2020 error(ScriptError.ERROR_expressionExpected); 2021 } 2022 break; 2023 case T.nbo: 2024 nbotype = paramAsStr(++i).toUpperCase(); 2025 sbCommand.append(" nbo ").append(nbotype).append(" "); 2026 //$FALL-THROUGH$ 2027 case T.mo: 2028 if (nbotype == null) 2029 sbCommand.append(" mo "); 2030 // mo 1-based-index 2031 int moNumber = Integer.MAX_VALUE; 2032 int offset = Integer.MAX_VALUE; 2033 boolean isNegOffset = (tokAt(i + 1) == T.minus); 2034 if (isNegOffset) 2035 i++; 2036 float[] linearCombination = null; 2037 switch (tokAt(++i)) { 2038 case T.nada: 2039 eval.bad(); 2040 break; 2041 case T.density: 2042 sbCommand.append("[1] squared "); 2043 addShapeProperty(propertyList, "squareLinear", Boolean.TRUE); 2044 linearCombination = new float[] { 1 }; 2045 offset = moNumber = 0; 2046 i++; 2047 break; 2048 case T.homo: 2049 case T.lumo: 2050 offset = moOffset(i); 2051 moNumber = 0; 2052 i = eval.iToken; 2053 //if (surfaceObjectSeen) { 2054 sbCommand.append((isNegOffset ? "-" : "") + "HOMO "); 2055 if (offset > 0) 2056 sbCommand.append("+"); 2057 if (offset != 0) 2058 sbCommand.appendI(offset); 2059 //} 2060 break; 2061 case T.integer: 2062 moNumber = intParameter(i); 2063 //if (surfaceObjectSeen) 2064 sbCommand.appendI(moNumber); 2065 if (tokAt(i + 1) == T.beta) { 2066 isBeta = true; 2067 i++; 2068 } 2069 break; 2070 default: 2071 if (eval.isArrayParameter(i)) { 2072 linearCombination = eval.floatParameterSet(i, 1, Integer.MAX_VALUE); 2073 i = eval.iToken; 2074 } 2075 } 2076 boolean squared = (tokAt(i + 1) == T.squared); 2077 if (squared) { 2078 addShapeProperty(propertyList, "squareLinear", Boolean.TRUE); 2079 sbCommand.append(" squared"); 2080 if (linearCombination == null) 2081 linearCombination = new float[0]; 2082 } else if (tokAt(i + 1) == T.point) { 2083 ++i; 2084 int monteCarloCount = intParameter(++i); 2085 int seed = (tokAt(i + 1) == T.integer ? intParameter(++i) 2086 : ((int) -System.currentTimeMillis()) % 10000); 2087 addShapeProperty(propertyList, "monteCarloCount", 2088 Integer.valueOf(monteCarloCount)); 2089 addShapeProperty(propertyList, "randomSeed", Integer.valueOf(seed)); 2090 sbCommand.append(" points ").appendI(monteCarloCount).appendC(' ') 2091 .appendI(seed); 2092 } 2093 setMoData(propertyList, moNumber, linearCombination, offset, 2094 isNegOffset, modelIndex, null, nbotype, isBeta); 2095 surfaceObjectSeen = true; 2096 continue; 2097 case T.nci: 2098 propertyName = "nci"; 2099 //if (surfaceObjectSeen) 2100 sbCommand.append(" " + propertyName); 2101 tok = tokAt(i + 1); 2102 boolean isPromolecular = (tok != T.file && tok != T.string 2103 && tok != T.mrc); 2104 propertyValue = Boolean.valueOf(isPromolecular); 2105 if (isPromolecular) 2106 surfaceObjectSeen = true; 2107 break; 2108 case T.mep: 2109 case T.mlp: 2110 boolean isMep = (tok == T.mep); 2111 propertyName = (isMep ? "mep" : "mlp"); 2112 //if (surfaceObjectSeen) 2113 sbCommand.append(" " + propertyName); 2114 String fname = null; 2115 int calcType = -1; 2116 surfaceObjectSeen = true; 2117 if (tokAt(i + 1) == T.integer) { 2118 calcType = intParameter(++i); 2119 sbCommand.append(" " + calcType); 2120 addShapeProperty(propertyList, "mepCalcType", 2121 Integer.valueOf(calcType)); 2122 } 2123 if (tokAt(i + 1) == T.string) { 2124 fname = stringParameter(++i); 2125 //if (surfaceObjectSeen) 2126 sbCommand.append(" /*file*/" + PT.esc(fname)); 2127 } else if (tokAt(i + 1) == T.property) { 2128 mepOrMlp = propertyName; 2129 continue; 2130 } 2131 if (!chk) 2132 try { 2133 data = (fname == null && isMep 2134 ? vwr.getOrCalcPartialCharges(bsSelect, bsIgnore) 2135 : getAtomicPotentials(bsSelect, bsIgnore, fname)); 2136 } catch (JmolAsyncException e1) { 2137 throw new ScriptInterruption(e, "partialcharge", 1); 2138 } 2139 if (!chk && data == null) 2140 error(ScriptError.ERROR_noPartialCharges); 2141 propertyValue = data; 2142 break; 2143 case T.volume: 2144 doCalcVolume = !chk; 2145 sbCommand.append(" volume"); 2146 break; 2147 case T.id: 2148 setShapeId(iShape, ++i, idSeen); 2149 isWild = (getShapeProperty(iShape, "ID") == null); 2150 i = eval.iToken; 2151 break; 2152 case T.colorscheme: 2153 // either order NOT OK -- documented for TRANSLUCENT "rwb" 2154 if (tokAt(i + 1) == T.translucent) { 2155 isColorSchemeTranslucent = true; 2156 i++; 2157 } 2158 colorScheme = paramAsStr(++i).toLowerCase(); 2159 if (colorScheme.equals("sets")) { 2160 sbCommand.append(" colorScheme \"sets\""); 2161 } else if (eval.isColorParam(i)) { 2162 colorScheme = eval.getColorRange(i); 2163 i = eval.iToken; 2164 } 2165 break; 2166 case T.addhydrogens: 2167 propertyName = "addHydrogens"; 2168 propertyValue = Boolean.TRUE; 2169 sbCommand.append(" addHydrogens"); 2170 break; 2171 case T.angstroms: 2172 propertyName = "angstroms"; 2173 sbCommand.append(" angstroms"); 2174 break; 2175 case T.anisotropy: 2176 propertyName = "anisotropy"; 2177 propertyValue = getPoint3f(++i, false); 2178 sbCommand.append(" anisotropy").append(Escape.eP((P3) propertyValue)); 2179 i = eval.iToken; 2180 break; 2181 case T.area: 2182 doCalcArea = !chk; 2183 sbCommand.append(" area"); 2184 break; 2185 case T.atomicorbital: 2186 case T.orbital: 2187 surfaceObjectSeen = true; 2188 if (isBicolor && !isPhased) { 2189 sbCommand.append(" phase \"_orb\""); 2190 addShapeProperty(propertyList, "phase", "_orb"); 2191 } 2192 float[] nlmZprs = new float[7]; 2193 nlmZprs[0] = intParameter(++i); 2194 nlmZprs[1] = intParameter(++i); 2195 nlmZprs[2] = intParameter(++i); 2196 nlmZprs[3] = (isFloatParameter(i + 1) ? floatParameter(++i) : 6f); 2197 //if (surfaceObjectSeen) 2198 sbCommand.append(" atomicOrbital ").appendI((int) nlmZprs[0]) 2199 .append(" ").appendI((int) nlmZprs[1]).append(" ") 2200 .appendI((int) nlmZprs[2]).append(" ").appendF(nlmZprs[3]); 2201 if (tokAt(i + 1) == T.point) { 2202 i += 2; 2203 nlmZprs[4] = intParameter(i); 2204 nlmZprs[5] = (tokAt(i + 1) == T.decimal ? floatParameter(++i) : 0); 2205 nlmZprs[6] = (tokAt(i + 1) == T.integer ? intParameter(++i) 2206 : ((int) -System.currentTimeMillis()) % 10000); 2207 //if (surfaceObjectSeen) 2208 sbCommand.append(" points ").appendI((int) nlmZprs[4]).appendC(' ') 2209 .appendF(nlmZprs[5]).appendC(' ').appendI((int) nlmZprs[6]); 2210 } 2211 propertyName = "hydrogenOrbital"; 2212 propertyValue = nlmZprs; 2213 break; 2214 case T.binary: 2215 sbCommand.append(" binary"); 2216 // for PMESH, specifically 2217 // ignore for now 2218 continue; 2219 case T.blockdata: 2220 sbCommand.append(" blockData"); 2221 propertyName = "blockData"; 2222 propertyValue = Boolean.TRUE; 2223 break; 2224 case T.cap: 2225 case T.slab: 2226 haveSlab = true; 2227 propertyName = (String) eval.theToken.value; 2228 propertyValue = getCapSlabObject(i, false); 2229 i = eval.iToken; 2230 break; 2231 case T.cavity: 2232 if (!isIsosurface) 2233 invArg(); 2234 isCavity = true; 2235 float cavityRadius = (isFloatParameter(i + 1) ? floatParameter(++i) 2236 : 1.2f); 2237 float envelopeRadius = (isFloatParameter(i + 1) ? floatParameter(++i) 2238 : 10f); 2239 if (chk) 2240 continue; 2241 if (envelopeRadius > 50f) { 2242 eval.integerOutOfRange(0, 50); 2243 return; 2244 } 2245 sbCommand.append(" cavity ").appendF(cavityRadius).append(" ") 2246 .appendF(envelopeRadius); 2247 addShapeProperty(propertyList, "envelopeRadius", 2248 Float.valueOf(envelopeRadius)); 2249 addShapeProperty(propertyList, "cavityRadius", 2250 Float.valueOf(cavityRadius)); 2251 propertyName = "cavity"; 2252 break; 2253 case T.contour: 2254 case T.contours: 2255 propertyName = "contour"; 2256 sbCommand.append(" contour"); 2257 switch (tokAt(i + 1)) { 2258 case T.discrete: 2259 propertyValue = eval.floatParameterSet(i + 2, 1, Integer.MAX_VALUE); 2260 sbCommand.append(" discrete ") 2261 .append(Escape.eAF((float[]) propertyValue)); 2262 i = eval.iToken; 2263 break; 2264 case T.increment: 2265 pt = getPoint3f(i + 2, false); 2266 if (pt.z <= 0 || pt.y < pt.x) 2267 invArg(); // from to step 2268 if (pt.z == (int) pt.z && pt.z > (pt.y - pt.x)) 2269 pt.z = (pt.y - pt.x) / pt.z; 2270 propertyValue = pt; 2271 i = eval.iToken; 2272 sbCommand.append(" increment ").append(Escape.eP(pt)); 2273 break; 2274 default: 2275 propertyValue = Integer 2276 .valueOf(tokAt(i + 1) == T.integer ? intParameter(++i) : 0); 2277 sbCommand.append(" ").appendO(propertyValue); 2278 if (tokAt(i + 1) == T.integer) { 2279 addShapeProperty(propertyList, propertyName, propertyValue); 2280 propertyValue = Integer.valueOf(-Math.abs(intParameter(++i))); 2281 sbCommand.append(" ").appendO(propertyValue); 2282 } 2283 } 2284 break; 2285 case T.cutoff: 2286 sbCommand.append(" cutoff "); 2287 if (tokAt(++i) == T.plus) { 2288 propertyName = "cutoffPositive"; 2289 propertyValue = Float.valueOf(cutoff = floatParameter(++i)); 2290 sbCommand.append("+").appendO(propertyValue); 2291 } else if (isFloatParameter(i)) { 2292 propertyName = "cutoff"; 2293 propertyValue = Float.valueOf(cutoff = floatParameter(i)); 2294 sbCommand.appendO(propertyValue); 2295 } else { 2296 propertyName = "cutoffRange"; 2297 propertyValue = eval.floatParameterSet(i, 2, 2); 2298 addShapeProperty(propertyList, "cutoff", Float.valueOf(0)); 2299 sbCommand.append(Escape.eAF((float[]) propertyValue)); 2300 i = eval.iToken; 2301 } 2302 break; 2303 case T.downsample: 2304 propertyName = "downsample"; 2305 propertyValue = Integer.valueOf(intParameter(++i)); 2306 //if (surfaceObjectSeen) 2307 sbCommand.append(" downsample ").appendO(propertyValue); 2308 break; 2309 case T.eccentricity: 2310 propertyName = "eccentricity"; 2311 propertyValue = eval.getPoint4f(++i); 2312 //if (surfaceObjectSeen) 2313 sbCommand.append(" eccentricity ") 2314 .append(Escape.eP4((P4) propertyValue)); 2315 i = eval.iToken; 2316 break; 2317 case T.ed: 2318 sbCommand.append(" ed"); 2319 // electron density - never documented 2320 setMoData(propertyList, -1, null, 0, false, modelIndex, null, null, 2321 false); 2322 surfaceObjectSeen = true; 2323 continue; 2324 case T.debug: 2325 case T.nodebug: 2326 sbCommand.append(" ").appendO(eval.theToken.value); 2327 propertyName = "debug"; 2328 propertyValue = (tok == T.debug ? Boolean.TRUE : Boolean.FALSE); 2329 break; 2330 case T.fixed: 2331 sbCommand.append(" fixed"); 2332 propertyName = "fixed"; 2333 propertyValue = Boolean.TRUE; 2334 break; 2335 case T.fullplane: 2336 sbCommand.append(" fullPlane"); 2337 propertyName = "fullPlane"; 2338 propertyValue = Boolean.TRUE; 2339 break; 2340 case T.functionxy: 2341 case T.functionxyz: 2342 // isosurface functionXY "functionName"|"data2d_xxxxx" 2343 // isosurface functionXYZ "functionName"|"data3d_xxxxx" 2344 // {origin} {ni ix iy iz} {nj jx jy jz} {nk kx ky kz} 2345 // or 2346 // isosurface origin.. step... count... functionXY[Z] = "x + y + z" 2347 boolean isFxyz = (tok == T.functionxyz); 2348 propertyName = "" + eval.theToken.value; 2349 Lst<Object> vxy = new Lst<Object>(); 2350 propertyValue = vxy; 2351 isFxy = surfaceObjectSeen = true; 2352 //if (surfaceObjectSeen) 2353 sbCommand.append(" ").append(propertyName); 2354 String name = paramAsStr(++i); 2355 if (name.equals("=")) { 2356 //if (surfaceObjectSeen) 2357 sbCommand.append(" ="); 2358 name = paramAsStr(++i); 2359 //if (surfaceObjectSeen) 2360 sbCommand.append(" ").append(PT.esc(name)); 2361 vxy.addLast(name); 2362 if (!chk) 2363 addShapeProperty(propertyList, "func", 2364 createFunction("__iso__", "x,y,z", name)); 2365 //surfaceObjectSeen = true; 2366 break; 2367 } 2368 // override of function or data name when saved as a state 2369 String dName = PT.getQuotedAttribute(eval.fullCommand, 2370 "# DATA" + (isFxy ? "2" : "")); 2371 if (dName == null) 2372 dName = "inline"; 2373 else 2374 name = dName; 2375 boolean isXYZ = (name.indexOf("data2d_") == 0); 2376 boolean isXYZV = (name.indexOf("data3d_") == 0); 2377 isInline = name.equals("inline"); 2378 //if (!surfaceObjectSeen) 2379 sbCommand.append(" inline"); 2380 vxy.addLast(name); // (0) = name 2381 P3 pt3 = getPoint3f(++i, false); 2382 //if (!surfaceObjectSeen) 2383 sbCommand.append(" ").append(Escape.eP(pt3)); 2384 vxy.addLast(pt3); // (1) = {origin} 2385 P4 pt4; 2386 ptX = ++eval.iToken; 2387 vxy.addLast(pt4 = eval.getPoint4f(ptX)); // (2) = {ni ix iy iz} 2388 //if (!surfaceObjectSeen) 2389 sbCommand.append(" ").append(Escape.eP4(pt4)); 2390 nX = (int) pt4.x; 2391 ptY = ++eval.iToken; 2392 vxy.addLast(pt4 = eval.getPoint4f(ptY)); // (3) = {nj jx jy jz} 2393 //if (!surfaceObjectSeen) 2394 sbCommand.append(" ").append(Escape.eP4(pt4)); 2395 nY = (int) pt4.x; 2396 vxy.addLast(pt4 = eval.getPoint4f(++eval.iToken)); // (4) = {nk kx ky kz} 2397 //if (!surfaceObjectSeen) 2398 sbCommand.append(" ").append(Escape.eP4(pt4)); 2399 nZ = (int) pt4.x; 2400 2401 if (nX == 0 || nY == 0 || nZ == 0) 2402 invArg(); 2403 if (!chk) { 2404 float[][] fdata = null; 2405 float[][][] xyzdata = null; 2406 if (isFxyz) { 2407 if (isInline) { 2408 nX = Math.abs(nX); 2409 nY = Math.abs(nY); 2410 nZ = Math.abs(nZ); 2411 xyzdata = floatArraySetXYZ(++eval.iToken, nX, nY, nZ); 2412 } else if (isXYZV) { 2413 xyzdata = (float[][][]) vwr.getDataObj(name, null, 2414 JmolDataManager.DATA_TYPE_AFFF); 2415 } else { 2416 xyzdata = vwr.functionXYZ(name, nX, nY, nZ); 2417 } 2418 nX = Math.abs(nX); 2419 nY = Math.abs(nY); 2420 nZ = Math.abs(nZ); 2421 if (xyzdata == null) { 2422 eval.iToken = ptX; 2423 eval.errorStr(ScriptError.ERROR_what, "xyzdata is null."); 2424 } 2425 if (xyzdata.length != nX || xyzdata[0].length != nY 2426 || xyzdata[0][0].length != nZ) { 2427 eval.iToken = ptX; 2428 eval.errorStr(ScriptError.ERROR_what, 2429 "xyzdata[" + xyzdata.length + "][" + xyzdata[0].length + "][" 2430 + xyzdata[0][0].length + "] is not of size [" + nX + "][" 2431 + nY + "][" + nZ + "]"); 2432 } 2433 vxy.addLast(xyzdata); // (5) = float[][][] data 2434 //if (!surfaceObjectSeen) 2435 sbCommand.append(" ").append(Escape.e(xyzdata)); 2436 } else { 2437 if (isInline) { 2438 nX = Math.abs(nX); 2439 nY = Math.abs(nY); 2440 fdata = floatArraySet(++eval.iToken, nX, nY); 2441 } else if (isXYZ) { 2442 fdata = (float[][]) vwr.getDataObj(name, null, 2443 JmolDataManager.DATA_TYPE_AFF); 2444 nX = (fdata == null ? 0 : fdata.length); 2445 nY = 3; 2446 } else { 2447 fdata = vwr.functionXY(name, nX, nY); 2448 nX = Math.abs(nX); 2449 nY = Math.abs(nY); 2450 } 2451 if (fdata == null) { 2452 eval.iToken = ptX; 2453 eval.errorStr(ScriptError.ERROR_what, "fdata is null."); 2454 } 2455 if (fdata.length != nX && !isXYZ) { 2456 eval.iToken = ptX; 2457 eval.errorStr(ScriptError.ERROR_what, 2458 "fdata length is not correct: " + fdata.length + " " + nX 2459 + "."); 2460 } 2461 for (int j = 0; j < nX; j++) { 2462 if (fdata[j] == null) { 2463 eval.iToken = ptY; 2464 eval.errorStr(ScriptError.ERROR_what, 2465 "fdata[" + j + "] is null."); 2466 } 2467 if (fdata[j].length != nY) { 2468 eval.iToken = ptY; 2469 eval.errorStr(ScriptError.ERROR_what, 2470 "fdata[" + j + "] is not the right length: " 2471 + fdata[j].length + " " + nY + "."); 2472 } 2473 } 2474 vxy.addLast(fdata); // (5) = float[][] data 2475 //if (!surfaceObjectSeen) 2476 sbCommand.append(" ").append(Escape.e(fdata)); 2477 } 2478 } 2479 i = eval.iToken; 2480 break; 2481 case T.val: 2482 boolean isBS = e.isAtomExpression(++i); 2483 P3[] probes = getAllPoints(i, 1); 2484 sbCommand.append(" value " 2485 + (isBS ? e.atomExpressionAt(i).toString() : Escape.eAP(probes))); 2486 propertyName = "probes"; 2487 propertyValue = probes; 2488 i = e.iToken; 2489 break; 2490 case T.gridpoints: 2491 propertyName = "gridPoints"; 2492 sbCommand.append(" gridPoints"); 2493 break; 2494 case T.ignore: 2495 propertyName = "ignore"; 2496 propertyValue = bsIgnore = atomExpressionAt(++i); 2497 sbCommand.append(" ignore ").append(Escape.eBS(bsIgnore)); 2498 i = eval.iToken; 2499 break; 2500 case T.insideout: 2501 propertyName = "insideOut"; 2502 sbCommand.append(" insideout"); 2503 break; 2504 case T.internal: 2505 case T.interior: 2506 case T.pocket: 2507 //if (!surfaceObjectSeen) 2508 sbCommand.append(" ").appendO(eval.theToken.value); 2509 propertyName = "pocket"; 2510 propertyValue = (tok == T.pocket ? Boolean.TRUE : Boolean.FALSE); 2511 break; 2512 case T.lobe: 2513 // lobe {eccentricity} 2514 propertyName = "lobe"; 2515 propertyValue = eval.getPoint4f(++i); 2516 i = eval.iToken; 2517 //if (!surfaceObjectSeen) 2518 sbCommand.append(" lobe ").append(Escape.eP4((P4) propertyValue)); 2519 surfaceObjectSeen = true; 2520 break; 2521 case T.lonepair: 2522 case T.lp: 2523 // lp {eccentricity} 2524 propertyName = "lp"; 2525 propertyValue = eval.getPoint4f(++i); 2526 i = eval.iToken; 2527 //if (!surfaceObjectSeen) 2528 sbCommand.append(" lp ").append(Escape.eP4((P4) propertyValue)); 2529 surfaceObjectSeen = true; 2530 break; 2531 case T.mapproperty: 2532 if (isMapped || slen == i + 1) 2533 invArg(); 2534 isMapped = true; 2535 if ((isCavity || haveRadius || haveIntersection) 2536 && !surfaceObjectSeen) { 2537 surfaceObjectSeen = true; 2538 addShapeProperty(propertyList, "bsSolvent", 2539 (haveRadius || haveIntersection ? new BS() 2540 : eval.lookupIdentifierValue("solvent"))); 2541 addShapeProperty(propertyList, "sasurface", Float.valueOf(0)); 2542 } 2543 if (sbCommand.length() == 0) { 2544 plane = (P4) getShapeProperty(JC.SHAPE_ISOSURFACE, "plane"); 2545 if (plane == null) { 2546 if (getShapeProperty(JC.SHAPE_ISOSURFACE, "contours") != null) { 2547 addShapeProperty(propertyList, "nocontour", null); 2548 } 2549 } else { 2550 addShapeProperty(propertyList, "plane", plane); 2551 sbCommand.append("plane ").append(Escape.eP4(plane)); 2552 planeSeen = true; 2553 plane = null; 2554 } 2555 } else if (!surfaceObjectSeen && !planeSeen) { 2556 invArg(); 2557 } 2558 sbCommand.append("; isosurface map"); 2559 addShapeProperty(propertyList, "map", 2560 (surfaceObjectSeen ? Boolean.TRUE : Boolean.FALSE)); 2561 break; 2562 case T.maxset: 2563 propertyName = "maxset"; 2564 propertyValue = Integer.valueOf(intParameter(++i)); 2565 sbCommand.append(" maxSet ").appendO(propertyValue); 2566 break; 2567 case T.minset: 2568 propertyName = "minset"; 2569 propertyValue = Integer.valueOf(intParameter(++i)); 2570 sbCommand.append(" minSet ").appendO(propertyValue); 2571 break; 2572 case T.radical: 2573 // rad {eccentricity} 2574 surfaceObjectSeen = true; 2575 propertyName = "rad"; 2576 propertyValue = eval.getPoint4f(++i); 2577 i = eval.iToken; 2578 //if (!surfaceObjectSeen) 2579 sbCommand.append(" radical ").append(Escape.eP4((P4) propertyValue)); 2580 break; 2581 case T.modelbased: 2582 propertyName = "fixed"; 2583 propertyValue = Boolean.FALSE; 2584 sbCommand.append(" modelBased"); 2585 break; 2586 case T.molecular: 2587 case T.sasurface: 2588 case T.solvent: 2589 onlyOneModel = eval.theToken.value; 2590 float radius; 2591 if (tok == T.molecular) { 2592 propertyName = "molecular"; 2593 sbCommand.append(" molecular"); 2594 radius = (isFloatParameter(i + 1) ? floatParameter(++i) : 1.4f); 2595 } else { 2596 addShapeProperty(propertyList, "bsSolvent", 2597 eval.lookupIdentifierValue("solvent")); 2598 propertyName = (tok == T.sasurface ? "sasurface" : "solvent"); 2599 sbCommand.append(" ").appendO(eval.theToken.value); 2600 radius = (isFloatParameter(i + 1) ? floatParameter(++i) 2601 : vwr.getFloat(T.solventproberadius)); 2602 } 2603 sbCommand.append(" ").appendF(radius); 2604 propertyValue = Float.valueOf(radius); 2605 if (tokAt(i + 1) == T.full) { 2606 addShapeProperty(propertyList, "doFullMolecular", null); 2607 //if (!surfaceObjectSeen) 2608 sbCommand.append(" full"); 2609 i++; 2610 } 2611 surfaceObjectSeen = true; 2612 break; 2613 case T.mrc: 2614 addShapeProperty(propertyList, "fileType", "Mrc"); 2615 sbCommand.append(" mrc"); 2616 continue; 2617 case T.type: 2618 String s = eval.stringParameter(++i); 2619 addShapeProperty(propertyList, "fileType", s); 2620 sbCommand.append(" type \"" + s + "\""); 2621 continue; 2622 case T.object: 2623 case T.obj: 2624 addShapeProperty(propertyList, "fileType", "Obj"); 2625 sbCommand.append(" obj"); 2626 continue; 2627 case T.msms: 2628 addShapeProperty(propertyList, "fileType", "Msms"); 2629 sbCommand.append(" msms"); 2630 continue; 2631 case T.phase: 2632 if (surfaceObjectSeen) 2633 invArg(); 2634 propertyName = "phase"; 2635 isPhased = true; 2636 propertyValue = (tokAt(i + 1) == T.string ? stringParameter(++i) 2637 : "_orb"); 2638 sbCommand.append(" phase ").append(PT.esc((String) propertyValue)); 2639 break; 2640 case T.pointsperangstrom: 2641 case T.resolution: 2642 propertyName = "resolution"; 2643 propertyValue = Float.valueOf(floatParameter(++i)); 2644 sbCommand.append(" resolution ").appendO(propertyValue); 2645 break; 2646 case T.reversecolor: 2647 propertyName = "reverseColor"; 2648 propertyValue = Boolean.TRUE; 2649 sbCommand.append(" reversecolor"); 2650 break; 2651 case T.rmsd: 2652 case T.sigma: 2653 propertyName = "sigma"; 2654 propertyValue = Float.valueOf(sigma = floatParameter(++i)); 2655 sbCommand.append(" sigma ").appendO(propertyValue); 2656 break; 2657 case T.geosurface: 2658 // geosurface [radius] 2659 propertyName = "geodesic"; 2660 propertyValue = Float.valueOf(floatParameter(++i)); 2661 //if (!surfaceObjectSeen) 2662 sbCommand.append(" geosurface ").appendO(propertyValue); 2663 surfaceObjectSeen = true; 2664 break; 2665 case T.sphere: 2666 // sphere [radius] 2667 propertyName = "sphere"; 2668 propertyValue = Float.valueOf(floatParameter(++i)); 2669 //if (!surfaceObjectSeen) 2670 sbCommand.append(" sphere ").appendO(propertyValue); 2671 surfaceObjectSeen = true; 2672 break; 2673 case T.squared: 2674 propertyName = "squareData"; 2675 propertyValue = Boolean.TRUE; 2676 sbCommand.append(" squared"); 2677 break; 2678 case T.inline: 2679 propertyName = (!surfaceObjectSeen && !planeSeen && !isMapped 2680 ? "readFile" 2681 : "mapColor"); 2682 str = stringParameter(++i); 2683 if (str == null) 2684 invArg(); 2685 // inline PMESH data 2686 if (isPmesh) 2687 str = PT.replaceWithCharacter(str, "{,}|", ' '); 2688 if (eval.debugHigh) 2689 Logger.debug("pmesh inline data:\n" + str); 2690 propertyValue = (chk ? null : str); 2691 addShapeProperty(propertyList, "fileName", ""); 2692 sbCommand.append(" INLINE ").append(PT.esc(str)); 2693 surfaceObjectSeen = true; 2694 break; 2695 case T.leftsquare: 2696 case T.spacebeforesquare: 2697 case T.varray: 2698 // [ float, filename, float, filename, ...] 2699 if (filesData != null || isWild) 2700 invArg(); 2701 Lst<Object> list = eval.listParameter4(i, 2, Integer.MAX_VALUE, true); 2702 i = eval.iToken; 2703 int n = list.size() / 2; 2704 if (n == 0 || n * 2 != list.size()) 2705 invArg(); 2706 String[] files = new String[n]; 2707 float[] factors = new float[n]; 2708 sbCommand.append("["); 2709 try { 2710 for (int j = 0, ptf = 0; j < n; j++) { 2711 factors[j] = ((Float) list.get(ptf++)).floatValue(); 2712 files[j] = e.checkFileExists("ISOSURFACE_" + j + "_", false, 2713 (String) list.get(ptf++), i, false); 2714 sbCommand.appendF(factors[j]); 2715 sbCommand.append(" /*file*/").append(PT.esc(files[j])); 2716 } 2717 sbCommand.append("]"); 2718 } catch (Exception e) { 2719 invArg(); 2720 } 2721 filesData = new Object[] { files, factors }; 2722 propertyName = (!surfaceObjectSeen && !planeSeen && !isMapped 2723 ? "readFile" 2724 : "mapColor"); 2725 surfaceObjectSeen = true; 2726 if (chk) 2727 break; 2728 addShapeProperty(propertyList, "filesData", filesData); 2729 break; 2730 case T.eds: 2731 case T.edsdiff: 2732 case T.density: 2733 case T.string: 2734 boolean firstPass = (!surfaceObjectSeen && !planeSeen); 2735 String filename = null; 2736 propertyName = (firstPass && !isMapped ? "readFile" : "mapColor"); 2737 if (tok == T.string) { 2738 filename = paramAsStr(i); 2739 } else if (tok == T.density) { 2740 filename = "=density/"; 2741 } 2742 if (filename == null || filename.length() == 0 || filename.equals("*") || filename.equals("=")) { 2743 String pdbID = vwr.getPdbID(); 2744 if (pdbID == null) 2745 eval.errorStr(ScriptError.ERROR_invalidArgument, 2746 "no PDBID available"); 2747 filename = "*" + (tok == T.edsdiff ? "*" : "") + pdbID; 2748 } 2749 2750 /* 2751 * A file name, optionally followed by a calculation type and/or an integer file index. 2752 * Or =xxxx, an EDM from Uppsala Electron Density Server 2753 * If the model auxiliary info has "jmolSufaceInfo", we use that. 2754 */ 2755 boolean checkWithin = false; 2756 if (filename.startsWith("http://eds.bmc.uu.se/eds/dfs/cb/") 2757 && filename.endsWith(".omap")) { 2758 // decommissoning Uppsala 2759 filename = (filename.indexOf("_diff") >= 0 ? "*" : "") + "*" 2760 + filename.substring(32, 36); 2761 //"http://eds.bmc.uu.se/eds/dfs/cb/1cbs/1cbs_diff.omap" 2762 // 0 1 2 3 xxxx 2763 // 0123456789012345678901234567890123456789 2764 } 2765 2766 if (filename.startsWith("*") || filename.startsWith("=")) { 2767 boolean haveCutoff = (!Float.isNaN(cutoff) || !Float.isNaN(sigma)); 2768 boolean isFull = (filename.indexOf("/full") >= 0); 2769 if (isFull) 2770 filename = PT.rep(filename, "/full", ""); 2771 if (filename.indexOf("/diff") >= 0) 2772 filename = "*" + filename.substring(0, filename.indexOf("/diff")); 2773 if (filename.startsWith("**")) { 2774 if (!haveCutoff) 2775 addShapeProperty(propertyList, "sigma", Float.valueOf(sigma = 3)); 2776 if (!isSign) { 2777 isSign = true; 2778 sbCommand.append(" sign"); 2779 addShapeProperty(propertyList, "sign", Boolean.TRUE); 2780 } 2781 } 2782 String fn = filename; 2783 filename = (String) vwr.setLoadFormat(filename, 2784 (chk? '?' : isFull ? '_' : '-'), false); 2785 if (filename == null) 2786 eval.errorStr(ScriptError.ERROR_invalidArgument, 2787 "error parsing filename: " + fn); 2788 // the initial dummy call just asertains that 2789 checkWithin = !isFull; 2790 } 2791 if (checkWithin) { 2792 if (pts == null && ptWithin == 0) { 2793 onlyOneModel = filename; 2794 if (modelIndex < 0) 2795 modelIndex = vwr.am.cmi; 2796 bs = vwr.getModelUndeletedAtomsBitSet(modelIndex); 2797 if (bs.nextSetBit(0) >= 0) { 2798 pts = getWithinDistanceVector(propertyList, 2.0f, null, bs, 2799 false); 2800 sbCommand.append(" within 2.0 ").append(Escape.eBS(bs)); 2801 } 2802 } 2803 if (pts != null && filename.indexOf("/0,0,0/0,0,0?") >= 0) { 2804 filename = filename.replace("0,0,0/0,0,0", 2805 pts[0].x + "," + pts[0].y + "," + pts[0].z + "/" 2806 + pts[pts.length - 1].x + "," + pts[pts.length - 1].y + "," 2807 + pts[pts.length - 1].z); 2808 } 2809 if (firstPass) 2810 defaultMesh = true; 2811 } 2812 int p = (filename == null ? -1 : filename.indexOf("#-")); 2813 if (Float.isNaN(sigma) && Float.isNaN(cutoff)) { 2814 if ((p = filename.indexOf("#-cutoff=")) >= 0) { 2815 addShapeProperty(propertyList, "cutoff", Float.valueOf(cutoff = Float.parseFloat(filename.substring(p + 9)))); 2816 sbCommand.append(" cutoff " + cutoff); 2817 } else if ((p = filename.indexOf("#-sigma=")) >= 0) { 2818 addShapeProperty(propertyList, "sigma", Float.valueOf(sigma = Float.parseFloat(filename.substring(p + 8)))); 2819 sbCommand.append(" sigma " + sigma); 2820 } 2821 } 2822 if (!Float.isNaN(sigma)) 2823 showString("using sigma = " + sigma); 2824 else if (!Float.isNaN(cutoff)) 2825 showString("using cutoff = " + cutoff); 2826 if (firstPass && vwr.getP("_fileType").equals("Pdb") 2827 && Float.isNaN(sigma) && Float.isNaN(cutoff)) { 2828 // negative sigma just indicates that 2829 addShapeProperty(propertyList, "sigma", Float.valueOf(-1)); 2830 sbCommand.append(" sigma -1.0"); 2831 } 2832 if (filename.length() == 0) { 2833 if (modelIndex < 0) 2834 modelIndex = vwr.am.cmi; 2835 filename = eval.getFullPathName(); 2836 propertyValue = vwr.ms.getInfo(modelIndex, "jmolSurfaceInfo"); // not implemented? 2837 } 2838 int fileIndex = -1; 2839 if (propertyValue == null && tokAt(i + 1) == T.integer) 2840 addShapeProperty(propertyList, "fileIndex", 2841 Integer.valueOf(fileIndex = intParameter(++i))); 2842 String stype = (tokAt(i + 1) == T.string ? stringParameter(++i) : null); 2843 // done reading parameters 2844 surfaceObjectSeen = true; 2845 if (chk) { 2846 break; 2847 } 2848 String[] fullPathNameOrError; 2849 String localName = null; 2850 if (propertyValue == null) { 2851 if (eval.fullCommand.indexOf("# FILE" + nFiles + "=") >= 0) { 2852 // old way, abandoned 2853 filename = PT.getQuotedAttribute(eval.fullCommand, 2854 "# FILE" + nFiles); 2855 if (tokAt(i + 1) == T.as) 2856 i += 2; // skip that 2857 } else if (tokAt(i + 1) == T.as) { 2858 localName = vwr.fm.getFilePath( 2859 stringParameter(eval.iToken = (i = i + 2)), false, false); 2860 fullPathNameOrError = vwr.getFullPathNameOrError(localName); 2861 localName = fullPathNameOrError[0]; 2862 if (vwr.fm.getPathForAllFiles() != "") { 2863 // we use the LOCAL name when reading from a local path only (in the case of JMOL files) 2864 filename = localName; 2865 localName = null; 2866 } else { 2867 addShapeProperty(propertyList, "localName", localName); 2868 } 2869 } 2870 } 2871 // just checking here, and getting the full path name 2872 if (stype == null) { 2873 filename = e.checkFileExists("ISOSURFACE_" + (isMapped ? "MAP_" : ""), 2874 false, filename, i, false); 2875 } 2876 showString("reading isosurface data from " + filename); 2877 2878 if (stype != null) { 2879 propertyValue = vwr.fm.cacheGet(filename, false); 2880 addShapeProperty(propertyList, "calculationType", stype); 2881 } 2882 if (propertyValue == null) { 2883 addShapeProperty(propertyList, "fileName", filename); 2884 if (localName != null) 2885 filename = localName; 2886 if (fileIndex >= 0) 2887 sbCommand.append(" ").appendI(fileIndex); 2888 } 2889 sbCommand.append(" /*file*/").append(PT.esc(filename)); 2890 if (stype != null) 2891 sbCommand.append(" ").append(PT.esc(stype)); 2892 break; 2893 case T.connect: 2894 propertyName = "connections"; 2895 switch (tokAt(++i)) { 2896 case T.define: 2897 case T.bitset: 2898 case T.expressionBegin: 2899 propertyValue = new int[] { atomExpressionAt(i).nextSetBit(0) }; 2900 break; 2901 default: 2902 propertyValue = new int[] { 2903 (int) eval.floatParameterSet(i, 1, 1)[0] }; 2904 break; 2905 } 2906 i = eval.iToken; 2907 break; 2908 case T.atomindex: 2909 propertyName = "atomIndex"; 2910 propertyValue = Integer.valueOf(intParameter(++i)); 2911 break; 2912 case T.link: 2913 propertyName = "link"; 2914 sbCommand.append(" link"); 2915 break; 2916 case T.unitcell: 2917 if (iShape != JC.SHAPE_ISOSURFACE) 2918 invArg(); 2919 if (tokAt(i + 1) == T.plus) 2920 i++; 2921 propertyName = "extendGrid"; 2922 propertyValue = Float.valueOf(floatParameter(++i)); 2923 sbCommand.append(" unitcell " + propertyValue); 2924 break; 2925 case T.lattice: 2926 if (iShape != JC.SHAPE_ISOSURFACE) 2927 invArg(); 2928 pt = getPoint3f(++i, false); 2929 i = eval.iToken; 2930 if (pt.x <= 0 || pt.y <= 0 || pt.z <= 0) 2931 break; 2932 pt.x = (int) pt.x; 2933 pt.y = (int) pt.y; 2934 pt.z = (int) pt.z; 2935 sbCommand.append(" lattice ").append(Escape.eP(pt)); 2936 if (isMapped) { 2937 propertyName = "mapLattice"; 2938 propertyValue = pt; 2939 } else { 2940 lattice = pt; 2941 if (tokAt(i + 1) == T.fixed) { 2942 sbCommand.append(" fixed"); 2943 fixLattice = true; 2944 i++; 2945 } 2946 } 2947 break; 2948 default: 2949 if (tok == T.identifier) { 2950 propertyName = "thisID"; 2951 propertyValue = str; 2952 } 2953 /* I have no idea why this is here.... 2954 if (planeSeen && !surfaceObjectSeen) { 2955 addShapeProperty(propertyList, "nomap", Float.valueOf(0)); 2956 surfaceObjectSeen = true; 2957 } 2958 */ 2959 if (!eval.setMeshDisplayProperty(iShape, 0, tok)) { 2960 if (T.tokAttr(tok, T.identifier) && !idSeen) { 2961 setShapeId(iShape, i, idSeen); 2962 i = eval.iToken; 2963 break; 2964 } 2965 invArg(); 2966 } 2967 if (iptDisplayProperty == 0) 2968 iptDisplayProperty = i; 2969 i = slen - 1; 2970 break; 2971 } 2972 idSeen = (tok != T.delete); 2973 if (isWild && surfaceObjectSeen) 2974 invArg(); 2975 if (propertyName != null) 2976 addShapeProperty(propertyList, propertyName, propertyValue); 2977 } 2978 2979 // OK, now send them all 2980 2981 if (!chk) { 2982 if ((isCavity || haveRadius) && !surfaceObjectSeen) { 2983 surfaceObjectSeen = true; 2984 addShapeProperty(propertyList, "bsSolvent", 2985 (haveRadius ? new BS() : eval.lookupIdentifierValue("solvent"))); 2986 addShapeProperty(propertyList, "sasurface", Float.valueOf(0)); 2987 } 2988 if (planeSeen && !surfaceObjectSeen && !isMapped) { 2989 // !isMapped mp.added 6/14/2012 12.3.30 2990 // because it was preventing planes from being mapped properly 2991 addShapeProperty(propertyList, "nomap", Float.valueOf(0)); 2992 surfaceObjectSeen = true; 2993 } 2994 if (thisSet != null) 2995 addShapeProperty(propertyList, "getSurfaceSets", thisSet); 2996 if (discreteColixes != null) { 2997 addShapeProperty(propertyList, "colorDiscrete", discreteColixes); 2998 } else if ("sets".equals(colorScheme)) { 2999 addShapeProperty(propertyList, "setColorScheme", null); 3000 } else if (colorScheme != null) { 3001 ColorEncoder ce = vwr.cm.getColorEncoder(colorScheme); 3002 if (ce != null) { 3003 ce.isTranslucent = isColorSchemeTranslucent; 3004 ce.hi = Float.MAX_VALUE; 3005 addShapeProperty(propertyList, "remapColor", ce); 3006 } 3007 } 3008 if (surfaceObjectSeen && !isLcaoCartoon && sbCommand.indexOf(";") != 0) { 3009 propertyList.add(0, new Object[] { "newObject", null }); 3010 boolean needSelect = (bsSelect == null); 3011 if (needSelect) 3012 bsSelect = BSUtil.copy(vwr.bsA()); 3013 if (modelIndex < 0) 3014 modelIndex = vwr.am.cmi; 3015 bsSelect.and(vwr.getModelUndeletedAtomsBitSet(modelIndex)); 3016 if (onlyOneModel != null) { 3017 BS bsModels = vwr.ms.getModelBS(bsSelect, false); 3018 if (bsModels.cardinality() > 1) 3019 eval.errorStr(ScriptError.ERROR_multipleModelsDisplayedNotOK, 3020 "ISOSURFACE " + onlyOneModel); 3021 if (needSelect) { 3022 propertyList.add(0, new Object[] { "select", bsSelect }); 3023 if (sbCommand.indexOf("; isosurface map") == 0) { 3024 sbCommand = new SB().append("; isosurface map select ") 3025 .append(Escape.eBS(bsSelect)).append(sbCommand.substring(16)); 3026 } 3027 } 3028 } 3029 } 3030 if (haveIntersection && !haveSlab) { 3031 if (!surfaceObjectSeen) 3032 addShapeProperty(propertyList, "sasurface", Float.valueOf(0)); 3033 if (!isMapped) { 3034 addShapeProperty(propertyList, "map", Boolean.TRUE); 3035 addShapeProperty(propertyList, "select", bs); 3036 addShapeProperty(propertyList, "sasurface", Float.valueOf(0)); 3037 } 3038 addShapeProperty(propertyList, "slab", getCapSlabObject(-100, false)); 3039 } 3040 3041 boolean timeMsg = (surfaceObjectSeen && vwr.getBoolean(T.showtiming)); 3042 if (timeMsg) 3043 Logger.startTimer("isosurface"); 3044 setShapeProperty(iShape, "setProperties", propertyList); 3045 if (timeMsg) 3046 showString(Logger.getTimerMsg("isosurface", 0)); 3047 if (defaultMesh) { 3048 setShapeProperty(iShape, "token", Integer.valueOf(T.mesh)); 3049 setShapeProperty(iShape, "token", Integer.valueOf(T.nofill)); 3050 isFrontOnly = true; 3051 sbCommand.append(" mesh nofill frontOnly"); 3052 } 3053 } 3054 if (lattice != null) { // before MAP, this is a display option 3055 setShapeProperty(iShape, "lattice", lattice); 3056 if (fixLattice) 3057 setShapeProperty(iShape, "fixLattice", Boolean.TRUE); 3058 } 3059 if (symops != null) // before MAP, this is a display option 3060 setShapeProperty(iShape, "symops", symops); 3061 if (isFrontOnly) 3062 setShapeProperty(iShape, "token", Integer.valueOf(T.frontonly)); 3063 if (iptDisplayProperty > 0) { 3064 if (!eval.setMeshDisplayProperty(iShape, iptDisplayProperty, 0)) 3065 invArg(); 3066 } 3067 if (chk) 3068 return; 3069 Object area = null; 3070 Object volume = null; 3071 if (doCalcArea) { 3072 area = getShapeProperty(iShape, "area"); 3073 if (area instanceof Float) 3074 vwr.setFloatProperty("isosurfaceArea", ((Float) area).floatValue()); 3075 else 3076 vwr.g.setUserVariable("isosurfaceArea", 3077 SV.getVariableAD((double[]) area)); 3078 } 3079 if (doCalcVolume) { 3080 volume = (doCalcVolume ? getShapeProperty(iShape, "volume") : null); 3081 if (volume instanceof Float) 3082 vwr.setFloatProperty("isosurfaceVolume", ((Float) volume).floatValue()); 3083 else 3084 vwr.g.setUserVariable("isosurfaceVolume", 3085 SV.getVariableAD((double[]) volume)); 3086 } 3087 if (!isLcaoCartoon) { 3088 String s = null; 3089 if (isMapped && !surfaceObjectSeen) { 3090 setShapeProperty(iShape, "finalize", sbCommand.toString()); 3091 } else if (surfaceObjectSeen) { 3092 cmd = sbCommand.toString(); 3093 setShapeProperty(iShape, "finalize", 3094 (cmd.indexOf("; isosurface map") == 0 ? "" 3095 : " select " + Escape.eBS(bsSelect) + " ") + cmd); 3096 s = (String) getShapeProperty(iShape, "ID"); 3097 if (s != null && !eval.tQuiet && !isSilent) { 3098 cutoff = ((Float) getShapeProperty(iShape, "cutoff")).floatValue(); 3099 if (Float.isNaN(cutoff) && !Float.isNaN(sigma)) 3100 Logger.error("sigma not supported"); 3101 s += " created " + getShapeProperty(iShape, "message"); 3102 } 3103 } 3104 String sarea, svol; 3105 if (doCalcArea || doCalcVolume) { 3106 sarea = (doCalcArea ? "isosurfaceArea = " 3107 + (area instanceof Float ? "" + area : Escape.eAD((double[]) area)) 3108 : null); 3109 svol = (doCalcVolume 3110 ? "isosurfaceVolume = " + (volume instanceof Float ? "" + volume 3111 : Escape.eAD((double[]) volume)) 3112 : null); 3113 if (s == null) { 3114 if (doCalcArea) 3115 showString(sarea); 3116 if (doCalcVolume) 3117 showString(svol); 3118 } else { 3119 if (doCalcArea) 3120 s += "\n" + sarea; 3121 if (doCalcVolume) 3122 s += "\n" + svol; 3123 } 3124 } 3125 if (s != null && !isSilent) 3126 showString(s); 3127 if (surfaceObjectSeen) { 3128 s = (String) getShapeProperty(iShape, "output"); 3129 if (s != null && !isSilent) 3130 showString(s); 3131 } 3132 } 3133 3134 if (translucency != null) 3135 setShapeProperty(iShape, "translucency", translucency); 3136 setShapeProperty(iShape, "clear", null); 3137 if (toCache) 3138 setShapeProperty(iShape, "cache", null); 3139 if (!isSilent && !isDisplay && !haveSlab && eval.theTok != T.delete) 3140 listIsosurface(iShape); 3141 } 3142 lcaoCartoon()3143 private void lcaoCartoon() throws ScriptException { 3144 ScriptEval eval = e; 3145 eval.sm.loadShape(JC.SHAPE_LCAOCARTOON); 3146 if (eval.tokAt(1) == T.list && listIsosurface(JC.SHAPE_LCAOCARTOON)) 3147 return; 3148 setShapeProperty(JC.SHAPE_LCAOCARTOON, "init", eval.fullCommand); 3149 if (slen == 1) { 3150 setShapeProperty(JC.SHAPE_LCAOCARTOON, "lcaoID", null); 3151 return; 3152 } 3153 boolean idSeen = false; 3154 String translucency = null; 3155 for (int i = 1; i < slen; i++) { 3156 String propertyName = null; 3157 Object propertyValue = null; 3158 switch (getToken(i).tok) { 3159 case T.cap: 3160 case T.slab: 3161 propertyName = (String) eval.theToken.value; 3162 if (tokAt(i + 1) == T.off) 3163 eval.iToken = i + 1; 3164 propertyValue = getCapSlabObject(i, true); 3165 i = eval.iToken; 3166 break; 3167 case T.center: 3168 // serialized lcaoCartoon in isosurface format 3169 isosurface(JC.SHAPE_LCAOCARTOON); 3170 return; 3171 case T.rotate: 3172 float degx = 0; 3173 float degy = 0; 3174 float degz = 0; 3175 switch (getToken(++i).tok) { 3176 case T.x: 3177 degx = floatParameter(++i) * JC.radiansPerDegree; 3178 break; 3179 case T.y: 3180 degy = floatParameter(++i) * JC.radiansPerDegree; 3181 break; 3182 case T.z: 3183 degz = floatParameter(++i) * JC.radiansPerDegree; 3184 break; 3185 default: 3186 invArg(); 3187 } 3188 propertyName = "rotationAxis"; 3189 propertyValue = V3.new3(degx, degy, degz); 3190 break; 3191 case T.on: 3192 case T.display: 3193 case T.displayed: 3194 propertyName = "on"; 3195 break; 3196 case T.off: 3197 case T.hide: 3198 case T.hidden: 3199 propertyName = "off"; 3200 break; 3201 case T.delete: 3202 propertyName = "delete"; 3203 break; 3204 case T.define: 3205 case T.bitset: 3206 case T.expressionBegin: 3207 propertyName = "select"; 3208 propertyValue = atomExpressionAt(i); 3209 i = eval.iToken; 3210 break; 3211 case T.color: 3212 translucency = setColorOptions(null, i + 1, JC.SHAPE_LCAOCARTOON, -2); 3213 if (translucency != null) 3214 setShapeProperty(JC.SHAPE_LCAOCARTOON, "settranslucency", 3215 translucency); 3216 i = eval.iToken; 3217 idSeen = true; 3218 continue; 3219 case T.translucent: 3220 case T.opaque: 3221 eval.setMeshDisplayProperty(JC.SHAPE_LCAOCARTOON, i, eval.theTok); 3222 i = eval.iToken; 3223 idSeen = true; 3224 continue; 3225 case T.spacefill: 3226 case T.string: 3227 propertyValue = paramAsStr(i).toLowerCase(); 3228 if (propertyValue.equals("spacefill")) 3229 propertyValue = "cpk"; 3230 propertyName = "create"; 3231 if (eval.optParameterAsString(i + 1).equalsIgnoreCase("molecular")) { 3232 i++; 3233 propertyName = "molecular"; 3234 } 3235 break; 3236 case T.select: 3237 if (eval.isAtomExpression(i + 1)) { 3238 propertyName = "select"; 3239 propertyValue = atomExpressionAt(i + 1); 3240 i = eval.iToken; 3241 } else { 3242 propertyName = "selectType"; 3243 propertyValue = paramAsStr(++i); 3244 if (propertyValue.equals("spacefill")) 3245 propertyValue = "cpk"; 3246 } 3247 break; 3248 case T.scale: 3249 propertyName = "scale"; 3250 propertyValue = Float.valueOf(floatParameter(++i)); 3251 break; 3252 case T.lonepair: 3253 case T.lp: 3254 propertyName = "lonePair"; 3255 break; 3256 case T.radical: 3257 case T.rad: 3258 propertyName = "radical"; 3259 break; 3260 case T.molecular: 3261 propertyName = "molecular"; 3262 break; 3263 case T.create: 3264 propertyValue = paramAsStr(++i); 3265 propertyName = "create"; 3266 if (eval.optParameterAsString(i + 1).equalsIgnoreCase("molecular")) { 3267 i++; 3268 propertyName = "molecular"; 3269 } 3270 break; 3271 case T.id: 3272 propertyValue = eval.setShapeNameParameter(++i); 3273 i = eval.iToken; 3274 if (idSeen) 3275 invArg(); 3276 propertyName = "lcaoID"; 3277 break; 3278 default: 3279 if (eval.theTok == T.times || T.tokAttr(eval.theTok, T.identifier)) { 3280 if (eval.theTok != T.times) 3281 propertyValue = paramAsStr(i); 3282 if (idSeen) 3283 invArg(); 3284 propertyName = "lcaoID"; 3285 break; 3286 } 3287 break; 3288 } 3289 if (eval.theTok != T.delete) 3290 idSeen = true; 3291 if (propertyName == null) 3292 invArg(); 3293 setShapeProperty(JC.SHAPE_LCAOCARTOON, propertyName, propertyValue); 3294 } 3295 setShapeProperty(JC.SHAPE_LCAOCARTOON, "clear", null); 3296 } 3297 contact()3298 private boolean contact() throws ScriptException { 3299 ScriptEval eval = e; 3300 eval.sm.loadShape(JC.SHAPE_CONTACT); 3301 if (tokAt(1) == T.list && listIsosurface(JC.SHAPE_CONTACT)) 3302 return false; 3303 int iptDisplayProperty = 0; 3304 eval.iToken = 1; 3305 String thisId = initIsosurface(JC.SHAPE_CONTACT); 3306 boolean idSeen = (thisId != null); 3307 boolean isWild = (idSeen 3308 && getShapeProperty(JC.SHAPE_CONTACT, "ID") == null); 3309 BS bsA = null; 3310 BS bsB = null; 3311 BS bs = null; 3312 RadiusData rd = null; 3313 float[] params = null; 3314 boolean colorDensity = false; 3315 SB sbCommand = new SB(); 3316 int minSet = Integer.MAX_VALUE; 3317 int displayType = T.plane; 3318 int contactType = T.nada; 3319 float distance = Float.NaN; 3320 float saProbeRadius = Float.NaN; 3321 boolean localOnly = true; 3322 Boolean intramolecular = null; 3323 Object userSlabObject = null; 3324 int colorpt = 0; 3325 boolean colorByType = false; 3326 int tok; 3327 int modelIndex = Integer.MIN_VALUE; 3328 boolean okNoAtoms = (eval.iToken > 1); 3329 for (int i = eval.iToken; i < slen; ++i) { 3330 switch (tok = getToken(i).tok) { 3331 // these first do not need atoms defined 3332 default: 3333 okNoAtoms = true; 3334 if (!eval.setMeshDisplayProperty(JC.SHAPE_CONTACT, 0, eval.theTok)) { 3335 if (eval.theTok != T.times && !T.tokAttr(eval.theTok, T.identifier)) 3336 invArg(); 3337 thisId = setShapeId(JC.SHAPE_CONTACT, i, idSeen); 3338 i = eval.iToken; 3339 break; 3340 } 3341 if (iptDisplayProperty == 0) 3342 iptDisplayProperty = i; 3343 i = eval.iToken; 3344 continue; 3345 case T.id: 3346 okNoAtoms = true; 3347 setShapeId(JC.SHAPE_CONTACT, ++i, idSeen); 3348 isWild = (getShapeProperty(JC.SHAPE_CONTACT, "ID") == null); 3349 i = eval.iToken; 3350 break; 3351 case T.color: 3352 switch (tokAt(i + 1)) { 3353 case T.density: 3354 tok = T.nada; 3355 colorDensity = true; 3356 sbCommand.append(" color density"); 3357 i++; 3358 break; 3359 case T.type: 3360 tok = T.nada; 3361 colorByType = true; 3362 sbCommand.append(" color type"); 3363 i++; 3364 break; 3365 } 3366 if (tok == T.nada) 3367 break; 3368 //$FALL-THROUGH$ to translucent 3369 case T.translucent: 3370 case T.opaque: 3371 okNoAtoms = true; 3372 if (colorpt == 0) 3373 colorpt = i; 3374 eval.setMeshDisplayProperty(JC.SHAPE_CONTACT, i, eval.theTok); 3375 i = eval.iToken; 3376 break; 3377 case T.slab: 3378 okNoAtoms = true; 3379 userSlabObject = getCapSlabObject(i, false); 3380 setShapeProperty(JC.SHAPE_CONTACT, "slab", userSlabObject); 3381 i = eval.iToken; 3382 break; 3383 3384 // now after this you need atoms 3385 3386 case T.density: 3387 colorDensity = true; 3388 sbCommand.append(" density"); 3389 if (isFloatParameter(i + 1)) { 3390 if (params == null) 3391 params = new float[1]; 3392 params[0] = -Math.abs(floatParameter(++i)); 3393 sbCommand.append(" " + -params[0]); 3394 } 3395 break; 3396 case T.resolution: 3397 float resolution = floatParameter(++i); 3398 if (resolution > 0) { 3399 sbCommand.append(" resolution ").appendF(resolution); 3400 setShapeProperty(JC.SHAPE_CONTACT, "resolution", 3401 Float.valueOf(resolution)); 3402 } 3403 break; 3404 case T.model: 3405 case T.modelindex: 3406 modelIndex = (eval.theTok == T.modelindex ? intParameter(++i) 3407 : eval.modelNumberParameter(++i)); 3408 sbCommand.append(" modelIndex " + modelIndex); 3409 break; 3410 case T.within: 3411 case T.distance: 3412 distance = floatParameter(++i); 3413 sbCommand.append(" within ").appendF(distance); 3414 break; 3415 case T.plus: 3416 case T.integer: 3417 case T.decimal: 3418 rd = eval.encodeRadiusParameter(i, false, false); 3419 if (rd == null) 3420 return false; 3421 sbCommand.append(" ").appendO(rd); 3422 i = eval.iToken; 3423 break; 3424 case T.intermolecular: 3425 case T.intramolecular: 3426 intramolecular = (tok == T.intramolecular ? Boolean.TRUE 3427 : Boolean.FALSE); 3428 sbCommand.append(" ").appendO(eval.theToken.value); 3429 break; 3430 case T.minset: 3431 minSet = intParameter(++i); 3432 break; 3433 case T.hbond: 3434 case T.clash: 3435 case T.vanderwaals: 3436 contactType = tok; 3437 sbCommand.append(" ").appendO(eval.theToken.value); 3438 break; 3439 case T.sasurface: 3440 if (isFloatParameter(i + 1)) 3441 saProbeRadius = floatParameter(++i); 3442 //$FALL-THROUGH$ 3443 case T.cap: 3444 case T.nci: 3445 case T.surface: 3446 localOnly = false; 3447 //$FALL-THROUGH$ 3448 case T.trim: 3449 case T.full: 3450 case T.plane: 3451 case T.connect: 3452 displayType = tok; 3453 sbCommand.append(" ").appendO(eval.theToken.value); 3454 if (tok == T.sasurface) 3455 sbCommand.append(" ").appendF(saProbeRadius); 3456 break; 3457 case T.parameters: 3458 params = eval.floatParameterSet(++i, 1, 10); 3459 i = eval.iToken; 3460 break; 3461 case T.define: 3462 case T.bitset: 3463 case T.expressionBegin: 3464 if (isWild || bsB != null) 3465 invArg(); 3466 bs = BSUtil.copy(atomExpressionAt(i)); 3467 i = eval.iToken; 3468 if (bsA == null) 3469 bsA = bs; 3470 else 3471 bsB = bs; 3472 sbCommand.append(" ").append(Escape.eBS(bs)); 3473 break; 3474 } 3475 idSeen = (eval.theTok != T.delete); 3476 } 3477 if (!okNoAtoms && bsA == null) 3478 error(ScriptError.ERROR_endOfStatementUnexpected); 3479 if (chk) 3480 return false; 3481 3482 if (bsA != null) { 3483 // bond mode, intramolec set here 3484 if (contactType == T.vanderwaals && rd == null) 3485 rd = new RadiusData(null, 0, EnumType.OFFSET, VDW.AUTO); 3486 RadiusData rd1 = (rd == null 3487 ? new RadiusData(null, 0.26f, EnumType.OFFSET, VDW.AUTO) 3488 : rd); 3489 if (displayType == T.nci && bsB == null && intramolecular != null 3490 && intramolecular.booleanValue()) 3491 bsB = bsA; 3492 else 3493 bsB = eval.getMathExt().setContactBitSets(bsA, bsB, localOnly, distance, 3494 rd1, true); 3495 switch (displayType) { 3496 case T.cap: 3497 case T.sasurface: 3498 BS bsSolvent = eval.lookupIdentifierValue("solvent"); 3499 bsA.andNot(bsSolvent); 3500 bsB.andNot(bsSolvent); 3501 bsB.andNot(bsA); 3502 break; 3503 case T.surface: 3504 bsB.andNot(bsA); 3505 break; 3506 case T.nci: 3507 if (minSet == Integer.MAX_VALUE) 3508 minSet = 100; 3509 setShapeProperty(JC.SHAPE_CONTACT, "minset", Integer.valueOf(minSet)); 3510 sbCommand.append(" minSet ").appendI(minSet); 3511 if (params == null) 3512 params = new float[] { 0.5f, 2 }; 3513 } 3514 3515 if (intramolecular != null) { 3516 params = (params == null ? new float[2] : AU.ensureLengthA(params, 2)); 3517 params[1] = (intramolecular.booleanValue() ? 1 : 2); 3518 } 3519 3520 if (params != null) 3521 sbCommand.append(" parameters ").append(Escape.eAF(params)); 3522 3523 // now adjust for type -- HBOND or HYDROPHOBIC or MISC 3524 // these are just "standard shortcuts" they are not necessary at all 3525 setShapeProperty(JC.SHAPE_CONTACT, "set", 3526 new Object[] { Integer.valueOf(contactType), 3527 Integer.valueOf(displayType), Boolean.valueOf(colorDensity), 3528 Boolean.valueOf(colorByType), bsA, bsB, rd, 3529 Float.valueOf(saProbeRadius), params, Integer.valueOf(modelIndex), 3530 sbCommand.toString() }); 3531 if (colorpt > 0) 3532 eval.setMeshDisplayProperty(JC.SHAPE_CONTACT, colorpt, 0); 3533 } 3534 if (iptDisplayProperty > 0) { 3535 if (!eval.setMeshDisplayProperty(JC.SHAPE_CONTACT, iptDisplayProperty, 0)) 3536 invArg(); 3537 } 3538 if (userSlabObject != null && bsA != null) 3539 setShapeProperty(JC.SHAPE_CONTACT, "slab", userSlabObject); 3540 if (bsA != null && (displayType == T.nci || localOnly)) { 3541 Object volume = getShapeProperty(JC.SHAPE_CONTACT, "volume"); 3542 double v; 3543 boolean isFull = (displayType == T.full); 3544 if (AU.isAD(volume)) { 3545 double[] vs = (double[]) volume; 3546 v = 0; 3547 for (int i = 0; i < vs.length; i++) 3548 v += (isFull ? vs[i] : Math.abs(vs[i])); // no abs value for full -- some are negative 3549 } else { 3550 v = ((Float) volume).floatValue(); 3551 } 3552 v = (Math.round(v * 1000) / 1000.); 3553 if (colorDensity || displayType != T.trim) { 3554 int nsets = ((Integer) getShapeProperty(JC.SHAPE_CONTACT, "nSets")) 3555 .intValue(); // will be < 0 if FULL option 3556 String s = "Contacts: " + (nsets < 0 ? -nsets / 2 : nsets); 3557 if (v != 0) 3558 s += ", with " + (isFull ? "approx " : "net ") + "volume " + v 3559 + " A^3"; 3560 showString(s); 3561 } 3562 } 3563 return true; 3564 } 3565 cgo()3566 private boolean cgo() throws ScriptException { 3567 ScriptEval eval = e; 3568 eval.sm.loadShape(JC.SHAPE_CGO); 3569 if (tokAt(1) == T.list && listIsosurface(JC.SHAPE_CGO)) 3570 return false; 3571 int iptDisplayProperty = 0; 3572 String thisId = initIsosurface(JC.SHAPE_CGO); 3573 boolean idSeen = (thisId != null); 3574 boolean isWild = (idSeen && getShapeProperty(JC.SHAPE_CGO, "ID") == null); 3575 boolean isInitialized = false; 3576 int modelIndex = -1; 3577 Lst<Object> data = null; 3578 float translucentLevel = Float.MAX_VALUE; 3579 int[] colorArgb = new int[] { Integer.MIN_VALUE }; 3580 int intScale = 0; 3581 for (int i = eval.iToken; i < slen; ++i) { 3582 String propertyName = null; 3583 Object propertyValue = null; 3584 int tok = getToken(i).tok; 3585 switch (tok) { 3586 case T.leftsquare: 3587 case T.spacebeforesquare: 3588 case T.varray: 3589 if (data != null || isWild) 3590 invArg(); 3591 data = new Lst<Object>(); 3592 int[] ai = new int[] { i, slen }; 3593 if (!eval.getShapePropertyData(JC.SHAPE_CGO, "data", 3594 new Object[] { st, ai, data, vwr })) 3595 invArg(); 3596 i = ai[0]; 3597 continue; 3598 case T.scale: 3599 if (++i >= slen) 3600 error(ScriptError.ERROR_numberExpected); 3601 switch (getToken(i).tok) { 3602 case T.integer: 3603 intScale = intParameter(i); 3604 continue; 3605 case T.decimal: 3606 intScale = Math.round(floatParameter(i) * 100); 3607 continue; 3608 } 3609 error(ScriptError.ERROR_numberExpected); 3610 break; 3611 case T.fixed: 3612 propertyName = "modelIndex"; 3613 propertyValue = Integer.valueOf(-1); 3614 break; 3615 case T.modelindex: 3616 case T.model: 3617 modelIndex = (eval.theTok == T.modelindex ? intParameter(++i) 3618 : eval.modelNumberParameter(++i)); 3619 propertyName = "modelIndex"; 3620 propertyValue = Integer.valueOf(modelIndex); 3621 break; 3622 case T.color: 3623 case T.translucent: 3624 case T.opaque: 3625 translucentLevel = getColorTrans(eval, i, false, colorArgb); 3626 i = eval.iToken; 3627 idSeen = true; 3628 continue; 3629 case T.id: 3630 thisId = setShapeId(JC.SHAPE_CGO, ++i, idSeen); 3631 isWild = (getShapeProperty(JC.SHAPE_CGO, "ID") == null); 3632 i = eval.iToken; 3633 break; 3634 default: 3635 if (!eval.setMeshDisplayProperty(JC.SHAPE_CGO, 0, eval.theTok)) { 3636 if (eval.theTok == T.times || T.tokAttr(eval.theTok, T.identifier)) { 3637 thisId = setShapeId(JC.SHAPE_CGO, i, idSeen); 3638 i = eval.iToken; 3639 break; 3640 } 3641 invArg(); 3642 } 3643 if (iptDisplayProperty == 0) 3644 iptDisplayProperty = i; 3645 i = eval.iToken; 3646 continue; 3647 } 3648 idSeen = (eval.theTok != T.delete); 3649 if (data != null && !isInitialized) { 3650 propertyName = "points"; 3651 propertyValue = Integer.valueOf(intScale); 3652 isInitialized = true; 3653 intScale = 0; 3654 } 3655 if (propertyName != null) 3656 setShapeProperty(JC.SHAPE_CGO, propertyName, propertyValue); 3657 } 3658 finalizeObject(JC.SHAPE_CGO, colorArgb[0], translucentLevel, intScale, 3659 data != null, data, iptDisplayProperty, null); 3660 return true; 3661 } 3662 3663 /** 3664 * 3665 * @param bsSelected 3666 * @param bsIgnore 3667 * @param fileName 3668 * @return calculated atom potentials 3669 */ getAtomicPotentials(BS bsSelected, BS bsIgnore, String fileName)3670 private float[] getAtomicPotentials(BS bsSelected, BS bsIgnore, 3671 String fileName) { 3672 float[] potentials = new float[vwr.ms.ac]; 3673 MepCalculation m = (MepCalculation) Interface 3674 .getOption("quantum.MlpCalculation", vwr, "script"); 3675 m.set(vwr); 3676 String data = (fileName == null ? null 3677 : vwr.getFileAsString3(fileName, false, null)); 3678 try { 3679 m.assignPotentials(vwr.ms.at, potentials, 3680 vwr.getSmartsMatch("a", bsSelected), 3681 vwr.getSmartsMatch("/noAromatic/[$(C=O),$(O=C),$(NC=O)]", bsSelected), 3682 bsIgnore, data); 3683 } catch (Exception e) { 3684 } 3685 return potentials; 3686 } 3687 getCapSlabObject(int i, boolean isLcaoCartoon)3688 private Object getCapSlabObject(int i, boolean isLcaoCartoon) 3689 throws ScriptException { 3690 if (i < 0) { 3691 // standard range -100 to 0 3692 return TempArray.getSlabWithinRange(i, 0); 3693 } 3694 ScriptEval eval = e; 3695 Object data = null; 3696 int tok0 = tokAt(i); 3697 boolean isSlab = (tok0 == T.slab); 3698 int tok = tokAt(i + 1); 3699 P4 plane = null; 3700 P3[] pts = null; 3701 float d, d2; 3702 BS bs = null; 3703 Short slabColix = null; 3704 Integer slabMeshType = null; 3705 if (tok == T.translucent) { 3706 float slabTranslucency = (isFloatParameter(++i + 1) ? floatParameter(++i) 3707 : 0.5f); 3708 if (eval.isColorParam(i + 1)) { 3709 slabColix = Short.valueOf( 3710 C.getColixTranslucent3(C.getColix(eval.getArgbParam(i + 1)), 3711 slabTranslucency != 0, slabTranslucency)); 3712 i = eval.iToken; 3713 } else { 3714 slabColix = Short.valueOf(C.getColixTranslucent3(C.INHERIT_COLOR, 3715 slabTranslucency != 0, slabTranslucency)); 3716 } 3717 switch (tok = tokAt(i + 1)) { 3718 case T.mesh: 3719 case T.fill: 3720 slabMeshType = Integer.valueOf(tok); 3721 tok = tokAt(++i + 1); 3722 break; 3723 default: 3724 slabMeshType = Integer.valueOf(T.fill); 3725 break; 3726 } 3727 } 3728 //TODO: check for compatibility with LCAOCARTOONS 3729 switch (tok) { 3730 case T.off: 3731 eval.iToken = i + 1; 3732 return Integer.valueOf(Integer.MIN_VALUE); 3733 case T.none: 3734 eval.iToken = i + 1; 3735 break; 3736 case T.dollarsign: 3737 // do we need distance here? "-" here? 3738 i++; 3739 data = new Object[] { Float.valueOf(1), paramAsStr(++i) }; 3740 tok = T.mesh; 3741 break; 3742 case T.within: 3743 // isosurface SLAB WITHIN RANGE f1 f2 3744 i++; 3745 if (tokAt(++i) == T.range) { 3746 d = floatParameter(++i); 3747 d2 = floatParameter(++i); 3748 data = new Object[] { Float.valueOf(d), Float.valueOf(d2) }; 3749 tok = T.range; 3750 } else if (isFloatParameter(i)) { 3751 // isosurface SLAB WITHIN distance {atomExpression}|[point array] 3752 d = floatParameter(i); 3753 if (eval.isCenterParameter(++i)) { 3754 Object[] ret = new Object[1]; 3755 P3 pt = eval.centerParameter(i, ret); 3756 if (chk || !(ret[0] instanceof BS)) { 3757 pts = new P3[] { pt }; 3758 } else { 3759 Atom[] atoms = vwr.ms.at; 3760 bs = (BS) ret[0]; 3761 pts = new P3[bs.cardinality()]; 3762 for (int k = 0, j = bs.nextSetBit(0); j >= 0; j = bs 3763 .nextSetBit(j + 1), k++) 3764 pts[k] = atoms[j]; 3765 } 3766 } else { 3767 pts = eval.getPointArray(i, -1, false); 3768 } 3769 if (pts.length == 0) { 3770 eval.iToken = i; 3771 invArg(); 3772 } 3773 data = new Object[] { Float.valueOf(d), pts, bs }; 3774 } else { 3775 data = eval.getPointArray(i, 4, false); 3776 tok = T.boundbox; 3777 } 3778 break; 3779 case T.boundbox: 3780 eval.iToken = i + 1; 3781 data = BoxInfo.toOABC(vwr.ms.getBBoxVertices(), null); 3782 break; 3783 //case Token.slicebox: 3784 // data = BoxInfo.getCriticalPoints(((JmolViewer)(vwr)).slicer.getSliceVert(), null); 3785 //eval.iToken = i + 1; 3786 //break; 3787 case T.brillouin: 3788 case T.unitcell: 3789 eval.iToken = i + 1; 3790 SymmetryInterface unitCell = vwr.getCurrentUnitCell(); 3791 if (unitCell == null) { 3792 if (tok == T.unitcell) 3793 invArg(); 3794 } else { 3795 pts = BoxInfo.toOABC(unitCell.getUnitCellVerticesNoOffset(), 3796 unitCell.getCartesianOffset()); 3797 int iType = (int) unitCell 3798 .getUnitCellInfoType(SimpleUnitCell.INFO_DIMENSIONS); 3799 V3 v1 = null; 3800 V3 v2 = null; 3801 switch (iType) { 3802 case 3: 3803 break; 3804 case 1: // polymer 3805 v2 = V3.newVsub(pts[2], pts[0]); 3806 v2.scale(1000f); 3807 //$FALL-THROUGH$ 3808 case 2: // slab 3809 // "a b c" is really "z y x" 3810 v1 = V3.newVsub(pts[1], pts[0]); 3811 v1.scale(1000f); 3812 pts[0].sub(v1); 3813 pts[1].scale(2000f); 3814 if (iType == 1) { 3815 pts[0].sub(v2); 3816 pts[2].scale(2000f); 3817 } 3818 break; 3819 } 3820 data = pts; 3821 } 3822 break; 3823 case T.define: 3824 case T.bitset: 3825 case T.expressionBegin: 3826 data = atomExpressionAt(i + 1); 3827 tok = T.decimal; 3828 if (!eval.isCenterParameter(++eval.iToken)) { 3829 isSlab = true; 3830 break; 3831 } 3832 data = null; 3833 //$FALL-THROUGH$ 3834 default: 3835 // isosurface SLAB n 3836 // isosurface SLAB -100. 0. as "within range" 3837 if (!isLcaoCartoon && isSlab && isFloatParameter(i + 1)) { 3838 d = floatParameter(++i); 3839 if (!isFloatParameter(i + 1)) 3840 return Integer.valueOf((int) d); 3841 d2 = floatParameter(++i); 3842 data = new Object[] { Float.valueOf(d), Float.valueOf(d2) }; 3843 tok = T.range; 3844 break; 3845 } 3846 // isosurface SLAB [plane] 3847 plane = eval.planeParameter(++i); 3848 float off = (isFloatParameter(eval.iToken + 1) 3849 ? floatParameter(++eval.iToken) 3850 : Float.NaN); 3851 if (!Float.isNaN(off)) 3852 plane.w -= off; 3853 data = plane; 3854 tok = T.plane; 3855 } 3856 Object colorData = (slabMeshType == null ? null 3857 : new Object[] { slabMeshType, slabColix }); 3858 return TempArray.getSlabObjectType(tok, data, !isSlab, colorData); 3859 } 3860 setColorOptions(SB sb, int index, int iShape, int nAllowed)3861 private String setColorOptions(SB sb, int index, int iShape, int nAllowed) 3862 throws ScriptException { 3863 ScriptEval eval = e; 3864 getToken(index); 3865 String translucency = "opaque"; 3866 if (eval.theTok == T.translucent) { 3867 translucency = "translucent"; 3868 if (nAllowed < 0) { 3869 float value = (isFloatParameter(index + 1) ? floatParameter(++index) 3870 : Float.MAX_VALUE); 3871 eval.setShapeTranslucency(iShape, null, "translucent", value, null); 3872 if (sb != null) { 3873 sb.append(" translucent"); 3874 if (value != Float.MAX_VALUE) 3875 sb.append(" ").appendF(value); 3876 } 3877 } else { 3878 eval.setMeshDisplayProperty(iShape, index, eval.theTok); 3879 } 3880 } else if (eval.theTok == T.opaque) { 3881 if (nAllowed >= 0) 3882 eval.setMeshDisplayProperty(iShape, index, eval.theTok); 3883 } else { 3884 eval.iToken--; 3885 } 3886 nAllowed = Math.abs(nAllowed); 3887 for (int i = 0; i < nAllowed; i++) { 3888 if (eval.isColorParam(eval.iToken + 1)) { 3889 int color = eval.getArgbParam(++eval.iToken); 3890 setShapeProperty(iShape, "colorRGB", Integer.valueOf(color)); 3891 if (sb != null) 3892 sb.append(" ").append(Escape.escapeColor(color)); 3893 } else if (eval.iToken < index) { 3894 invArg(); 3895 } else { 3896 break; 3897 } 3898 } 3899 return translucency; 3900 } 3901 3902 /** 3903 * for the ISOSURFACE command 3904 * 3905 * @param fname 3906 * @param xyz 3907 * @param ret 3908 * @return [ ScriptFunction, Params ] 3909 */ createFunction(String fname, String xyz, String ret)3910 private Object[] createFunction(String fname, String xyz, String ret) { 3911 ScriptEval e = (new ScriptEval()).setViewer(vwr); 3912 try { 3913 e.compileScript(null, 3914 "function " + fname + "(" + xyz + ") { return " + ret + "}", false); 3915 Lst<SV> params = new Lst<SV>(); 3916 for (int i = 0; i < xyz.length(); i += 2) 3917 params.addLast(SV.newF(0).setName(xyz.substring(i, i + 1))); 3918 return new Object[] { e.aatoken[0][1].value, params }; 3919 } catch (Exception ex) { 3920 return null; 3921 } 3922 } 3923 getWithinDistanceVector(Lst<Object[]> propertyList, float distance, P3 ptc, BS bs, boolean isShow)3924 private P3[] getWithinDistanceVector(Lst<Object[]> propertyList, 3925 float distance, P3 ptc, BS bs, 3926 boolean isShow) { 3927 Lst<P3> v = new Lst<P3>(); 3928 P3[] pts = new P3[2]; 3929 if (bs == null) { 3930 P3 pt1 = P3.new3(distance, distance, distance); 3931 P3 pt0 = P3.newP(ptc); 3932 pt0.sub(pt1); 3933 pt1.add(ptc); 3934 pts[0] = pt0; 3935 pts[1] = pt1; 3936 v.addLast(ptc); 3937 } else { 3938 BoxInfo bbox = vwr.ms.getBoxInfo(bs, -Math.abs(distance * 2)); 3939 pts[0] = bbox.getBoundBoxVertices()[0]; 3940 pts[1] = bbox.getBoundBoxVertices()[BoxInfo.XYZ]; 3941 if (bs.cardinality() == 1) 3942 v.addLast(vwr.ms.at[bs.nextSetBit(0)]); 3943 } 3944 if (v.size() == 1 && !isShow) { 3945 addShapeProperty(propertyList, "withinDistance", Float.valueOf(distance)); 3946 addShapeProperty(propertyList, "withinPoint", v.get(0)); 3947 } 3948 addShapeProperty(propertyList, (isShow ? "displayWithin" : "withinPoints"), 3949 new Object[] { Float.valueOf(distance), pts, bs, v }); 3950 return pts; 3951 } 3952 addShapeProperty(Lst<Object[]> propertyList, String key, Object value)3953 private void addShapeProperty(Lst<Object[]> propertyList, String key, 3954 Object value) { 3955 if (chk) 3956 return; 3957 propertyList.addLast(new Object[] { key, value }); 3958 } 3959 floatArraySetXYZ(int i, int nX, int nY, int nZ)3960 private float[][][] floatArraySetXYZ(int i, int nX, int nY, int nZ) 3961 throws ScriptException { 3962 ScriptEval eval = e; 3963 int tok = tokAt(i++); 3964 if (tok == T.spacebeforesquare) 3965 tok = tokAt(i++); 3966 if (tok != T.leftsquare || nX <= 0) 3967 invArg(); 3968 float[][][] fparams = AU.newFloat3(nX, -1); 3969 int n = 0; 3970 while (tok != T.rightsquare) { 3971 tok = getToken(i).tok; 3972 switch (tok) { 3973 case T.spacebeforesquare: 3974 case T.rightsquare: 3975 continue; 3976 case T.comma: 3977 i++; 3978 break; 3979 case T.leftsquare: 3980 fparams[n++] = floatArraySet(i, nY, nZ); 3981 i = ++eval.iToken; 3982 tok = T.nada; 3983 if (n == nX && tokAt(i) != T.rightsquare) 3984 invArg(); 3985 break; 3986 default: 3987 invArg(); 3988 } 3989 } 3990 return fparams; 3991 } 3992 floatArraySet(int i, int nX, int nY)3993 private float[][] floatArraySet(int i, int nX, int nY) 3994 throws ScriptException { 3995 int tok = tokAt(i++); 3996 if (tok == T.spacebeforesquare) 3997 tok = tokAt(i++); 3998 if (tok != T.leftsquare) 3999 invArg(); 4000 float[][] fparams = AU.newFloat2(nX); 4001 int n = 0; 4002 while (tok != T.rightsquare) { 4003 tok = getToken(i).tok; 4004 switch (tok) { 4005 case T.spacebeforesquare: 4006 case T.rightsquare: 4007 continue; 4008 case T.comma: 4009 i++; 4010 break; 4011 case T.leftsquare: 4012 i++; 4013 float[] f = new float[nY]; 4014 fparams[n++] = f; 4015 for (int j = 0; j < nY; j++) { 4016 f[j] = floatParameter(i++); 4017 if (tokAt(i) == T.comma) 4018 i++; 4019 } 4020 if (tokAt(i++) != T.rightsquare) 4021 invArg(); 4022 tok = T.nada; 4023 if (n == nX && tokAt(i) != T.rightsquare) 4024 invArg(); 4025 break; 4026 default: 4027 invArg(); 4028 } 4029 } 4030 return fparams; 4031 } 4032 initIsosurface(int iShape)4033 private String initIsosurface(int iShape) throws ScriptException { 4034 4035 // handle isosurface/mo/pmesh delete and id delete here 4036 4037 ScriptEval eval = e; 4038 setShapeProperty(iShape, "init", eval.fullCommand); 4039 eval.iToken = 0; 4040 int tok1 = tokAt(1); 4041 int tok2 = tokAt(2); 4042 if (tok1 == T.delete || tok2 == T.delete && tokAt(++eval.iToken) == T.all) { 4043 setShapeProperty(iShape, "delete", null); 4044 eval.iToken += 2; 4045 if (slen > eval.iToken) { 4046 setShapeProperty(iShape, "init", eval.fullCommand); 4047 setShapeProperty(iShape, "thisID", MeshCollection.PREVIOUS_MESH_ID); 4048 } 4049 return null; 4050 } 4051 eval.iToken = 1; 4052 if (!eval.setMeshDisplayProperty(iShape, 0, tok1)) { 4053 setShapeProperty(iShape, "thisID", MeshCollection.PREVIOUS_MESH_ID); 4054 if (iShape != JC.SHAPE_DRAW) 4055 setShapeProperty(iShape, "title", new String[] { eval.thisCommand }); 4056 if (tok1 != T.id && (tok2 == T.times 4057 || tok1 == T.times && eval.setMeshDisplayProperty(iShape, 0, tok2))) { 4058 String id = setShapeId(iShape, 1, false); 4059 eval.iToken++; 4060 return id; 4061 } 4062 } 4063 return null; 4064 } 4065 listIsosurface(int iShape)4066 private boolean listIsosurface(int iShape) throws ScriptException { 4067 String s = (slen > 3 ? "0" 4068 : tokAt(2) == T.nada ? "" : " " + getToken(2).value); 4069 if (!chk) 4070 showString((String) getShapeProperty(iShape, "list" + s)); 4071 return true; 4072 } 4073 4074 /** 4075 * 4076 * @param type 4077 * unitcell or boundbox 4078 * @param plane 4079 * plane to intersect, or null for just the full box 4080 * @param scale 4081 * @param uc 4082 * @param flags 4083 * 1 -- edges only 2 -- triangles only 3 -- both 4084 * @return Vector 4085 */ getPlaneIntersection(int type, P4 plane, SymmetryInterface uc, float scale, int flags)4086 private Lst<Object> getPlaneIntersection(int type, P4 plane, 4087 SymmetryInterface uc, float scale, 4088 int flags) { 4089 T3[] pts = null; 4090 switch (type) { 4091 case T.unitcell: 4092 if (uc == null) 4093 return null; 4094 pts = uc.getCanonicalCopy(scale, true); 4095 break; 4096 case T.boundbox: 4097 pts = BoxInfo.getCanonicalCopy(vwr.ms.getBoxInfo().getBoundBoxVertices(), 4098 scale); 4099 break; 4100 } 4101 Triangulator t = vwr.getTriangulator(); // this instantiation forces reflection to get Triangulator class 4102 if (plane != null) 4103 return t.intersectPlane(plane, pts, flags); 4104 Lst<Object> v = new Lst<Object>(); 4105 v.addLast(pts); 4106 v.addLast(Triangulator.fullCubePolygon); 4107 return v; 4108 } 4109 4110 } 4111