checkpoint autogen tile
[anneal.git] / src / edu / berkeley / qfat / Mesh.java
index 774c7f9..1e83eee 100644 (file)
@@ -169,6 +169,20 @@ public class Mesh implements Iterable<Mesh.T> {
             //     t2' = t2.getMatrix(t1) * M * t1
             //     t1 =     t1.getMatrix(t2) * t2
             // M * t1 = M * t1.getMatrix(t2) * t2
+            if (bindingGroup!=null && this != bindingGroup.getMaster()) {
+                Matrix v = getBindingMatrix(bindingGroup.getMaster());
+                return ((Vertex)bindingGroup.getMaster()).move(v.inverse().times(m).times(v), ignoreProblems);
+            }
+
+            if (bindingGroup != null) {
+                Matrix m2 = null;
+                for(int i=0; i<20 && !m.equals(m2); i++) {
+                    m2 = m.times(bindingGroup.krank);
+                    //System.out.println(m.minus(m2));
+                }
+                if (!m.equals(m2)) return true;
+            }
+
             Point op = this.p;
             Point pt = m.times(this.p);
             for(Vertex v : (Iterable<Vertex>)getBoundPeers()) {
@@ -178,12 +192,18 @@ public class Mesh implements Iterable<Mesh.T> {
                     throw new Error(v.p+" "+pt2+"\n"+op+" "+pt+"\n"+v.getBindingMatrix(this));
                 if (Math.abs( v.p.minus(pt2).mag() / pt.minus(op).mag() ) < 1/5) throw new Error();
                 */
-                good &= v.transform(pt2,
-                                    ignoreProblems, v.getBindingMatrix(this));
+                good &= v.transform(pt2, ignoreProblems, v.getBindingMatrix(this));
+            }
+
+            if (!good) {
+                for(Vertex v : (Iterable<Vertex>)getBoundPeers()) 
+                    v.transform(v.oldp, true, null);
             }
 
             for(Vertex v : (Iterable<Vertex>)getBoundPeers())
                 v.recomputeFundamentalQuadricIfNeighborChanged();
+            for(Vertex v : (Iterable<Vertex>)getBoundPeers())
+                v.reComputeErrorAround();
             return good;
         }
 
@@ -312,13 +332,20 @@ public class Mesh implements Iterable<Mesh.T> {
                 (edu.berkeley.qfat.geom.BindingGroup<E>)newBindingGroup_;
             if (newBindingGroup==null) return;
             if (this==newBindingGroup.getMaster()) return;
-            for(E eother : (Iterable<E>)newBindingGroup) {
+            HashSet<E> nbg = new HashSet<E>();
+            for(E eother : (Iterable<E>)newBindingGroup) nbg.add(eother);
+            for(E eother : nbg) {
                 if (next==null || prev==null) continue;
                 if (eother.next==null || eother.prev==null) continue;
                 if (next.isBoundTo(eother.pair.prev.pair) && !prev.isBoundTo(eother.pair.next.pair))
                     prev.bindTo(next.getBindingMatrix(eother.pair.prev.pair), eother.pair.next.pair);
                 if (!next.isBoundTo(eother.pair.prev.pair) && prev.isBoundTo(eother.pair.next.pair))
                     next.bindTo(prev.getBindingMatrix(eother.pair.next.pair), eother.pair.prev.pair);
+
+                if (next.isBoundTo(eother.next) && !prev.isBoundTo(eother.prev))
+                    prev.bindTo(next.getBindingMatrix(eother.next), eother.prev);
+                if (!next.isBoundTo(eother.next) && prev.isBoundTo(eother.prev))
+                    next.bindTo(prev.getBindingMatrix(eother.prev), eother.next);
             }
 
         }
@@ -390,12 +417,14 @@ public class Mesh implements Iterable<Mesh.T> {
                 Point mid = e.midpoint();
                 Vertex r = e.next.p2;
                 Vertex l = e.pair.next.p2;
-                e.destroy();
-                e.pair.destroy();
-                newT(r.p, e.p1.p, mid,    null, 0);
-                newT(r.p, mid,    e.p2.p, null, 0);
-                newT(l.p, mid,    e.p1.p, null, 0);
-                newT(l.p, e.p2.p, mid,    null, 0);
+                if (!e.destroyed) {
+                    e.destroy();
+                    e.pair.destroy();
+                    newT(r.p, e.p1.p, mid,    null, 0);
+                    newT(r.p, mid,    e.p2.p, null, 0);
+                    newT(l.p, mid,    e.p1.p, null, 0);
+                    newT(l.p, e.p2.p, mid,    null, 0);
+                }
             }
             for(E e : (Iterable<E>)getBoundPeers()) {
                 Point mid = e.midpoint();
@@ -410,6 +439,10 @@ public class Mesh implements Iterable<Mesh.T> {
                 e.p1.getE(mid).pair.     bindTo(e.getBindingMatrix(firste), first.pair);
                 e.p2.getE(mid).pair.     bindTo(e.getBindingMatrix(firste), firstq);
                 e.p2.getE(mid).pair.pair.bindTo(e.getBindingMatrix(firste), firstq.pair);
+                first.bindingGroup.setKrank(e.bindingGroup.krank);
+                firstq.bindingGroup.setKrank(e.bindingGroup.krank);
+                first.pair.bindingGroup.setKrank(e.bindingGroup.krank);
+                firstq.pair.bindingGroup.setKrank(e.bindingGroup.krank);
             }
             return null;
         }
@@ -554,7 +587,22 @@ public class Mesh implements Iterable<Mesh.T> {
         if (v2 != null) return new E(v2.getFreeIncident(), p1).pair;
         return new E(p1, p2);
     }
+    public boolean coalesce = false;
+    private static float round(float f) {
+        return Math.round(f*1000)/1000f;
+    }
     public T newT(Point p1, Point p2, Point p3, Vec norm, int colorclass) {
+        if (coalesce) {
+
+            for(Vertex v : vertices) { if (p1.distance(v.p) < EPSILON) { p1 = v.p; break; } }
+            for(Vertex v : vertices) { if (p2.distance(v.p) < EPSILON) { p2 = v.p; break; } }
+            for(Vertex v : vertices) { if (p3.distance(v.p) < EPSILON) { p3 = v.p; break; } }
+            /*
+            p1 = new Point(round(p1.x), round(p1.y), round(p1.z));
+            p2 = new Point(round(p2.x), round(p2.y), round(p2.z));
+            p3 = new Point(round(p3.x), round(p3.y), round(p3.z));
+            */
+        }
         if (norm != null) {
             Vec norm2 = p3.minus(p1).cross(p2.minus(p1));
             float dot = norm.dot(norm2);
@@ -625,11 +673,11 @@ public class Mesh implements Iterable<Mesh.T> {
         public void reinsert() { triangles.remove(this); triangles.add(this); }
 
         public boolean shouldBeDrawn() {
-            /*
+
             if (e1().bindingGroupSize() <= 1) return false;
             if (e2().bindingGroupSize() <= 1) return false;
             if (e3().bindingGroupSize() <= 1) return false;
-            */
+
             return true;
         }