X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fqfat%2FMesh.java;h=8592d8aafc0aa7a274145c5b43846bb94f062686;hb=a3a659d0128908676e5793c7e59884b565c367cf;hp=fc1f8def2bc766949fe4faf7c073ac00cc50c7f0;hpb=63dc978f13754c01481004edd2427dd156424534;p=anneal.git diff --git a/src/edu/berkeley/qfat/Mesh.java b/src/edu/berkeley/qfat/Mesh.java index fc1f8de..8592d8a 100644 --- a/src/edu/berkeley/qfat/Mesh.java +++ b/src/edu/berkeley/qfat/Mesh.java @@ -11,17 +11,36 @@ import edu.berkeley.qfat.geom.Point; public class Mesh implements Iterable { - private KDTree kd = new KDTree(3); - public static float EPSILON = (float)0.0001; public static Random random = new Random(); - private HashMap ps = new HashMap(); - public HashSet es = new HashSet(); + private PointSet pointset = new PointSet(); + public Vert nearest(Point p) { return pointset.nearest(p); } + private HashMap verts = new HashMap(); + + public Iterable edges() { + return + new Iterable() { + public Iterator iterator() { + // HACK + HashSet hse = new HashSet(); + for(T t : Mesh.this) { + hse.add(t.e1()); + hse.add(t.e2()); + hse.add(t.e3()); + hse.add(t.e1().pair); + hse.add(t.e2().pair); + hse.add(t.e3().pair); + } + return hse.iterator(); + } }; + } public Iterator iterator() { - if (es.size() == 0) return new FaceIterator(); - return new FaceIterator(es.iterator().next().p1); + for(Vert v : pointset) + if (v.e != null && v.e.t != null) + return new FaceIterator(v); + return new FaceIterator(); } public Point origin() { return new Point(0, 0, 0); } @@ -59,59 +78,27 @@ public class Mesh implements Iterable { done.add(p); p.rescore(); } + /* for(T t : this) for(Vert p : new Vert[] { t.v1(), t.v2(), t.v3() }) p.kdremove(); - kd = new KDTree(3); + pointset.clear(); for(T t : this) for(Vert p : new Vert[] { t.v1(), t.v2(), t.v3() }) p.kdinsert(); + */ return (float)(dist/num); } public void transform(Matrix m) { ArrayList set = new ArrayList(); - set.addAll(ps.values()); + for (Vert v : pointset) + set.add(v); for(Vert v : set) v.transform(m); } - public Vec diagonal() { - float min_x = Float.MAX_VALUE; - float min_y = Float.MAX_VALUE; - float min_z = Float.MAX_VALUE; - float max_x = Float.MIN_VALUE; - float max_y = Float.MIN_VALUE; - float max_z = Float.MIN_VALUE; - for(Point p : ps.keySet()) { - if (p.x < min_x) min_x = p.x; - if (p.y < min_y) min_y = p.y; - if (p.z < min_z) min_z = p.z; - if (p.x > max_x) max_x = p.x; - if (p.y > max_y) max_y = p.y; - if (p.z > max_z) max_z = p.z; - } - return new Vec(max_x - min_x, max_y - min_y, max_z - min_z); - } - - public Point centroid() { - float min_x = Float.MAX_VALUE; - float min_y = Float.MAX_VALUE; - float min_z = Float.MAX_VALUE; - float max_x = Float.MIN_VALUE; - float max_y = Float.MIN_VALUE; - float max_z = Float.MIN_VALUE; - for(Point p : ps.keySet()) { - if (p.x < min_x) min_x = p.x; - if (p.y < min_y) min_y = p.y; - if (p.z < min_z) min_z = p.z; - if (p.x > max_x) max_x = p.x; - if (p.y > max_y) max_y = p.y; - if (p.z > max_z) max_z = p.z; - } - return new Point((float)(max_x + min_x)/2, - (float)(max_y + min_y)/2, - (float)(max_z + min_z)/2); - } + public Vec diagonal() { return pointset.diagonal(); } + public Point centroid() { return pointset.centroid(); } public float volume() { double total = 0; @@ -125,11 +112,6 @@ public class Mesh implements Iterable { return (float)total; } - public Vert nearest(Point p) { - Object[] results; - try { results = kd.nearest(new double[]{p.x,p.y,p.z},1); } catch (Exception e) { throw new Error(e); } - return (Vert)results[0]; - } public class BindingGroup { public HashSet es = new HashSet(); @@ -150,23 +132,29 @@ public class Mesh implements Iterable { } } - public Vert register(Point p) { Vert v = ps.get(p); return v==null ? new Vert(p) : v; } - public final class Vert { + public Vert register(Point p) { Vert v = verts.get(p); return v==null ? new Vert(p) : v; } + public final class Vert extends HasPoint { public Point p; + public Point getPoint() { return p; } private Vert(Point p) { this.p = p; - if (ps.get(p) != null) throw new Error(); - ps.put(this.p, this); + if (verts.get(p) != null) throw new Error(); + verts.put(this.p, this); + pointset.add(this); + } + public void reinsert() { + pointset.remove(this); + pointset.add(this); } public void kdremove() { if (!inserted) return; inserted = false; - try { kd.delete(new double[]{p.x,p.y,p.z}); } catch (Exception e) { } + pointset.remove(this); } public void kdinsert() { if (inserted) return; inserted = true; - try { kd.insert(new double[]{p.x,p.y,p.z},this); } catch (Exception e) { throw new Error(e); } + pointset.add(this); } public float score() { return oldscore; } @@ -198,7 +186,7 @@ public class Mesh implements Iterable { watch = score_against.nearest(po.p); // don't attract to vertices that face the other way - if (watch.norm().dot(norm()) < 0) { + if (watch.e == null || watch.norm().dot(norm()) < 0) { watch = null; } else { watch.watch_x += po.p.x; @@ -222,14 +210,16 @@ public class Mesh implements Iterable { // FIXME: screws up hashmap unscore(); try { - if (ps.get(this.p)==null) throw new Error(); - ps.remove(this.p); + if (verts.get(this.p)==null) throw new Error(); + verts.remove(this.p); + pointset.remove(this); float newx = m.a*p.x + m.b*p.y + m.c*p.z + m.d; float newy = m.e*p.x + m.f*p.y + m.g*p.z + m.h; float newz = m.i*p.x + m.j*p.y + m.k*p.z + m.l; this.p = new Point(newx, newy, newz); // FIXME: what if we move onto exactly where another point is? - ps.put(this.p,(Vert)this); + pointset.add(this); + verts.put(this.p,(Vert)this); } catch (Exception e) { throw new RuntimeException(e); } @@ -481,8 +471,6 @@ public class Mesh implements Iterable { pair.next = prev; if (p1.e == this) p1.e = prev.next; if (pair.p1.e == pair) pair.p1.e = pair.prev.next; - es.remove(this); - es.remove(pair); avgedge -= this.length(); avgedge -= pair.length(); numedges--; @@ -496,7 +484,6 @@ public class Mesh implements Iterable { if (this.next.p1 != p2) throw new Error(); if (this.prev.p2 != p1) throw new Error(); if (this.p1.e == null) this.p1.e = this; - es.add(this); if (!added) { added = true; numedges++; @@ -581,7 +568,7 @@ public class Mesh implements Iterable { if (norm != null) { Vec norm2 = p3.p.minus(p1.p).cross(p2.p.minus(p1.p)); float dot = norm.dot(norm2); - //if (Math.abs(dot) < EPointSILON) throw new Error("dot products within epsilon of each other: "+norm+" "+norm2); + //if (Math.abs(dot) < EPointSILON) throw new Error("dot products within evertsilon of each other: "+norm+" "+norm2); if (dot < 0) { Vert p = p1; p1=p2; p2 = p; } } E e12 = p1.makeE(p2);