In the previous tutorial we have written a simple class for creating a vase generator with Processing. Now we will continue our work by adding a GUI to it, so that it will be much easier to experiment with different shapes, before choosing what we want to print.
Adding a GUI
First, download, import and initialize the library controlP5, the one we will use to create our GUI.
//... import controlP5.*; ControlP5 cp5; // Control P5 for GUI //... void setup() { size(800, 600, P3D); //... // Initialize Control P5 cp5 = new ControlP5(this); cp5.setAutoDraw(false); //... }
I suggest now to create a new tab in your Processing sketch and call it “GUI”.
We will now create a new class that will make the code for our GUI more tidy and easier to maintain. Let’s call this class Builder
.
class Builder { Printer printer = new Printer(); Settings settings = new Settings(); Processor processor = new Processor(); Drawer drawer; GcodeGenerator gcodeGenerator; Vase vase; Builder() { addCreator(); update(); } void addCreator() { vase = new Vase(printer, settings, printer.x_center_table, printer.y_center_table); } void update() { vase.generate(); processor = new Processor(); processor.addObject(vase); processor.sortPaths(); drawer = new Drawer(processor, printer); gcodeGenerator = new GcodeGenerator(printer, settings, processor); } void visualize() { drawer.displayPrinterChamber(); drawer.displayPaths(color(0, 150)); } void exportGcode() { gcodeGenerator = new GcodeGenerator(printer, settings, processor); gcodeGenerator.generate().export(); } }
As you can see, Builder
packs together everything that was previously written in the main tab of the sketch. Let’s see how this looks now:
import java.util.Collections; import java.util.Comparator; import peasy.*; import peasy.org.apache.commons.math.*; import peasy.org.apache.commons.math.geometry.*; PeasyCam cam; // Peasy cam for 3d views import controlP5.*; ControlP5 cp5; // Control P5 for GUI Builder builder; void setup() { size(800, 600, P3D); cam = new PeasyCam(this, 100); builder = new Builder(); // Initialize Control P5 cp5 = new ControlP5(this); cp5.setAutoDraw(false); setGui(); } void draw() { background(255); builder.visualize(); gui(); }
As you notice, there are two functions which we have not covered yet: setGui()
and gui()
.
gui()
allows us to use controlP5 together with PeasyCam, making sure that the two libraries don’t interfere with each other:
// ENABLE CONTOLP5 WITH PEASYCAM void gui() { hint(DISABLE_DEPTH_TEST); cam.beginHUD(); if (cp5.isMouseOver()) { cam.setActive(false); } else { cam.setActive(true); } cp5.draw(); cam.endHUD(); hint(ENABLE_DEPTH_TEST); }
setGui()
adds the different controllers that we want to our interface, in these case several sliders and a button. Refer to the controlP5 documentation and examples to find out how they exactly work and what else you can do with the library. Associated with setGui()
there is a ControlEvent()
function:
void setGui() { cp5.setAutoDraw(false); float start_X = 10; float inc_X = 10; float start_Y = 10; float inc_Y = 10; cp5.addSlider("sides").setPosition(start_X, start_Y+=2*inc_Y).setRange(3, 100).setNumberOfTickMarks(98).setCaptionLabel("sides number").setColorCaptionLabel(100).setValue(4); cp5.addSlider("width_vase").setPosition(start_X, start_Y+=2*inc_Y).setRange(0, builder.printer.width_table/2).setCaptionLabel("Width X (mm)").setColorCaptionLabel(100).setValue(10); cp5.addSlider("length_vase").setPosition(start_X, start_Y+=inc_Y).setRange(0, builder.printer.length_table/2).setCaptionLabel("Length X (mm)").setColorCaptionLabel(100).setValue(10); cp5.addSlider("height_vase").setPosition(start_X, start_Y+=inc_Y).setRange(0, builder.printer.height_printer).setCaptionLabel("Height X (mm)").setColorCaptionLabel(100).setValue(10); cp5.addSlider("rotation").setPosition(start_X, start_Y+=2*inc_Y).setRange(0, QUARTER_PI/15).setCaptionLabel("Rotation (rad)").setColorCaptionLabel(100).setValue(0); cp5.addSlider("amount_oscillation_XY").setPosition(start_X, start_Y+=2*inc_Y).setRange(0, 50).setCaptionLabel("amount oscillation XY (mm)").setColorCaptionLabel(100).setValue(0); cp5.addSlider("increment_oscillation_XY").setPosition(start_X, start_Y+=inc_Y).setRange(0, PI).setCaptionLabel("increment oscillation XY (rad)").setColorCaptionLabel(100).setValue(0); cp5.addSlider("amount_oscillation_Z").setPosition(start_X, start_Y+=2*inc_Y).setRange(0, 50).setCaptionLabel("amount oscillation Z (mm)").setColorCaptionLabel(100).setValue(0); cp5.addSlider("increment_oscillation_Z").setPosition(start_X, start_Y+=inc_Y).setRange(0, QUARTER_PI/15).setCaptionLabel("increment oscillation Z (rad)").setColorCaptionLabel(100).setValue(0); cp5.addButton("Export GCODE").setPosition(10, height-50).setHeight(40).setWidth(int(0.2*width)-10).setColorLabel(10).setColorBackground(color(0, 200, 0)); } void controlEvent(ControlEvent theEvent) { if (theEvent.isController()) { if (theEvent.getController().getName()=="sides") { builder.vase.setSides((int)cp5.getController("sides").getValue()); builder.update(); } else if (theEvent.getController().getName()=="width_vase") { builder.vase.setWidth(cp5.getController("width_vase").getValue()); builder.update(); } else if (theEvent.getController().getName()=="length_vase") { builder.vase.setLength(cp5.getController("length_vase").getValue()); builder.update(); } else if (theEvent.getController().getName()=="height_vase") { builder.vase.setHeight(cp5.getController("height_vase").getValue()); builder.update(); } else if (theEvent.getController().getName()=="rotation") { builder.vase.setRotation(cp5.getController("rotation").getValue()); builder.update(); } else if (theEvent.getController().getName()=="amount_oscillation_XY") { builder.vase.setOscillationXYAmount(cp5.getController("amount_oscillation_XY").getValue()); builder.update(); } else if (theEvent.getController().getName()=="increment_oscillation_XY") { builder.vase.setOscillationXY(cp5.getController("increment_oscillation_XY").getValue()); builder.update(); } else if (theEvent.getController().getName()=="amount_oscillation_Z") { builder.vase.setOscillationZAmount(cp5.getController("amount_oscillation_Z").getValue()); builder.update(); } else if (theEvent.getController().getName()=="increment_oscillation_Z") { builder.vase.setOscillationZ(cp5.getController("increment_oscillation_Z").getValue()); builder.update(); } else if (theEvent.getController().getName()=="Export GCODE") { builder.exportGcode(); } } }
And here we have out GUI for our vase generator:
As we said in the previous tutorial, this is only a little example: try to expand this vase generator and see what you can achieve!
Hey, cool tutorial and great work, thanks! 🙂
Getting The function displayPrinterChamber() does not exist?
Hi, you can get all the code here https://github.com/zmorph/codeplastic/tree/master/vase_generator