/// 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; }
/** * 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; }
/** * 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; }