public static Random random = new Random();
private HashMap<P,P> ps = new HashMap<P,P>();
- private HashMap<E,E> es = new HashMap<E,E>();
private HashSet<T> ts = new HashSet<T>();
public Iterator<T> iterator() { return ts.iterator(); }
e23.makeAdjacent(e31);
e31.makeAdjacent(e12);
}
- T ret = e12.newT();
+ T ret = e12.makeT();
if (e12.t == null) throw new Error();
if (e23.t == null) throw new Error();
if (e31.t == null) throw new Error();
} while (p != this);
}
- /** the next edge going around this point [FIXME: direction] */
- /*
- public E nextE(E e) {
- //e.other(this); // sanity check
- if (e.t != null && e.t.nextE(e).has(this)) return e.t.nextE(e);
- if (e.pair.t != null && e.pair.t.nextE(e).has(this)) return e.pair.nextE(e.pair);
- throw new Error();
- }
- */
-
public P(float x, float y, float z) {
this.x = x; this.y = y; this.z = z;
}
Float.floatToIntBits(z);
}
public void glVertex(GL gl) { gl.glVertex3f(x, y, z); }
- //public String toString() { return ""+name; }
public String toString() { return "("+x+","+y+","+z+")"; }
public V norm() {
V norm = new V(0, 0, 0);
/** [UNIQUE] an edge */
public final class E {
public final P p1, p2;
- T t;
- E prev;
- E next;
- E pair;
+ T t; // triangle to our "left"
+ E prev; // previous half-edge
+ E next; // next half-edge
+ E pair; // partner half-edge
private void sync() {
this.prev.next = this;
if (this.p1.e == null) this.p1.e = this;
}
- public T newT() {
- if (t==null) t = new T(this);
- return t;
- }
+ public T makeT() { return t==null ? (t = new T(this)) : t; }
/** angle between this half-edge and the next */
public double angle() {
public boolean has(P p) { return p==p1 || p==p2; }
public float length() { return p1.minus(p2).mag(); }
public String toString() { return p1+"->"+p2; }
- public int hashCode() { return p1.hashCode() ^ p2.hashCode(); }
- public boolean equals(Object o) { return o!=null && o instanceof E && this.p1 == ((E)o).p1 && this.p2 == ((E)o).p2; }
}
/** [UNIQUE] a triangle (face) */
E e3 = e2.next;
if (e1==e2 || e1==e3) throw new Error();
if (e3.next!=e1) throw new Error();
- if (e1.t!=null || e2.t!=null || e3.t!=null) throw new Error("non-manifold surface");
+ if (e1.t!=null || e2.t!=null || e3.t!=null)
+ throw new Error("non-manifold surface or disagreeing normals");
e1.t = this;
e1.next.t = this;
e1.next.next.t = this;
- /*
- if (e1.pair.t != null && e1.pair.t.nextP(e1) != prevP(e1)) throw new Error("normals disagree!");
- if (e2.pair.t != null && e2.pair.t.nextP(e2) != prevP(e2)) throw new Error("normals disagree!");
- if (e3.pair.t != null && e3.pair.t.nextP(e3) != prevP(e3)) throw new Error("normals disagree!");
- */
+
// FIXME: check for sealed/watertight surface once construction is complete (and infer normal(s)?)
int color = Math.abs(random.nextInt());
-
while(true) {
color = color % 4;
if (e1().pair.t != null && color == e1().pair.t.color) { color++; continue; }
this.color = color;
}
- /*
- public int hashCode() { return e1().hashCode() ^ e2().hashCode() ^ e3.hashCode(); }
- public boolean equals(Object o) {
- if (o==null || !(o instanceof T)) return false;
- T t = (T)o;
- return e1==t.e1() || e1==t.e2() || e1==t.e3();
- }
- */
public P p1() { return e1.p1; }
public P p2() { return e1.p2; }
public P p3() { return e1.next.p2; }
return Math.max(Math.max(e1().length(), e2().length()), e3().length()) / 2;
}
- /** returns the next triangle walking clockwise around the vertex normal */
- /*
- public T nextT(P p) { return prevE(p).pair.t; }
- public T prevT(P p) { return nextE(p).pair.t; }
-
- public E nextE(E e) {
- if (e==e2) return e1;
- if (e==e3) return e2;
- if (e==e1) return e3;
- throw new Error("triangle " + this + " does not own edge " + e);
- }
-
- public E prevE(E e) {
- if (e==e2) return e3;
- if (e==e3) return e1;
- if (e==e1) return e2;
- throw new Error("triangle " + this + " does not own edge " + e);
- }
- // edge "after" this point, moving clockwise around the normal
- public E nextE(P p) {
- if (p == e1.shared(e2)) return e1;
- else if (p == e2.shared(e3)) return e2;
- else if (p == e3.shared(e1)) return e3;
- else throw new Error("triangle " + this + " does not own point " + p);
- }
- // edge "before" this point, moving clockwise around the normal
- public E prevE(P p) {
- if (p == e1.shared(e2)) return e2;
- else if (p == e2.shared(e3)) return e3;
- else if (p == e3.shared(e1)) return e1;
- else throw new Error("triangle " + this + " does not own point " + p);
- }
- */
}
//mtf.move(geom.new V(0, (float)-0.05, (float)0.05));
mtf.move(geom.new V(0, (float)-0.05, (float)0.00));
- /*
+ /*
for(int i=0; i<stlf.coordArray.length; i+=3) {
Geom.P p0 = geom.newP(stlf.coordArray[i+0].x * MAG, stlf.coordArray[i+0].y * MAG, stlf.coordArray[i+0].z * MAG);
Geom.P p1 = geom.newP(stlf.coordArray[i+1].x * MAG, stlf.coordArray[i+1].y * MAG, stlf.coordArray[i+1].z * MAG);
Geom.P p2 = geom.newP(stlf.coordArray[i+2].x * MAG, stlf.coordArray[i+2].y * MAG, stlf.coordArray[i+2].z * MAG);
Geom.V n = geom.new V(stlf.normArray[i/3].x * MAG, stlf.normArray[i/3].y * MAG, stlf.normArray[i/3].z * MAG);
- Geom.T t = geom.newT(geom.newE(p0, p1), geom.newE(p1, p2), geom.newE(p2, p0), n);
+ Geom.T t = geom.newT(p0, p1, p2, n);
}
-
*/
+
}
/**