Merge pull request #4294 from larsbrubaker/master

Always do T0 T1 change in streams
This commit is contained in:
Lars Brubaker 2019-02-19 18:13:59 -08:00 committed by GitHub
commit 6aeb7e6b56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 468 additions and 163 deletions

View file

@ -128,7 +128,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
double feedRate = 0;
GCodeFile.GetFirstNumberAfter("F", lineBeingSent, ref feedRate);
StringBuilder newLine = new StringBuilder("G1 ");
var newLine = new StringBuilder("G1");
if (lineBeingSent.Contains("X") || lineBeingSent.Contains("Y") || lineBeingSent.Contains("Z"))
{
@ -136,20 +136,20 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
lastDestinationWithLevelingApplied = outPosition;
newLine = newLine.Append($"X{outPosition.X:0.##} Y{outPosition.Y:0.##} Z{outPosition.Z:0.##} ");
newLine.Append($" X{outPosition.X:0.##} Y{outPosition.Y:0.##} Z{outPosition.Z:0.##}");
}
if (lineBeingSent.Contains("E"))
{
newLine = newLine.Append($"E{extruderDelta:0.###} ");
newLine.Append($" E{extruderDelta:0.###}");
}
if (lineBeingSent.Contains("F"))
{
newLine = newLine.Append($"F{feedRate:0.##}");
newLine.Append($" F{feedRate:0.##}");
}
return newLine.ToString().Trim();
return newLine.ToString();
}
public Vector3 GetPositionWithZOffset(Vector3 currentDestination)

View file

@ -39,8 +39,6 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
public class CalibrateProbeLastPageInstructions : WizardPage
{
private bool pageWasActive = false;
public CalibrateProbeLastPageInstructions(ISetupWizard setupWizard, string headerText)
: base(setupWizard, headerText, "")
{
@ -66,23 +64,24 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
printer.Connection.QueueLine("T0");
printer.Connection.MoveRelative(PrinterConnection.Axis.X, .1, printer.Connection.CurrentFeedRate);
if (printer.Settings.GetValue<bool>(SettingsKey.z_homes_to_max))
{
printer.Connection.HomeAxis(PrinterConnection.Axis.XYZ);
}
pageWasActive = true;
else if (!printer.Settings.GetValue<bool>(SettingsKey.has_z_probe))
{
// Lift the hotend off the bed - at the conclusion of the wizard, make sure we lift the heated nozzle off the bed
printer.Connection.MoveRelative(PrinterConnection.Axis.Z, 2, printer.Settings.Helpers.ManualMovementSpeeds().Z);
}
base.OnLoad(args);
}
public override void OnClosed(EventArgs e)
{
if (pageWasActive)
{
// move from this wizard to the print leveling wizard if needed
ApplicationController.Instance.RunAnyRequiredPrinterSetup(printer, theme);
}
// move from this wizard to the print leveling wizard if needed
ApplicationController.Instance.RunAnyRequiredPrinterSetup(printer, theme);
}
}
}

View file

@ -97,14 +97,21 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
printer.Connection.HomeAxis(PrinterConnection.Axis.XYZ);
}
Closed += (s, e) =>
else if (!printer.Settings.GetValue<bool>(SettingsKey.has_z_probe))
{
// give instruction about how to load filament if the user has not gotten them
ApplicationController.Instance.RunAnyRequiredPrinterSetup(printer, theme);
};
// Lift the hotend off the bed - at the conclusion of the wizard, make sure we lift the heated nozzle off the bed
printer.Connection.MoveRelative(PrinterConnection.Axis.Z, 2, printer.Settings.Helpers.ManualMovementSpeeds().Z);
}
base.OnLoad(args);
}
public override void OnClosed(EventArgs e)
{
// give instruction about how to load filament if the user has not gotten them
ApplicationController.Instance.RunAnyRequiredPrinterSetup(printer, theme);
base.OnClosed(e);
}
}
}

View file

@ -131,7 +131,7 @@ namespace MatterHackers.MatterControl.DesignTools
}
}
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
}
}
}

View file

@ -261,7 +261,7 @@ namespace MatterHackers.MatterControl.DesignTools
}
}
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
}
}

View file

@ -65,7 +65,7 @@ namespace MatterHackers.MatterControl.Plugins.Lithophane
public Vector3 ImageOffset { get; private set; } = Vector3.Zero;
public override void OnInvalidate(InvalidateArgs invalidateArgs)
public override async void OnInvalidate(InvalidateArgs invalidateArgs)
{
var invalidateType = invalidateArgs.InvalidateType;
if ((invalidateType.HasFlag(InvalidateType.Children)
@ -74,12 +74,12 @@ namespace MatterHackers.MatterControl.Plugins.Lithophane
&& invalidateArgs.Source != this
&& !RebuildLocked)
{
Rebuild();
await Rebuild();
}
else if (invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties)
&& invalidateArgs.Source == this)
{
Rebuild();
await Rebuild();
}
else
{
@ -114,7 +114,7 @@ namespace MatterHackers.MatterControl.Plugins.Lithophane
// Apply offset
this.Matrix *= Matrix4X4.CreateTranslation(-this.ImageOffset);
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});

View file

@ -96,7 +96,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -274,7 +274,7 @@ namespace MatterHackers.MatterControl.DesignTools
Matrix = currentMatrix;
}
Invalidate(InvalidateType.Mesh);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
if (valuesChanged)
{
Invalidate(InvalidateType.DisplayValues);

View file

@ -103,7 +103,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
list.AddRange(ScaleItem.Children);
});
}
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
}
public override void Remove(UndoBuffer undoBuffer)
@ -124,7 +124,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
});
}
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
}
public override void OnInvalidate(InvalidateArgs invalidateType)
@ -178,7 +178,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}

View file

@ -90,7 +90,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -93,12 +93,12 @@ namespace MatterHackers.MatterControl.DesignTools
this.Matrix = oldMatrix;
}
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
}
public override void OnInvalidate(InvalidateArgs invalidateType)
public override async void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Children)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
@ -106,12 +106,12 @@ namespace MatterHackers.MatterControl.DesignTools
&& invalidateType.Source != this
&& !RebuildLocked)
{
Rebuild();
await Rebuild();
}
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
&& invalidateType.Source == this)
{
Rebuild();
await Rebuild();
}
else
{

View file

@ -56,7 +56,7 @@ namespace MatterHackers.MatterControl.DesignTools
[DisplayName("Back Ratio")]
public double PinchRatio { get; set; } = .5;
public override void OnInvalidate(InvalidateArgs invalidateType)
public override async void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Children)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
@ -64,12 +64,12 @@ namespace MatterHackers.MatterControl.DesignTools
&& invalidateType.Source != this
&& !RebuildLocked)
{
Rebuild();
await Rebuild();
}
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
&& invalidateType.Source == this)
{
Rebuild();
await Rebuild();
}
else
{
@ -125,7 +125,7 @@ namespace MatterHackers.MatterControl.DesignTools
Matrix = currentMatrix;
}
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
}
}

View file

@ -93,7 +93,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}

View file

@ -420,7 +420,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}));
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}

View file

@ -100,7 +100,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
});
SourceContainer.Visible = false;
rebuildLock.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -86,7 +86,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
SourceContainer.Visible = false;
rebuildLock.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -128,7 +128,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
});
SourceContainer.Visible = false;
rebuildLock.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -185,7 +185,7 @@ namespace MatterHackers.MatterControl.DesignTools
SourceContainer.Visible = false;
rebuildLocks.Dispose();
}
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
}
return Task.CompletedTask;

View file

@ -233,7 +233,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}

View file

@ -191,7 +191,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}

View file

@ -127,7 +127,7 @@ namespace MatterHackers.MatterControl.DesignTools
}
rebuildLock.Dispose();
Invalidate(InvalidateType.Mesh);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
return Task.CompletedTask;
});
}

View file

@ -106,7 +106,7 @@ namespace MatterHackers.MatterControl.DesignTools
this.Matrix = oldMatrix;
SourceContainer.Visible = false;
rebuildLock.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -32,7 +32,6 @@ using ClipperLib;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools.Operations;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
@ -58,7 +57,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
[Description("Change the width of the image lines.")]
public double Inflate { get; set; }
public override void OnInvalidate(InvalidateArgs invalidateType)
public override async void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Children)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
@ -66,12 +65,12 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
&& invalidateType.Source != this
&& !RebuildLocked)
{
Rebuild();
await Rebuild();
}
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
&& invalidateType.Source == this)
{
Rebuild();
await Rebuild();
}
else
{
@ -87,7 +86,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
InsetPath();
}
Invalidate(InvalidateType.Path);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Path));
return Task.CompletedTask;
}

View file

@ -92,7 +92,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
DoSmoothing((long)(SmoothDistance * 1000), Iterations);
rebuildLock.Dispose();
Invalidate(InvalidateType.Path);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Path));
return Task.CompletedTask;
});
}

View file

@ -137,7 +137,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
ItemWithTransform.Matrix = RotationMatrix;
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}

View file

@ -218,7 +218,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
ItemWithTransform.Matrix *= Matrix4X4.CreateTranslation(ScaleAbout);
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}

View file

@ -76,7 +76,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
#endregion // editable properties
public override void OnInvalidate(InvalidateArgs invalidateType)
public override async void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Children)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
@ -84,12 +84,12 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
&& invalidateType.Source != this
&& !RebuildLocked)
{
Rebuild();
await Rebuild();
}
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
&& invalidateType.Source == this)
{
Rebuild();
await Rebuild();
}
else
{
@ -107,7 +107,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
ItemWithTransform.Matrix = Matrix4X4.CreateTranslation(Translation);
}
Invalidate(InvalidateType.Matrix);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
return Task.CompletedTask;
}
}

View file

@ -101,7 +101,7 @@ namespace MatterHackers.MatterControl.DesignTools
}
// send the invalidate on image change
Invalidate(InvalidateType.Image);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Image));
}
return _image;

View file

@ -287,6 +287,11 @@ namespace MatterHackers.MatterControl.Library.Export
var queueStream = new QueuedCommandsStream(printer, gCodeBaseStream);
GCodeStream accumulatedStream = queueStream;
if (printer.Settings.GetValue<int>(SettingsKey.extruder_count) > 1)
{
accumulatedStream = new ToolChangeStream(printer, accumulatedStream);
}
accumulatedStream = new RelativeToAbsoluteStream(printer, accumulatedStream);
bool levelingEnabled = printer.Settings.GetValue<bool>(SettingsKey.print_leveling_enabled) && applyLeveling;

View file

@ -69,7 +69,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -70,7 +70,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -178,7 +178,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -131,7 +131,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -99,7 +99,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -137,7 +137,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
rebuildLocks.Dispose();
Invalidate(InvalidateType.Children);
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
return Task.CompletedTask;
});
}

View file

@ -27,18 +27,10 @@ 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.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using MatterControl.Printing;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.PrinterControls;
using MatterHackers.MatterControl.SlicerConfiguration;
namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
@ -46,15 +38,11 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
private List<string> commandQueue = new List<string>();
private object locker = new object();
private int requestedExtruder;
private int extruderLastSwitchedTo;
PrinterMove lastDestination = PrinterMove.Unknown;
int extruderCount = 0;
public QueuedCommandsStream(PrinterConfig printer, GCodeStream internalStream)
: base(printer, internalStream)
{
extruderCount = printer.Settings.GetValue<int>(SettingsKey.extruder_count);
}
public int Count => commandQueue.Count;
@ -70,68 +58,11 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
}
else
{
// If we are not printing, check if we need to switch extruders
if (extruderCount > 1
&& !printer.Connection.Printing)
{
CheckIfNeedToSwitchExtruders(line);
}
commandQueue.Add(line);
}
}
}
private void CheckIfNeedToSwitchExtruders(string lineIn)
{
if(lineIn == null)
{
return;
}
var lineNoComment = lineIn.Split(';')[0];
TrackExtruderState(lineNoComment);
if ((lineNoComment.StartsWith("G0 ") || lineNoComment.StartsWith("G1 ")) // is a G1 or G0
&& (lineNoComment.Contains("X") || lineNoComment.Contains("Y") || lineNoComment.Contains("Z")) // hase a move axis in it
&& extruderLastSwitchedTo != requestedExtruder) // is different than the last extruder set
{
string gcodeToQueue = "";
switch (requestedExtruder)
{
case 0:
gcodeToQueue = printer.Settings.GetValue(SettingsKey.before_toolchange_gcode).Replace("\\n", "\n");
break;
case 1:
gcodeToQueue = printer.Settings.GetValue(SettingsKey.before_toolchange_gcode_1).Replace("\\n", "\n");
break;
}
if (gcodeToQueue.Trim().Length > 0)
{
if (gcodeToQueue.Contains("\n"))
{
string[] linesToWrite = gcodeToQueue.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 0; i < linesToWrite.Length; i++)
{
string gcodeLine = linesToWrite[i].Trim();
if (gcodeLine.Length > 0)
{
commandQueue.Add(gcodeLine);
}
}
}
else
{
commandQueue.Add(gcodeToQueue);
}
}
extruderLastSwitchedTo = requestedExtruder;
}
}
public void Cancel()
{
Reset();
@ -187,30 +118,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
lineToSend = base.ReadLine();
}
TrackExtruderState(lineToSend);
return lineToSend;
}
private void TrackExtruderState(string line)
{
if (line == null)
{
return;
}
if (line.StartsWith("G28)"))
{
extruderLastSwitchedTo = 0;
requestedExtruder = 0;
}
if (line.StartsWith("T"))
{
GCodeFile.GetFirstNumberAfter("T", line, ref requestedExtruder);
}
}
public void Reset()
{
lock (locker)

View file

@ -0,0 +1,148 @@
/*
Copyright (c) 2014, Lars Brubaker
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 MatterHackers.Agg;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
public class SoftwareEndstopsStream : GCodeStreamProxy
{
private PrinterMove lastDestination = PrinterMove.Unknown;
AxisAlignedBoundingBox[] extruderBounds = new AxisAlignedBoundingBox[4];
public SoftwareEndstopsStream(PrinterConfig printer, GCodeStream internalStream)
: base(printer, internalStream)
{
CalculateBounds();
printer.Settings.SettingChanged += Settings_SettingChanged;
// Register to listen for position after home and update Bounds based on the axis homed and position info.
}
private void Settings_SettingChanged(object sender, StringEventArgs stringEvent)
{
if (stringEvent.Data == SettingsKey.bed_size
|| stringEvent.Data == SettingsKey.print_center
|| stringEvent.Data == SettingsKey.build_height
|| stringEvent.Data == SettingsKey.bed_shape)
{
this.CalculateBounds();
}
}
public override void Dispose()
{
printer.Settings.SettingChanged -= Settings_SettingChanged;
base.Dispose();
}
private void CalculateBounds()
{
var bedSize = printer.Settings.GetValue<Vector2>(SettingsKey.bed_size);
var printCenter = printer.Settings.GetValue<Vector2>(SettingsKey.print_center);
var buildHeight = printer.Settings.GetValue<double>(SettingsKey.build_height);
if (buildHeight == 0)
{
buildHeight = double.PositiveInfinity;
}
// first set all the extruders to the bounds defined by the settings file
for (int i = 0; i < extruderBounds.Length; i++)
{
extruderBounds[i] = new AxisAlignedBoundingBox(
printCenter.X - bedSize.X / 2, // min x
printCenter.Y - bedSize.Y / 2, // min y
0, // min z
printCenter.X + bedSize.X / 2, // max x
printCenter.Y + bedSize.Y / 2, // max y
buildHeight); // max z
}
// if we have more constrained info for extruders, add that it
// If we know something about the homing positions, add them in.
// Specifically never go above a z homes max endstop.
// We may also want to add in all other know (measured) endstop postions.
}
public override string ReadLine()
{
string lineToSend = base.ReadLine();
if (lineToSend != null
&& lineToSend.EndsWith("; NO_PROCESSING"))
{
return lineToSend;
}
if (lineToSend != null
&& LineIsMovement(lineToSend))
{
PrinterMove currentMove = GetPosition(lineToSend, lastDestination);
PrinterMove moveToSend = currentMove;
if (moveToSend.HaveAnyPosition)
{
ClampToPrinter(ref moveToSend);
lineToSend = CreateMovementLine(moveToSend, lastDestination);
}
lastDestination = currentMove;
return lineToSend;
}
return lineToSend;
}
public override void SetPrinterPosition(PrinterMove position)
{
this.lastDestination.CopyKnowSettings(position);
internalStream.SetPrinterPosition(lastDestination);
}
private void ClampToPrinter(ref PrinterMove moveToSend)
{
var bounds = extruderBounds[printer.Connection.ActiveExtruderIndex];
if (moveToSend.position.X < bounds.MinXYZ.X)
{
moveToSend.position.X = bounds.MinXYZ.X;
// If we clamp, than do not do any extrusion at all
moveToSend.extrusion = 0;
}
}
}
}

View file

@ -0,0 +1,156 @@
/*
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 System.Collections.Generic;
using MatterControl.Printing;
using MatterHackers.MatterControl.SlicerConfiguration;
namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
public class ToolChangeStream : GCodeStreamProxy
{
private Queue<string> commandQueue = new Queue<string>();
private object locker = new object();
private int requestedExtruder;
private int extruderLastSwitchedTo;
PrinterMove lastDestination = PrinterMove.Unknown;
int extruderCount = 0;
public ToolChangeStream(PrinterConfig printer, GCodeStream internalStream)
: base(printer, internalStream)
{
extruderCount = printer.Settings.GetValue<int>(SettingsKey.extruder_count);
}
private bool CheckIfNeedToSwitchExtruders(string lineIn)
{
bool queuedSwitch = false;
if (lineIn == null)
{
return queuedSwitch;
}
var lineNoComment = lineIn.Split(';')[0];
TrackExtruderState(lineNoComment);
if ((lineNoComment.StartsWith("G0 ") || lineNoComment.StartsWith("G1 ")) // is a G1 or G0
&& (lineNoComment.Contains("X") || lineNoComment.Contains("Y") || lineNoComment.Contains("Z")) // hase a move axis in it
&& extruderLastSwitchedTo != requestedExtruder) // is different than the last extruder set
{
string gcodeToQueue = "";
switch (requestedExtruder)
{
case 0:
gcodeToQueue = printer.Settings.GetValue(SettingsKey.before_toolchange_gcode).Replace("\\n", "\n");
break;
case 1:
gcodeToQueue = printer.Settings.GetValue(SettingsKey.before_toolchange_gcode_1).Replace("\\n", "\n");
break;
}
if (gcodeToQueue.Trim().Length > 0)
{
if (gcodeToQueue.Contains("\n"))
{
string[] linesToWrite = gcodeToQueue.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 0; i < linesToWrite.Length; i++)
{
string gcodeLine = linesToWrite[i].Trim();
if (gcodeLine.Length > 0)
{
commandQueue.Enqueue(gcodeLine);
}
}
}
else
{
commandQueue.Enqueue(gcodeToQueue);
}
commandQueue.Enqueue(lineIn);
queuedSwitch = true;
}
extruderLastSwitchedTo = requestedExtruder;
}
return queuedSwitch;
}
public override string ReadLine()
{
string lineToSend = null;
// lock queue
lock (locker)
{
if (commandQueue.Count > 0)
{
lineToSend = commandQueue.Dequeue();
lineToSend = printer.ReplaceMacroValues(lineToSend);
}
}
if (lineToSend == null)
{
lineToSend = base.ReadLine();
}
if(CheckIfNeedToSwitchExtruders(lineToSend))
{
return "";
}
TrackExtruderState(lineToSend);
return lineToSend;
}
private void TrackExtruderState(string line)
{
if (line == null)
{
return;
}
if (line.StartsWith("G28)"))
{
extruderLastSwitchedTo = 0;
requestedExtruder = 0;
}
if (line.StartsWith("T"))
{
GCodeFile.GetFirstNumberAfter("T", line, ref requestedExtruder);
}
}
}
}

View file

@ -195,6 +195,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
private FeedRateMultiplyerStream feedrateMultiplyerStream9 = null;
private RequestTemperaturesStream requestTemperaturesStream10 = null;
private ProcessWriteRegexStream processWriteRegExStream11 = null;
//private SoftwareEndstopsStream softwareEndstopsExStream12 = null;
private GCodeStream totalGCodeStream = null;
@ -2132,7 +2133,15 @@ You will then need to logout and log back in to the computer for the changes to
}
queuedCommandStream3 = new QueuedCommandsStream(Printer, firstStreamToRead);
relativeToAbsoluteStream4 = new RelativeToAbsoluteStream(Printer, queuedCommandStream3);
if (ExtruderCount > 1)
{
var switchExtruderStream = new ToolChangeStream(Printer, queuedCommandStream3);
relativeToAbsoluteStream4 = new RelativeToAbsoluteStream(Printer, switchExtruderStream);
}
else
{
relativeToAbsoluteStream4 = new RelativeToAbsoluteStream(Printer, queuedCommandStream3);
}
bool enableLineSpliting = gcodeFilename != null && Printer.Settings.GetValue<bool>(SettingsKey.enable_line_splitting);
babyStepsStream5 = new BabyStepsStream(Printer, relativeToAbsoluteStream4, enableLineSpliting ? 1 : 2000);
printLevelingStream6 = new PrintLevelingStream(Printer, babyStepsStream5, true);
@ -2141,7 +2150,13 @@ You will then need to logout and log back in to the computer for the changes to
feedrateMultiplyerStream9 = new FeedRateMultiplyerStream(Printer, extrusionMultiplyerStream8);
requestTemperaturesStream10 = new RequestTemperaturesStream(Printer, feedrateMultiplyerStream9);
processWriteRegExStream11 = new ProcessWriteRegexStream(Printer, requestTemperaturesStream10, queuedCommandStream3);
#if true
totalGCodeStream = processWriteRegExStream11;
#else
softwareEndstopsExStream12 = new SoftwareEndstopsStream(Printer, processWriteRegExStream11);
totalGCodeStream = softwareEndstopsExStream12;
#endif
// Force a reset of the printer checksum state (but allow it to be write regexed)
var transformedCommand = processWriteRegExStream11?.ProcessWriteRegEx("M110 N1");

View file

@ -159,9 +159,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
new AsPercentOfReferenceOrDirect(printer, SettingsKey.first_layer_extrusion_width, "firstLayerExtrusionWidth", SettingsKey.nozzle_diameter),
new AsPercentOfReferenceOrDirect(printer, SettingsKey.first_layer_height, "firstLayerThickness", SettingsKey.layer_height),
new GCodeForSlicer(printer, SettingsKey.end_gcode, "endCode"),
new GCodeForSlicer(printer, SettingsKey.before_toolchange_gcode, "beforeToolchangeCode"),
new GCodeForSlicer(printer, SettingsKey.toolchange_gcode, "toolChangeCode"),
new GCodeForSlicer(printer, SettingsKey.before_toolchange_gcode_1, "beforeToolchangeCode1"),
new GCodeForSlicer(printer, SettingsKey.toolchange_gcode_1, "toolChangeCode1"),
new MapFirstValue(printer, SettingsKey.retract_before_travel, "minimumTravelToCauseRetraction"),
new RetractionLength(printer, SettingsKey.retract_length, "retractionOnTravel"),

@ -1 +1 @@
Subproject commit 2572ad0b29d45fb647ef4d0d5d4dcc2e38e308e4
Subproject commit d93dba440e76111af31c3c873a3d5c2bfc8c0d5a

@ -1 +1 @@
Subproject commit d53980a7dc44efd0d3ecad0213caf78a3da5128f
Subproject commit 1e4317a904e923f338dde1600d65bce11bb46b97

View file

@ -559,6 +559,74 @@ namespace MatterControl.Tests.MatterControl
}
}
[Test, Category("GCodeStream"), Ignore("WIP")]
public void SoftwareEndstopstreamTests()
{
string[] inputLines = new string[]
{
// test x min
// move without extrusion
"G1 X100Y100Z0E0", // start at the bed center
"G1 X-100", // move left off the bed
"G1 Y110", // move while outside bounds
"G1 X100", // move back on
// move with extrusion
"G1 X100Y100Z0E0", // start at the bed center
"G1 X-100E10", // move left off the bed
"G1 Y110E20", // move while outside bounds
"G1 X100E30", // move back on
// test x max
// test y min
// test y max
// test z min
// test z max
null,
};
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string[] expected = new string[]
{
// move without extrusion
"G1 X100 Y100 Z0 E0", // strat position
"G1 X0", // clamped x
"", // move while outside
"G1 Y110", // first position back in bounds
"G1 X100", // move to requested x
// move with extrusion
"G1 X100Y100Z0E0", // start at the bed center
"G1 X-100E10", // move left off the bed
"G1 Y110E20", // move while outside bounds
"G1 X100E30", // move back on
null,
};
AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));
var printer = new PrinterConfig(new PrinterSettings());
var pauseHandlingStream = new SoftwareEndstopsStream(printer, new TestGCodeStream(printer, inputLines));
int expectedIndex = 0;
string actualLine = pauseHandlingStream.ReadLine();
string expectedLine = expected[expectedIndex++];
Assert.AreEqual(expectedLine, actualLine, "Unexpected response from PauseHandlingStream");
while (actualLine != null)
{
expectedLine = expected[expectedIndex++];
actualLine = pauseHandlingStream.ReadLine();
Assert.AreEqual(expectedLine, actualLine, "Unexpected response from PauseHandlingStream");
}
}
[Test, Category("GCodeStream")]
public void MorePauseHandlingStreamTests()
{