Package org.jmol.shapesurface

Source Code of org.jmol.shapesurface.IsosurfaceRenderer

/* $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.shapesurface;

import java.util.List;

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

import org.jmol.g3d.Graphics3D;
import org.jmol.jvxl.data.JvxlCoder;
import org.jmol.jvxl.readers.Parameters;
import org.jmol.shape.MeshRenderer;

public class IsosurfaceRenderer extends MeshRenderer {

  private boolean iShowNormals;
  protected boolean iHideBackground;
  protected boolean isBicolorMap;
  protected short backgroundColix;
  protected int nError = 0;
  protected float[] vertexValues;
  protected IsosurfaceMesh imesh;

  protected void initRenderer() {
    super.initRenderer();
  }
  protected void render() {
    iShowNormals = viewer.getTestFlag4();
    Isosurface isosurface = (Isosurface) shape;
    int slabValue = (viewer.getNavigationMode() ? g3d.getSlab() : Integer.MAX_VALUE);
    for (int i = isosurface.meshCount; --i >= 0;) {
      imesh = (IsosurfaceMesh) isosurface.meshes[i];
      g3d.setTranslucentCoverOnly(imesh.frontOnly);
      thePlane = imesh.jvxlData.jvxlPlane;
      vertexValues = imesh.vertexValues;
      if (slabValue != Integer.MAX_VALUE && imesh.isSolvent) {
        g3d.setSlab((int) viewer.getNavigationOffset().z);
        render1(imesh);
        g3d.setSlab(slabValue);
      } else {
        render1(imesh);
      }
      g3d.setTranslucentCoverOnly(false);
    }
  }

  protected void render2(boolean isExport) {
    if (imesh.jvxlData.colorDensity) {
      renderPoints();
      return;
    }
    switch (imesh.dataType) {
    case Parameters.SURFACE_LONEPAIR:
      renderLonePair(false);
      return;
    case Parameters.SURFACE_RADICAL:
      renderLonePair(true);
      return;
    }
    isBicolorMap = imesh.jvxlData.isBicolorMap;
    super.render2(isExport);
    if (!g3d.setColix(Graphics3D.BLACK)) // must be 1st pass
      return;
    if (imesh.showContourLines)
      renderContourLines();
  }
 
  private void renderLonePair(boolean isRadical) {
    pt2f.set(imesh.vertices[1]);
    viewer.transformPoint(pt2f, pt2f);
    int r = viewer.scaleToScreen((int)pt2f.z, 100);
    if (r < 1)
      r = 1;
    if (!isRadical) {
      Vector3f v1 = new Vector3f();
      Vector3f v2 = new Vector3f();
      pt1f.set(imesh.vertices[0]);
      viewer.transformPoint(pt1f, pt1f);
      v1.sub(pt2f, pt1f);
      v2.set(v1.x, v1.y, v1.z + 1);
      v2.cross(v2,v1);
      v2.normalize();
      float f = viewer.scaleToScreen((int)pt1f.z, 100);
      v2.scale(f);
      pt1f.set(pt2f);
      pt1f.add(v2);
      pt2f.sub(v2);
      screens[0].set((int)pt1f.x,(int)pt1f.y,(int)pt1f.z);
      g3d.fillSphere(r, screens[0]);
    }
    screens[1].set((int)pt2f.x,(int)pt2f.y,(int)pt2f.z);
    g3d.fillSphere(r, screens[1]);
  }
 
  private void renderContourLines() {
    List[] vContours = imesh.getContours();
    if (vContours == null)
      return;
    for (int i = vContours.length; --i >= 0;) {
      List v = vContours[i];
      if (v.size() < JvxlCoder.CONTOUR_POINTS)
        continue;
      colix = (imesh.meshColix == 0 ? ((short[]) v.get(JvxlCoder.CONTOUR_COLIX))[0]
          : imesh.meshColix);
      if (!g3d.setColix(colix))
        return;
      int n = v.size() - 1;
      for (int j = JvxlCoder.CONTOUR_POINTS; j < n; j++) {
        Point3f pt1 = (Point3f) v.get(j);
        Point3f pt2 = (Point3f) v.get(++j);
        viewer.transformPoint(pt1, pt1i);
        viewer.transformPoint(pt2, pt2i);
        if (Float.isNaN(pt1.x) || Float.isNaN(pt2.x))
          break;
        pt1i.z -= 2;
        pt2i.z -= 2;
        g3d.drawLine(pt1i, pt2i);
      }
    }
  }
 
  private final Point3f ptTemp = new Point3f();
  private final Point3i ptTempi = new Point3i();

  protected void renderPoints() {
    int incr = imesh.vertexIncrement;
    int diam = viewer.getScreenDim() / 100;
    boolean showNumbers = viewer.getTestFlag3();
    int cX = (showNumbers ? viewer.getScreenWidth()/2 : 0);
    int cY = (showNumbers ? viewer.getScreenHeight()/2 : 0);
   
    if (showNumbers)
      g3d.setFont(g3d.getFontFid("Monospaced", 24));
    for (int i = (!imesh.hasGridPoints || imesh.firstRealVertex < 0 ? 0
        : imesh.firstRealVertex); i < vertexCount; i += incr) {
      if (vertexValues != null && Float.isNaN(vertexValues[i]) || frontOnly
          && transformedVectors[normixes[i]].z < 0
          || imesh.thisSet >= 0 && imesh.vertexSets[i] != imesh.thisSet
          || imesh.vertexColixes != null && !g3d.setColix(imesh.vertexColixes[i]))
          continue;
      if (showNumbers && screens[i].z > 10
         && Math.abs(screens[i].x - cX) < 50
         && Math.abs(screens[i].y - cY) < 50
        ) {
        String s = i + (imesh.isColorSolid ? "" : " " + imesh.vertexValues[i]);
        //System.out.println("IsoSurfaceRenderer i=" + s + " "
          //  + imesh.vertices[i] + " " + imesh.vertexValues[i]);
        g3d.drawStringNoSlab(s, null,
            screens[i].x, screens[i].y, screens[i].z);
      }
      g3d.fillSphere(diam, screens[i]);
    }
    if (incr != 3)
      return;
    g3d.setColix(isTranslucent ? Graphics3D.getColixTranslucent(
        Graphics3D.GRAY, true, 0.5f) : Graphics3D.GRAY);
    for (int i = 1; i < vertexCount; i += 3)
      g3d.fillCylinder(Graphics3D.ENDCAPS_SPHERICAL, diam/4, screens[i],
          screens[i + 1]);

    g3d.setColix(isTranslucent ? Graphics3D.getColixTranslucent(
        Graphics3D.YELLOW, true, 0.5f) : Graphics3D.YELLOW);
    for (int i = 1; i < vertexCount; i += 3)
      g3d.fillSphere(diam, screens[i]);
   
    g3d.setColix(isTranslucent ? Graphics3D.getColixTranslucent(
        Graphics3D.BLUE, true, 0.5f) : Graphics3D.BLUE);
    for (int i = 2; i < vertexCount; i += 3) {
      g3d.fillSphere(diam, screens[i]);
    }
  }

  protected void renderTriangles(boolean fill, boolean iShowTriangles,
                                 boolean isExport) {
    int[][] polygonIndexes = imesh.polygonIndexes;
    colix = (!fill && imesh.meshColix != 0 ? imesh.meshColix : imesh.colix);
    short[] vertexColixes = (!fill && imesh.meshColix != 0 ? null : imesh.vertexColixes);
    g3d.setColix(colix);
    boolean generateSet = isExport;
    if (generateSet) {
      if (frontOnly && fill)
        frontOnly = false;
      bsPolygons.clear();
    }
    if (exportType == Graphics3D.EXPORT_CARTESIAN) {
      frontOnly = false;
    }
    boolean colorSolid = (vertexColixes == null || imesh.isColorSolid);
    //System.out.println("isosurfacerenderer imesh.isColorSolid = " + imesh.isColorSolid);
    boolean noColor = (vertexColixes == null || !fill && imesh.meshColix != 0);
    boolean isPlane = (imesh.jvxlData.jvxlPlane != null);
    short colix = this.colix;
    if (isPlane && !colorSolid && !fill && imesh.fillTriangles) {
      colorSolid = true;
      colix = Graphics3D.BLACK;
    }
/*  only an idea -- causes flickering
    if (isPlane && colorSolid) {
      g3d.setNoisySurfaceShade(screens[polygonIndexes[0][0]],
          screens[polygonIndexes[imesh.polygonCount / 2][1]], screens[polygonIndexes[imesh.polygonCount - 1][2]]);
    }
*/
    boolean colorArrayed = (colorSolid && imesh.polygonColixes != null);
    if (colorArrayed && !fill && imesh.fillTriangles)
      colorArrayed = false;
    short[] contourColixes = imesh.jvxlData.contourColixes;
    // two-sided means like a plane, with no front/back distinction
   
    for (int i = imesh.polygonCount; --i >= 0;) {
     
      int[] vertexIndexes = polygonIndexes[i];
      if (vertexIndexes == null)
        continue;
      int iA = vertexIndexes[0];
      int iB = vertexIndexes[1];
      int iC = vertexIndexes[2];
      if (imesh.thisSet >= 0 && imesh.vertexSets[iA] != imesh.thisSet)
        continue;
      short nA = normixes[iA];
      short nB = normixes[iB];
      short nC = normixes[iC];
      int check = checkNormals(nA, nB, nC);
      if (fill && check == 0)
        continue;
      short colixA, colixB, colixC;
      if (colorSolid) {
        if (colorArrayed && i < imesh.polygonColixes.length) {
          short c = imesh.polygonColixes[i];
          if (c == 0)
            continue;
          colix = c;
        }
        colixA = colixB = colixC = colix;
      } else {
        colixA = vertexColixes[iA];
        colixB = vertexColixes[iB];
        colixC = vertexColixes[iC];
        if (isBicolorMap && (colixA != colixB || colixB != colixC))
          continue;
      }
      if (fill) {
        if (generateSet) {
          bsPolygons.set(i);
          continue;
        }
        if (iShowTriangles) {
          g3d.fillTriangle(screens[iA], colixA, nA, screens[iB], colixB, nB,
              screens[iC], colixC, nC, 0.1f);
        } else {
/*         
          if (colorSolid && isPlane) {
            g3d.fillTriangle(screens[iA], screens[iB], screens[iC]);
          } else {
*/
            g3d.fillTriangle(screens[iA], colixA, nA, screens[iB], colixB, nB,
                screens[iC], colixC, nC);
//          }
        }
        if (iShowNormals)
          renderNormals();
      } else {
        // mesh only
        // check: 1 (ab) | 2(bc) | 4(ac)
        check &= vertexIndexes[3];
        if (iShowTriangles)
          check = 7;
        if (check == 0)
          continue;
        pt1i.set(screens[iA]);
        pt2i.set(screens[iB]);
        pt3i.set(screens[iC]);
        pt1i.z -= 2;
        pt2i.z -= 2;
        pt3i.z -= 2;
        if (noColor) {
        } else if (colorArrayed) {
          g3d.setColix(mesh.fillTriangles ? Graphics3D.BLACK
              : contourColixes[vertexIndexes[4] % contourColixes.length]);
        } else {
          g3d.drawTriangle(pt1i, colixA, pt2i, colixB, pt3i, colixC, check);
          continue;
        }
        g3d.drawTriangle(pt1i, pt2i, pt3i, check);
      }
    }
    if (generateSet)
      exportSurface();
  }

  private void renderNormals() {
    // Logger.debug("mesh renderPoints: " + vertexCount);
    if (!g3d.setColix(Graphics3D.WHITE))
      return;
    g3d.setFont(g3d.getFontFid("Monospaced", 24));
    for (int i = vertexCount; --i >= 0;) {
      if (vertexValues != null && !Float.isNaN(vertexValues[i])) {
        ptTemp.set(mesh.vertices[i]);
        short n = mesh.normixes[i];
        // -n is an intensity2sided and does not correspond to a true normal
        // index
        if (n >= 0) {
          ptTemp.add(Graphics3D.getNormixVector(n));
          viewer.transformPoint(ptTemp, ptTempi);
          g3d.drawLine(screens[i], ptTempi);
          g3d.drawStringNoSlab("" + n, null, ptTempi.x, ptTempi.y, ptTempi.z);
        }
      }
    }
  }

}
TOP

Related Classes of org.jmol.shapesurface.IsosurfaceRenderer

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.