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();*/ }
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.01;
+ //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);
// 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);
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;
}
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();
}
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);
}
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))
if (e==this) continue;
p1.bindTo(getBindingMatrix(e), e.p1);
p2.bindTo(getBindingMatrix(e), e.p2);
+ e.p1.setConstraint(getConstraint());
+ e.p2.setConstraint(getConstraint());
}
}
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();
e.p2.getE(mid).pair. bindTo(e.getBindingMatrix(firste), firstq);
e.p2.getE(mid).pair.pair.bindTo(e.getBindingMatrix(firste), firstq.pair);
}
+ if (firste.bindingGroup != null)
+ firste.bindingGroup.setKrank(bindingGroup.krank);
+ if (firstq.bindingGroup != null)
+ firstq.bindingGroup.setKrank(bindingGroup.krank);
return null;
}
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 */