From 8cb2aceb7c2b140b70b9955f1a0a6f2524f2314e Mon Sep 17 00:00:00 2001 From: adam Date: Mon, 7 Jul 2008 13:41:38 -0700 Subject: [PATCH] checkpoint darcs-hash:20080707204138-5007d-081fd1526ff05363314d982e9dc3674f1e4e442c.gz --- src/edu/berkeley/qfat/InteractiveMeshViewer.java | 30 +- src/edu/berkeley/qfat/Main.java | 368 +++++++++++----------- src/edu/berkeley/qfat/Mesh.java | 21 ++ src/edu/berkeley/qfat/MeshViewer.java | 9 +- 4 files changed, 215 insertions(+), 213 deletions(-) diff --git a/src/edu/berkeley/qfat/InteractiveMeshViewer.java b/src/edu/berkeley/qfat/InteractiveMeshViewer.java index 068dc56..f87f257 100644 --- a/src/edu/berkeley/qfat/InteractiveMeshViewer.java +++ b/src/edu/berkeley/qfat/InteractiveMeshViewer.java @@ -66,26 +66,6 @@ public class InteractiveMeshViewer extends JPanel implements KeyListener { for(MeshViewer mv : mvs) mv.addMesh(this.goal); } - public synchronized void dump() { - try { - PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("dump.stl"))); - pw.println("solid dump"); - for(Mesh.T t : tile) { - Vec normal = t.norm(); - pw.println("facet normal " + normal.x + " " + normal.y + " " + normal.z); - pw.println(" outer loop"); - for(Mesh.Vertex v : new Mesh.Vertex[] { t.v1(), t.v2(), t.v3() }) { - pw.println(" vertex " + v.p.x + " " + v.p.y + " " + v.p.z); - } - pw.println(" endloop"); - pw.println("endfacet"); - } - pw.println("endsolid dump"); - pw.flush(); - pw.close(); - } catch (Exception e) { throw new RuntimeException(e); } - } - public int whichNeighbor = 1; public double temp; public boolean tileon = true; @@ -99,7 +79,6 @@ public class InteractiveMeshViewer extends JPanel implements KeyListener { public boolean errorNormals = false; public boolean force = false; - public Mesh.Vertex[] points; public int breaks = 0; public int temps; @@ -112,7 +91,6 @@ public class InteractiveMeshViewer extends JPanel implements KeyListener { //super.keyPressed(e); switch(e.getKeyCode()) { case KeyEvent.VK_SPACE: - System.err.println("hak"); synchronized(this) { tile.subdivide(); tile.rebindPoints(); @@ -123,7 +101,13 @@ public class InteractiveMeshViewer extends JPanel implements KeyListener { case KeyEvent.VK_ENTER: temp = 10; break; case KeyEvent.VK_N: whichNeighbor++; break; case KeyEvent.VK_RIGHT: whichNeighbor++; break; - case KeyEvent.VK_D: dump(); break; + case KeyEvent.VK_D: + try { + tile.dump(new FileOutputStream("dump.stl")); + } catch (Exception ee) { + throw new RuntimeException(ee); + } + break; case KeyEvent.VK_E: errorNormals = !errorNormals; break; case KeyEvent.VK_A: hillclimb = false; anneal = !anneal; break; case KeyEvent.VK_H: anneal = true; hillclimb = !hillclimb; break; diff --git a/src/edu/berkeley/qfat/Main.java b/src/edu/berkeley/qfat/Main.java index 237266b..b7df3d4 100644 --- a/src/edu/berkeley/qfat/Main.java +++ b/src/edu/berkeley/qfat/Main.java @@ -14,13 +14,6 @@ import edu.berkeley.qfat.geom.Polygon; // TO DO: // -// - Implement "real" constraints (plane, line, point) -// -// - Constrained surface subdivision -// - Edge.flip() gets us the triforce subdivision -// - Edge.delete() gets us the catmull-clark subdivision -// - Catmull-Clark: just don't move points if we can't. Need to average the influence of the points on a binding group. -// // - Ability to snap three views to orthgonal // - SLIDE UI // - left button -> crystal ball @@ -32,28 +25,11 @@ import edu.berkeley.qfat.geom.Polygon; // Editing: // - fracture edge, face // - change aspect ratio +// - translate, rotate goal mesh // - ability to select a point, rotate the model, then move the point // - when moving a vertex in one window, show that window's axes in all other windows // - -// TO DO: -// - real anneal -// - solve self-intersection problem -// - get a better test model? -// - symmetry constraints withing the tile -// - rotation matrices -// - overbinding results in forced equational constraints on the leader -// - shatter in invertd-triforce pattern brian mentioned -// - aspect ratio? non-uniform deformation? -// - rotational alignment - -// - movie-style user interface like -// http://www.coleran.com/markcoleranreell.html ? - -// - consider recasting the Shewchuk predicates in Java? -// http://www.cs.cmu.edu/afs/cs/project/quake/public/code/predicates.c - /* blender keys - middle mouse = option+click @@ -66,20 +42,39 @@ import edu.berkeley.qfat.geom.Polygon; wheel: zoom home: home view: take current angle, zoom to whole scnee 5 = ortho vs non-ortho - */ /* +Meshlab Notes: +Log console + - blend-shaded overlay? slick. +face/vertex count +rendering FPS +ability to not draw edges between faces - */ +three circumcircles showing crystal ball -- these don't get scaled +axes? -// FIXME: re-orient goal (how?) +drawing modes: + - bounding box + - vertices + - edges + - visible-edges + - flat with or without edges + - shaded with or without edges + * contrasting-faces -public class Main extends InteractiveMeshViewer { +quadric decimation? +show normals +show bounding box +show axes (big+fat) + */ + +public class Main extends InteractiveMeshViewer { public static int verts = 1; @@ -229,162 +224,6 @@ public class Main extends InteractiveMeshViewer { fixupGoal(); } - public void breakit() { - int oldverts = verts; - if (verts > 2000 && !force) return; - force = false; - System.out.println("doubling vertices."); - PriorityQueue es = new PriorityQueue(); - for(Mesh.T t : tile) { - es.add(t.e1()); - es.add(t.e2()); - es.add(t.e3()); - Thread.yield(); - repaint(); - } - for(int i=0; i 0) { - while (breaks>0) { - breaks--; - breakit(); - } - seek_upward = true; - continue; - } else if (acceptance > 0.96) gamma = 0.1f; - else if (acceptance > 0.9) gamma = 0.2f; - else if (acceptance > 0.8) gamma = 0.3f; - else if (acceptance > 0.6) gamma = 0.4f; - else if (acceptance > 0.3) gamma = 0.8f; - else if (acceptance > 0.15) gamma = 0.94f; - else if (acceptance > 0.10) gamma = 0.98f; - - else if (acceptance < 0.01) breaks++; - - if (seek_upward) { - if (acceptance > 0.25) seek_upward = false; - else gamma = 2-gamma; - } - - if (anneal) - temp = temp * gamma; - - - HashSet hs = new HashSet(); - for(Mesh.Vertex p : tile.vertices()) hs.add(p); - Mesh.Vertex[] pts = (Mesh.Vertex[])hs.toArray(new Mesh.Vertex[0]); - - int count = 0; - long then = System.currentTimeMillis(); - for(int i=0; i<300; i++) { - if (anneal) { - Mesh.Vertex v = pts[Math.abs(random.nextInt()) % pts.length]; - if (breaks>0) break; - if (!rand(temp,v)) { i--; continue; } - v.recomputeFundamentalQuadricIfStale(); - v.recomputeFundamentalQuadricIfNeighborChanged(); - count++; - } - Thread.yield(); - repaint(); - } - - System.out.println("temp="+temp + " ratio="+(Math.ceil(acceptance*100)) + " " + - "points_per_second=" + - (count*1000)/((double)(System.currentTimeMillis()-then))); - for(Mesh.Vertex p : goal.vertices()) { - p.quadricStale = true; - p.recomputeFundamentalQuadricIfNeighborChanged(); - } - } - } - } - - - public static void main(String[] s) throws Exception { - JFrame f = new JFrame(); - f.setLayout(new BorderLayout()); - Main main = new Main(f); - f.add(main, BorderLayout.CENTER); - f.setJMenuBar(main.new MyMenuBar()); - f.pack(); - f.show(); - f.setSize(900, 900); - f.doLayout(); - main.anneal(); - } public class MyMenuItem extends JMenuItem implements ActionListener { public MyMenuItem(String s) { @@ -1013,4 +852,163 @@ public class Main extends InteractiveMeshViewer { mthis.m, mthis.n, mthis.o, 1); } +////////////////////////////////////////////////////////////////////////////// + public void breakit() { + int oldverts = verts; + if (verts > 2000 && !force) return; + force = false; + System.out.println("doubling vertices."); + PriorityQueue es = new PriorityQueue(); + for(Mesh.T t : tile) { + es.add(t.e1()); + es.add(t.e2()); + es.add(t.e3()); + Thread.yield(); + repaint(); + } + for(int i=0; i 0) { + while (breaks>0) { + breaks--; + breakit(); + } + seek_upward = true; + continue; + } else if (acceptance > 0.96) gamma = 0.1f; + else if (acceptance > 0.9) gamma = 0.2f; + else if (acceptance > 0.8) gamma = 0.3f; + else if (acceptance > 0.6) gamma = 0.4f; + else if (acceptance > 0.3) gamma = 0.8f; + else if (acceptance > 0.15) gamma = 0.94f; + else if (acceptance > 0.10) gamma = 0.98f; + + else if (acceptance < 0.01) breaks++; + + if (seek_upward) { + if (acceptance > 0.25) seek_upward = false; + else gamma = 2-gamma; + } + + if (anneal) + temp = temp * gamma; + + + HashSet hs = new HashSet(); + for(Mesh.Vertex p : tile.vertices()) hs.add(p); + Mesh.Vertex[] pts = (Mesh.Vertex[])hs.toArray(new Mesh.Vertex[0]); + + int count = 0; + long then = System.currentTimeMillis(); + for(int i=0; i<300; i++) { + if (anneal) { + Mesh.Vertex v = pts[Math.abs(random.nextInt()) % pts.length]; + if (breaks>0) break; + if (!rand(temp,v)) { i--; continue; } + v.recomputeFundamentalQuadricIfStale(); + v.recomputeFundamentalQuadricIfNeighborChanged(); + count++; + } + Thread.yield(); + repaint(); + } + + System.out.println("temp="+temp + " ratio="+(Math.ceil(acceptance*100)) + " " + + "points_per_second=" + + (count*1000)/((double)(System.currentTimeMillis()-then))); + for(Mesh.Vertex p : goal.vertices()) { + p.quadricStale = true; + p.recomputeFundamentalQuadricIfNeighborChanged(); + } + } + } + } + + + public static void main(String[] s) throws Exception { + JFrame f = new JFrame(); + f.setLayout(new BorderLayout()); + Main main = new Main(f); + f.add(main, BorderLayout.CENTER); + f.setJMenuBar(main.new MyMenuBar()); + f.pack(); + f.show(); + f.setSize(900, 900); + f.doLayout(); + main.anneal(); + } + + } \ No newline at end of file diff --git a/src/edu/berkeley/qfat/Mesh.java b/src/edu/berkeley/qfat/Mesh.java index 926a5b7..cca7321 100644 --- a/src/edu/berkeley/qfat/Mesh.java +++ b/src/edu/berkeley/qfat/Mesh.java @@ -1,6 +1,7 @@ package edu.berkeley.qfat; import java.awt.*; import java.util.*; +import java.io.*; import java.awt.event.*; import javax.swing.*; import javax.media.opengl.*; @@ -1171,4 +1172,24 @@ public class Mesh implements Iterable { super.glVertices(gl, m); } } + + // Dump ///////////////////////////////////////////////////////////////////////////// + + public void dump(OutputStream os) throws IOException { + PrintWriter pw = new PrintWriter(new OutputStreamWriter(os)); + pw.println("solid dump"); + for(Mesh.T t : this) { + Vec normal = t.norm(); + pw.println("facet normal " + normal.x + " " + normal.y + " " + normal.z); + pw.println(" outer loop"); + for(Mesh.Vertex v : new Mesh.Vertex[] { t.v1(), t.v2(), t.v3() }) { + pw.println(" vertex " + v.p.x + " " + v.p.y + " " + v.p.z); + } + pw.println(" endloop"); + pw.println("endfacet"); + } + pw.println("endsolid dump"); + pw.flush(); + } + } diff --git a/src/edu/berkeley/qfat/MeshViewer.java b/src/edu/berkeley/qfat/MeshViewer.java index d02470c..d7481e5 100644 --- a/src/edu/berkeley/qfat/MeshViewer.java +++ b/src/edu/berkeley/qfat/MeshViewer.java @@ -12,11 +12,14 @@ import edu.berkeley.qfat.bind.*; import edu.berkeley.qfat.geom.*; import edu.berkeley.qfat.geom.Point; +/** + * A basic MeshViewer displays zero or more meshes to the user, in + * wireframe or shaded panels. + */ public class MeshViewer extends JPanel implements GLEventListener, MouseListener, MouseMotionListener, KeyListener, MouseWheelListener { Main main; - private float tz = 0; private float anglex = 0; private float angley = 0; @@ -55,10 +58,6 @@ public class MeshViewer extends JPanel implements GLEventListener, MouseListener float mat_specular[] = { 0.5f, 0.5f, 0.5f, 0.5f }; float mat_shininess[] = { 50.0f }; gl.glShadeModel(GL.GL_SMOOTH); - //gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, mat_specular, 0); - //gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat_specular, 0); - //gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.3f, 0.3f, 0.3f, 0.3f }, 0); - //gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, mat_shininess, 0); gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 1.0f, 4.0f, -10.0f, 0.0f }, 0); gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, new float[] { -10.0f, 10.0f, 10.0f, 0.0f }, 0); gl.glLightfv(GL.GL_LIGHT2, GL.GL_POSITION, new float[] { 10.0f, -10.0f, 10.0f, 0.0f }, 0); -- 1.7.10.4