package edu.berkeley.qfat;
import java.awt.*;
import java.util.*;
+import java.io.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
public boolean option_errorNormals = false;
public boolean option_selectable = true;
- public void render(GL gl, Matrix m) {
+ public void render(GL gl, Matrix m) { render(gl, m, false); }
+ public void render(GL gl, Matrix m, boolean noColor) {
if (option_wireframe) {
gl.glDisable(GL.GL_LIGHTING);
gl.glBegin(GL.GL_LINES);
- gl.glColor3f(1, 1, 1);
+ if (!noColor) gl.glColor3f(1, 1, 1);
for (T t : this) {
// fixme used to be .goodp
m.times(t.e1().v1.p).glVertex(gl);
return;
}
for(T t : this) {
- gl.glColor4f((float)(0.25+(0.05*t.color)),
- (float)(0.25+(0.05*t.color)),
- (float)(0.75+(0.05*t.color)),
- (float)0.3);
+ if (!noColor)
+ gl.glColor4f((float)(0.25+(0.05*t.color)),
+ (float)(0.25+(0.05*t.color)),
+ (float)(0.75+(0.05*t.color)),
+ (float)0.3);
/*
if (t.red) {
gl.glColor4f((float)(0.75+(0.05*t.color)),
for(Mesh.Vertex p : new Mesh.Vertex[] { t.v1(), t.v2(), t.v3() }) {
if (p.ok) {
gl.glBegin(GL.GL_LINES);
- gl.glColor3f(1, 1, 1);
+ if (!noColor)
+ gl.glColor3f(1, 1, 1);
p.p.glVertex(gl);
p.p.plus(p.norm().times((float)p.error()*10)).glVertex(gl);
gl.glEnd();
/** a vertex in the mesh */
- public final class Vertex extends HasQuadric implements Visitor {
+ public final class Vertex extends HasQuadric implements Visitor, HasPoint {
public void bindTo(Matrix bindingMatrix, HasBindingGroup other) {
bindTo(bindingMatrix, other, EPSILON);
}
+ public float getMaxX() { return getPoint().getMaxX(); }
+ public float getMinX() { return getPoint().getMinX(); }
+ public float getMaxY() { return getPoint().getMaxY(); }
+ public float getMinY() { return getPoint().getMinY(); }
+ public float getMaxZ() { return getPoint().getMaxZ(); }
+ public float getMinZ() { return getPoint().getMinZ(); }
public Point p, goodp;
public Point oldp;
Point pt = vv.plus(getPoint());
Point pp = pt;
pt = getBindingConstraint().getProjection(pp);
- if (pt==null) return false;
+ if (pt==null) {
+ System.out.println("constraint violation: " + getBindingConstraint());
+ return false;
+ }
System.out.println(pt.minus(pp).mag() + " " + getBindingConstraint());
for(Vertex v : (Iterable<Vertex>)getBoundPeers()) {
E pair; // partner half-edge
boolean shattered = false;
+
+ /** the "edge normal" -- average of the normals of the adjacent faces */
+ public Vec norm() {
+ return
+ (t==null || pair==null || pair.t==null)
+ ? null
+ : t.norm().plus(pair.t.norm()).norm();
+ }
+
+ public void glVertices(GL gl) {
+ Point p1 = v1.p;
+ Point p2 = v2.p;
+ if (t != null) {
+ p1 = p1.plus(t.centroid().minus(p1).times(0.1f));
+ p2 = p2.plus(t.centroid().minus(p2).times(0.1f));
+ p1 = p1.plus(norm().times(length() * 0.01f));
+ p2 = p2.plus(norm().times(length() * 0.01f));
+ }
+ p1.glVertex(gl);
+ p2.glVertex(gl);
+ if (t==null || pair.t==null) return;
+
+ Point atip = p2.minus(Point.ZERO).times(4).plus(p1.minus(Point.ZERO)).div(5).plus(Point.ZERO);
+ atip = (t.norm().plus(pair.t.norm())).norm().times(getSegment().length() / 5).plus(atip);
+ p2.glVertex(gl);
+ atip.glVertex(gl);
+ }
+
public boolean intersects(T t) { return t.intersects(v1.p, v2.p); }
public Segment getSegment() { return new Segment(v1.getPoint(), v2.getPoint()); }
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);
+ Matrix m = getBindingMatrix(eother);
+ if (next.isBoundTo(eother.pair.prev.pair) &&
+ !prev.isBoundTo(eother.pair.next.pair) &&
+ m.equalsModuloEpsilon(next.getBindingMatrix(eother.pair.prev.pair), EPSILON))
+ prev.bindEdge(next.getBindingMatrix(eother.pair.prev.pair), eother.pair.next.pair);
+ if (!next.isBoundTo(eother.pair.prev.pair) &&
+ prev.isBoundTo(eother.pair.next.pair) &&
+ m.equalsModuloEpsilon(prev.getBindingMatrix(eother.pair.next.pair), EPSILON))
+ next.bindEdge(prev.getBindingMatrix(eother.pair.next.pair), eother.pair.prev.pair);
+
+ //if (next.isBoundTo(eother.prev) && !prev.isBoundTo(eother.next))
+ //prev.bindTo(next.getBindingMatrix(eother.prev), eother.next);
+ //if (!next.isBoundTo(eother.prev) && prev.isBoundTo(eother.next))
+ //next.bindTo(prev.getBindingMatrix(eother.next), eother.prev);
+
+ if (next.isBoundTo(eother.next) &&
+ !prev.isBoundTo(eother.prev) &&
+ m.equalsModuloEpsilon(next.getBindingMatrix(eother.next), EPSILON))
+ prev.bindEdge(next.getBindingMatrix(eother.next), eother.prev);
+ if (!next.isBoundTo(eother.next) &&
+ prev.isBoundTo(eother.prev) &&
+ m.equalsModuloEpsilon(prev.getBindingMatrix(eother.prev), EPSILON))
+ next.bindEdge(prev.getBindingMatrix(eother.prev), eother.next);
- /*
- if (next.isBoundTo(eother.prev) && !prev.isBoundTo(eother.next))
- prev.bindTo(next.getBindingMatrix(eother.prev), eother.next);
- if (!next.isBoundTo(eother.prev) && prev.isBoundTo(eother.next))
- next.bindTo(prev.getBindingMatrix(eother.next), eother.prev);
- */
- 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);
}
}
public int compareTo(E e) {
return e.comparator() > comparator() ? 1 : -1;
}
- public void bindEdge(E e, Matrix m) {
- _bindEdge(e, m);
- pair._bindEdge(e.pair, m);
+ public void bindEdge(Matrix m, E e) {
+ bindEdge(e, m);
}
- public void _bindEdge(E e, Matrix m) {
- e = e.pair;
- /*
- //assumes edges are identical length at binding time
- Vec reflectionPlaneNormal = e.v2.p.minus(e.v1.p).norm();
- float a = reflectionPlaneNormal.x;
- float b = reflectionPlaneNormal.y;
- float c = reflectionPlaneNormal.z;
- Matrix reflectionMatrix =
- new Matrix( 1-2*a*a, -2*a*b, -2*a*c, 0,
- -2*a*b, 1-2*b*b, -2*b*c, 0,
- -2*a*c, -2*b*c, 1-2*c*c, 0,
- 0, 0, 0, 1);
- m = m.times(Matrix.translate(e.midpoint().minus(Point.ORIGIN))
- .times(reflectionMatrix)
- .times(Matrix.translate(Point.ORIGIN.minus(e.midpoint()))));
- System.out.println(reflectionPlaneNormal);
- System.out.println(" " + v1.p + " " + m.times(e.v1.p));
- System.out.println(" " + v2.p + " " + m.times(e.v2.p));
- */
+ public void bindEdge(E e, Matrix m) {
/*
- if (m.times(e.v1.p).minus(v1.p).mag() > EPSILON) throw new Error();
- if (m.times(e.v2.p).minus(v2.p).mag() > EPSILON) throw new Error();
+ for(E e_ : (Iterable<E>)e.getBoundPeers()) {
+ if (e.v1.getPoint().distance((e.getBindingMatrix(e_).times(e_.v1.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + e.v1.getPoint() + " " + e.getBindingMatrix(e_).times(e_.v1.getPoint()));
+ if (e.v2.getPoint().distance((e.getBindingMatrix(e_).times(e_.v2.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + e.v2.getPoint() + " " + e.getBindingMatrix(e_).times(e_.v2.getPoint()));
+ if (v1.getPoint().distance(m.times(e.getBindingMatrix(e_).times(e_.v1.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + v1.getPoint() + " " + m.times(e_.v1.getPoint()));
+ if (v2.getPoint().distance(m.times(e.getBindingMatrix(e_).times(e_.v2.getPoint()))) > 0.01f)
+ throw new RuntimeException("blah! " + v2.getPoint() + " " + m.times(e_.v2.getPoint()));
+ }
*/
- this.bindTo(m, e);
+ this.bindTo(m, e, EPSILON);
+ this.pair.bindTo(m, e.pair, EPSILON);
}
public void dobind() {
if (e==this) continue;
v1.bindTo(getBindingMatrix(e), e.v1);
v2.bindTo(getBindingMatrix(e), e.v2);
- /*
- e.v1.setConstraint(getAffineConstraint());
- e.v2.setConstraint(getAffineConstraint());
- */
}
}
public boolean destroyed() { return destroyed; }
public boolean shouldBeDrawn() {
-
- if (e1().bindingGroupSize() <= 1) return false;
- if (e2().bindingGroupSize() <= 1) return false;
- if (e3().bindingGroupSize() <= 1) return false;
-
+ if (e1().bindingGroupUnconstrained()) return false;
+ if (e2().bindingGroupUnconstrained()) return false;
+ if (e3().bindingGroupUnconstrained()) return false;
return true;
}
super.glVertices(gl, m);
}
}
+
+ // Dump /////////////////////////////////////////////////////////////////////////////
+
+ public void dump(OutputStream os) throws IOException {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
+ pw.println("solid dump");
+ for(Mesh.T t : this) {
+ Vec normal = t.norm();
+ pw.println("facet normal " + normal.x + " " + normal.y + " " + normal.z);
+ pw.println(" outer loop");
+ for(Mesh.Vertex v : new Mesh.Vertex[] { t.v1(), t.v2(), t.v3() }) {
+ pw.println(" vertex " + v.p.x + " " + v.p.y + " " + v.p.z);
+ }
+ pw.println(" endloop");
+ pw.println("endfacet");
+ }
+ pw.println("endsolid dump");
+ pw.flush();
+ }
+
}