/* * Copyright (C) 2010-2014 - Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */ package edu.stanford.rsl.apps.gui.opengl; import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import javax.media.opengl.GL; import javax.media.opengl.GL4bc; import javax.media.opengl.GLAutoDrawable; import edu.stanford.rsl.conrad.geometry.AbstractShape; import edu.stanford.rsl.conrad.geometry.shapes.compound.CompoundShape; import edu.stanford.rsl.conrad.geometry.shapes.simple.Edge; import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND; import edu.stanford.rsl.conrad.geometry.shapes.simple.Triangle; import edu.stanford.rsl.conrad.geometry.splines.SurfaceBSpline; import edu.stanford.rsl.conrad.geometry.transforms.AffineTransform; import edu.stanford.rsl.conrad.geometry.transforms.Translation; import edu.stanford.rsl.conrad.numerics.SimpleMatrix; import edu.stanford.rsl.conrad.numerics.SimpleVector; import edu.stanford.rsl.conrad.utils.DoublePrecisionPointUtil; /** * Class to render Surface B-Splines in an OpenGL viewer. * @author Mathias Unberath * */ public class BSplineVolumeRenderer extends OpenGLViewer{ ArrayList<SurfaceBSpline> splines; ArrayList<Triangle> triangles; ArrayList<Color> colors; double sampling = 30; private static final long serialVersionUID = 2752954430998793647L; public BSplineVolumeRenderer(String filename) throws IOException { super(filename); this.setSize(640, 480); splines = SurfaceBSpline.readSplinesFromFile(filename); setUp(sampling, sampling); } public BSplineVolumeRenderer(SurfaceBSpline... spline){ super("Spline rendering."); this.setSize(640, 480); splines = new ArrayList<SurfaceBSpline>(); for(int i = 0; i < spline.length; i++){ splines.add(spline[i]); } setUp(sampling, sampling); } public BSplineVolumeRenderer(double samplingU, double samplingV, SurfaceBSpline... spline){ super("Spline rendering."); this.setSize(640, 480); splines = new ArrayList<SurfaceBSpline>(); for(int i = 0; i < spline.length; i++){ splines.add(spline[i]); } setUp(samplingU, samplingV); } private void setUp(double samplingU, double samplingV){ this.triangles = new ArrayList<Triangle>(); for( int i = 0; i < splines.size(); i++){ CompoundShape cs = (CompoundShape) splines.get(i).tessellateMesh(samplingU, samplingV, 2); for(int j = 0; j < cs.size(); j++){ try{ CompoundShape cs2 = (CompoundShape) cs.get(j); for(int k = 0; k < cs2.size(); k++){ triangles.add((Triangle)cs2.get(k)); } }catch(Exception e){ // } } } modify(); } private void modify(){ ArrayList<PointND> centerPoints = new ArrayList<PointND>(); for (Triangle t : triangles) { centerPoints.add(t.getPoint()); } PointND center = DoublePrecisionPointUtil.getGeometricCenter(centerPoints); Translation translation = new Translation(center.getAbstractVector().negated()); double max = 0; for (Triangle t : triangles) { t.applyTransform(translation); PointND p = t.getPoint(); for (int i = 0; i < 3; i++) { if (Math.abs(p.get(i)) > max) { max = Math.abs(p.get(i)); } } } AffineTransform affineTransform = new AffineTransform( SimpleMatrix.I_3.dividedBy(max / 1.0),new SimpleVector(0, 0, 0)); for (Triangle t : triangles) { // t.applyTransform(translation); t.applyTransform(affineTransform); } } public void display(GLAutoDrawable arg0) { if (!initialized) { return; } GL4bc gl = (GL4bc) arg0.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL4bc.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustum(-1.5, 1.5, -1.5, 1.5, 5, 15); gl.glMatrixMode(GL4bc.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslated(0, 0, -10); gl.glTranslatef(-translationX, -translationY, -translationZ); gl.glRotatef(-rotationX, 1.0f, 0.0f, 0.0f); gl.glRotatef(-(rotationY), 0.0f, 1.0f, 0.0f); // Internal Coordinates we want to use for visualization: (0,0,0) to (1,1,1); for (int i = 0; i < triangles.size(); i++) { Triangle p = triangles.get(i); if (colors == null) { drawTriangle(gl, p, Color.WHITE); } else { Color col = colors.get(i); drawTriangle(gl, p, col); } } } public void init(GLAutoDrawable arg0) { // Perform the default GL initialization GL4bc gl = (GL4bc) arg0.getGL(); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glShadeModel(GL4bc.GL_SMOOTH); gl.glEnable(GL.GL_DEPTH_TEST); if (initialized) { return; } initialized = true; } public void update(SurfaceBSpline... spline){ splines = new ArrayList<SurfaceBSpline>(); for(int i = 0; i < spline.length; i++){ splines.add(spline[i]); } setUp(sampling, sampling); } public void dispose(GLAutoDrawable arg0) { // TODO Auto-generated method stub } }