[Bprocessor-commit] model/src/net/sourceforge/bprocessor/model ClippingPlane.java, 1.33, 1.34 Plane
Status: Pre-Alpha
Brought to you by:
henryml
From: Michael L. <he...@us...> - 2008-09-18 10:43:04
|
Update of /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv26404/src/net/sourceforge/bprocessor/model Modified Files: ClippingPlane.java Plane.java Log Message: Clipping plane improvement Index: ClippingPlane.java =================================================================== RCS file: /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model/ClippingPlane.java,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** ClippingPlane.java 10 Sep 2008 22:53:44 -0000 1.33 --- ClippingPlane.java 18 Sep 2008 10:43:14 -0000 1.34 *************** *** 8,16 **** import java.util.Collection; - import java.util.HashMap; import java.util.Iterator; import java.util.ArrayList; import java.util.List; - import java.util.Map; import java.util.Set; import java.util.HashSet; --- 8,14 ---- *************** *** 190,227 **** } - private Container calculateSilhouette(Mesh input) { - Container silhouette = new Container("Section", Space.CONSTRUCTION, true); - Plane plane = getPlane(); - Map map = new HashMap(); - Map<Edge, Surface> e2s = new HashMap(); - for (Edge current : input.edges()) { - if (plane.contains(current)) { - Edge edge = (Edge) current.copy(map); - silhouette.insert(edge); - } - } - for (Surface current : input.surfaces()) { - Collection<Edge> contour = current.getEdges(); - Vertex from = null; - for (Edge edge : contour) { - Vertex vertex = plane.intersection(edge); - if (vertex != null) { - if (from != null) { - Edge line = new Edge(from, vertex); - line.setStrippled(true); - line = silhouette.insert(line); - e2s.put(line, current); - from = null; - } else { - from = vertex; - } - } - } - } - SurfaceAnalysis analysis = new SurfaceAnalysis(); - analysis.surfaceAnalysis(silhouette, plane.coordinateSystem(), silhouette.getEdges()); - return silhouette; - } - /** * Returns the silhouette --- 188,191 ---- *************** *** 232,236 **** Container space = Project.getInstance().getActiveSpace(); Mesh input = space.mesh(); ! silhouette = calculateSilhouette(input); } return silhouette; --- 196,201 ---- Container space = Project.getInstance().getActiveSpace(); Mesh input = space.mesh(); ! Plane plane = getPlane(); ! silhouette = plane.intersection(input); } return silhouette; Index: Plane.java =================================================================== RCS file: /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model/Plane.java,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** Plane.java 11 Dec 2007 14:49:02 -0000 1.35 --- Plane.java 18 Sep 2008 10:43:14 -0000 1.36 *************** *** 8,12 **** --- 8,18 ---- import java.util.Collection; + import java.util.Collections; + import java.util.Comparator; + import java.util.HashMap; import java.util.Iterator; + import java.util.LinkedList; + import java.util.List; + import java.util.Map; import org.apache.log4j.Logger; *************** *** 218,221 **** --- 224,473 ---- /** + * Calculates the intersection between the input geometry and this Plane + * @param input Geometry in the form of a Mesh + * @return intersection in the form of a Container + */ + public Container intersection(Mesh input) { + Container silhouette = new Container("Section", Space.CONSTRUCTION, true); + List<Entry> entries = new LinkedList(); + Map map = new HashMap(); + Map<Edge, Entry> planar = new HashMap(); + for (Edge current : input.edges()) { + if (contains(current)) { + Edge edge = (Edge) current.copy(map); + silhouette.insert(edge); + Entry entry = new Entry(edge, Entry.PLANAR); + entries.add(entry); + planar.put(current, entry); + } + } + for (Surface current : input.surfaces()) { + Collection<Edge> contour = current.getEdges(); + if (planar.keySet().containsAll(contour)) { + for (Edge edge : contour) { + Entry entry = planar.get(edge); + entry.surfaces().add(current); + } + } else { + { + LinkedList<Vertex> intersections = new LinkedList(); + Vertex from = current.getFirstVertex(); + Vertex to = null; + for (Edge edge : contour) { + to = edge.otherVertex(from); + if (contains(from)) { + intersections.add(from); + } else if (!contains(to)) { + Vertex intersection = intersection(edge); + if (intersection != null) { + intersections.add(intersection); + } + } + from = to; + } + + if (intersections.size() > 1) { + { + final Vertex leader = intersections.getFirst(); + Vertex last = intersections.getLast(); + final Vertex direction = last.minus(leader); + + Comparator<Vertex> compare = new Comparator<Vertex>() { + public double distance(Vertex vertex) { + Vertex delta = vertex.minus(leader); + double distance = delta.length(); + double dot = direction.dot(delta); + if (dot < 0) { + distance = -distance; + } + return distance; + } + public int compare(Vertex o1, Vertex o2) { + double d1 = distance(o1); + double d2 = distance(o2); + if (d1 < d2) { + return -1; + } else if (d1 > d2) { + return 1; + } else { + return 0; + } + } + }; + + Collections.sort(intersections, compare); + + Vertex previous = null; + for (Vertex vertex : intersections) { + if (previous != null) { + Edge line = new Edge(previous, vertex); + if (silhouette.findEdge(line) == null) { + line.setStrippled(true); + silhouette.insert(line); + Entry entry = new Entry(line, Entry.INTERSECTION); + entries.add(entry); + entry.surfaces().add(current); + } + } + previous = vertex; + } + } + } + } + } + } + + CoordinateSystem system = coordinateSystem(); + SurfaceAnalysis analysis = new SurfaceAnalysis(); + analysis.surfaceAnalysis(silhouette, coordinateSystem(), silhouette.getEdges()); + + { + List<Vertex> vertices = new LinkedList(silhouette.getVertices()); + system.translateIt(vertices); + + for (Entry current : entries) { + current.order(); + } + + { + Iterator<Entry> iter = entries.iterator(); + while (iter.hasNext()) { + Entry current = iter.next(); + if (current.ignore()) { + iter.remove(); + } + } + } + + final Comparator<Entry> compareY = new Comparator<Entry> () { + public int compare(Entry left, Entry right) { + if (left.y0 < right.y0) { + return -1; + } else if (left.y0 > right.y0) { + return 1; + } else { + return 0; + } + } + }; + + final Comparator<Entry> compareX = new Comparator<Entry> () { + public int compare(Entry left, Entry right) { + if (left.x < right.x) { + return -1; + } else if (left.x > right.x) { + return 1; + } else { + return 0; + } + } + }; + + Collections.sort(entries, compareY); + + + Iterator<Entry> iterator = entries.iterator(); + Entry next = iterator.next(); + List<Entry> active = new LinkedList(); + + while (next != null) { + double y = next.y0; + // weed + { + Iterator<Entry> iter = active.iterator(); + while (iter.hasNext()) { + Entry current = iter.next(); + if (current.y1 >= y) { + iter.remove(); + } + } + } + // insert + { + while (next != null && next.y0 == y) { + active.add(next); + if (iterator.hasNext()) { + next = iterator.next(); + } else { + next = null; + } + } + } + // intersection + { + Iterator<Entry> iter = active.iterator(); + while (iter.hasNext()) { + Entry current = iter.next(); + current.findIntersectingX(y); + } + } + // sort + Collections.sort(active, compareX); + // scan + } + + system.unTranslateIt(vertices); + } + return silhouette; + } + + private class Entry { + public static final int PLANAR = 0; + public static final int INTERSECTION = 1; + + + private Edge edge; + private int kind; + private List<Surface> surfaces; + private double x; + private double y0; + private double y1; + private double x0; + private double x1; + + public Entry(Edge edge, int kind) { + this.edge = edge; + this.kind = kind; + surfaces = new LinkedList(); + } + + public List<Surface> surfaces() { + return surfaces; + } + + public boolean eq(double a, double b) { + return Math.abs(a - b) < 0.0000001; + } + + public boolean ignore() { + return eq(y0, y1); + } + + public void order() { + if (edge.from.y < edge.to.y) { + y0 = edge.from.y; + x0 = edge.from.x; + y1 = edge.to.y; + x1 = edge.from.x; + } else { + y0 = edge.to.y; + x0 = edge.to.x; + y1 = edge.from.y; + x1 = edge.to.x; + } + } + + public void findIntersectingX(double y) { + double dx = x1 - x0; + double dy = y1 - y0; + x = x1 + ((y - y0 / dy)) * dx; + } + + public String toString() { + return "{" + edge + " " + y0 + " " + y1 + "}"; + } + } + + /** * Return the projection of the vertex into this Plane * @param vertex Vertex |