/* Copyright (c) 2010, Chris Want Based on a FORTRAN code by Jon Johansson Please see BSD style licence at the end of this file */ /* Images */ PImage bg=null; // Background PImage glow=null; // Heat sprite /* Calculation intesive objects */ HydrogenProgress hy=null; IsoSurface surface=null; Scene scene; /* Important global variables hooked up to widgets */ int N, L, M, NMin, LMin, MMin, NMax, LMax, MMax; int Res, ResMin, ResMax, ResStep, ResBigStep; /* State variables */ boolean updateVolume=true; int fontsize = 16; /* GUI and widgets */ GUI gui=null; NWidget nwidget=null; LWidget lwidget=null; MWidget mwidget=null; IsoWidget isowidget=null; ResWidget reswidget=null; HeatWidget heatwidget=null; void setup() { size(500,600,P3D); rectMode(CORNERS); textFont(loadFont("AmericanTypewriter-24.vlw"),fontsize); textAlign(CENTER); scene = new Scene("bg.jpg"); //bg=loadImage("bg.jpg"); glow=loadImage("glow.png"); N = 5; L = 4; M = 0; Res = 50; ResMin = 50; ResMax = 200; ResStep = 1; ResBigStep = 25; updateMinMaxNLM(); hy = new HydrogenProgress(Res, N, L, M); surface=new IsoSurface(hy); surface.update(); surface.setColor(color(255,255,255)); scene.setView(hy); int ygui; int widgetw2; int x1, x2; widgetw2 = 80; x1 = width/2 + 120 - widgetw2; x2 = width/2 + 120 + widgetw2; ygui = 20; nwidget = new NWidget(x1,ygui,x2,ygui+40); ygui += 50; lwidget = new LWidget(x1,ygui,x2,ygui+40); ygui += 50; mwidget = new MWidget(x1,ygui,x2,ygui+40); widgetw2 = 100; x1 = width/2 - widgetw2; x2 = width/2 + widgetw2; ygui = height - 150; isowidget =new IsoWidget(x1, ygui, x2, ygui+40); ygui += 50; heatwidget =new HeatWidget(x1, ygui, x2, ygui+40); ygui += 50; reswidget =new ResWidget(x1, ygui, x2, ygui+40); gui=new GUI(); gui.addElement(nwidget); gui.addElement(lwidget); gui.addElement(mwidget); gui.addElement(isowidget); gui.addElement(reswidget); gui.addElement(heatwidget); } boolean validateNLM(float n, float l, float m) { if ((n < 1) || (l<0) || (m<0) || (l>=n) || (m>l)) { return false; } return true; } void updateMinMaxNLM() { NMax = 25; LMax = N - 1; MMax = L; NMin = max(1, L+1); LMin = max(0, M); MMin = 0; } void mouseMoved() { // check GUI elements for rollover if (gui.mouseMoved()) scene.setUpdateView(true); scene.mouseMoved(); } void mousePressed() { scene.mousePressed(); } void mouseReleased() { gui.mouseReleased(); scene.mouseReleased(); } void drawGrid(PGraphics pg, ScalarField scalars) { int dx = scalars.xRes / 5, dz = scalars.zRes / 5; float x, z, xSlope, zSlope; xSlope = (scalars.xMax - scalars.xMin) / (dx - 1); zSlope = (scalars.zMax - scalars.zMin) / (dz - 1); pg.stroke(color(102, 102, 51)); pg.beginShape(LINES); for (int i=0; i 0) { // Get screen coords of hot spots in transformed view float hotScale = 3.5 / max(hy.xRes, hy.yRes , hy.zRes); float[] xHot = new float[hy.numHot]; float[] yHot = new float[hy.numHot]; for (int i = 0; i < hy.numHot; ++i) { xHot[i] = pg.screenX(hy.xHot[i], hy.yHot[i], hy.zHot[i]); yHot[i] = pg.screenY(hy.xHot[i], hy.yHot[i], hy.zHot[i]); } // restore view and draw scene.restoreView(pg); pg.noStroke(); pg.textureMode(NORMALIZED); for (int i = 0; i < hy.numHot; ++i) { float currScale = scene.getScale(); pg.beginShape(); pg.texture(glow); pg.vertex(xHot[i]-currScale*hotScale, yHot[i]-currScale*hotScale, 0, 0); pg.vertex(xHot[i]+currScale*hotScale, yHot[i]-currScale*hotScale, 1, 0); pg.vertex(xHot[i]+currScale*hotScale, yHot[i]+currScale*hotScale, 1, 1); pg.vertex(xHot[i]-currScale*hotScale, yHot[i]+currScale*hotScale, 0, 1); pg.endShape(); } scene.transformView(pg); } } } class NWidget extends IntegerUpDownWidget { NWidget(int xx, int yy, int xx2, int yy2) { super("N", N, 1, NMin, NMax, xx, yy, xx2, yy2); setColors(color(204, 255, 204),color(102, 204, 102)); } float handle() { int oldv, newv; oldv = int(value); newv = int(super.handle()); if ( (newv != oldv) && validateNLM(newv, L, M)) { value = newv; N = newv; newHydrogen(); } else { value = oldv; } return value; } void sync() { setValue(N); setMin(NMin); setMax(NMax); } } class LWidget extends IntegerUpDownWidget { LWidget(int xx, int yy, int xx2, int yy2) { super("L", L, 1, LMin, LMax, xx, yy, xx2, yy2); //setColors(color(204, 255, 230),color(102, 204, 153)); setColors(color(204, 255, 255),color(102, 204, 204)); } float handle() { int oldv, newv; oldv = int(value); newv = int(super.handle()); if ( (newv != oldv) && validateNLM(N, newv, M)) { value = newv; L = newv; newHydrogen(); } else { value = oldv; } return value; } void sync() { setValue(L); setMin(LMin); setMax(LMax); } } class MWidget extends IntegerUpDownWidget { MWidget(int xx, int yy, int xx2, int yy2) { super("M", M, 1, MMin, MMax, xx, yy, xx2, yy2); //setColors(color(204, 255, 255),color(102, 204, 204)); setColors(color(204, 230, 255),color(102, 153, 204)); } float handle() { int oldv, newv; oldv = int(value); newv = int(super.handle()); if ( (newv != oldv) && validateNLM(N, L, newv)) { value = newv; M = newv; newHydrogen(); } else { value = oldv; } return value; } void sync() { setValue(M); setMin(MMin); setMax(MMax); } } class IsoWidget extends FloatDoubleUpDownWidget { //IsoSurface surface; IsoWidget(int xx, int yy, int xx2, int yy2) { super("Iso", surface.isoVal, surface.isoStep, 10*surface.isoStep, surface.scalars.scalMin, surface.scalars.scalMax, xx, yy, xx2, yy2); } float handle() { value = surface.isoVal = super.handle(); surface.update(); scene.setUpdateView(true); return value; } void sync() { setValue(surface.isoVal); setMin(surface.scalars.scalMin); setMax(surface.scalars.scalMax); setStep(surface.isoStep); setBigStep(10*surface.isoStep); } } class HeatWidget extends FloatDoubleUpDownWidget { //IsoSurface surface; HeatWidget(int xx, int yy, int xx2, int yy2) { super("Minimum Heat", hy.heat, 0.01, 0.05, 0.8, 1.0, xx, yy, xx2, yy2); setColors(color(255, 204, 204),color(204, 102, 102)); setNumFormat(new DecimalFormat("0.00")); } float handle() { value = hy.heat = super.handle(); hy.findHotSpots(); scene.setUpdateView(true); return value; } void sync() { setValue(hy.heat); setMin(0.8); setMax(1.0); setStep(0.01); setBigStep(0.05); } } class ResWidget extends IntegerDoubleUpDownWidget { ResWidget(int xx, int yy, int xx2, int yy2) { super("Resolution", Res, ResStep, ResBigStep, ResMin, ResMax, xx, yy, xx2, yy2); setColors(color(255, 255, 204),color(204, 204, 102)); } float handle() { int oldv, newv; oldv = int(value); newv = int(super.handle()); if (newv != oldv) { value = newv; Res = newv; newHydrogen(); } else { value = oldv; } return value; } void sync() { setValue(Res); } } void newHydrogen() { HydrogenProgress hyNew = new HydrogenProgress(Res, N, L, M); updateMinMaxNLM(); if (hy != null) { hyNew.heat = hy.heat; hy.destroy(); } hy = hyNew; reswidget.sync(); nwidget.sync(); lwidget.sync(); mwidget.sync(); heatwidget.sync(); newIsosurface(); } void newIsosurface() { IsoSurface newSurface = new IsoSurface(hy); if (surface != null) { if ((surface.isoVal >= hy.scalMin) && (surface.isoVal <= hy.scalMax)) { newSurface.isoVal = surface.isoVal; } surface.destroy(); } surface = newSurface; surface.setColor(color(255,255,255)); isowidget.sync(); surface.update(); scene.setView(hy); scene.setUpdateView(true); } /* Copyright (c) 2010, Chris Want, Research Support Group, AICT, University of Alberta. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Contributors: Chris Want (University of Alberta), Jon Johansson (University of Alberta) */