commit
63652a3a3e
16 changed files with 594 additions and 80 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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<bool>(SettingsKey.probe_has_been_calibrated);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public static bool UsingZProbe(PrinterConfig printer)
|
||||
{
|
||||
var required = printer.Settings.GetValue<bool>(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<bool>(SettingsKey.print_leveling_enabled))
|
||||
&& printer.Settings.GetValue<bool>(SettingsKey.has_z_probe)
|
||||
&& printer.Settings.GetValue<bool>(SettingsKey.use_z_probe);
|
||||
}
|
||||
|
||||
private IEnumerator<WizardPage> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
154
MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs
Normal file
154
MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs
Normal file
|
|
@ -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<double>(SettingsKey.first_layer_height) * 2, printer.Settings.GetValue<double>(SettingsKey.layer_height) * 2),
|
||||
.5,
|
||||
printer.Settings.GetValue<double>(SettingsKey.nozzle_diameter)).GetAwaiter().GetResult();
|
||||
break;
|
||||
|
||||
case XyCalibrationData.QualityType.Fine:
|
||||
item = XyCalibrationFaceObject3D.Create(1,
|
||||
printer.Settings.GetValue<double>(SettingsKey.first_layer_height) * 2,
|
||||
printer.Settings.GetValue<double>(SettingsKey.layer_height),
|
||||
.05,
|
||||
printer.Settings.GetValue<double>(SettingsKey.nozzle_diameter),
|
||||
printer.Settings.GetValue<double>(SettingsKey.wipe_tower_size),
|
||||
8).GetAwaiter().GetResult();
|
||||
break;
|
||||
|
||||
default:
|
||||
item = XyCalibrationFaceObject3D.Create(1,
|
||||
printer.Settings.GetValue<double>(SettingsKey.first_layer_height) * 2,
|
||||
printer.Settings.GetValue<double>(SettingsKey.layer_height),
|
||||
.1,
|
||||
printer.Settings.GetValue<double>(SettingsKey.nozzle_diameter),
|
||||
printer.Settings.GetValue<double>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<XyCalibrationFaceObject3D> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<XyCalibrationTabObject3D> Create(int calibrationMaterialIndex = 1,
|
||||
private double TabDepth => NozzleWidth * TabScale * 5;
|
||||
private double TabScale => 3;
|
||||
private double TabWidth => NozzleWidth * TabScale * 3;
|
||||
|
||||
public static async Task<XyCalibrationTabObject3D> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -301,6 +301,12 @@ namespace MatterHackers.MatterControl.Library.Export
|
|||
accumulatedStream = new PrintLevelingStream(printer, accumulatedStream, false);
|
||||
}
|
||||
|
||||
if (printer.Settings.GetValue<bool>(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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<bool>(SettingsKey.emulate_endstops))
|
||||
{
|
||||
var softwareEndstopsExStream12 = new SoftwareEndstopsStream(Printer, accumulatedStream);
|
||||
accumulatedStream = softwareEndstopsExStream12;
|
||||
}
|
||||
|
||||
totalGCodeStream = accumulatedStream;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit faf2b6dc7a81e0e160413258408ee4df3f34aba8
|
||||
Subproject commit 9d087831b8d0bb88acb6c5170dd623f4e503e1fc
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit ac3ff0613332fb7d422e4ce90d705a68da3f4d29
|
||||
Subproject commit 68fbc9038707549c1d08f7dd24a8b1c34a944cb1
|
||||
Loading…
Add table
Add a link
Reference in a new issue