Merge pull request #4362 from larsbrubaker/master

master
This commit is contained in:
johnlewin 2019-03-19 19:45:48 -07:00 committed by GitHub
commit 63652a3a3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 594 additions and 80 deletions

View file

@ -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);

View file

@ -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(),

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View 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);
}
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -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);

View file

@ -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())

View file

@ -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,

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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,

View file

@ -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