Package org.jmol.shape

Source Code of org.jmol.shape.MeshCollection

/* $RCSfile$
* $Author: hansonr $
* $Date: 2007-04-18 01:25:52 -0500 (Wed, 18 Apr 2007) $
* $Revision: 7435 $
*
* 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.g3d.*;
import org.jmol.viewer.JmolConstants;
import org.jmol.viewer.StateManager;
import org.jmol.script.Token;

import java.util.BitSet;
import java.util.Hashtable;

import javax.vecmath.Point3f;

import org.jmol.util.Escape;
import org.jmol.util.ArrayUtil;
import org.jmol.util.Logger;
import org.jmol.util.TextFormat;

public abstract class MeshCollection extends Shape {

  // Draw, Isosurface(LcaoCartoon MolecularOrbital Pmesh)
   
  public int meshCount;
  public Mesh[] meshes = new Mesh[4];
  public Mesh currentMesh;
  public int modelCount;
  public boolean isFixed; 
  public String script;
  public int nUnnamed;
  public short colix;
  public String myType;
  public boolean explicitID;
  public String actualID;
  protected String previousMeshID;
  protected Mesh linkedMesh;
  protected boolean iHaveModelIndex;
  protected int modelIndex;
  protected boolean allowContourLines;
  protected boolean haveContours = false;
 
  public String[] title;
  protected boolean allowMesh = true;
 
  protected Mesh pickedMesh = null;
  protected int pickedModel;
  protected int pickedVertex;

  private Mesh setMesh(String thisID) {
    linkedMesh = null;
    if (thisID == null || TextFormat.isWild(thisID)) {
      currentMesh = null;
      return null;
    }
    currentMesh = getMesh(thisID);
    if (currentMesh == null) {
      allocMesh(thisID, null);
    } else if (thisID.equals(JmolConstants.PREVIOUS_MESH_ID)) {
      linkedMesh = currentMesh.linkedMesh;
    }
    if (currentMesh.thisID == null) {
      currentMesh.thisID = myType + (++nUnnamed);
      if (htObjects != null)
        htObjects.put(currentMesh.thisID.toUpperCase(), currentMesh);
    }
    previousMeshID = currentMesh.thisID;
    return currentMesh;
  }

  protected Hashtable htObjects;
 
  public void allocMesh(String thisID, Mesh m) {
    // this particular version is only run from privately;
    // isosurface and draw both have overriding methods
    int index = meshCount++;
    meshes = (Mesh[])ArrayUtil.ensureLength(meshes, meshCount * 2);
    currentMesh = meshes[index] = (m == null ? new Mesh(thisID, g3d, colix, index) : m);
    currentMesh.index = index;
    if (thisID != null && htObjects != null)
      htObjects.put(thisID.toUpperCase(), currentMesh);
    previousMeshID = null;
  }

  /**
   * called by ParallelProcessor at completion
   *
   * @param shape
   *
   */
  public void merge(Shape shape) {
    MeshCollection mc = (MeshCollection) shape;
    for (int i = 0; i < mc.meshCount; i++) {
      if (mc.meshes[i] != null) {
        Mesh m = mc.meshes[i];
        Mesh m0 = getMesh(m.thisID);
        if (m0 == null) {
          allocMesh(m.thisID, m);
        } else {
          meshes[m0.index] = m;
          m.index = m0.index;
        }
      }     
    }
    previousMeshID = null;
    currentMesh = null;
  }

  public void initShape() {
    super.initShape();
    colix = Graphics3D.ORANGE;
    modelCount = viewer.getModelCount();
  }
 
public void setProperty(String propertyName, Object value, BitSet bs) {

   if (propertyName == "setXml") {
     if (currentMesh != null)
       currentMesh.xmlProperties = xmlProperties;
   }
  
    if ("init" == propertyName) {
      title = null;
      return;
    }

    if ("link" == propertyName) {
      if (meshCount >= 2 && currentMesh != null)
        currentMesh.linkedMesh = meshes[meshCount - 2];
      return;
    }

    if ("lattice" == propertyName) {
      if (currentMesh != null)
        currentMesh.lattice = (Point3f) value;
      return;
    }

    if ("variables" == propertyName) {
      if (currentMesh != null && currentMesh.scriptCommand != null && !currentMesh.scriptCommand.startsWith("{"))
        currentMesh.scriptCommand = "{\n" + StateManager.getVariableList((Hashtable) value, 0, false) + "\n" + currentMesh.scriptCommand;
      return;
    }

    if ("thisID" == propertyName) {
      String id = (String) value;
      setMesh(id);
      checkExplicit(id);
      return;
    }

    if ("title" == propertyName) {
      if (value == null) {
        title = null;
      } else if (value instanceof String[]) {
        title = (String[]) value;
      } else {
        int nLine = 1;
        String lines = (String) value;
        for (int i = lines.length(); --i >= 0;)
          if (lines.charAt(i) == '|')
            nLine++;
        title = new String[nLine];
        nLine = 0;
        int i0 = -1;
        for (int i = 0; i < lines.length(); i++)
          if (lines.charAt(i) == '|') {
            title[nLine++] = lines.substring(i0 + 1, i);
            i0 = i;
          }
        title[nLine] = lines.substring(i0 + 1);
      }
      return;
    }

    if ("delete" == propertyName) {
      deleteMesh();
      return;
    }

    if ("reset" == propertyName) {
      String thisID = (String) value;
      if (setMesh(thisID) == null)
        return;
//      deleteMesh();
      setMesh(thisID);
      return;
    }

    if ("color" == propertyName) {
      if (value == null)
        return;
      colix = Graphics3D.getColix(value);
      setTokenProperty(Token.color, false);
      return;
    }

    if ("translucency" == propertyName) {
      setTokenProperty(Token.translucent, (((String) value).equals("translucent")));
      return;
    }

    if ("hidden" == propertyName) {
      value = new Integer(((Boolean)value).booleanValue() ? Token.off: Token.on);
      propertyName = "token";
      //continue
    }

    if ("token" == propertyName) {
      int tok = ((Integer) value).intValue();
      int tok2 = 0;
      boolean test = true;
      switch (tok) {
      case Token.on:
      case Token.frontlit:
      case Token.backlit:
      case Token.fullylit:
      case Token.dots:
      case Token.fill:
      case Token.triangles:
      case Token.frontonly:
        break;
      case Token.off:
        test = false;
        tok = Token.on;
        break;
      case Token.contourlines:
        tok2 = Token.mesh;
        break;
      case Token.nocontourlines:
        test = false;
        // TODO leave this as is for now; probably TRUE is correct...
        tok = Token.contourlines; //(true || allowContourLines ? Token.contourlines : Token.mesh);
        tok2 = Token.mesh;
        break;
      case Token.mesh:
        tok2 = Token.contourlines;
        break;
      case Token.nomesh:
        test = false;
        tok = Token.mesh;
        tok2 = Token.contourlines;
        break;
      case Token.nodots:
        test = false;
        tok = Token.dots;
        break;
      case Token.nofill:
        test = false;
        tok = Token.fill;
        break;
      case Token.notriangles:
        test = false;
        tok = Token.triangles;
        break;
      case Token.notfrontonly:
        test = false;
        tok = Token.frontonly;
        break;
      default:
        Logger.error("PROBLEM IN MESHCOLLECTION: token? " + Token.nameOf(tok));
      }
      setTokenProperty(tok, test);
      if (tok2 != 0) {
        if (currentMesh.havePlanarContours && currentMesh.drawTriangles != currentMesh.showContourLines)
          setTokenProperty(tok2, test);
      }
      return;
    }
    super.setProperty(propertyName, value, bs);
  }

  protected void checkExplicit(String id) {
    if (explicitID) // not twice
      return;
    explicitID = (id != null && !id.equals(JmolConstants.PREVIOUS_MESH_ID));
    if (explicitID)
      previousMeshID = id;
  }
 
  private void setTokenProperty(int tokProp, boolean bProp) {
    if (currentMesh == null) {
      String key = (explicitID && previousMeshID != null
          && TextFormat.isWild(previousMeshID) ? previousMeshID.toUpperCase()
          : null);
      if (key != null && key.length() == 0)
        key = null;
      for (int i = 0; i < meshCount; i++)
        if (key == null
            || TextFormat.isMatch(meshes[i].thisID.toUpperCase(), key, true, true))
          setMeshTokenProperty(meshes[i], tokProp, bProp);
    } else {
      setMeshTokenProperty(currentMesh, tokProp, bProp);
      if (linkedMesh != null)
        setMeshTokenProperty(linkedMesh, tokProp, bProp);
    }
  }
  private void setMeshTokenProperty(Mesh m, int tokProp, boolean bProp) {
    switch (tokProp) {
    case Token.on:
      m.visible = bProp;
      return;
    case Token.color:
      m.colix = colix;
      return;
    case Token.translucent:
      m.setTranslucent(bProp, translucentLevel);
      return;
    case Token.frontlit:
    case Token.backlit:
    case Token.fullylit:
      m.setLighting(tokProp);
      return;
    case Token.dots:
      m.showPoints = bProp;
      return;
    case Token.mesh:
      m.drawTriangles = bProp;
      return;
    case Token.fill:
      m.fillTriangles = bProp;
      return;
    case Token.triangles:
      m.showTriangles = bProp;
      return;
    case Token.contourlines:
      m.showContourLines = bProp;
      return;
    case Token.frontonly:
      m.frontOnly = bProp;
      return;
    }
  }
 
  public boolean getProperty(String property, Object[] data) {
    if (property == "checkID") {
      String key = ((String) data[0]).toUpperCase();
      boolean isWild = TextFormat.isWild(key);
      for (int i = meshCount; --i >= 0;) {
        String id = meshes[i].thisID;
        if (id.equalsIgnoreCase(key) || isWild
            && TextFormat.isMatch(id.toUpperCase(), key, true, true)) {
          data[1] = id;
          return true;
        }
      }
      return false;
    }
    if (property == "getCenter") {
      String id = (String) data[0];
      int index = ((Integer) data[1]).intValue();
      Mesh m;
      if ((m = getMesh(id)) == null || m.vertices == null)
        return false;
      if (index == Integer.MAX_VALUE)
        data[2] = new Point3f(m.index + 1, meshCount, m.vertexCount);
      else
        data[2] = m.vertices[m.getVertexIndexFromNumber(index)];
      return true;
    }
    return false;
  }

  public Object getProperty(String property, int index) {
   Mesh m;
    if (property == "count") {
      int n = 0;
      for (int i = 0; i < meshCount; i++)
        if ((m = meshes[i]) != null && m.vertexCount > 0)
          n++;
      return new Integer(n);
    }
    if (property == "ID")
      return (currentMesh == null ? null : currentMesh.thisID);
    if (property == "list") {
      StringBuffer sb = new StringBuffer();
      int k = 0;
      for (int i = 0; i < meshCount; i++) {
         if ((m = meshes[i]) == null || m.vertexCount == 0)
          continue;
        sb.append((++k)).append(" id:" + m.thisID).append(
            "; model:" + viewer.getModelNumberDotted(m.modelIndex)).append(
            "; vertices:" + m.vertexCount).append(
            "; polygons:" + m.polygonCount).append("; visible:" + m.visible);
        if (m.title != null) {
          String s = "";
          for (int j = 0; j < m.title.length; j++)
            s += (j == 0 ? "; title:" : " | ") + m.title[j];
          if (s.length() > 10000)
            s = s.substring(0, 10000) + "...";
          sb.append(s);
        }
        sb.append('\n');
      }
      return sb.toString();
    }
    if (property == "vertices")
      return getVertices(currentMesh);
    return null;
  }

  private Object getVertices(Mesh mesh) {
    if (mesh == null)
      return null;
    return mesh.vertices;
  }
  protected void clean() {
    for (int i = meshCount; --i >= 0;)
      if (meshes[i] == null || meshes[i].vertexCount == 0)
        deleteMesh(i);
  }

  private void deleteMesh() {
    if (explicitID && currentMesh != null)
      deleteMesh(currentMesh.index);
    else
      deleteMesh(explicitID && previousMeshID != null
          && TextFormat.isWild(previousMeshID)
              previousMeshID : null);
    currentMesh = null;
  }

  protected void deleteMesh(String key) {
    if (key == null || key.length() == 0) {
      for (int i = meshCount; --i >= 0; )
        meshes[i] = null;
      meshCount = 0;
      nUnnamed = 0;
      if (htObjects != null)
        htObjects.clear();
    } else {
      key = key.toLowerCase();
      for (int i = meshCount; --i >= 0; ) {
        if (TextFormat.isMatch(meshes[i].thisID.toLowerCase(), key, true, true))
          deleteMesh(i);
      }
    }
  }

  public void deleteMesh(int i) {
    if (htObjects != null)
      htObjects.remove(meshes[i].thisID.toUpperCase());
    for (int j = i + 1; j < meshCount; ++j)
      meshes[--meshes[j].index] = meshes[j];
    meshes[--meshCount] = null;
  }
 
  public Mesh getMesh(String thisID) {
    int i = getIndexFromName(thisID);
    return (i < 0 ? null : meshes[i]);
  }
 
  public int getIndexFromName(String thisID) {
    if (JmolConstants.PREVIOUS_MESH_ID.equals(thisID))
      return (previousMeshID == null ? meshCount - 1
          : getIndexFromName(previousMeshID));
    if (TextFormat.isWild(thisID)) {
      thisID = thisID.toLowerCase();
      for (int i = meshCount; --i >= 0;) {
        if (meshes[i] != null
            && TextFormat.isMatch(meshes[i].thisID, thisID, true, true))
          return i;
      }
    } else {
      if (htObjects != null) {
        Mesh m = (Mesh)(htObjects.get(thisID.toUpperCase()));
        return (m == null ? -1 : m.index);
      }
      for (int i = meshCount; --i >= 0;) {
        if (meshes[i] != null && thisID.equalsIgnoreCase(meshes[i].thisID))
          return i;
      }
    }
    return -1;
  }
 
  public void setModelIndex(int atomIndex, int modelIndex) {
    if (currentMesh == null)
      return;
    currentMesh.visible = true;
    if ((currentMesh.atomIndex = atomIndex) >= 0)
      currentMesh.modelIndex = viewer.getAtomModelIndex(atomIndex);
    else if (isFixed)
      currentMesh.modelIndex = -1;
    else if (modelIndex >= 0)
      currentMesh.modelIndex = modelIndex;
    else
      currentMesh.modelIndex = viewer.getCurrentModelIndex();
    currentMesh.scriptCommand = script;
  }

  public void setVisibilityFlags(BitSet bs) {
    /*
     * set all fixed objects visible; others based on model being displayed
     *
     */
    BitSet bsDeleted = viewer.getDeletedAtoms();
    for (int i = meshCount; --i >= 0;) {
      Mesh mesh = meshes[i];
      mesh.visibilityFlags = (mesh.visible
          && mesh.isValid
          && (mesh.modelIndex < 0 || bs.get(mesh.modelIndex)
              && (mesh.atomIndex < 0 || !modelSet.isAtomHidden(mesh.atomIndex)
                  && !(bsDeleted != null && bsDeleted.get(mesh.atomIndex)))) ? myVisibilityFlag
          : 0);
    }
  }
  protected void getModelIndex(String script) {
    //pmesh and isosurface state
    int i;
    iHaveModelIndex = false;
    modelIndex = -1;
    if (script == null || (i = script.indexOf("MODEL({")) < 0)
      return;
    int j = script.indexOf("})", i);
    if (j < 0)
      return;
    BitSet bs = Escape.unescapeBitset(script.substring(i + 3, j + 1));
    modelIndex = (bs == null ? -1 : bs.nextSetBit(0));
    iHaveModelIndex = (modelIndex >= 0);
  }
 
  protected void setStatusPicked(int flag, Point3f v) {
    // for draw and isosurface
    viewer.setStatusAtomPicked(flag, "[\"" + myType + "\"," + Escape.escape(pickedMesh.thisID) + "," +
        + pickedModel + "," + pickedVertex + "," + v.x + "," + v.y + "," + v.z + ","
        + (pickedMesh.title == null ? "\"\""
               : Escape.escape(pickedMesh.title[0]))+"]");
  }
}

TOP

Related Classes of org.jmol.shape.MeshCollection

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.