checkpoint
[anneal.git] / src / edu / berkeley / qfat / Mesh.java
index 0d7a96a..57eda26 100644 (file)
@@ -52,6 +52,7 @@ public class Mesh implements Iterable<Mesh.T> {
         ArrayList<Vertex> set = new ArrayList<Vertex>();
         for(Vertex v : vertices) set.add(v);
         for(Vertex v : set) v.transform(m.times(v.p), true, null);
+        for(Vertex v : set) v.goodp = v.p;
     }
 
     public void rebuild() { /*vertices.rebuild();*/ }
@@ -89,6 +90,7 @@ public class Mesh implements Iterable<Mesh.T> {
         private Vertex(Point p) {
             this.p = p;
             this.goodp = p;
+            this.oldp = p;
             if (vertices.get(p) != null) throw new Error();
             vertices.add(this);
         }
@@ -147,15 +149,20 @@ public class Mesh implements Iterable<Mesh.T> {
 
             if (!immutableVertices && quadric_count == 0)
                 nerror *= 2;
-                
+            //System.out.println(nerror);
             for(E e = this.e; e!=null; e=e.pair.next==this.e?null:e.pair.next) {
-                double ang = Math.abs(e.dihedralAngle());
+                double ang = e.dihedralAngle();
                 if (ang > Math.PI) throw new Error();
-                float minangle = (float)(Math.PI * 0.8);
-                if (ang > minangle) nerror += (ang - minangle);
+                if (ang < -Math.PI) throw new Error();
+                //float minangle = (float)(Math.PI * 0.8);
+                nerror += ((ang / Math.PI)*(ang/Math.PI)) * e.length() * 0.05;
+                //System.out.println(((ang / Math.PI)*(ang/Math.PI)) * 0.000001);
+                //if (ang > minangle) nerror += (ang - minangle);
+                /*
                 if (e.t.aspect() < 0.2) {
                     nerror += (0.2-e.t.aspect()) * 10;
                 }
+                */
             }
 
             setError(nerror);
@@ -169,6 +176,7 @@ 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);
@@ -177,7 +185,7 @@ public class Mesh implements Iterable<Mesh.T> {
             if (bindingGroup != null) {
                 Matrix m2 = null;
                 for(int i=0; i<20 && !m.equals(m2); i++) {
-                    m2 = m.times(bindingGroup.krank);
+                    m2 = m.times(getConstraint());
                     //System.out.println(m.minus(m2));
                 }
                 if (!m.equals(m2)) return true;
@@ -192,12 +200,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 && !ignoreProblems) {
+                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;
         }
 
@@ -209,17 +223,18 @@ public class Mesh implements Iterable<Mesh.T> {
             unApplyQuadricToNeighbor();
 
 
+            boolean illegalbefore = illegal;
             illegal = false;
-            if (this.p.minus(newp).mag() > 0.1 && !ignoreProblems) {
             /*
+            if (this.p.minus(newp).mag() > 0.1 && !ignoreProblems) {
                 try {
                     throw new Exception(""+this.p.minus(newp).mag()+" "+ignoreProblems+" "+yes);
                 } catch(Exception e) {
                     e.printStackTrace();
                 }
-            */
                 illegal = true;
             }
+            */
 
             this.p = newp;
             reinsert();
@@ -230,15 +245,17 @@ public class Mesh implements Iterable<Mesh.T> {
             }
             for(E e = this.e; e!=null; e=e.pair.next==this.e?null:e.pair.next)
                 e.p2.quadricStale = true;
-            return !illegal;
+            return !illegal || (illegalbefore && illegal);
         } 
 
         public void checkLegality() {
+            /*
             for(E e = this.e; e!=null; e=e.pair.next==this.e?null:e.pair.next) {
                 if (Math.abs(e.dihedralAngle()) > (Math.PI * 0.9) ||
                     Math.abs(e.next.dihedralAngle()) > (Math.PI * 0.9)) illegal = true;
                 if (e.t.aspect() < 0.2) illegal = true;
             }
+            */
             if (!illegal) triangles.range(oldp, this.p, (Visitor<T>)this);
         }
 
@@ -331,6 +348,7 @@ public class Mesh implements Iterable<Mesh.T> {
             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))
@@ -393,6 +411,8 @@ public class Mesh implements Iterable<Mesh.T> {
                 if (e==this) continue;
                 p1.bindTo(getBindingMatrix(e), e.p1);
                 p2.bindTo(getBindingMatrix(e), e.p2);
+                e.p1.setConstraint(getConstraint());
+                e.p2.setConstraint(getConstraint());
             }
         }
 
@@ -411,12 +431,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();
@@ -432,6 +454,10 @@ public class Mesh implements Iterable<Mesh.T> {
                 e.p2.getE(mid).pair.     bindTo(e.getBindingMatrix(firste), firstq);
                 e.p2.getE(mid).pair.pair.bindTo(e.getBindingMatrix(firste), firstq.pair);
             }
+            /*
+            first.setConstraint(firste.getConstraint());
+            firstq.setConstraint(firste.getConstraint());
+            */
             return null;
         }
 
@@ -481,7 +507,12 @@ public class Mesh implements Iterable<Mesh.T> {
         public double dihedralAngle() {
             Vec v1 = t.norm().times(-1);
             Vec v2 = pair.t.norm().times(-1);
-            return Math.acos(v1.norm().dot(v2.norm()));
+            double prod = v1.norm().dot(v2.norm());
+            prod = Math.min(1,prod);
+            prod = Math.max(-1,prod);
+            double ret = Math.acos(prod);
+            if (Double.isNaN(ret)) throw new Error("nan! " + prod);
+            return ret;
         }
 
         /** angle between this half-edge and the next */