rewrite createShape() handling to clean up the mess

This commit is contained in:
Ben Fry
2015-04-28 12:42:53 -04:00
parent 656acc58c0
commit 631cb4276d
12 changed files with 294 additions and 97 deletions
+1 -9
View File
@@ -10266,21 +10266,13 @@ public class PApplet implements PConstants {
}
public PShape createShape(PShape source) {
return g.createShape(source);
}
/**
* @param type either POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP
*/
public PShape createShape(int type) {
return g.createShape(type);
}
/**
* @param kind either LINE, TRIANGLE, RECT, ELLIPSE, ARC, SPHERE, BOX
* @param kind either POINT, LINE, TRIANGLE, QUAD, RECT, ELLIPSE, ARC, BOX, SPHERE
* @param p parameters that match the kind of shape
*/
public PShape createShape(int kind, float... p) {
+99 -14
View File
@@ -1500,6 +1500,7 @@ public class PGraphics extends PImage implements PConstants {
vertexCount++;
}
/**
* Used by renderer subclasses or PShape to efficiently pass in already
* formatted vertex information.
@@ -1614,6 +1615,7 @@ public class PGraphics extends PImage implements PConstants {
showMissingWarning("beginContour");
}
/**
* @webref shape:vertex
*/
@@ -1626,6 +1628,7 @@ public class PGraphics extends PImage implements PConstants {
endShape(OPEN);
}
/**
* ( begin auto-generated from endShape.xml )
*
@@ -1646,10 +1649,12 @@ public class PGraphics extends PImage implements PConstants {
}
//////////////////////////////////////////////////////////////
// SHAPE I/O
/**
* @webref shape
* @param filename name of file to load, can be .svg or .obj
@@ -1660,6 +1665,7 @@ public class PGraphics extends PImage implements PConstants {
return loadShape(filename, null);
}
/**
* @nowebref
*/
@@ -1674,6 +1680,7 @@ public class PGraphics extends PImage implements PConstants {
// SHAPE CREATION
/**
* @webref shape
* @see PShape
@@ -1681,36 +1688,113 @@ public class PGraphics extends PImage implements PConstants {
* @see PApplet#loadShape(String)
*/
public PShape createShape() {
showMissingWarning("createShape");
return null;
// Defaults to GEOMETRY (rather than GROUP like the default constructor)
// because that's how people will use it within a sketch.
return createShape(PShape.GEOMETRY);
}
public PShape createShape(PShape source) {
showMissingWarning("createShape");
return null;
}
/**
* @param type either POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP
*/
// POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP
public PShape createShape(int type) {
showMissingWarning("createShape");
// If it's a PRIMITIVE, it needs the 'params' field anyway
if (type == PConstants.GROUP ||
type == PShape.PATH ||
type == PShape.GEOMETRY) {
return createShapeFamily(type);
}
final String msg =
"Only GROUP, PShape.PATH, and PShape.GEOMETRY work with createShape()";
throw new IllegalArgumentException(msg);
}
/** Override this method to return an appropriate shape for your renderer */
protected PShape createShapeFamily(int type) {
showMethodWarning("createShape()");
return null;
}
/**
* @param kind either LINE, TRIANGLE, RECT, ELLIPSE, ARC, SPHERE, BOX
* @param kind either POINT, LINE, TRIANGLE, QUAD, RECT, ELLIPSE, ARC, BOX, SPHERE
* @param p parameters that match the kind of shape
*/
public PShape createShape(int kind, float... p) {
showMissingWarning("createShape");
int len = p.length;
if (kind == POINT) {
if (is3D() && len != 2 && len != 3) {
throw new IllegalArgumentException("Use createShape(POINT, x, y) or createShape(POINT, x, y, z)");
} else if (len != 2) {
throw new IllegalArgumentException("Use createShape(POINT, x, y)");
}
return createShapePrimitive(kind, p);
} else if (kind == LINE) {
if (is3D() && len != 4 && len != 6) {
throw new IllegalArgumentException("Use createShape(LINE, x1, y1, x2, y2) or createShape(LINE, x1, y1, z1, x2, y2, z1)");
} else if (len != 4) {
throw new IllegalArgumentException("Use createShape(LINE, x1, y1, x2, y2)");
}
return createShapePrimitive(kind, p);
} else if (kind == TRIANGLE) {
if (len != 6) {
throw new IllegalArgumentException("Use createShape(TRIANGLE, x1, y1, x2, y2, x3, y3)");
}
return createShapePrimitive(kind, p);
} else if (kind == QUAD) {
if (len != 8) {
throw new IllegalArgumentException("Use createShape(QUAD, x1, y1, x2, y2, x3, y3, x4, y4)");
}
return createShapePrimitive(kind, p);
} else if (kind == RECT) {
if (len != 4 && len != 5 && len != 8 && len != 9) {
throw new IllegalArgumentException("Wrong number of parameters for createShape(RECT), see the reference");
}
return createShapePrimitive(kind, p);
} else if (kind == ELLIPSE) {
if (len != 4 && len != 5) {
throw new IllegalArgumentException("Use createShape(ELLIPSE, x, y, w, h) or createShape(ELLIPSE, x, y, w, h, mode)");
}
return createShapePrimitive(kind, p);
} else if (kind == ARC) {
if (len != 6 && len != 7) {
throw new IllegalArgumentException("Use createShape(ARC, x, y, w, h, start, stop)");
}
return createShapePrimitive(kind, p);
} else if (kind == BOX) {
if (!is3D()) {
throw new IllegalArgumentException("createShape(BOX) is not supported in 2D");
} else if (len != 1 && len != 3) {
throw new IllegalArgumentException("Use createShape(BOX, size) or createShape(BOX, width, height, depth)");
}
return createShapePrimitive(kind, p);
} else if (kind == SPHERE) {
if (!is3D()) {
throw new IllegalArgumentException("createShape(SPHERE) is not supported in 2D");
} else if (len != 1) {
throw new IllegalArgumentException("Use createShape(SPHERE, radius)");
}
return createShapePrimitive(kind, p);
}
throw new IllegalArgumentException("Unknown shape type passed to createShape()");
}
protected PShape createShapePrimitive(int kind, float... p) {
showMethodWarning("createShape()");
return null;
}
//////////////////////////////////////////////////////////////
// SHADERS
@@ -1754,6 +1838,7 @@ public class PGraphics extends PImage implements PConstants {
showMissingWarning("shader");
}
/**
* @param kind type of shader, either POINTS, LINES, or TRIANGLES
*/
+28 -26
View File
@@ -538,41 +538,31 @@ public class PGraphicsJava2D extends PGraphics {
//////////////////////////////////////////////////////////////
// SHAPES
//////////////////////////////////////////////////////////////
// SHAPE CREATION
@Override
protected PShape createShapeFamily(int type) {
return new PShape(this, type);
}
@Override
protected PShape createShapePrimitive(int kind, float... p) {
return new PShape(this, kind, p);
}
// @Override
// public PShape createShape(PShape source) {
// return PShapeOpenGL.createShape2D(this, source);
// }
@Override
public PShape createShape() {
return createShape(PShape.GEOMETRY);
}
@Override
public PShape createShape(int type) {
return createShapeImpl(this, type);
}
@Override
public PShape createShape(int kind, float... p) {
return createShapeImpl(this, kind, p);
}
static protected PShape createShapeImpl(PGraphicsJava2D pg, int type) {
/*
protected PShape createShapeImpl(PGraphicsJava2D pg, int type) {
PShape shape = null;
if (type == PConstants.GROUP) {
shape = new PShape(pg, PConstants.GROUP);
@@ -581,11 +571,14 @@ public class PGraphicsJava2D extends PGraphics {
} else if (type == PShape.GEOMETRY) {
shape = new PShape(pg, PShape.GEOMETRY);
}
shape.set3D(false);
// defaults to false, don't assign it and make complexity for overrides
//shape.set3D(false);
return shape;
}
*/
/*
static protected PShape createShapeImpl(PGraphicsJava2D pg,
int kind, float... p) {
PShape shape = null;
@@ -652,9 +645,18 @@ public class PGraphicsJava2D extends PGraphics {
shape.setParams(p);
}
shape.set3D(false);
// defaults to false, don't assign it and make complexity for overrides
//shape.set3D(false);
return shape;
}
*/
//////////////////////////////////////////////////////////////
// SHAPES
@Override
+42 -27
View File
@@ -23,9 +23,9 @@
package processing.core;
import java.util.HashMap;
import java.util.Map;
import processing.core.PApplet;
import processing.core.PGraphicsJava2D;
/**
@@ -79,11 +79,11 @@ import processing.core.PGraphicsJava2D;
*/
public class PShape implements PConstants {
protected String name;
protected HashMap<String,PShape> nameTable;
protected Map<String,PShape> nameTable;
// /** Generic, only draws its child objects. */
// static public final int GROUP = 0;
// GROUP now inherited from PConstants
// GROUP now inherited from PConstants, and is still zero
/** A line, ellipse, arc, image, etc. */
static public final int PRIMITIVE = 1;
/** A series of vertex, curveVertex, and bezierVertex calls. */
@@ -147,7 +147,7 @@ public class PShape implements PConstants {
public float depth;
PGraphicsJava2D g;
PGraphics g;
// set to false if the object is hidden in the layers palette
protected boolean visible = true;
@@ -271,6 +271,7 @@ public class PShape implements PConstants {
// public float px;
// public float py;
/**
* @nowebref
*/
@@ -278,6 +279,7 @@ public class PShape implements PConstants {
this.family = GROUP;
}
/**
* @nowebref
*/
@@ -285,45 +287,45 @@ public class PShape implements PConstants {
this.family = family;
}
/**
* @nowebref
*/
public PShape(PGraphicsJava2D pg, int family) {
this.g = pg;
public PShape(PGraphics g, int family) {
this.g = g;
this.family = family;
this.parent = null;
// Style parameters are retrieved from the current values in the renderer.
textureMode = pg.textureMode;
textureMode = g.textureMode;
colorMode(pg.colorMode,
pg.colorModeX, pg.colorModeY, pg.colorModeZ, pg.colorModeA);
colorMode(g.colorMode,
g.colorModeX, g.colorModeY, g.colorModeZ, g.colorModeA);
// Initial values for fill, stroke and tint colors are also imported from
// the renderer. This is particular relevant for primitive shapes, since is
// not possible to set their color separately when creating them, and their
// input vertices are actually generated at rendering time, by which the
// color configuration of the renderer might have changed.
fill = pg.fill;
fillColor = pg.fillColor;
fill = g.fill;
fillColor = g.fillColor;
stroke = pg.stroke;
strokeColor = pg.strokeColor;
strokeWeight = pg.strokeWeight;
strokeCap = pg.strokeCap;
strokeJoin = pg.strokeJoin;
stroke = g.stroke;
strokeColor = g.strokeColor;
strokeWeight = g.strokeWeight;
strokeCap = g.strokeCap;
strokeJoin = g.strokeJoin;
tint = pg.tint;
tintColor = pg.tintColor;
tint = g.tint;
tintColor = g.tintColor;
setAmbient = pg.setAmbient;
ambientColor = pg.ambientColor;
specularColor = pg.specularColor;
emissiveColor = pg.emissiveColor;
shininess = pg.shininess;
setAmbient = g.setAmbient;
ambientColor = g.ambientColor;
specularColor = g.specularColor;
emissiveColor = g.emissiveColor;
shininess = g.shininess;
sphereDetailU = pg.sphereDetailU;
sphereDetailV = pg.sphereDetailV;
sphereDetailU = g.sphereDetailU;
sphereDetailV = g.sphereDetailV;
// bezierDetail = pg.bezierDetail;
// curveDetail = pg.curveDetail;
@@ -346,10 +348,23 @@ public class PShape implements PConstants {
if (family == GROUP) {
// GROUP shapes are always marked as ended.
// shapeCreated = true;
// TODO why was this commented out?
}
}
public PShape(PGraphics g, int kind, float... params) {
this(g, PRIMITIVE);
setKind(kind);
setParams(params);
}
public void setFamily(int family) {
this.family = family;
}
public void setKind(int kind) {
this.kind = kind;
}
@@ -1565,7 +1580,7 @@ public class PShape implements PConstants {
/**
* Draws the SVG document.
*/
public void drawImpl(PGraphics g) {
protected void drawImpl(PGraphics g) {
if (family == GROUP) {
drawGroup(g);
} else if (family == PRIMITIVE) {
+14 -1
View File
@@ -26,7 +26,6 @@ import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import processing.core.PMatrix3D;
import processing.core.PShape;
@@ -275,6 +274,19 @@ public class PGraphics2D extends PGraphicsOpenGL {
// SHAPE CREATION
// @Override
// protected PShape createShapeFamily(int type) {
// return new PShapeOpenGL(this, type);
// }
//
//
// @Override
// protected PShape createShapePrimitive(int kind, float... p) {
// return new PShapeOpenGL(this, kind, p);
// }
/*
@Override
public PShape createShape(PShape source) {
return PShapeOpenGL.createShape2D(this, source);
@@ -382,6 +394,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
shape.set3D(false);
return shape;
}
*/
//////////////////////////////////////////////////////////////
@@ -26,7 +26,6 @@ import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import processing.core.PMatrix3D;
import processing.core.PShape;
@@ -276,6 +275,7 @@ public class PGraphics2D2X extends PGraphicsOpenGL {
// SHAPE CREATION
/*
@Override
public PShape createShape(PShape source) {
return PShapeOpenGL.createShape2D(this, source);
@@ -383,6 +383,7 @@ public class PGraphics2D2X extends PGraphicsOpenGL {
shape.set3D(false);
return shape;
}
*/
//////////////////////////////////////////////////////////////
+19 -1
View File
@@ -26,7 +26,6 @@ import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import processing.core.PShape;
import processing.core.PShapeOBJ;
@@ -158,6 +157,23 @@ public class PGraphics3D extends PGraphicsOpenGL {
// SHAPE CREATION
// @Override
// protected PShape createShapeFamily(int type) {
// PShape shape = new PShapeOpenGL(this, type);
// shape.set3D(true);
// return shape;
// }
//
//
// @Override
// protected PShape createShapePrimitive(int kind, float... p) {
// PShape shape = new PShapeOpenGL(this, kind, p);
// shape.set3D(true);
// return shape;
// }
/*
@Override
public PShape createShape(PShape source) {
return PShapeOpenGL.createShape3D(this, source);
@@ -250,6 +266,7 @@ public class PGraphics3D extends PGraphicsOpenGL {
}
shape = new PShapeOpenGL(pg, PShape.PRIMITIVE);
shape.setKind(ARC);
} else if (kind == BOX) {
if (len != 1 && len != 3) {
showWarning("Wrong number of parameters");
@@ -275,4 +292,5 @@ public class PGraphics3D extends PGraphicsOpenGL {
shape.set3D(true);
return shape;
}
*/
}
@@ -26,7 +26,6 @@ import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import processing.core.PShape;
import processing.core.PShapeOBJ;
@@ -154,6 +153,7 @@ public class PGraphics3D2X extends PGraphicsOpenGL {
}
/*
//////////////////////////////////////////////////////////////
// SHAPE CREATION
@@ -276,4 +276,5 @@ public class PGraphics3D2X extends PGraphicsOpenGL {
shape.set3D(true);
return shape;
}
*/
}
@@ -2154,6 +2154,32 @@ public class PGraphicsOpenGL extends PGraphics {
}
//////////////////////////////////////////////////////////////
// CREATE SHAPE
@Override
protected PShape createShapeFamily(int type) {
PShape shape = new PShapeOpenGL(this, type);
if (is3D()) {
shape.set3D(true);
}
return shape;
}
@Override
protected PShape createShapePrimitive(int kind, float... p) {
PShape shape = new PShapeOpenGL(this, kind, p);
if (is3D()) {
shape.set3D(true);
}
return shape;
}
//////////////////////////////////////////////////////////////
// VERTEX SHAPES
+38 -17
View File
@@ -307,6 +307,8 @@ public class PShapeOpenGL extends PShape {
public PShapeOpenGL(PGraphicsOpenGL pg, int family) {
this.pg = pg;
this.family = family;
pgl = pg.pgl;
context = pgl.createEmptyContext();
@@ -331,7 +333,6 @@ public class PShapeOpenGL extends PShape {
glPointIndex = 0;
this.tessellator = PGraphicsOpenGL.tessellator;
this.family = family;
this.root = this;
this.parent = null;
this.tessellated = false;
@@ -398,6 +399,14 @@ public class PShapeOpenGL extends PShape {
}
/** Create a shape from the PRIMITIVE family, using this kind and these params */
public PShapeOpenGL(PGraphicsOpenGL pg, int kind, float... p) {
this(pg, PRIMITIVE);
setKind(kind);
setParams(p);
}
@Override
public void addChild(PShape who) {
if (who instanceof PShapeOpenGL) {
@@ -594,16 +603,20 @@ public class PShapeOpenGL extends PShape {
public static PShapeOpenGL createShape3D(PGraphicsOpenGL pg, PShape src) {
PShapeOpenGL dest = null;
if (src.getFamily() == GROUP) {
dest = PGraphics3D.createShapeImpl(pg, GROUP);
//dest = PGraphics3D.createShapeImpl(pg, GROUP);
dest = (PShapeOpenGL) ((PGraphics3D) pg).createShapeFamily(GROUP);
copyGroup3D(pg, src, dest);
} else if (src.getFamily() == PRIMITIVE) {
dest = PGraphics3D.createShapeImpl(pg, src.getKind(), src.getParams());
//dest = PGraphics3D.createShapeImpl(pg, src.getKind(), src.getParams());
dest = (PShapeOpenGL) ((PGraphics3D) pg).createShapePrimitive(src.getKind(), src.getParams());
PShape.copyPrimitive(src, dest);
} else if (src.getFamily() == GEOMETRY) {
dest = PGraphics3D.createShapeImpl(pg, PShape.GEOMETRY);
//dest = PGraphics3D.createShapeImpl(pg, PShape.GEOMETRY);
dest = (PShapeOpenGL) ((PGraphics3D) pg).createShapeFamily(PShape.GEOMETRY);
PShape.copyGeometry(src, dest);
} else if (src.getFamily() == PATH) {
dest = PGraphics3D.createShapeImpl(pg, PATH);
dest = (PShapeOpenGL) ((PGraphics3D) pg).createShapeFamily(PShape.PATH);
//dest = PGraphics3D.createShapeImpl(pg, PATH);
PShape.copyPath(src, dest);
}
dest.setName(src.getName());
@@ -617,16 +630,20 @@ public class PShapeOpenGL extends PShape {
static public PShapeOpenGL createShape2D(PGraphicsOpenGL pg, PShape src) {
PShapeOpenGL dest = null;
if (src.getFamily() == GROUP) {
dest = PGraphics2D.createShapeImpl(pg, GROUP);
//dest = PGraphics2D.createShapeImpl(pg, GROUP);
dest = (PShapeOpenGL) ((PGraphics2D) pg).createShapeFamily(GROUP);
copyGroup2D(pg, src, dest);
} else if (src.getFamily() == PRIMITIVE) {
dest = PGraphics2D.createShapeImpl(pg, src.getKind(), src.getParams());
//dest = PGraphics2D.createShapeImpl(pg, src.getKind(), src.getParams());
dest = (PShapeOpenGL) ((PGraphics2D) pg).createShapePrimitive(src.getKind(), src.getParams());
PShape.copyPrimitive(src, dest);
} else if (src.getFamily() == GEOMETRY) {
dest = PGraphics2D.createShapeImpl(pg, PShape.GEOMETRY);
//dest = PGraphics2D.createShapeImpl(pg, PShape.GEOMETRY);
dest = (PShapeOpenGL) ((PGraphics2D) pg).createShapeFamily(PShape.GEOMETRY);
PShape.copyGeometry(src, dest);
} else if (src.getFamily() == PATH) {
dest = PGraphics2D.createShapeImpl(pg, PATH);
//dest = PGraphics2D.createShapeImpl(pg, PATH);
dest = (PShapeOpenGL) ((PGraphics2D) pg).createShapeFamily(PShape.PATH);
PShape.copyPath(src, dest);
}
dest.setName(src.getName());
@@ -2512,14 +2529,18 @@ public class PShapeOpenGL extends PShape {
short[] indices = tessGeo.polyIndices;
PShape tess;
if (is3D()) {
tess = PGraphics3D.createShapeImpl(pg, PShape.GEOMETRY);
} else if (is2D()) {
tess = PGraphics2D.createShapeImpl(pg, PShape.GEOMETRY);
} else {
PGraphics.showWarning("This shape is not either 2D or 3D!");
return null;
}
// if (is3D()) {
// //tess = PGraphics3D.createShapeImpl(pg, PShape.GEOMETRY);
// tess = pg.createShapeFamily(PShape.GEOMETRY);
// } else if (is2D()) {
// //tess = PGraphics2D.createShapeImpl(pg, PShape.GEOMETRY);
// tess = pg.createShapeFamily(PShape.GEOMETRY);
// } else {
// PGraphics.showWarning("This shape is not either 2D or 3D!");
// return null;
// }
tess = pg.createShapeFamily(PShape.GEOMETRY);
tess.set3D(is3D); // if this is a 3D shape, make the new shape 3D as well
tess.beginShape(TRIANGLES);
tess.noStroke();
+17
View File
@@ -1,5 +1,22 @@
0235 (3.0a8)
X pop() was not implemented correctly
X fairly major rewrite of createShape()
X prevents same code from appearing 5x (!) in the source
X improves bad api design with the static createShapeImpl() methods
_ need reference update for createShape()
_ createShape(RECT) uses x/y/w/h, and optionally adds a mode param
_ and optionally the corner radii
_ createShape(ELLIPSE) is x/y/w/h, and optionally adds a mode param
opengl
_ why is createShape() implemented 4x (for P2D, P3D, and 2x versions)?
_ shouldn't be static, run it from the renderer, that's point of createXxx()
_ when did setPath() sneak into PShape? API is nothing like anything else
_ public createShape() method that takes another shape as param?
_ should just be the constructor doing this, or copy()
high priority
+6
View File
@@ -6,11 +6,16 @@ X https://github.com/processing/processing/issues/3224
X also update the Windows and Linux versions
_ we've lost arrow keys to expand items in the examples window
_ sketchbook window too?
_ "Your sketch has been modified externally..." appears erroneously
_ https://github.com/processing/processing/issues/3222
_ add a preference for this while it's being debugged
_ Error message changes from "function" to "method"
_ https://github.com/processing/processing/issues/3225
_ move to launch4j 3.7 http://launch4j.sourceforge.net/
_ ErrorMessageSimplifier should use the language subst stuff
_ also, shouldn't that be one text() method with different args?
_ move processing-java inside the Java Mode?
_ make a Tool that installs it for all platforms, not just OS X
@@ -24,6 +29,7 @@ _ https://github.com/processing/processing/blob/master/app/src/processing/app/
pdex
_ debugger button should show/hide toolbar buttons for step/continue
_ fix hasJavaTabs() function
_ almost always used as a negative, or tied to a 'return' from fxn
_ name isn't tied to its function, but the symptom