diff --git a/MatterControl.Printing/Settings/PrinterSettings.cs b/MatterControl.Printing/Settings/PrinterSettings.cs index 5b6ed7987..ad3c54129 100644 --- a/MatterControl.Printing/Settings/PrinterSettings.cs +++ b/MatterControl.Printing/Settings/PrinterSettings.cs @@ -238,6 +238,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SettingsKey.trim_filament_markdown, SettingsKey.unload_filament_length, SettingsKey.use_z_probe, + SettingsKey.validate_leveling, SettingsKey.validate_layer_height, SettingsKey.write_regex, SettingsKey.xy_offsets_have_been_calibrated, diff --git a/MatterControl.Printing/Settings/SettingsHelpers.cs b/MatterControl.Printing/Settings/SettingsHelpers.cs index 38016cdc5..115b09a1b 100644 --- a/MatterControl.Printing/Settings/SettingsHelpers.cs +++ b/MatterControl.Printing/Settings/SettingsHelpers.cs @@ -186,6 +186,18 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } + public bool HasProbeWithLevelingValidation + { + get + { + return printerSettings.GetValue(SettingsKey.print_leveling_enabled) + && printerSettings.GetValue(SettingsKey.has_z_probe) + && printerSettings.GetValue(SettingsKey.use_z_probe) + && printerSettings.GetValue(SettingsKey.validate_leveling); + } + } + + public void DoPrintLeveling(bool doLeveling) { // Early exit if already set diff --git a/MatterControl.Printing/Settings/SettingsKey.cs b/MatterControl.Printing/Settings/SettingsKey.cs index 4f62bed27..57b1b3e15 100644 --- a/MatterControl.Printing/Settings/SettingsKey.cs +++ b/MatterControl.Printing/Settings/SettingsKey.cs @@ -260,6 +260,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string use_relative_e_distances = nameof(use_relative_e_distances); public const string use_z_probe = nameof(use_z_probe); public const string validate_layer_height = nameof(validate_layer_height); + public const string validate_leveling = nameof(validate_leveling); public const string vibration_limit = nameof(vibration_limit); public const string windows_driver = nameof(windows_driver); public const string wipe_shield_distance = nameof(wipe_shield_distance); diff --git a/MatterControl.Printing/Settings/SliceSettingsFields.cs b/MatterControl.Printing/Settings/SliceSettingsFields.cs index 311bb7eac..bf070de0a 100644 --- a/MatterControl.Printing/Settings/SliceSettingsFields.cs +++ b/MatterControl.Printing/Settings/SliceSettingsFields.cs @@ -721,7 +721,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DataEditType = DataEditTypes.CHECK_BOX, ShowAsOverride = true, ShowIfSet = "!sla_printer", - ResetAtEndOfPrint = false, DefaultValue = "0", ReloadUiWhenChanged = true, RebuildGCodeOnChange = false @@ -734,7 +733,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DataEditType = DataEditTypes.CHECK_BOX, ShowAsOverride = true, ShowIfSet = "!sla_printer", - ResetAtEndOfPrint = false, DefaultValue = "0", ReloadUiWhenChanged = true, RebuildGCodeOnChange = false @@ -747,7 +745,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DataEditType = DataEditTypes.CHECK_BOX, ShowAsOverride = true, ShowIfSet = "has_z_probe", - ResetAtEndOfPrint = false, DefaultValue = "0", ReloadUiWhenChanged = true, RebuildGCodeOnChange = false @@ -955,7 +952,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DataEditType = DataEditTypes.CHECK_BOX, ShowAsOverride = true, ShowIfSet = "!sla_printer", - ResetAtEndOfPrint = false, DefaultValue = "0", RebuildGCodeOnChange = false }, @@ -967,7 +963,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DataEditType = DataEditTypes.CHECK_BOX, ShowAsOverride = true, ShowIfSet = "!sla_printer&filament_runout_sonsor", - ResetAtEndOfPrint = false, + DefaultValue = "0", RebuildGCodeOnChange = false }, @@ -1030,12 +1026,22 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DataEditType = DataEditTypes.CHECK_BOX, ShowAsOverride = true, ShowIfSet = "!has_hardware_leveling&has_z_probe", - ResetAtEndOfPrint = false, RebuildGCodeOnChange = false, ReloadUiWhenChanged = true, DefaultValue = "0" }, new SliceSettingData() + { + SlicerConfigName = SettingsKey.validate_leveling, + PresentationName = "Validate Calibration Before Printing".Localize(), + HelpText = "Enable this if your printer has an automatic Z Probe and you want to validate the leveling before every print.".Localize(), + DataEditType = DataEditTypes.CHECK_BOX, + ShowAsOverride = true, + ShowIfSet = "!has_hardware_leveling&has_z_probe&use_z_probe", + RebuildGCodeOnChange = false, + DefaultValue = "0" + }, + new SliceSettingData() { SlicerConfigName = SettingsKey.probe_offset, PresentationName = "Probe Offset".Localize(), @@ -1044,7 +1050,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Units = "mm".Localize(), ShowAsOverride = true, ShowIfSet = "!sla_printer&!has_hardware_leveling&has_z_probe&use_z_probe", - ResetAtEndOfPrint = false, RebuildGCodeOnChange = false, DefaultValue = "0,0,0" }, @@ -1057,7 +1062,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Units = "", ShowAsOverride = true, ShowIfSet = "!has_hardware_leveling&has_z_probe&use_z_probe", - ResetAtEndOfPrint = false, RebuildGCodeOnChange = false, DefaultValue = "1" }, @@ -1070,7 +1074,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Units = "°".Localize(), ShowAsOverride = true, ShowIfSet = "!has_hardware_leveling&has_z_probe&use_z_probe&has_z_servo", - ResetAtEndOfPrint = false, RebuildGCodeOnChange = false, DefaultValue = "0" }, @@ -1083,7 +1086,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Units = "°".Localize(), ShowAsOverride = true, ShowIfSet = "!has_hardware_leveling&has_z_probe&use_z_probe&has_z_servo", - ResetAtEndOfPrint = false, RebuildGCodeOnChange = false, DefaultValue = "0" }, @@ -1751,7 +1753,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Units = "", ShowAsOverride = true, ShowIfSet = null, - ResetAtEndOfPrint = false, DefaultValue = "" }, new SliceSettingData() @@ -1763,7 +1764,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Units = "", ShowAsOverride = true, ShowIfSet = null, - ResetAtEndOfPrint = false, DefaultValue = "" }, new SliceSettingData() @@ -2207,7 +2207,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration DataEditType = DataEditTypes.INT, ShowAsOverride = false, ShowIfSet = null, - ResetAtEndOfPrint = false, DefaultValue = "250000", RebuildGCodeOnChange = false }, diff --git a/MatterControlLib/ConfigurationPage/PrintLeveling/LevelingValidation.cs b/MatterControlLib/ConfigurationPage/PrintLeveling/LevelingValidation.cs index d08176ef4..d0a62ee6b 100644 --- a/MatterControlLib/ConfigurationPage/PrintLeveling/LevelingValidation.cs +++ b/MatterControlLib/ConfigurationPage/PrintLeveling/LevelingValidation.cs @@ -54,6 +54,14 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling var enabled = printer.Settings.GetValue(SettingsKey.print_leveling_enabled); + if (enabled + && printer.Settings.GetValue(SettingsKey.has_z_probe) + && printer.Settings.GetValue(SettingsKey.use_z_probe) + && printer.Settings.GetValue(SettingsKey.validate_leveling)) + { + return false; + } + // check if leveling is turned on if (required && !enabled) { diff --git a/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/PrintLevelingWizard.cs b/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/PrintLevelingWizard.cs index 907329cdd..6d3ba6202 100644 --- a/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/PrintLevelingWizard.cs +++ b/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/PrintLevelingWizard.cs @@ -59,11 +59,11 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling public LevelingPlan LevelingPlan { get; set; } - public override bool Visible => true; + public override bool Visible => !printer.Settings.Helpers.HasProbeWithLevelingValidation; public override string HelpText => hasHardwareLeveling ? "Unable due to hardware leveling".Localize() : null; - public override bool Enabled => !hasHardwareLeveling; + public override bool Enabled => !hasHardwareLeveling && Visible; public override bool Completed => !hasHardwareLeveling && !LevelingValidation.NeedsToBeRun(printer); diff --git a/MatterControlLib/PrinterCommunication/Io/ValidatePrintLevelingStream.cs b/MatterControlLib/PrinterCommunication/Io/ValidatePrintLevelingStream.cs index 8bed5259e..3cf457d97 100644 --- a/MatterControlLib/PrinterCommunication/Io/ValidatePrintLevelingStream.cs +++ b/MatterControlLib/PrinterCommunication/Io/ValidatePrintLevelingStream.cs @@ -51,48 +51,81 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io private List sampledPositions; private bool validationHasBeenRun; private bool validationRunning; - private bool waitingForG30Result; + private bool waitingToCompleteNextSample; + private string moveAfterLevel; public ValidatePrintLevelingStream(PrinterConfig printer, GCodeStream internalStream) : base(printer, internalStream) { + printer.Connection.PrintCanceled += Connection_PrintCanceled; } - public static string BeginString => "; VALIDATE_LEVELING"; + private void Connection_PrintCanceled(object sender, EventArgs e) + { + ShutdownProbing(); + } public override string DebugInfo => ""; public override void Dispose() { - printer.Connection.LineReceived -= GetZProbeHeight; - - if (validationRunning || validationHasBeenRun) - { - // If leveling was on when we started, make sure it is on when we are done. - printer.Connection.AllowLeveling = true; - - // set the baby stepping back to the last known good value - printer.Settings.ForTools(SettingsKey.baby_step_z_offset, (key, value, i) => - { - printer.Settings.SetValue(key, babySteppingValue[i].ToString()); - }); - - // make sure we raise the probe on close - if (printer.Settings.GetValue(SettingsKey.has_z_probe) - && printer.Settings.GetValue(SettingsKey.use_z_probe) - && printer.Settings.GetValue(SettingsKey.has_z_servo)) - { - // make sure the servo is retracted - var servoRetract = printer.Settings.GetValue(SettingsKey.z_servo_retracted_angle); - queuedCommands.Enqueue($"M280 P0 S{servoRetract}"); - } - } + ShutdownProbing(); + printer.Connection.PrintCanceled -= Connection_PrintCanceled; base.Dispose(); } + private void ShutdownProbing() + { + if (validationRunning) + { + validationRunning = false; + validationHasBeenRun = true; + + if (!string.IsNullOrEmpty(moveAfterLevel)) + { + queuedCommands.Enqueue(moveAfterLevel); + } + + printer.Connection.LineReceived -= GetZProbeHeight; + + if (validationRunning || validationHasBeenRun) + { + // If leveling was on when we started, make sure it is on when we are done. + printer.Connection.AllowLeveling = true; + + // set the baby stepping back to the last known good value + printer.Settings.ForTools(SettingsKey.baby_step_z_offset, (key, value, i) => + { + printer.Settings.SetValue(key, babySteppingValue[i].ToString()); + }); + + // make sure we raise the probe on close + if (printer.Settings.GetValue(SettingsKey.has_z_probe) + && printer.Settings.GetValue(SettingsKey.use_z_probe) + && printer.Settings.GetValue(SettingsKey.has_z_servo)) + { + // make sure the servo is retracted + var servoRetract = printer.Settings.GetValue(SettingsKey.z_servo_retracted_angle); + queuedCommands.Enqueue($"M280 P0 S{servoRetract}"); + } + } + } + } + public override string ReadLine() { + if (queuedCommands.Count > 0) + { + return queuedCommands.Dequeue(); + } + + if (validationRunning + && !validationHasBeenRun) + { + SampleProbePoints(); + } + string lineToSend = base.ReadLine(); if (lineToSend != null @@ -101,32 +134,39 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io return lineToSend; } - if (queuedCommands.Count > 0) - { - return queuedCommands.Dequeue(); - } - if (lineToSend == "; Software Leveling Applied") { gcodeAlreadyLeveled = true; } - if (validationRunning) - { - SampleProbePoints(); - } - if (lineToSend != null && !gcodeAlreadyLeveled && printer.Connection.IsConnected - && printer.Connection.CurrentlyPrintingLayer == 0 - && !validationHasBeenRun) + && printer.Connection.CurrentlyPrintingLayer <= 0 + && !validationHasBeenRun + && printer.Settings.GetValue(SettingsKey.validate_leveling)) { - if (lineToSend == BeginString) + // we are setting the bed temp + if (lineToSend.Contains("M190")) { SetupForValidation(); + // still set the bed temp and wait return lineToSend; } + + if (LineIsMovement(lineToSend)) + { + var destination = GetPosition(lineToSend, PrinterMove.Unknown); + // double startProbeHeight = printer.Settings.GetValue(SettingsKey.print_leveling_probe_start); + if (destination.position.Z < printer.Settings.GetValue(SettingsKey.print_leveling_probe_start)) + { + SetupForValidation(); + // remember the move + moveAfterLevel = lineToSend; + // and send nothing until leveling done + return ""; + } + } } return lineToSend; @@ -172,7 +212,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io sampledPositions[activeProbeIndex].Position.Z = Math.Round(samplesForSinglePosition.Average(), 2); // When probe data has been collected, resume our thread to continue collecting - waitingForG30Result = false; + waitingToCompleteNextSample = false; // and go on to the next point activeProbeIndex++; } @@ -190,7 +230,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io private void SampleProbePoints() { - if (waitingForG30Result) + if (waitingToCompleteNextSample) { return; } @@ -202,15 +242,43 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io var validProbePosition2D = PrintLevelingWizard.EnsureInPrintBounds(printer, positionsToSample[activeProbeIndex]); positionToSample = new Vector3(validProbePosition2D, startProbeHeight); - this.StartSampling(); - waitingForG30Result = true; + this.SampleNextPoint(); } else { - validationHasBeenRun = true; + SaveSamplePoints(); + ShutdownProbing(); } } + private void SaveSamplePoints() + { + PrintLevelingData levelingData = printer.Settings.Helpers.PrintLevelingData; + levelingData.SampledPositions.Clear(); + + for (int i = 0; i < sampledPositions.Count; i++) + { + levelingData.SampledPositions.Add(sampledPositions[i].Position); + } + + levelingData.LevelingSystem = printer.Settings.GetValue(SettingsKey.print_leveling_solution); + levelingData.CreationDate = DateTime.Now; + // record the temp the bed was when we measured it (or 0 if no heated bed) + levelingData.BedTemperature = printer.Settings.GetValue(SettingsKey.has_heated_bed) ? + printer.Settings.GetValue(SettingsKey.bed_temperature) + : 0; + levelingData.IssuedLevelingTempWarning = false; + + // Invoke setter forcing persistence of leveling data + printer.Settings.Helpers.PrintLevelingData = levelingData; + printer.Settings.ForTools(SettingsKey.baby_step_z_offset, (key, value, i) => + { + printer.Settings.SetValue(key, "0"); + }); + printer.Connection.AllowLeveling = true; + printer.Settings.Helpers.DoPrintLeveling(true); + } + private void SetupForValidation() { validationRunning = true; @@ -280,8 +348,10 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io positionsToSample = levelingPlan.GetPrintLevelPositionToSample().ToList(); } - private void StartSampling() + private void SampleNextPoint() { + waitingToCompleteNextSample = true; + samplesForSinglePosition.Clear(); if (printer.Settings.GetValue(SettingsKey.has_z_servo)) diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index 81f47879d..7ea195631 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -2403,10 +2403,11 @@ Make sure that your printer is turned on. Some printers will appear to be connec bool enableLineSplitting = gcodeStream != null && Printer.Settings.GetValue(SettingsKey.enable_line_splitting); accumulatedStream = maxLengthStream = new MaxLengthStream(Printer, accumulatedStream, enableLineSplitting ? 1 : 2000); - if (!LevelingValidation.NeedsToBeRun(Printer)) + var hasProbeWithLevelingValidation = Printer.Settings.Helpers.HasProbeWithLevelingValidation; + if (!LevelingValidation.NeedsToBeRun(Printer) + || hasProbeWithLevelingValidation) { - if (Printer.Settings.Helpers.UseZProbe() - && Printer.Settings.GetValue(SettingsKey.start_gcode).Contains(ValidatePrintLevelingStream.BeginString)) + if (hasProbeWithLevelingValidation) { accumulatedStream = new ValidatePrintLevelingStream(Printer, accumulatedStream); } diff --git a/MatterControlLib/PrinterControls/ControlWidgets/PrinterCalibrationWizard.cs b/MatterControlLib/PrinterControls/ControlWidgets/PrinterCalibrationWizard.cs index b888020c5..fe90057c1 100644 --- a/MatterControlLib/PrinterControls/ControlWidgets/PrinterCalibrationWizard.cs +++ b/MatterControlLib/PrinterControls/ControlWidgets/PrinterCalibrationWizard.cs @@ -27,6 +27,9 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using System; +using System.Collections.Generic; +using System.Linq; using MatterHackers.Agg; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; @@ -37,9 +40,6 @@ using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.PrinterControls; using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.VectorMath; -using System; -using System.Collections.Generic; -using System.Linq; namespace MatterHackers.MatterControl { diff --git a/MatterControlLib/SetupWizard/WizardStageRow.cs b/MatterControlLib/SetupWizard/WizardStageRow.cs index 46aa49f9d..0e46bb308 100644 --- a/MatterControlLib/SetupWizard/WizardStageRow.cs +++ b/MatterControlLib/SetupWizard/WizardStageRow.cs @@ -73,7 +73,7 @@ namespace MatterHackers.MatterControl public override Color BackgroundColor { - get => (Active) ? theme.AccentMimimalOverlay : base.BackgroundColor; + get => Active ? theme.AccentMimimalOverlay : base.BackgroundColor; set => base.BackgroundColor = value; } diff --git a/StaticData/SliceSettings/Layouts.txt b/StaticData/SliceSettings/Layouts.txt index f65ed2564..27c86f9e6 100644 --- a/StaticData/SliceSettings/Layouts.txt +++ b/StaticData/SliceSettings/Layouts.txt @@ -153,6 +153,7 @@ Printer Probe print_leveling_probe_start use_z_probe + validate_leveling z_probe_samples probe_offset z_servo_depolyed_angle