PageRenderTime 67ms CodeModel.GetById 36ms app.highlight 25ms RepoModel.GetById 2ms app.codeStats 0ms

/src/org/mt4j/util/ShapeBuilder.java

http://mt4j.googlecode.com/
Java | 259 lines | 165 code | 46 blank | 48 comment | 12 complexity | 9f8943f8c54bf35a6641e1792d7fbbfd MD5 | raw file
  1/***********************************************************************
  2 * mt4j Copyright (c) 2008 - 2010 Christopher Ruff, Fraunhofer-Gesellschaft All rights reserved.
  3 *  
  4 *   This program is free software: you can redistribute it and/or modify
  5 *   it under the terms of the GNU General Public License as published by
  6 *   the Free Software Foundation, either version 3 of the License, or
  7 *   (at your option) any later version.
  8 *
  9 *   This program is distributed in the hope that it will be useful,
 10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *   GNU General Public License for more details.
 13 *
 14 *   You should have received a copy of the GNU General Public License
 15 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 16 *
 17 ***********************************************************************/
 18package org.mt4j.util;
 19
 20import java.util.ArrayList;
 21import java.util.List;
 22
 23
 24import org.mt4j.components.TransformSpace;
 25import org.mt4j.components.bounds.BoundsZPlaneRectangle;
 26import org.mt4j.components.bounds.IBoundingShape;
 27import org.mt4j.components.visibleComponents.shapes.AbstractShape;
 28import org.mt4j.components.visibleComponents.shapes.MTComplexPolygon;
 29import org.mt4j.components.visibleComponents.shapes.MTPolygon;
 30import org.mt4j.util.math.ConvexityUtil;
 31import org.mt4j.util.math.ToolsGeometry;
 32import org.mt4j.util.math.Vertex;
 33import org.mt4j.util.xml.svg.CustomPathHandler;
 34
 35import processing.core.PApplet;
 36
 37public class ShapeBuilder {
 38	private CustomPathHandler pathHandler;
 39	private PApplet app;
 40	
 41	public ShapeBuilder(PApplet app){
 42		this.app = app;
 43		this.pathHandler = new CustomPathHandler();
 44		
 45	}
 46	
 47//	public void startPath() throws ParseException {
 48//		this.pathHandler.startPath();
 49//	}
 50	
 51	public void reset(){
 52		this.pathHandler = new CustomPathHandler();
 53	}
 54
 55	/**
 56	 * Starts a new path at the specified absolute coordinate.
 57	 *
 58	 * @param x the x
 59	 * @param y the y
 60	 */
 61	public void movetoAbs(float x, float y){
 62		this.pathHandler.movetoAbs(x, y);
 63	}
 64
 65	/**
 66	 * Starts a new path at the specified coordinate relative to the last coordinate.
 67	 *
 68	 * @param x the x
 69	 * @param y the y
 70	 */
 71	public void movetoRel(float x, float y){
 72		this.pathHandler.movetoRel(x, y);
 73	}
 74	
 75	public void arcAbs(float rx, float ry, float phi, boolean largeArc,	boolean sweep, float x, float y) {
 76		this.pathHandler.arcAbs(rx, ry, phi, largeArc, sweep, x, y);
 77	}
 78
 79	public void arcRel(float rx, float ry, float phi, boolean largeArc,boolean sweep, float x, float y) {
 80		this.pathHandler.arcRel(rx, ry, phi, largeArc, sweep, x, y);
 81	}
 82
 83
 84	public void curvetoCubicAbs(float x1, float y1, float x2, float y2,float x, float y){
 85		this.pathHandler.curvetoCubicAbs(x1, y1, x2, y2, x, y);
 86	}
 87
 88	public void curvetoCubicRel(float x1, float y1, float x2, float y2,float x, float y) {
 89		this.pathHandler.curvetoCubicRel(x1, y1, x2, y2, x, y);
 90	}
 91
 92	public void curvetoCubicSmoothAbs(float x2, float y2, float x, float y){
 93		this.pathHandler.curvetoCubicSmoothAbs(x2, y2, x, y);
 94	}
 95
 96	public void curvetoCubicSmoothRel(float x2, float y2, float x, float y){
 97		this.pathHandler.curvetoCubicSmoothRel(x2, y2, x, y);
 98	}
 99
100	public void curvetoQuadraticAbs(float x1, float y1, float x, float y) {
101		this.pathHandler.curvetoQuadraticAbs(x1, y1, x, y);
102	}
103
104	public void curvetoQuadraticRel(float x1, float y1, float x, float y){
105		this.pathHandler.curvetoQuadraticRel(x1, y1, x, y);
106	}
107
108	public void curvetoQuadraticSmoothAbs(float x, float y){
109		this.pathHandler.curvetoQuadraticSmoothAbs(x, y);
110	}
111
112	public void curvetoQuadraticSmoothRel(float x, float y) {
113		this.pathHandler.curvetoQuadraticSmoothRel(x, y);
114	}
115
116	public void linetoAbs(float x, float y){
117		this.pathHandler.linetoAbs(x, y);
118	}
119
120	public void linetoHorizontalAbs(float x){
121		this.pathHandler.linetoHorizontalAbs(x);
122	}
123
124	public void linetoHorizontalRel(float x){
125		this.pathHandler.linetoHorizontalRel(x);
126	}
127
128	public void linetoRel(float x, float y){
129		this.pathHandler.linetoRel(x, y);
130	}
131
132	public void linetoVerticalAbs(float y){
133		this.pathHandler.linetoVerticalAbs(y);
134	}
135
136	public void linetoVerticalRel(float y){
137		this.pathHandler.linetoVerticalRel(y);
138	}
139
140	public void setVerbose(boolean verbose) {
141		this.pathHandler.setVerbose(verbose);
142	}
143	
144	/**
145	 * Closed the current path by adding the start point again.
146	 */
147	public void closePath(){
148		this.pathHandler.closePath();
149	}
150	
151	private void endPath(){
152		this.pathHandler.endPath();
153	}
154
155	
156	public AbstractShape getShape(){
157		this.endPath();
158		
159		ArrayList<Vertex[]> contours = this.pathHandler.getContours();
160		Vertex[] allPoints = this.pathHandler.getPathPointsArray();
161		AbstractShape returnComponent = null;
162		//Check for convexity
163		int convexity = ConvexityUtil.classifyPolygon2(allPoints.length, allPoints);
164		switch (convexity) {
165			case ConvexityUtil.NotConvexDegenerate:
166//				logger.debug("not Convex Degenerate");
167			case ConvexityUtil.NotConvex:
168//				logger.debug("not convex");
169				returnComponent = createComplexPoly(contours, MTComplexPolygon.WINDING_RULE_ODD);
170				break;
171			case ConvexityUtil.ConvexDegenerate:
172//				logger.debug("convex degenerate");
173			case ConvexityUtil.ConvexCW:
174//				logger.debug("convex clockwise");
175			case ConvexityUtil.ConvexCCW:
176//				logger.debug("convex counterclockwise");
177				returnComponent = createPoly(allPoints);
178				break;
179			default:
180				break;
181		}
182		
183		//Create some default texture coords
184		if (returnComponent != null && returnComponent.hasBounds() && returnComponent.getBounds() instanceof BoundsZPlaneRectangle){
185			BoundsZPlaneRectangle bounds = (BoundsZPlaneRectangle) returnComponent.getBounds();
186			float width = bounds.getWidthXY(TransformSpace.LOCAL);
187			float height = bounds.getHeightXY(TransformSpace.LOCAL);
188			float upperLeftX = bounds.getVectorsLocal()[0].x;
189			float upperLeftY = bounds.getVectorsLocal()[0].y;
190			Vertex[] verts = returnComponent.getVerticesLocal();
191            for (Vertex vertex : verts) {
192                vertex.setTexCoordU((vertex.x - upperLeftX) / width);
193                vertex.setTexCoordV((vertex.y - upperLeftY) / height);
194                //System.out.println("TexU:" + vertex.getTexCoordU() + " TexV:" + vertex.getTexCoordV());
195            }
196			returnComponent.getGeometryInfo().updateTextureBuffer(returnComponent.isUseVBOs());
197		}
198		return returnComponent;
199	}
200
201	private AbstractShape createPoly(Vertex[] verts) {
202		int segments = 15; 
203		if (ToolsGeometry.containsBezierVertices(verts))
204			verts = ToolsGeometry.createVertexArrFromBezierArr(verts, segments);
205
206		//Blow up vertex array, that will be used for picking etc
207		//to at least be of size == 3 for generating normals
208		if (verts.length <3){
209			Vertex[] newVerts = new Vertex[3];
210			if (verts.length == 2){
211				newVerts[0] = verts[0];
212				newVerts[1] = verts[1];
213				newVerts[2] = (Vertex)verts[1].getCopy();
214				verts = newVerts;
215			}else if (verts.length == 1){
216				newVerts[0] = verts[0];
217				newVerts[1] = (Vertex)verts[0].getCopy();
218				newVerts[2] = (Vertex)verts[0].getCopy();
219				verts = newVerts;
220			}else{
221				//ERROR
222			}
223		}
224		return new MTPolygon2D(verts, app);
225	}
226
227	
228	private AbstractShape createComplexPoly(ArrayList<Vertex[]> contours, int windingRuleOdd) {
229		int segments = 15; 
230		List<Vertex[]> bezierContours = ToolsGeometry.createVertexArrFromBezierVertexArrays(contours, segments);
231		return new MTComplexPolygon2D(app, bezierContours);
232	}
233	
234	
235	private class MTComplexPolygon2D extends MTComplexPolygon{
236		public MTComplexPolygon2D(PApplet app, List<Vertex[]> contours) {
237			super(app, contours);
238			
239		}
240		@Override
241		protected IBoundingShape computeDefaultBounds() {
242			//Use z plane bounding rect instead default boundingsphere since always 2D!
243			return new BoundsZPlaneRectangle(this);
244		}
245	}
246	
247	private class MTPolygon2D extends MTPolygon{
248		public MTPolygon2D(Vertex[] vertices, PApplet applet) {
249			super(applet, vertices);
250		}
251		
252		protected IBoundingShape computeDefaultBounds() {
253			//Use z plane bounding rect instead default boundingsphere since always 2D!
254			return new BoundsZPlaneRectangle(this);
255		}
256	}
257	
258
259}