private static void ApplyRule(OverrideRule activeRule, List <GCodeLine> replacementLines, OverrideRule rule) { if (rule == null) { // Reset speed and/or extrusion factor if (activeRule.SpeedFactor != 100) { replacementLines.Add(new GCodeLine("M220 S100")); } if (activeRule.ExtrusionFactor != 100) { replacementLines.Add(new GCodeLine("M221 S100")); } } else { // Apply new speed and/or extrusion factor if ((activeRule == null && rule.SpeedFactor != 100) || (activeRule != null && activeRule.SpeedFactor != rule.SpeedFactor)) { replacementLines.Add(new GCodeLine($"M220 S{rule.SpeedFactor.ToString("F1", FrmMain.numberFormat)}")); } if ((activeRule == null && rule.ExtrusionFactor != 100) || (activeRule != null && activeRule.ExtrusionFactor != rule.ExtrusionFactor)) { replacementLines.Add(new GCodeLine($"M221 S{rule.ExtrusionFactor.ToString("F1", FrmMain.numberFormat)}")); } } }
// Perform island combination for a given tool on a given layer returning a segment for the selected tool private GCodeSegment CombineSegments(GCodeLayer layer, int toolNumber, ref int currentTool, ref OverrideRule activeRule, int startSegment = 0) { if (settings.Tools[toolNumber - 1].Type != ToolType.Nozzle) { // Don't bother with unconfigured tools return(null); } List <GCodeLine> replacementLines = new List <GCodeLine>(); double currentZ = 0.0; Coordinate lastPosition = null; foreach (GCodeSegment segment in layer.Segments) { // Filter to the requested tool if (segment.Tool == toolNumber) { lastPosition = EnrichSegment(layer, segment, replacementLines, toolNumber, ref currentTool, ref activeRule, ref currentZ); } } return((replacementLines.Count == 0) ? null : new GCodeSegment($"T{toolNumber}", toolNumber, null) { Lines = replacementLines, LastPosition = lastPosition }); }
private Coordinate EnrichSegment(GCodeLayer layer, GCodeSegment segment, List <GCodeLine> replacementLines, int toolNumber, ref int currentTool, ref OverrideRule activeRule, ref double currentZ) { bool primeTool = false; bool ensureUnhopAfterToolChange = false; foreach (GCodeLine line in segment.Lines) { // Get GCode of current line int?gCode = line.GetIValue('G'); // Movement if (gCode == 0 || gCode == 1) { // Keep track of the current Z position double?zPosition = line.GetFValue('Z'); if (zPosition.HasValue) { currentZ = zPosition.Value; // Since we have a Z height in this line we don't have to insert an artificial one ensureUnhopAfterToolChange = false; } // Make sure to un-hop before the first extrusion if required if (!double.IsNaN(layer.ZHeight) && line.GetFValue('E').HasValue&& (currentZ != layer.ZHeight || ensureUnhopAfterToolChange)) { replacementLines.Add(new GCodeLine($"G1 Z{layer.ZHeight.ToString("F3", FrmMain.numberFormat)} F{(line.Feedrate * 60.0).ToString("F0", FrmMain.numberFormat)}")); currentZ = layer.ZHeight; ensureUnhopAfterToolChange = false; } // Prime tool before first extrusion if (primeTool && line.GetFValue('E').HasValue) { replacementLines.Add(new GCodeLine($"G1 E{toolChangeRetractionDistance.ToString("F2", FrmMain.numberFormat)} F{toolChangeRetractionSpeed.ToString(FrmMain.numberFormat)}", toolChangeRetractionSpeed / 60.0)); toolPrimed[currentTool - 1] = true; primeTool = false; } // Add next movement of the segment replacementLines.Add(line); // Insert potential tool changes after first G0/G1 code if (toolNumber != currentTool) { // Reset any speed overrides so tool change is not slowed down if (activeRule != null) { replacementLines.Add(new GCodeLine("M220 S100")); activeRule = null; } AddToolChange(replacementLines, currentTool, toolNumber); currentTool = toolNumber; primeTool = !toolPrimed[currentTool - 1]; // Make sure we go to the height of the current layer after tool change but only before the first extrusion (see above) ensureUnhopAfterToolChange = true; } } // Always add it if is no movement else { replacementLines.Add(line); } // Deal with custom rules OverrideRule rule = GetRule(currentTool, layer.Number, segment); if (rule != activeRule) { ApplyRule(activeRule, replacementLines, rule); activeRule = rule; } } return(segment.LastPosition); }
public void PostProcess() { // We know how much we need to do here... maxProgress.Report(Math.Max(layers.Count * 4 - 4, 0)); // Combine tool islands per layer, adjust tool change sequences and take care of rules OverrideRule activeRule = null; int iteration = 1; bool startWithLowestTool = true; int currentTool = -1; for (int layerIndex = 1; layerIndex < layers.Count; layerIndex++) { GCodeLayer layer = layers[layerIndex]; GCodeLayer replacementLayer = new GCodeLayer(layerIndex, layer.ZHeight); if (settings.IslandCombining) { if (startWithLowestTool) { for (int toolNumber = 1; toolNumber <= settings.Tools.Length; toolNumber++) { // Go from T1-T5 GCodeSegment segment = CombineSegments(layer, toolNumber, ref currentTool, ref activeRule); if (segment != null) { replacementLayer.Segments.Add(segment); } } } else { for (int toolNumber = settings.Tools.Length; toolNumber >= 1; toolNumber--) { // Go from T5-T1 GCodeSegment segment = CombineSegments(layer, toolNumber, ref currentTool, ref activeRule); if (segment != null) { replacementLayer.Segments.Add(segment); } } } startWithLowestTool = !startWithLowestTool; } else { double currentZ = 0.0; foreach (GCodeSegment segment in layer.Segments) { int toolNumber = segment.Tool; List <GCodeLine> replacementLines = new List <GCodeLine>(); Coordinate lastPosition = EnrichSegment(layer, segment, replacementLines, toolNumber, ref currentTool, ref activeRule, ref currentZ); if (replacementLines.Count > 0) { replacementLayer.Segments.Add( new GCodeSegment($"T{toolNumber}", toolNumber, null) { Lines = replacementLines, LastPosition = lastPosition }); } } } layers[layerIndex] = replacementLayer; progress.Report(iteration++); } // Make sure the last applied rule is reset before the print finishes if (activeRule != null) { GCodeSegment lastSegment = layers.Last((layer) => layer.Segments.Count > 0).Segments.Last(); if (activeRule.SpeedFactor != 100) { lastSegment.Lines.Add(new GCodeLine("M220 S100")); } if (activeRule.ExtrusionFactor != 100) { lastSegment.Lines.Add(new GCodeLine("M221 S100")); } activeRule = null; } FixToolChangeRetractionAndPriming(ref iteration); InsertPreheatingSequences(ref iteration); }