Thread: [Bprocessor-commit] model/src/net/sourceforge/bprocessor/model Command.java, 1.15, 1.16
Status: Pre-Alpha
Brought to you by:
henryml
From: Michael L. <he...@us...> - 2007-10-26 13:01:39
|
Update of /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv8065/src/net/sourceforge/bprocessor/model Modified Files: Command.java Log Message: A subdivision algo Index: Command.java =================================================================== RCS file: /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model/Command.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Command.java 24 Oct 2007 16:04:54 -0000 1.15 --- Command.java 26 Oct 2007 13:01:31 -0000 1.16 *************** *** 10,16 **** --- 10,18 ---- import java.util.ArrayList; import java.util.Collection; + import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; + import java.util.Map; import java.util.Set; *************** *** 135,138 **** --- 137,360 ---- /** * + */ + public static class SmoothSpace extends Command { + private Map<Vertex, List<Edge>> vmap; + + /** + * + * @param space Space + */ + public SmoothSpace(Space space) { + parameters.put("space", space); + } + + /** {@inheritDoc} */ + public String getGeneralName() { + return "Smooth"; + } + + private Vertex common(Edge e1, Edge e2) { + if (e2.contains(e1.from)) { + return e1.from; + } else { + return e1.to; + } + } + + + private Edge edge(Vertex v1, Vertex v2) { + List<Edge> l1 = vmap.get(v1); + List<Edge> l2 = vmap.get(v2); + for (Edge current : l1) { + if (current.otherVertex(v1) == v2) { + return current; + } + } + Edge edge = new Edge(v1, v2); + l1.add(edge); + l2.add(edge); + return edge; + } + + private Surface quad(Edge e1, Edge e2, Edge e3, Edge e4) { + List edges = new ArrayList(); + edges.add(e1); + edges.add(e2); + edges.add(e3); + edges.add(e4); + return new Surface(edges); + } + + private Surface quad(Vertex v1, Vertex v2, Vertex v3, Vertex v4) { + Edge e1 = edge(v1, v2); + Edge e2 = edge(v2, v3); + Edge e3 = edge(v3, v4); + Edge e4 = edge(v4, v1); + return quad(e1, e2, e3, e4); + } + + private Vertex average(Collection<Vertex> vertices) { + double x = 0; + double y = 0; + double z = 0; + for (Vertex current : vertices) { + x += current.x; + y += current.y; + z += current.z; + } + int n = vertices.size(); + return new Vertex(x / n, y / n, z / n); + } + + /** {@inheritDoc} */ + @Override + public void evaluate() { + Space space = (Space) parameters.get("space"); + System.out.println("smooth " + space); + + List<Surface> faces = new ArrayList(space.getEnvelope()); + List<Edge> edges = new ArrayList(Surface.edges(faces)); + List<Vertex> vertices = new ArrayList(Edge.vertices(edges)); + + Map<Surface, Vertex> facemap = new HashMap(); + Map<Edge, Vertex> edgemap = new HashMap(); + Map<Vertex, Vertex> vertexmap = new HashMap(); + + LinkedList<Vertex> points = new LinkedList(); + List<Surface> quads = new LinkedList(); + + { + // Subdivision step + + for (Surface current : faces) { + Vertex vertex = current.center(); + facemap.put(current, vertex); + } + + for (Edge current : edges) { + Vertex vertex = current.center(); + edgemap.put(current, vertex); + } + + for (Vertex current : vertices) { + Vertex vertex = current.copy(); + vertexmap.put(current, vertex); + } + + + points.addAll(facemap.values()); + points.addAll(edgemap.values()); + points.addAll(vertexmap.values()); + + // Initialize vmap for speeding + // up quad generation + + vmap = new HashMap(); + for (Vertex current : points) { + vmap.put(current, new LinkedList()); + } + + for (Surface face : faces) { + LinkedList<Edge> contour = new LinkedList(face.getEdges()); + Edge previous = contour.getLast(); + Vertex f = facemap.get(face); + for (Edge current : contour) { + Vertex v = vertexmap.get(common(previous, current)); + Vertex p1 = edgemap.get(previous); + Vertex p2 = edgemap.get(current); + quads.add(quad(f, p1, v, p2)); + previous = current; + } + } + } + + { + // Averaging step + + Map<Vertex, List<Edge>> v2e = new HashMap(); + Map<Edge, List<Surface>> e2s = new HashMap(); + Map<Vertex, List<Surface>> v2s = new HashMap(); + + for (Vertex current : vertices) { + v2e.put(current, new LinkedList()); + } + for (Edge current : edges) { + List<Edge> fl = v2e.get(current.from); + fl.add(current); + List<Edge> tl = v2e.get(current.to); + tl.add(current); + e2s.put(current, new LinkedList()); + } + for (Surface current : faces) { + for (Edge edge : current.getEdges()) { + List<Surface> l = e2s.get(edge); + l.add(current); + } + } + for (Vertex current : vertices) { + Set<Surface> set = new HashSet(); + List<Edge> l = v2e.get(current); + for (Edge edge : l) { + set.addAll(e2s.get(edge)); + } + v2s.put(current, new LinkedList(set)); + } + + + for (Edge current : edges) { + Vertex edgepoint = edgemap.get(current); + List<Edge> es = vmap.get(edgepoint); + List<Vertex> vs = new LinkedList(); + for (Edge edge : es) { + vs.add(edge.otherVertex(edgepoint)); + } + edgepoint.set(average(vs)); + } + + for (Vertex current : vertices) { + List<Edge> es = v2e.get(current); + List<Surface> ss = v2s.get(current); + int n = es.size(); + List<Vertex> vs = new LinkedList(); + for (Edge edge : es) { + vs.add(edge.otherVertex(current)); + } + List<Vertex> fs = new LinkedList(); + for (Surface surface : ss) { + fs.add(facemap.get(surface)); + } + + Vertex a1 = average(vs); + Vertex a2 = average(fs); + double x = ((n - 2) * current.x) / n + a1.x / n + a2.x / n; + double y = ((n - 2) * current.y) / n + a1.y / n + a2.y / n; + double z = ((n - 2) * current.z) / n + a1.z / n + a2.z / n; + + Vertex vertexpoint = vertexmap.get(current); + vertexpoint.setX(x); + vertexpoint.setY(y); + vertexpoint.setZ(z); + } + } + + + for (Vertex current : points) { + space.add(current); + } + + for (Surface quad : quads) { + for (Edge current : quad.getEdges()) { + space.add(current); + } + space.add(quad); + } + + Project.getInstance().changed(Project.getInstance()); + } + } + + + /** + * * */ |