diff --git a/MatterControl.Printing/Settings/SettingsKey.cs b/MatterControl.Printing/Settings/SettingsKey.cs index 9d8d31ac0..4c10af4b8 100644 --- a/MatterControl.Printing/Settings/SettingsKey.cs +++ b/MatterControl.Printing/Settings/SettingsKey.cs @@ -58,6 +58,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string default_material_presets = nameof(default_material_presets); public const string device_token = nameof(device_token); public const string device_type = nameof(device_type); + public const string emulate_endstops = nameof(emulate_endstops); public const string enable_line_splitting = nameof(enable_line_splitting); public const string enable_network_printing = nameof(enable_network_printing); public const string enable_retractions = nameof(enable_retractions); diff --git a/MatterControl.Printing/Settings/SliceSettingsFields.cs b/MatterControl.Printing/Settings/SliceSettingsFields.cs index 81e8c4b88..69f68b361 100644 --- a/MatterControl.Printing/Settings/SliceSettingsFields.cs +++ b/MatterControl.Printing/Settings/SliceSettingsFields.cs @@ -2048,6 +2048,16 @@ namespace MatterHackers.MatterControl.SlicerConfiguration RebuildGCodeOnChange = false }, new SliceSettingData() + { + SlicerConfigName = SettingsKey.emulate_endstops, + PresentationName = "Emulate Endstops".Localize(), + HelpText = "Make MatterControl emulate bed limits and endstops in software and prevent the printer from moving to invalid locations.".Localize(), + ShowIfSet = "!sla_printer", + DataEditType = DataEditTypes.CHECK_BOX, + DefaultValue = "0", + RebuildGCodeOnChange = false + }, + new SliceSettingData() { SlicerConfigName = SettingsKey.enable_sailfish_communication, PresentationName = "Sailfish Communication".Localize(), diff --git a/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/XyCalibrationWizard.cs b/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/XyCalibrationWizard.cs new file mode 100644 index 000000000..fd47b797b --- /dev/null +++ b/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/XyCalibrationWizard.cs @@ -0,0 +1,86 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.Collections.Generic; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.SlicerConfiguration; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling +{ + public class XyCalibrationWizard : PrinterSetupWizard + { + public XyCalibrationWizard(PrinterConfig printer) + : base(printer) + { + this.WindowTitle = $"{ApplicationController.Instance.ProductName} - " + "Nozzle Calibration Wizard".Localize(); + this.WindowSize = new Vector2(600 * GuiWidget.DeviceScale, 700 * GuiWidget.DeviceScale); + + pages = this.GetPages(); + pages.MoveNext(); + } + + public static bool NeedsToBeRun(PrinterConfig printer) + { + // we have a probe that we are using and we have not done leveling yet + return UsingZProbe(printer) && !printer.Settings.GetValue(SettingsKey.probe_has_been_calibrated); + } + + public override void Dispose() + { + } + + public static bool UsingZProbe(PrinterConfig printer) + { + var required = printer.Settings.GetValue(SettingsKey.print_leveling_required_to_print); + + // we have a probe that we are using and we have not done leveling yet + return (required || printer.Settings.GetValue(SettingsKey.print_leveling_enabled)) + && printer.Settings.GetValue(SettingsKey.has_z_probe) + && printer.Settings.GetValue(SettingsKey.use_z_probe); + } + + private IEnumerator GetPages() + { + var xyCalibrationData = new XyCalibrationData(); + + yield return new XyCalibrationSelectPage(this, printer, xyCalibrationData); + + yield return new XyCalibrationStartPrintPage(this, printer, xyCalibrationData); + } + } + + public class XyCalibrationData + { + public enum QualityType { Coarse, Normal, Fine } + public QualityType Quality { get; set; } = QualityType.Normal; + } +} \ No newline at end of file diff --git a/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs b/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs index 52d984eab..70bf78a9b 100644 --- a/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs +++ b/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs @@ -71,26 +71,6 @@ namespace MatterHackers.MatterControl VAnchor = VAnchor.Center, Margin = new BorderDouble(right: 10) }); - - this.NextButton.Visible = false; - - var nextButton = theme.CreateDialogButton("Finish".Localize()); - nextButton.Name = "FinishCalibration"; - nextButton.Click += (s, e) => - { - // TODO: removed fixed index - var hotendOffset = printer.Settings.Helpers.ExtruderOffset(1); - hotendOffset.X += xOffset; - hotendOffset.Y += yOffset; - - printer.Settings.Helpers.SetExtruderOffset(1, hotendOffset); - - this.DialogWindow.CloseOnIdle(); - }; - - theme.ApplyPrimaryActionStyle(nextButton); - - this.AddPageAction(nextButton); } } } diff --git a/MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs b/MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs new file mode 100644 index 000000000..df6a19ead --- /dev/null +++ b/MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs @@ -0,0 +1,154 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; +using MatterHackers.MatterControl.DesignTools; +using MatterHackers.MatterControl.SlicerConfiguration; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl +{ + public class XyCalibrationSelectPage : WizardPage + { + private RadioButton coarseCalibration; + private RadioButton normalCalibration; + private RadioButton fineCalibration; + + public XyCalibrationSelectPage(ISetupWizard setupWizard, PrinterConfig printer, XyCalibrationData xyCalibrationData) + : base(setupWizard) + { + this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); + this.HeaderText = "Nozzle Offset Calibration".Localize() + ":"; + this.Name = "Nozzle Offset Calibration Wizard"; + + contentRow.Padding = theme.DefaultContainerPadding; + + contentRow.AddChild(new TextWidget("Choose the calibration you would like to perform.".Localize(), textColor: theme.TextColor, pointSize: theme.DefaultFontSize) + { + Margin = new Agg.BorderDouble(0, 15, 0, 0) + }); + + contentRow.AddChild(coarseCalibration = new RadioButton("Coarse Calibration: If your printer is way off".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize) + { + Checked = xyCalibrationData.Quality == XyCalibrationData.QualityType.Coarse + }); + coarseCalibration.CheckedStateChanged += (s, e) => xyCalibrationData.Quality = XyCalibrationData.QualityType.Coarse; + contentRow.AddChild(normalCalibration = new RadioButton("Normal Calibration: Start here".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize) + { + Checked = xyCalibrationData.Quality == XyCalibrationData.QualityType.Normal + }); + normalCalibration.CheckedStateChanged += (s, e) => xyCalibrationData.Quality = XyCalibrationData.QualityType.Normal; + contentRow.AddChild(fineCalibration = new RadioButton("Fine Calibration: When you want that extra precision".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize) + { + Checked = xyCalibrationData.Quality == XyCalibrationData.QualityType.Fine + }); + fineCalibration.CheckedStateChanged += (s, e) => xyCalibrationData.Quality = XyCalibrationData.QualityType.Fine; + } + } + + public class XyCalibrationStartPrintPage : WizardPage + { + public XyCalibrationStartPrintPage(ISetupWizard setupWizard, PrinterConfig printer, XyCalibrationData xyCalibrationData) + : base(setupWizard) + { + this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); + this.HeaderText = "Nozzle Offset Calibration".Localize(); + this.Name = "Nozzle Offset Calibration Wizard"; + + var content = "Here is what we are going to do:".Localize(); + content += "\n\n • " + "Stash your current bed".Localize(); + content += "\n • " + "Print the calibration object".Localize(); + content += "\n • " + "Collect data".Localize(); + content += "\n • " + "Restore your current bed, after all calibration is complete".Localize(); + + contentRow.AddChild(this.CreateTextField(content)); + + contentRow.Padding = theme.DefaultContainerPadding; + + this.NextButton.Visible = false; + + var startCalibrationPrint = theme.CreateDialogButton("Start Print".Localize()); + startCalibrationPrint.Name = "Start Calibration Print"; + startCalibrationPrint.Click += (s, e) => + { + this.DialogWindow.CloseOnIdle(); + // stash the current bed + var scene = printer.Bed.Scene; + scene.Children.Modify((list) => list.Clear()); + IObject3D item = null; + // add the calibration object to the bed + switch(xyCalibrationData.Quality) + { + case XyCalibrationData.QualityType.Coarse: + item = XyCalibrationTabObject3D.Create(1, + Math.Max(printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, printer.Settings.GetValue(SettingsKey.layer_height) * 2), + .5, + printer.Settings.GetValue(SettingsKey.nozzle_diameter)).GetAwaiter().GetResult(); + break; + + case XyCalibrationData.QualityType.Fine: + item = XyCalibrationFaceObject3D.Create(1, + printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, + printer.Settings.GetValue(SettingsKey.layer_height), + .05, + printer.Settings.GetValue(SettingsKey.nozzle_diameter), + printer.Settings.GetValue(SettingsKey.wipe_tower_size), + 8).GetAwaiter().GetResult(); + break; + + default: + item = XyCalibrationFaceObject3D.Create(1, + printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, + printer.Settings.GetValue(SettingsKey.layer_height), + .1, + printer.Settings.GetValue(SettingsKey.nozzle_diameter), + printer.Settings.GetValue(SettingsKey.wipe_tower_size), + 8).GetAwaiter().GetResult(); + break; + } + + // move the part to the center of the bed + var bedBounds = printer.Bed.Bounds; + var aabb = item.GetAxisAlignedBoundingBox(); + item.Matrix *= Matrix4X4.CreateTranslation(bedBounds.Center.X - aabb.MinXYZ.X - aabb.XSize / 2, bedBounds.Center.Y - aabb.MinXYZ.Y - aabb.YSize / 2, -aabb.MinXYZ.Z); + scene.Children.Add(item); + // switch to 3D view + // start the calibration print + }; + + theme.ApplyPrimaryActionStyle(startCalibrationPrint); + + this.AddPageAction(startCalibrationPrint); + } + } +} diff --git a/MatterControlLib/DesignTools/Primitives/XyCalibrationFaceObject3D.cs b/MatterControlLib/DesignTools/Primitives/XyCalibrationFaceObject3D.cs new file mode 100644 index 000000000..33646a5be --- /dev/null +++ b/MatterControlLib/DesignTools/Primitives/XyCalibrationFaceObject3D.cs @@ -0,0 +1,204 @@ +/* +Copyright (c) 2018, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.ComponentModel; +using System.Threading.Tasks; +using MatterHackers.Agg; +using MatterHackers.Agg.VertexSource; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.PolygonMesh; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.DesignTools +{ + public class XyCalibrationFaceObject3D : Object3D + { + public double NozzleWidth = .4; + + public XyCalibrationFaceObject3D() + { + Name = "Calibration Faces".Localize(); + } + + public double BaseHeight { get; set; } = .4; + + [DisplayName("Material")] + public int CalibrationMaterialIndex { get; set; } = 1; + + public override bool CanFlatten => true; + public double ChangingHeight { get; set; } = .4; + public int Layers { get; set; } = 10; + public double Offset { get; set; } = .5; + public double WipeTowerSize { get; set; } = 10; + + private double TabDepth => NozzleWidth * TabScale * 5; + private double TabScale => 3; + private double TabWidth => NozzleWidth * TabScale * 3; + + public static async Task Create(int calibrationMaterialIndex = 1, + double baseHeight = 1, double changingHeight = .2, double offset = .5, double nozzleWidth = .4, double wipeTowerSize = 10, int layers = 8) + { + var item = new XyCalibrationFaceObject3D() + { + WipeTowerSize = wipeTowerSize, + Layers = layers, + CalibrationMaterialIndex = calibrationMaterialIndex, + BaseHeight = baseHeight, + ChangingHeight = changingHeight, + Offset = offset, + NozzleWidth = nozzleWidth + }; + + await item.Rebuild(); + return item; + } + + public override async void OnInvalidate(InvalidateArgs invalidateType) + { + if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties) + && invalidateType.Source == this) + { + await Rebuild(); + } + else + { + base.OnInvalidate(invalidateType); + } + } + + public override Task Rebuild() + { + this.DebugDepth("Rebuild"); + + using (RebuildLock()) + { + using (new CenterAndHeightMantainer(this)) + { + this.Children.Modify((list) => + { + list.Clear(); + }); + + var calibrateX = GetTab(true); + this.Children.Add(calibrateX); + var calibrateY = GetTab(false); + this.Children.Add(calibrateY); + // add in the corner connecter + this.Children.Add(new Object3D() + { + Mesh = PlatonicSolids.CreateCube(), + Matrix = Matrix4X4.CreateTranslation(-1 / 2.0, 1 / 2.0, 1 / 2.0) * Matrix4X4.CreateScale(TabDepth, TabDepth, BaseHeight), + Color = Color.LightBlue + }); + + if (WipeTowerSize > 0) + { + // add in the wipe tower + this.Children.Add(new Object3D() + { + Mesh = PlatonicSolids.CreateCube(), + Matrix = Matrix4X4.CreateTranslation(1 / 2.0, 1 / 2.0, 1 / 2.0) + * Matrix4X4.CreateScale(WipeTowerSize, WipeTowerSize, BaseHeight + Layers * ChangingHeight) + * Matrix4X4.CreateTranslation(TabDepth * 1, TabDepth * 2, 0), + OutputType = PrintOutputTypes.WipeTower + }); + } + } + } + + Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); + return Task.CompletedTask; + } + + private Object3D GetTab(bool calibrateX) + { + var content = new Object3D(); + + var spaceBetween = NozzleWidth * TabScale; + + var shape = new VertexStorage(); + shape.MoveTo(0, 0); + // left + spaces + blocks + right + var baseWidth = (2 * spaceBetween) + (4 * spaceBetween) + (5 * TabWidth) + (2 * spaceBetween); + shape.LineTo(baseWidth, 0); + if (calibrateX) + { + var origin = new Vector2(baseWidth, TabDepth / 2); + var delta = new Vector2(0, -TabDepth / 2); + var count = 15; + for (int i = 0; i < count; i++) + { + delta.Rotate(MathHelper.Tau / 2 / count); + shape.LineTo(origin + delta); + } + } + else + { + shape.LineTo(baseWidth + TabDepth, TabDepth / 2); // a point on the left + } + shape.LineTo(baseWidth, TabDepth); + shape.LineTo(0, TabDepth); + + content.Children.Add(new Object3D() + { + Mesh = shape.Extrude(BaseHeight), + Color = Color.LightBlue + }); + + var position = new Vector2(TabWidth / 2 + 2 * spaceBetween, TabDepth / 2 - Offset * 2); + var step = new Vector2(spaceBetween + TabWidth, Offset); + for (int i = 0; i < 5; i++) + { + for (int j = 0; j < Layers; j++) + { + var calibrationMaterial = (j % 2 == 0); + var cube = PlatonicSolids.CreateCube(); + var yOffset = calibrationMaterial ? position.Y : TabDepth / 2; + var offset = Matrix4X4.CreateTranslation(position.X, yOffset, BaseHeight + .5 * ChangingHeight + j * ChangingHeight); + content.Children.Add(new Object3D() + { + Mesh = cube, + Color = Color.Yellow, + Matrix = Matrix4X4.CreateScale(TabWidth, TabDepth, ChangingHeight) * offset, + MaterialIndex = calibrationMaterial ? CalibrationMaterialIndex : 0 + }); + } + position += step; + } + + if (calibrateX) + { + content.Matrix = Matrix4X4.CreateRotationZ(MathHelper.Tau / 4) * Matrix4X4.CreateTranslation(0, TabDepth, 0); + } + + return content; + } + } +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Primitives/XyCalibrationTabObject3D.cs b/MatterControlLib/DesignTools/Primitives/XyCalibrationTabObject3D.cs index 449e14b32..665298d5a 100644 --- a/MatterControlLib/DesignTools/Primitives/XyCalibrationTabObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/XyCalibrationTabObject3D.cs @@ -40,21 +40,26 @@ namespace MatterHackers.MatterControl.DesignTools { public class XyCalibrationTabObject3D : Object3D { + public double NozzleWidth = .4; + public XyCalibrationTabObject3D() { Name = "Calibration Tab".Localize(); } - public enum Layout { Horizontal, Vertical } - public Layout Direction { get; set; } = Layout.Horizontal; - [DisplayName("Material")] public int CalibrationMaterialIndex { get; set; } = 1; + + public override bool CanFlatten => true; public double ChangeHeight { get; set; } = .4; public double Offset { get; set; } = .5; - public double NozzleWidth = .4; + public double WipeTowerSize { get; set; } = 10; - public static async Task Create(int calibrationMaterialIndex = 1, + private double TabDepth => NozzleWidth * TabScale * 5; + private double TabScale => 3; + private double TabWidth => NozzleWidth * TabScale * 3; + + public static async Task Create(int calibrationMaterialIndex = 1, double changeHeight = .4, double offset = .5, double nozzleWidth = .4) { var item = new XyCalibrationTabObject3D() @@ -95,70 +100,95 @@ namespace MatterHackers.MatterControl.DesignTools list.Clear(); }); - var content = new Object3D(); - - var scale = 3.0; - var width = NozzleWidth * scale * 3; - var depth = NozzleWidth * scale * 5; - var spaceBetween = NozzleWidth * scale; - - var shape = new VertexStorage(); - shape.MoveTo(0, 0); - // left + spaces + blocks + right - var baseWidth = (2 * spaceBetween) + (4 * spaceBetween) + (5 * width) + (2 * spaceBetween); - shape.LineTo(baseWidth, 0); - if (Direction == Layout.Vertical) + var calibrateX = GetTab(true); + this.Children.Add(calibrateX); + var calibrateY = GetTab(false); + this.Children.Add(calibrateY); + // add in the corner connecter + this.Children.Add(new Object3D() { - var origin = new Vector2(baseWidth, depth / 2); - var delta = new Vector2(0, -depth / 2); - var count = 15; - for (int i = 0; i < count; i++) - { - delta.Rotate(MathHelper.Tau / 2 / count); - shape.LineTo(origin + delta); - } - } - else - { - shape.LineTo(baseWidth+depth, depth / 2); // a point on the left - } - shape.LineTo(baseWidth, depth); - shape.LineTo(0, depth); - - var baseMesh = shape.Extrude(ChangeHeight); - content.Children.Add(new Object3D() - { - Mesh = shape.Extrude(ChangeHeight), + Mesh = PlatonicSolids.CreateCube(), + Matrix = Matrix4X4.CreateTranslation(-1 / 2.0, 1 / 2.0, 1 / 2.0) * Matrix4X4.CreateScale(TabDepth, TabDepth, ChangeHeight), Color = Color.LightBlue }); - var position = new Vector2(width / 2 + 2 * spaceBetween, depth / 2 - Offset * 2); - var step = new Vector2(spaceBetween + width, Offset); - for (int i=0; i<5; i++) + if (WipeTowerSize > 0) { - var cube = PlatonicSolids.CreateCube(); - content.Children.Add(new Object3D() + // add in the wipe tower + this.Children.Add(new Object3D() { - Mesh = cube, - Color = Color.Yellow, - Matrix = Matrix4X4.CreateScale(width, depth, ChangeHeight) - * Matrix4X4.CreateTranslation(position.X, position.Y, ChangeHeight * 1.5), - MaterialIndex = CalibrationMaterialIndex + Mesh = PlatonicSolids.CreateCube(), + Matrix = Matrix4X4.CreateTranslation(1 / 2.0, 1 / 2.0, 1 / 2.0) + * Matrix4X4.CreateScale(WipeTowerSize, WipeTowerSize, ChangeHeight * 2) + * Matrix4X4.CreateTranslation(TabDepth * 1, TabDepth * 2, 0), + OutputType = PrintOutputTypes.WipeTower }); - position += step; } - - if (Direction == Layout.Vertical) - { - content.Matrix = Matrix4X4.CreateRotationZ(MathHelper.Tau / 4); - } - - this.Children.Add(content); } } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return Task.CompletedTask; } + + private Object3D GetTab(bool calibrateX) + { + var content = new Object3D(); + + var spaceBetween = NozzleWidth * TabScale; + + var shape = new VertexStorage(); + shape.MoveTo(0, 0); + // left + spaces + blocks + right + var baseWidth = (2 * spaceBetween) + (4 * spaceBetween) + (5 * TabWidth) + (2 * spaceBetween); + shape.LineTo(baseWidth, 0); + if (calibrateX) + { + var origin = new Vector2(baseWidth, TabDepth / 2); + var delta = new Vector2(0, -TabDepth / 2); + var count = 15; + for (int i = 0; i < count; i++) + { + delta.Rotate(MathHelper.Tau / 2 / count); + shape.LineTo(origin + delta); + } + } + else + { + shape.LineTo(baseWidth + TabDepth, TabDepth / 2); // a point on the left + } + shape.LineTo(baseWidth, TabDepth); + shape.LineTo(0, TabDepth); + + content.Children.Add(new Object3D() + { + Mesh = shape.Extrude(ChangeHeight), + Color = Color.LightBlue + }); + + var position = new Vector2(TabWidth / 2 + 2 * spaceBetween, TabDepth / 2 - Offset * 2); + var step = new Vector2(spaceBetween + TabWidth, Offset); + for (int i = 0; i < 5; i++) + { + var cube = PlatonicSolids.CreateCube(); + content.Children.Add(new Object3D() + { + Mesh = cube, + Color = Color.Yellow, + Matrix = Matrix4X4.CreateScale(TabWidth, TabDepth, ChangeHeight) + // translate by 1.5 as it is a centered cube (.5) plus the base (1) = 1.5 + * Matrix4X4.CreateTranslation(position.X, position.Y, ChangeHeight * 1.5), + MaterialIndex = CalibrationMaterialIndex + }); + position += step; + } + + if (calibrateX) + { + content.Matrix = Matrix4X4.CreateRotationZ(MathHelper.Tau / 4) * Matrix4X4.CreateTranslation(0, TabDepth, 0); + } + + return content; + } } } \ No newline at end of file diff --git a/MatterControlLib/Library/Export/GCodeExport.cs b/MatterControlLib/Library/Export/GCodeExport.cs index bdffe3813..37198073c 100644 --- a/MatterControlLib/Library/Export/GCodeExport.cs +++ b/MatterControlLib/Library/Export/GCodeExport.cs @@ -301,6 +301,12 @@ namespace MatterHackers.MatterControl.Library.Export accumulatedStream = new PrintLevelingStream(printer, accumulatedStream, false); } + if (printer.Settings.GetValue(SettingsKey.emulate_endstops)) + { + var softwareEndstopsExStream12 = new SoftwareEndstopsStream(printer, accumulatedStream); + accumulatedStream = softwareEndstopsExStream12; + } + // this is added to ensure we are rewriting the G0 G1 commands as needed accumulatedStream = new ProcessWriteRegexStream(printer, accumulatedStream, queuedCommandStream); diff --git a/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs b/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs index 67028d80e..ce0f16d12 100644 --- a/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs +++ b/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs @@ -56,6 +56,16 @@ namespace MatterHackers.MatterControl.Library () => "Cube".Localize(), async () => await CubeObject3D.Create()) { DateCreated = new System.DateTime(index++) }, +#if DEBUG + new GeneratorItem( + () => "Calibration Tab".Localize(), + async () => await XyCalibrationTabObject3D.Create()) + { DateCreated = new System.DateTime(index++) }, + new GeneratorItem( + () => "Calibration Face".Localize(), + async () => await XyCalibrationFaceObject3D.Create()) + { DateCreated = new System.DateTime(index++) }, +#endif new GeneratorItem( () => "Pyramid".Localize(), async () => await PyramidObject3D.Create()) diff --git a/MatterControlLib/PartPreviewWindow/MainViewWidget.cs b/MatterControlLib/PartPreviewWindow/MainViewWidget.cs index a1dfc523b..ce9338d93 100644 --- a/MatterControlLib/PartPreviewWindow/MainViewWidget.cs +++ b/MatterControlLib/PartPreviewWindow/MainViewWidget.cs @@ -669,6 +669,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow // Add new items foreach (var taskItem in tasks.RunningTasks.Where(t => !displayedTasks.Contains(t))) { + // TODO: find out how we are getting a null task item in the list + if (taskItem == null) + { + continue; + } + var runningTaskPanel = new RunningTaskStatusPanel("", taskItem, theme) { HAnchor = HAnchor.Absolute, diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index ce7d34182..1db36e4b9 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -2247,8 +2247,11 @@ You will then need to logout and log back in to the computer for the changes to accumulatedStream = new FeedRateMultiplyerStream(Printer, accumulatedStream); accumulatedStream = new RequestTemperaturesStream(Printer, accumulatedStream); - var softwareEndstopsExStream12 = new SoftwareEndstopsStream(Printer, accumulatedStream); - accumulatedStream = softwareEndstopsExStream12; + if (Printer.Settings.GetValue(SettingsKey.emulate_endstops)) + { + var softwareEndstopsExStream12 = new SoftwareEndstopsStream(Printer, accumulatedStream); + accumulatedStream = softwareEndstopsExStream12; + } totalGCodeStream = accumulatedStream; diff --git a/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs b/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs index 572cad466..eae110f74 100644 --- a/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs +++ b/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs @@ -146,6 +146,28 @@ namespace MatterHackers.MatterControl.PrinterControls settingsRow.BorderColor = Color.Transparent; settingsRow.AddChild(calibrateButton); + + // in progress new calibration page + this.AddChild(settingsRow = new SettingsRow( + "New Nozzle Offsets".Localize(), + null, + theme, + AggContext.StaticData.LoadIcon("probing_32x32.png", 16, 16, theme.InvertIcons))); + + var xyCalibrateButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) + { + VAnchor = VAnchor.Center, + Margin = theme.ButtonSpacing, + ToolTipText = "Calibrate Nozzle Offsets".Localize() + }; + + xyCalibrateButton.Click += (s, e) => UiThread.RunOnIdle(() => + { + DialogWindow.Show(new XyCalibrationWizard(printer)); + }); + + settingsRow.BorderColor = Color.Transparent; + settingsRow.AddChild(xyCalibrateButton); } } diff --git a/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs b/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs index 41f1eb7a9..0eac776e1 100644 --- a/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs +++ b/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs @@ -73,6 +73,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SettingsKey.com_port, SettingsKey.connect_gcode, SettingsKey.created_date, + SettingsKey.emulate_endstops, SettingsKey.enable_line_splitting, SettingsKey.enable_network_printing, SettingsKey.enable_retractions, diff --git a/StaticData/SliceSettings/Layouts.txt b/StaticData/SliceSettings/Layouts.txt index a7df0bf30..db41d0049 100644 --- a/StaticData/SliceSettings/Layouts.txt +++ b/StaticData/SliceSettings/Layouts.txt @@ -183,6 +183,7 @@ Printer heat_extruder_before_homing auto_release_motors validate_layer_height + emulate_endstops send_with_checksum reset_long_extrusion Slicing Options diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index faf2b6dc7..9d087831b 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit faf2b6dc7a81e0e160413258408ee4df3f34aba8 +Subproject commit 9d087831b8d0bb88acb6c5170dd623f4e503e1fc diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index ac3ff0613..68fbc9038 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit ac3ff0613332fb7d422e4ce90d705a68da3f4d29 +Subproject commit 68fbc9038707549c1d08f7dd24a8b1c34a944cb1