1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2010-02-15 07:31:37 -0600 (Mon, 15 Feb 2010) $
4  * $Revision: 12396 $
5  *
6  * Copyright (C) 2003-2005  Miguel, Jmol Development
7  *
8  * Contact: jmol-developers@lists.sf.net, 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 package org.jmol.viewer;
25 
26 
27 import java.util.Map;
28 
29 
30 import org.jmol.api.Interface;
31 import org.jmol.atomdata.RadiusData;
32 import org.jmol.c.PAL;
33 import org.jmol.c.VDW;
34 import javajs.util.BS;
35 import org.jmol.modelset.Atom;
36 import org.jmol.modelset.Group;
37 import org.jmol.modelset.ModelSet;
38 import org.jmol.script.T;
39 import org.jmol.shape.Shape;
40 import org.jmol.util.BSUtil;
41 import org.jmol.util.GData;
42 import org.jmol.util.Edge;
43 
44 import org.jmol.util.JmolMolecule;
45 
46 import javajs.util.M4;
47 import javajs.util.P3;
48 import javajs.util.P3i;
49 import org.jmol.util.Vibration;
50 
51 public class ShapeManager {
52 
53   private ModelSet ms;
54   public Shape[] shapes;
55   public Viewer vwr;
56 
ShapeManager(Viewer vwr)57   public ShapeManager(Viewer vwr) {
58     this.vwr = vwr;
59     bsRenderableAtoms = new BS();
60     bsSlabbedInternal = new BS();
61   }
62 
63   /**
64    * @j2sIgnore
65    *
66    */
setParallel()67   public void setParallel() {
68     resetShapes();
69     loadDefaultShapes(vwr.ms);
70   }
71 
72 
73   // public methods
74 
findNearestShapeAtomIndex(int x, int y, Atom[] closest, BS bsNot)75   public void findNearestShapeAtomIndex(int x, int y, Atom[] closest, BS bsNot) {
76     if (shapes != null)
77       for (int i = 0; i < shapes.length && closest[0] == null; ++i)
78         if (shapes[i] != null)
79           shapes[i].findNearestAtomIndex(x, y, closest, bsNot);
80   }
81 
getShapePropertyIndex(int shapeID, String propertyName, int index)82   public Object getShapePropertyIndex(int shapeID, String propertyName, int index) {
83     if (shapes == null || shapes[shapeID] == null)
84       return null;
85     vwr.setShapeErrorState(shapeID, "get " + propertyName);
86     Object result = shapes[shapeID].getProperty(propertyName, index);
87     vwr.setShapeErrorState(-1, null);
88     return result;
89   }
90 
getShapePropertyData(int shapeID, String propertyName, Object[] data)91   public boolean getShapePropertyData(int shapeID, String propertyName, Object[] data) {
92     if (shapes == null || shapes[shapeID] == null)
93       return false;
94     vwr.setShapeErrorState(shapeID, "get " + propertyName);
95     // echo, dipoles, draw, ellipsoids, isosurface
96     boolean result = shapes[shapeID].getPropertyData(propertyName, data);
97     vwr.setShapeErrorState(-1, null);
98     return result;
99   }
100 
101   /**
102    * Returns the shape type index for a shape object given the object name.
103    * @param objectName (string) string name of object
104    * @return shapeType (int) integer corresponding to the shape type index
105    *                   see ShapeManager.shapes[].
106    */
getShapeIdFromObjectName(String objectName)107   public int getShapeIdFromObjectName(String objectName) {
108     if (shapes != null)
109       for (int i = JC.SHAPE_MIN_SPECIAL; i < JC.SHAPE_MAX_MESH_COLLECTION; ++i)
110         if (shapes[i] != null && shapes[i].getIndexFromName(objectName) >= 0)
111           return i;
112       if (shapes[JC.SHAPE_MEASURES] != null && shapes[JC.SHAPE_MEASURES].getIndexFromName(objectName) >= 0) {
113           return JC.SHAPE_MEASURES;
114       }
115     return -1;
116   }
117 
loadDefaultShapes(ModelSet newModelSet)118   public void loadDefaultShapes(ModelSet newModelSet) {
119     ms = newModelSet;
120     if (shapes != null)
121       for (int i = 0; i < shapes.length; ++i)
122         if (shapes[i] != null)
123           shapes[i].setModelSet(newModelSet);
124     loadShape(JC.SHAPE_BALLS);
125     loadShape(JC.SHAPE_STICKS);
126   }
127 
loadShape(int shapeID)128   public Shape loadShape(int shapeID) {
129     if (shapes == null)
130       return null;
131     if (shapes[shapeID] != null)
132       return shapes[shapeID];
133     if (shapeID == JC.SHAPE_HSTICKS || shapeID == JC.SHAPE_SSSTICKS
134         || shapeID == JC.SHAPE_STRUTS)
135       return null;
136     String className = JC.getShapeClassName(shapeID, false);
137     Shape shape;
138     if ((shape = (Shape) Interface.getInterface(className, vwr, "shape")) == null)
139       return null;
140     vwr.setShapeErrorState(shapeID, "allocate");
141     shape.initializeShape(vwr, ms, shapeID);
142     vwr.setShapeErrorState(-1, null);
143     return shapes[shapeID] = shape;
144   }
145 
notifyAtomPositionsChanged(int baseModel, BS bs, M4 mat)146   public void notifyAtomPositionsChanged(int baseModel, BS bs, M4 mat) {
147     Integer Imodel = Integer.valueOf(baseModel);
148     BS bsModelAtoms = vwr.getModelUndeletedAtomsBitSet(baseModel);
149     for (int i = 0; i < JC.SHAPE_MAX; i++)
150       if (shapes[i] != null)
151         setShapePropertyBs(i, "refreshTrajectories", new Object[] { Imodel, bs, mat }, bsModelAtoms);
152   }
153 
releaseShape(int shapeID)154   public void releaseShape(int shapeID) {
155     if (shapes != null)
156       shapes[shapeID] = null;
157   }
158 
resetShapes()159   public void resetShapes() {
160 //    if (!vwr.noGraphicsAllowed)  ?? Why this?? We need shapes!
161       shapes = new Shape[JC.SHAPE_MAX];
162   }
163 
164   /**
165    * @param shapeID
166    * @param size in milliangstroms
167    * @param rd
168    * @param bsSelected
169    */
setShapeSizeBs(int shapeID, int size, RadiusData rd, BS bsSelected)170   public void setShapeSizeBs(int shapeID, int size, RadiusData rd, BS bsSelected) {
171     if (shapes == null)
172       return;
173     if (bsSelected == null &&
174         (shapeID != JC.SHAPE_STICKS || size != Integer.MAX_VALUE))
175       bsSelected = vwr.bsA();
176     if (rd != null && rd.value != 0 && rd.vdwType == VDW.TEMP)
177       ms.getBfactor100Lo();
178     vwr.setShapeErrorState(shapeID, "set size");
179     if (rd == null ? size != 0 : rd.value != 0)
180       loadShape(shapeID);
181     if (shapes[shapeID] != null) {
182       shapes[shapeID].setShapeSizeRD(size, rd, bsSelected);
183     }
184     vwr.setShapeErrorState(-1, null);
185   }
186 
setLabel(Object strLabel, BS bsSelection)187   public void setLabel(Object strLabel, BS bsSelection) {
188     if (strLabel == null) {
189       if (shapes[JC.SHAPE_LABELS] == null)
190         return;
191     } else {// force the class to load and display
192       loadShape(JC.SHAPE_LABELS);
193       setShapeSizeBs(JC.SHAPE_LABELS, 0, null, bsSelection);
194     }
195     setShapePropertyBs(JC.SHAPE_LABELS, "label", strLabel, bsSelection);
196   }
197 
setShapePropertyBs(int shapeID, String propertyName, Object value, BS bsSelected)198   public void setShapePropertyBs(int shapeID, String propertyName, Object value,
199                                BS bsSelected) {
200     if (shapes == null || shapes[shapeID] == null)
201       return;
202     if (bsSelected == null)
203       bsSelected = vwr.bsA();
204     vwr.setShapeErrorState(shapeID, "set " + propertyName);
205     shapes[shapeID].setProperty(propertyName.intern(), value, bsSelected);
206     vwr.setShapeErrorState(-1, null);
207   }
208 
209   // methods local to Viewer and other managers
210 
checkFrankclicked(int x, int y)211   boolean checkFrankclicked(int x, int y) {
212     Shape frankShape = shapes[JC.SHAPE_FRANK];
213     return (frankShape != null && frankShape.wasClicked(x, y));
214   }
215 
216   private final static int[] hoverable = {
217     JC.SHAPE_ECHO,
218     JC.SHAPE_ELLIPSOIDS,
219     JC.SHAPE_CONTACT,
220     JC.SHAPE_ISOSURFACE,
221     JC.SHAPE_DRAW,
222     JC.SHAPE_FRANK
223   };
224 
225   private static int clickableMax = hoverable.length - 1;
226 
checkObjectClicked(int x, int y, int modifiers, BS bsVisible, boolean drawPicking)227   Map<String, Object> checkObjectClicked(int x, int y, int modifiers,
228                                          BS bsVisible, boolean drawPicking) {
229     Shape shape;
230     Map<String, Object> map = null;
231     if (vwr.getPickingMode() == ActionManager.PICKING_LABEL) {
232       return shapes[JC.SHAPE_LABELS].checkObjectClicked(x, y, modifiers,
233           bsVisible, false);
234     }
235     if (modifiers != 0
236         && vwr.getBondsPickable()
237         && (map = shapes[JC.SHAPE_STICKS].checkObjectClicked(x, y, modifiers,
238             bsVisible, false)) != null)
239       return map;
240     for (int i = 0; i < clickableMax; i++)
241       if ((shape = shapes[hoverable[i]]) != null
242           && (map = shape.checkObjectClicked(x, y, modifiers, bsVisible,
243               drawPicking)) != null)
244         return map;
245     return null;
246   }
247 
checkObjectDragged(int prevX, int prevY, int x, int y, int modifiers, BS bsVisible, int iShape)248   boolean checkObjectDragged(int prevX, int prevY, int x, int y, int modifiers,
249                              BS bsVisible, int iShape) {
250     boolean found = false;
251     int n = (iShape > 0 ? iShape + 1 : JC.SHAPE_MAX);
252     for (int i = iShape; !found && i < n; ++i)
253       if (shapes[i] != null)
254         found = shapes[i].checkObjectDragged(prevX, prevY, x, y, modifiers,
255             bsVisible);
256     return found;
257   }
258 
checkObjectHovered(int x, int y, BS bsVisible, boolean checkBonds)259   boolean checkObjectHovered(int x, int y, BS bsVisible, boolean checkBonds) {
260     Shape shape = shapes[JC.SHAPE_STICKS];
261     if (checkBonds && shape != null
262         && shape.checkObjectHovered(x, y, bsVisible))
263       return true;
264     for (int i = 0; i < hoverable.length; i++) {
265       shape = shapes[hoverable[i]];
266       if (shape != null && shape.checkObjectHovered(x, y, bsVisible))
267         return true;
268     }
269     return false;
270   }
271 
deleteShapeAtoms(Object[] value, BS bs)272   public void deleteShapeAtoms(Object[] value, BS bs) {
273     if (shapes != null)
274       for (int j = 0; j < JC.SHAPE_MAX; j++)
275         if (shapes[j] != null)
276           setShapePropertyBs(j, "deleteModelAtoms", value, bs);
277   }
278 
deleteVdwDependentShapes(BS bs)279   void deleteVdwDependentShapes(BS bs) {
280     if (bs == null)
281       bs = vwr.bsA();
282     if (shapes[JC.SHAPE_ISOSURFACE] != null)
283       shapes[JC.SHAPE_ISOSURFACE].setProperty("deleteVdw", null, bs);
284     if (shapes[JC.SHAPE_CONTACT] != null)
285       shapes[JC.SHAPE_CONTACT].setProperty("deleteVdw", null, bs);
286   }
287 
getAtomShapeValue(int tok, Group group, int atomIndex)288   public float getAtomShapeValue(int tok, Group group, int atomIndex) {
289     int iShape = JC.shapeTokenIndex(tok);
290     if (iShape < 0 || shapes[iShape] == null)
291       return 0;
292     int mad = shapes[iShape].getSize(atomIndex);
293     if (mad == 0) {
294       if ((group.shapeVisibilityFlags & shapes[iShape].vf) == 0)
295         return 0;
296       mad = shapes[iShape].getSizeG(group);
297     }
298     return mad / 2000f;
299   }
300 
replaceGroup(Group g0, Group g1)301   public void replaceGroup(Group g0, Group g1) {
302     if (shapes == null)
303       return;
304     for (int i = JC.SHAPE_MIN_SECONDARY; i < JC.SHAPE_MAX_SECONDARY; i++)
305       if (shapes[i] != null)
306         shapes[i].replaceGroup(g0, g1);
307   }
308 
getObjectMap(Map<String, ?> map, boolean withDollar)309   void getObjectMap(Map<String, ?> map, boolean withDollar) {
310     if (shapes == null)
311       return;
312     Boolean bDollar = Boolean.valueOf(withDollar);
313     for (int i = JC.SHAPE_MIN_SPECIAL; i < JC.SHAPE_MAX_MESH_COLLECTION; ++i)
314       getShapePropertyData(i, "getNames", new Object[] { map, bDollar });
315   }
316 
getProperty(Object paramInfo)317   Object getProperty(Object paramInfo) {
318     if (paramInfo.equals("getShapes"))
319       return shapes;
320     // could be more here...
321     return null;
322   }
323 
324   public final BS bsRenderableAtoms, bsSlabbedInternal;
325 
getShape(int i)326   public Shape getShape(int i) {
327     //RepaintManager
328     return (shapes == null ? null : shapes[i]);
329   }
330 
resetBioshapes(BS bsAllAtoms)331   public void resetBioshapes(BS bsAllAtoms) {
332     if (shapes == null)
333       return;
334     for (int i = 0; i < shapes.length; ++i)
335       if (shapes[i] != null && shapes[i].isBioShape) {
336         shapes[i].setModelSet(ms);
337         shapes[i].setShapeSizeRD(0, null, bsAllAtoms);
338         shapes[i].setProperty("color", PAL.NONE, bsAllAtoms);
339       }
340   }
341 
setAtomLabel(String strLabel, int i)342   public void setAtomLabel(String strLabel, int i) {
343     if (shapes != null)
344       shapes[JC.SHAPE_LABELS].setProperty("label:"+strLabel, Integer.valueOf(i), null);
345   }
346 
347   /**
348    * Sets shape visibility flags, including ATOM_VIS_INFRAME and
349    * ATOM_VIS_NOTHIDDEN.
350    *
351    */
setModelVisibility()352   void setModelVisibility() {
353     Shape[] shapes = this.shapes;
354     if (shapes == null || shapes[JC.SHAPE_BALLS] == null)
355       return;
356 
357     //named objects must be set individually
358     //in the future, we might include here a BITSET of models rather than just a modelIndex
359 
360     // all these isTranslucent = f() || isTranslucent are that way because
361     // in general f() does MORE than just check translucency.
362     // so isTranslucent = isTranslucent || f() would NOT work.
363 
364     BS bs = vwr.getVisibleFramesBitSet();
365 
366     // i=2 skips balls and sticks
367     // as these are handled differently.
368 
369     // Bbcage, Halos, Dipoles, Draw, Ellipsoids, Polyhedra
370     // bioshapes, Echo, Hover,
371     for (int i = JC.SHAPE_MIN_HAS_SETVIS; i < JC.SHAPE_MAX_HAS_SETVIS; i++)
372       if (shapes[i] != null)
373         shapes[i].setModelVisibilityFlags(bs);
374 
375     // now check ATOM_IN_FRAME, and ATOM_NOTHIDDEN, VIS_BALLS_FLAG
376 
377     //    todo: deleted atoms not showing up in state
378     boolean showHydrogens = vwr.getBoolean(T.showhydrogens);
379     BS bsDeleted = vwr.slm.bsDeleted;
380     Atom[] atoms = ms.at;
381     ms.clearVisibleSets();
382     if (atoms.length > 0) {
383       for (int i = ms.ac; --i >= 0;) {
384         Atom atom = atoms[i];
385         if (atom != null)
386         atom.shapeVisibilityFlags &= Atom.ATOM_NOFLAGS;
387         if (bsDeleted != null && bsDeleted.get(i))
388           continue;
389         if (bs.get(atom.mi)) {
390           int f = Atom.ATOM_INFRAME;
391           if (!ms.isAtomHidden(i)
392               && (showHydrogens || atom.getElementNumber() != 1)) {
393             f |= Atom.ATOM_NOTHIDDEN;
394             if (atom.madAtom != 0)
395               f |= JC.VIS_BALLS_FLAG;
396             atom.setShapeVisibility(f, true);
397           }
398         }
399       }
400     }
401     setShapeVis();
402   }
403 
setShapeVis()404   private void setShapeVis() {
405     //set clickability -- this enables measures and such
406     for (int i = 0; i < JC.SHAPE_MAX; ++i) {
407       Shape shape = shapes[i];
408       if (shape != null)
409         shape.setAtomClickability();
410     }
411   }
412 
413   private final int[] navMinMax = new int[4];
414 
finalizeAtoms(BS bsTranslateSelected, boolean finalizeParams)415   public int[] finalizeAtoms(BS bsTranslateSelected, boolean finalizeParams) {
416     Viewer vwr = this.vwr;
417     TransformManager tm = vwr.tm;
418     if (finalizeParams)
419       vwr.finalizeTransformParameters();
420     if (bsTranslateSelected != null) {
421       // translateSelected operation
422       P3 ptCenter = ms.getAtomSetCenter(bsTranslateSelected);
423       P3 pt = new P3();
424       tm.transformPt3f(ptCenter, pt);
425       pt.add(tm.ptOffset);
426       tm.unTransformPoint(pt, pt);
427       pt.sub(ptCenter);
428       vwr.setAtomCoordsRelative(pt, bsTranslateSelected);
429       tm.ptOffset.set(0, 0, 0);
430       tm.bsSelectedAtoms = null;
431     }
432     BS bsOK = bsRenderableAtoms;
433     ms.getAtomsInFrame(bsOK);
434     Vibration[] vibrationVectors = ms.vibrations;
435     boolean vibs = (vibrationVectors != null && tm.vibrationOn);
436     boolean checkOccupancy = (ms.bsModulated != null && ms.occupancies != null);
437     Atom[] atoms = ms.at;
438     int occ;
439     boolean haveMods = false;
440     BS bsSlabbed = bsSlabbedInternal;
441     bsSlabbed.clearAll();
442     for (int i = bsOK.nextSetBit(0); i >= 0; i = bsOK.nextSetBit(i + 1)) {
443       // note that this vibration business is not compatible with
444       // PDB objects such as cartoons and traces, which
445       // use Cartesian coordinates, not screen coordinates
446       Atom atom = atoms[i];
447       P3i screen = (vibs && atom.hasVibration() ? tm.transformPtVib(atom,
448           vibrationVectors[i]) : tm.transformPt(atom));
449       if (screen.z == 1 && tm.internalSlab && tm.xyzIsSlabbedInternal(atom)) {
450         bsSlabbed.set(i);
451       }
452       atom.sX = screen.x;
453       atom.sY = screen.y;
454       atom.sZ = screen.z;
455       int d = Math.abs(atom.madAtom);
456       if (d == Atom.MAD_GLOBAL)
457         d = (int) (vwr.getFloat(T.atoms) * 2000);
458       atom.sD = (short) vwr.tm.scaleToScreen(screen.z, d);
459       if (checkOccupancy
460           && vibrationVectors[i] != null
461           && (occ = vibrationVectors[i].getOccupancy100(vibs)) != Integer.MIN_VALUE) {
462         //System.out.println(atom + " " + occ);
463         haveMods = true;
464         atom.setShapeVisibility(Atom.ATOM_VISSET, false);
465         if (occ >= 0 && occ < 50)
466           atom.setShapeVisibility(Atom.ATOM_NOTHIDDEN | JC.VIS_BALLS_FLAG,
467               false);
468         else
469           atom.setShapeVisibility(Atom.ATOM_NOTHIDDEN
470               | (atom.madAtom > 0 ? JC.VIS_BALLS_FLAG : 0), true);
471         ms.occupancies[atom.i] = Math.abs(occ);
472       }
473     }
474     if (haveMods)
475       setShapeVis();
476     GData gdata = vwr.gdata;
477     if (tm.slabEnabled) {
478       boolean slabByMolecule = vwr.getBoolean(T.slabbymolecule);
479       boolean slabByAtom = vwr.getBoolean(T.slabbyatom);
480       int minZ = gdata.slab;
481       int maxZ = gdata.depth;
482       if (slabByMolecule) {
483         JmolMolecule[] molecules = ms.getMolecules();
484         int moleculeCount = ms.getMoleculeCountInModel(-1);
485         for (int i = 0; i < moleculeCount; i++) {
486           JmolMolecule m = molecules[i];
487           int j = 0;
488           int pt = m.firstAtomIndex;
489           if (!bsOK.get(pt))
490             continue;
491           for (; j < m.ac; j++, pt++)
492             if (gdata.isClippedZ(atoms[pt].sZ - (atoms[pt].sD >> 1)))
493               break;
494           if (j != m.ac) {
495             pt = m.firstAtomIndex;
496             for (int k = 0; k < m.ac; k++) {
497               bsOK.clear(pt);
498               atoms[pt++].sZ = 0;
499             }
500           }
501         }
502       }
503       for (int i = bsOK.nextSetBit(0); i >= 0; i = bsOK.nextSetBit(i + 1)) {
504         Atom atom = atoms[i];
505         if (gdata.isClippedZ(atom.sZ - (slabByAtom ? atoms[i].sD >> 1 : 0))) {
506           atom.setClickable(0);
507           // note that in the case of navigation,
508           // maxZ is set to Integer.MAX_VALUE.
509           int r = (slabByAtom ? -1 : 1) * atom.sD / 2;
510           if (atom.sZ + r < minZ || atom.sZ - r > maxZ
511               || !gdata.isInDisplayRange(atom.sX, atom.sY)) {
512             bsOK.clear(i);
513           }
514         }
515       }
516     }
517     if (ms.ac == 0 || !vwr.getShowNavigationPoint())
518       return null;
519     // set min/max for navigation crosshair rendering
520     int minX = Integer.MAX_VALUE;
521     int maxX = Integer.MIN_VALUE;
522     int minY = Integer.MAX_VALUE;
523     int maxY = Integer.MIN_VALUE;
524     for (int i = bsOK.nextSetBit(0); i >= 0; i = bsOK.nextSetBit(i + 1)) {
525       Atom atom = atoms[i];
526       if (atom.sX < minX)
527         minX = atom.sX;
528       if (atom.sX > maxX)
529         maxX = atom.sX;
530       if (atom.sY < minY)
531         minY = atom.sY;
532       if (atom.sY > maxY)
533         maxY = atom.sY;
534     }
535     navMinMax[0] = minX;
536     navMinMax[1] = maxX;
537     navMinMax[2] = minY;
538     navMinMax[3] = maxY;
539     return navMinMax;
540   }
541 
setModelSet(ModelSet modelSet)542   public void setModelSet(ModelSet modelSet) {
543     ms = vwr.ms = modelSet;
544   }
545 
546   /**
547    * starting with Jmol 13.1.13, isosurfaces can use "property color"
548    * to inherit the color of the underlying atoms. This is then dynamic
549    *
550    */
checkInheritedShapes()551   public void checkInheritedShapes() {
552     if (shapes[JC.SHAPE_ISOSURFACE] == null)
553       return;
554     setShapePropertyBs(JC.SHAPE_ISOSURFACE, "remapInherited", null, null);
555   }
556 
restrictSelected(boolean isBond, boolean doInvert)557   public void restrictSelected(boolean isBond, boolean doInvert) {
558     BS bsSelected = vwr.slm.getSelectedAtomsNoSubset();
559     if (doInvert) {
560       vwr.slm.invertSelection();
561       BS bsSubset = vwr.slm.bsSubset;
562       if (bsSubset != null) {
563         bsSelected = vwr.slm.getSelectedAtomsNoSubset();
564         bsSelected.and(bsSubset);
565         vwr.select(bsSelected, false, 0, true);
566         BSUtil.invertInPlace(bsSelected, vwr.ms.ac);
567         bsSelected.and(bsSubset);
568       }
569     }
570     BSUtil.andNot(bsSelected, vwr.slm.bsDeleted);
571     boolean bondmode = vwr.getBoolean(T.bondmodeor);
572 
573     if (!isBond)
574       vwr.setBooleanProperty("bondModeOr", true);
575     setShapeSizeBs(JC.SHAPE_STICKS, 0, null, null);
576     // wireframe will not operate on STRUTS even though they are
577     // a form of bond order (see BondIteratoSelected)
578     setShapePropertyBs(JC.SHAPE_STICKS, "type", Integer
579         .valueOf(Edge.BOND_STRUT), null);
580     setShapeSizeBs(JC.SHAPE_STICKS, 0, null, null);
581     setShapePropertyBs(JC.SHAPE_STICKS, "type", Integer
582         .valueOf(Edge.BOND_COVALENT_MASK), null);
583     // also need to turn off backbones, ribbons, strands, cartoons
584     BS bs = vwr.bsA();
585     for (int iShape = JC.SHAPE_MAX_SIZE_ZERO_ON_RESTRICT; --iShape >= 0;)
586       if (iShape != JC.SHAPE_MEASURES && getShape(iShape) != null)
587         setShapeSizeBs(iShape, 0, null, bs);
588     if (getShape(JC.SHAPE_POLYHEDRA) != null)
589       setShapePropertyBs(JC.SHAPE_POLYHEDRA, "off", bs, null);
590     setLabel(null, bs);
591     if (!isBond)
592       vwr.setBooleanProperty("bondModeOr", bondmode);
593     vwr.select(bsSelected, false, 0, true);
594   }
595 
596 }
597