/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. ***********************************************************************/
  18. package org.mt4j.util;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. import org.mt4j.components.TransformSpace;
  22. import org.mt4j.components.bounds.BoundsZPlaneRectangle;
  23. import org.mt4j.components.bounds.IBoundingShape;
  24. import org.mt4j.components.visibleComponents.shapes.AbstractShape;
  25. import org.mt4j.components.visibleComponents.shapes.MTComplexPolygon;
  26. import org.mt4j.components.visibleComponents.shapes.MTPolygon;
  27. import org.mt4j.util.math.ConvexityUtil;
  28. import org.mt4j.util.math.ToolsGeometry;
  29. import org.mt4j.util.math.Vertex;
  30. import org.mt4j.util.xml.svg.CustomPathHandler;
  31. import processing.core.PApplet;
  32. public class ShapeBuilder {
  33. private CustomPathHandler pathHandler;
  34. private PApplet app;
  35. public ShapeBuilder(PApplet app){
  36. this.app = app;
  37. this.pathHandler = new CustomPathHandler();
  38. }
  39. // public void startPath() throws ParseException {
  40. // this.pathHandler.startPath();
  41. // }
  42. public void reset(){
  43. this.pathHandler = new CustomPathHandler();
  44. }
  45. /**
  46. * Starts a new path at the specified absolute coordinate.
  47. *
  48. * @param x the x
  49. * @param y the y
  50. */
  51. public void movetoAbs(float x, float y){
  52. this.pathHandler.movetoAbs(x, y);
  53. }
  54. /**
  55. * Starts a new path at the specified coordinate relative to the last coordinate.
  56. *
  57. * @param x the x
  58. * @param y the y
  59. */
  60. public void movetoRel(float x, float y){
  61. this.pathHandler.movetoRel(x, y);
  62. }
  63. public void arcAbs(float rx, float ry, float phi, boolean largeArc, boolean sweep, float x, float y) {
  64. this.pathHandler.arcAbs(rx, ry, phi, largeArc, sweep, x, y);
  65. }
  66. public void arcRel(float rx, float ry, float phi, boolean largeArc,boolean sweep, float x, float y) {
  67. this.pathHandler.arcRel(rx, ry, phi, largeArc, sweep, x, y);
  68. }
  69. public void curvetoCubicAbs(float x1, float y1, float x2, float y2,float x, float y){
  70. this.pathHandler.curvetoCubicAbs(x1, y1, x2, y2, x, y);
  71. }
  72. public void curvetoCubicRel(float x1, float y1, float x2, float y2,float x, float y) {
  73. this.pathHandler.curvetoCubicRel(x1, y1, x2, y2, x, y);
  74. }
  75. public void curvetoCubicSmoothAbs(float x2, float y2, float x, float y){
  76. this.pathHandler.curvetoCubicSmoothAbs(x2, y2, x, y);
  77. }
  78. public void curvetoCubicSmoothRel(float x2, float y2, float x, float y){
  79. this.pathHandler.curvetoCubicSmoothRel(x2, y2, x, y);
  80. }
  81. public void curvetoQuadraticAbs(float x1, float y1, float x, float y) {
  82. this.pathHandler.curvetoQuadraticAbs(x1, y1, x, y);
  83. }
  84. public void curvetoQuadraticRel(float x1, float y1, float x, float y){
  85. this.pathHandler.curvetoQuadraticRel(x1, y1, x, y);
  86. }
  87. public void curvetoQuadraticSmoothAbs(float x, float y){
  88. this.pathHandler.curvetoQuadraticSmoothAbs(x, y);
  89. }
  90. public void curvetoQuadraticSmoothRel(float x, float y) {
  91. this.pathHandler.curvetoQuadraticSmoothRel(x, y);
  92. }
  93. public void linetoAbs(float x, float y){
  94. this.pathHandler.linetoAbs(x, y);
  95. }
  96. public void linetoHorizontalAbs(float x){
  97. this.pathHandler.linetoHorizontalAbs(x);
  98. }
  99. public void linetoHorizontalRel(float x){
  100. this.pathHandler.linetoHorizontalRel(x);
  101. }
  102. public void linetoRel(float x, float y){
  103. this.pathHandler.linetoRel(x, y);
  104. }
  105. public void linetoVerticalAbs(float y){
  106. this.pathHandler.linetoVerticalAbs(y);
  107. }
  108. public void linetoVerticalRel(float y){
  109. this.pathHandler.linetoVerticalRel(y);
  110. }
  111. public void setVerbose(boolean verbose) {
  112. this.pathHandler.setVerbose(verbose);
  113. }
  114. /**
  115. * Closed the current path by adding the start point again.
  116. */
  117. public void closePath(){
  118. this.pathHandler.closePath();
  119. }
  120. private void endPath(){
  121. this.pathHandler.endPath();
  122. }
  123. public AbstractShape getShape(){
  124. this.endPath();
  125. ArrayList<Vertex[]> contours = this.pathHandler.getContours();
  126. Vertex[] allPoints = this.pathHandler.getPathPointsArray();
  127. AbstractShape returnComponent = null;
  128. //Check for convexity
  129. int convexity = ConvexityUtil.classifyPolygon2(allPoints.length, allPoints);
  130. switch (convexity) {
  131. case ConvexityUtil.NotConvexDegenerate:
  132. // logger.debug("not Convex Degenerate");
  133. case ConvexityUtil.NotConvex:
  134. // logger.debug("not convex");
  135. returnComponent = createComplexPoly(contours, MTComplexPolygon.WINDING_RULE_ODD);
  136. break;
  137. case ConvexityUtil.ConvexDegenerate:
  138. // logger.debug("convex degenerate");
  139. case ConvexityUtil.ConvexCW:
  140. // logger.debug("convex clockwise");
  141. case ConvexityUtil.ConvexCCW:
  142. // logger.debug("convex counterclockwise");
  143. returnComponent = createPoly(allPoints);
  144. break;
  145. default:
  146. break;
  147. }
  148. //Create some default texture coords
  149. if (returnComponent != null && returnComponent.hasBounds() && returnComponent.getBounds() instanceof BoundsZPlaneRectangle){
  150. BoundsZPlaneRectangle bounds = (BoundsZPlaneRectangle) returnComponent.getBounds();
  151. float width = bounds.getWidthXY(TransformSpace.LOCAL);
  152. float height = bounds.getHeightXY(TransformSpace.LOCAL);
  153. float upperLeftX = bounds.getVectorsLocal()[0].x;
  154. float upperLeftY = bounds.getVectorsLocal()[0].y;
  155. Vertex[] verts = returnComponent.getVerticesLocal();
  156. for (Vertex vertex : verts) {
  157. vertex.setTexCoordU((vertex.x - upperLeftX) / width);
  158. vertex.setTexCoordV((vertex.y - upperLeftY) / height);
  159. //System.out.println("TexU:" + vertex.getTexCoordU() + " TexV:" + vertex.getTexCoordV());
  160. }
  161. returnComponent.getGeometryInfo().updateTextureBuffer(returnComponent.isUseVBOs());
  162. }
  163. return returnComponent;
  164. }
  165. private AbstractShape createPoly(Vertex[] verts) {
  166. int segments = 15;
  167. if (ToolsGeometry.containsBezierVertices(verts))
  168. verts = ToolsGeometry.createVertexArrFromBezierArr(verts, segments);
  169. //Blow up vertex array, that will be used for picking etc
  170. //to at least be of size == 3 for generating normals
  171. if (verts.length <3){
  172. Vertex[] newVerts = new Vertex[3];
  173. if (verts.length == 2){
  174. newVerts[0] = verts[0];
  175. newVerts[1] = verts[1];
  176. newVerts[2] = (Vertex)verts[1].getCopy();
  177. verts = newVerts;
  178. }else if (verts.length == 1){
  179. newVerts[0] = verts[0];
  180. newVerts[1] = (Vertex)verts[0].getCopy();
  181. newVerts[2] = (Vertex)verts[0].getCopy();
  182. verts = newVerts;
  183. }else{
  184. //ERROR
  185. }
  186. }
  187. return new MTPolygon2D(verts, app);
  188. }
  189. private AbstractShape createComplexPoly(ArrayList<Vertex[]> contours, int windingRuleOdd) {
  190. int segments = 15;
  191. List<Vertex[]> bezierContours = ToolsGeometry.createVertexArrFromBezierVertexArrays(contours, segments);
  192. return new MTComplexPolygon2D(app, bezierContours);
  193. }
  194. private class MTComplexPolygon2D extends MTComplexPolygon{
  195. public MTComplexPolygon2D(PApplet app, List<Vertex[]> contours) {
  196. super(app, contours);
  197. }
  198. @Override
  199. protected IBoundingShape computeDefaultBounds() {
  200. //Use z plane bounding rect instead default boundingsphere since always 2D!
  201. return new BoundsZPlaneRectangle(this);
  202. }
  203. }
  204. private class MTPolygon2D extends MTPolygon{
  205. public MTPolygon2D(Vertex[] vertices, PApplet applet) {
  206. super(applet, vertices);
  207. }
  208. protected IBoundingShape computeDefaultBounds() {
  209. //Use z plane bounding rect instead default boundingsphere since always 2D!
  210. return new BoundsZPlaneRectangle(this);
  211. }
  212. }
  213. }