diff --git a/PrinterCommunication/Io/GCodeFileStream.cs b/PrinterCommunication/Io/GCodeFileStream.cs index c4dbf6dfe..14698bfbd 100644 --- a/PrinterCommunication/Io/GCodeFileStream.cs +++ b/PrinterCommunication/Io/GCodeFileStream.cs @@ -34,12 +34,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io { public class GCodeFileStream : GCodeStream { - private GCodeFile fileStreaming; + public GCodeFile FileStreaming { get; private set; } private int printerCommandQueueLineIndex = -1; public GCodeFileStream(GCodeFile fileStreaming, int startLine = 0) { - this.fileStreaming = fileStreaming; + this.FileStreaming = fileStreaming; printerCommandQueueLineIndex = startLine; } @@ -51,9 +51,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io public override string ReadLine() { - if (printerCommandQueueLineIndex < fileStreaming.LineCount) + if (printerCommandQueueLineIndex < FileStreaming.LineCount) { - return fileStreaming.Instruction(printerCommandQueueLineIndex++).Line; + return FileStreaming.Instruction(printerCommandQueueLineIndex++).Line; } return null; diff --git a/PrinterCommunication/Io/GCodeStreamProxy.cs b/PrinterCommunication/Io/GCodeStreamProxy.cs index c9208abdf..5d17fbffc 100644 --- a/PrinterCommunication/Io/GCodeStreamProxy.cs +++ b/PrinterCommunication/Io/GCodeStreamProxy.cs @@ -52,7 +52,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io } public override string ReadLine() { - return internalStream.ReadLine(); + if (internalStream != null) + { + return internalStream.ReadLine(); + } + + return null; } public override void SetPrinterPosition(PrinterMove position) diff --git a/PrinterCommunication/Io/ResumePrintingStream.cs b/PrinterCommunication/Io/ResumePrintingStream.cs index 39dac0759..9b18c1725 100644 --- a/PrinterCommunication/Io/ResumePrintingStream.cs +++ b/PrinterCommunication/Io/ResumePrintingStream.cs @@ -29,20 +29,31 @@ either expressed or implied, of the FreeBSD Project. using System; using MatterHackers.GCodeVisualizer; +using MatterHackers.Agg; +using MatterHackers.MatterControl.SlicerConfiguration; +using MatterHackers.MatterControl.PrinterControls; namespace MatterHackers.MatterControl.PrinterCommunication.Io { internal class ResumePrintingStream : GCodeStream { + enum ResumeState { RemoveHeating, Raising, Homing, FindingResumeLayer, SkippingGCode, PrimingAndMovingToStart, PrintingSlow, PrintingToEnd } private GCodeFileStream gCodeFileStream0; - private GCodeFile loadedGCode; private double percentDone; + PrinterMove lastDestination; + QueuedCommandsStream raiseCommands; - public ResumePrintingStream(GCodeFile loadedGCode, GCodeFileStream gCodeFileStream0, double percentDone) + ResumeState resumeState = ResumeState.RemoveHeating; + + public ResumePrintingStream(GCodeFileStream gCodeFileStream0, double percentDone) { - this.loadedGCode = loadedGCode; this.gCodeFileStream0 = gCodeFileStream0; this.percentDone = percentDone; + + raiseCommands = new QueuedCommandsStream(null); + raiseCommands.Add("G91 ; move relative"); + raiseCommands.Add("G1 Z10 F{0}".FormatWith(MovementControls.ZSpeed)); + raiseCommands.Add("G90 ; move absolute"); } public override void Dispose() @@ -51,34 +62,96 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io public override string ReadLine() { - // heat the extrude to remove it from the part - // remove it from the part - // if top homing, home the extruder - - // run through the gcode that the device expected looking for things like temp - // and skip everything else until we get to the point we left off last time - while (loadedGCode.PercentComplete(gCodeFileStream0.LineIndex) < percentDone) + switch(resumeState) { - string line = gCodeFileStream0.ReadLine(); - // check if the line is something we want to send to the printer (like a temp) - if (line.StartsWith("M109") - || line.StartsWith("M104")) - { - return line; - } + // heat the extrude to remove it from the part + case ResumeState.RemoveHeating: + // TODO: make sure we heat up all the extruders that we need to (all that are used) + resumeState = ResumeState.Raising; + return "M109 S{0}".FormatWith(ActiveSliceSettings.Instance.GetMaterialValue("temperature", 1)); + + // remove it from the part + case ResumeState.Raising: + string nextCommand = raiseCommands.ReadLine(); + if(nextCommand != null) + { + return nextCommand; + } + resumeState = ResumeState.Homing; + goto case ResumeState.Homing; + + // if top homing, home the extruder + case ResumeState.Homing: + resumeState = ResumeState.FindingResumeLayer; + return "G28"; + + // This is to resume printing if an out a filament occurs. + // Help the user move the extruder down to just touching the part + case ResumeState.FindingResumeLayer: + if (false) // help the user get the head to the right position + { + // move to above the completed print + // move over a know good part of the model at the current top layer (extrude vertex from gcode) + // let the user move down until they like the height + // calculate that position and continue + } + else // we are resuming because of disconnect or reset, skip this + { + resumeState = ResumeState.SkippingGCode; + goto case ResumeState.SkippingGCode; + } + + case ResumeState.SkippingGCode: + // run through the gcode that the device expected looking for things like temp + // and skip everything else until we get to the point we left off last time + while (gCodeFileStream0.FileStreaming.PercentComplete(gCodeFileStream0.LineIndex) < percentDone) + { + string line = gCodeFileStream0.ReadLine(); + + lastDestination = GetPosition(line, lastDestination); + + // check if the line is something we want to send to the printer (like a temp) + if (line.StartsWith("M109") + || line.StartsWith("M104")) + { + return line; + } + } + + resumeState = ResumeState.PrimingAndMovingToStart; + goto case ResumeState.PrimingAndMovingToStart; + + case ResumeState.PrimingAndMovingToStart: + resumeState = ResumeState.PrintingSlow; + goto case ResumeState.PrintingSlow; + + case ResumeState.PrintingSlow: + string lineToSend = gCodeFileStream0.ReadLine(); + if(!lineToSend.StartsWith("; LAYER:")) + { + if (lineToSend != null + && LineIsMovement(lineToSend)) + { + PrinterMove currentMove = GetPosition(lineToSend, lastDestination); + PrinterMove moveToSend = currentMove; + double feedRate = ActiveSliceSettings.Instance.GetActiveValueAsDouble("first_layer_speed", 10); + moveToSend.feedRate = feedRate; + + lineToSend = CreateMovementLine(moveToSend, lastDestination); + lastDestination = currentMove; + return lineToSend; + } + + return lineToSend; + } + resumeState = ResumeState.PrintingToEnd; + goto case ResumeState.PrintingToEnd; + + case ResumeState.PrintingToEnd: + return gCodeFileStream0.ReadLine(); } - bool isFirstLayerOfResume = false; - - string lineToSend = gCodeFileStream0.ReadLine(); - - if (isFirstLayerOfResume) - { - // print at resume speed - return lineToSend; - } - - return lineToSend; + return null; } public override void SetPrinterPosition(PrinterMove position) diff --git a/PrinterCommunication/PrinterConnectionAndCommunication.cs b/PrinterCommunication/PrinterConnectionAndCommunication.cs index e693d7b8f..d22729735 100644 --- a/PrinterCommunication/PrinterConnectionAndCommunication.cs +++ b/PrinterCommunication/PrinterConnectionAndCommunication.cs @@ -2449,7 +2449,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication gCodeFileStream0 = new GCodeFileStream(loadedGCode); if(activePrintTask != null) // We are resuming a failed print (do lots of interesting stuff). { - pauseHandlingStream1 = new PauseHandlingStream(new ResumePrintingStream(loadedGCode, gCodeFileStream0, activePrintTask.PercentDone)); + pauseHandlingStream1 = new PauseHandlingStream(new ResumePrintingStream(gCodeFileStream0, activePrintTask.PercentDone)); } else { @@ -2743,7 +2743,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication double secondsSinceStartedPrint = timeSinceStartedPrint.Elapsed.TotalSeconds; if (secondsSinceUpdateHistory > secondsSinceStartedPrint - || secondsSinceUpdateHistory + 5 < secondsSinceStartedPrint) + || secondsSinceUpdateHistory + 1 < secondsSinceStartedPrint) { activePrintTask.PercentDone = loadedGCode.PercentComplete(gCodeFileStream0.LineIndex); activePrintTask.Commit(); diff --git a/PrinterControls/ControlWidgets/MovementControls.cs b/PrinterControls/ControlWidgets/MovementControls.cs index b4d8e697f..851502764 100644 --- a/PrinterControls/ControlWidgets/MovementControls.cs +++ b/PrinterControls/ControlWidgets/MovementControls.cs @@ -48,7 +48,6 @@ namespace MatterHackers.MatterControl.PrinterControls { public bool hotKeysEnabled = false; public FlowLayoutWidget manualControlsLayout; - private double borderWidth = 2; private Button disableMotors; private EditManualMovementSpeedsWindow editManualMovementSettingsWindow; private Button homeAllButton; diff --git a/SlicerConfiguration/ActiveSliceSettings.cs b/SlicerConfiguration/ActiveSliceSettings.cs index d8c8b8ac8..c25ee5ad8 100644 --- a/SlicerConfiguration/ActiveSliceSettings.cs +++ b/SlicerConfiguration/ActiveSliceSettings.cs @@ -161,6 +161,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } + public double GetActiveValueAsDouble(string keyToLookUp, double valueOnError) + { + double foundValue; + if (!double.TryParse(GetActiveValue(keyToLookUp), out foundValue)) + { + return valueOnError; + } + + return foundValue; + } + public string GetMaterialValue(string sliceSetting, int extruderNumber1Based) { int numberOfActiveLayers = activeSettingsLayers.Count;