Wrote Re-Slice for dynamically replacing current gcode
adding comments
This commit is contained in:
parent
193f65948e
commit
c408ef055d
5 changed files with 273 additions and 33 deletions
|
|
@ -942,6 +942,11 @@ namespace MatterControl.Printing
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the height of this layer (from the top of the previous layer to the top of this layer).
|
||||
/// </summary>
|
||||
/// <param name="layerIndex"></param>
|
||||
/// <returns></returns>
|
||||
public override double GetLayerHeight(int layerIndex)
|
||||
{
|
||||
if (layerHeights.Count > 0)
|
||||
|
|
@ -962,6 +967,11 @@ namespace MatterControl.Printing
|
|||
return .5;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the height of the top of this layer as measure from the bed
|
||||
/// </summary>
|
||||
/// <param name="layerIndex"></param>
|
||||
/// <returns></returns>
|
||||
public override double GetLayerTop(int layerIndex)
|
||||
{
|
||||
double total = 0;
|
||||
|
|
@ -972,6 +982,21 @@ namespace MatterControl.Printing
|
|||
return total;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the height of the bottom of this layer as measure from the bed
|
||||
/// </summary>
|
||||
/// <param name="layerIndex"></param>
|
||||
/// <returns></returns>
|
||||
public double GetLayerBottom(int layerIndex)
|
||||
{
|
||||
double total = 0;
|
||||
for (int i = 0; i < layerIndex; i++)
|
||||
{
|
||||
total += GetLayerHeight(i);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public override int GetLayerIndex(int instructionIndex)
|
||||
{
|
||||
if (instructionIndex >= 0
|
||||
|
|
|
|||
|
|
@ -461,11 +461,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
var bodyRow = new GuiWidget()
|
||||
{
|
||||
HAnchor = HAnchor.Fit | HAnchor.Center,
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Top | VAnchor.Fit,
|
||||
//BackgroundColor = new Color(theme.Colors.PrimaryBackgroundColor, 128),
|
||||
MinimumSize = new Vector2(275, 140),
|
||||
Selectable = false
|
||||
};
|
||||
|
||||
// Progress section
|
||||
|
|
@ -477,9 +476,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
var progressContainer = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
||||
{
|
||||
Margin = new BorderDouble(50, 0),
|
||||
VAnchor = VAnchor.Center | VAnchor.Fit,
|
||||
HAnchor = HAnchor.Center | HAnchor.Fit,
|
||||
HAnchor = HAnchor.Stretch,
|
||||
};
|
||||
expandingContainer.AddChild(progressContainer);
|
||||
|
||||
|
|
@ -491,12 +489,88 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
};
|
||||
progressContainer.AddChild(progressDial);
|
||||
|
||||
var bottomRow = new GuiWidget()
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit
|
||||
};
|
||||
progressContainer.AddChild(bottomRow);
|
||||
|
||||
var timeContainer = new FlowLayoutWidget()
|
||||
{
|
||||
HAnchor = HAnchor.Center | HAnchor.Fit,
|
||||
Margin = 3
|
||||
};
|
||||
progressContainer.AddChild(timeContainer);
|
||||
bottomRow.AddChild(timeContainer);
|
||||
|
||||
// we can only reslice on 64 bit, because in 64 bit we always have the gcode loaded
|
||||
if (IntPtr.Size == 8)
|
||||
{
|
||||
var resliceButton = new TextButton("Re-Slice", theme)
|
||||
{
|
||||
HAnchor = HAnchor.Right,
|
||||
VAnchor = VAnchor.Center,
|
||||
Margin = new BorderDouble(0, 0, 7, 0)
|
||||
};
|
||||
bool activelySlicing = false;
|
||||
resliceButton.Click += (s, e) =>
|
||||
{
|
||||
resliceButton.Enabled = false;
|
||||
UiThread.RunOnIdle(async () =>
|
||||
{
|
||||
if (!activelySlicing
|
||||
&& printer.Settings.IsValid()
|
||||
&& printer.Bed.EditContext.SourceItem != null)
|
||||
{
|
||||
activelySlicing = true;
|
||||
if (bottomRow.Name == null)
|
||||
{
|
||||
bottomRow.Name = printer.Bed.EditContext.GCodeFilePath;
|
||||
}
|
||||
await ApplicationController.Instance.Tasks.Execute("Saving".Localize(), printer.Bed.SaveChanges);
|
||||
// start up a new slice on a backgroud thread
|
||||
await ApplicationController.Instance.SliceItemLoadOutput(
|
||||
printer,
|
||||
printer.Bed.Scene,
|
||||
printer.Bed.EditContext.GCodeFilePath);
|
||||
// Switch to the 3D layer view if on Model view
|
||||
if (printer.ViewState.ViewMode == PartViewMode.Model)
|
||||
{
|
||||
printer.ViewState.ViewMode = PartViewMode.Layers3D;
|
||||
}
|
||||
// when it is done queue it to the change to gcode stream
|
||||
var message2 = "Would you like to switch to the new G-Code? Before you switch, check that your are seeing the changes you expect.".Localize();
|
||||
var caption2 = "Switch to new G-Code?".Localize();
|
||||
StyledMessageBox.ShowMessageBox(async (clickedOk2) =>
|
||||
{
|
||||
if (clickedOk2)
|
||||
{
|
||||
if (printer.Connection != null
|
||||
&& (printer.Connection.PrinterIsPrinting || printer.Connection.PrinterIsPaused))
|
||||
{
|
||||
printer.Connection.SwitchToGCode(printer.Bed.EditContext.GCodeFilePath);
|
||||
bottomRow.Name = printer.Bed.EditContext.GCodeFilePath;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ApplicationController.Instance.SliceItemLoadOutput(
|
||||
printer,
|
||||
printer.Bed.Scene,
|
||||
bottomRow.Name);
|
||||
}
|
||||
activelySlicing = false;
|
||||
resliceButton.Enabled = true;
|
||||
}, message2, caption2, StyledMessageBox.MessageType.YES_NO, "Switch".Localize(), "Cancel".Localize());
|
||||
}
|
||||
else
|
||||
{
|
||||
resliceButton.Enabled = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
bottomRow.AddChild(resliceButton);
|
||||
}
|
||||
|
||||
timeContainer.AddChild(new ImageWidget(AggContext.StaticData.LoadIcon("fa-clock_24.png", theme.InvertIcons))
|
||||
{
|
||||
|
|
|
|||
141
MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs
Normal file
141
MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
Copyright (c) 2015, 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 MatterControl.Printing;
|
||||
using MatterHackers.VectorMath;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
||||
{
|
||||
public class GCodeSwitcher : GCodeStream
|
||||
{
|
||||
private GCodeMemoryFile switchToGCode = null;
|
||||
PrinterConnection printerConnection;
|
||||
|
||||
public GCodeSwitcher(string gcodeFilename, PrinterConnection printerConnection, int startLine = 0)
|
||||
{
|
||||
this.printerConnection = printerConnection;
|
||||
var fileStreaming = GCodeFile.Load(gcodeFilename,
|
||||
new Vector4(),
|
||||
new Vector4(),
|
||||
new Vector4(),
|
||||
Vector4.One,
|
||||
CancellationToken.None);
|
||||
|
||||
this.GCodeFile = fileStreaming;
|
||||
LineIndex = startLine;
|
||||
}
|
||||
|
||||
public GCodeFile GCodeFile { get; private set; }
|
||||
public int LineIndex { get; private set; } = -1;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public override string ReadLine()
|
||||
{
|
||||
if (LineIndex < GCodeFile.LineCount)
|
||||
{
|
||||
if (LineIndex > 1
|
||||
&& GCodeFile is GCodeMemoryFile currentMemoryFile)
|
||||
{
|
||||
if (switchToGCode != null)
|
||||
{
|
||||
var prevlayerIndex = currentMemoryFile.GetLayerIndex(LineIndex - 1);
|
||||
var layerIndex = currentMemoryFile.GetLayerIndex(LineIndex);
|
||||
// we only try to switch as we are changing layers
|
||||
if (prevlayerIndex < layerIndex)
|
||||
{
|
||||
var currentBottom = currentMemoryFile.GetLayerBottom(layerIndex);
|
||||
// see if there is a layer height that is compatible in the new gcode
|
||||
for (int i = 0; i < switchToGCode.LayerCount; i++)
|
||||
{
|
||||
// find the first layer in the new code that is greater than or eaqual to our current height
|
||||
var switchBottom = switchToGCode.GetLayerBottom(i);
|
||||
if (switchBottom >= currentBottom)
|
||||
{
|
||||
// is the current gcode the same or bigger than the new gcode
|
||||
if (currentBottom >= switchBottom)
|
||||
{
|
||||
// switch the first time we can
|
||||
GCodeFile = switchToGCode;
|
||||
LineIndex = switchToGCode.GetFirstLayerInstruction(i);
|
||||
printerConnection.QueueLine($"G92 E{switchToGCode.Instruction(LineIndex).EPosition}", true);
|
||||
switchToGCode = null;
|
||||
}
|
||||
else // only switch if we are within one layer height of the new gcode
|
||||
{
|
||||
if(currentBottom - switchBottom < switchToGCode.GetLayerHeight(layerIndex))
|
||||
{
|
||||
GCodeFile = switchToGCode;
|
||||
LineIndex = switchToGCode.GetFirstLayerInstruction(i);
|
||||
printerConnection.QueueLine($"G92 E{switchToGCode.Instruction(LineIndex).EPosition}", true);
|
||||
}
|
||||
}
|
||||
// we are done evaluating after the first found layer
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return GCodeFile.Instruction(LineIndex++).Line;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void SetPrinterPosition(PrinterMove position)
|
||||
{
|
||||
}
|
||||
|
||||
public void SwitchTo(string gcodeFilename)
|
||||
{
|
||||
if (GCodeFile is GCodeMemoryFile)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
var switchToGCode = GCodeFile.Load(gcodeFilename,
|
||||
new Vector4(),
|
||||
new Vector4(),
|
||||
new Vector4(),
|
||||
Vector4.One,
|
||||
CancellationToken.None);
|
||||
|
||||
if (switchToGCode is GCodeMemoryFile memoryFile)
|
||||
{
|
||||
this.switchToGCode = memoryFile;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
|
||||
public class PrintRecoveryStream : GCodeStream
|
||||
{
|
||||
private GCodeFileStream internalStream;
|
||||
private GCodeSwitcher internalStream;
|
||||
private double percentDone;
|
||||
double recoverFeedRate;
|
||||
PrinterMove lastDestination;
|
||||
|
|
@ -48,7 +48,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
public RecoveryState RecoveryState { get; private set; } = RecoveryState.RemoveHeating;
|
||||
private PrinterConfig printer;
|
||||
|
||||
public PrintRecoveryStream(PrinterConfig printer, GCodeFileStream internalStream, double percentDone)
|
||||
public PrintRecoveryStream(PrinterConfig printer, GCodeSwitcher internalStream, double percentDone)
|
||||
{
|
||||
this.printer = printer;
|
||||
this.internalStream = internalStream;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
|
||||
private PrinterMove lastReportedPosition;
|
||||
|
||||
private GCodeFileStream gCodeFileStream0 = null;
|
||||
private GCodeSwitcher gCodeFileSwitcher0 = null;
|
||||
private SendProgressStream sendProgressStream1 = null;
|
||||
private PauseHandlingStream pauseHandlingStream2 = null;
|
||||
private QueuedCommandsStream queuedCommandStream3 = null;
|
||||
|
|
@ -513,6 +513,11 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
}
|
||||
}
|
||||
|
||||
public void SwitchToGCode(string gCodeFilePath)
|
||||
{
|
||||
gCodeFileSwitcher0.SwitchTo(gCodeFilePath);
|
||||
}
|
||||
|
||||
public string ComPort => printer.Settings?.Helpers.ComPort();
|
||||
|
||||
public string DriverType => (this.ComPort == "Emulator") ? "Emulator" : printer.Settings?.GetValue("driver_type");
|
||||
|
|
@ -542,9 +547,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
{
|
||||
get
|
||||
{
|
||||
if (gCodeFileStream0 != null)
|
||||
if (gCodeFileSwitcher0 != null)
|
||||
{
|
||||
return gCodeFileStream0?.GCodeFile?.GetLayerIndex(gCodeFileStream0.LineIndex) ?? -1;
|
||||
return gCodeFileSwitcher0?.GCodeFile?.GetLayerIndex(gCodeFileSwitcher0.LineIndex) ?? -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
|
@ -597,9 +602,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
return 100.0;
|
||||
}
|
||||
else if (NumberOfLinesInCurrentPrint > 0
|
||||
&& gCodeFileStream0?.GCodeFile != null)
|
||||
&& gCodeFileSwitcher0?.GCodeFile != null)
|
||||
{
|
||||
return gCodeFileStream0.GCodeFile.PercentComplete(gCodeFileStream0.LineIndex);
|
||||
return gCodeFileSwitcher0.GCodeFile.PercentComplete(gCodeFileSwitcher0.LineIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -714,12 +719,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
{
|
||||
get
|
||||
{
|
||||
if (gCodeFileStream0?.GCodeFile == null)
|
||||
if (gCodeFileSwitcher0?.GCodeFile == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return gCodeFileStream0.GCodeFile.Ratio0to1IntoContainedLayer(gCodeFileStream0.LineIndex);
|
||||
return gCodeFileSwitcher0.GCodeFile.Ratio0to1IntoContainedLayer(gCodeFileSwitcher0.LineIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -754,22 +759,22 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
}
|
||||
}
|
||||
|
||||
public int TotalLayersInPrint => gCodeFileStream0?.GCodeFile?.LayerCount ?? -1;
|
||||
public int TotalLayersInPrint => gCodeFileSwitcher0?.GCodeFile?.LayerCount ?? -1;
|
||||
|
||||
private int NumberOfLinesInCurrentPrint => gCodeFileStream0?.GCodeFile?.LineCount ?? -1;
|
||||
private int NumberOfLinesInCurrentPrint => gCodeFileSwitcher0?.GCodeFile?.LineCount ?? -1;
|
||||
|
||||
public int TotalSecondsInPrint
|
||||
{
|
||||
get
|
||||
{
|
||||
if (gCodeFileStream0?.GCodeFile?.LineCount > 0)
|
||||
if (gCodeFileSwitcher0?.GCodeFile?.LineCount > 0)
|
||||
{
|
||||
if (this.FeedRateRatio != 0)
|
||||
{
|
||||
return (int)(gCodeFileStream0.GCodeFile.TotalSecondsInPrint / this.FeedRateRatio);
|
||||
return (int)(gCodeFileSwitcher0.GCodeFile.TotalSecondsInPrint / this.FeedRateRatio);
|
||||
}
|
||||
|
||||
return (int)(gCodeFileStream0.GCodeFile.TotalSecondsInPrint);
|
||||
return (int)(gCodeFileSwitcher0.GCodeFile.TotalSecondsInPrint);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -2031,7 +2036,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
|
||||
private void ClearQueuedGCode()
|
||||
{
|
||||
gCodeFileStream0?.GCodeFile?.Clear();
|
||||
gCodeFileSwitcher0?.GCodeFile?.Clear();
|
||||
}
|
||||
|
||||
private void DonePrintingSdFile(object sender, FoundStringEventArgs e)
|
||||
|
|
@ -2096,24 +2101,19 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
GCodeStream firstStreamToRead = null;
|
||||
if (gcodeFilename != null)
|
||||
{
|
||||
gCodeFileStream0 = new GCodeFileStream(GCodeFile.Load(gcodeFilename,
|
||||
new Vector4(),
|
||||
new Vector4(),
|
||||
new Vector4(),
|
||||
Vector4.One,
|
||||
CancellationToken.None));
|
||||
gCodeFileSwitcher0 = new GCodeSwitcher(gcodeFilename, this);
|
||||
|
||||
if (this.RecoveryIsEnabled
|
||||
&& activePrintTask != null) // We are resuming a failed print (do lots of interesting stuff).
|
||||
{
|
||||
sendProgressStream1 = new SendProgressStream(printer, new PrintRecoveryStream(printer, gCodeFileStream0, activePrintTask.PercentDone));
|
||||
sendProgressStream1 = new SendProgressStream(printer, new PrintRecoveryStream(printer, gCodeFileSwitcher0, activePrintTask.PercentDone));
|
||||
// And increment the recovery count
|
||||
activePrintTask.RecoveryCount++;
|
||||
activePrintTask.Commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
sendProgressStream1 = new SendProgressStream(printer, gCodeFileStream0);
|
||||
sendProgressStream1 = new SendProgressStream(printer, gCodeFileSwitcher0);
|
||||
}
|
||||
|
||||
pauseHandlingStream2 = new PauseHandlingStream(printer, sendProgressStream1);
|
||||
|
|
@ -2121,7 +2121,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
}
|
||||
else
|
||||
{
|
||||
gCodeFileStream0 = null;
|
||||
gCodeFileSwitcher0 = null;
|
||||
firstStreamToRead = new NotPrintingStream();
|
||||
}
|
||||
|
||||
|
|
@ -2167,12 +2167,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
double secondsSinceStartedPrint = timeSinceStartedPrint.Elapsed.TotalSeconds;
|
||||
|
||||
if (timeSinceStartedPrint.Elapsed.TotalSeconds > 0
|
||||
&& gCodeFileStream0 != null
|
||||
&& gCodeFileSwitcher0 != null
|
||||
&& (secondsSinceUpdateHistory > secondsSinceStartedPrint
|
||||
|| secondsSinceUpdateHistory + 1 < secondsSinceStartedPrint
|
||||
|| lineSinceUpdateHistory + 20 < gCodeFileStream0.LineIndex))
|
||||
|| lineSinceUpdateHistory + 20 < gCodeFileSwitcher0.LineIndex))
|
||||
{
|
||||
double currentDone = gCodeFileStream0.GCodeFile.PercentComplete(gCodeFileStream0.LineIndex);
|
||||
double currentDone = gCodeFileSwitcher0.GCodeFile.PercentComplete(gCodeFileSwitcher0.LineIndex);
|
||||
// Only update the amount done if it is greater than what is recorded.
|
||||
// We don't want to mess up the resume before we actually resume it.
|
||||
if (activePrintTask != null
|
||||
|
|
@ -2190,7 +2190,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
|
|||
//timer.Restart();
|
||||
}
|
||||
secondsSinceUpdateHistory = secondsSinceStartedPrint;
|
||||
lineSinceUpdateHistory = gCodeFileStream0.LineIndex;
|
||||
lineSinceUpdateHistory = gCodeFileSwitcher0.LineIndex;
|
||||
}
|
||||
|
||||
Thread.Sleep(5);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue