package org.reprap.pcb; import org.reprap.geometry.polygons.*; import org.reprap.utilities.RrGraphics; import org.reprap.Preferences; import org.reprap.Extruder; import java.util.Iterator; import java.util.LinkedList; //import GerberGCode.Aperture; public class GerberGCode { private class Aperture { int num; double width, height; char type; public Aperture(int num, double width, char type) { this.num = num; this.width = width; this.height = width; this.type = type; } public Aperture(int num, double width, double height, char type) { this.num = num; this.width = width; this.height = height; this.type = type; } } boolean dawingOn = false; LinkedList <Aperture> apertures = new LinkedList<Aperture>(); Aperture curAperture = null; boolean absolute = true; Extruder pcbPen; BooleanGrid pcb; Point2D lastCoords = null; boolean colour = true; public GerberGCode(Extruder pp, BooleanGrid p, boolean c) { pcbPen = pp; enableAbsolute(); disableDrawing(); pcb = p; colour = c; lastCoords = new Point2D(0, 0); } public Rectangle drawLine(Point2D c) { return drawFatLine(fixCoords(c)); } public void goTo(Point2D c) { lastCoords = new Point2D(fixCoords(c)); } public void enableAbsolute() { absolute = true; } public void enableRelative() { absolute = false; } public void selectAperture(int aperture) { Iterator<Aperture> itr = apertures.iterator(); Aperture cur; while(itr.hasNext()) { cur = itr.next(); if(cur.num == aperture) { curAperture = cur; break; } } } public void addCircleAperture(int apertureNum, double width) { apertures.add(new Aperture(apertureNum, width, 'C')); } public void addRectangleAperture(int apertureNum, double width, double height) { apertures.add(new Aperture(apertureNum, width, height, 'R')); } public Rectangle exposePoint(Point2D c) { if(curAperture.type == 'C') return createCircle(fixCoords(c)); else return createRec(fixCoords(c)); } public Rectangle createRec(Point2D c) { //TODO: make this fill the rectangle double recWidth = curAperture.width/2.0f; double recHeight = curAperture.height/2.0f; c = fixCoords(c); Point2D p = new Point2D(recWidth, recHeight); Rectangle result = new Rectangle(Point2D.sub(c, p), Point2D.add(c, p)); if(pcb == null) return result; pcb.homogeneous(result.sw(), result.ne(), colour); lastCoords = new Point2D(fixCoords(c)); return result; } public Rectangle createCircle(Point2D c) { Rectangle result = circleToRectangle(c); if(pcb == null) return result; pcb.disc(c, curAperture.width*0.5, colour); lastCoords = new Point2D(fixCoords(c)); //octagon(fixCoords(c), curAperture.width); return result; } // private void addPointToPolygons(Rr2Point c) // { // if(currentPolygon == null && dawingOn) // { // currentPolygon = new RrPolygon(new Attributes(null, null, null, looksLike), false); // currentPolygon.add(new Rr2Point(c)); // } else if(!dawingOn) // { // if(currentPolygon != null) // if(currentPolygon.size() > 1) // thePattern.add(new RrPolygon(currentPolygon)); // currentPolygon = new RrPolygon(new Attributes(null, null, null, looksLike), false); // currentPolygon.add(new Rr2Point(c)); // } else // currentPolygon.add(new Rr2Point(c)); // // lastCoords = new Rr2Point(c); // enableDrawing(); // } private Rectangle circleToRectangle(Point2D c) { Point2D p = new Point2D(0.5*curAperture.width, 0.5*curAperture.width); return new Rectangle(Point2D.sub(c, p), Point2D.add(c, p)); } // private void octagon(Rr2Point p, double diameter) // { // double x, y, r; // double ang = 22.5*Math.PI/180; // r = 0.5*diameter; // Rr2Point q; // disableDrawing(); // for(int i = 0; i <= 8; i++) // { // q = new Rr2Point(p); // q = Rr2Point.add(q, new Rr2Point(r*Math.cos(ang), r*Math.sin(ang))); // addPointToPolygons(q); // ang += 0.25*Math.PI; // } // disableDrawing(); // } // private void drawOneLine(Rr2Point c) // { // addPointToPolygons(c); // } private Rectangle drawFatLine(Point2D c) { Rectangle result = circleToRectangle(c); result = Rectangle.union(result, circleToRectangle(lastCoords)); if(pcb == null) return result; //TODO: make this draw a fat line pcb.rectangle(lastCoords, c, 0.5*curAperture.width, colour); pcb.disc(c, curAperture.width*0.5, true); pcb.disc(lastCoords, curAperture.width*0.5, colour); lastCoords = new Point2D(c); return result; } private void enableDrawing() { dawingOn = true; } private void disableDrawing() { dawingOn = false; } Point2D fixCoords(Point2D c) { if(!absolute) { c = new Point2D(c); c = Point2D.add(c, lastCoords); } return c; } public PolygonList getPolygons() { if(Preferences.simulate()) { RrGraphics simulationPlot1 = new RrGraphics("PCB from gerber"); // if(currentPolygon != null) // thePattern.add(new RrPolygon(currentPolygon)); simulationPlot1.init(pcb.box(), false, "0"); simulationPlot1.add(pcb); } PolygonList result = new PolygonList(); double penWidth = pcbPen.getExtrusionSize(); pcb = pcb.offset(-0.5*penWidth); PolygonList pol = pcb.allPerimiters(pcb.attribute()); while(pol.size() > 0) { result.add(pol); pcb = pcb.offset(-penWidth); pol = pcb.allPerimiters(pcb.attribute()); } return result; } }