checkpoint
[anneal.git] / src / edu / berkeley / qfat / Main.java
index 16cdbe1..96c5c06 100644 (file)
@@ -8,10 +8,17 @@ import java.util.*;
 import edu.berkeley.qfat.geom.*;
 import edu.berkeley.qfat.geom.Point;
 
+// TO DO:
+// - real anneal
+// - solve self-intersection problem
+// - get a better test model?
+
 // FIXME: re-orient goal (how?)
 
 public class Main extends MeshViewer {
 
+    public static int verts = 0;
+
     public static final Random random = new Random();
     
     /** magnification factor */
@@ -25,7 +32,7 @@ public class Main extends MeshViewer {
             Point p1 = new Point(stlf.coordArray[i+1].x * MAG, stlf.coordArray[i+1].y * MAG, stlf.coordArray[i+1].z * MAG);
             Point p2 = new Point(stlf.coordArray[i+2].x * MAG, stlf.coordArray[i+2].y * MAG, stlf.coordArray[i+2].z * MAG);
             Vec n  = new Vec(stlf.normArray[i/3].x * MAG, stlf.normArray[i/3].y  * MAG, stlf.normArray[i/3].z * MAG);
-            Mesh.T t  = goal.newT(p0, p1, p2, n);
+            Mesh.T t  = goal.newT(p0, p1, p2, n, 0);
         }
 
         // rotate to align major axis -- this probably needs to be done by a human.
@@ -35,41 +42,49 @@ public class Main extends MeshViewer {
         float goal_height = goal.diagonal().dot(new Vec(0, 1, 0));
         float goal_depth  = goal.diagonal().dot(new Vec(0, 0, 1));
 
+        /*
         float width  = (float)0.6;
         float height = (float)0.08;
         float depth  = (float)0.3;
+        */
+        float width  = (float)0.6;
+        float depth  = (float)0.08;
+        float height = (float)0.3;
+
+        float rshift = width/2;
+        float lshift = -(width/2);
+
         translations = new Matrix[] {
 
-            new Matrix(new Vec(-(width/2),  height,    0)),
-            new Matrix(new Vec( (width/2),  height,    0)),
-            new Matrix(new Vec(-(width/2), -height,    0)),
-            new Matrix(new Vec( (width/2), -height,    0)),
-            new Matrix(new Vec(-(width/2),       0,  depth)),
-            new Matrix(new Vec( (width/2),       0,  depth)),
-            new Matrix(new Vec(-(width/2),       0, -depth)),
-            new Matrix(new Vec( (width/2),       0, -depth)),
+            new Matrix(new Vec(lshift,  depth,    0)),
+            new Matrix(new Vec(rshift,  depth,    0)),
+            new Matrix(new Vec(lshift, -depth,    0)),
+            new Matrix(new Vec(rshift, -depth,    0)),
+            new Matrix(new Vec(lshift,       0,  height)),
+            new Matrix(new Vec(rshift,       0,  height)),
+            new Matrix(new Vec(lshift,       0, -height)),
+            new Matrix(new Vec(rshift,       0, -height)),
 
             new Matrix(new Vec( width,           0,    0)),
             new Matrix(new Vec(-width,           0,    0)),
-            /*
-            new Matrix(new Vec(     0,           0,    depth)),
-            new Matrix(new Vec(     0,           0,   -depth)),
-            */
+
+            new Matrix(new Vec(     0,           0,    height)),
+            new Matrix(new Vec(     0,           0,   -height)),
         };
 
 
-        Point ltf = new Point(-(width/2),  (height/2),  (depth/2));
-        Point mtf = new Point( 0.0,        (height/2),  (depth/2));
-        Point rtf = new Point( (width/2),  (height/2),  (depth/2));
-        Point ltn = new Point(-(width/2),  (height/2), -(depth/2));
-        Point mtn = new Point( 0.0,        (height/2), -(depth/2));
-        Point rtn = new Point( (width/2),  (height/2), -(depth/2));
-        Point lbf = new Point(-(width/2), -(height/2),  (depth/2));
-        Point mbf = new Point( 0.0,       -(height/2),  (depth/2));
-        Point rbf = new Point( (width/2), -(height/2),  (depth/2));
-        Point lbn = new Point(-(width/2), -(height/2), -(depth/2));
-        Point mbn = new Point( 0.0,       -(height/2), -(depth/2));
-        Point rbn = new Point( (width/2), -(height/2), -(depth/2));
+        Point ltf = new Point(lshift,  (depth/2),  (height/2));
+        Point mtf = new Point( 0.0,        (depth/2),  (height/2));
+        Point rtf = new Point(rshift,  (depth/2),  (height/2));
+        Point ltn = new Point(lshift,  (depth/2), -(height/2));
+        Point mtn = new Point( 0.0,        (depth/2), -(height/2));
+        Point rtn = new Point(rshift,  (depth/2), -(height/2));
+        Point lbf = new Point(lshift, -(depth/2),  (height/2));
+        Point mbf = new Point( 0.0,       -(depth/2),  (height/2));
+        Point rbf = new Point(rshift, -(depth/2),  (height/2));
+        Point lbn = new Point(lshift, -(depth/2), -(height/2));
+        Point mbn = new Point( 0.0,       -(depth/2), -(height/2));
+        Point rbn = new Point(rshift, -(depth/2), -(height/2));
         
         Point[] points = new Point[] {
             ltf,
@@ -88,36 +103,36 @@ public class Main extends MeshViewer {
 
 
         // top
-        tile.newT(ltf, mtf, mtn, null);
-        tile.newT(mtn, ltn, ltf, null);
-        tile.newT(mtf, rtf, rtn, null);
-        tile.newT(rtn, mtn, mtf, null);
+        tile.newT(ltf, mtf, mtn, null, 1);
+        tile.newT(mtn, ltn, ltf, null, 1);
+        tile.newT(mtf, rtf, rtn, null, 1);
+        tile.newT(rtn, mtn, mtf, null, 1);
 
         // bottom (swap normals)
-        tile.newT(mbf, lbf, mbn, null);
-        tile.newT(lbn, mbn, lbf, null);
-        tile.newT(rbf, mbf, rbn, null);
-        tile.newT(mbn, rbn, mbf, null);
+        tile.newT(mbf, lbf, mbn, null, 2);
+        tile.newT(lbn, mbn, lbf, null, 2);
+        tile.newT(rbf, mbf, rbn, null, 2);
+        tile.newT(mbn, rbn, mbf, null, 2);
         
         // left
-        tile.newT(ltf, ltn, lbn, null);
-        tile.newT(lbn, lbf, ltf, null);
+        tile.newT(ltf, ltn, lbn, null, 3);
+        tile.newT(lbn, lbf, ltf, null, 3);
 
         // right (swap normals)
-        tile.newT(rtn, rtf, rbn, null);
-        tile.newT(rbf, rbn, rtf, null);
+        tile.newT(rtn, rtf, rbn, null, 4);
+        tile.newT(rbf, rbn, rtf, null, 4);
 
         // front
-        tile.newT(ltn, mtn, mbn, null);
-        tile.newT(ltn, mbn, lbn, null);
-        tile.newT(mtn, rtn, rbn, null);
-        tile.newT(mtn, rbn, mbn, null);
+        tile.newT(ltn, mtn, mbn, null, 5);
+        tile.newT(ltn, mbn, lbn, null, 5);
+        tile.newT(mtn, rtn, rbn, null, 5);
+        tile.newT(mtn, rbn, mbn, null, 5);
 
         // back
-        tile.newT(mtf, ltf, mbf, null);
-        tile.newT(mbf, ltf, lbf, null);
-        tile.newT(rtf, mtf, rbf, null);
-        tile.newT(rbf, mtf, mbf, null);
+        tile.newT(mtf, ltf, mbf, null, 6);
+        tile.newT(mbf, ltf, lbf, null, 6);
+        tile.newT(rtf, mtf, rbf, null, 6);
+        tile.newT(rbf, mtf, mbf, null, 6);
 
         for(Matrix m : translations) {
             for(Mesh.T t1 : tile) {
@@ -127,23 +142,23 @@ public class Main extends MeshViewer {
                     if ((t1.v1().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
                         (t1.v2().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
                         (t1.v3().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
-                        t1.e1().bind(t2.e3().pair);
-                        t1.e2().bind(t2.e2().pair);
-                        t1.e3().bind(t2.e1().pair);
+                        t1.e1().bindEdge(t2.e3());
+                        t1.e2().bindEdge(t2.e2());
+                        t1.e3().bindEdge(t2.e1());
                     }
                     if ((t1.v2().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
                         (t1.v3().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
                         (t1.v1().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
-                        t1.e2().bind(t2.e3().pair);
-                        t1.e3().bind(t2.e2().pair);
-                        t1.e1().bind(t2.e1().pair);
+                        t1.e2().bindEdge(t2.e3());
+                        t1.e3().bindEdge(t2.e2());
+                        t1.e1().bindEdge(t2.e1());
                     }
                     if ((t1.v3().p.times(m).minus(t2.v1().p).mag() < Mesh.EPSILON) &&
                         (t1.v1().p.times(m).minus(t2.v3().p).mag() < Mesh.EPSILON) &&
                         (t1.v2().p.times(m).minus(t2.v2().p).mag() < Mesh.EPSILON)) {
-                        t1.e3().bind(t2.e3().pair);
-                        t1.e1().bind(t2.e2().pair);
-                        t1.e2().bind(t2.e1().pair);
+                        t1.e3().bindEdge(t2.e3());
+                        t1.e1().bindEdge(t2.e2());
+                        t1.e2().bindEdge(t2.e1());
                     }
                 }
             }
@@ -178,29 +193,33 @@ public class Main extends MeshViewer {
     }
 
     public synchronized void breakit() {
-        if (verts > 50) return;
+        if (verts > 800) return;
+        //while(verts < 800) {
         PriorityQueue<Mesh.E> es = new PriorityQueue<Mesh.E>();
         for(Mesh.E e : tile.edges()) es.add(e);
-        for(int i=0; i<10; i++) {
+        for(int i=0; i<40; i++) {
             Mesh.E e = es.poll();
             verts++;
-            System.out.println("shatter " + e);
+            //System.out.println("shatter " + e);
             e.shatter();
             tile.rebindPoints();
         }
+        //}
     }
 
     public synchronized void rand(double temperature, Mesh.Vert p) {
         double tile_score = tile.score();
         double goal_score = goal.score();
-        p.rescore();
+        p.reComputeError();
+
 
         Vec v = new Vec((random.nextFloat() - (float)0.5) / 1000,
                         (random.nextFloat() - (float)0.5) / 1000,
                         (random.nextFloat() - (float)0.5) / 1000);
-        //Matrix inv = p.errorQuadric();
-        //Vec v = new Vec(inv.d, inv.h, inv.l).norm().times(1/(float)1000);
-
+        /*
+        Matrix inv = p.errorQuadric();
+        Vec v = new Vec(inv.d, inv.h, inv.l).norm().times(1/(float)1000);
+        */
         boolean good = p.move(v);
         double new_tile_score = tile.score();
         double new_goal_score = goal.score();
@@ -210,7 +229,6 @@ public class Main extends MeshViewer {
         //double swapProbability = Math.exp((-1 * delta) / temperature);
         //boolean doSwap = Math.random() < swapProbability;
         boolean doSwap = good && (tile_delta <= 0 && goal_delta <= 0);
-
         if (doSwap) {
             tile_score = new_tile_score;
             goal_score = new_goal_score;
@@ -220,8 +238,6 @@ public class Main extends MeshViewer {
         }
     }
 
-    public static int verts = 0;
-
     public void anneal() throws Exception {
         int verts = 0;
         while(true) {
@@ -231,13 +247,15 @@ public class Main extends MeshViewer {
                 repaint();
                 for(Mesh.Vert v : hs) rand(10,v);
             }
+            tile.rebuildPointSet();
+            repaint();
             breakit();
             repaint();
-            goal.unscore();
+            goal.unApplyQuadricToNeighborAll();
             repaint();
             tile.recomputeAllFundamentalQuadrics();
             repaint();
-            goal.rescore();
+            goal.applyQuadricToNeighborAll();
        }
     }
 
@@ -248,4 +266,5 @@ public class Main extends MeshViewer {
         Main main = new Main(stlf, f);
         main.anneal();
     }
+
 }
\ No newline at end of file