Compare commits

...

59 Commits

Author SHA1 Message Date
Sandy Noble
9c224d039b Merge branch 'master' of https://github.com/euphy/polargraphcontroller 2020-03-21 12:50:11 +00:00
Sandy Noble
f8f1f78ce3 Some debugging help. 2020-03-21 12:47:22 +00:00
Sandy Noble
dba2788d1f
Added link to the instructions for building from source. 2019-03-12 20:50:46 +00:00
Sandy Noble
417c18fec7
Add try/catch around the previewQueue(). Fixes #19 2018-11-05 21:36:13 +00:00
Sandy Noble
995db8a8a5
Addition to support gcode without Z codes 2018-10-28 15:18:33 +00:00
Sandy Noble
8e263852ee Merge branch 'master' of https://github.com/euphy/polargraphcontroller 2018-09-16 01:47:37 +01:00
Sandy Noble
6665883c9b v2.6 added ability to invert the mask to reveal instead of hide 2018-09-16 01:47:25 +01:00
Sandy Noble
75fe43ddcb Added handler for 5-part SYNC command. 2018-08-19 16:48:04 +01:00
Sandy Noble
aadca73b17
Update README.md 2018-05-27 23:05:45 +01:00
Sandy Noble
5e7e010a79 v2.5.2 - UI changes to make cycling er, work properly. Changed the .toMM() method of the Machine class to be floaty. This helps rendering a bit. 2018-05-27 23:01:08 +01:00
Sandy Noble
f2b1df7405 Fixed merge 2017-06-25 21:58:42 +01:00
Sandy Noble
9307c4e61e Minor tweaks to window sizes 2017-06-25 21:50:44 +01:00
Sandy Noble
f32f22abae v2.4.3 fixes for D2S gcode import 2017-06-25 17:22:29 +01:00
Sandy Noble
c545545f19 Merge branch 'master' of https://github.com/euphy/polargraphcontroller 2017-06-25 17:18:56 +01:00
Sandy Noble
0c687ed234 Fixed some gcode importing gotchas 2017-06-25 17:12:18 +01:00
MurKit
936d918402 Dropdown selects the actual selected port (#15)
Also mentioned against issue #14.
2017-04-20 23:35:17 +01:00
Sandy Noble
d74881f2de #14 Serial port now choosable 2017-04-20 23:30:31 +01:00
Sandy Noble
7da0e7e378 #14 converted serial port radio button to dropdown control - still has debug code in place because I don't have multiple serial ports to test with on home pc. 2017-04-17 22:33:57 +01:00
Sandy Noble
a7f37d8553 Updated a couple of bits in @jerabina 's pull request 2016-03-30 12:45:40 +01:00
Sandy Noble
6b49794cc1 Merge pull request #9 from jerabina/patch-1
remembering last directory, gcode file extensions, unpackGCodeInstruction repair loading Gcode the character ; at the end of the line
2016-03-29 22:41:49 +01:00
Luboš Jeřábek
eddaf3661a Update polargraphcontroller.pde 2016-03-29 16:21:25 +02:00
Luboš Jeřábek
3bf418fa93 And next remove debugging code
remove debugging code
2016-03-29 14:44:35 +02:00
Luboš Jeřábek
3909dee0a7 Update polargraphcontroller.pde
sorry I was distracted
2016-03-29 13:55:09 +02:00
Luboš Jeřábek
bbcae8b079 Update polargraphcontroller.pde
Change  wrong case variablles, remove debugging code
2016-03-29 13:49:39 +02:00
Sandy Noble
d584624791 Made polygonizer changeable, and polygonizerLength too. Also fixed the machine origin while zooming, yep - they said it couldn't be done. I done it. 2016-03-28 15:37:20 +01:00
jerabina
bd1d19018e I joined remembering directory with pictures, curves (LastImageDir) and setting (LastPrefDir) 2016-03-17 21:42:01 +01:00
Sandy Noble
71713b5246 v2.3.0 2016-01-26 23:16:05 +00:00
Sandy Noble
6f6755f231 Couldn't decide whether to use windowWidth or frameWidth. 2016-01-26 23:15:21 +00:00
Sandy Noble
2fbe578954 Made the density preview depth linked to the pen width. 2016-01-26 23:11:57 +00:00
Sandy Noble
c221b9456c Repaired the queue preview 2016-01-26 12:54:21 +00:00
Sandy Noble
69ab977f90 Fixing merge 2016-01-26 12:50:48 +00:00
Sandy Noble
cd61a66253 Wrapping with try catch to make a bit more robust. 2016-01-26 12:48:44 +00:00
Sandy Noble
81b45259e3 v2.2.2 better startup options 2016-01-24 16:40:22 +00:00
Sandy Noble
dba8bb5b2a Added the posterization feature into the density preview 2016-01-17 22:37:24 +00:00
Sandy Noble
74636289e5 Got the console working again. 2016-01-02 22:00:12 +00:00
Sandy Noble
1179fd7471 Added a safety net for when the machine auto-fit-to-window goes wrong. 2015-11-10 22:53:47 +00:00
Sandy Noble
a1bdca895f Auto fit machine to window, fix tab label sizes, cycle density preview styles, hurray 2015-10-25 11:09:31 +00:00
Sandy Noble
70eaae51bd Fixed problem where controllers placed outside of the window didn't work - thanks to https://github.com/sojamo/controlp5/issues/26 2015-10-25 01:29:40 +01:00
Sandy Noble
e84d027d43 Update to v2.1.0 2015-10-24 22:17:15 +01:00
Sandy Noble
4b3f7c5edd Added density preview cycling 2015-10-24 22:12:44 +01:00
Sandy Noble
3b5648085c Added .txt as a valid gcode extension 2015-10-24 18:35:14 +01:00
Sandy Noble
1b0455a886 Re-added the gcode importing 2015-10-24 18:34:45 +01:00
Sandy Noble
f48d625b49 Merge 2015-10-24 15:26:40 +01:00
Sandy Noble
cbd018fc3d Adding a slash. Don't even remember why. 2015-10-24 15:23:48 +01:00
Sandy Noble
87e11f6b93 Removing initImages() from setup(), duh 2015-10-10 10:31:40 +01:00
Sandy Noble
7f2421f0d8 Update README.md 2015-09-13 18:39:52 +01:00
Sandy Noble
142e91d830 Merge branch 'master' into processing_v2 2015-09-13 18:17:28 +01:00
Sandy Noble
f27d625cc2 Cleaned up a little. 2015-09-13 18:07:56 +01:00
Sandy Noble
6510da9a45 All done for processing v2 2015-09-05 22:02:43 +01:00
Sandy Noble
00cd41eaeb Norwegian pixel dialog working. 2015-09-05 18:33:45 +01:00
Sandy Noble
d005b1bb0c Most control frames now working. 2015-09-05 16:00:22 +01:00
Sandy Noble
f9ab305fad Merge branch 'processing_v2' of https://github.com/euphy/polargraphcontroller into processing_v2 2015-08-16 12:20:16 +01:00
Sandy Noble
cbb2678aef Quite a few things working. The window focus is still a bit weird. 2015-08-16 12:19:19 +01:00
Sandy Noble
cc7774edc2 Update README.md 2015-07-18 10:01:02 +01:00
Sandy Noble
d075117fbf Added star.gco example 2015-07-15 21:21:37 +01:00
Sandy Noble
4bf7cf2680 Update README.md 2015-04-26 23:08:15 +01:00
Sandy Noble
1abe63bba6 Split Draw pixels window out, started on draw writing 2015-04-26 23:00:04 +01:00
Sandy Noble
fdf2bca1c0 Added MAchineExecWindow class 2015-04-26 20:58:07 +01:00
Sandy Noble
cb4fa89674 Updated a bunch of stuff to make it compile and run in Processing v2 2015-04-26 12:13:35 +01:00
21 changed files with 2599 additions and 1993 deletions

52
ControlFrame.pde Normal file
View File

@ -0,0 +1,52 @@
// the ControlFrame class extends PApplet, so we
// are creating a new processing applet inside a
// new frame with a controlP5 object loaded
public class ControlFrame extends PApplet {
public int w, h;
int abc = 100;
public ControlP5 cp5;
protected PApplet parent;
private ControlFrame() {
}
public ControlFrame(PApplet theParent, int theWidth, int theHeight) {
this.parent = theParent;
this.w = theWidth;
this.h = theHeight;
}
public ControlP5 cp5() {
if (this.cp5 == null) {
this.cp5 = this.setupControlP5();
}
return this.cp5;
}
public PApplet getParent() {
return this.parent;
}
public void setup() {
size(w, h);
frameRate(5);
}
public ControlP5 setupControlP5() {
println("About to create new ControlP5");
ControlP5 cp5 = new ControlP5(this);
println("Created: " + cp5);
while (cp5 == null) {
println("Was null: " + cp5);
}
println("Finally created: " + cp5);
return cp5;
}
public void draw() {
background(abc);
}
}

40
ControlFrameSimple.pde Normal file
View File

@ -0,0 +1,40 @@
// the ControlFrame class extends PApplet, so we
// are creating a new processing applet inside a
// new frame with a controlP5 object loaded
public class ControlFrameSimple extends PApplet {
int w, h;
int bg;
public void setup() {
size(w, h);
frameRate(5);
cp5 = new ControlP5( this );
}
public void draw() {
background( bg );
}
private ControlFrameSimple() {
}
public ControlFrameSimple(Object theParent, int theWidth, int theHeight, int theColor) {
parent = theParent;
w = theWidth;
h = theHeight;
bg = theColor;
}
public ControlP5 cp5() {
return this.cp5;
}
ControlP5 cp5;
Object parent;
}

View File

@ -25,8 +25,8 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
class DisplayMachine extends Machine class DisplayMachine extends Machine
{ {
private Rectangle outline = null; private Rectangle outline = null;
@ -316,6 +316,10 @@ class DisplayMachine extends Machine
{ {
drawExtractedPixelCentres(); drawExtractedPixelCentres();
} }
if (displayingGridSpots)
{
drawGridIntersections();
}
if (displayingDensityPreview) if (displayingDensityPreview)
{ {
drawExtractedPixelDensities(); drawExtractedPixelDensities();
@ -532,10 +536,13 @@ class DisplayMachine extends Machine
beginShape(); beginShape();
inShape = true; inShape = true;
} }
// PVector nativeCoords = asNativeCoords(inSteps(p));
// println(j + "! Adding point " + nativeCoords);
p = scaleToScreen(p); p = scaleToScreen(p);
stroke(strokeColour); stroke(strokeColour);
vertex(p.x, p.y); vertex(p.x, p.y);
//ellipse(p.x, p.y, 3, 3); // ellipse(p.x, p.y, 2, 2);
} }
else else
{ {
@ -660,10 +667,18 @@ class DisplayMachine extends Machine
*/ */
public void drawRows() public void drawRows()
{ {
PVector mVect = getMouseVector(); float rowThickness = inMM(getGridSize()) * getScaling();
rowThickness = (rowThickness < 1.0) ? 1.0 : rowThickness;
strokeWeight(rowThickness);
stroke(150, 200, 255, 50);
strokeCap(SQUARE);
drawRow(getMouseVector(), true, true);
noStroke();
}
public void drawRow(PVector mouse, boolean left, boolean right) {
// scale it to find out the coordinates on the machine that the mouse is pointing at. // scale it to find out the coordinates on the machine that the mouse is pointing at.
mVect = scaleToDisplayMachine(mVect); PVector mVect = scaleToDisplayMachine(mouse);
// convert it to the native coordinates system // convert it to the native coordinates system
mVect = convertToNative(mVect); mVect = convertToNative(mVect);
// snap it to the grid // snap it to the grid
@ -674,17 +689,15 @@ class DisplayMachine extends Machine
// and finally, because scaleToScreen also allows for the machine position (offset), subtract it. // and finally, because scaleToScreen also allows for the machine position (offset), subtract it.
mVect.sub(getOffset()); mVect.sub(getOffset());
float rowThickness = inMM(getGridSize()) * getScaling();
rowThickness = (rowThickness < 1.0) ? 1.0 : rowThickness;
strokeWeight(rowThickness);
stroke(150, 200, 255, 50);
strokeCap(SQUARE);
float dia = mVect.x*2; float dia = mVect.x*2;
arc(getOutline().getLeft(), getOutline().getTop(), dia, dia, 0, 1.57079633); if (left) {
arc(getOutline().getLeft(), getOutline().getTop(), dia, dia, 0, 1.57079633);
}
dia = mVect.y*2; dia = mVect.y*2;
arc(getOutline().getRight(), getOutline().getTop(), dia, dia, 1.57079633, 3.14159266); if (right) {
arc(getOutline().getRight(), getOutline().getTop(), dia, dia, 1.57079633, 3.14159266);
}
} }
@ -701,6 +714,28 @@ class DisplayMachine extends Machine
line(scaledPos.x-1, scaledPos.y+1, scaledPos.x+1, scaledPos.y-1); line(scaledPos.x-1, scaledPos.y+1, scaledPos.x+1, scaledPos.y-1);
} }
} }
void drawGridIntersections()
{
// println("oh");
}
int pixel_maxDensity(float penSize, float rowSizeInMM)
{
float numberOfSegments = rowSizeInMM / penSize;
int maxDens = 1;
if (numberOfSegments >= 2.0) {
maxDens = int(numberOfSegments);
}
if (maxDens <= 1) {
maxDens = 1;
}
return maxDens;
}
void drawExtractedPixelDensities() void drawExtractedPixelDensities()
{ {
@ -709,17 +744,38 @@ class DisplayMachine extends Machine
pixelSize = (pixelSize < 1.0) ? 1.0 : pixelSize; pixelSize = (pixelSize < 1.0) ? 1.0 : pixelSize;
pixelSize = pixelSize * getPixelScalingOverGridSize(); pixelSize = pixelSize * getPixelScalingOverGridSize();
float rowSizeInMM = inMM(getGridSize()) * getPixelScalingOverGridSize();
int posterizeLevels = 255;
if (previewPixelDensityRange) {
posterizeLevels = pixel_maxDensity(currentPenWidth, rowSizeInMM);
}
else {
posterizeLevels = densityPreviewPosterize;
}
if (getExtractedPixels() != null) if (getExtractedPixels() != null)
{ {
for (PVector cartesianPos : getExtractedPixels()) for (PVector cartesianPos : getExtractedPixels())
{ {
if ((cartesianPos.z <= pixelExtractBrightThreshold) && (cartesianPos.z >= pixelExtractDarkThreshold)) if ((cartesianPos.z <= pixelExtractBrightThreshold) &&
(cartesianPos.z >= pixelExtractDarkThreshold))
{ {
// scale em, danno. // scale em, danno.
PVector scaledPos = scaleToScreen(cartesianPos); PVector scaledPos = scaleToScreen(cartesianPos);
noStroke(); noStroke();
fill(cartesianPos.z); if ((scaledPos.x <= 0) || (scaledPos.x > windowWidth) ||
(scaledPos.y <= 0) || (scaledPos.y > windowHeight)) {
continue;
}
// Posterize the density value
int reduced = int(map(cartesianPos.z, 1, 255, 1, posterizeLevels)+0.5);
int brightness = int(map(reduced, 1, posterizeLevels, 1, 255));
fill(brightness);
switch (getDensityPreviewStyle()) switch (getDensityPreviewStyle())
{ {
case DENSITY_PREVIEW_ROUND: case DENSITY_PREVIEW_ROUND:
@ -727,20 +783,20 @@ class DisplayMachine extends Machine
break; break;
case DENSITY_PREVIEW_ROUND_SIZE: case DENSITY_PREVIEW_ROUND_SIZE:
fill(0); fill(0);
previewRoundPixel(scaledPos, map(cartesianPos.z, 1, 255, pixelSize, 1)); previewRoundPixel(scaledPos, map(brightness, 1, posterizeLevels, pixelSize, 1));
break; break;
case DENSITY_PREVIEW_DIAMOND: case DENSITY_PREVIEW_DIAMOND:
previewDiamondPixel(scaledPos, pixelSize, pixelSize, cartesianPos.z); previewDiamondPixel(scaledPos, pixelSize, pixelSize, brightness);
break; break;
case DENSITY_PREVIEW_NATIVE: case DENSITY_PREVIEW_NATIVE:
previewNativePixel(scaledPos, pixelSize, cartesianPos.z); previewNativePixel(scaledPos, pixelSize, brightness);
break; break;
case DENSITY_PREVIEW_NATIVE_SIZE: case DENSITY_PREVIEW_NATIVE_SIZE:
previewNativePixel(scaledPos, map(cartesianPos.z, 1, 255, pixelSize, 1), 50); previewNativePixel(scaledPos, map(brightness, 1, posterizeLevels, pixelSize, 1), 50);
break; break;
case DENSITY_PREVIEW_NATIVE_ARC: case DENSITY_PREVIEW_NATIVE_ARC:
previewRoundPixel(scaledPos, pixelSize*0.8); previewRoundPixel(scaledPos, pixelSize*0.8);
previewNativeArcPixel(scaledPos, pixelSize, cartesianPos.z); previewNativeArcPixel(scaledPos, pixelSize, brightness);
break; break;
default: default:
previewRoundPixel(scaledPos, pixelSize); previewRoundPixel(scaledPos, pixelSize);
@ -767,8 +823,6 @@ class DisplayMachine extends Machine
void previewNativePixel(PVector pos, float size, float brightness) void previewNativePixel(PVector pos, float size, float brightness)
{ {
float half = size / 2.0; float half = size / 2.0;
fill(0,0,0, 255-brightness);
beginShape();
// arcs from the left-hand corner // arcs from the left-hand corner
float distFromPointA = getOutline().getTopLeft().dist(pos); float distFromPointA = getOutline().getTopLeft().dist(pos);
@ -776,14 +830,19 @@ class DisplayMachine extends Machine
List<PVector> int1 = findIntersections(getOutline().getLeft(), distFromPointA-half, getOutline().getRight(), distFromPointB-half, size); List<PVector> int1 = findIntersections(getOutline().getLeft(), distFromPointA-half, getOutline().getRight(), distFromPointB-half, size);
List<PVector> int2 = findIntersections(getOutline().getLeft(), distFromPointA+half, getOutline().getRight(), distFromPointB-half, size); List<PVector> int2 = findIntersections(getOutline().getLeft(), distFromPointA+half, getOutline().getRight(), distFromPointB-half, size);
// plot out the vertexes if (!int1.isEmpty() && !int2.isEmpty()) {
vertex(int1.get(0).x, int1.get(0).y); fill(0,0,0, 255-brightness);
vertex(int2.get(0).x, int2.get(0).y); beginShape();
vertex(int2.get(1).x, int2.get(1).y);
vertex(int1.get(1).x, int1.get(1).y); // plot out the vertexes
vertex(int1.get(0).x, int1.get(0).y); vertex(int1.get(0).x, int1.get(0).y);
endShape(); vertex(int2.get(0).x, int2.get(0).y);
vertex(int2.get(1).x, int2.get(1).y);
vertex(int1.get(1).x, int1.get(1).y);
vertex(int1.get(0).x, int1.get(0).y);
endShape();
}
} }
void previewNativeArcPixel(PVector pos, float size, float brightness) void previewNativeArcPixel(PVector pos, float size, float brightness)
@ -802,25 +861,30 @@ class DisplayMachine extends Machine
// plot out the vertexes // plot out the vertexes
noFill(); noFill();
stroke(0,0,0, 255-brightness); stroke(0,0,0, 255-brightness);
try {
float i1Angle1 = atan2(int1.get(0).y-getOutline().getTop(), int1.get(0).x-getOutline().getLeft()); float i1Angle1 = atan2(int1.get(0).y-getOutline().getTop(), int1.get(0).x-getOutline().getLeft());
float i1Angle2 = atan2(int1.get(1).y-getOutline().getTop(), int1.get(1).x-getOutline().getLeft()); float i1Angle2 = atan2(int1.get(1).y-getOutline().getTop(), int1.get(1).x-getOutline().getLeft());
arc(getOutline().getLeft(), getOutline().getTop(), (distFromPointA-half)*2, (distFromPointA-half)*2, i1Angle1, i1Angle2); arc(getOutline().getLeft(), getOutline().getTop(), (distFromPointA-half)*2, (distFromPointA-half)*2, i1Angle1, i1Angle2);
i1Angle1 = atan2(int2.get(0).y-getOutline().getTop(), int2.get(0).x-getOutline().getLeft()); i1Angle1 = atan2(int2.get(0).y-getOutline().getTop(), int2.get(0).x-getOutline().getLeft());
i1Angle2 = atan2(int2.get(1).y-getOutline().getTop(), int2.get(1).x-getOutline().getLeft()); i1Angle2 = atan2(int2.get(1).y-getOutline().getTop(), int2.get(1).x-getOutline().getLeft());
arc(getOutline().getLeft(), getOutline().getTop(), (distFromPointA+half)*2, (distFromPointA+half)*2, i1Angle1, i1Angle2); arc(getOutline().getLeft(), getOutline().getTop(), (distFromPointA+half)*2, (distFromPointA+half)*2, i1Angle1, i1Angle2);
i1Angle1 = atan2( int1.get(0).y-getOutline().getTop(), int1.get(0).x-getOutline().getRight()); i1Angle1 = atan2( int1.get(0).y-getOutline().getTop(), int1.get(0).x-getOutline().getRight());
i1Angle2 = atan2( int2.get(0).y-getOutline().getTop(), int2.get(0).x-getOutline().getRight()); i1Angle2 = atan2( int2.get(0).y-getOutline().getTop(), int2.get(0).x-getOutline().getRight());
arc(getOutline().getRight(), getOutline().getTop(), (distFromPointB-half)*2, (distFromPointB-half)*2, i1Angle2, i1Angle1); arc(getOutline().getRight(), getOutline().getTop(), (distFromPointB-half)*2, (distFromPointB-half)*2, i1Angle2, i1Angle1);
i1Angle1 = atan2( int1.get(1).y-getOutline().getTop(), int1.get(1).x-getOutline().getRight()); i1Angle1 = atan2( int1.get(1).y-getOutline().getTop(), int1.get(1).x-getOutline().getRight());
i1Angle2 = atan2( int2.get(1).y-getOutline().getTop(), int2.get(1).x-getOutline().getRight()); i1Angle2 = atan2( int2.get(1).y-getOutline().getTop(), int2.get(1).x-getOutline().getRight());
arc(getOutline().getRight(), getOutline().getTop(), (distFromPointB+half)*2, (distFromPointB+half)*2, i1Angle2, i1Angle1); arc(getOutline().getRight(), getOutline().getTop(), (distFromPointB+half)*2, (distFromPointB+half)*2, i1Angle2, i1Angle1);
}
catch (IndexOutOfBoundsException ioobe) {
endShape(); println(ioobe);
}
finally {
endShape();
}
} }

138
DrawPixelsWindow.pde Normal file
View File

@ -0,0 +1,138 @@
///*------------------------------------------------------------------------
// Details about the "drawing" subwindow
//------------------------------------------------------------------------*/
public Integer renderStartDirection = DRAW_DIR_SE; // default start drawing in SE direction (DOWN)
public Integer renderStartPosition = DRAW_DIR_NE; // default top right hand corner for start
public Integer renderStyle = PIXEL_STYLE_SQ_FREQ; // default pixel style square wave
ControlFrameSimple addDrawPixelsControlFrame(String theName, int theWidth, int theHeight, int theX, int theY, int theColor ) {
final Frame f = new Frame( theName );
final ControlFrameSimple p = new ControlFrameSimple( this, theWidth, theHeight, theColor );
f.add( p );
p.init();
f.setTitle(theName);
f.setSize( p.w, p.h );
f.setLocation( theX, theY );
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
p.dispose();
f.dispose();
}
}
);
f.setResizable( true );
f.setVisible( true );
// sleep a little bit to allow p to call setup.
// otherwise a nullpointerexception might be caused.
try {
Thread.sleep( 100 );
}
catch(Exception e) {
}
// set up controls
RadioButton rPos = p.cp5().addRadioButton("radio_startPosition",10,10)
.add("Top-right", DRAW_DIR_NE)
.add("Bottom-right", DRAW_DIR_SE)
.add("Bottom-left", DRAW_DIR_SW)
.add("Top-left", DRAW_DIR_NW)
.plugTo(this, "radio_startPosition");
RadioButton rSkip = p.cp5().addRadioButton("radio_pixelSkipStyle",10,100)
.add("Lift pen over masked pixels", 1)
.add("Draw masked pixels as blanks", 2)
.plugTo(this, "radio_pixelSkipStyle");
RadioButton rStyle = p.cp5().addRadioButton("radio_pixelStyle",100,10);
rStyle.add("Variable frequency square wave", PIXEL_STYLE_SQ_FREQ);
rStyle.add("Variable size square wave", PIXEL_STYLE_SQ_SIZE);
rStyle.add("Solid square wave", PIXEL_STYLE_SQ_SOLID);
rStyle.add("Scribble", PIXEL_STYLE_SCRIBBLE);
if (currentHardware >= HARDWARE_VER_MEGA) {
rStyle.add("Spiral", PIXEL_STYLE_CIRCLE);
rStyle.add("Sawtooth", PIXEL_STYLE_SAW);
}
rStyle.plugTo(this, "radio_pixelStyle");
Button submitButton = p.cp5().addButton("submitDrawWindow",0,280,10,120,20)
.setLabel("Generate commands")
.plugTo(this, "submitDrawWindow");
return p;
}
void radio_startPosition(int pos) {
renderStartPosition = pos;
radio_rowStartDirection(1);
}
void radio_rowStartDirection(int dir) {
if (renderStartPosition == DRAW_DIR_NE || renderStartPosition == DRAW_DIR_SW)
renderStartDirection = (dir == 0) ? DRAW_DIR_NW : DRAW_DIR_SE;
else if (renderStartPosition == DRAW_DIR_SE || renderStartPosition == DRAW_DIR_NW)
renderStartDirection = (dir == 0) ? DRAW_DIR_NE : DRAW_DIR_SW;
}
void radio_pixelStyle(int style) {
renderStyle = style;
}
void radio_pixelSkipStyle(int style) {
if (style == 1)
liftPenOnMaskedPixels = true;
else if (style == 2)
liftPenOnMaskedPixels = false;
}
void submitDrawWindow(int theValue) {
println("draw.");
println("Style: " + renderStyle);
println("Start pos: " + renderStartPosition);
println("Start dir: " + renderStartDirection);
switch (renderStyle) {
case PIXEL_STYLE_SQ_FREQ: button_mode_renderSquarePixel(); break;
case PIXEL_STYLE_SQ_SIZE: button_mode_renderScaledSquarePixels(); break;
case PIXEL_STYLE_SQ_SOLID: button_mode_renderSolidSquarePixels(); break;
case PIXEL_STYLE_SCRIBBLE: button_mode_renderScribblePixels(); break;
case PIXEL_STYLE_CIRCLE: button_mode_renderCirclePixel(); break;
case PIXEL_STYLE_SAW: button_mode_renderSawPixel(); break;
}
}
class DrawPixelsWindow extends ControlFrame {
public DrawPixelsWindow () {
super(parentPapplet, 450, 150);
int xPos = 100;
int yPos = 100;
String name = DRAW_PIXELS_WINDOW_NAME;
final Frame f = new Frame(DRAW_PIXELS_WINDOW_NAME);
f.add(this);
this.init();
f.setTitle(CHANGE_SERIAL_PORT_WINDOW_NAME);
f.setSize(super.w, super.h);
f.setLocation(xPos, yPos);
f.setResizable(false);
f.setVisible(true);
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
f.dispose();
}
});
}
}

439
FileLoading.pde Normal file
View File

@ -0,0 +1,439 @@
/**
Polargraph controller
Copyright Sandy Noble 2018.
This file is part of Polargraph Controller.
Polargraph Controller is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Polargraph Controller is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
sandy.noble@gmail.com
http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller
*/
void loadImageWithFileChooser()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run() {
JFileChooser fc = new JFileChooser();
if (lastImageDirectory != null) fc.setCurrentDirectory(lastImageDirectory);
fc.setFileFilter(new ImageFileFilter());
fc.setDialogTitle("Choose an image file...");
int returned = fc.showOpenDialog(frame);
lastImageDirectory = fc.getCurrentDirectory();
if (returned == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
// see if it's an image
PImage img = loadImage(file.getPath());
if (img != null)
{
img = null;
getDisplayMachine().loadNewImageFromFilename(file.getPath());
if (getDisplayMachine().pixelsCanBeExtracted() && isBoxSpecified())
{
getDisplayMachine().extractPixelsFromArea(getBoxVector1(), getBoxVectorSize(), getGridSize(), sampleArea);
}
}
}
}
});
}
class ImageFileFilter extends javax.swing.filechooser.FileFilter
{
public boolean accept(File file) {
String filename = file.getName();
filename.toLowerCase();
if (file.isDirectory() || filename.endsWith(".png") || filename.endsWith(".jpg") || filename.endsWith(".jpeg"))
return true;
else
return false;
}
public String getDescription() {
return "Image files (PNG or JPG)";
}
}
void loadVectorWithFileChooser()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run() {
JFileChooser fc = new JFileChooser();
if (lastImageDirectory != null)
{
fc.setCurrentDirectory(lastImageDirectory);
}
fc.setFileFilter(new VectorFileFilter());
fc.setDialogTitle("Choose a vector file...");
int returned = fc.showOpenDialog(frame);
lastImageDirectory = fc.getCurrentDirectory();
if (returned == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
if (file.exists())
{
RShape shape = loadShapeFromFile(file.getPath());
if (shape != null)
{
setVectorFilename(file.getPath());
setVectorShape(shape);
}
else
{
println("File not found (" + file.getPath() + ")");
}
}
}
}
}
);
}
class VectorFileFilter extends javax.swing.filechooser.FileFilter
{
public boolean accept(File file) {
String filename = file.getName();
filename.toLowerCase();
if (file.isDirectory() || filename.endsWith(".svg") || isGCodeExtension(filename))
return true;
else
return false;
}
public String getDescription() {
return "Vector graphic files (SVG, GCode)";
}
}
void loadNewPropertiesFilenameWithFileChooser()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JFileChooser fc = new JFileChooser();
if (lastPropertiesDirectory != null) fc.setCurrentDirectory(lastPropertiesDirectory);
fc.setFileFilter(new PropertiesFileFilter());
fc.setDialogTitle("Choose a config file...");
int returned = fc.showOpenDialog(frame);
lastPropertiesDirectory = fc.getCurrentDirectory();
if (returned == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
if (file.exists())
{
println("New properties file exists.");
newPropertiesFilename = file.toString();
println("new propertiesFilename: "+ newPropertiesFilename);
propertiesFilename = newPropertiesFilename;
// clear old properties.
props = null;
loadFromPropertiesFile();
// set values of number spinners etc
updateNumberboxValues();
}
}
}
});
}
class PropertiesFileFilter extends javax.swing.filechooser.FileFilter
{
public boolean accept(File file) {
String filename = file.getName();
filename.toLowerCase();
if (file.isDirectory() || filename.endsWith(".properties.txt"))
return true;
else
return false;
}
public String getDescription() {
return "Properties files (*.properties.txt)";
}
}
void saveNewPropertiesFileWithFileChooser()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JFileChooser fc = new JFileChooser();
if (lastPropertiesDirectory != null) fc.setCurrentDirectory(lastPropertiesDirectory);
fc.setFileFilter(new PropertiesFileFilter());
fc.setDialogTitle("Enter a config file name...");
int returned = fc.showSaveDialog(frame);
if (returned == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
newPropertiesFilename = file.toString();
newPropertiesFilename.toLowerCase();
if (!newPropertiesFilename.endsWith(".properties.txt"))
newPropertiesFilename+=".properties.txt";
println("new propertiesFilename: "+ newPropertiesFilename);
propertiesFilename = newPropertiesFilename;
savePropertiesFile();
// clear old properties.
props = null;
loadFromPropertiesFile();
}
}
});
}
RShape loadShapeFromFile(String filename) {
RShape sh = null;
if (filename.toLowerCase().endsWith(".svg")) {
sh = RG.loadShape(filename);
}
else if (isGCodeExtension(filename)) {
sh = loadShapeFromGCodeFile(filename);
}
return sh;
}
boolean isGCodeExtension(String filename) {
return (filename.toLowerCase().endsWith(".gcode") || filename.toLowerCase().endsWith(".g") || filename.toLowerCase().endsWith(".ngc") || filename.toLowerCase().endsWith(".txt"));
}
int countLines(String filename) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
return (count == 0 && !empty) ? 1 : count+1;
} finally {
is.close();
}
}
RShape loadShapeFromGCodeFile(String filename) {
noLoop();
RShape parent = null;
BufferedReader reader = null;
long totalPoints = 0;
long time = millis();
long countLines = 0;
try {
countLines = countLines(filename);
println("" + countLines + " lines found.");
if (countLines < 1) {
throw new IOException("No lines found in GCode file.");
}
reader = createReader(filename);
parent = new RShape();
String line;
boolean drawLine = false;
int gCodeZAxisChanges = 0;
long lineNo = 0;
float lastPercent = 0.0f;
boolean reportStatus = true;
while ((line = reader.readLine ()) != null) {
lineNo++;
// println("Line: " + line);
if (reportStatus) {
float percent = ((float)lineNo / (float)countLines) * 100.0;
println("----" + percent + "% of the way through.");
lastPercent = percent;
}
if (line.toUpperCase().startsWith("G")) {
if (reportStatus) {
println(new StringBuilder().append(lineNo).append(" of ").append(countLines).append(": ").append(line).append(". Points: ").append(totalPoints).toString());
long free = Runtime.getRuntime().freeMemory();
long maximum = Runtime.getRuntime().maxMemory();
println(new StringBuilder().append("Free: ").append(free).append(", max: ").append(maximum).toString());
}
Map<String, Float> ins = null;
try {
ins = unpackGCodeInstruction(line);
}
catch (Exception e) {
println(e.toString());
continue;
}
// println("Ins: " + ins);
Integer code = Math.round(ins.get("G"));
Float z = ins.get("Z");
if (z != null) {
gCodeZAxisChanges++;
if (gCodeZAxisChanges == 2) {
println("Assume second z axis change is to drop the pen to start drawing " + z);
gcodeZAxisDrawingHeight = z;
drawLine = true;
}
else if (gCodeZAxisChanges > 2) {
drawLine = isGCodeZAxisForDrawing(z);
}
else {
println("Assume first z axis change is to RAISE the pen " + z);
drawLine = false;
}
}
else { // if there is no Z axis, assume it's always on
// drawLine = true; // this isn't always safe!
}
Float x = ins.get("X");
Float y = ins.get("Y");
if (x != null && y == null) {
// move x axis only, use y of last
RPoint[][] points = parent.getPointsInPaths();
RPoint rp = points[points.length-1][points[points.length-1].length-1];
y = rp.y;
}
else if (x == null && y != null) {
// move y axis only, use x of last
RPoint[][] points = parent.getPointsInPaths();
RPoint rp = points[points.length-1][points[points.length-1].length-1];
x = rp.x;
}
if (x != null && y != null) {
// move both x and y axis
if (drawLine) {
parent.addLineTo(x, y);
}
else {
parent.addMoveTo(x, y);
}
}
}
else {
}
if ((millis() - time) > 500) {
time = millis();
reportStatus = true;
}
else {
reportStatus = false;
}
if (lineNo == (countLines-1)) {
reportStatus = true;
}
}
}
catch (IOException e) {
println("IOExecption reading lines from the gcode file " + filename);
e.printStackTrace();
}
finally {
try {
reader.close();
}
catch (IOException e) {
println("IOException closing the gcode file " + filename);
e.printStackTrace();
}
}
RPoint[][] points = parent.getPointsInPaths();
totalPoints = 0;
if (points != null) {
for (int i = 0; i<points.length; i++) {
if (points[i] != null) {
for (int j = 0; j<points[i].length; j++) {
totalPoints++;
}
}
}
}
String conclusionMessage = "Imported " + totalPoints + " points from " + countLines + " lines of code in the file.";
println(conclusionMessage);
javax.swing.JOptionPane.showMessageDialog(null, conclusionMessage);
loop();
return parent;
}
Boolean isGCodeZAxisForDrawing(float z) {
return gcodeZAxisDrawingHeight.compareTo(z) == 0;
}
Map<String, Float> unpackGCodeInstruction(String line) throws Exception {
Map<String, Float> instruction = new HashMap<String, Float>(4);
try {
String[] splitted = line.trim().split(" ");
for (int i = 0; i < splitted.length; i++) {
// remove ; character
splitted[i] = splitted[i].replace(";", "");
String axis = splitted[i].substring(0, 1);
String sanitisedValue = splitted[i].substring(1);
sanitisedValue = sanitisedValue.replace(",", ".");
Float value = Float.parseFloat(sanitisedValue);
if ("X".equalsIgnoreCase(axis) || "Y".equalsIgnoreCase(axis) || "Z".equalsIgnoreCase(axis) || "G".equalsIgnoreCase(axis)) {
instruction.put(axis.toUpperCase(), value);
}
}
// println("instruction: " + instruction);
if (instruction.isEmpty()) {
throw new Exception("Empty instruction");
}
}
catch (NumberFormatException nfe) {
println("Number format exception: " + nfe.getMessage());
}
catch (Exception e) {
println("e: " + e);
throw new Exception("Exception while reading the lines from a gcode file: " + line + ", " + e.getMessage());
}
return instruction;
}

View File

@ -25,7 +25,11 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/
/**
*
*
*
*/ */
class Machine class Machine
{ {
@ -35,7 +39,7 @@ class Machine
protected Rectangle imageFrame = new Rectangle(1500,1500,1000,1000); protected Rectangle imageFrame = new Rectangle(1500,1500,1000,1000);
protected Rectangle pictureFrame = new Rectangle(1600,1600,800,800); protected Rectangle pictureFrame = new Rectangle(1600,1600,800,800);
protected Float stepsPerRev = 800.0; protected Float stepsPerRev = 200.0;
protected Float mmPerRev = 95.0; protected Float mmPerRev = 95.0;
protected Float mmPerStep = null; protected Float mmPerStep = null;
@ -182,9 +186,15 @@ class Machine
return mmInt; return mmInt;
} }
public float inMMFloat(float steps)
{
double mm = steps / getStepsPerMM();
return (float) mm;
}
public PVector inMM (PVector steps) public PVector inMM (PVector steps)
{ {
PVector mm = new PVector(inMM(steps.x), inMM(steps.y)); PVector mm = new PVector(inMMFloat(steps.x), inMMFloat(steps.y));
return mm; return mm;
} }
@ -282,6 +292,16 @@ class Machine
} }
} }
boolean isMasked(PVector pos, float scalingFactor)
{
switch (invertMaskMode) {
case MASK_IS_UNUSED: return false;
case MASKED_COLOURS_ARE_HIDDEN: return isChromaKey(pos, scalingFactor);
case MASKED_COLOURS_ARE_SHOWN: return !isChromaKey(pos, scalingFactor);
default: return false;
}
}
boolean isChromaKey(PVector pos, float scalingFactor) boolean isChromaKey(PVector pos, float scalingFactor)
{ {
if (getImageFrame().surrounds(pos)) if (getImageFrame().surrounds(pos))
@ -318,8 +338,8 @@ class Machine
public PVector asCartesianCoords(PVector pgCoords) public PVector asCartesianCoords(PVector pgCoords)
{ {
float calcX = int((pow(getWidth(), 2) - pow(pgCoords.y, 2) + pow(pgCoords.x, 2)) / (getWidth()*2)); float calcX = (pow(getWidth(), 2.0) - pow(pgCoords.y, 2.0) + pow(pgCoords.x, 2.0)) / (getWidth()*2.0);
float calcY = int(sqrt(pow(pgCoords.x,2)-pow(calcX,2))); float calcY = sqrt(pow(pgCoords.x,2.0)-pow(calcX,2.0));
PVector vect = new PVector(calcX, calcY); PVector vect = new PVector(calcX, calcY);
return vect; return vect;
} }
@ -360,7 +380,7 @@ class Machine
public void loadDefinitionFromProperties(Properties props) public void loadDefinitionFromProperties(Properties props)
{ {
// get these first because they are important to convert the rest of them // get these first because they are important to convert the rest of them
setStepsPerRev(getFloatProperty("machine.motors.stepsPerRev", 800.0)); setStepsPerRev(getFloatProperty("machine.motors.stepsPerRev", 200.0));
setMMPerRev(getFloatProperty("machine.motors.mmPerRev", 95.0)); setMMPerRev(getFloatProperty("machine.motors.mmPerRev", 95.0));
// now stepsPerMM and mmPerStep should have been calculated. It's safe to get the rest. // now stepsPerMM and mmPerStep should have been calculated. It's safe to get the rest.
@ -379,12 +399,12 @@ class Machine
String pos = getStringProperty("controller.page.position.x", "CENTRE"); String pos = getStringProperty("controller.page.position.x", "CENTRE");
float px = 0.0; float px = 0.0;
println("machine size: " + getSize().x + ", " + inSteps(pageSize.x)); println("machine size: " + getSize().x + ", " + inSteps(pageSize.x));
if (pos.equalsIgnoreCase("CENTRE")) if (pos.equalsIgnoreCase("CENTRE")) {
{
px = inMM((getSize().x - pageSize.x) / 2.0); px = inMM((getSize().x - pageSize.x) / 2.0);
} }
else else {
px = getFloatProperty("controller.page.position.x", (int) getDisplayMachine().getPageCentrePosition(pageSize.x)); px = getFloatProperty("controller.page.position.x", (int) getDisplayMachine().getPageCentrePosition(pageSize.x));
}
float py = getFloatProperty("controller.page.position.y", 120); float py = getFloatProperty("controller.page.position.y", 120);
@ -616,7 +636,7 @@ class Machine
PVector cartesianCoord = asCartesianCoords(nativeCoord); PVector cartesianCoord = asCartesianCoords(nativeCoord);
if (selectedArea.surrounds(cartesianCoord)) if (selectedArea.surrounds(cartesianCoord))
{ {
if (isChromaKey(cartesianCoord, scalingFactor)) if (isMasked(cartesianCoord, scalingFactor))
{ {
nativeCoord.z = MASKED_PIXEL_BRIGHTNESS; // magic number nativeCoord.z = MASKED_PIXEL_BRIGHTNESS; // magic number
nativeCoords.add(nativeCoord); nativeCoords.add(nativeCoord);

64
MachineExecWindow.pde Normal file
View File

@ -0,0 +1,64 @@
ControlFrameSimple addMachineExecControlFrame(String theName, int theWidth, int theHeight, int theX, int theY, int theColor ) {
final Frame f = new Frame( theName );
final ControlFrameSimple p = new ControlFrameSimple( this, theWidth, theHeight, theColor );
f.add( p );
p.init();
f.setTitle(theName);
f.setSize( p.w, p.h );
f.setLocation( theX, theY );
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
p.dispose();
f.dispose();
}
}
);
f.setResizable( true );
f.setVisible( true );
// sleep a little bit to allow p to call setup.
// otherwise a nullpointerexception might be caused.
try {
Thread.sleep( 100 );
}
catch(Exception e) {
}
// set up controls
Textfield filenameField = p.cp5().addTextfield("machineExec_execFilename",20,20,150,20)
.setText(getStoreFilename())
.setLabel("Filename to execute from")
.addListener( new ControlListener() {
public void controlEvent( ControlEvent ev ) {
machineExec_execFilename(ev.getController().getStringValue());
Textfield tf = p.cp5().get(Textfield.class, "machineExec_execFilename");
}
});
Button submitButton = p.cp5().addButton("machineExec_submitExecFilenameWindow",0,180,20,60,20)
.setLabel("Submit")
.addListener( new ControlListener() {
public void controlEvent( ControlEvent ev ) {
p.cp5().get(Textfield.class, "machineExec_execFilename").submit();
p.cp5().get(Textfield.class, "machineExec_execFilename").setText(getStoreFilename());
}
});
filenameField.setFocus(true);
return p;
}
void machineExec_execFilename(String filename) {
println("Filename event: "+ filename);
if (filename != null
&& filename.length() <= 12
&& !"".equals(filename.trim())) {
filename = filename.trim();
setStoreFilename(filename);
sendMachineExecMode();
}
}

77
MachineStoreWindow.pde Normal file
View File

@ -0,0 +1,77 @@
/*------------------------------------------------------------------------
Details about the "machine store" subwindow
------------------------------------------------------------------------*/
ControlFrameSimple addMachineStoreControlFrame(String theName, int theWidth, int theHeight, int theX, int theY, int theColor ) {
final Frame f = new Frame( theName );
final ControlFrameSimple p = new ControlFrameSimple( this, theWidth, theHeight, theColor );
f.add( p );
p.init();
f.setTitle(theName);
f.setSize( p.w, p.h );
f.setLocation( theX, theY );
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
p.dispose();
f.dispose();
}
}
);
f.setResizable( true );
f.setVisible( true );
// sleep a little bit to allow p to call setup.
// otherwise a nullpointerexception might be caused.
try {
Thread.sleep( 100 );
}
catch(Exception e) {
}
// set up controls
Textfield filenameField = p.cp5().addTextfield("machineStore_storeFilename",20,20,150,20)
.setText(getStoreFilename())
.setLabel("Filename to store to")
.addListener( new ControlListener() {
public void controlEvent( ControlEvent ev ) {
machineStore_storeFilename(ev.getController().getStringValue());
Textfield tf = p.cp5().get(Textfield.class, "machineExec_execFilename");
}
});
Button submitButton = p.cp5().addButton("machineStore_submitStoreFilenameWindow",0,180,20,60,20)
.setLabel("Submit")
.addListener( new ControlListener() {
public void controlEvent( ControlEvent ev ) {
p.cp5().get(Textfield.class, "machineStore_storeFilename").submit();
p.cp5().get(Textfield.class, "machineStore_storeFilename").setText(getStoreFilename());
}
});
Toggle overwriteToggle = p.cp5().addToggle("machineStore_toggleAppendToFile",true,180,50,20,20)
.setCaptionLabel("Overwrite existing file")
.plugTo(this, "machineStore_toggleAppendToFile");
filenameField.setFocus(true);
return p;
}
void machineStore_toggleAppendToFile(boolean theFlag) {
setOverwriteExistingStoreFile(theFlag);
}
void machineStore_storeFilename(String filename) {
println("Filename event: "+ filename);
if (filename != null
&& filename.length() <= 12
&& !"".equals(filename.trim())) {
filename = filename.trim();
setStoreFilename(filename);
sendMachineStoreMode();
}
}

399
Misc.pde
View File

@ -25,7 +25,6 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
class Scaler class Scaler
@ -53,202 +52,202 @@ class PreviewVector extends PVector
{ {
public String command; public String command;
} }
//
//
import java.awt.Toolkit; //import java.awt.Toolkit;
import java.awt.BorderLayout; //import java.awt.BorderLayout;
import java.awt.GraphicsEnvironment; //import java.awt.GraphicsEnvironment;
//
public class Console extends WindowAdapter implements WindowListener, ActionListener, Runnable //public class Console extends WindowAdapter implements WindowListener, ActionListener, Runnable
{ //{
private JFrame frame; // private JFrame frame;
private JTextArea textArea; // private JTextArea textArea;
private Thread reader; // private Thread reader;
private Thread reader2; // private Thread reader2;
private boolean quit; // private boolean quit;
//
private final PipedInputStream pin=new PipedInputStream(); // private final PipedInputStream pin=new PipedInputStream();
private final PipedInputStream pin2=new PipedInputStream(); // private final PipedInputStream pin2=new PipedInputStream();
//
private PrintStream cOut = System.out; // private PrintStream cOut = System.out;
private PrintStream cErr = System.err; // private PrintStream cErr = System.err;
//
Thread errorThrower; // just for testing (Throws an Exception at this Console // Thread errorThrower; // just for testing (Throws an Exception at this Console
//
public Console() // public Console()
{ // {
// create all components and add them // // create all components and add them
frame=new JFrame("Java Console"); // frame=new JFrame("Java Console");
Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize(); // Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize=new Dimension((int)(screenSize.width/2),(int)(screenSize.height/2)); // Dimension frameSize=new Dimension((int)(screenSize.width/2),(int)(screenSize.height/2));
int x=(int)(frameSize.width/2); // int x=(int)(frameSize.width/2);
int y=(int)(frameSize.height/2); // int y=(int)(frameSize.height/2);
frame.setBounds(x,y,frameSize.width,frameSize.height); // frame.setBounds(x,y,frameSize.width,frameSize.height);
//
textArea=new JTextArea(); // textArea=new JTextArea();
textArea.setEditable(false); // textArea.setEditable(false);
JButton button=new JButton("clear"); // JButton button=new JButton("clear");
//
frame.getContentPane().setLayout(new BorderLayout()); // frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(new JScrollPane(textArea),BorderLayout.CENTER); // frame.getContentPane().add(new JScrollPane(textArea),BorderLayout.CENTER);
frame.getContentPane().add(button,BorderLayout.SOUTH); // frame.getContentPane().add(button,BorderLayout.SOUTH);
frame.setVisible(true); // frame.setVisible(true);
//
frame.addWindowListener(this); // frame.addWindowListener(this);
button.addActionListener(this); // button.addActionListener(this);
//
try // try
{ // {
this.cOut = System.out; // this.cOut = System.out;
PipedOutputStream pout=new PipedOutputStream(this.pin); // PipedOutputStream pout=new PipedOutputStream(this.pin);
System.setOut(new PrintStream(pout,true)); // System.setOut(new PrintStream(pout,true));
} // }
catch (java.io.IOException io) // catch (java.io.IOException io)
{ // {
textArea.append("Couldn't redirect STDOUT to this console\n"+io.getMessage()); // textArea.append("Couldn't redirect STDOUT to this console\n"+io.getMessage());
} // }
catch (SecurityException se) // catch (SecurityException se)
{ // {
textArea.append("Couldn't redirect STDOUT to this console\n"+se.getMessage()); // textArea.append("Couldn't redirect STDOUT to this console\n"+se.getMessage());
} // }
//
try // try
{ // {
this.cErr = System.err; // this.cErr = System.err;
PipedOutputStream pout2=new PipedOutputStream(this.pin2); // PipedOutputStream pout2=new PipedOutputStream(this.pin2);
System.setErr(new PrintStream(pout2,true)); // System.setErr(new PrintStream(pout2,true));
} // }
catch (java.io.IOException io) // catch (java.io.IOException io)
{ // {
textArea.append("Couldn't redirect STDERR to this console\n"+io.getMessage()); // textArea.append("Couldn't redirect STDERR to this console\n"+io.getMessage());
} // }
catch (SecurityException se) // catch (SecurityException se)
{ // {
textArea.append("Couldn't redirect STDERR to this console\n"+se.getMessage()); // textArea.append("Couldn't redirect STDERR to this console\n"+se.getMessage());
} // }
//
quit=false; // signals the Threads that they should exit // quit=false; // signals the Threads that they should exit
//
// Starting two seperate threads to read from the PipedInputStreams // // Starting two seperate threads to read from the PipedInputStreams
// // //
reader=new Thread(this); // reader=new Thread(this);
reader.setDaemon(true); // reader.setDaemon(true);
reader.start(); // reader.start();
// // //
reader2=new Thread(this); // reader2=new Thread(this);
reader2.setDaemon(true); // reader2.setDaemon(true);
reader2.start(); // reader2.start();
//
// // testing part //// // testing part
// // you may omit this part for your application //// // you may omit this part for your application
// // //// //
// System.out.println("Hello World 2"); //// System.out.println("Hello World 2");
// System.out.println("All fonts available to Graphic2D:\n"); //// System.out.println("All fonts available to Graphic2D:\n");
// GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); //// GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
// String[] fontNames=ge.getAvailableFontFamilyNames(); //// String[] fontNames=ge.getAvailableFontFamilyNames();
// for(int n=0;n<fontNames.length;n++) System.out.println(fontNames[n]); //// for(int n=0;n<fontNames.length;n++) System.out.println(fontNames[n]);
// // Testing part: simple an error thrown anywhere in this JVM will be printed on the Console //// // Testing part: simple an error thrown anywhere in this JVM will be printed on the Console
// // We do it with a seperate Thread becasue we don't wan't to break a Thread used by the Console. //// // We do it with a seperate Thread becasue we don't wan't to break a Thread used by the Console.
// System.out.println("\nLets throw an error on this console"); //// System.out.println("\nLets throw an error on this console");
// errorThrower=new Thread(this); //// errorThrower=new Thread(this);
// errorThrower.setDaemon(true); //// errorThrower.setDaemon(true);
// errorThrower.start(); //// errorThrower.start();
} // }
//
public synchronized void windowClosed(WindowEvent evt) // public synchronized void windowClosed(WindowEvent evt)
{ // {
quit=true; // quit=true;
this.notifyAll(); // stop all threads // this.notifyAll(); // stop all threads
try { // try {
reader.join(1000); // reader.join(1000);
pin.close(); // pin.close();
System.setOut(this.cOut); // System.setOut(this.cOut);
} // }
catch (Exception e){ // catch (Exception e){
} // }
try { // try {
reader2.join(1000); // reader2.join(1000);
pin2.close(); // pin2.close();
System.setErr(this.cErr); // System.setErr(this.cErr);
} // }
catch (Exception e){ // catch (Exception e){
} // }
// System.exit(0); //// System.exit(0);
} // }
//
public synchronized void windowClosing(WindowEvent evt) // public synchronized void windowClosing(WindowEvent evt)
{ // {
frame.setVisible(false); // default behaviour of JFrame // frame.setVisible(false); // default behaviour of JFrame
frame.dispose(); // frame.dispose();
} // }
//
public synchronized void actionPerformed(ActionEvent evt) // public synchronized void actionPerformed(ActionEvent evt)
{ // {
textArea.setText(""); // textArea.setText("");
} // }
//
public synchronized void run() // public synchronized void run()
{ // {
try // try
{ // {
while (Thread.currentThread()==reader) // while (Thread.currentThread()==reader)
{ // {
try { // try {
this.wait(100); // this.wait(100);
} // }
catch(InterruptedException ie) { // catch(InterruptedException ie) {
} // }
if (pin.available()!=0) // if (pin.available()!=0)
{ // {
String input=this.readLine(pin); // String input=this.readLine(pin);
textArea.append(input); // textArea.append(input);
textArea.setCaretPosition(textArea.getDocument().getLength()); // textArea.setCaretPosition(textArea.getDocument().getLength());
//
} // }
if (quit) return; // if (quit) return;
} // }
//
while (Thread.currentThread()==reader2) // while (Thread.currentThread()==reader2)
{ // {
try { // try {
this.wait(100); // this.wait(100);
} // }
catch(InterruptedException ie) { // catch(InterruptedException ie) {
} // }
if (pin2.available()!=0) // if (pin2.available()!=0)
{ // {
String input=this.readLine(pin2); // String input=this.readLine(pin2);
textArea.append(input); // textArea.append(input);
textArea.setCaretPosition(textArea.getDocument().getLength()); // textArea.setCaretPosition(textArea.getDocument().getLength());
//
} // }
if (quit) return; // if (quit) return;
} // }
} // }
catch (Exception e) // catch (Exception e)
{ // {
textArea.append("\nConsole reports an Internal error."); // textArea.append("\nConsole reports an Internal error.");
textArea.append("The error is: "+e); // textArea.append("The error is: "+e);
} // }
} // }
//
public void close() // public void close()
{ // {
this.windowClosing(null); // this.windowClosing(null);
} // }
//
public synchronized String readLine(PipedInputStream in) throws IOException // public synchronized String readLine(PipedInputStream in) throws IOException
{ // {
String input=""; // String input="";
do // do
{ // {
int available=in.available(); // int available=in.available();
if (available==0) break; // if (available==0) break;
byte b[]=new byte[available]; // byte b[]=new byte[available];
in.read(b); // in.read(b);
input=input+new String(b,0,b.length); // input=input+new String(b,0,b.length);
} // }
while( !input.endsWith("\n") && !input.endsWith("\r\n") && !quit); // while( !input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
return input; // return input;
} // }
} //}

View File

@ -1,6 +1,6 @@
/** /**
Polargraph controller Polargraph controller
Copyright Sandy Noble 2015. Copyright Sandy Noble 2012.
This file is part of Polargraph Controller. This file is part of Polargraph Controller.
@ -25,7 +25,6 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
class Panel class Panel
{ {
@ -121,9 +120,11 @@ class Panel
public void draw() public void draw()
{ {
// stroke(outlineColour); if (debugPanels) {
// strokeWeight(2); stroke(outlineColour);
// rect(getOutline().getLeft(), getOutline().getTop(), getOutline().getWidth(), getOutline().getHeight()); strokeWeight(2);
rect(getOutline().getLeft(), getOutline().getTop(), getOutline().getWidth(), getOutline().getHeight());
}
drawControls(); drawControls();
} }
@ -132,13 +133,12 @@ class Panel
{ {
for (Controller c : this.getControls()) for (Controller c : this.getControls())
{ {
//println("Control: " + c.name()); PVector pos = getControlPositions().get(c.getName());
PVector pos = getControlPositions().get(c.name());
float x = pos.x+getOutline().getLeft(); float x = pos.x+getOutline().getLeft();
float y = pos.y+getOutline().getTop(); float y = pos.y+getOutline().getTop();
c.setPosition(x, y); c.setPosition(x, y);
PVector cSize = getControlSizes().get(c.name()); PVector cSize = getControlSizes().get(c.getName());
c.setSize((int)cSize.x, (int)cSize.y); c.setSize((int)cSize.x, (int)cSize.y);
boolean locked = false; boolean locked = false;
@ -147,32 +147,39 @@ class Panel
// any drawing / extracting controls are disabled if there is no selec // any drawing / extracting controls are disabled if there is no selec
// box specified. // box specified.
if (getControlsToLockIfBoxNotSpecified().contains(c.name()) && !isBoxSpecified()) if (getControlsToLockIfBoxNotSpecified().contains(c.getName()) && !isBoxSpecified())
{ {
locked = true; locked = true;
} }
// if there is no vector shape loaded then lock the "draw vector" // if there is no vector shape loaded then lock the "draw vector"
// control. // control.
if (c.name().equals(MODE_RENDER_VECTORS) && getVectorShape() == null) if (c.getName().equals(MODE_RENDER_VECTORS) && getVectorShape() == null)
{ {
locked = true; locked = true;
} }
// if there's no image loaded, then hide resizing/moving // if there's no image loaded, then hide resizing/moving
if (getControlsToLockIfImageNotLoaded().contains(c.name()) && getDisplayMachine().getImage() == null) if (getControlsToLockIfImageNotLoaded().contains(c.getName()) && getDisplayMachine().getImage() == null)
{ {
locked = true; locked = true;
} }
// if there's no vector loaded, then hide vector controls
if (getControlsToLockIfVectorNotLoaded().contains(c.getName()) && vectorFilename == null)
{
locked = true;
}
if (c.name().equals(MODE_LOAD_VECTOR_FILE)) if (c.getName().equals(MODE_LOAD_VECTOR_FILE))
{ {
if (getVectorShape() != null) if (getVectorShape() != null)
c.setLabel("Clear vector"); c.setLabel("Clear vector");
else else
c.setLabel("Load vector"); c.setLabel("Load vector");
} }
else if (c.name().equals(MODE_LOAD_IMAGE)) else if (c.getName().equals(MODE_LOAD_IMAGE))
{ {
if (getDisplayMachine().getImage() != null) if (getDisplayMachine().getImage() != null)
c.setLabel("Clear image"); c.setLabel("Clear image");
@ -201,37 +208,29 @@ class Panel
} }
} }
void setHeight(float h) void setSizeByHeight(float h)
{ {
// println("Setting size for " + this.getName());
if (this.isResizable()) if (this.isResizable())
{ {
if (h <= getMinimumHeight()) if (h <= getMinimumHeight())
this.getOutline().setHeight(getMinimumHeight()); this.getOutline().setHeight(getMinimumHeight());
else else
this.getOutline().setHeight(h); this.getOutline().setHeight(h);
setControlPositions(buildControlPositionsForPanel(this)); setControlPositions(buildControlPositionsForPanel(this));
float left = 0.0; float left = 0.0;
String controlName = "";
for (String key : getControlPositions().keySet()) for (String key : getControlPositions().keySet())
{ {
PVector pos = getControlPositions().get(key); PVector pos = getControlPositions().get(key);
if (pos.x >= left) if (pos.x > left)
{ {
left = pos.x; left = pos.x;
controlName = key;
} }
} }
Map<String, PVector> map = getControlSizes();
// PVector size = getControlSizes().get(controlName);
// println("size: " + size);
float right = left + DEFAULT_CONTROL_SIZE.x; float right = left + DEFAULT_CONTROL_SIZE.x;
this.getOutline().setWidth(right); this.getOutline().setWidth(right);
} }
} }
} }

View File

@ -2,19 +2,18 @@ polargraphcontroller
==================== ====================
Polargraph controller Polargraph controller
Copyright Sandy Noble 2014. Copyright Sandy Noble 2018.
- Requires v0.5.4 of the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/ - Requires the excellent ControlP5 GUI library available from https://github.com/sojamo/controlp5.
- (http://code.google.com/p/controlp5/downloads/detail?name=controlP5_0.5.4.zip&can=2&q=).
- Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/. - Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
- Currently only runs on Processing v1.5 - Running on Processing v2.2.1.
This is a desktop application for controlling a polargraph machine, communicating using ASCII command language over a serial link. This is a desktop application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
Very sorry that this doesn't work with newest versions of the libraries and Processing.
The [latest releases bundle] (https://github.com/euphy/polargraphcontroller/releases/latest) contains The [latest releases bundle] (https://github.com/euphy/polargraphcontroller/releases/latest) contains
copies of all the libraries that I use, as well as all the source, and compiled versions of the code where sensible. copies of all the libraries that I use, as well as all the source, and compiled versions of the code where sensible.
How to [run it from source](https://github.com/euphy/polargraph/wiki/Running-the-controller-from-source-code).
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/

View File

@ -25,7 +25,6 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
class Rectangle class Rectangle
{ {
@ -123,4 +122,8 @@ class Rectangle
return false; return false;
} }
public String toString() {
return new StringBuffer().append("Rectangle pos: ").append(this.getPosition()).append(", size: ").append(this.getSize()).append(".").toString();
}
} }

120
SerialPortWindow.pde Normal file
View File

@ -0,0 +1,120 @@
/*------------------------------------------------------------------------
Class and controllers on the "serial port" subwindow
------------------------------------------------------------------------*/
ControlFrameSimple addSerialPortControlFrame(String theName, int theWidth, int theHeight, int theX, int theY, int theColor ) {
final Frame f = new Frame( theName );
final ControlFrameSimple p = new ControlFrameSimple( this, theWidth, theHeight, theColor );
f.add( p );
p.init();
f.setTitle(theName);
f.setSize( p.w, p.h );
f.setLocation( theX, theY );
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
p.dispose();
f.dispose();
}
}
);
f.setResizable( true );
f.setVisible( true );
// sleep a little bit to allow p to call setup.
// otherwise a nullpointerexception might be caused.
try {
Thread.sleep( 100 );
}
catch(Exception e) {
}
ScrollableList sl = p.cp5().addScrollableList("dropdown_serialPort")
.setPosition(10, 10)
.setSize(150, 450)
.setBarHeight(20)
.setItemHeight(16)
.plugTo(this, "dropdown_serialPort");
sl.addItem("No serial connection", -1);
String[] ports = Serial.list();
for (int i = 0; i < ports.length; i++) {
println("Adding " + ports[i]);
sl.addItem(ports[i], i);
}
int portNo = getSerialPortNumber();
println("portNo: " + portNo);
if (portNo < 0 || portNo >= ports.length)
portNo = -1;
// set the value of the actual control
sl.setValue(portNo);
sl.setOpen(true);
return p;
}
void dropdown_serialPort(int newSerialPort)
{
println("In dropdown_serialPort, newSerialPort: " + newSerialPort);
// No serial in list is slot 0 in code because of list index
// So shift port index by one
newSerialPort -= 1;
if (newSerialPort == -2)
{
}
else if (newSerialPort == -1) {
println("Disconnecting serial port.");
useSerialPortConnection = false;
if (myPort != null)
{
myPort.stop();
myPort = null;
}
drawbotReady = false;
drawbotConnected = false;
serialPortNumber = newSerialPort;
}
else if (newSerialPort != getSerialPortNumber()) {
println("About to connect to serial port in slot " + newSerialPort);
// Print a list of the serial ports, for debugging purposes:
if (newSerialPort < Serial.list().length) {
try {
drawbotReady = false;
drawbotConnected = false;
if (myPort != null) {
myPort.stop();
myPort = null;
}
if (getSerialPortNumber() >= 0)
println("closing " + Serial.list()[getSerialPortNumber()]);
serialPortNumber = newSerialPort;
String portName = Serial.list()[serialPortNumber];
myPort = new Serial(this, portName, getBaudRate());
//read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil('\n');
useSerialPortConnection = true;
println("Successfully connected to port " + portName);
}
catch (Exception e) {
println("Attempting to connect to serial port in slot " + getSerialPortNumber()
+ " caused an exception: " + e.getMessage());
}
} else {
println("No serial ports found.");
useSerialPortConnection = false;
}
} else {
println("no serial port change.");
}
}

View File

@ -25,7 +25,6 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
void button_mode_begin() void button_mode_begin()
{ {
@ -164,12 +163,17 @@ void button_mode_liveConfirmDraw()
float scaling = getDisplayMachine().inMM(getDisplayMachine().getImageFrame().getWidth()) / captureShape.getWidth(); float scaling = getDisplayMachine().inMM(getDisplayMachine().getImageFrame().getWidth()) / captureShape.getWidth();
PVector position = new PVector(getDisplayMachine().inMM(getDisplayMachine().getImageFrame().getPosition().x), PVector position = new PVector(getDisplayMachine().inMM(getDisplayMachine().getImageFrame().getPosition().x),
getDisplayMachine().inMM(getDisplayMachine().getImageFrame().getPosition().y)); getDisplayMachine().inMM(getDisplayMachine().getImageFrame().getPosition().y));
int oldPolygonizer = polygonizer;
polygonizer = RG.ADAPTATIVE;
setupPolygonizer();
sendVectorShapes(captureShape, scaling, position, PATH_SORT_CENTRE_FIRST); sendVectorShapes(captureShape, scaling, position, PATH_SORT_CENTRE_FIRST);
button_mode_penUp(); button_mode_penUp();
// save shape as SVG // save shape as SVG
trace_saveShape(captureShape); trace_saveShape(captureShape);
polygonizer = oldPolygonizer;
setupPolygonizer();
} }
} }
void toggle_mode_showWebcamRawVideo(boolean flag) void toggle_mode_showWebcamRawVideo(boolean flag)
@ -319,6 +323,7 @@ void button_mode_loadImage()
getDisplayMachine().setImageFilename(null); getDisplayMachine().setImageFilename(null);
} }
} }
void button_mode_loadVectorFile() void button_mode_loadVectorFile()
{ {
if (getVectorShape() == null) if (getVectorShape() == null)
@ -332,6 +337,7 @@ void button_mode_loadVectorFile()
vectorFilename = null; vectorFilename = null;
} }
} }
void numberbox_mode_pixelBrightThreshold(float value) void numberbox_mode_pixelBrightThreshold(float value)
{ {
pixelExtractBrightThreshold = (int) value; pixelExtractBrightThreshold = (int) value;
@ -527,12 +533,14 @@ void numberbox_mode_changeMachineWidth(float value)
clearBoxVectors(); clearBoxVectors();
float steps = getDisplayMachine().inSteps((int) value); float steps = getDisplayMachine().inSteps((int) value);
getDisplayMachine().getSize().x = steps; getDisplayMachine().getSize().x = steps;
getDisplayMachine().maxLength = null;
} }
void numberbox_mode_changeMachineHeight(float value) void numberbox_mode_changeMachineHeight(float value)
{ {
clearBoxVectors(); clearBoxVectors();
float steps = getDisplayMachine().inSteps((int) value); float steps = getDisplayMachine().inSteps((int) value);
getDisplayMachine().getSize().y = steps; getDisplayMachine().getSize().y = steps;
getDisplayMachine().maxLength = null;
} }
void numberbox_mode_changeMMPerRev(float value) void numberbox_mode_changeMMPerRev(float value)
{ {
@ -609,7 +617,7 @@ void button_mode_sendPenWidth()
NumberFormat nf = NumberFormat.getNumberInstance(Locale.UK); NumberFormat nf = NumberFormat.getNumberInstance(Locale.UK);
DecimalFormat df = (DecimalFormat)nf; DecimalFormat df = (DecimalFormat)nf;
df.applyPattern("###.##"); df.applyPattern("###.##");
addToRealtimeCommandQueue(CMD_CHANGEPENWIDTH+df.format(currentPenWidth)+",END"); addToRealtimeCommandQueue(CMD_SETPENWIDTH+df.format(currentPenWidth)+",END");
} }
void numberbox_mode_changePenTestStartWidth(float value) void numberbox_mode_changePenTestStartWidth(float value)
@ -723,7 +731,49 @@ void button_mode_sendButtonDeactivate()
void numberbox_mode_previewCordOffsetValue(int value) void numberbox_mode_previewCordOffsetValue(int value)
{ {
previewCordOffset = value; previewCordOffset = value;
lastCommandQueueHash = 0; previewQueue(true);
}
void dropdown_mode_cycleDensityPreviewStyle(int index)
{
println("In dropdown_mode_cycleDensityPreviewStyle");
densityPreviewStyle = index;
println("Style: " + densityPreviewStyle);
}
void numberbox_mode_changeDensityPreviewPosterize(int value) {
if (value < 1) value = 1;
else if (value > 255) value = 255;
densityPreviewPosterize = value;
}
void minitoggle_mode_previewPixelDensityRange(boolean flag) {
previewPixelDensityRange = flag;
println("previewPixelDensityRange: " + previewPixelDensityRange);
}
void numberbox_mode_changePolygonizerLength(float value) {
polygonizerLength = value;
setupPolygonizer();
}
void numberbox_mode_changePolygonizerAdaptativeAngle(float value) {
println("numberbox_mode_changePolygonizerAdaptativeAngle");
polygonizerAdaptativeAngle = value;
setupPolygonizer();
}
void dropdown_mode_changePolygonizer(int value)
{
polygonizer = value;
setupPolygonizer();
}
void dropdown_mode_changeMaskInvert(int value)
{
invertMaskMode = value;
rebuildPixels();
} }

View File

@ -1,569 +1,412 @@
/** /**
Polargraph controller Polargraph controller
Copyright Sandy Noble 2015. Copyright Sandy Noble 2015.
This file is part of Polargraph Controller.
Polargraph Controller is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Polargraph Controller is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
sandy.noble@gmail.com
http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller
*/
This file is part of Polargraph Controller. void button_mode_sendMachineLiveMode() {
Polargraph Controller is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Polargraph Controller is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
sandy.noble@gmail.com
http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller
*/
/*------------------------------------------------------------------------
Details about the "serial port" subwindow
------------------------------------------------------------------------*/
void button_mode_serialPortDialog()
{
ControlWindow serialPortWindow = cp5.addControlWindow("changeSerialPortWindow",100,100,150,350);
serialPortWindow.hideCoordinates();
serialPortWindow.setBackground(getBackgroundColour());
Radio r = cp5.addRadio("radio_serialPort",10,10);
r.setWindow(serialPortWindow);
String[] ports = Serial.list();
if (getSerialPortNumber() >= 0 && getSerialPortNumber() < ports.length)
r.setValue(getSerialPortNumber());
r.add("setup", -2);
r.add("No serial connection", -1);
for (int i = 0; i < ports.length; i++)
{
r.add(ports[i], i);
}
int portNo = getSerialPortNumber();
if (portNo > -1 && portNo < ports.length)
r.activate(ports[portNo]);
else
r.activate("No serial connection");
r.removeItem("setup");
}
void radio_serialPort(int newSerialPort)
{
if (newSerialPort == -2)
{
}
else if (newSerialPort == -1)
{
println("Disconnecting serial port.");
useSerialPortConnection = false;
if (myPort != null)
{
myPort.stop();
myPort = null;
}
drawbotReady = false;
drawbotConnected = false;
serialPortNumber = newSerialPort;
}
else if (newSerialPort != getSerialPortNumber())
{
println("About to connect to serial port in slot " + newSerialPort);
// Print a list of the serial ports, for debugging purposes:
if (newSerialPort < Serial.list().length)
{
try
{
drawbotReady = false;
drawbotConnected = false;
if (myPort != null)
{
myPort.stop();
myPort = null;
}
if (getSerialPortNumber() >= 0)
println("closing " + Serial.list()[getSerialPortNumber()]);
serialPortNumber = newSerialPort;
String portName = Serial.list()[serialPortNumber];
myPort = new Serial(this, portName, getBaudRate());
//read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil('\n');
useSerialPortConnection = true;
println("Successfully connected to port " + portName);
}
catch (Exception e)
{
println("Attempting to connect to serial port in slot " + getSerialPortNumber()
+ " caused an exception: " + e.getMessage());
}
}
else
{
println("No serial ports found.");
useSerialPortConnection = false;
}
}
else
{
println("no serial port change.");
}
}
/*------------------------------------------------------------------------
Details about the "machine store" subwindow
------------------------------------------------------------------------*/
ControlWindow dialogWindow = null;
void button_mode_machineStoreDialog()
{
this.dialogWindow = cp5.addControlWindow("chooseStoreFilenameWindow",100,100,450,150);
dialogWindow.hideCoordinates();
dialogWindow.setBackground(getBackgroundColour());
Textfield filenameField = cp5.addTextfield("storeFilename",20,20,150,20);
filenameField.setText(getStoreFilename());
filenameField.setLabel("Filename to store to");
filenameField.setWindow(dialogWindow);
Button submitButton = cp5.addButton("submitStoreFilenameWindow",0,180,20,60,20);
submitButton.setLabel("Submit");
submitButton.setWindow(dialogWindow);
Toggle overwriteToggle = cp5.addToggle("toggleAppendToFile",true,180,50,20,20);
overwriteToggle.setCaptionLabel("Overwrite existing file");
overwriteToggle.setWindow(dialogWindow);
filenameField.setFocus(true);
}
void storeFilename(String filename)
{
println("Filename event: "+ filename);
if (filename != null && filename.length() <= 12)
{
setStoreFilename(filename);
sendMachineStoreMode();
}
}
void toggleAppendToFile(boolean theFlag)
{
setOverwriteExistingStoreFile(theFlag);
}
void submitStoreFilenameWindow(int theValue)
{
Textfield tf = (Textfield) cp5.controller("storeFilename");
tf.submit();
}
void button_mode_machineExecDialog()
{
this.dialogWindow = cp5.addControlWindow("chooseExecFilenameWindow",100,100,450,150);
dialogWindow.hideCoordinates();
dialogWindow.setBackground(getBackgroundColour());
Textfield filenameField = cp5.addTextfield("execFilename",20,20,150,20);
filenameField.setText(getStoreFilename());
filenameField.setLabel("Filename to execute from");
filenameField.setWindow(dialogWindow);
Button submitButton = cp5.addButton("submitExecFilenameWindow",0,180,20,60,20);
submitButton.setLabel("Submit");
submitButton.setWindow(dialogWindow);
filenameField.setFocus(true);
}
void execFilename(String filename)
{
println("Filename event: "+ filename);
if (filename != null && filename.length() <= 12)
{
setStoreFilename(filename);
sendMachineExecMode();
}
}
void submitExecFilenameWindow(int theValue)
{
Textfield tf = (Textfield) cp5.controller("execFilename");
tf.submit();
}
void button_mode_sendMachineLiveMode()
{
sendMachineLiveMode(); sendMachineLiveMode();
} }
String CHANGE_SERIAL_PORT_WINDOW_NAME = "changeSerialPortWindow";
String MACHINE_STORE_WINDOW_NAME = "chooseStoreFilenameWindow";
String MACHINE_EXEC_WINDOW_NAME = "chooseExecFilenameWindow";
String DRAW_PIXELS_WINDOW_NAME = "drawPixelsWindow";
String DRAW_WRITING_WINDOW_NAME = "drawWritingWindow";
void button_mode_serialPortDialog() {
ControlFrameSimple cf = addSerialPortControlFrame("Serial Port", 200, 500, 20, 240, color( 100 ) );
}
void button_mode_machineStoreDialog() {
ControlFrameSimple cf = addMachineStoreControlFrame("Machine Store", 450, 250, 20, 240, color( 100 ) );
}
void button_mode_machineExecDialog() {
ControlFrameSimple cf = addMachineExecControlFrame("Machine Execute", 450, 250, 20, 240, color( 100 ) );
}
/*------------------------------------------------------------------------ void button_mode_drawPixelsDialog() {
Details about the "drawing" subwindow ControlFrameSimple cf = addDrawPixelsControlFrame("Render pixels", 450, 250, 20, 240, color( 100 ) );
------------------------------------------------------------------------*/ }
void button_mode_drawPixelsDialog()
{
this.dialogWindow = cp5.addControlWindow("drawPixelsWindow",100,100,450,150);
dialogWindow.hideCoordinates();
dialogWindow.setBackground(getBackgroundColour());
Radio rPos = cp5.addRadio("radio_startPosition",10,10); void button_mode_drawWritingDialog() {
rPos.add("Top-right", DRAW_DIR_NE); ControlFrameSimple cf = addSpriteWritingControlFrame("Sprite Writing", 450, 250, 20, 240, color( 100 ) );
rPos.add("Bottom-right", DRAW_DIR_SE); }
rPos.add("Bottom-left", DRAW_DIR_SW);
rPos.add("Top-left", DRAW_DIR_NW);
rPos.setWindow(dialogWindow);
Radio rSkip = cp5.addRadio("radio_pixelSkipStyle",10,100); void button_mode_RandomSpriteDialog() {
rSkip.add("Lift pen over masked pixels", 1); ControlFrameSimple cf = addRandomSpriteControlFrame("Random Sprite", 450, 250, 20, 240, color( 100 ) );
rSkip.add("Draw masked pixels as blanks", 2); }
rSkip.setWindow(dialogWindow);
// Radio rDir = cp5.addRadio("radio_rowStartDirection",100,10); void button_mode_drawNorwegianDialog() {
// rDir.add("Upwards", 0); ControlFrameSimple cf = addNorwegianPixelControlFrame("Norwegian Pixel", 450, 250, 20, 240, color( 100 ) );
// rDir.add("Downwards", 1); }
// rDir.setWindow(dialogWindow);
Radio rStyle = cp5.addRadio("radio_pixelStyle",100,10); ///*------------------------------------------------------------------------
rStyle.add("Variable frequency square wave", PIXEL_STYLE_SQ_FREQ); // Details about the "writing" subwindow
rStyle.add("Variable size square wave", PIXEL_STYLE_SQ_SIZE); //------------------------------------------------------------------------*/
rStyle.add("Solid square wave", PIXEL_STYLE_SQ_SOLID);
rStyle.add("Scribble", PIXEL_STYLE_SCRIBBLE); String spriteWriting_textToWrite = "";
if (currentHardware >= HARDWARE_VER_MEGA) String spriteWriting_spriteFilePrefix = "sprite/let";
{ String spriteWriting_spriteFileSuffix = ".txt";
rStyle.add("Spiral", PIXEL_STYLE_CIRCLE);
rStyle.add("Sawtooth", PIXEL_STYLE_SAW); ControlFrameSimple addSpriteWritingControlFrame(String theName, int theWidth, int theHeight, int theX, int theY, int theColor ) {
final Frame f = new Frame( theName );
final ControlFrameSimple p = new ControlFrameSimple( this, theWidth, theHeight, theColor );
f.add( p );
p.init();
f.setTitle(theName);
f.setSize( p.w, p.h );
f.setLocation( theX, theY );
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
p.dispose();
f.dispose();
cp5s.remove(DRAW_WRITING_WINDOW_NAME);
}
} }
rStyle.setWindow(dialogWindow); );
f.setResizable( true );
Button submitButton = cp5.addButton("submitDrawWindow",0,280,10,120,20); f.setVisible( true );
submitButton.setLabel("Generate commands"); // sleep a little bit to allow p to call setup.
submitButton.setWindow(dialogWindow); // otherwise a nullpointerexception might be caused.
try {
Thread.sleep( 100 );
} }
catch(Exception e) {
public Integer renderStartPosition = DRAW_DIR_NE; // default top right hand corner for start
public Integer renderStartDirection = DRAW_DIR_SE; // default start drawing in SE direction (DOWN)
public Integer renderStyle = PIXEL_STYLE_SQ_FREQ; // default pixel style square wave
void radio_startPosition(int pos)
{
this.renderStartPosition = pos;
radio_rowStartDirection(1);
}
void radio_rowStartDirection(int dir)
{
if (renderStartPosition == DRAW_DIR_NE || renderStartPosition == DRAW_DIR_SW)
renderStartDirection = (dir == 0) ? DRAW_DIR_NW : DRAW_DIR_SE;
else if (renderStartPosition == DRAW_DIR_SE || renderStartPosition == DRAW_DIR_NW)
renderStartDirection = (dir == 0) ? DRAW_DIR_NE : DRAW_DIR_SW;
}
void radio_pixelStyle(int style)
{
renderStyle = style;
}
void radio_pixelSkipStyle(int style)
{
if (style == 1)
liftPenOnMaskedPixels = true;
else if (style == 2)
liftPenOnMaskedPixels = false;
}
void submitDrawWindow(int theValue)
{
println("draw.");
println("Style: " + renderStyle);
println("Start pos: " + renderStartPosition);
println("Start dir: " + renderStartDirection);
switch (renderStyle)
{
case PIXEL_STYLE_SQ_FREQ: button_mode_renderSquarePixel(); break;
case PIXEL_STYLE_SQ_SIZE: button_mode_renderScaledSquarePixels(); break;
case PIXEL_STYLE_SQ_SOLID: button_mode_renderSolidSquarePixels(); break;
case PIXEL_STYLE_SCRIBBLE: button_mode_renderScribblePixels(); break;
case PIXEL_STYLE_CIRCLE: button_mode_renderCirclePixel(); break;
case PIXEL_STYLE_SAW: button_mode_renderSawPixel(); break;
} }
cp5s.put(DRAW_WRITING_WINDOW_NAME, p.cp5());
} println(cp5s);
/*------------------------------------------------------------------------
Details about the "writing" subwindow
------------------------------------------------------------------------*/
String textToWrite = "";
String spriteFilePrefix = "sprite/let";
String spriteFileSuffix = ".txt";
void button_mode_drawWritingDialog()
{
this.dialogWindow = cp5.addControlWindow("drawWritingWindow",100,100,450,200);
dialogWindow.hideCoordinates();
dialogWindow.setBackground(getBackgroundColour()); // set up controls
Textfield spriteFileField = p.cp5().addTextfield("spriteWriting_spriteFilePrefixField", 20, 20, 150, 20)
.setText(spriteWriting_getSpriteFilePrefix())
.setLabel("File prefix")
.plugTo(this, "spriteWriting_spriteFilePrefixField");
Textfield spriteFileField = cp5.addTextfield("spriteFilePrefixField",20,20,150,20); Textfield writingField = p.cp5().addTextfield("spriteWriting_textToWriteField", 20, 60, 400, 20)
spriteFileField.setText(getSpriteFilePrefix()); .setText(spriteWriting_getTextToWrite())
spriteFileField.setLabel("File prefix"); .setLabel("Text to write")
spriteFileField.setWindow(dialogWindow); .plugTo(this, "spriteWriting_textToWriteField");
Textfield writingField = cp5.addTextfield("textToWriteField",20,60,400,20); Button importTextButton = p.cp5().addButton("spriteWriting_importTextButton", 0, 20, 100, 120, 20)
writingField.setText(getTextToWrite()); .setLabel("Load text from file")
writingField.setLabel("Text to write"); .addListener( new ControlListener() {
writingField.setWindow(dialogWindow); public void controlEvent( ControlEvent ev ) {
spriteWriting_importTextButton();
}
});
RadioButton rPos = p.cp5().addRadioButton("spriteWriting_radio_drawWritingDirection", 20, 140);
rPos.add("South-east", DRAW_DIR_SE);
rPos.activate("South-east");
rPos.plugTo(this, "spriteWriting_radio_drawWritingDirection");
Button importTextButton = cp5.addButton("importTextButton",0,20,100,120,20); Button submitButton = p.cp5.addButton("spriteWriting_submitWritingWindow", 0, 300, 100, 120, 20)
importTextButton.setLabel("Load text from file"); .setLabel("Generate commands")
importTextButton.setWindow(dialogWindow); .addListener( new ControlListener() {
public void controlEvent( ControlEvent ev ) {
Radio rPos = cp5.addRadio("radio_drawWritingDirection",20,140); spriteWriting_submitWritingWindow(p.cp5());
// rPos.add("North-east", DRAW_DIR_NE); }
rPos.add("South-east", DRAW_DIR_SE); });
// rPos.add("South-west", DRAW_DIR_SW);
// rPos.add("North-west", DRAW_DIR_NW);
rPos.setWindow(dialogWindow); return p;
Button submitButton = cp5.addButton("submitWritingWindow",0,300,100,120,20);
submitButton.setLabel("Generate commands");
submitButton.setWindow(dialogWindow);
}
void spriteFilePrefixField(String value)
{
spriteFilePrefix = value;
}
void textToWriteField(String value)
{
textToWrite = value;
}
String getTextToWrite()
{
return textToWrite;
}
String getSpriteFilePrefix()
{
return spriteFilePrefix;
}
String getSpriteFileSuffix()
{
return spriteFileSuffix;
}
void importTextButton()
{
textToWrite = importTextToWriteFromFile();
Textfield tf = (Textfield) cp5.controller("textToWriteField");
tf.setText(getTextToWrite());
tf.submit();
} }
void submitWritingWindow(int theValue)
{
println("Write.");
Textfield tf = (Textfield) cp5.controller("spriteFilePrefixField");
tf.submit();
tf.setText(getSpriteFilePrefix());
tf = (Textfield) cp5.controller("textToWriteField");
tf.submit();
tf.setText(getTextToWrite());
println("Start dir: " + renderStartDirection);
println("Sprite file prefix: " + spriteFilePrefix);
println("Text: " + textToWrite);
for (int i=0; i<getTextToWrite().length(); i++) void spriteWriting_spriteFilePrefixField(String value) {
spriteWriting_spriteFilePrefix = value;
}
void spriteWriting_textToWriteField(String value) {
spriteWriting_textToWrite = value;
}
String spriteWriting_getTextToWrite() {
return spriteWriting_textToWrite;
}
String spriteWriting_getSpriteFilePrefix() {
return spriteWriting_spriteFilePrefix;
}
String spriteWriting_getSpriteFileSuffix() {
return spriteWriting_spriteFileSuffix;
}
void spriteWriting_importTextButton() {
println("Text being imported!");
selectInput("Select the text file to load the text from:",
"spriteWriting_importTextToWriteFromFile");
}
public void spriteWriting_importTextToWriteFromFile(File selection) {
if (selection != null) {
String fp = selection.getAbsolutePath();
println("Input file: " + fp);
List<String> rows = java.util.Arrays.asList(loadStrings(fp));
StringBuilder sb = new StringBuilder(200);
for (String row : rows) {
sb.append(row);
}
spriteWriting_textToWriteField(sb.toString());
println("Completed text import, " + spriteWriting_getTextToWrite().length() + " characters found.");
println("Text: " + spriteWriting_getTextToWrite());
println(cp5s);
Textfield tf = cp5s.get(DRAW_WRITING_WINDOW_NAME).get(Textfield.class, "spriteWriting_textToWriteField");
if (spriteWriting_getTextToWrite() != null
&& !"".equals(spriteWriting_getTextToWrite().trim())) {
tf.setText(spriteWriting_getTextToWrite());
tf.submit();
tf.setText(spriteWriting_getTextToWrite());
}
}
}
void spriteWriting_submitWritingWindow(ControlP5 parent)
{ {
String filename = getSpriteFilePrefix() + (int) getTextToWrite().charAt(i) + getSpriteFileSuffix(); println("Write.");
addToCommandQueue(CMD_DRAW_SPRITE + int(gridSize * pixelScalingOverGridSize) + "," + filename+",END");
println(filename); Textfield tf = parent.get(Textfield.class, "spriteWriting_spriteFilePrefixField");
tf.submit();
tf.setText(spriteWriting_getSpriteFilePrefix());
Textfield wf = parent.get(Textfield.class, "spriteWriting_textToWriteField");
wf.submit();
wf.setText(spriteWriting_getTextToWrite());
println("Start dir: " + renderStartDirection);
println("Sprite file prefix: " + spriteWriting_spriteFilePrefix);
println("Text: " + spriteWriting_textToWrite);
for (int i=0; i<spriteWriting_getTextToWrite ().length(); i++) {
String filename = spriteWriting_getSpriteFilePrefix() + (int) spriteWriting_getTextToWrite().charAt(i) + spriteWriting_getSpriteFileSuffix();
addToCommandQueue(CMD_DRAW_SPRITE + int(gridSize * pixelScalingOverGridSize) + "," + filename+",END");
println(filename);
}
}
///*------------------------------------------------------------------------
// Details about the "sprite" subwindow
//------------------------------------------------------------------------*/
String sprite_spriteFilename;
int sprite_minSpriteSize = 100;
int sprite_maxSpriteSize = 500;
ControlFrameSimple addRandomSpriteControlFrame(String theName, int theWidth, int theHeight, int theX, int theY, int theColor ) {
final Frame f = new Frame( theName );
final ControlFrameSimple p = new ControlFrameSimple( this, theWidth, theHeight, theColor );
f.add( p );
p.init();
f.setTitle(theName);
f.setSize( p.w, p.h );
f.setLocation( theX, theY );
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
p.dispose();
f.dispose();
}
}
);
f.setResizable( true );
f.setVisible( true );
// sleep a little bit to allow p to call setup.
// otherwise a nullpointerexception might be caused.
try {
Thread.sleep( 100 );
}
catch(Exception e) {
} }
// set up controls
Textfield spriteFilenameField = p.cp5().addTextfield("sprite_spriteFilenameField",20,20,400,20)
.setText("filename.txt")
.setLabel("Sprite filename")
.plugTo(this, "sprite_spriteFilenameField");
Numberbox minSizeField = p.cp5().addNumberbox("sprite_minimumSpriteSize",20,60,100,20)
.setValue(sprite_getMinimumSpriteSize())
.setMin(10)
.setMax(sprite_getMaximumSpriteSize())
.setMultiplier(0.5)
.setLabel("Minimum size")
.plugTo(this, "sprite_minimumSpriteSize");
Numberbox maxSizeField = p.cp5().addNumberbox("sprite_maximumSpriteSize",20,100,100,20)
.setValue(sprite_getMaximumSpriteSize())
.setMin(sprite_getMinimumSpriteSize())
.setMultiplier(0.5)
.setLabel("Maximum size")
.plugTo(this, "sprite_maximumSpriteSize");
Button submitButton = p.cp5().addButton("sprite_submitSpriteWindow",0,300,100,120,20)
.setLabel("Draw sprite")
.addListener( new ControlListener() {
public void controlEvent( ControlEvent ev ) {
spriteWriting_submitWritingWindow(p.cp5());
}
});
spriteFilenameField.setFocus(true);
return p;
} }
String sprite_getSpriteFilename()
/*------------------------------------------------------------------------
Details about the "sprite" subwindow
------------------------------------------------------------------------*/
String spriteFilename;
int minSpriteSize = 100;
int maxSpriteSize = 500;
void button_mode_drawSpriteDialog()
{ {
this.dialogWindow = cp5.addControlWindow("drawSpriteWindow",100,100,450,200); return sprite_spriteFilename;
dialogWindow.hideCoordinates();
dialogWindow.setBackground(getBackgroundColour());
delay(200);
Textfield spriteFilenameField = cp5.addTextfield("spriteFilenameField",20,20,400,20);
spriteFilenameField.setText("filename.txt");
spriteFilenameField.setLabel("Sprite filename");
spriteFilenameField.setWindow(dialogWindow);
Numberbox minSizeField = cp5.addNumberbox("minimumSpriteSize",20,60,100,20);
minSizeField.setValue(getMinimumSpriteSize());
minSizeField.setMin(10);
minSizeField.setMax(getMaximumSpriteSize());
minSizeField.setMultiplier(0.5);
minSizeField.setLabel("Minimum size");
minSizeField.setWindow(dialogWindow);
Numberbox maxSizeField = cp5.addNumberbox("maximumSpriteSize",20,100,100,20);
maxSizeField.setValue(getMaximumSpriteSize());
maxSizeField.setMin(getMinimumSpriteSize());
maxSizeField.setMultiplier(0.5);
maxSizeField.setLabel("Maximum size");
maxSizeField.setWindow(dialogWindow);
Radio rPos = cp5.addRadio("radio_drawWritingDirection",20,140);
rPos.add("North-east", DRAW_DIR_NE);
rPos.add("South-east", DRAW_DIR_SE);
rPos.add("South-west", DRAW_DIR_SW);
rPos.add("North-west", DRAW_DIR_NW);
rPos.setWindow(dialogWindow);
Button submitButton = cp5.addButton("submitSpriteWindow",0,300,100,120,20);
submitButton.setLabel("Draw sprite");
submitButton.setWindow(dialogWindow);
} }
int sprite_getMinimumSpriteSize()
void radio_drawWritingDirection(int dir)
{ {
renderStartDirection = dir; return sprite_minSpriteSize;
}
int sprite_getMaximumSpriteSize()
{
return sprite_maxSpriteSize;
} }
String getSpriteFilename() void sprite_submitSpriteWindow(Textfield tf)
{
return spriteFilename;
}
int getMinimumSpriteSize()
{
return minSpriteSize;
}
int getMaximumSpriteSize()
{
return maxSpriteSize;
}
void submitSpriteWindow(int theValue)
{ {
println("Sprite."); println("Sprite.");
Textfield tf = (Textfield) cp5.controller("spriteFilenameField");
tf.submit(); tf.submit();
tf.setText(getSpriteFilename()); tf.setText(sprite_getSpriteFilename());
println("Start dir: " + renderStartDirection); println("Filename: " + sprite_getSpriteFilename());
println("Filename: " + spriteFilename);
addToCommandQueue(CMD_DRAW_SPRITE + "," + spriteFilename + "," addToCommandQueue(CMD_DRAW_SPRITE + "," + sprite_getSpriteFilename() + ","
+ getMinimumSpriteSize() + "," + getMaximumSpriteSize() + "," + renderStartDirection + ",END"); + sprite_getMinimumSpriteSize() + "," + sprite_getMaximumSpriteSize() + "," + DRAW_DIR_NE + ",END");
} }
/*------------------------------------------------------------------------ ///*------------------------------------------------------------------------
Details about the "norwegian draw" subwindow // Details about the "norwegian draw" subwindow
------------------------------------------------------------------------*/ //------------------------------------------------------------------------*/
String norwegianExecFilename = "filename.pbm"; String norwegian_execFilename = "filename.pbm";
int norwegianAmplitude = 20; int norwegian_amplitude = 20;
int norwegianWavelength = 2; int norwegian_wavelength = 2;
void button_mode_drawNorwegianDialog() ControlFrameSimple addNorwegianPixelControlFrame(String theName, int theWidth, int theHeight, int theX, int theY, int theColor ) {
{ final Frame f = new Frame( theName );
this.dialogWindow = cp5.addControlWindow("chooseNorwegianFilenameWindow",100,100,450,150); final ControlFrameSimple p = new ControlFrameSimple( this, theWidth, theHeight, theColor );
dialogWindow.hideCoordinates();
f.add( p );
p.init();
f.setTitle(theName);
f.setSize( p.w, p.h );
f.setLocation( theX, theY );
f.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
p.dispose();
f.dispose();
}
}
);
f.setResizable( true );
f.setVisible( true );
// sleep a little bit to allow p to call setup.
// otherwise a nullpointerexception might be caused.
try {
Thread.sleep( 100 );
}
catch(Exception e) {
}
dialogWindow.setBackground(getBackgroundColour()); // set up controls
Textfield filenameField = p.cp5().addTextfield("norwegian_execFilename",20,20,150,20)
.setText(norwegian_execFilename)
.setLabel("Filename to execute from")
.plugTo(this, "norwegian_execFilename");
Textfield filenameField = cp5.addTextfield("norwegianExecFilename",20,20,150,20); Numberbox minSizeField = p.cp5().addNumberbox("norwegian_amplitude",20,60,100,20)
filenameField.setText(norwegianExecFilename); .setValue(norwegian_amplitude)
filenameField.setLabel("Filename to execute from"); .setMin(10)
filenameField.setWindow(dialogWindow); .setMultiplier(0.5)
.setLabel("Amplitude")
.plugTo(this, "norwegian_amplitude");
Numberbox minSizeField = cp5.addNumberbox("norwegianAmplitude",20,60,100,20); Numberbox maxSizeField = p.cp5().addNumberbox("norwegian_wavelength",20,100,100,20)
minSizeField.setValue(norwegianAmplitude); .setValue(norwegian_wavelength)
minSizeField.setMin(10); .setMin(1)
minSizeField.setMultiplier(0.5); .setMultiplier(0.5)
minSizeField.setLabel("Amplitude"); .setLabel("Wavelength")
minSizeField.setWindow(dialogWindow); .plugTo(this, "norwegian_wavelength");
Numberbox maxSizeField = cp5.addNumberbox("norwegianWavelength",20,100,100,20); Button outlineButton = p.cp5().addButton("norwegian_submitNorwegianExecTraceOutline",0,180,20,80,20)
maxSizeField.setValue(norwegianWavelength); .setLabel("Trace outline")
maxSizeField.setMin(1); .addListener( new ControlListener() {
maxSizeField.setMultiplier(0.5); public void controlEvent( ControlEvent ev ) {
maxSizeField.setLabel("Wavelength"); norwegian_submitNorwegianExec(p.cp5().get(Textfield.class, "norwegian_execFilename"), true);
maxSizeField.setWindow(dialogWindow); }
});
Button outlineButton = cp5.addButton("submitNorwegianExecTraceOutline",0,180,20,80,20); Button submitButton = p.cp5().addButton("norwegian_submitNorwegianExecFilenameWindow",0,180,100,80,20)
outlineButton.setLabel("Trace outline"); .setLabel("Submit")
outlineButton.setWindow(dialogWindow); .addListener( new ControlListener() {
public void controlEvent( ControlEvent ev ) {
Button submitButton = cp5.addButton("submitNorwegianExecFilenameWindow",0,180,100,80,20); norwegian_submitNorwegianExec(p.cp5().get(Textfield.class, "norwegian_execFilename"), false);
submitButton.setLabel("Submit"); }
submitButton.setWindow(dialogWindow); });
filenameField.setFocus(true); filenameField.setFocus(true);
return p;
} }
void submitNorwegianExecTraceOutline(int theValue)
void norwegian_submitNorwegianExec(Textfield tf, boolean outline)
{ {
Textfield tf = (Textfield) cp5.controller("norwegianExecFilename");
tf.submit(); tf.submit();
tf.setText(norwegianExecFilename); tf.setText(norwegian_execFilename);
println("Filename:" + norwegianExecFilename); println("Filename:" + norwegian_execFilename);
addToCommandQueue(CMD_DRAW_NORWEGIAN_OUTLINE + norwegianExecFilename + ",END"); if (outline) {
} addToCommandQueue(CMD_DRAW_NORWEGIAN_OUTLINE + norwegian_execFilename + ",END");
}
void submitNorwegianExecFilenameWindow(int theValue) else {
{ println("Filename:" + norwegian_execFilename);
Textfield tf = (Textfield) cp5.controller("norwegianExecFilename"); println("Amplitude:" + norwegian_amplitude);
tf.submit(); println("Wavelength:" + norwegian_wavelength);
tf.setText(norwegianExecFilename);
addToCommandQueue(CMD_DRAW_NORWEGIAN + norwegian_execFilename + ","+norwegian_amplitude+","+norwegian_wavelength+",END");
println("Filename:" + norwegianExecFilename); }
println("Amplitude:" + norwegianAmplitude);
println("Wavelength:" + norwegianWavelength);
addToCommandQueue(CMD_DRAW_NORWEGIAN + norwegianExecFilename + ","+norwegianAmplitude+","+norwegianWavelength+",END");
} }

View File

@ -25,60 +25,49 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
Set<String> getPanelNames() {
Set<String> getPanelNames()
{
if (this.panelNames == null) if (this.panelNames == null)
this.panelNames = buildPanelNames(); this.panelNames = buildPanelNames();
return this.panelNames; return this.panelNames;
} }
List<String> getTabNames() List<String> getTabNames() {
{
if (this.tabNames == null) if (this.tabNames == null)
this.tabNames = buildTabNames(); this.tabNames = buildTabNames();
return this.tabNames; return this.tabNames;
} }
Set<String> getControlNames() Set<String> getControlNames() {
{
if (this.controlNames == null) if (this.controlNames == null)
this.controlNames = buildControlNames(); this.controlNames = buildControlNames();
return this.controlNames; return this.controlNames;
} }
Map<String, List<Controller>> getControlsForPanels() Map<String, List<Controller>> getControlsForPanels() {
{
if (this.controlsForPanels == null) if (this.controlsForPanels == null)
this.controlsForPanels = buildControlsForPanels(); this.controlsForPanels = buildControlsForPanels();
return this.controlsForPanels; return this.controlsForPanels;
} }
Map<String, Controller> getAllControls() Map<String, Controller> getAllControls() {
{
if (this.allControls == null) if (this.allControls == null)
this.allControls = buildAllControls(); this.allControls = buildAllControls();
return this.allControls; return this.allControls;
} }
Map<String, String> getControlLabels() Map<String, String> getControlLabels() {
{
if (this.controlLabels == null) if (this.controlLabels == null)
this.controlLabels = buildControlLabels(); this.controlLabels = buildControlLabels();
return this.controlLabels; return this.controlLabels;
} }
Map<String, Set<Panel>> getPanelsForTabs() Map<String, Set<Panel>> getPanelsForTabs() {
{
if (this.panelsForTabs == null) if (this.panelsForTabs == null)
this.panelsForTabs = buildPanelsForTabs(); this.panelsForTabs = buildPanelsForTabs();
return this.panelsForTabs; return this.panelsForTabs;
} }
Map<String, Panel> getPanels() Map<String, Panel> getPanels() {
{
if (this.panels == null) if (this.panels == null)
this.panels = buildPanels(); this.panels = buildPanels();
return this.panels; return this.panels;
} }
Set<String> getControlsToLockIfBoxNotSpecified() Set<String> getControlsToLockIfBoxNotSpecified() {
{
if (this.controlsToLockIfBoxNotSpecified == null) if (this.controlsToLockIfBoxNotSpecified == null)
{ {
this.controlsToLockIfBoxNotSpecified = buildControlsToLockIfBoxNotSpecified(); this.controlsToLockIfBoxNotSpecified = buildControlsToLockIfBoxNotSpecified();
@ -86,8 +75,7 @@ Set<String> getControlsToLockIfBoxNotSpecified()
return this.controlsToLockIfBoxNotSpecified; return this.controlsToLockIfBoxNotSpecified;
} }
Set<String> getControlsToLockIfImageNotLoaded() Set<String> getControlsToLockIfImageNotLoaded() {
{
if (this.controlsToLockIfImageNotLoaded == null) if (this.controlsToLockIfImageNotLoaded == null)
{ {
this.controlsToLockIfImageNotLoaded = buildControlsToLockIfImageNotLoaded(); this.controlsToLockIfImageNotLoaded = buildControlsToLockIfImageNotLoaded();
@ -95,9 +83,15 @@ Set<String> getControlsToLockIfImageNotLoaded()
return this.controlsToLockIfImageNotLoaded; return this.controlsToLockIfImageNotLoaded;
} }
Set<String> getControlsToLockIfVectorNotLoaded() {
if (this.controlsToLockIfVectorNotLoaded == null)
{
this.controlsToLockIfVectorNotLoaded = buildControlsToLockIfVectorNotLoaded();
}
return this.controlsToLockIfVectorNotLoaded;
}
void hideAllControls() void hideAllControls() {
{
for (String key : allControls.keySet()) for (String key : allControls.keySet())
{ {
Controller c = allControls.get(key); Controller c = allControls.get(key);
@ -105,14 +99,13 @@ void hideAllControls()
} }
} }
Map<String, Panel> buildPanels() Map<String, Panel> buildPanels() {
{
Map<String, Panel> panels = new HashMap<String, Panel>(); Map<String, Panel> panels = new HashMap<String, Panel>();
float panelHeight = frame.getHeight() - getMainPanelPosition().y - (DEFAULT_CONTROL_SIZE.y*3); float panelHeight = frame.getHeight() - getMainPanelPosition().y - (DEFAULT_CONTROL_SIZE.y*3);
Rectangle panelOutline = new Rectangle(getMainPanelPosition(), Rectangle panelOutlineInput = new Rectangle(getMainPanelPosition(),
new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, panelHeight)); new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, panelHeight));
Panel inputPanel = new Panel(PANEL_NAME_INPUT, panelOutline); Panel inputPanel = new Panel(PANEL_NAME_INPUT, panelOutlineInput);
inputPanel.setResizable(true); inputPanel.setResizable(true);
inputPanel.setOutlineColour(color(200, 200, 200)); inputPanel.setOutlineColour(color(200, 200, 200));
// get controls // get controls
@ -122,8 +115,10 @@ Map<String, Panel> buildPanels()
inputPanel.setControlSizes(buildControlSizesForPanel(inputPanel)); inputPanel.setControlSizes(buildControlSizesForPanel(inputPanel));
panels.put(PANEL_NAME_INPUT, inputPanel); panels.put(PANEL_NAME_INPUT, inputPanel);
Panel rovingPanel = new Panel(PANEL_NAME_ROVING, panelOutline); Rectangle panelOutlineRoving = new Rectangle(getMainPanelPosition(),
rovingPanel.setOutlineColour(color(200,200,200)); new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, panelHeight));
Panel rovingPanel = new Panel(PANEL_NAME_ROVING, panelOutlineRoving);
rovingPanel.setOutlineColour(color(100,200,200));
// get controls // get controls
rovingPanel.setResizable(true); rovingPanel.setResizable(true);
rovingPanel.setControls(getControlsForPanels().get(PANEL_NAME_ROVING)); rovingPanel.setControls(getControlsForPanels().get(PANEL_NAME_ROVING));
@ -132,8 +127,10 @@ Map<String, Panel> buildPanels()
rovingPanel.setControlSizes(buildControlSizesForPanel(rovingPanel)); rovingPanel.setControlSizes(buildControlSizesForPanel(rovingPanel));
panels.put(PANEL_NAME_ROVING, rovingPanel); panels.put(PANEL_NAME_ROVING, rovingPanel);
Panel tracePanel = new Panel(PANEL_NAME_TRACE, panelOutline); Rectangle panelOutlineTrace = new Rectangle(getMainPanelPosition(),
tracePanel.setOutlineColour(color(200,200,200)); new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, panelHeight));
Panel tracePanel = new Panel(PANEL_NAME_TRACE, panelOutlineTrace);
tracePanel.setOutlineColour(color(200,255,200));
// get controls // get controls
tracePanel.setResizable(true); tracePanel.setResizable(true);
tracePanel.setControls(getControlsForPanels().get(PANEL_NAME_TRACE)); tracePanel.setControls(getControlsForPanels().get(PANEL_NAME_TRACE));
@ -142,8 +139,10 @@ Map<String, Panel> buildPanels()
tracePanel.setControlSizes(buildControlSizesForPanel(tracePanel)); tracePanel.setControlSizes(buildControlSizesForPanel(tracePanel));
panels.put(PANEL_NAME_TRACE, tracePanel); panels.put(PANEL_NAME_TRACE, tracePanel);
Panel detailsPanel = new Panel(PANEL_NAME_DETAILS, panelOutline); Rectangle panelOutlineDetails = new Rectangle(getMainPanelPosition(),
detailsPanel.setOutlineColour(color(200, 200, 200)); new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, panelHeight));
Panel detailsPanel = new Panel(PANEL_NAME_DETAILS, panelOutlineDetails);
detailsPanel.setOutlineColour(color(200, 200, 255));
// get controls // get controls
detailsPanel.setResizable(true); detailsPanel.setResizable(true);
detailsPanel.setControls(getControlsForPanels().get(PANEL_NAME_DETAILS)); detailsPanel.setControls(getControlsForPanels().get(PANEL_NAME_DETAILS));
@ -152,8 +151,10 @@ Map<String, Panel> buildPanels()
detailsPanel.setControlSizes(buildControlSizesForPanel(detailsPanel)); detailsPanel.setControlSizes(buildControlSizesForPanel(detailsPanel));
panels.put(PANEL_NAME_DETAILS, detailsPanel); panels.put(PANEL_NAME_DETAILS, detailsPanel);
Panel queuePanel = new Panel(PANEL_NAME_QUEUE, panelOutline); Rectangle panelOutlineQueue = new Rectangle(getMainPanelPosition(),
queuePanel.setOutlineColour(color(200, 200, 200)); new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, panelHeight));
Panel queuePanel = new Panel(PANEL_NAME_QUEUE, panelOutlineQueue);
queuePanel.setOutlineColour(color(200, 200, 50));
// get controls // get controls
queuePanel.setResizable(true); queuePanel.setResizable(true);
queuePanel.setControls(getControlsForPanels().get(PANEL_NAME_QUEUE)); queuePanel.setControls(getControlsForPanels().get(PANEL_NAME_QUEUE));
@ -162,18 +163,20 @@ Map<String, Panel> buildPanels()
queuePanel.setControlSizes(buildControlSizesForPanel(queuePanel)); queuePanel.setControlSizes(buildControlSizesForPanel(queuePanel));
panels.put(PANEL_NAME_QUEUE, queuePanel); panels.put(PANEL_NAME_QUEUE, queuePanel);
panelOutline = new Rectangle( Rectangle panelOutlineGeneral = new Rectangle(
new PVector(getMainPanelPosition().x, getMainPanelPosition().y-((DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)*2)), new PVector(getMainPanelPosition().x, getMainPanelPosition().y-((DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)*2)),
new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, (DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)*2)); new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, (DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)*2));
Panel generalPanel = new Panel(PANEL_NAME_GENERAL, panelOutline); Panel generalPanel = new Panel(PANEL_NAME_GENERAL, panelOutlineGeneral);
generalPanel.setResizable(false); generalPanel.setResizable(false);
generalPanel.setOutlineColour(color(200, 200, 200)); generalPanel.setOutlineColour(color(200, 50, 200));
// get controls // get controls
generalPanel.setControls(getControlsForPanels().get(PANEL_NAME_GENERAL)); generalPanel.setControls(getControlsForPanels().get(PANEL_NAME_GENERAL));
// get control positions // get control positions
generalPanel.setControlPositions(buildControlPositionsForPanel(generalPanel)); generalPanel.setControlPositions(buildControlPositionsForPanel(generalPanel));
generalPanel.setControlSizes(buildControlSizesForPanel(generalPanel)); generalPanel.setControlSizes(buildControlSizesForPanel(generalPanel));
panels.put(PANEL_NAME_GENERAL, generalPanel); panels.put(PANEL_NAME_GENERAL, generalPanel);
return panels; return panels;
} }
@ -188,6 +191,18 @@ void updateNumberboxValues()
initialiseNumberboxValues(getAllControls()); initialiseNumberboxValues(getAllControls());
} }
void initConsoleWindow() {
consoleArea = cp5.addTextarea("txt")
.setPosition(300, 100)
.setSize(400, 600)
.setFont(createFont("", 12))
.setLineHeight(14)
.setColor(color(255))
.setColorBackground(color(0, 200))
.setColorForeground(color(255, 100))
.setVisible(false);
}
Set<String> buildControlsToLockIfBoxNotSpecified() Set<String> buildControlsToLockIfBoxNotSpecified()
{ {
Set<String> result = new HashSet<String>(); Set<String> result = new HashSet<String>();
@ -220,11 +235,41 @@ Set<String> buildControlsToLockIfImageNotLoaded()
result.add(MODE_CHANGE_SAMPLE_AREA); result.add(MODE_CHANGE_SAMPLE_AREA);
result.add(MODE_SELECT_PICTUREFRAME); result.add(MODE_SELECT_PICTUREFRAME);
result.add(MODE_CHANGE_PIXEL_SCALING);
result.add(MODE_CHOOSE_CHROMA_KEY_COLOUR);
return result; return result;
} }
Set<String> buildControlsToLockIfVectorNotLoaded()
{
Set<String> result = new HashSet<String>();
result.add(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH);
result.add(MODE_RESIZE_VECTOR);
result.add(MODE_MOVE_VECTOR);
result.add(MODE_CHANGE_POLYGONIZER_LENGTH);
result.add(MODE_CHANGE_POLYGONIZER);
return result;
}
CallbackListener toFront = new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
theEvent.getController().bringToFront();
((ScrollableList)theEvent.getController()).open();
}
};
CallbackListener close = new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
((ScrollableList)theEvent.getController()).close();
}
};
Map<String, Controller> buildAllControls() Map<String, Controller> buildAllControls()
{ {
initConsoleWindow();
Map<String, Controller> map = new HashMap<String, Controller>(); Map<String, Controller> map = new HashMap<String, Controller>();
@ -235,6 +280,8 @@ Map<String, Controller> buildAllControls()
Button b = cp5.addButton(controlName, 0, 100, 100, 100, 100); Button b = cp5.addButton(controlName, 0, 100, 100, 100, 100);
b.setLabel(getControlLabels().get(controlName)); b.setLabel(getControlLabels().get(controlName));
b.hide(); b.hide();
controlP5.Label l = b.getCaptionLabel();
l.align(ControlP5.LEFT, CENTER);
map.put(controlName, b); map.put(controlName, b);
// println("Added button " + controlName); // println("Added button " + controlName);
} }
@ -243,9 +290,9 @@ Map<String, Controller> buildAllControls()
Toggle t = cp5.addToggle(controlName, false, 100, 100, 100, 100); Toggle t = cp5.addToggle(controlName, false, 100, 100, 100, 100);
t.setLabel(getControlLabels().get(controlName)); t.setLabel(getControlLabels().get(controlName));
t.hide(); t.hide();
controlP5.Label l = t.captionLabel(); controlP5.Label l = t.getCaptionLabel();
l.style().marginTop = -17; //move upwards (relative to button size) l.align(ControlP5.LEFT, CENTER);
l.style().marginLeft = 4; //move to the right l.getStyle().setPaddingLeft(4);
map.put(controlName, t); map.put(controlName, t);
// println("Added toggle " + controlName); // println("Added toggle " + controlName);
} }
@ -254,9 +301,9 @@ Map<String, Controller> buildAllControls()
Toggle t = cp5.addToggle(controlName, false, 100, 100, 100, 100); Toggle t = cp5.addToggle(controlName, false, 100, 100, 100, 100);
t.setLabel(getControlLabels().get(controlName)); t.setLabel(getControlLabels().get(controlName));
t.hide(); t.hide();
controlP5.Label l = t.captionLabel(); controlP5.Label l = t.getCaptionLabel();
l.style().marginTop = -17; //move upwards (relative to button size) l.align(ControlP5.LEFT, CENTER);
l.style().marginLeft = 4; //move to the right l.getStyle().setPaddingLeft(4);
map.put(controlName, t); map.put(controlName, t);
// println("Added minitoggle " + controlName); // println("Added minitoggle " + controlName);
} }
@ -266,21 +313,57 @@ Map<String, Controller> buildAllControls()
n.setLabel(getControlLabels().get(controlName)); n.setLabel(getControlLabels().get(controlName));
n.hide(); n.hide();
n.setDecimalPrecision(0); n.setDecimalPrecision(0);
controlP5.Label l = n.captionLabel(); controlP5.Label l = n.getCaptionLabel();
l.style().marginTop = -17; //move upwards (relative to button size) l.align(ControlP5.LEFT, CENTER);
l.style().marginLeft = 40; //move to the right l.getStyle().setPaddingLeft(35);
// change the control direction to left/right // change the control direction to left/right
n.setDirection(Controller.VERTICAL); n.setDirection(Controller.VERTICAL);
map.put(controlName, n); map.put(controlName, n);
// println("Added numberbox " + controlName); // println("Added numberbox " + controlName);
} }
else if (controlName.startsWith("dropdown_"))
{
ScrollableList sl = cp5.addScrollableList(controlName, 100, 100, 100, 100);
sl.setBarHeight(20);
sl.setItemHeight(20);
sl.setLabel(getControlLabels().get(controlName));
sl.setType(ScrollableList.DROPDOWN);
sl.onEnter(toFront);
sl.onLeave(close);
sl.setHeight(100);
sl.hide();
controlP5.Label l = sl.getCaptionLabel();
map.put(controlName, sl);
println("Added dropdown " + controlName);
}
} }
initialiseButtonValues(map);
initialiseToggleValues(map); initialiseToggleValues(map);
initialiseNumberboxValues(map); initialiseNumberboxValues(map);
initialiseDropdownContents(map);
initialiseDropdownValues(map);
return map; return map;
} }
Map<String, Controller> initialiseButtonValues(Map<String, Controller> map)
{
for (String key : map.keySet())
{
if (key.startsWith("button_"))
{
Button n = (Button) map.get(key);
if (MODE_CHANGE_POLYGONIZER.equals(key)) {
n.setValue(polygonizer);
n.setLabel(this.controlLabels.get(MODE_CHANGE_POLYGONIZER) + ": " + polygonizer);
}
}
}
return map;
}
Map<String, Controller> initialiseNumberboxValues(Map<String, Controller> map) Map<String, Controller> initialiseNumberboxValues(Map<String, Controller> map)
{ {
for (String key : map.keySet()) for (String key : map.keySet())
@ -445,7 +528,7 @@ Map<String, Controller> initialiseNumberboxValues(Map<String, Controller> map)
n.setDecimalPrecision(2); n.setDecimalPrecision(2);
n.setValue(pixelScalingOverGridSize); n.setValue(pixelScalingOverGridSize);
n.setMin(0.1); n.setMin(0.1);
n.setMax(4.0); // n.setMax(4.0);
n.setMultiplier(0.01); n.setMultiplier(0.01);
} }
else if (MODE_CHANGE_MIN_VECTOR_LINE_LENGTH.equals(key)) else if (MODE_CHANGE_MIN_VECTOR_LINE_LENGTH.equals(key))
@ -504,10 +587,31 @@ Map<String, Controller> initialiseNumberboxValues(Map<String, Controller> map)
} }
else if (MODE_ADJUST_PREVIEW_CORD_OFFSET.equals(key)) else if (MODE_ADJUST_PREVIEW_CORD_OFFSET.equals(key))
{ {
n.setDecimalPrecision(1); n.setDecimalPrecision(2);
n.setValue(0); n.setValue(0.0);
n.setMultiplier(0.5); n.setMultiplier(0.5);
} }
else if (MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE.equals(key))
{
n.setValue(densityPreviewPosterize);
n.setMin(1);
n.setMax(255);
n.setDecimalPrecision(1);
n.setMultiplier(0.1);
}
else if (MODE_CHANGE_POLYGONIZER_LENGTH.equals(key)) {
n.setValue(polygonizerLength);
n.setMin(1.0);
n.setDecimalPrecision(1);
n.setMultiplier(0.1);
}
else if (MODE_CHANGE_POLYGONIZER_ADAPTATIVE_ANGLE.equals(key)) {
n.setValue(polygonizerAdaptativeAngle);
n.setMin(0.0);
n.setMax(1.57079632679);
n.setDecimalPrecision(2);
n.setMultiplier(0.01);
}
} }
} }
return map; return map;
@ -558,12 +662,71 @@ Map<String, Controller> initialiseToggleValues(Map<String, Controller> map)
Toggle t = (Toggle) map.get(key); Toggle t = (Toggle) map.get(key);
t.setValue((rotateWebcamImage) ? 1 : 0); t.setValue((rotateWebcamImage) ? 1 : 0);
} }
else if (MODE_PREVIEW_PIXEL_DENSITY_RANGE.equals(key))
{
Toggle t = (Toggle) map.get(key);
t.setValue((previewPixelDensityRange) ? 1 : 0);
}
} }
return map; return map;
} }
Map<String, Controller> initialiseDropdownContents(Map<String, Controller> map)
{
println("Init dropdown contents");
for (String key : map.keySet())
{
if (MODE_CYCLE_DENSITY_PREVIEW_STYLE.equals(key))
{
println("Adding " + key);
ScrollableList sl = (ScrollableList) map.get(key);
sl.setItems(densityPreviewStyles);
}
if (MODE_CHANGE_POLYGONIZER.equals(key))
{
println("Adding " + key);
ScrollableList sl = (ScrollableList) map.get(key);
sl.setItems(polygonizerStyles);
}
if (MODE_CHANGE_INVERT_MASK.equals(key))
{
println("Adding " + key);
ScrollableList sl = (ScrollableList) map.get(key);
sl.setItems(invertMaskModes);
}
}
return map;
}
Map<String, Controller> initialiseDropdownValues(Map<String, Controller> map)
{
println("Init dropdown values");
for (String key : map.keySet())
{
if (MODE_CYCLE_DENSITY_PREVIEW_STYLE.equals(key))
{
println("Adding " + key);
ScrollableList sl = (ScrollableList) map.get(key);
sl.setValue(densityPreviewStyle);
sl.close();
}
else if (MODE_CHANGE_POLYGONIZER.equals(key))
{
println("Adding " + key);
ScrollableList sl = (ScrollableList) map.get(key);
sl.setValue(polygonizer);
sl.close();
}
else if (MODE_CHANGE_INVERT_MASK.equals(key))
{
println("Adding " + key);
ScrollableList sl = (ScrollableList) map.get(key);
sl.setValue(polygonizer);
sl.close();
}
}
return map;
}
String getControlLabel(String butName) String getControlLabel(String butName)
@ -582,10 +745,23 @@ Map<String, PVector> buildControlPositionsForPanel(Panel panel)
int row = 0; int row = 0;
for (Controller controller : panel.getControls()) for (Controller controller : panel.getControls())
{ {
if (controller.name().startsWith("minitoggle_"))
if (controller.getName().startsWith("minitoggle_"))
{ {
PVector p = new PVector(col*(DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x), row*(DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)); PVector p = new PVector(col*(DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x), row*(DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y));
map.put(controller.name(), p); map.put(controller.getName(), p);
row++;
if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight())
{
row = 0;
col++;
}
}
else if (controller.getName().startsWith("dropdown_"))
{
PVector p = new PVector(col*(DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x), row*(DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y));
println(controller);
map.put(controller.getName(), p);
row++; row++;
if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight()) if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight())
{ {
@ -596,7 +772,7 @@ Map<String, PVector> buildControlPositionsForPanel(Panel panel)
else else
{ {
PVector p = new PVector(col*(DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x), row*(DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)); PVector p = new PVector(col*(DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x), row*(DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y));
map.put(controller.name(), p); map.put(controller.getName(), p);
row++; row++;
if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight()) if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight())
{ {
@ -605,9 +781,9 @@ Map<String, PVector> buildControlPositionsForPanel(Panel panel)
} }
} }
} }
return map; return map;
} }
Map<String, PVector> buildControlSizesForPanel(Panel panel) Map<String, PVector> buildControlSizesForPanel(Panel panel)
{ {
//println("Building control sizes for panel " + panel.getName()); //println("Building control sizes for panel " + panel.getName());
@ -617,16 +793,21 @@ Map<String, PVector> buildControlSizesForPanel(Panel panel)
int row = 0; int row = 0;
for (Controller controller : panel.getControls()) for (Controller controller : panel.getControls())
{ {
if (controller.name().startsWith("minitoggle_")) if (controller.getName().startsWith("minitoggle_"))
{ {
PVector s = new PVector(DEFAULT_CONTROL_SIZE.y, DEFAULT_CONTROL_SIZE.y); PVector s = new PVector(DEFAULT_CONTROL_SIZE.y, DEFAULT_CONTROL_SIZE.y);
map.put(controller.name(), s); map.put(controller.getName(), s);
}
else if (controller.getName().startsWith("dropdown_"))
{
PVector s = new PVector(DEFAULT_CONTROL_SIZE.x, DEFAULT_CONTROL_SIZE.y * 4);
map.put(controller.getName(), s);
} }
else else
{ {
PVector s = new PVector(DEFAULT_CONTROL_SIZE.x, DEFAULT_CONTROL_SIZE.y); PVector s = new PVector(DEFAULT_CONTROL_SIZE.x, DEFAULT_CONTROL_SIZE.y);
map.put(controller.name(), s); map.put(controller.getName(), s);
//println("Added size of " + controller.name() + " to panel. " + s); //println("Added size of " + controller.getName() + " to panel. " + s);
} }
} }
@ -682,8 +863,9 @@ List<String> getControlNamesForInputPanel()
controlNames.add(MODE_CHANGE_GRID_SIZE); controlNames.add(MODE_CHANGE_GRID_SIZE);
controlNames.add(MODE_CHANGE_SAMPLE_AREA); controlNames.add(MODE_CHANGE_SAMPLE_AREA);
controlNames.add(MODE_CHOOSE_CHROMA_KEY_COLOUR); controlNames.add(MODE_CHOOSE_CHROMA_KEY_COLOUR);
controlNames.add(MODE_CHANGE_INVERT_MASK);
controlNames.add(MODE_CHANGE_PIXEL_SCALING); controlNames.add(MODE_CHANGE_PIXEL_SCALING);
controlNames.add(MODE_RENDER_PIXEL_DIALOG); controlNames.add(MODE_RENDER_PIXEL_DIALOG);
// controlNames.add(MODE_DRAW_GRID); // controlNames.add(MODE_DRAW_GRID);
controlNames.add(MODE_DRAW_OUTLINE_BOX); controlNames.add(MODE_DRAW_OUTLINE_BOX);
@ -693,18 +875,24 @@ List<String> getControlNamesForInputPanel()
controlNames.add(MODE_LOAD_VECTOR_FILE); controlNames.add(MODE_LOAD_VECTOR_FILE);
controlNames.add(MODE_RESIZE_VECTOR); controlNames.add(MODE_RESIZE_VECTOR);
controlNames.add(MODE_MOVE_VECTOR); controlNames.add(MODE_MOVE_VECTOR);
controlNames.add(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH);
//controlNames.add(MODE_VECTOR_PATH_LENGTH_HIGHPASS_CUTOFF);
controlNames.add(MODE_RENDER_VECTORS);
controlNames.add(MODE_ADJUST_PREVIEW_CORD_OFFSET); controlNames.add(MODE_ADJUST_PREVIEW_CORD_OFFSET);
controlNames.add(MODE_RENDER_VECTORS);
controlNames.add(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH);
controlNames.add(MODE_CHANGE_POLYGONIZER);
controlNames.add(MODE_CHANGE_POLYGONIZER_LENGTH);
// controlNames.add(MODE_CHANGE_POLYGONIZER_ADAPTATIVE_ANGLE);
controlNames.add(MODE_SHOW_IMAGE); controlNames.add(MODE_SHOW_IMAGE);
controlNames.add(MODE_SHOW_VECTOR); controlNames.add(MODE_SHOW_VECTOR);
controlNames.add(MODE_SHOW_QUEUE_PREVIEW); controlNames.add(MODE_SHOW_QUEUE_PREVIEW);
controlNames.add(MODE_SHOW_DENSITY_PREVIEW);
controlNames.add(MODE_SHOW_GUIDES); controlNames.add(MODE_SHOW_GUIDES);
controlNames.add(MODE_SHOW_DENSITY_PREVIEW);
controlNames.add(MODE_PREVIEW_PIXEL_DENSITY_RANGE);
controlNames.add(MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE);
controlNames.add(MODE_CYCLE_DENSITY_PREVIEW_STYLE);
return controlNames; return controlNames;
} }
@ -931,6 +1119,7 @@ Map<String, String> buildControlLabels()
result.put(MODE_MOVE_VECTOR, "Move vector"); result.put(MODE_MOVE_VECTOR, "Move vector");
result.put(MODE_RENDER_PIXEL_DIALOG, "Render pixels..."); result.put(MODE_RENDER_PIXEL_DIALOG, "Render pixels...");
result.put(MODE_CHOOSE_CHROMA_KEY_COLOUR, "Choose mask colour"); result.put(MODE_CHOOSE_CHROMA_KEY_COLOUR, "Choose mask colour");
result.put(MODE_CHANGE_INVERT_MASK, "Mask mode");
result.put(MODE_CHANGE_PIXEL_SCALING, "Pixel scaling"); result.put(MODE_CHANGE_PIXEL_SCALING, "Pixel scaling");
result.put(MODE_PEN_LIFT_UP, "Pen lift"); result.put(MODE_PEN_LIFT_UP, "Pen lift");
@ -970,7 +1159,15 @@ Map<String, String> buildControlLabels()
result.put(MODE_SEND_BUTTON_ACTIVATE, "Activate button"); result.put(MODE_SEND_BUTTON_ACTIVATE, "Activate button");
result.put(MODE_SEND_BUTTON_DEACTIVATE, "Deactivate button"); result.put(MODE_SEND_BUTTON_DEACTIVATE, "Deactivate button");
result.put(MODE_ADJUST_PREVIEW_CORD_OFFSET, "Preview cord offset"); result.put(MODE_ADJUST_PREVIEW_CORD_OFFSET, "Cord offset");
result.put(MODE_CYCLE_DENSITY_PREVIEW_STYLE, "Density preview style");
result.put(MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE, "Pixel posterize");
result.put(MODE_PREVIEW_PIXEL_DENSITY_RANGE, "Show density range");
result.put(MODE_CHANGE_POLYGONIZER, "Polygonizer style");
result.put(MODE_CHANGE_POLYGONIZER_LENGTH, "Polygonizer length");
result.put(MODE_CHANGE_POLYGONIZER_ADAPTATIVE_ANGLE, "Polygonizer angle");
return result; return result;
@ -1078,6 +1275,7 @@ Set<String> buildControlNames()
result.add(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH); result.add(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH);
result.add(MODE_CHOOSE_CHROMA_KEY_COLOUR); result.add(MODE_CHOOSE_CHROMA_KEY_COLOUR);
result.add(MODE_CHANGE_INVERT_MASK);
result.add(MODE_CHANGE_PIXEL_SCALING); result.add(MODE_CHANGE_PIXEL_SCALING);
result.add(MODE_PEN_LIFT_UP); result.add(MODE_PEN_LIFT_UP);
result.add(MODE_PEN_LIFT_DOWN); result.add(MODE_PEN_LIFT_DOWN);
@ -1090,13 +1288,13 @@ Set<String> buildControlNames()
result.add(MODE_SELECT_ROVE_IMAGE_SOURCE); result.add(MODE_SELECT_ROVE_IMAGE_SOURCE);
result.add(MODE_SEND_START_TEXT); result.add(MODE_SEND_START_TEXT);
result.add(MODE_SHOW_WRITING_DIALOG); result.add(MODE_SHOW_WRITING_DIALOG);
result.add(MODE_START_SWIRLING); // result.add(MODE_START_SWIRLING);
result.add(MODE_STOP_SWIRLING); // result.add(MODE_STOP_SWIRLING);
result.add(MODE_START_MARKING); // result.add(MODE_START_MARKING);
result.add(MODE_STOP_MARKING); // result.add(MODE_STOP_MARKING);
result.add(MODE_START_SPRITE); // result.add(MODE_START_SPRITE);
result.add(MODE_START_RANDOM_SPRITES); // result.add(MODE_START_RANDOM_SPRITES);
result.add(MODE_STOP_RANDOM_SPRITES); // result.add(MODE_STOP_RANDOM_SPRITES);
result.add(MODE_DRAW_NORWEGIAN_DIALOG); result.add(MODE_DRAW_NORWEGIAN_DIALOG);
result.add(MODE_LIVE_BLUR_VALUE); result.add(MODE_LIVE_BLUR_VALUE);
@ -1116,6 +1314,14 @@ Set<String> buildControlNames()
result.add(MODE_SEND_BUTTON_DEACTIVATE); result.add(MODE_SEND_BUTTON_DEACTIVATE);
result.add(MODE_ADJUST_PREVIEW_CORD_OFFSET); result.add(MODE_ADJUST_PREVIEW_CORD_OFFSET);
result.add(MODE_CYCLE_DENSITY_PREVIEW_STYLE);
result.add(MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE);
result.add(MODE_PREVIEW_PIXEL_DENSITY_RANGE);
result.add(MODE_CHANGE_POLYGONIZER_LENGTH);
result.add(MODE_CHANGE_POLYGONIZER);
result.add(MODE_CHANGE_POLYGONIZER_ADAPTATIVE_ANGLE);
return result; return result;
} }

View File

@ -25,12 +25,11 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
static final String CMD_CHANGELENGTH = "C01,"; static final String CMD_CHANGELENGTH = "C01,";
static final String CMD_CHANGEPENWIDTH = "C02,"; static final String CMD_SETPENWIDTH = "C02,";
static final String CMD_CHANGEMOTORSPEED = "C03,"; //static final String CMD_CHANGEMOTORSPEED = "C03,";
static final String CMD_CHANGEMOTORACCEL = "C04,"; //static final String CMD_CHANGEMOTORACCEL = "C04,";
static final String CMD_DRAWPIXEL = "C05,"; static final String CMD_DRAWPIXEL = "C05,";
static final String CMD_DRAWSCRIBBLEPIXEL = "C06,"; static final String CMD_DRAWSCRIBBLEPIXEL = "C06,";
static final String CMD_DRAWRECT = "C07,"; static final String CMD_DRAWRECT = "C07,";
@ -121,9 +120,7 @@ void sendRequestMachineSize()
void sendMachineSpec() void sendMachineSpec()
{ {
// ask for input to get the new machine size // ask for input to get the new machine size
String command = CMD_CHANGEMACHINENAME+newMachineName+",END"; String command = CMD_CHANGEMACHINESIZE+getDisplayMachine().inMM(getDisplayMachine().getWidth())+","+getDisplayMachine().inMM(getDisplayMachine().getHeight())+",END";
addToCommandQueue(command);
command = CMD_CHANGEMACHINESIZE+getDisplayMachine().inMM(getDisplayMachine().getWidth())+","+getDisplayMachine().inMM(getDisplayMachine().getHeight())+",END";
addToCommandQueue(command); addToCommandQueue(command);
command = CMD_CHANGEMACHINEMMPERREV+int(getDisplayMachine().getMMPerRev())+",END"; command = CMD_CHANGEMACHINEMMPERREV+int(getDisplayMachine().getMMPerRev())+",END";
addToCommandQueue(command); addToCommandQueue(command);
@ -200,13 +197,13 @@ void sendTestPenWidth()
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(testPenWidthCommand) sb.append(testPenWidthCommand)
.append(int(gridSize)) .append(int(gridSize))
.append(",") .append(",")
.append(df.format(testPenWidthStartSize)) .append(df.format(testPenWidthStartSize))
.append(",") .append(",")
.append(df.format(testPenWidthEndSize)) .append(df.format(testPenWidthEndSize))
.append(",") .append(",")
.append(df.format(testPenWidthIncrementSize)) .append(df.format(testPenWidthIncrementSize))
.append(",END"); .append(",END");
addToCommandQueue(sb.toString()); addToCommandQueue(sb.toString());
} }
@ -685,7 +682,6 @@ void sendVectorShapes(RShape vec, float scaling, PVector position, int pathSorti
if (pointPaths[i] != null) if (pointPaths[i] != null)
{ {
boolean firstPointFound = false; boolean firstPointFound = false;
if (pointPaths[i].length > pathLengthHighPassCutoff) if (pointPaths[i].length > pathLengthHighPassCutoff)
{ {
List<PVector> filteredPoints = filterPoints(pointPaths[i], VECTOR_FILTER_LOW_PASS, minimumVectorLineLength, scaling, position); List<PVector> filteredPoints = filterPoints(pointPaths[i], VECTOR_FILTER_LOW_PASS, minimumVectorLineLength, scaling, position);
@ -702,7 +698,7 @@ void sendVectorShapes(RShape vec, float scaling, PVector position, int pathSorti
if (liftToGetToNewPoint) if (liftToGetToNewPoint)
addToCommandQueue(CMD_PENUP+"END"); addToCommandQueue(CMD_PENUP+"END");
// move to this point and put the pen down // move to this point and put the pen down
command = CMD_CHANGELENGTHDIRECT+(int)p.x+","+(int)p.y+","+getMaxSegmentLength()+",END"; command = CMD_CHANGELENGTHDIRECT+Math.round(p.x)+","+Math.round(p.y)+","+getMaxSegmentLength()+",END";
addToCommandQueue(command); addToCommandQueue(command);
if (liftToGetToNewPoint) if (liftToGetToNewPoint)
addToCommandQueue(CMD_PENDOWN+"END"); addToCommandQueue(CMD_PENDOWN+"END");
@ -713,7 +709,7 @@ void sendVectorShapes(RShape vec, float scaling, PVector position, int pathSorti
for (int j=1; j<filteredPoints.size(); j++) for (int j=1; j<filteredPoints.size(); j++)
{ {
p = filteredPoints.get(j); p = filteredPoints.get(j);
command = CMD_CHANGELENGTHDIRECT+(int)p.x+","+(int)p.y+","+getMaxSegmentLength()+",END"; command = CMD_CHANGELENGTHDIRECT+Math.round(p.x)+","+Math.round(p.y)+","+getMaxSegmentLength()+",END";
addToCommandQueue(command); addToCommandQueue(command);
} }
lastPoint = new PVector(p.x, p.y); lastPoint = new PVector(p.x, p.y);
@ -891,6 +887,7 @@ List<PVector> filterPointsLowPass(RPoint[] points, long filterParam, float scali
// scale and convert all the points first // scale and convert all the points first
List<PVector> scaled = new ArrayList<PVector>(points.length); List<PVector> scaled = new ArrayList<PVector>(points.length);
println("a filterPointsLowPass: Scaled length: " + points.length);
for (int j = 0; j<points.length; j++) for (int j = 0; j<points.length; j++)
{ {
RPoint firstPoint = points[j]; RPoint firstPoint = points[j];
@ -905,7 +902,8 @@ List<PVector> filterPointsLowPass(RPoint[] points, long filterParam, float scali
} }
} }
if (scaled.size() > 1) println("b filterPointsLowPass: Scaled length: " + scaled.size());
if (scaled.size() > 1.0)
{ {
PVector p = scaled.get(0); PVector p = scaled.get(0);
result.add(p); result.add(p);
@ -914,17 +912,18 @@ List<PVector> filterPointsLowPass(RPoint[] points, long filterParam, float scali
{ {
p = scaled.get(j); p = scaled.get(j);
// and even then, only bother drawing if it's a move of over "x" steps // and even then, only bother drawing if it's a move of over "x" steps
int diffx = int(p.x) - int(result.get(result.size()-1).x); int diffx = abs(int(p.x) - int(result.get(result.size()-1).x));
int diffy = int(p.y) - int(result.get(result.size()-1).y); int diffy = abs(int(p.y) - int(result.get(result.size()-1).y));
if (abs(diffx) > filterParam || abs(diffy) > filterParam) if (diffx > filterParam || diffy > filterParam)
{ {
//println("Adding point " + p + ", last: " + result.get(result.size()-1)); println(j + ". Adding point " + p + " because diffx (" + diffx + ") or diffy (" + diffy + ") is > " + filterParam + ", last: " + result.get(result.size()-1));
result.add(p); result.add(p);
} }
} }
} }
println("c filterPointsLowPass: Scaled length: " + result.size());
if (result.size() < 2) if (result.size() < 2)
result.clear(); result.clear();
@ -945,7 +944,7 @@ void sendMachineStoreMode()
} }
void sendMachineLiveMode() void sendMachineLiveMode()
{ {
addToRealtimeCommandQueue(CMD_MACHINE_MODE_LIVE+"END"); addToCommandQueue(CMD_MACHINE_MODE_LIVE+"END");
} }
void sendMachineExecMode() void sendMachineExecMode()
{ {
@ -969,5 +968,3 @@ void sendDrawRandomSprite(String spriteFilename)
{ {
addToCommandQueue(CMD_DRAW_RANDOM_SPRITE+","+spriteFilename+",100,500,END"); addToCommandQueue(CMD_DRAW_RANDOM_SPRITE+","+spriteFilename+",100,500,END");
} }

View File

@ -1,234 +0,0 @@
//ControllIO controllIO;
//ControllDevice joypad;
//
//ControllButton buttonA;
//ControllButton buttonB;
//ControllButton buttonX;
//ControllButton buttonY;
//ControllButton buttonL;
//ControllButton buttonR;
//ControllButton buttonStart;
//
//ControllCoolieHat dpad;
//
//List<String> devices = new ArrayList<String>(
// Arrays.asList("Controller (Xbox 360 Wireless Receiver for Windows)",
// "Controller (XBOX 360 For Windows)"));
//
//String signalFromGamepad = null;
//
//static final String BUTTON_A_RELEASED = "ButtonAReleased";
//static final String BUTTON_B_RELEASED = "ButtonBReleased";
//static final String BUTTON_L_RELEASED = "ButtonLReleased";
//static final String BUTTON_R_RELEASED = "ButtonRReleased";
//static final String BUTTON_START_RELEASED = "ButtonStartReleased";
//
//void gamepad_init()
//{
// controllIO = ControllIO.getInstance(this);
//
// try
// {
// controllIO.printDevices();
// for (int i = 0; i<devices.size(); i++)
// {
// try
// {
// println("trying " + i + ": " + devices.get(i));
// joypad = controllIO.getDevice(devices.get(i));
// break;
// }
// catch (RuntimeException e)
// {
// println("Requested device (" + devices.get(i) + ") not found.");
// joypad = null;
// }
// }
//
// if (joypad != null)
// {
// joypad.printButtons();
//
// buttonA = joypad.getButton("Button 0");
// buttonB = joypad.getButton("Button 1");
// buttonX = joypad.getButton("Button 2");
// buttonY = joypad.getButton("Button 3");
//
// buttonL = joypad.getButton("Button 4");
// buttonR = joypad.getButton("Button 5");
//
// buttonStart = joypad.getButton("Button 7");
//
// buttonA.plug(this, "buttonARelease", ControllIO.ON_RELEASE);
// buttonB.plug(this, "buttonBRelease", ControllIO.ON_RELEASE);
// buttonX.plug(this, "buttonXPress", ControllIO.ON_PRESS);
// buttonX.plug(this, "buttonXRelease", ControllIO.ON_RELEASE);
// buttonY.plug(this, "buttonYRelease", ControllIO.ON_RELEASE);
//
// buttonL.plug(this, "buttonLRelease", ControllIO.ON_RELEASE);
// buttonR.plug(this, "buttonRRelease", ControllIO.ON_RELEASE);
//
// buttonStart.plug(this, "buttonStartRelease", ControllIO.ON_RELEASE);
//
// dpad = joypad.getCoolieHat(10);
// dpad.setMultiplier(4);
// dpad.plug(this, "dpadPress", ControllIO.ON_PRESS);
// }
// }
// catch (RuntimeException e)
// {
// println("Exception occurred while initialising gamepad: " + e.getMessage());
// }
//}
//
//public void buttonARelease()
//{
// signalFromGamepad = BUTTON_A_RELEASED;
//}
//public void buttonBRelease()
//{
// signalFromGamepad = BUTTON_B_RELEASED;
//}
//public void buttonLRelease()
//{
// signalFromGamepad = BUTTON_L_RELEASED;
//}
//public void buttonRRelease()
//{
// signalFromGamepad = BUTTON_R_RELEASED;
//}
//public void buttonStartRelease()
//{
// signalFromGamepad = BUTTON_START_RELEASED;
//}
//
//void buttonXPress()
//{
// drawingLiveVideo = true;
//}
//void buttonXRelease()
//{
// drawingLiveVideo = false;
//}
//void buttonYRelease()
//{
// flipWebcamImage = !flipWebcamImage;
//}
//
//void dpadPress(float x, float y)
//{
// float val = dpad.getValue();
// if (val == 6.0)
// {
// liveSimplification--;
// if (liveSimplification < LIVE_SIMPLIFICATION_MIN)
// liveSimplification = LIVE_SIMPLIFICATION_MIN;
// }
// else if (val == 2.0)
// {
// liveSimplification++;
// if (liveSimplification > LIVE_SIMPLIFICATION_MAX)
// liveSimplification = LIVE_SIMPLIFICATION_MAX;
// }
// if (val == 8.0) // left
// {
// pathLengthHighPassCutoff--;
// if (pathLengthHighPassCutoff < PATH_LENGTH_HIGHPASS_CUTOFF_MIN)
// pathLengthHighPassCutoff = PATH_LENGTH_HIGHPASS_CUTOFF_MIN;
// }
// else if (val == 4.0) // right
// {
// pathLengthHighPassCutoff++;
// if (pathLengthHighPassCutoff > PATH_LENGTH_HIGHPASS_CUTOFF_MAX)
// pathLengthHighPassCutoff = PATH_LENGTH_HIGHPASS_CUTOFF_MAX;
// }
//
// Numberbox n = (Numberbox) getAllControls().get(MODE_LIVE_SIMPLIFICATION_VALUE);
// n.setValue(liveSimplification);
// n.update();
//
// n = (Numberbox) getAllControls().get(MODE_VECTOR_PATH_LENGTH_HIGHPASS_CUTOFF);
// n.setValue(pathLengthHighPassCutoff);
// n.update();
//
//}
//
//void processGamepadInput()
//{
// if (signalFromGamepad != null)
// {
// println("Signal from gamepad: " + signalFromGamepad);
// if (signalFromGamepad == BUTTON_A_RELEASED)
// {
// if (captureShape == null && !confirmedDraw)
// button_mode_liveCaptureFromLive();
// else if (captureShape != null && !confirmedDraw)
// button_mode_liveClearCapture();
// else if (captureShape != null && confirmedDraw)
// {
// button_mode_liveClearCapture();
// button_mode_clearQueue();
// confirmedDraw = false;
// }
// }
// else if (signalFromGamepad == BUTTON_B_RELEASED)
// {
// if (captureShape != null && !confirmedDraw)
// button_mode_liveConfirmDraw();
// }
// else if (signalFromGamepad == BUTTON_L_RELEASED)
// {
// commandQueueRunning = !commandQueueRunning;
// }
// else if (signalFromGamepad == BUTTON_R_RELEASED)
// {
// }
// else if (signalFromGamepad == BUTTON_START_RELEASED)
// {
// preLoadCommandQueue();
// button_mode_setPositionHome();
// }
//
//
// // clear the signal
// signalFromGamepad = null;
// }
//
//}
//void displayGamepadOverlay()
//{
// textSize(40);
// fill(255);
//
// if (captureShape == null)
// {
// image(aButtonImage, width-400, height-180, 128, 128);
// text("SNAP!", width-400, height-200);
//
// textSize(30);
// image(dpadYImage, width-600, height-180, 128, 128);
// text("Simplify", width-600, height-200);
//
// image(dpadXImage, width-600, height-400, 128, 128);
// text("Filter short paths", width-600, height-420);
// }
// else
// {
// if (confirmedDraw)
// {
// image(aButtonImage, width-400, height-180, 128, 128);
// text("CANCEL!", width-385, height-200);
// }
// else
// {
// image(aButtonImage, width-400, height-180, 128, 128);
// text("BACK", width-400, height-200);
// image(bButtonImage, width-190, height-180, 128, 128);
// text("DRAW!", width-180, height-200);
// }
// }
//
//
// textSize(12);
//}

File diff suppressed because it is too large Load Diff

7
queue.pde Normal file
View File

@ -0,0 +1,7 @@
/**
Tools for dealing with a full command queue.
Optimise queue.
*/

View File

@ -25,7 +25,6 @@
sandy.noble@gmail.com sandy.noble@gmail.com
http://www.polargraph.co.uk/ http://www.polargraph.co.uk/
https://github.com/euphy/polargraphcontroller https://github.com/euphy/polargraphcontroller
*/ */
Set<Panel> getPanelsForTab(String tabName) Set<Panel> getPanelsForTab(String tabName)
@ -84,25 +83,35 @@ List<String> buildTabNames()
void initTabs() void initTabs()
{ {
cp5.tab(TAB_NAME_INPUT).setLabel(TAB_LABEL_INPUT); int tabWidth = (int)DEFAULT_CONTROL_SIZE.x;
cp5.tab(TAB_NAME_INPUT).activateEvent(true); int tabHeight = (int)DEFAULT_CONTROL_SIZE.y;
cp5.tab(TAB_NAME_INPUT).setId(1);
Tab.padding = 13; // that's a weird thing to do
Tab input = cp5.getTab(TAB_NAME_INPUT);
input.setLabel(TAB_LABEL_INPUT);
input.activateEvent(true);
input.setId(1);
cp5.tab(TAB_NAME_DETAILS).setLabel(TAB_LABEL_DETAILS); Tab details = cp5.getTab(TAB_NAME_DETAILS);
cp5.tab(TAB_NAME_DETAILS).activateEvent(true); details.setLabel(TAB_LABEL_DETAILS);
cp5.tab(TAB_NAME_DETAILS).setId(2); details.activateEvent(true);
details.setId(2);
Tab roving = cp5.getTab(TAB_NAME_ROVING);
roving.setLabel(TAB_LABEL_ROVING);
roving.activateEvent(true);
roving.setId(3);
cp5.tab(TAB_NAME_ROVING).setLabel(TAB_LABEL_ROVING); Tab trace = cp5.getTab(TAB_NAME_TRACE);
cp5.tab(TAB_NAME_ROVING).activateEvent(true); trace.setLabel(TAB_LABEL_TRACE);
cp5.tab(TAB_NAME_ROVING).setId(3); trace.activateEvent(true);
trace.setId(4);
cp5.tab(TAB_NAME_TRACE).setLabel(TAB_LABEL_TRACE); Tab queue = cp5.getTab(TAB_NAME_QUEUE);
cp5.tab(TAB_NAME_TRACE).activateEvent(true); queue.setLabel(TAB_LABEL_QUEUE);
cp5.tab(TAB_NAME_TRACE).setId(4); queue.activateEvent(true);
queue.setId(5);
cp5.tab(TAB_NAME_QUEUE).setLabel(TAB_LABEL_QUEUE);
cp5.tab(TAB_NAME_QUEUE).activateEvent(true);
cp5.tab(TAB_NAME_QUEUE).setId(5);
} }
public Set<String> buildPanelNames() public Set<String> buildPanelNames()