Package org.jmol.shape

Source Code of org.jmol.shape.Measures

/* $RCSfile$
* $Author: hansonr $
* $Date: 2011-01-23 07:24:52 +0100 (dim., 23 janv. 2011) $
* $Revision: 15021 $
*
* Copyright (C) 2002-2005  The Jmol Development Team
*
* Contact: jmol-developers@lists.sf.net
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package org.jmol.shape;

import org.jmol.api.JmolMeasurementClient;
import org.jmol.g3d.*;
import org.jmol.modelset.Atom;
import org.jmol.modelset.Measurement;
import org.jmol.modelset.MeasurementData;
import org.jmol.modelset.MeasurementPending;
import org.jmol.util.BitSetUtil;
import org.jmol.util.Escape;
import org.jmol.util.Point3fi;
import org.jmol.modelset.TickInfo;
import org.jmol.viewer.JmolConstants;
import org.jmol.script.Token;

import java.util.BitSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Hashtable;


public class Measures extends Shape implements JmolMeasurementClient {

  private BitSet bsColixSet;
  private BitSet bsSelected;
  private String strFormat;
  private boolean mustBeConnected = false;
  private boolean mustNotBeConnected = false;
  private float[] rangeMinMax = {Float.MAX_VALUE, Float.MAX_VALUE};

  private Atom[] atoms;

  int measurementCount = 0;
  final List measurements = new ArrayList();
  MeasurementPending measurementPending;
 
  short mad = (short)-1;
  short colix; // default to none in order to contrast with background
 
  Font3D font3d;

  TickInfo tickInfo;
  TickInfo defaultTickInfo;
 
  protected void initModelSet() {
    for (int i = measurements.size(); --i >= 0; ) {
      Measurement m = (Measurement) measurements.get(i);
      if (m != null)
        m.modelSet = modelSet;
    }
    atoms = modelSet.atoms;
  }
 
  public void initShape() {
    super.initShape();
    font3d = g3d.getFont3D(JmolConstants.MEASURE_DEFAULT_FONTSIZE);
  }

  protected void setSize(int size, BitSet bsSelected) {
    mad = (short)size;
  }

  public void setProperty(String propertyName, Object value, BitSet bsIgnored) {
    // the following can be used with "select measures ({bitset})"
   
    Measurement mt;
    if ("clearModelIndex" == propertyName) {
      for (int i = 0; i < measurementCount; i++)
        ((Measurement) measurements.get(i)).setModelIndex((short) 0);
      return;
    }
   
    if ("color" == propertyName) {
      setColor(value == null ? Graphics3D.INHERIT_ALL : Graphics3D.getColix(value));
      return;
    }

    if ("delete" == propertyName) {
      delete(value);
      setIndices();
      return;
    }
   
    if ("font" == propertyName) {
      font3d = (Font3D) value;
      return;
    }
   
    if ("hideAll" == propertyName) {
      showHide(((Boolean) value).booleanValue());
      return;
    }
   
    if ("pending" == propertyName) {
      pending((MeasurementPending) value);
      return;
    }
   
    boolean isRefresh;
    if ((isRefresh = ("refresh" == propertyName))
        || "refreshTrajectories" == propertyName) {
      for (int i = measurements.size(); --i >= 0;)
        if ((mt = (Measurement) measurements.get(i)) != null
            && (isRefresh || mt.isTrajectory()))
          mt.refresh();
      return;
    }

    if ("select" == propertyName) {
      BitSet bs = (BitSet) value;
      if (bs == null || BitSetUtil.cardinalityOf(bs) == 0) {
        bsSelected = null;
      } else {
        bsSelected = new BitSet();
        bsSelected.or(bs);
      }
      return;
    }
   
    if ("setFormats" == propertyName) {
      setFormats((String) value);
      return;
    }

    //any one of the following clears the "select measures" business
   
    bsSelected = null;

    if ("maps" == propertyName) {
      int[][] maps = (int[][]) value;
      for (int i = 0; i < maps.length; i++) {
        int len = maps[i].length;
        if (len < 2 || len > 4)
          continue;
        int[] v = new int[len + 1];
        v[0] = len;
        System.arraycopy(maps[i], 0, v, 1, len);
        toggleOn((int[]) v);
      }
    } else if ("measure" == propertyName) {
      MeasurementData md = (MeasurementData) value;
      tickInfo = md.tickInfo;
      if (md.tickInfo != null && md.tickInfo.id.equals("default")) {
        defaultTickInfo = md.tickInfo;
        return;
      }
      rangeMinMax[0] = md.rangeMinMax[0];
      rangeMinMax[1] = md.rangeMinMax[1];
      mustBeConnected = md.mustBeConnected;
      mustNotBeConnected = md.mustNotBeConnected;
      strFormat = md.strFormat;
      if (md.isAll) {
        if (tickInfo != null)
          define(md, Token.delete);
        define(md, md.tokAction);
        setIndices();
        return;
      }
      Measurement pt = setSingleItem(md.points);
      switch (md.tokAction) {
      case Token.delete:
        define(Integer.MIN_VALUE, pt, true, false, false);
        setIndices();
        break;
      case Token.on:
        showHide(pt, false);         
        break;
      case Token.off:
        showHide(pt, true);
        break;
      case Token.define:
        delete(pt);
        toggle(pt);       
        break;
      case Token.opToggle:
        toggle(pt);       
      }
      return;
    }
   
    if ("clear" == propertyName) {
      clear();
      return;
    }
   
    if ("deleteModelAtoms" == propertyName) {
      atoms = (Atom[])((Object[])value)[1];
      int modelIndex = ((int[]) ((Object[]) value)[2])[0];
      int firstAtomDeleted = ((int[])((Object[])value)[2])[1];
      int nAtomsDeleted = ((int[])((Object[])value)[2])[2];
      int atomMax = firstAtomDeleted + nAtomsDeleted;
      for (int i = measurementCount; --i >= 0;) {
        mt = (Measurement) measurements.get(i);
        int[] indices = mt.getCountPlusIndices();
        for (int j = 1; j <= indices[0]; j++) {
          int iAtom = indices[j];
          if (iAtom >= firstAtomDeleted) {
            if (iAtom < atomMax) {
              deleteMeasurement(i);
              break;
            }
            indices[j] -= nAtomsDeleted;
          } else if (iAtom < 0) {
            Point3fi pt = mt.getAtom(j);
            if (pt.modelIndex > modelIndex) {
              pt.modelIndex--;
            } else if (pt.modelIndex == modelIndex) {
              deleteMeasurement(i);
              break;
            }
          }
        }
      }
      return;
    }

    if ("hide" == propertyName) {
      showHide(new Measurement(modelSet, (int[]) value, null, null), true);
      return;
    }
   
    if ("reformatDistances" == propertyName) {
      reformatDistances();
      return;
    }
   
    if ("show" == propertyName) {
      showHide(new Measurement(modelSet, (int[]) value, null, null), false);
      return;
    }
   
    if ("toggle" == propertyName) {
      toggle(new Measurement(modelSet, (int[]) value, null, null));
      return;
    }
   
    if ("toggleOn" == propertyName) {
      toggleOn((int[]) value);
      return;
    }
   
  }

  private Measurement setSingleItem(List vector) {
    Point3fi[] points = new Point3fi[4];
    int[] indices = new int[5];
    indices[0] = vector.size();
    for (int i = vector.size(); --i >= 0; ) {
      Object value = vector.get(i);
      if (value instanceof BitSet) {
        int atomIndex = ((BitSet) value).nextSetBit(0);
        if (atomIndex < 0)
          return null;
        indices[i + 1] = atomIndex;
      } else {
        points[i] = (Point3fi) value;
        indices[i + 1] = -2 - i;
      }
    }
    return new Measurement(modelSet, indices, points, tickInfo == null ? defaultTickInfo : tickInfo);
  }

  public Object getProperty(String property, int index) {
    if ("pending".equals(property))
      return measurementPending;
    if ("count".equals(property))
      return new Integer(measurementCount);
    if ("countPlusIndices".equals(property))
      return (index < measurementCount ?
          ((Measurement) measurements.get(index)).getCountPlusIndices() : null);
    if ("stringValue".equals(property))
      return (index < measurementCount ? ((Measurement) measurements.get(index)).getString() : null);
    if ("pointInfo".equals(property))
      return ((Measurement) measurements.get(index / 10)).getLabel(index % 10, false, false);
    if ("info".equals(property))
      return getAllInfo();
    if ("infostring".equals(property))
      return getAllInfoAsString();
    return null;
  }

  private void clear() {
    if (measurementCount == 0)
      return;
    measurementCount = 0;
    measurements.clear();
    viewer.setStatusMeasuring("measureDeleted", -1, "all", 0);
  }

  private void setColor(short colix) {
    if (bsColixSet == null)
      bsColixSet = new BitSet();
      if (bsSelected == null)
        this.colix = colix;
    Measurement mt;
    for (int i = measurements.size(); --i >= 0; )
      if ((mt = (Measurement) measurements.get(i)) != null
          && (bsSelected != null && bsSelected.get(i) || bsSelected == null
              && (colix == Graphics3D.INHERIT_ALL || mt.getColix() == Graphics3D.INHERIT_ALL))) {
        mt.setColix(colix);
        bsColixSet.set(i);
      }
  }

  private void setFormats(String format) {
    if (format != null && format.length() == 0)
      format = null;
    for (int i = measurements.size(); --i >= 0;)
      if (bsSelected == null || bsSelected.get(i))
        ((Measurement) measurements.get(i)).formatMeasurement(format, null, false);
  }
 
  private void showHide(boolean isHide) {
    for (int i = measurements.size(); --i >= 0;)
      if (bsSelected == null || bsSelected.get(i))
        ((Measurement) measurements.get(i)).setHidden(isHide);
  }

  private void showHide(Measurement m, boolean isHide) {
    int i = find(m);
    if (i >= 0)
      ((Measurement) measurements.get(i)).setHidden(isHide);
  }
 
  private void toggle(Measurement m) {
    rangeMinMax[0] = Float.MAX_VALUE;
    //toggling one that is hidden should be interpreted as DEFINE
    int i = find(m);
    Measurement mt;
    if (i >= 0 && !(mt = (Measurement) measurements.get(i)).isHidden()) // delete it and all like it
      define(i, mt, true, false, false);
    else // define OR turn on if measureAllModels
      define(-1, m, false, true, false);
    setIndices();
  }

  private void toggleOn(int[] indices) {
    rangeMinMax[0] = Float.MAX_VALUE;
    //toggling one that is hidden should be interpreted as DEFINE
    bsSelected = new BitSet();
    define(Integer.MIN_VALUE, new Measurement(modelSet, indices, null, defaultTickInfo), false, true, true);
    setIndices();
    reformatDistances();
  }

  private void delete(Measurement m) {
    rangeMinMax[0] = Float.MAX_VALUE;
    //toggling one that is hidden should be interpreted as DEFINE
    int i = find(m);
    if (i >= 0)
      define(i, (Measurement) measurements.get(i), true, false, false);
    setIndices();
  }

  private void delete(Object value) {
    if (value instanceof int[]) {
      define(Integer.MIN_VALUE, new Measurement(modelSet, (int[])value, null, null), true, false, false);
      return;
    }
    if ((value instanceof Integer))
      deleteMeasurement(((Integer)value).intValue());  
  }

  private void define(int iPt, Measurement m, boolean isDelete, boolean isShow,
                      boolean doSelect) {
    if (!viewer.getMeasureAllModelsFlag()) {
      if (isDelete) {
        if (iPt == Integer.MIN_VALUE)
          iPt = find(m);
        if (iPt >= 0)
          deleteMeasurement(iPt);
        return;
      }
      defineMeasurement(iPt, m, doSelect);
      return;
    }
    if (isShow) { // make sure all like this are deleted, not just hidden
      define(iPt, m, true, false, false); // self-reference
      if (isDelete)
        return;
    }
    // we create a set of atoms involving all atoms with the
    // same atom number in each model
    List points = new ArrayList();
    int nPoints = m.getCount();
    for (int i = 1; i <= nPoints; i++) {
      int atomIndex = m.getAtomIndex(i);
      points.add(atomIndex >= 0 ? (Object) viewer.getAtomBits(
          Token.atomno, new Integer(atoms[atomIndex].getAtomNumber()))
          : (Object) m.getAtom(i));
    }
    MeasurementData md = new MeasurementData(points,
                   tokAction,
                   rangeMinMax,
                   strFormat, null,
                   tickInfo,
                   mustBeConnected,
                   mustNotBeConnected,
                   true);
    define(md, (isDelete ? Token.delete
        : Token.define
        ));
  }

  private int find(Measurement m) {
    return Measurement.find(measurements, m);
  }

  private void setIndices() {
    for (int i = 0; i < measurementCount; i++)
      ((Measurement) measurements.get(i)).setIndex(i);
  }
 
  private int tokAction;
 
  private void define(MeasurementData md, int tokAction) {
    this.tokAction = tokAction;
    md.define(this, modelSet);
  }

  public void processNextMeasure(Measurement m) {
    // a callback from Measurement.define
    // all atom bitsets have been iterated
    int iThis = find(m);
    if (iThis >= 0) {
      if (tokAction == Token.delete) {
        deleteMeasurement(iThis);
      } else if (strFormat != null) {
        ((Measurement) measurements.get(iThis)).formatMeasurement(strFormat,
            null, true);
      } else {
        ((Measurement) measurements.get(iThis))
            .setHidden(tokAction == Token.off);
      }
    } else if (tokAction == Token.define || tokAction == Token.opToggle) {
      m.tickInfo = (tickInfo == null ? defaultTickInfo : tickInfo);
      defineMeasurement(-1, m, true);
    }
  }

  private void defineMeasurement(int i, Measurement m, boolean doSelect) {
    float value = m.getMeasurement();
    if (rangeMinMax[0] != Float.MAX_VALUE
        && (value < rangeMinMax[0] || value > rangeMinMax[1]))
      return;
    if (i == Integer.MIN_VALUE)
      i = find(m);
    if (i >= 0) {
      ((Measurement) measurements.get(i)).setHidden(false);
      if (doSelect)
        bsSelected.set(i);
      return;
    }
    Measurement measureNew = new Measurement(modelSet, m, value, colix,
        strFormat, measurementCount);
    measurements.add(measureNew);
    viewer.setStatusMeasuring("measureCompleted", measurementCount++,
        measureNew.toVector().toString(), measureNew.getValue());
  }

  private void deleteMeasurement(int i) {
    String msg = ((Measurement) measurements.get(i)).toVector().toString();
    measurements.remove(i);
    measurementCount--;
    viewer.setStatusMeasuring("measureDeleted", i, msg, 0);
  }

  private void pending(MeasurementPending measurementPending) {
    this.measurementPending = measurementPending;
    if (measurementPending == null)
      return;
    if (measurementPending.getCount() > 1)
      viewer.setStatusMeasuring("measurePending",
          measurementPending.getCount(), measurementPending.toVector().toString(), measurementPending.getValue());
  }

  private void reformatDistances() {
    for (int i = measurementCount; --i >= 0; )
      ((Measurement) measurements.get(i)).reformatDistanceIfSelected();   
  }
 
  private List getAllInfo() {
    List info = new ArrayList();
    for (int i = 0; i< measurementCount; i++) {
      info.add(getInfo(i));
    }
    return info;
  }
 
  private String getAllInfoAsString() {
    String info = "Measurement Information";
    for (int i = 0; i< measurementCount; i++) {
      info += "\n" + getInfoAsString(i);
    }
    return info;
  }
 
  private Hashtable getInfo(int index) {
    Measurement m = (Measurement) measurements.get(index);
    int count = m.getCount();
    Hashtable info = new Hashtable();
    info.put("index", new Integer(index));
    info.put("type", (count == 2 ? "distance" : count == 3 ? "angle"
        : "dihedral"));
    info.put("strMeasurement", m.getString());
    info.put("count", new Integer(count));
    info.put("value", new Float(m.getValue()));
    TickInfo tickInfo = m.getTickInfo();
    if (tickInfo != null) {
      info.put("ticks", tickInfo.ticks);
      if (tickInfo.scale != null)
        info.put("tickScale", tickInfo.scale);
      if (tickInfo.tickLabelFormats != null)
        info.put("tickLabelFormats", tickInfo.tickLabelFormats);
      if (!Float.isNaN(tickInfo.first))
        info.put("tickStart", new Float(tickInfo.first));
    }
    List atomsInfo = new ArrayList();
    for (int i = 1; i <= count; i++) {
      Hashtable atomInfo = new Hashtable();
      int atomIndex = m.getAtomIndex(i);
      atomInfo.put("_ipt", new Integer(atomIndex));
      atomInfo.put("coord", Escape.escape(m.getAtom(i)));
      atomInfo.put("atomno", new Integer(atomIndex < 0 ? -1 : atoms[atomIndex].getAtomNumber()));
      atomInfo.put("info", (atomIndex < 0 ? "<point>" : atoms[atomIndex].getInfo()));
      atomsInfo.add(atomInfo);
    }
    info.put("atoms", atomsInfo);
    return info;
  }

  private String getInfoAsString(int index) {
    return ((Measurement) measurements.get(index)).getInfoAsString(null);
  }
 
  void setVisibilityInfo() {
    BitSet bsModels = viewer.getVisibleFramesBitSet();
    out:
    for (int i = measurementCount; --i >= 0; ) {
      Measurement m = ((Measurement) measurements.get(i));
      m.setVisible(false);
      if(mad == 0 || m.isHidden())
        continue;
      for (int iAtom = m.getCount(); iAtom > 0; iAtom--) {
        int atomIndex = m.getAtomIndex(iAtom);
        if (atomIndex >= 0) {
          if (!modelSet.atoms[atomIndex].isClickable())
            continue out;
        } else {
          int modelIndex = m.getAtom(iAtom).modelIndex;
          if (modelIndex >= 0 && !bsModels.get(modelIndex))
            continue out;
        }
      }
      m.setVisible(true);
    }
  }
 
public String getShapeState() {
    StringBuffer commands = new StringBuffer("");
    appendCmd(commands, "measures delete");
    for (int i = 0; i < measurementCount; i++)
      appendCmd(commands, getState(i));
    appendCmd(commands, "select *; set measures " + viewer.getMeasureDistanceUnits());
    appendCmd(commands, getFontCommand("measures", font3d));
    int nHidden = 0;
    Hashtable temp = new Hashtable();
    BitSet bs = new BitSet(measurementCount);
    for (int i = 0; i < measurementCount; i++) {
      Measurement m = ((Measurement) measurements.get(i));
      if (m.isHidden()) {
        nHidden++;
        bs.set(i);
      }
      if (bsColixSet != null && bsColixSet.get(i))
        setStateInfo(temp, i, getColorCommand("measure", m.getColix()));
      if (m.getStrFormat() != null)
        setStateInfo(temp, i, "measure "
            + Escape.escape(m.getStrFormat()));
    }
    if (nHidden > 0)
      if (nHidden == measurementCount)
        appendCmd(commands, "measures off; # lines and numbers off");
      else
        for (int i = 0; i < measurementCount; i++)
          if (bs.get(i))
            setStateInfo(temp, i, "measure off");
    if (defaultTickInfo != null) {
      commands.append(" measure ");
      FontLineShape.addTickInfo(commands, defaultTickInfo, true);
      commands.append(";\n");
    }
    if (mad >= 0)
      commands.append(" set measurements " + (mad / 2000f));
    String s = getShapeCommands(temp, null, "select measures");
    if (s != null && s.length() != 0) {
      commands.append(s);
      appendCmd(commands, "select measures ({null})");
    }
   
    return commands.toString();
  }
 
  private String getState(int index) {
    Measurement m = ((Measurement) measurements.get(index));
    int count = m.getCount();
    StringBuffer sb = new StringBuffer("measure");
    TickInfo tickInfo = m.getTickInfo();
    if (tickInfo != null)
      FontLineShape.addTickInfo(sb, tickInfo, true);
    for (int i = 1; i <= count; i++)
      sb.append(" ").append(m.getLabel(i, true, true));
    sb.append("; # " + getInfoAsString(index));
    return sb.toString();
  }
}
TOP

Related Classes of org.jmol.shape.Measures

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.