[Bprocessor-commit] gl/src/net/sourceforge/bprocessor/gl/tool OffsetTool.java, NONE, 1.1
Status: Pre-Alpha
Brought to you by:
henryml
From: Nordholt <nor...@us...> - 2006-07-09 16:19:59
|
Update of /cvsroot/bprocessor/gl/src/net/sourceforge/bprocessor/gl/tool In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv23994 Added Files: OffsetTool.java Log Message: an offset tool --- NEW FILE: OffsetTool.java --- //--------------------------------------------------------------------------------- // $Id: OffsetTool.java,v 1.1 2006/07/09 16:19:55 nordholt 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.MouseEvent; import java.util.Iterator; import java.util.List; import java.util.LinkedList; import java.util.Map; import java.util.HashMap; import net.sourceforge.bprocessor.gl.GLView; import net.sourceforge.bprocessor.gl.model.Intersection; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.Surface; import net.sourceforge.bprocessor.model.Vertex; /** * OffsetTool */ public class OffsetTool extends AbstractPencil { /** The current contour */ private List contour; /** A map of wich direction each vertex should be moved */ private Map directionMap; /** The intersection before the current */ private Intersection lastIntersection; /** Dragging flag */ private boolean dragging; /** * Constructor fo OffsetTool * @param glv The GLView * @param cursor The Cursor */ public OffsetTool(GLView glv, Cursor cursor) { super(glv, cursor); contour = new LinkedList(); directionMap = new HashMap(); dragging = false; } /** * * Update feedback */ public void updateFeedback() { if (start != null) { double lastRadius = start.vertex().minus(lastIntersection.vertex()).length(); double newRadius = start.vertex().minus(current.vertex()).length(); double delta = newRadius - lastRadius; Iterator it = collect(contour).iterator(); while (it.hasNext()) { Vertex v = (Vertex)it.next(); Vertex dir = ((Vertex)directionMap.get(v)).copy(); dir.scale(delta); v.move(dir.getX(), dir.getY(), dir.getZ()); } } makeTarget(current); } /** * Invoked when the mouse cursor has been moved * @param e The MouseEvent object */ protected void moved(MouseEvent e) { lastIntersection = current; current = findIntersection(e); if (current != null) { updateFeedback(); } updateConstructors(); } /** * Invoked when a mouse button has been pressed. * @param e The MouseEvent object */ protected void pressed(MouseEvent e) { if (start == null) { if (current != null && current.object() instanceof Surface) { start = current; Surface surface = (Surface)current.object(); contour = copyContour(surface); directionMap = findDirections(contour, surface.normal()); feedback(contour); } } else { endOffset(); } } /** * onVertex - necessary only to make the general "apply" method work * when using the length field. */ public void onVertex() { if (start != null) { updateFeedback(); endOffset(); } } /** * Ends this offset. */ private void endOffset() { Iterator it = contour.iterator(); while (it.hasNext()) { Edge edge = (Edge)it.next(); insertEdge(edge, false); } directionMap = new HashMap(); contour = new LinkedList(); feedback(contour); start = null; } /** * Finds the directions each vertex must move inorder for * the contour to be expanded correctly. These are put in * the direction map. * @param edges the contour, the list must be ordered * @param surfaceNormal the normal of the surface we are offsetting * @return the directionmap */ private Map findDirections(List edges, Vertex surfaceNormal) { //The direction of a vertex should be the sum of the normals of each //of its edges, and scaled propably so it does not twist the contour out of shape Map directions = new HashMap(); Edge firstEdge = null; Edge e1 = null; Edge e2 = null; Iterator it = edges.iterator(); if (it.hasNext()) { firstEdge = (Edge)it.next(); e1 = firstEdge; } while (it.hasNext()) { e2 = (Edge)it.next(); Vertex dir1 = e1.getDirection().cross(surfaceNormal); Vertex dir2 = e2.getDirection().cross(surfaceNormal); dir1.scale(1 / dir1.length()); dir2.scale(1 / dir2.length()); Vertex mainDir = dir1.add(dir2); mainDir.scale(1 / mainDir.dot(dir1)); if (e2.contains(e1.getTo())) { directions.put(e1.getTo(), mainDir); } else { directions.put(e1.getFrom(), mainDir); } e1 = e2; } //Here I make sure the first vertex gets a direction Vertex dir1 = e1.getDirection().cross(surfaceNormal); Vertex dir2 = firstEdge.getDirection().cross(surfaceNormal); dir1.scale(1 / dir1.length()); dir2.scale(1 / dir2.length()); Vertex mainDir = dir1.add(dir2); mainDir.scale(1 / mainDir.dot(dir1)); if (firstEdge.contains(e1.getTo())) { directions.put(e1.getTo(), mainDir); } else { directions.put(e1.getFrom(), mainDir); } return directions; } /** * Copies the edges of a surface maintaining the connectivity. * @param surface the surface * @return a list of the edges */ private List copyContour(Surface surface) { List edges = new LinkedList(); Vertex from = null; Vertex to = null; Vertex first = null; Iterator it = surface.getVertices().iterator(); if (it.hasNext()) { first = ((Vertex)it.next()).copy(); from = first; } while (it.hasNext()) { to = ((Vertex)it.next()).copy(); Edge offsetEdge = new Edge(from, to); offsetEdge.setConstructor(true); edges.add(offsetEdge); from = to; } Edge offsetEdge = new Edge(from, first); offsetEdge.setConstructor(true); edges.add(offsetEdge); return edges; } /** * Invoked when a mouse is dragged with button down. * @param e The MouseEvent object */ protected void dragged(MouseEvent e) { moved(e); if (!dragging) { dragging = true; } } /** * Invoked when the mouse button is released. * @param e Event */ protected void released(MouseEvent e) { if (dragging) { pressed(e); dragging = false; } } } |