X-Git-Url: http://git.megacz.com/?p=anneal.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fqfat%2FMain.java;h=910c35ca2eb950eb0c0e98aa965211e0f46e0e7c;hp=50f44c07064fdb2db7c4b25e126f7667eb5c0851;hb=64c6939d78acfa06e7bc380cb713e3800bf16be5;hpb=78303bd63882bf70a079f25874a8ff78fa0f652c diff --git a/src/edu/berkeley/qfat/Main.java b/src/edu/berkeley/qfat/Main.java index 50f44c0..910c35c 100644 --- a/src/edu/berkeley/qfat/Main.java +++ b/src/edu/berkeley/qfat/Main.java @@ -1,5 +1,6 @@ package edu.berkeley.qfat; import java.awt.*; +import java.io.*; import java.awt.event.*; import javax.swing.*; import javax.media.opengl.*; @@ -10,6 +11,31 @@ import edu.berkeley.qfat.geom.Point; import edu.berkeley.qfat.geom.Polygon; // TO DO: +// +// - Implement "real" constraints (plane, line, point) +// +// - Constrained surface subdivision +// - Edge.flip() gets us the triforce subdivision +// - Edge.delete() gets us the catmull-clark subdivision +// - Catmull-Clark: just don't move points if we can't. Need to average the influence of the points on a binding group. +// +// - Ability to snap three views to orthgonal +// - SLIDE UI +// - left button -> crystal ball +// - translate +// - rightbutton/mousewheel zoom +// - v+click to select vertex +// - show: constraints, bindings, faces +// +// Editing: +// - fracture edge, face +// - change aspect ratio +// - ability to select a point, rotate the model, then move the point +// - when moving a vertex in one window, show that window's axes in all other windows +// + + +// TO DO: // - real anneal // - solve self-intersection problem // - get a better test model? @@ -49,7 +75,9 @@ import edu.berkeley.qfat.geom.Polygon; // FIXME: re-orient goal (how?) -public class Main extends MeshViewer { +public class Main extends InteractiveMeshViewer { + + public static int verts = 1; @@ -65,20 +93,20 @@ public class Main extends MeshViewer { HashSet halfSpaces = new HashSet(); HashSet polygons = new HashSet(); for(Matrix m : matrices) { - Vec v = m.getTranslationalComponent(); - if (v.mag() < 0.0001) continue; - v = v.times(0.5f); - Point p = Point.ORIGIN.plus(v); - Vec v0 = v; - if (v.dot(Point.ORIGIN.minus(p)) < 0) v = v.times(-1); - - System.out.println(v); - HalfSpace hs = new HalfSpace(p, v.norm()); - halfSpaces.add(hs); - polygons.add(new Polygon(hs)); + Vec v = m.getTranslationalComponent(); + if (v.mag() < 0.0001) continue; + v = v.times(-1); + v = v.times(0.5f); + Point p = Point.ZERO.plus(v); + v = v.times(-1); + + //System.out.println(v); + HalfSpace hs = new HalfSpace(p, v.norm()); + halfSpaces.add(hs); + polygons.add(new Polygon(hs)); } for(Polygon p : polygons) { - System.out.println(p.plane.norm + " " + p.plane.dvalue); + System.out.println(p.plane.norm() + " " + p.plane.d); for(HalfSpace hs : halfSpaces) { if (p.plane==hs) continue; p = p.intersect(hs); @@ -104,13 +132,14 @@ public class Main extends MeshViewer { public void loadGoal(String file) { try { StlFile stlf = new StlFile(); - stlf.load(file); - goal = new Mesh(false); + InputStream res = this.getClass().getClassLoader().getResourceAsStream(file); + stlf.readBinaryFile(file, res); + setGoal(new Mesh(false)); for(int i=0; i 2000 && !force) return; + force = false; System.out.println("doubling vertices."); PriorityQueue es = new PriorityQueue(); for(Mesh.T t : tile) { @@ -213,6 +247,7 @@ public class Main extends MeshViewer { Thread.yield(); repaint(); } + System.out.println("now have " + verts + " vertices; max is 2000"); tile.rebindPoints(); } @@ -226,8 +261,7 @@ public class Main extends MeshViewer { Vec v = new Vec(random.nextFloat(), random.nextFloat(), random.nextFloat()); v = v.norm().times((random.nextFloat() - 0.5f) * max); Matrix m = Matrix.translate(v); - - boolean good = p.move(m, false); + boolean good = p.move(v, false); if (!good) { return false; } double new_tile_error = tile.error(); @@ -241,13 +275,19 @@ public class Main extends MeshViewer { //boolean doSwap = good && (tile_delta + goal_delta <= 0); //if (temp < 0.000001) doSwap = good && (tile_delta <= 0 && goal_delta <= 0); boolean doSwap = good && (Math.random() < swapProbability); + + // always move uphill if possible -- potential idea + if (tile_delta <= 0 && goal_delta <= 0 && good) doSwap = true; + if (hillclimb) + doSwap = tile_delta <= 0 && goal_delta <= 0 && good; + if (doSwap) { tile_error = new_tile_error; goal_error = new_goal_error; hits++; p.goodp = p.p; } else { - p.move(Matrix.translate(v.times(-1)), true); + p.move(v.times(-1), true); misses++; } p.reComputeErrorAround(); @@ -263,13 +303,8 @@ public class Main extends MeshViewer { boolean seek_upward = false; double acceptance = 1; while(true) { - synchronized(safeTriangles) { - safeTriangles.clear(); - for(Mesh.T t : tile) - if (t.shouldBeDrawn()) - safeTriangles.add(t); - } - if (!anneal) { repaint(); Thread.sleep(10); continue; } + synchronized(this) { + if (!anneal) { repaint(); Thread.sleep(10); continue; } double ratio = (hits+misses==0) ? 1 : (hits / (hits+misses)); hits = 0; @@ -293,7 +328,8 @@ public class Main extends MeshViewer { else if (acceptance > 0.3) gamma = 0.8f; else if (acceptance > 0.15) gamma = 0.94f; else if (acceptance > 0.10) gamma = 0.98f; - else { breaks++; } + + else if (acceptance < 0.01) breaks++; if (seek_upward) { if (acceptance > 0.25) seek_upward = false; @@ -330,13 +366,16 @@ public class Main extends MeshViewer { p.quadricStale = true; p.recomputeFundamentalQuadricIfNeighborChanged(); } + } } } public static void main(String[] s) throws Exception { JFrame f = new JFrame(); + f.setLayout(new BorderLayout()); Main main = new Main(f); + f.add(main, BorderLayout.CENTER); f.setJMenuBar(main.new MyMenuBar()); f.pack(); f.show(); @@ -352,16 +391,14 @@ public class Main extends MeshViewer { } public void actionPerformed(ActionEvent event) { synchronized(Main.this) { - synchronized(safeTriangles) { hit(); - } } } public void hit() {} } public void hexBrick(boolean offset, boolean rotated) { - tile = new Mesh(false); + setTile(new Mesh(false)); float width = (float)0.8; float depth = (float)0.08; float height = (float)0.4; @@ -484,9 +521,9 @@ public class Main extends MeshViewer { es.add(t.e3()); } for(Mesh.E e : es) { - if (e.p1.p.x == e.p2.p.x && e.p1.p.y == e.p2.p.y) continue; - if (e.p1.p.z == e.p2.p.z && e.p1.p.y == e.p2.p.y) continue; - if (e.p1.p.x == e.p2.p.x && e.p1.p.z == e.p2.p.z) continue; + if (e.v1.p.x == e.v2.p.x && e.v1.p.y == e.v2.p.y) continue; + if (e.v1.p.z == e.v2.p.z && e.v1.p.y == e.v2.p.y) continue; + if (e.v1.p.x == e.v2.p.x && e.v1.p.z == e.v2.p.z) continue; e.shatter(); } transforms = new Matrix[] { @@ -534,11 +571,38 @@ public class Main extends MeshViewer { hideMenu.add(new MyMenuItem("Show All Neighbors Wireframe") { public void hit() { neighborsWire = true; neighborsWireOne = false;}}); hideMenu.add(new MyMenuItem("Hide Neighbors") { public void hit() { neighborsWire = false; neighborsWireOne = false; neighbors = false; }}); + goalMenu.add(new MyMenuItem("Fish with face") { public void hit() { + loadGoal("face.stl"); + //goal.transform(Matrix.rotate(new Vec(0, 1, 0), (float)(Math.PI/2))); + goal.transform(Matrix.rotate(new Vec(0, 0, 1), (float)(Math.PI/2))); + //goal.transform(Matrix.scale(1, 2.2f, 1)); + float factor = (float)Math.pow(tile.volume() / goal.volume(), 1.0/3.0); + //factor = factor * 0.8f; + goal.transform(Matrix.scale(0.3f)); + //goal.transform(Matrix.rotate(new Vec(0,1,0), (float)(Math.PI*1/3))); + goal.transform(Matrix.rotate(new Vec(1,0,0), (float)(Math.PI*1/3))); + fixupGoal(true, false); + //goal.transform(Matrix.translate(new Vec(0.145f, 0, 0))); + fixupGoal(false, true); + }}); goalMenu.add(new MyMenuItem("Fish") { public void hit() { loadGoal("fish.stl"); //goal.transform(Matrix.rotate(new Vec(0, 1, 0), (float)(Math.PI/2))); goal.transform(Matrix.rotate(new Vec(0, 0, 1), (float)(Math.PI/2))); + goal.transform(Matrix.scale(1, 2.2f, 1)); + float factor = (float)Math.pow(tile.volume() / goal.volume(), 1.0/3.0); + factor = factor * 0.8f; + goal.transform(Matrix.scale(factor)); + fixupGoal(true, false); + //goal.transform(Matrix.translate(new Vec(0.145f, 0, 0))); + fixupGoal(false, true); + }}); + goalMenu.add(new MyMenuItem("Hammerhead Fish") { public void hit() { + loadGoal("fish.stl"); + goal.transform(Matrix.rotate(new Vec(0, 1, 0), (float)(Math.PI/2))); + goal.transform(Matrix.rotate(new Vec(0, 0, 1), (float)(3*Math.PI/2))); float factor = (float)Math.pow(tile.volume() / goal.volume(), 1.0/3.0); + factor *= 0.75f; goal.transform(Matrix.scale(factor)); fixupGoal(); }}); @@ -553,7 +617,7 @@ public class Main extends MeshViewer { goalMenu.add(new MyMenuItem("Torus") { public void hit() { loadGoal("torus.stl"); float factor = (float)Math.pow(tile.volume() / goal.volume(), 1.0/3.0); - goal.transform(Matrix.scale(factor/3.3f)); + goal.transform(Matrix.scale(factor/2.5f)); goal.transform(Matrix.rotate(new Vec(0, 1, 0), (float)(Math.PI/2))); fixupGoal(); }}); @@ -567,7 +631,7 @@ public class Main extends MeshViewer { hexBrick(false, true); }}); tileMenu.add(new MyMenuItem("Temp (do not use)") { public void hit() { - tile = new Mesh(false); + setTile(new Mesh(false)); float width = (float)0.8; float depth = (float)0.08; float height = (float)0.4; @@ -627,8 +691,8 @@ public class Main extends MeshViewer { }; fixupTile(); } }); - tileMenu.add(new MyMenuItem("Dense Packing (Hex)") { public void hit() { - tile = new Mesh(false); + tileMenu.add(new MyMenuItem("Dense Packing (hex)") { public void hit() { + setTile(new Mesh(false)); float width = (float)3.2; float depth = (float)0.32; float height = (float)1.6; @@ -669,30 +733,16 @@ public class Main extends MeshViewer { generateTile(transforms, tile); fixupTile(); } }); - tileMenu.add(new MyMenuItem("Slim Dense Packing (Hex)") { public void hit() { - tile = new Mesh(false); - float width = (float)3.2; - float depth = (float)0.32; - float height = (float)1.6; + tileMenu.add(new MyMenuItem("Slim Dense Packing (Cubic)") { public void hit() { + setTile(new Mesh(false)); float unit = 0.4f; float r = unit/2; float sin = (float)(unit * Math.sin(Math.PI/3)); float cos = (float)(unit * Math.cos(Math.PI/3)); float x = (float)(r*Math.tan(Math.PI/6)); float z = (float)(r/Math.cos(Math.PI/6)); - height = 2*r*(float)Math.sqrt(2f/3f); - - - r *= 0.3f; - cos *= 0.3f; - unit *= 0.3f; - height *= 1.5f; + float height = 2*r*(float)Math.sqrt(2f/3f); - /* - sin *= 0.3f; - x *= 0.3f; - z *= 0.3f; - */ transforms = new Matrix[] { Matrix.translate(new Vec(-unit, 0, 0)), Matrix.translate(new Vec( unit, 0, 0)), @@ -700,24 +750,51 @@ public class Main extends MeshViewer { Matrix.translate(new Vec( cos, 0, sin)), Matrix.translate(new Vec(-cos, 0, -sin)), Matrix.translate(new Vec( cos, 0, -sin)), - Matrix.translate(new Vec( 0, height, z)), - Matrix.translate(new Vec(-r, height, -x)), - Matrix.translate(new Vec( r, height, -x)), - Matrix.translate(new Vec( 0, -height, -z)), - Matrix.translate(new Vec(-r, -height, x)), - Matrix.translate(new Vec( r, -height, x)), - Matrix.ONE, + + /* + Matrix.translate(new Vec( 0, height, -z)).times(Matrix.rotate(new Vec(0,1,0), (float)Math.PI)), + Matrix.translate(new Vec(-r, height, x)).times(Matrix.rotate(new Vec(0,1,0), (float)Math.PI)), + Matrix.translate(new Vec( r, height, x)).times(Matrix.rotate(new Vec(0,1,0), (float)Math.PI)), + Matrix.translate(new Vec( 0, -height, -z)).times(Matrix.rotate(new Vec(0,1,0), (float)Math.PI)), + Matrix.translate(new Vec(-r, -height, x)).times(Matrix.rotate(new Vec(0,1,0), (float)Math.PI)), + Matrix.translate(new Vec( r, -height, x)).times(Matrix.rotate(new Vec(0,1,0), (float)Math.PI)), + */ + + Matrix.translate(new Vec( 0, height, -z)), + Matrix.translate(new Vec(-r, height, x)), + Matrix.translate(new Vec( r, height, x)), + Matrix.translate(new Vec( 0, -height, z)), + Matrix.translate(new Vec(-r, -height, -x)), + Matrix.translate(new Vec( r, -height, -x)), + //Matrix.rotate(new Vec(0,0,1), (float)Math.PI), + + /* + Matrix.translate(new Vec( 0, height, -z)).times(Matrix.scale(-1,1,-1)), + Matrix.translate(new Vec(-r, height, x)).times(Matrix.scale(-1,1,-1)), + Matrix.translate(new Vec( r, height, x)).times(Matrix.scale(-1,1,-1)), + Matrix.translate(new Vec( 0, -height, -z)).times(Matrix.scale(-1,1,-1)), + Matrix.translate(new Vec(-r, -height, x)).times(Matrix.scale(-1,1,-1)), + Matrix.translate(new Vec( r, -height, x)).times(Matrix.scale(-1,1,-1)), + */ + Matrix.ONE }; generateTile(transforms, tile); + //for(int i=0; i