Package org.jmol.shape

Source Code of org.jmol.shape.MeshRenderer

/* $RCSfile$
* $Author: hansonr $
* $Date: 2007-04-25 09:53:35 -0500 (Wed, 25 Apr 2007) $
* $Revision: 7491 $
*
* 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 java.util.BitSet;

import javax.vecmath.Point3f;
import javax.vecmath.Point4f;
import javax.vecmath.Vector3f;
import javax.vecmath.Point3i;

import org.jmol.api.SymmetryInterface;
import org.jmol.g3d.Graphics3D;

public abstract class MeshRenderer extends ShapeRenderer {

  protected float imageFontScaling;
  protected float scalePixelsPerMicron;
  protected Point3f[] vertices;
  protected short[] normixes;
  protected Point3i[] screens;
  protected Vector3f[] transformedVectors;
  protected int vertexCount;
  protected boolean frontOnly;
  protected boolean antialias;
  protected Mesh mesh;
  protected int diameter;
  protected float width;
  protected boolean isTranslucent;
  protected Point4f thePlane;
  protected Point3f latticeOffset = new Point3f();

  protected final Point3f pt1f = new Point3f();
  protected final Point3f pt2f = new Point3f();

  protected final Point3i pt1i = new Point3i();
  protected final Point3i pt2i = new Point3i();
  protected final Point3i pt3i = new Point3i();

  protected void render() {
    antialias = g3d.isAntialiased()
    MeshCollection mc = (MeshCollection) shape;
    for (int i = mc.meshCount; --i >= 0;)
      render1(mc.meshes[i]);
  }

  // draw, isosurface, molecular orbitals
  public boolean render1(Mesh mesh) { // used by mps renderer
    this.mesh = mesh;
    if (!setVariables())
      return false;
    if (!g3d.setColix(colix) && !mesh.showContourLines)
      return mesh.title != null;
    latticeOffset.set(0, 0, 0);
    for (int i = vertexCount; --i >= 0;)
      viewer.transformPoint(vertices[i], screens[i]);
    render2(exportType != Graphics3D.EXPORT_NOT);
    if (mesh.lattice == null || mesh.modelIndex < 0) {
      render2(exportType != Graphics3D.EXPORT_NOT);
    } else {
      SymmetryInterface unitcell = viewer.getModelUnitCell(mesh.modelIndex);
      if (unitcell != null) {
        Point3f vTemp = new Point3f();
        Point3i minXYZ = new Point3i();
        Point3i maxXYZ = new Point3i((int) mesh.lattice.x,
            (int) mesh.lattice.y, (int) mesh.lattice.z);
        unitcell.setMinMaxLatticeParameters(minXYZ, maxXYZ);
        for (int tx = minXYZ.x; tx < maxXYZ.x; tx++)
          for (int ty = minXYZ.y; ty < maxXYZ.y; ty++)
            for (int tz = minXYZ.z; tz < maxXYZ.z; tz++) {
              latticeOffset.set(tx, ty, tz);
              unitcell.toCartesian(latticeOffset, false);
              for (int i = vertexCount; --i >= 0;) {
                vTemp.set(vertices[i]);
                vTemp.add(latticeOffset);
                viewer.transformPoint(vTemp, screens[i]);
              }
              render2(exportType != Graphics3D.EXPORT_NOT);
            }
      }
    }

    if (screens != null)
      viewer.freeTempScreens(screens);
    return true;
  }

  private boolean setVariables() {
    vertices = (mesh.ptOffset == null && mesh.scale3d == 0
        ? mesh.vertices : mesh.getOffsetVertices(thePlane));
   
    colix = mesh.colix;
    if (mesh.visibilityFlags == 0)
      return false;
    if (mesh.lineData == null) {
      if ((vertexCount = mesh.vertexCount) == 0 ||
          !mesh.colorDensity && mesh.polygonCount == 0)
        return false;
      normixes = mesh.normixes;
      if (normixes == null || vertices == null)
        return false;
      // this can happen when user switches windows
      // during a surface calculation

      frontOnly = !viewer.getSlabEnabled() && mesh.frontOnly && !mesh.isTwoSided;
      screens = viewer.allocTempScreens(vertexCount);
      transformedVectors = g3d.getTransformedVertexVectors();
    }
    isTranslucent = Graphics3D.isColixTranslucent(mesh.colix);
    return true;
  }

  // all of the following methods are overridden in subclasses
  // DO NOT change parameters without first checking for the
  // same method in a subclass.
 
  protected boolean isPolygonDisplayable(int i) {
    return true;
  }

  //isosurface,meshRenderer::render1 (just about everything)
  protected void render2(boolean generateSet) {
    if (!g3d.setColix(colix))
      return;
    if (mesh.showPoints)
      renderPoints();
    if (mesh.drawTriangles)
      renderTriangles(false, mesh.showTriangles, false);
    if (mesh.fillTriangles)
      renderTriangles(true, mesh.showTriangles, generateSet);
  }
 
  protected void renderPoints() {
    if (mesh.isPolygonSet) {
      int[][] polygonIndexes = mesh.polygonIndexes;
      BitSet bsPoints = new BitSet();
      for (int i = mesh.polygonCount; --i >= 0;) {
        int[] p = polygonIndexes[i];
        if (frontOnly && transformedVectors[normixes[i]].z < 0)
          continue;
        for (int j = p.length - 1; --j >= 0;) {
          int pt = p[j];
          if (bsPoints.get(pt))
            continue;
          bsPoints.set(pt);
          g3d.fillSphere(4, screens[pt]);
        }
      }
      return;
    }
    for (int i = vertexCount; --i >= 0;) {
      if (frontOnly && transformedVectors[normixes[i]].z < 0)
        continue;
      g3d.fillSphere(4, screens[i]);
    }
  }

  protected BitSet bsPolygons = new BitSet();
  protected void renderTriangles(boolean fill, boolean iShowTriangles,
                                 boolean generateSet) {
    int[][] polygonIndexes = mesh.polygonIndexes;
    colix = mesh.colix;
    // vertexColixes are only isosurface properties of IsosurfaceMesh, not Mesh
    g3d.setColix(colix);
    if (generateSet) {
      if (frontOnly && fill)
        frontOnly = false;
      bsPolygons.clear();
    }
    for (int i = mesh.polygonCount; --i >= 0;) {
      if (!isPolygonDisplayable(i))
        continue;
      int[] vertexIndexes = polygonIndexes[i];
      int iA = vertexIndexes[0];
      int iB = vertexIndexes[1];
      int iC = vertexIndexes[2];
      if (iB == iC) {
        // line or point
        drawLine(iA, iB, fill, vertices[iA], vertices[iB], screens[iA],
            screens[iB]);
        continue;
      }
      int check;
      if (mesh.isPolygonSet) {
        short normix = normixes[i];
        if (!g3d.isDirectedTowardsCamera(normix))
          continue;
        if (fill) {
          if (exportType != Graphics3D.EXPORT_NOT) {
            g3d.fillTriangle(screens[iC], colix, normix, screens[iB], colix,
                normix, screens[iA], colix, normix);
          } else if (iShowTriangles) {
            g3d.fillTriangle(screens[iA], colix, normix, screens[iB], colix, normix,
                screens[iC], colix, normix, 0.1f);
          } else {
            g3d.fillTriangle(screens[iA], colix, normix, screens[iB], colix,
                normix, screens[iC], colix, normix);
          }
          continue;
        }
        check = vertexIndexes[3];
        if ((check & 1) == 1)
          drawLine(iA, iB, true, vertices[iA], vertices[iB], screens[iA],
              screens[iB]);
        if ((check & 2) == 2)
          drawLine(iB, iC, true, vertices[iB], vertices[iC], screens[iB],
              screens[iC]);
        if ((check & 4) == 4)
          drawLine(iA, iC, true, vertices[iA], vertices[iC], screens[iA],
              screens[iC]);
        continue;
      }
      short nA = normixes[iA];
      short nB = normixes[iB];
      short nC = normixes[iC];
      check = checkNormals(nA, nB, nC);
      if (fill && check != 7)
        continue;
      switch (vertexIndexes.length) {
      case 3:
        if (fill) {
          if (generateSet) {
            bsPolygons.set(i);
            continue;
          }
          if (iShowTriangles) {
            g3d.fillTriangle(screens[iA], colix, nA, screens[iB], colix, nB,
                screens[iC], colix, nC, 0.1f);
            continue;
          }
          // System.out.println(normixes[iA]+ " " + normixes[iB] + " " +
          // normixes[iC]);
          g3d.fillTriangle(screens[iA], colix, nA, screens[iB], colix, nB,
              screens[iC], colix, nC);
          continue;
        }
        g3d.drawTriangle(screens[iA], screens[iB], screens[iC], check);
        continue;
      case 4:
        int iD = vertexIndexes[3];
        short nD = normixes[iD];
        if (frontOnly && (check != 7 || transformedVectors[nD].z < 0))
          continue;
        if (fill) {
          if (generateSet) {
            bsPolygons.set(i);
            continue;
          }
          g3d.fillQuadrilateral(screens[iA], colix, nA, screens[iB], colix, nB,
              screens[iC], colix, nC, screens[iD], colix, nD);
          continue;
        }
        g3d.drawQuadrilateral(colix, screens[iA], screens[iB], screens[iC],
            screens[iD]);
      }
    }
    if (generateSet)
      exportSurface();
  }

  protected int checkNormals(short nA, short nB, short nC) {
    int check = 7;
    if (frontOnly) {
      if (transformedVectors[nA].z < 0)
        check ^= 1;
      if (transformedVectors[nB].z < 0)
        check ^= 2;
      if (transformedVectors[nC].z < 0)
        check ^= 4;
    }
    return check;
  }

  protected void drawLine(int iA, int iB, boolean fill,
                          Point3f vA, Point3f vB,
                          Point3i sA, Point3i sB) {
    byte endCap = (iA != iB  && !fill ? Graphics3D.ENDCAPS_NONE
        : width < 0 || width == -0.0 || iA != iB && isTranslucent ? Graphics3D.ENDCAPS_FLAT
        : Graphics3D.ENDCAPS_SPHERICAL);
    if (width == 0) {
      if (diameter == 0)
        diameter = (mesh.diameter > 0 ? mesh.diameter : iA == iB ? 7 : 3);
      if (exportType == Graphics3D.EXPORT_CARTESIAN) {
        pt1f.set(vA);
        pt1f.add(vB);
        pt1f.scale(1f / 2f);
        viewer.transformPoint(pt1f, pt1i);
        diameter = (int) (viewer.unscaleToScreen(pt1i.z, diameter) * 1000);
      }
      if (iA == iB) {
        g3d.fillSphere(diameter, sA);
      } else {
        g3d.fillCylinder(endCap, diameter, sA, sB);
      }
    } else {
      pt1f.set(vA);
      pt1f.add(vB);
      pt1f.scale(1f / 2f);
      viewer.transformPoint(pt1f, pt1i);
      int mad = (int) (Math.abs(width) * 1000);
      diameter = (exportType == Graphics3D.EXPORT_CARTESIAN ? mad
          : viewer.scaleToScreen(pt1i.z, mad));
      if (diameter == 0)
        diameter = 1;
      viewer.transformPoint(vA, pt1f);
      viewer.transformPoint(vB, pt2f);
      g3d.fillCylinderBits(endCap, diameter, pt1f, pt2f);
    }
  }

  protected void exportSurface() {
    mesh.vertexNormals = mesh.getNormals(vertices, null);
    mesh.bsFaces = bsPolygons;
    g3d.drawSurface(mesh, mesh.offsetVertices, latticeOffset);
    mesh.vertexNormals = null;
    mesh.bsFaces = null;
  }
 
}
TOP

Related Classes of org.jmol.shape.MeshRenderer

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.