checkpoint
[anneal.git] / src / edu / berkeley / qfat / MeshViewer.java
1 package edu.berkeley.qfat;
2 import java.io.*;
3 import java.nio.*;
4 import java.awt.*;
5 import java.awt.event.*;
6 import javax.swing.*;
7 import javax.media.opengl.*;
8 import javax.media.opengl.glu.*;
9 import com.sun.opengl.util.*;
10 import java.util.*;
11 import edu.berkeley.qfat.geom.*;
12 import edu.berkeley.qfat.geom.Point;
13
14 public class MeshViewer extends Viewer {
15
16     public int whichNeighbor = 1;
17
18     public double temp;
19     public boolean tileon = true;
20     public boolean tilemeshon = false;
21     public boolean goalon = true;
22     public boolean anneal = false;
23     public boolean hillclimb = false;
24     public boolean neighbors = false;
25     public boolean neighborsWire = false;
26     public boolean neighborsWireOne = false;
27     public boolean errorNormals = false;
28
29     public boolean force = false;
30     public Matrix[] transforms;
31     public Mesh.Vertex[] points;
32     public int breaks = 0;
33
34     public int temps;
35     public int accepts;
36     public    int vertss;
37     protected HashSet<Mesh.T> safeTriangles = new HashSet<Mesh.T>();
38
39     public MeshViewer(JFrame f) { super(f); }
40
41     /**
42      * Take care of initialization here.
43      */
44     public void init(GLAutoDrawable gld) {
45         GL gl = gld.getGL();
46         gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
47         gl.glViewport(0, 0, 500, 300);
48         gl.glEnable(GL.GL_DEPTH_TEST);
49         gl.glClearDepth(1.0);
50         gl.glDepthFunc(GL.GL_LEQUAL);
51         gl.glMatrixMode(GL.GL_PROJECTION);
52         gl.glLoadIdentity();
53         gl.glMatrixMode(GL.GL_MODELVIEW);
54
55         float mat_specular[] = { 0.5f, 0.5f, 0.5f, 0.5f };
56         float mat_shininess[] = { 50.0f };
57         gl.glShadeModel(GL.GL_SMOOTH);
58         //gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, mat_specular, 0);
59         //gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat_specular, 0);  
60         //gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.3f, 0.3f, 0.3f, 0.3f }, 0);  
61         //gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, mat_shininess, 0);
62         gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 1.0f,    4.0f,  -10.0f, 0.0f }, 0);
63         gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, new float[] { -10.0f, 10.0f,   10.0f, 0.0f }, 0);
64         gl.glLightfv(GL.GL_LIGHT2, GL.GL_POSITION, new float[] { 10.0f, -10.0f,   10.0f, 0.0f }, 0);
65         gl.glLightfv(GL.GL_LIGHT3, GL.GL_POSITION, new float[] { 10.0f,  10.0f,  -10.0f, 0.0f }, 0);
66         gl.glLightfv(GL.GL_LIGHT4, GL.GL_POSITION, new float[] { -10.0f, 10.0f,  -10.0f, 0.0f }, 0);
67         gl.glLightfv(GL.GL_LIGHT5, GL.GL_POSITION, new float[] { 10.0f, -10.0f,  -10.0f, 0.0f }, 0);
68         gl.glEnable(GL.GL_LIGHTING);
69         gl.glEnable(GL.GL_LIGHT0);
70         /*
71         gl.glEnable(GL.GL_LIGHT1);
72         gl.glEnable(GL.GL_LIGHT2);
73         gl.glEnable(GL.GL_LIGHT3);
74         gl.glEnable(GL.GL_LIGHT4);
75         gl.glEnable(GL.GL_LIGHT5);
76         */
77         gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE);
78         gl.glEnable(GL.GL_COLOR_MATERIAL);
79
80         display(gld);
81     }
82
83     public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
84     public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { }
85     public void _display(GLAutoDrawable drawable, GL gl) {
86
87         if (transforms==null) return;
88         glcanvas.setSize(f.getWidth(), f.getHeight() - 100);
89         Graphics2D g = (Graphics2D)f.getGraphics();
90         g.setColor(Color.black);
91         g.fillRect(0, f.getHeight()-100, f.getWidth(), f.getHeight());
92         g.setColor(Color.red);
93         int top = f.getHeight()-70;
94         g.drawString("temperature: "+temps, 10, 30+top);
95         g.drawString("acceptance: "+accepts, 10, 50+top);
96         g.drawString("vertices: "+vertss, 10, 70+top);
97         g.fillRect(140, 25+top, temps, 10);
98         g.fillRect(140, 45+top, accepts, 10);
99         g.fillRect(140, 65+top, vertss, 10);
100
101         GLU glu = new GLU();
102         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
103         gl.glPointSize(5.0f);
104         gl.glLoadIdentity();
105         glu.gluPerspective(50, ((float)drawable.getWidth())/drawable.getHeight(), 0.5, 10);
106         glu.gluLookAt(0, 0, -((tz/10)-1), 0, 0, 0, 0, 1, 0);
107         gl.glRotatef(anglex/3, 0, 1, 0);
108         gl.glRotatef(-(angley/3), 1, 0, 0);
109
110
111         gl.glDisable(GL.GL_LIGHTING);
112         gl.glColor4f(1, 0, 0, 1);
113         gl.glBegin(GL.GL_LINES);
114         gl.glVertex3f(0,0,0);
115         gl.glVertex3f(.3f,0,0);
116         gl.glEnd();
117         gl.glColor4f(0, 1, 0, 1);
118         gl.glBegin(GL.GL_LINES);
119         gl.glVertex3f(0,0,0);
120         gl.glVertex3f(0,.3f,0);
121         gl.glEnd();
122         gl.glColor4f(0, 0, 1, 1);
123         gl.glBegin(GL.GL_LINES);
124         gl.glVertex3f(0,0,0);
125         gl.glVertex3f(0,0,.3f);
126         gl.glEnd();
127         gl.glEnable(GL.GL_LIGHTING);
128
129
130         gl.glBegin(GL.GL_TRIANGLES);
131         if (tileon)
132             draw(gl, true, safeTriangles);
133         if (tilemeshon)
134             draw(gl, false, safeTriangles);
135         gl.glEnd();
136
137         //draw(gl, false, tile);
138
139         gl.glBegin(GL.GL_TRIANGLES);
140         gl.glColor4f((float)0.5, (float)0.5, (float)0.5, (float)0.8);
141         if (goalon)
142             draw(gl, false, goal);
143         gl.glEnd();
144
145
146         int i = 0;
147         //gl.glDisable(GL.GL_DEPTH_TEST);
148         gl.glColor4f(1,1,1,1);
149         for(Matrix m : transforms) {
150             /*
151               gl.glColor4f(0, 1, 1, 1);
152               gl.glBegin(GL.GL_LINES);
153               new Point(0,0,0).glVertex(gl);
154               new Point(0,0,0).plus(m.getTranslationalComponent()).glVertex(gl);
155               gl.glEnd();
156               gl.glEnable(GL.GL_LIGHTING);
157             */
158             //if (v1.z==0 && v1.y==0) continue;
159             i++;
160             if (neighborsWireOne && i!=whichNeighbor) continue;
161             //if (i>4) continue;
162             /*
163             Point p = new Point(0, 0, 0).times(m);
164             Vec v = new Vec(p.x, p.y, p.z);
165             v = v.times((float)1.04);
166             gl.glTranslatef(v.x, v.y, v.z);
167             */
168             if (neighbors) draw(gl, true, safeTriangles, m);
169             else if (neighborsWire || neighborsWireOne) draw(gl, false, safeTriangles, m);
170             /*
171             gl.glTranslatef(-v.x, -v.y, -v.z);
172             */
173         }
174         //gl.glEnable(GL.GL_DEPTH_TEST);
175
176         gl.glDisable(GL.GL_LIGHTING);
177         gl.glShadeModel(GL.GL_FLAT);
178         if (closest != null) {
179             gl.glColor3f(1,1,1);
180             gl.glBegin(gl.GL_POINTS);
181             closest.getPoint().glVertex(gl);
182             gl.glEnd();
183             /*
184             Mesh.Vertex v2 = closest.hack(gl, getMouse());
185             gl.glBegin(GL.GL_LINES);        
186             closest.getPoint().glVertex(gl);                                                                                                  
187             if (v2 != null) v2.getPoint().glVertex(gl);
188             gl.glEnd();
189             */
190         }
191
192         gl.glFlush();
193         gl.glDrawBuffer(GL.GL_BACK);
194         gl.glReadBuffer( GL.GL_BACK );
195         gl.glPixelStorei( GL.GL_PACK_ALIGNMENT, 1);
196         gl.glFlush();
197         gl.glDisable(GL.GL_LIGHTING);
198         gl.glShadeModel(GL.GL_FLAT);
199
200         IntBuffer buf = ByteBuffer.allocateDirect(9*4*4).order(ByteOrder.nativeOrder()).asIntBuffer();
201         gl.glColor3f(0,0,0);
202         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
203         double dist = Double.MAX_VALUE;
204         if (clickPoint==null) closest = null;
205         synchronized(this) {
206             for(Mesh.T t : safeTriangles)
207                 t.glTriangle(gl, null);
208             for(Mesh.Vertex v : tile.vertices()) {
209                 Point p = v.getPoint();
210                 gl.glColor3f(1,1,1);
211                 gl.glBegin(gl.GL_POINTS);
212                 p.glVertex(gl);
213                 gl.glEnd();
214                 gl.glFlush();
215
216                 Point projected = projection.times(p);
217                 int x = (int)projected.x;
218                 int y = (int)projected.y;
219                 gl.glReadPixels(x-1, y-1, 3, 3, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, buf);
220
221                 boolean vis = false;
222                 for(int j=0; j<9*4; j++) vis |= buf.get(j)!=0;
223                 v.visible = vis;
224                 if (vis) {
225                     gl.glColor3f(0,0,0);
226                     gl.glBegin(gl.GL_POINTS);
227                     p.glVertex(gl);
228                     gl.glEnd();
229                     y = glcanvas.getHeight()-y;
230                     if (clickPoint==null) {
231                         if (closest==null || (x-mousex)*(x-mousex)+(y-mousey)*(y-mousey) < dist) {
232                             dist = (x-mousex)*(x-mousex)+(y-mousey)*(y-mousey);
233                             closest = v;
234                         }
235                     }
236                 }
237             }
238         }
239         gl.glShadeModel(GL.GL_SMOOTH);
240         gl.glEnable(GL.GL_LIGHTING);
241         gl.glDrawBuffer(GL.GL_FRONT);
242     }
243
244
245     private void draw(GL gl, boolean triangles, Iterable<Mesh.T> tris) { draw(gl, triangles, tris, Matrix.ONE); }
246     private void draw(GL gl, boolean triangles, Iterable<Mesh.T> tris, Matrix m) {
247         float red = 0.0f;
248         float green = 0.0f;
249         float blue = 0.0f;
250         synchronized(this) {
251         for(Mesh.T t : tris) {
252             if (red < 0.15) red = 1.0f;
253             if (green < 0.15) green = 1.0f;
254             if (blue < 0.15) blue = 1.0f;
255             red -= .09f;
256             green -= .12f;
257             blue -= .15f;
258
259             /*
260             if (triangles) switch(t.color) {
261                 case 0: gl.glColor4f((float)0.25, (float)0.25, (float)0.75, (float)0.3); break;
262                 case 1: gl.glColor4f((float)0.25, (float)0.75, (float)0.25, (float)0.3); break;
263                 case 2: gl.glColor4f((float)0.75, (float)0.25, (float)0.25, (float)0.3); break;
264                 case 3: gl.glColor4f((float)0.50, (float)0.50, (float)0.50, (float)0.3); break;
265                 case 4: gl.glColor4f((float)0.25, (float)0.75, (float)0.75, (float)0.3); break;
266                 case 5: gl.glColor4f((float)0.25, (float)0.75, (float)0.75, (float)0.3); break;
267                 case 6: gl.glColor4f((float)0.75, (float)0.25, (float)0.75, (float)0.3); break;
268             }
269             */
270             
271             gl.glColor4f((float)(0.25+(0.05*t.color)),
272                          (float)(0.25+(0.05*t.color)),
273                          (float)(0.75+(0.05*t.color)),
274                          (float)0.3); 
275             //if (t.v1().visible && t.v2().visible && t.v3().visible) continue;
276
277             /*
278             if (t.e1().pair.t==null) gl.glColor4f((float)0.25, (float)0.25, (float)0.75, (float)0.3);
279             else if (t.e2().pair.t==null) gl.glColor4f((float)0.25, (float)0.25, (float)0.75, (float)0.3);
280             else if (t.e3().pair.t==null) gl.glColor4f((float)0.25, (float)0.25, (float)0.75, (float)0.3);
281             else  gl.glColor4f((float)0.75, (float)0.25, (float)0.25, (float)0.3);
282             */
283             //gl.glBegin(GL.GL_LINES);
284
285             if (triangles) {
286                 t.glTriangle(gl, m);
287             } else {
288                 gl.glDisable(GL.GL_LIGHTING);
289                 gl.glBegin(GL.GL_LINES);
290                 gl.glColor3f(1, 1, 1);
291                 m.times(t.e1().p1.goodp).glVertex(gl);
292                 m.times(t.e1().p2.goodp).glVertex(gl);
293                 m.times(t.e2().p1.goodp).glVertex(gl);
294                 m.times(t.e2().p2.goodp).glVertex(gl);
295                 m.times(t.e3().p1.goodp).glVertex(gl);
296                 m.times(t.e3().p2.goodp).glVertex(gl);
297                 gl.glEnd();
298                 gl.glEnable(GL.GL_LIGHTING);
299             }
300
301             Point centroid = t.centroid();
302             gl.glBegin(GL.GL_LINES);
303             gl.glColor3f(1, 1, 1);
304
305             if (triangles && errorNormals)
306                 for(Mesh.Vertex p : new Mesh.Vertex[] { t.v1(), t.v2(), t.v3() }) {
307                     if (p.ok) {
308                         //gl.glDisable(GL.GL_LIGHTING);
309                         gl.glBegin(GL.GL_LINES);
310                         gl.glColor3f(1, 1, 1);
311                         p.p.glVertex(gl);
312                         p.p.plus(p.norm().times((float)p.error()*10)).glVertex(gl);
313                         //if (p.nearest_in_other_mesh != null) p.nearest_in_other_mesh.p.glVertex(gl);
314                         //tile.nearest(p).centroid().glVertex(gl);
315                         gl.glEnd();
316                         //gl.glEnable(GL.GL_LIGHTING);
317                     }
318                 }
319             gl.glEnd();
320             
321         }
322         }
323     }
324
325     public synchronized void dump() {
326         try {
327         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("dump.stl")));
328         pw.println("solid dump");
329         for(Mesh.T t : tile) {
330             Vec normal = t.norm();
331             pw.println("facet normal " + normal.x + " " + normal.y + " " + normal.z);
332             pw.println("  outer loop");
333             for(Mesh.Vertex v : new Mesh.Vertex[] { t.v1(), t.v2(), t.v3() }) {
334                 pw.println("    vertex " + v.p.x + " " + v.p.y + " " + v.p.z);
335             }
336             pw.println("  endloop");
337             pw.println("endfacet");
338         }
339         pw.println("endsolid dump");
340         pw.flush();
341         pw.close();
342         } catch (Exception e) { throw new RuntimeException(e); }
343     }
344
345     public void keyPressed(KeyEvent e)  {
346         super.keyPressed(e);
347         switch(e.getKeyCode()) {
348             case KeyEvent.VK_SPACE: breaks++; force = true; break;
349             case KeyEvent.VK_UP: temp = temp * 2; break;
350             case KeyEvent.VK_ENTER: temp = 10; break;
351             case KeyEvent.VK_LEFT: whichNeighbor--; break;
352             case KeyEvent.VK_RIGHT: whichNeighbor++; break;
353             case KeyEvent.VK_D: dump(); break;
354             case KeyEvent.VK_E: errorNormals = !errorNormals; break;
355             case KeyEvent.VK_A: hillclimb = false; anneal = !anneal; break;
356             case KeyEvent.VK_H: anneal = true; hillclimb = !hillclimb; break;
357             case KeyEvent.VK_N: neighbors = !neighbors; break;
358             case KeyEvent.VK_T: tileon = !tileon; break;
359             case KeyEvent.VK_G: goalon = !goalon; break;
360             case KeyEvent.VK_M: tilemeshon = !tilemeshon; break;
361         }
362     }
363
364 }