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.

This commit is contained in:
Sandy Noble 2018-05-27 23:01:08 +01:00
parent f2b1df7405
commit 5e7e010a79
8 changed files with 658 additions and 485 deletions

436
FileLoading.pde Normal file
View File

@ -0,0 +1,436 @@
/**
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;
}
}
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

@ -186,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;
} }
@ -322,8 +328,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;
} }

View File

@ -133,7 +133,6 @@ class Panel
{ {
for (Controller c : this.getControls()) for (Controller c : this.getControls())
{ {
// println("Control: " + c.getName());
PVector pos = getControlPositions().get(c.getName()); PVector pos = getControlPositions().get(c.getName());
float x = pos.x+getOutline().getLeft(); float x = pos.x+getOutline().getLeft();
float y = pos.y+getOutline().getTop(); float y = pos.y+getOutline().getTop();
@ -165,6 +164,13 @@ class Panel
{ {
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.getName().equals(MODE_LOAD_VECTOR_FILE)) if (c.getName().equals(MODE_LOAD_VECTOR_FILE))
{ {
@ -211,6 +217,7 @@ class Panel
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;

View File

@ -323,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)
@ -336,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;
@ -730,17 +732,11 @@ void numberbox_mode_previewCordOffsetValue(int value)
previewQueue(true); previewQueue(true);
} }
void button_mode_cycleDensityPreviewStyle() void dropdown_mode_cycleDensityPreviewStyle(int index)
{ {
Controller c = cp5.getController(MODE_CYCLE_DENSITY_PREVIEW_STYLE); println("In dropdown_mode_cycleDensityPreviewStyle");
c.setLabel(this.controlLabels.get(MODE_CYCLE_DENSITY_PREVIEW_STYLE) + ": " + densityPreviewStyle); densityPreviewStyle = index;
println("Style: " + densityPreviewStyle);
if (densityPreviewStyle == DENSITY_PREVIEW_STYLE_COUNT) {
densityPreviewStyle = 0;
}
else {
densityPreviewStyle++;
}
} }
void numberbox_mode_changeDensityPreviewPosterize(int value) { void numberbox_mode_changeDensityPreviewPosterize(int value) {
@ -760,20 +756,17 @@ void numberbox_mode_changePolygonizerLength(float value) {
setupPolygonizer(); setupPolygonizer();
} }
void numberbox_mode_changePolygonizerAdaptativeAngle(float value) {
void button_mode_cyclePolygonizer() println("numberbox_mode_changePolygonizerAdaptativeAngle");
{ polygonizerAdaptativeAngle = value;
setupPolygonizer();
// this is a bit silly for only two choices }
if (polygonizer == 1) {
polygonizer = 0;
} void dropdown_mode_changePolygonizer(int value)
else { {
polygonizer++; polygonizer = value;
}
setupPolygonizer(); setupPolygonizer();
Controller c = cp5.getController(MODE_CHANGE_POLYGONIZER);
c.setLabel(this.controlLabels.get(MODE_CHANGE_POLYGONIZER) + ": " + polygonizer);
} }

View File

@ -83,6 +83,14 @@ 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())
{ {
@ -227,9 +235,37 @@ 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()
{ {
@ -243,6 +279,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));
controlP5.Label l = b.getCaptionLabel();
l.getStyle().marginLeft = 4; //move to the right
b.hide(); b.hide();
map.put(controlName, b); map.put(controlName, b);
// println("Added button " + controlName); // println("Added button " + controlName);
@ -283,11 +321,29 @@ Map<String, Controller> buildAllControls()
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); initialiseButtonValues(map);
initialiseToggleValues(map); initialiseToggleValues(map);
initialiseNumberboxValues(map); initialiseNumberboxValues(map);
initialiseDropdownContents(map);
initialiseDropdownValues(map);
return map; return map;
} }
@ -298,12 +354,7 @@ Map<String, Controller> initialiseButtonValues(Map<String, Controller> map)
if (key.startsWith("button_")) if (key.startsWith("button_"))
{ {
Button n = (Button) map.get(key); Button n = (Button) map.get(key);
if (MODE_CHANGE_POLYGONIZER.equals(key)) {
if (MODE_CYCLE_DENSITY_PREVIEW_STYLE.equals(key)) {
n.setValue(densityPreviewStyle);
n.setLabel(this.controlLabels.get(MODE_CYCLE_DENSITY_PREVIEW_STYLE) + ": " + densityPreviewStyle);
}
else if (MODE_CHANGE_POLYGONIZER.equals(key)) {
n.setValue(polygonizer); n.setValue(polygonizer);
n.setLabel(this.controlLabels.get(MODE_CHANGE_POLYGONIZER) + ": " + polygonizer); n.setLabel(this.controlLabels.get(MODE_CHANGE_POLYGONIZER) + ": " + polygonizer);
} }
@ -536,8 +587,8 @@ 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(0); 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)) else if (MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE.equals(key))
@ -553,7 +604,13 @@ Map<String, Controller> initialiseNumberboxValues(Map<String, Controller> map)
n.setMin(1.0); n.setMin(1.0);
n.setDecimalPrecision(1); n.setDecimalPrecision(1);
n.setMultiplier(0.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);
} }
} }
} }
@ -614,6 +671,51 @@ Map<String, Controller> initialiseToggleValues(Map<String, Controller> map)
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);
}
}
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();
}
}
return map;
}
String getControlLabel(String butName) String getControlLabel(String butName)
{ {
if (controlLabels.containsKey(butName)) if (controlLabels.containsKey(butName))
@ -642,6 +744,18 @@ Map<String, PVector> buildControlPositionsForPanel(Panel panel)
col++; 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++;
if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight())
{
row = 0;
col++;
}
}
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));
@ -671,6 +785,11 @@ Map<String, PVector> buildControlSizesForPanel(Panel panel)
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.getName(), 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);
@ -732,8 +851,6 @@ List<String> getControlNamesForInputPanel()
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_PIXEL_SCALING); controlNames.add(MODE_CHANGE_PIXEL_SCALING);
controlNames.add(MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE);
controlNames.add(MODE_CYCLE_DENSITY_PREVIEW_STYLE);
controlNames.add(MODE_RENDER_PIXEL_DIALOG); controlNames.add(MODE_RENDER_PIXEL_DIALOG);
// controlNames.add(MODE_DRAW_GRID); // controlNames.add(MODE_DRAW_GRID);
@ -744,20 +861,23 @@ 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);
controlNames.add(MODE_CHANGE_POLYGONIZER_LENGTH); 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_PREVIEW_PIXEL_DENSITY_RANGE);
controlNames.add(MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE);
controlNames.add(MODE_CYCLE_DENSITY_PREVIEW_STYLE);
return controlNames; return controlNames;
@ -1025,13 +1145,14 @@ Map<String, String> buildControlLabels()
result.put(MODE_SEND_BUTTON_DEACTIVATE, "Deactivate button"); result.put(MODE_SEND_BUTTON_DEACTIVATE, "Deactivate button");
result.put(MODE_ADJUST_PREVIEW_CORD_OFFSET, "Cord offset"); result.put(MODE_ADJUST_PREVIEW_CORD_OFFSET, "Cord offset");
result.put(MODE_CYCLE_DENSITY_PREVIEW_STYLE, "Cycle preview style"); result.put(MODE_CYCLE_DENSITY_PREVIEW_STYLE, "Density preview style");
result.put(MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE, "Pixel posterize"); result.put(MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE, "Pixel posterize");
result.put(MODE_PREVIEW_PIXEL_DENSITY_RANGE, "Show density range"); result.put(MODE_PREVIEW_PIXEL_DENSITY_RANGE, "Show density range");
result.put(MODE_CHANGE_POLYGONIZER, "Cycle polygonizer"); result.put(MODE_CHANGE_POLYGONIZER, "Polygonizer style");
result.put(MODE_CHANGE_POLYGONIZER_LENGTH, "Polygonizer length"); result.put(MODE_CHANGE_POLYGONIZER_LENGTH, "Polygonizer length");
result.put(MODE_CHANGE_POLYGONIZER_ADAPTATIVE_ANGLE, "Polygonizer angle");
return result; return result;
@ -1184,6 +1305,7 @@ Set<String> buildControlNames()
result.add(MODE_CHANGE_POLYGONIZER_LENGTH); result.add(MODE_CHANGE_POLYGONIZER_LENGTH);
result.add(MODE_CHANGE_POLYGONIZER); result.add(MODE_CHANGE_POLYGONIZER);
result.add(MODE_CHANGE_POLYGONIZER_ADAPTATIVE_ANGLE);
return result; return result;
} }

View File

@ -912,12 +912,12 @@ 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(j + ". 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);
} }
} }
@ -967,4 +967,4 @@ void sendStopSwirling()
void sendDrawRandomSprite(String spriteFilename) 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,7 +1,7 @@
/** /**
Polargraph controller Polargraph controller
Copyright Sandy Noble 2015. Copyright Sandy Noble 2018.
This file is part of Polargraph Controller. This file is part of Polargraph Controller.
Polargraph Controller is free software: you can redistribute it and/or modify Polargraph Controller is free software: you can redistribute it and/or modify
@ -35,11 +35,8 @@ import diewald_CV_kit.utility.*;
import diewald_CV_kit.blobdetection.*; import diewald_CV_kit.blobdetection.*;
import geomerative.*; import geomerative.*;
//import org.apache.batik.svggen.font.table.*;
//import org.apache.batik.svggen.font.*;
import java.util.zip.CRC32; import java.util.zip.CRC32;
// for OSX // for OSX
import java.text.*; import java.text.*;
import java.util.*; import java.util.*;
@ -58,7 +55,7 @@ import java.lang.reflect.Method;
int majorVersionNo = 2; int majorVersionNo = 2;
int minorVersionNo = 5; int minorVersionNo = 5;
int buildNo = 1; int buildNo = 2;
String programTitle = "Polargraph Controller v" + majorVersionNo + "." + minorVersionNo + " build " + buildNo; String programTitle = "Polargraph Controller v" + majorVersionNo + "." + minorVersionNo + " build " + buildNo;
ControlP5 cp5; ControlP5 cp5;
@ -340,16 +337,16 @@ static final String MODE_SEND_BUTTON_DEACTIVATE = "button_mode_sendButtonDeactiv
static final String MODE_ADJUST_PREVIEW_CORD_OFFSET = "numberbox_mode_previewCordOffsetValue"; static final String MODE_ADJUST_PREVIEW_CORD_OFFSET = "numberbox_mode_previewCordOffsetValue";
static final String MODE_CYCLE_DENSITY_PREVIEW_STYLE = "button_mode_cycleDensityPreviewStyle"; static final String MODE_CYCLE_DENSITY_PREVIEW_STYLE = "dropdown_mode_cycleDensityPreviewStyle";
static final String MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE = "numberbox_mode_changeDensityPreviewPosterize"; static final String MODE_CHANGE_DENSITY_PREVIEW_POSTERIZE = "numberbox_mode_changeDensityPreviewPosterize";
static final String MODE_PREVIEW_PIXEL_DENSITY_RANGE = "minitoggle_mode_previewPixelDensityRange"; static final String MODE_PREVIEW_PIXEL_DENSITY_RANGE = "minitoggle_mode_previewPixelDensityRange";
static final String MODE_CHANGE_POLYGONIZER = "button_mode_cyclePolygonizer"; static final String MODE_CHANGE_POLYGONIZER = "dropdown_mode_changePolygonizer";
static final String MODE_CHANGE_POLYGONIZER_LENGTH = "numberbox_mode_changePolygonizerLength"; static final String MODE_CHANGE_POLYGONIZER_LENGTH = "numberbox_mode_changePolygonizerLength";
static final String MODE_CHANGE_POLYGONIZER_ADAPTATIVE_ANGLE = "numberbox_mode_changePolygonizerAdaptativeAngle";
List<String> polygonizerStyles = Arrays.asList("ADAPTATIVE", "UNIFORMLENGTH");
PVector statusTextPosition = new PVector(300.0, 12.0); PVector statusTextPosition = new PVector(300.0, 12.0);
@ -386,6 +383,8 @@ boolean displayingDensityPreview = false;
boolean displayingGuides = true; boolean displayingGuides = true;
List<String> densityPreviewStyles = Arrays.asList("Round", "Diamond", "Native Simple", "Native Arc", "Round size", "Native size");
static final int DENSITY_PREVIEW_STYLE_COUNT = 6; static final int DENSITY_PREVIEW_STYLE_COUNT = 6;
static final int DENSITY_PREVIEW_ROUND = 0; static final int DENSITY_PREVIEW_ROUND = 0;
@ -496,6 +495,7 @@ float vectorScaling = 100;
PVector vectorPosition = new PVector(0.0,0.0); PVector vectorPosition = new PVector(0.0,0.0);
int minimumVectorLineLength = 2; int minimumVectorLineLength = 2;
public static final int VECTOR_FILTER_LOW_PASS = 0; public static final int VECTOR_FILTER_LOW_PASS = 0;
public Set<String> controlsToLockIfVectorNotLoaded = null;
String storeFilename = "comm.txt"; String storeFilename = "comm.txt";
@ -544,6 +544,7 @@ boolean rescaleDisplayMachine = true;
// Polygonization. It's a geomerative thing. // Polygonization. It's a geomerative thing.
int polygonizer = 0; int polygonizer = 0;
float polygonizerLength = 0.0; float polygonizerLength = 0.0;
float polygonizerAdaptativeAngle = 0.0F;
void setup() void setup()
{ {
@ -1081,411 +1082,6 @@ void showGroupBox()
} }
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;
}
}
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;
}
void setPictureFrameDimensionsToBox() void setPictureFrameDimensionsToBox()
@ -1799,7 +1395,7 @@ void mouseClicked()
if (getDisplayMachine().pixelsCanBeExtracted() && isBoxSpecified()) if (getDisplayMachine().pixelsCanBeExtracted() && isBoxSpecified())
getDisplayMachine().extractPixelsFromArea(getBoxVector1(), getBoxVectorSize(), getGridSize(), sampleArea); getDisplayMachine().extractPixelsFromArea(getBoxVector1(), getBoxVectorSize(), getGridSize(), sampleArea);
} }
else if (currentMode.equals(MODE_MOVE_VECTOR)) else if (currentMode.equals(MODE_MOVE_VECTOR) && vectorShape != null)
{ {
// offset mouse vector so it grabs the centre of the shape // offset mouse vector so it grabs the centre of the shape
PVector centroid = new PVector(getVectorShape().width/2, getVectorShape().height/2); PVector centroid = new PVector(getVectorShape().width/2, getVectorShape().height/2);
@ -1934,23 +1530,23 @@ void leftButtonMachineClick()
void mouseWheel(int delta) void mouseWheel(int delta)
{ {
noLoop(); noLoop();
// get the mouse position on the machine, before changing the machine scaling
PVector pos = getDisplayMachine().scaleToDisplayMachine(getMouseVector());
changeMachineScaling(delta);
// now work out what the machine position needs to be to line the pos up with mousevector again if (mouseOverMachine()) {
PVector scaledPos = getDisplayMachine().scaleToDisplayMachine(getMouseVector()); // get the mouse position on the machine, before changing the machine scaling
// println("original pos: " + pos); PVector pos = getDisplayMachine().scaleToDisplayMachine(getMouseVector());
// println("scaled pos: " + scaledPos); changeMachineScaling(delta);
// now work out what the machine position needs to be to line the pos up with mousevector again
PVector scaledPos = getDisplayMachine().scaleToDisplayMachine(getMouseVector());
PVector change = PVector.sub(scaledPos, pos);
PVector change = PVector.sub(scaledPos, pos); // and adjust for the new scaling factor
// println("change: " + change); change.mult(machineScaling);
// and adjust for the new scaling factor // finally update the machine offset (position)
change.mult(machineScaling); getDisplayMachine().getOffset().add(change);
}
// finally update the machine offset (position)
getDisplayMachine().getOffset().add(change);
loop(); loop();
} }
@ -3082,6 +2678,9 @@ void loadFromPropertiesFile()
// println("home point loaded: " + homePointCartesian + ", " + getHomePoint()); // println("home point loaded: " + homePointCartesian + ", " + getHomePoint());
// Geomerative stuff // Geomerative stuff
println("RG.ADAPTATIVE is " + RG.ADAPTATIVE);
println("RG.UNIFORMLENGTH is " + RG.UNIFORMLENGTH);
println("RG.UNIFORMSTEP is " + RG.UNIFORMSTEP);
polygonizer = getIntProperty("controller.geomerative.polygonizer", RG.ADAPTATIVE); polygonizer = getIntProperty("controller.geomerative.polygonizer", RG.ADAPTATIVE);
polygonizerLength = getFloatProperty("controller.geomerative.polygonizerLength", 1.0); polygonizerLength = getFloatProperty("controller.geomerative.polygonizerLength", 1.0);
setupPolygonizer(); setupPolygonizer();
@ -3342,12 +2941,15 @@ Integer getBaudRate()
void setupPolygonizer() { void setupPolygonizer() {
RG.setPolygonizer(polygonizer); // http://www.polargraph.co.uk/forum/polargraphs-group2/troubleshooting-forum5/svg-differences-between-polargraphcontroller-2-1-1-2-3-0-thread523.0 RG.setPolygonizer(polygonizer); // http://www.polargraph.co.uk/forum/polargraphs-group2/troubleshooting-forum5/svg-differences-between-polargraphcontroller-2-1-1-2-3-0-thread523.0
switch(polygonizer) { switch(polygonizer) {
case 1: RG.setPolygonizerLength(polygonizerLength); break; // case 0:
} // RG.setPolygonizerAngle(polygonizerAdaptativeAngle);
println("Polygonizer: " + polygonizer); // break;
println("PolygonizerLength: " + polygonizerLength); case 1:
RG.setPolygonizerLength(polygonizerLength);
break;
}
} }
void initLogging() void initLogging()
{ {
try try

7
queue.pde Normal file
View File

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