Thread: [Bprocessor-commit] gl/src/net/sourceforge/bprocessor/gl/tool PencilTool.java, 1.65, 1.66 Tool.java
Status: Pre-Alpha
Brought to you by:
henryml
|
From: Michael L. <he...@us...> - 2006-11-30 22:03:51
|
Update of /cvsroot/bprocessor/gl/src/net/sourceforge/bprocessor/gl/tool In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv23976/src/net/sourceforge/bprocessor/gl/tool Modified Files: Tool.java ToolFactory.java Added Files: PencilTool.java Log Message: New PencilTool implements a new algorithm to find surface. Currently not incremental Index: ToolFactory.java =================================================================== RCS file: /cvsroot/bprocessor/gl/src/net/sourceforge/bprocessor/gl/tool/ToolFactory.java,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** ToolFactory.java 17 Nov 2006 15:47:33 -0000 1.67 --- ToolFactory.java 30 Nov 2006 22:03:41 -0000 1.68 *************** *** 70,73 **** --- 70,76 ---- /** pencil tool */ private Pencil pencil; + + /** extra pencil tool */ + private PencilTool penciltool; /** eraser tool */ *************** *** 174,177 **** --- 177,181 ---- select = new SpaceTool(glv, null); pencil = new Pencil(glv, pencilcursor); + penciltool = new PencilTool(glv, pencilcursor); eraser = new EraserTool(glv, pencilcursor); arc = new ArcTool(glv, pencilcursor); *************** *** 194,197 **** --- 198,202 ---- pencilBut = this.registerTool(Tool.PENCIL_TOOL, pencil, "Biconpentool.gif", "Pencil"); pencilBut.setMnemonic(KeyEvent.VK_W); + this.registerTool(Tool.ALT_PENCIL_TOOL, penciltool, "Biconpentool2.gif", "Pencil"); eraserBut = this.registerTool(Tool.ERASER_TOOL, eraser, "Biconeraser.gif", "Eraser"); eraserBut.setMnemonic(KeyEvent.VK_A); Index: Tool.java =================================================================== RCS file: /cvsroot/bprocessor/gl/src/net/sourceforge/bprocessor/gl/tool/Tool.java,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** Tool.java 4 Aug 2006 11:48:11 -0000 1.26 --- Tool.java 30 Nov 2006 22:03:41 -0000 1.27 *************** *** 58,61 **** --- 58,63 ---- /** The controlled move tool */ public static final int CONTROLLED_MOVE_TOOL = 18; + /** the alternative pecnil tool */ + public static final int ALT_PENCIL_TOOL = 19; /** --- NEW FILE: PencilTool.java --- //--------------------------------------------------------------------------------- // $Id: PencilTool.java,v 1.66 2006/11/30 22:03:41 henryml Exp $ // // Copyright (c) 2005 The BProcessor Team (http://bprocessor.sourceforge.net) // Released under the Lesser GNU Public License v2.1 //--------------------------------------------------------------------------------- package net.sourceforge.bprocessor.gl.tool; import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.AbstractAction; import javax.swing.JPopupMenu; import net.sourceforge.bprocessor.gl.GLView; import net.sourceforge.bprocessor.gl.view.View; import net.sourceforge.bprocessor.model.CoordinateSystem; import net.sourceforge.bprocessor.model.Entity; import net.sourceforge.bprocessor.model.Plane; import net.sourceforge.bprocessor.model.Project; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.Selection; import net.sourceforge.bprocessor.model.Space; import net.sourceforge.bprocessor.model.Surface; import net.sourceforge.bprocessor.model.Vertex; /** * Pencil * */ public class PencilTool extends AbstractPencil { /** * Constructor for Pencil * @param glv GLView * @param cursor Cursor */ public PencilTool(GLView glv, Cursor cursor) { super(glv, cursor); dragging = false; } /** * * Update feedback */ public void updateFeedback() { if (start != null) { Edge edge = new Edge(start.vertex(), current.vertex()); List edges = new LinkedList(); edges.add(edge); feedback(edges); } else { constructors(new LinkedList()); feedback(new LinkedList()); } makeTarget(current); updateConstructors(); } /** * @param e MouseEvent */ protected void moved(MouseEvent e) { current = findIntersection(e); if (current != null) { updateFeedback(); } } /** * * @return JPopupMenu */ public JPopupMenu menu() { JPopupMenu menu = new JPopupMenu(); AbstractAction planeanalysis = new AbstractAction("Plane Analysis") { public void actionPerformed(ActionEvent arg0) { Space space = Project.getInstance().getActiveSpace(); clearPlanes(space); Collection planes = planeAnalysis(space); Iterator iter = planes.iterator(); while (iter.hasNext()) { CoordinateSystem current = (CoordinateSystem) iter.next(); space.insert(current); } Project.getInstance().changed(space); Project.getInstance().checkpoint(); } }; menu.add(planeanalysis); AbstractAction clearplanes = new AbstractAction("Delete Planes") { public void actionPerformed(ActionEvent arg0) { Space space = Project.getInstance().getActiveSpace(); clearPlanes(space); Project.getInstance().changed(space); Project.getInstance().checkpoint(); } }; menu.add(clearplanes); AbstractAction surfaceanalysis = new AbstractAction("Surface Analysis") { public void actionPerformed(ActionEvent arg0) { Space space = Project.getInstance().getActiveSpace(); clearSurfaces(space); surfaceAnalysis(space); Project.getInstance().changed(space); Project.getInstance().checkpoint(); } }; menu.add(surfaceanalysis); AbstractAction clearsurfaces = new AbstractAction("Delete Surfaces") { public void actionPerformed(ActionEvent arg0) { Space space = Project.getInstance().getActiveSpace(); clearSurfaces(space); Project.getInstance().changed(space); Project.getInstance().checkpoint(); } }; menu.add(clearsurfaces); return menu; } /** * * @param planes Collection of coordinatesystem * @param edge Edge * @return True if edge is contained in a coordinatesystem */ private boolean contains(Collection planes, Edge edge) { Iterator iter = planes.iterator(); while (iter.hasNext()) { CoordinateSystem system = (CoordinateSystem) iter.next(); if (system.plane().contains(edge)) { return true; } } return false; } /** * Remove all coordinatesystems from space * @param space Space */ public void clearPlanes(Space space) { Collection planes = space.getCoordinateSystems(); Iterator iter = planes.iterator(); while (iter.hasNext()) { CoordinateSystem current = (CoordinateSystem) iter.next(); space.remove(current); } } /** * @param space Space * @return Collection of planes */ public Collection planeAnalysis(Space space) { Collection planes = new LinkedList(); Collection edges = space.getEdges(); { Set mark = new HashSet(); Map neighbours = new HashMap(); { Collection vertices = space.getVertices(); Map edgemap = new HashMap(); { Iterator iter = vertices.iterator(); while (iter.hasNext()) { Vertex current = (Vertex) iter.next(); edgemap.put(current, new LinkedList()); } } { Iterator iter = edges.iterator(); while (iter.hasNext()) { Edge current = (Edge) iter.next(); Vertex from = current.getFrom(); List fl = (List) edgemap.get(from); fl.add(current); Vertex to = current.getTo(); List tl = (List) edgemap.get(to); tl.add(current); } } { Iterator iter = edges.iterator(); while (iter.hasNext()) { Edge current = (Edge) iter.next(); List incident = new LinkedList(); { Vertex from = current.getFrom(); List fl = (List) edgemap.get(from); Iterator flit = fl.iterator(); while (flit.hasNext()) { Edge edge = (Edge) flit.next(); if (edge != current) { incident.add(edge); } } } { Vertex to = current.getTo(); List tl = (List) edgemap.get(to); Iterator tlit = tl.iterator(); while (tlit.hasNext()) { Edge edge = (Edge) tlit.next(); if (edge != current) { incident.add(edge); } } } neighbours.put(current, incident); } } } Iterator iter = edges.iterator(); while (iter.hasNext()) { Edge current = (Edge) iter.next(); if (!mark.contains(current)) { mark.add(current); if (!contains(planes, current)) { List incident = (List) neighbours.get(current); List pls = new LinkedList(); Iterator it = incident.iterator(); while (it.hasNext()) { Edge edge = (Edge) it.next(); if (!contains(pls, edge)) { CoordinateSystem system = CoordinateSystem.create(current, edge); mark.add(edge); if (system != null) { pls.add(system); } } } planes.addAll(pls); } } } } return planes; } /** * @param e MouseEvent */ protected void pressed(MouseEvent e) { if (e.isPopupTrigger()) { glv.popup(menu(), e.getX(), e.getY()); } else { onVertex(); moved(e); } } /** * Current vertex is pressed */ public void onVertex() { if (start == null) { start = current; active = true; } else { if (start.vertex().equalEps(current.vertex())) { cleanUp(); return; } else { Edge edge = new Edge(start.vertex(), current.vertex()); Project.getInstance().getActiveSpace().insert(edge); Project.getInstance().changed(Project.getInstance().getActiveSpace()); Project.getInstance().checkpoint(); hooverEdge = edge; start = current; incident = null; cleanUp(); } } updateConstructors(); updateFeedback(); glv.repaint(); } /** * Clear surfaces in specified space * @param space Space */ public void clearSurfaces(Space space) { Collection surfaces = new LinkedList(space.getSurfaces()); Iterator iter = surfaces.iterator(); while (iter.hasNext()) { Surface current = (Surface) iter.next(); space.remove(current); } } /** * Find surfaces in specified space * @param space Space */ public void surfaceAnalysis(Space space) { Collection planes = space.getCoordinateSystems(); Iterator iter = planes.iterator(); while (iter.hasNext()) { CoordinateSystem current = (CoordinateSystem) iter.next(); surfaceAnalysis(space, current); } } /** * Find surfaces in specified space that lies in the specified * coordinatesystem * @param space Space * @param system CoordinateSystem */ public void surfaceAnalysis(Space space, CoordinateSystem system) { Plane plane = system.plane(); Map vmap = new LinkedHashMap(); Map emap = new LinkedHashMap(); { List vertices = new LinkedList(space.getVertices()); Entity.sort(vertices); Iterator iter = vertices.iterator(); while (iter.hasNext()) { Vertex current = (Vertex) iter.next(); glv.getView().clearColor(current); if (plane.contains(current)) { glv.getView().changeColor(current, View.CLIP_PLANE_COLOR); Selection.primary().add(current); vmap.put(current, new VertexNode(current)); } } } { List edges = new LinkedList(space.getEdges()); Entity.sort(edges); Iterator iter = edges.iterator(); while (iter.hasNext()) { Edge current = (Edge) iter.next(); glv.getView().clearColor(current); VertexNode from = (VertexNode) vmap.get(current.getFrom()); VertexNode to = (VertexNode) vmap.get(current.getTo()); if (from != null && to != null) { glv.getView().changeColor(current, View.CLIP_PLANE_COLOR); EdgeNode node = new EdgeNode(current, from, to); emap.put(current, node); from.add(node); to.add(node); } } } { Iterator iter = vmap.values().iterator(); while (iter.hasNext()) { VertexNode current = (VertexNode) iter.next(); current.sort(system); } } { Iterator iter = emap.values().iterator(); System.out.println("-- analysis --"); while (iter.hasNext()) { EdgeNode current = (EdgeNode) iter.next(); surfaceAnalysis(current, system); } } } /** * Return a list of Edge corresponding to a list of EdgeNodes such * that all nodes with the same surfacenode on both sides are ignored. * @param nodes list of EdgeNode * @return list of Edge */ public List contour(List nodes) { List edges = new LinkedList(); { Iterator iter = nodes.iterator(); while (iter.hasNext()) { EdgeNode current = (EdgeNode) iter.next(); if (current.left != current.right) { edges.add(current.edge); } } } return edges; } /** * * @param start EdgeNode * @param system CoordinateSystem */ public void surfaceAnalysis(EdgeNode start, CoordinateSystem system) { if (start.left == null) { System.out.println("left analyze " + start); SurfaceNode s = new SurfaceNode(); List nodes = new LinkedList(); VertexNode to = start.to; EdgeNode current = start; while (current.getLeft(to) != s) { System.out.println(current); nodes.add(current); current.setLeft(to, s); current = current.pred(to); to = current.other(to); } List edges = contour(nodes); if (edges.size() > 2) { System.out.println("left surface:" + edges); int turn = direction(edges, system); if (turn == LEFT) { System.out.println("turns left"); Surface surface = new Surface(edges); Project.getInstance().getActiveSpace().add(surface); } if (turn == RIGHT) { System.out.println("turns right"); } } } if (start.right == null) { System.out.println("right analyze " + start); SurfaceNode s = new SurfaceNode(); List nodes = new LinkedList(); VertexNode to = start.to; EdgeNode current = start; while (current.getRight(to) != s) { System.out.println(current); nodes.add(current); current.setRight(to, s); current = current.succ(to); to = current.other(to); } List edges = contour(nodes); if (edges.size() > 2) { System.out.println("right surface:" + edges); int turn = direction(edges, system); if (turn == LEFT) { System.out.println("turns left"); } if (turn == RIGHT) { System.out.println("turns right"); Surface surface = new Surface(edges); Project.getInstance().getActiveSpace().add(surface); } } } } /** LEFT means counterclockwise */ public static final int LEFT = 1; /** RIGHT means clockwise */ public static final int RIGHT = 2; /** PARALLEL means not turning */ public static final int PARALLEL = 3; /** * Find the turn direction of the edges * @param edges list of Edge * @param system CoordinateSystem * @return direction (LEFT or RIGHT) */ public int direction(List edges, CoordinateSystem system) { double y = Double.MAX_VALUE; Edge e1 = null; Edge e2 = null; Edge previous = (Edge) edges.get(edges.size() - 1); Iterator iter = edges.iterator(); while (iter.hasNext()) { Edge current = (Edge) iter.next(); Vertex v = Edge.commonVertex(previous, current); v = system.translate(v); if (v.getY() <= y) { y = v.getY(); e1 = previous; e2 = current; } previous = current; } Vertex common = Edge.commonVertex(e1, e2); Vertex from = e1.otherVertex(common); Vertex to = e2.otherVertex(common); from = system.translate(from); common = system.translate(common); to = system.translate(to); Vertex u = common.minus(from); Vertex v = to.minus(common); Vertex cross = u.cross(v); double determinant = cross.getZ(); // if the cross points into the screen (along the negative z), // the vectors are doing a right turn. Otherwise they are doing // a left turn. If the cross are zero, they er parallel, but the // above code should ensure that does not happen assuming the // edges has a nonzero area. if (determinant < 0) { return RIGHT; } if (determinant > 0) { return LEFT; } return PARALLEL; } /** * VertexNode */ public class VertexNode { /** vertex */ private Vertex vertex; /** edges */ private List edges; /** * Constructor * @param vertex Vertex */ public VertexNode(Vertex vertex) { this.vertex = vertex; edges = new LinkedList(); } /** * * @param edge Edge */ public void add(EdgeNode edge) { edges.add(edge); } /** * * @param system CoordinateSystem */ public void sort(CoordinateSystem system) { /** * Entry */ class Entry implements Comparable { protected double dx; protected double dy; protected EdgeNode node; /** * * @param node EdgeNode * @param dx double * @param dy double */ public Entry(EdgeNode node, double dx, double dy) { this.node = node; this.dx = dx; this.dy = dy; } /** * @param other Object * @return int */ public int compareTo(Object other) { Entry entry = (Entry) other; if (this.dx == 0) { return -1; } if (entry.dx == 0) { return 1; } if ((this.dy / this.dx) < (entry.dy / entry.dx)) { return -1; } else { return 1; } } } { List left = new LinkedList(); List right = new LinkedList(); Iterator iter = edges.iterator(); while (iter.hasNext()) { EdgeNode current = (EdgeNode) iter.next(); VertexNode other = current.other(this); Vertex delta = other.vertex.minus(vertex); double dx = system.getI().dot(delta); double dy = system.getJ().dot(delta); Entry entry = new Entry(current, dx, dy); if (dx == 0) { if (dy < 0) { right.add(entry); } if (dy > 0) { left.add(entry); } } else { if (dx > 0) { right.add(entry); } if (dx < 0) { left.add(entry); } } } Object[] rights = right.toArray(); Arrays.sort(rights); Object[] lefts = left.toArray(); Arrays.sort(lefts); List result = new LinkedList(); for (int i = 0; i < rights.length; i++) { result.add(((Entry) rights[i]).node); } for (int i = 0; i < lefts.length; i++) { result.add(((Entry) lefts[i]).node); } edges = result; } { EdgeNode previous = (EdgeNode) edges.get(edges.size() - 1); Iterator iter = edges.iterator(); while (iter.hasNext()) { EdgeNode current = (EdgeNode) iter.next(); if (previous.to == this) { previous.toSucc = current; } if (previous.from == this) { previous.fromSucc = current; } if (current.to == this) { current.toPred = previous; } if (current.from == this) { current.fromPred = previous; } previous = current; } } } /** * @return String */ public String toString() { return "{" + vertex.getName() + " " + edges + "}"; } } /** * EdgeNode */ public class EdgeNode { /** edge */ private Edge edge; /** from */ private VertexNode from; /** to */ private VertexNode to; /** successor arround to */ private EdgeNode toSucc; /** predecessor around to */ private EdgeNode toPred; /** sucessor around from */ private EdgeNode fromSucc; /** predecessor around from */ private EdgeNode fromPred; /** left surface */ private SurfaceNode left; /** right surface */ private SurfaceNode right; /** * * @param edge Edge * @param from VertexNode * @param to VertexNode */ public EdgeNode(Edge edge, VertexNode from, VertexNode to) { this.edge = edge; this.from = from; this.to = to; } /** * * @param end VertexNode * @return VertexNode */ public VertexNode other(VertexNode end) { if (end == from) { return to; } if (end == to) { return from; } return null; } /** * * @param end VertexNode * @return EdgeNode */ public EdgeNode succ(VertexNode end) { if (end == to) { return toSucc; } if (end == from) { return fromSucc; } return null; } /** * * @param end VertexNode * @return EdgeNode */ public EdgeNode pred(VertexNode end) { if (end == to) { return toPred; } if (end == from) { return fromPred; } return null; } /** * * @param end VertexNode * @return SurfaceNode */ public SurfaceNode getLeft(VertexNode end) { if (end == to) { return left; } if (end == from) { return right; } return null; } /** * @param end VertexNode * @param left SurfaceNode */ public void setLeft(VertexNode end, SurfaceNode left) { if (end == to) { this.left = left; } if (end == from) { this.right = left; } } /** * * @param end VertexNode * @return SurfaceNode */ public SurfaceNode getRight(VertexNode end) { if (end == to) { return right; } if (end == from) { return left; } return null; } /** * * @param end VertexNode * @param right SurfaceNode */ public void setRight(VertexNode end, SurfaceNode right) { if (end == to) { this.right = right; } if (end == from) { this.left = right; } } /** * @return String */ public String toString() { return "{" + edge.getName() + " fp:" + ((fromPred == null) ? "nil" : fromPred.edge.getName()) + " fs:" + ((fromSucc == null) ? "nil" : fromSucc.edge.getName()) + " tp:" + ((toPred == null) ? "nil" : toPred.edge.getName()) + " ts:" + ((toSucc == null) ? "nil" : toSucc.edge.getName()) + "}"; } } /** * SurfaceNode */ public class SurfaceNode { } } |