/** * If only one toolhead is used, a cool command for the unused head is added to this gcode source * object. Created to avoid smell/problems for single prints on a dual machine when prior build * was cancelled, or a toolhead is left hot from pre-heating. */ public void coolUnusedToolhead() { GCodeCommand gcode; String line; double tval; int additionPoint = 0; boolean addPointFound = false; boolean seenT0 = false; boolean seenT1 = false; for (Iterator<String> it = source.iterator(); it.hasNext(); ) { line = it.next(); gcode = new GCodeCommand(line); tval = gcode.getCodeValue('T'); if (tval == 0) seenT0 = true; if (tval == 1) seenT1 = true; if (!addPointFound) additionPoint++; if (gcode.getCodeValue('M') == 104) addPointFound = true; if (seenT0 && seenT1) return; } if (seenT0 && !seenT1) add(additionPoint, "M104 T1 S0"); if (seenT1 && !seenT0) add(additionPoint, "M104 T0 S0"); }
/// Runs through this gcode file, swapping all references to the the current toolhead /// to instread reference the specified toolhead. Alters select G, M and T Codes. public void changeToolhead(ToolheadAlias tool) { GCodeCommand gcode; int value; String line; /// FUTURE: create a synchronize block here someday ArrayList<String> newSource = new ArrayList<String>(source.size()); for (Iterator<String> it = source.iterator(); it.hasNext(); ) { line = it.next(); gcode = new GCodeCommand(line); if (gcode.hasCode('T')) { value = (int) gcode.getCodeValue('T'); if (value != tool.number) { if (value == 0) line = line.replace("T0", "T1"); else if (value == 1) line = line.replace("T1", "T0"); } } if (gcode.getCodeValue('G') == 54 && !(tool.getRecallOffsetGcodeCommand().equals("G54"))) { line = line.replace("G54", tool.getRecallOffsetGcodeCommand()); } if (gcode.getCodeValue('G') == 55 && !(tool.getRecallOffsetGcodeCommand().equals("G55"))) { line = line.replace("G55", tool.getRecallOffsetGcodeCommand()); } newSource.add(line); } source = newSource; }
/** * This gets the first feedrate used in a layer * * @param l * @return */ private String getFirstFeedrate(final Layer l) { final List<String> search = l.getCommands(); GCodeCommand gcode; for (int i = 0; i < search.size(); i++) { gcode = new GCodeCommand(search.get(i)); if (gcode.getCodeValue('F') != -1) return "F" + Base.getGcodeFormat().format(gcode.getCodeValue('F')); } return ""; }
/** * Apparently skeinforge does not have all the moves in a layer at the same height. The first one * is frequently lower than the following ones, so this function finds the last height listed in a * layer * * @param l the layer in which to look * @return the layer height (maybe) */ private Double getLayerZ(final Layer l) { final List<String> search = l.getCommands(); GCodeCommand gcode; for (int i = search.size() - 1; i >= 0; i--) { gcode = new GCodeCommand(search.get(i)); if (gcode.getCodeValue('G') == 1 && gcode.hasCode('Z')) { return gcode.getCodeValue('Z'); } } return null; }
/** * gets the first G1 from a layer, returns the position of X, Y, Z axes * * @param l * @return */ private Point5d getFirstPosition(final Layer l) { final List<String> search = l.getCommands(); GCodeCommand gcode; for (int i = 0; i < search.size(); i++) { gcode = new GCodeCommand(search.get(i)); if (gcode.getCodeValue('G') == 1) { Point5d result = new Point5d(); result.setX(gcode.getCodeValue('X')); result.setY(gcode.getCodeValue('Y')); result.setZ(gcode.getCodeValue('Z')); return result; } } return null; }
/** * Takes a GCodeSource, assumed to be lacking any start- or end- specific blocks of code and to be * in order of increasing layer height, and returns a LinkedList of Layers. Each Layer should * contain codes for a single height. The list should be in sorted order from lowest height to * highest. We use a LinkedList because all this is internal, so it doesn't change any interfaces * if we want to change it, and a LinkedList doubles as a Queue, which is handy for doMerge(). * * <p>WARNING: This code assumes that the source gcode follows one of two formats: Either the * extruder is turned off at the end of each layer using an M103, Or the gcode uses 5D, and there * are no M103/M101/M108 commands * * <p>These should be safe assumptions for any code generated by Skeinforge * * @param source * @return */ private LinkedList<Layer> testParseLayers(final GCodeSource source) { /* * So this is a little more complicated than just breaking up stuff by Z height, * there may be M commands between layers, some of which belong to the previous * layer, and some to the next. * To get around this we: * Walk through the source * // this assumes that every layer ends with the extruder off * keep a trailing pointer to the last M103 we saw, and a count of the last layer height * we saw when we see a new layer height, break off a new layer after the previous M103 * * but, with 5d, there won't be any M103, layers should have no associated pre/post Mcodes * */ final LinkedList<Layer> layers = new LinkedList<Layer>(); final Queue<String> read = new LinkedList<String>(); // debug code/////////////////////////// layers.add( new Layer( 0d, new ArrayList<String>() { { add("(*************start layer*************)"); } })); ////////////////////////////////////// String lastM103 = null; double lastZHeight = Double.MIN_VALUE; for (String line : source) { GCodeCommand gcode = new GCodeCommand(line); if (gcode.getCodeValue('M') == 103) lastM103 = line; if (gcode.hasCode('Z')) { double newZ = gcode.getCodeValue('Z'); // keeps us from creating an initial, empty layer if (lastZHeight == Double.MIN_VALUE) { lastZHeight = newZ; } else if (newZ > lastZHeight) { ArrayList<String> tmpLayer = new ArrayList<String>(); // fill the tmpLayer with the accumulated lines, up to the // most recent "stop extruding" or until the queue is empty (5D) while (read.peek() != null && read.peek() != lastM103) tmpLayer.add(read.poll()); // Also grab the M103, if present if (read.peek() == lastM103) tmpLayer.add(read.poll()); // put it in a new layer layers.add(new Layer(lastZHeight, tmpLayer)); // record our next layer height lastZHeight = newZ; } } read.add(line); } // debug code/////////////////////////// layers.add( new Layer( 0d, new ArrayList<String>() { { add("(*************end layer*************)"); } })); ////////////////////////////////////// return layers; }