diff --git a/MatterControl.OpenGL/GCodeRenderer/GCodeRenderer.cs b/MatterControl.OpenGL/GCodeRenderer/GCodeRenderer.cs
index 1a82b41b0..dffc52fa9 100644
--- a/MatterControl.OpenGL/GCodeRenderer/GCodeRenderer.cs
+++ b/MatterControl.OpenGL/GCodeRenderer/GCodeRenderer.cs
@@ -128,15 +128,15 @@ namespace MatterHackers.GCodeVisualizer
if (Math.Abs(eMovement) > 0)
{
// this is a retraction
- renderFeaturesForLayer.Add(new RenderFeatureRetract(currentInstruction.Position, eMovement, currentInstruction.ToolIndex, currentInstruction.FeedRate));
+ renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, eMovement, currentInstruction.ToolIndex, currentInstruction.FeedRate));
}
if (currentInstruction.Line.StartsWith("G10"))
{
- renderFeaturesForLayer.Add(new RenderFeatureRetract(currentInstruction.Position, -1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
+ renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, -1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
}
else if (currentInstruction.Line.StartsWith("G11"))
{
- renderFeaturesForLayer.Add(new RenderFeatureRetract(currentInstruction.Position, 1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
+ renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, 1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
}
}
else
@@ -148,6 +148,7 @@ namespace MatterHackers.GCodeVisualizer
Color extrusionColor = ExtrusionColors.GetColorForSpeed((float)currentInstruction.FeedRate);
renderFeaturesForLayer.Add(
new RenderFeatureExtrusion(
+ instructionIndex,
previousInstruction.Position,
currentInstruction.Position,
currentInstruction.ToolIndex,
@@ -162,6 +163,7 @@ namespace MatterHackers.GCodeVisualizer
{
renderFeaturesForLayer.Add(
new RenderFeatureTravel(
+ instructionIndex,
previousInstruction.Position,
currentInstruction.Position,
currentInstruction.ToolIndex,
diff --git a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureBase.cs b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureBase.cs
index 763231a48..fc6686dcf 100644
--- a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureBase.cs
+++ b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureBase.cs
@@ -36,6 +36,10 @@ namespace MatterHackers.GCodeVisualizer
{
protected int toolIndex;
+ ///
+ /// The actual gcode line in the sourc gcode file
+ ///
+ public int InstructionIndex { get; private set; }
public static Color HighlightColor { get; set; } = new Color("#D0F476");
public static Color StartColor { get; set; } = Color.Red;
@@ -46,9 +50,10 @@ namespace MatterHackers.GCodeVisualizer
public abstract void CreateRender3DData(VectorPOD colorVertexData, VectorPOD indexData, GCodeRenderInfo renderInfo);
- public RenderFeatureBase(int extruderIndex)
+ public RenderFeatureBase(int instructionIndex, int toolIndex)
{
- this.toolIndex = extruderIndex;
+ this.toolIndex = toolIndex;
+ this.InstructionIndex = instructionIndex;
}
static public void CreateCylinder(VectorPOD colorVertexData, VectorPOD indexData, Vector3 startPos, Vector3 endPos, double radius, int steps, Color color, double layerHeight)
diff --git a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureExtrusion.cs b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureExtrusion.cs
index 02f5148a0..0be7663f5 100644
--- a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureExtrusion.cs
+++ b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureExtrusion.cs
@@ -42,8 +42,8 @@ namespace MatterHackers.GCodeVisualizer
private Color color;
private Color gray;
- public RenderFeatureExtrusion(Vector3 start, Vector3 end, int toolIndex, double travelSpeed, double totalExtrusionMm, double filamentDiameterMm, double layerHeight, Color color, Color gray)
- : base(start, end, toolIndex, travelSpeed)
+ public RenderFeatureExtrusion(int instructionIndex, Vector3 start, Vector3 end, int toolIndex, double travelSpeed, double totalExtrusionMm, double filamentDiameterMm, double layerHeight, Color color, Color gray)
+ : base(instructionIndex, start, end, toolIndex, travelSpeed)
{
this.color = color;
this.gray = gray;
diff --git a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureRetract.cs b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureRetract.cs
index 689ec4d28..0ac0e0e90 100644
--- a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureRetract.cs
+++ b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureRetract.cs
@@ -43,8 +43,8 @@ namespace MatterHackers.GCodeVisualizer
private float mmPerSecond;
private Vector3Float position;
- public RenderFeatureRetract(Vector3 position, double extrusionAmount, int extruderIndex, double mmPerSecond)
- : base(extruderIndex)
+ public RenderFeatureRetract(int instructionIndex, Vector3 position, double extrusionAmount, int extruderIndex, double mmPerSecond)
+ : base(instructionIndex, extruderIndex)
{
this.extrusionAmount = (float)extrusionAmount;
this.mmPerSecond = (float)mmPerSecond;
diff --git a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureTravel.cs b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureTravel.cs
index 764f3ef67..c90587515 100644
--- a/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureTravel.cs
+++ b/MatterControl.OpenGL/GCodeRenderer/RenderFeatures/RenderFeatureTravel.cs
@@ -45,8 +45,8 @@ namespace MatterHackers.GCodeVisualizer
public Vector3Float End => end;
- public RenderFeatureTravel(Vector3 start, Vector3 end, int toolIndex, double travelSpeed)
- : base(toolIndex)
+ public RenderFeatureTravel(int instructionIndex, Vector3 start, Vector3 end, int toolIndex, double travelSpeed)
+ : base(instructionIndex, toolIndex)
{
this.toolIndex = toolIndex;
this.start = new Vector3Float(start);
diff --git a/MatterControl.Printing/GCode/GCodeFile.cs b/MatterControl.Printing/GCode/GCodeFile.cs
index 46b054209..3dc99a948 100644
--- a/MatterControl.Printing/GCode/GCodeFile.cs
+++ b/MatterControl.Printing/GCode/GCodeFile.cs
@@ -185,12 +185,13 @@ namespace MatterControl.Printing
}
else
{
- return new GCodeMemoryFile(fileName,
+ return GCodeMemoryFile.Load(fileName,
maxAccelerationMmPerS2,
maxVelocityMmPerS,
velocitySameAsStopMmPerS,
speedMultiplier,
- cancellationToken);
+ cancellationToken,
+ null);
}
}
diff --git a/MatterControl.Printing/GCode/GCodeMemoryFile.cs b/MatterControl.Printing/GCode/GCodeMemoryFile.cs
index 81e8227cb..def53fbcd 100644
--- a/MatterControl.Printing/GCode/GCodeMemoryFile.cs
+++ b/MatterControl.Printing/GCode/GCodeMemoryFile.cs
@@ -40,79 +40,35 @@ namespace MatterControl.Printing
{
public class GCodeMemoryFile : GCodeFile
{
- private double parsingLastZ;
- private bool gcodeHasExplicitLayerChangeInfo = false;
-
- private double filamentUsedMmCache = 0;
private double diameterOfFilamentUsedMmCache = 0;
-
- private List layerHeights = new List();
- private List toolChanges = new List();
- private List GCodeCommandQueue = new List();
-
+ private double filamentDiameterCache = 0;
+ private double filamentUsedMmCache = 0;
private bool foundFirstLayerMarker;
+ private List GCodeCommandQueue = new List();
+ private bool gcodeHasExplicitLayerChangeInfo = false;
+ private int lastPrintLine;
+ private List layerHeights = new List();
+ private double parsingLastZ;
+ private List toolChanges = new List();
public GCodeMemoryFile(bool gcodeHasExplicitLayerChangeInfo = false)
{
this.gcodeHasExplicitLayerChangeInfo = gcodeHasExplicitLayerChangeInfo;
}
- public GCodeMemoryFile(string pathAndFileName,
- Vector4 maxAccelerationMmPerS2,
- Vector4 maxVelocityMmPerS,
- Vector4 velocitySameAsStopMmPerS,
- Vector4 speedMultiplier,
- CancellationToken cancellationToken, bool gcodeHasExplicitLayerChangeInfo = false)
- {
- this.gcodeHasExplicitLayerChangeInfo = gcodeHasExplicitLayerChangeInfo;
+ public List IndexOfLayerStart { get; private set; } = new List();
- var loadedFile = GCodeMemoryFile.Load(pathAndFileName,
- maxAccelerationMmPerS2,
- maxVelocityMmPerS,
- velocitySameAsStopMmPerS,
- speedMultiplier,
- cancellationToken, null);
- if (loadedFile != null)
- {
- this.IndexOfLayerStart = loadedFile.IndexOfLayerStart;
- this.parsingLastZ = loadedFile.parsingLastZ;
- this.GCodeCommandQueue = loadedFile.GCodeCommandQueue;
- }
- }
-
- public override PrinterMachineInstruction Instruction(int index)
+ public override int LayerCount
{
- return GCodeCommandQueue[index];
+ get { return IndexOfLayerStart.Count; }
}
public override int LineCount => GCodeCommandQueue.Count;
- public override void Clear()
- {
- IndexOfLayerStart.Clear();
- GCodeCommandQueue.Clear();
- }
+ public HashSet Speeds { get; private set; }
public override double TotalSecondsInPrint => Instruction(0).SecondsToEndFromHere;
- public void Add(PrinterMachineInstruction printerMachineInstruction)
- {
- Insert(LineCount, printerMachineInstruction);
- }
-
- public void Insert(int insertIndex, PrinterMachineInstruction printerMachineInstruction)
- {
- for (int i = 0; i < IndexOfLayerStart.Count; i++)
- {
- if (insertIndex < IndexOfLayerStart[i])
- {
- IndexOfLayerStart[i]++;
- }
- }
-
- GCodeCommandQueue.Insert(insertIndex, printerMachineInstruction);
- }
-
public static GCodeMemoryFile Load(Stream fileStream,
Vector4 maxAccelerationMmPerS2,
Vector4 maxVelocityMmPerS,
@@ -170,20 +126,342 @@ namespace MatterControl.Printing
return null;
}
- private static IEnumerable CustomSplit(string newtext, char splitChar)
+ public void Add(PrinterMachineInstruction printerMachineInstruction)
{
- int endOfLastFind = 0;
- int positionOfSplitChar = newtext.IndexOf(splitChar);
- while (positionOfSplitChar != -1)
+ Insert(LineCount, printerMachineInstruction);
+ }
+
+ public override void Clear()
+ {
+ IndexOfLayerStart.Clear();
+ GCodeCommandQueue.Clear();
+ }
+
+ public override RectangleDouble GetBounds()
+ {
+ RectangleDouble bounds = new RectangleDouble(double.MaxValue, double.MaxValue, double.MinValue, double.MinValue);
+ foreach (PrinterMachineInstruction state in GCodeCommandQueue)
{
- string text = newtext.Substring(endOfLastFind, positionOfSplitChar - endOfLastFind).Trim();
- yield return text;
- endOfLastFind = positionOfSplitChar + 1;
- positionOfSplitChar = newtext.IndexOf(splitChar, endOfLastFind);
+ bounds.Left = Math.Min(state.Position.X, bounds.Left);
+ bounds.Right = Math.Max(state.Position.X, bounds.Right);
+ bounds.Bottom = Math.Min(state.Position.Y, bounds.Bottom);
+ bounds.Top = Math.Max(state.Position.Y, bounds.Top);
}
- string lastText = newtext.Substring(endOfLastFind);
- yield return lastText;
+ return bounds;
+ }
+
+ public override double GetFilamentCubicMm(double filamentDiameterMm)
+ {
+ double filamentUsedMm = GetFilamentUsedMm(filamentDiameterMm);
+ double filamentRadius = filamentDiameterMm / 2;
+ double areaSquareMm = (filamentRadius * filamentRadius) * Math.PI;
+
+ return areaSquareMm * filamentUsedMm;
+ }
+
+ public override double GetFilamentDiameter()
+ {
+ if (filamentDiameterCache == 0)
+ {
+ // check the beginning of the file for the filament diameter
+ for (int i = 0; i < Math.Min(100, GCodeCommandQueue.Count); i++)
+ {
+ if (FindDiameter(i, ref filamentDiameterCache))
+ {
+ break;
+ }
+ }
+
+ // check the end of the file for the filament diameter
+ if (filamentDiameterCache == 0)
+ {
+ // didn't find it, so look at the end of the file for filament_diameter =
+ for (int i = GCodeCommandQueue.Count - 1; i > Math.Max(0, GCodeCommandQueue.Count - 100); i--)
+ {
+ if (FindDiameter(i, ref filamentDiameterCache))
+ {
+ break;
+ }
+ }
+ }
+
+ if (filamentDiameterCache == 0)
+ {
+ // it is still 0 so set it to something so we render
+ filamentDiameterCache = 1.75;
+ }
+ }
+
+ return filamentDiameterCache;
+ }
+
+ public override double GetFilamentUsedMm(double filamentDiameter)
+ {
+ if (filamentUsedMmCache == 0 || filamentDiameter != diameterOfFilamentUsedMmCache)
+ {
+ double lastEPosition = 0;
+ double filamentMm = 0;
+ for (int i = 0; i < GCodeCommandQueue.Count; i++)
+ {
+ PrinterMachineInstruction instruction = GCodeCommandQueue[i];
+ //filamentMm += instruction.EPosition;
+
+ string lineToParse = instruction.Line;
+ if (lineToParse.StartsWith("G0") || lineToParse.StartsWith("G1"))
+ {
+ double ePosition = lastEPosition;
+ if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
+ {
+ if (instruction.MovementType == PrinterMachineInstruction.MovementTypes.Absolute)
+ {
+ double deltaEPosition = ePosition - lastEPosition;
+ filamentMm += deltaEPosition;
+ }
+ else
+ {
+ filamentMm += ePosition;
+ }
+
+ lastEPosition = ePosition;
+ }
+ }
+ else if (lineToParse.StartsWith("G92"))
+ {
+ double ePosition = 0;
+ if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
+ {
+ lastEPosition = ePosition;
+ }
+ }
+ }
+
+ filamentUsedMmCache = filamentMm;
+ diameterOfFilamentUsedMmCache = filamentDiameter;
+ }
+
+ return filamentUsedMmCache;
+ }
+
+ public override double GetFilamentWeightGrams(double filamentDiameterMm, double densityGramsPerCubicCm)
+ {
+ double cubicMmPerCubicCm = 1000;
+ double gramsPerCubicMm = densityGramsPerCubicCm / cubicMmPerCubicCm;
+ double cubicMms = GetFilamentCubicMm(filamentDiameterMm);
+ return cubicMms * gramsPerCubicMm;
+ }
+
+ public override int GetFirstLayerInstruction(int layerIndex)
+ {
+ if (layerIndex < IndexOfLayerStart.Count)
+ {
+ return IndexOfLayerStart[layerIndex];
+ }
+
+ // else return the last instruction
+ return GCodeCommandQueue.Count - 1;
+ }
+
+ ///
+ /// Get the height of the bottom of this layer as measure from the bed
+ ///
+ ///
+ ///
+ public double GetLayerBottom(int layerIndex)
+ {
+ double total = 0;
+ for (int i = 0; i < layerIndex; i++)
+ {
+ total += GetLayerHeight(i);
+ }
+ return total;
+ }
+
+ ///
+ /// Get the height of this layer (from the top of the previous layer to the top of this layer).
+ ///
+ ///
+ ///
+ public override double GetLayerHeight(int layerIndex)
+ {
+ if (layerHeights.Count > 0)
+ {
+ if (layerIndex < layerHeights.Count)
+ {
+ return layerHeights[layerIndex];
+ }
+
+ return 0;
+ }
+
+ if (IndexOfLayerStart.Count > 2)
+ {
+ return GCodeCommandQueue[IndexOfLayerStart[2]].Z - GCodeCommandQueue[IndexOfLayerStart[1]].Z;
+ }
+
+ return .5;
+ }
+
+ public override int GetLayerIndex(int instructionIndex)
+ {
+ if (instructionIndex >= 0
+ && instructionIndex <= LineCount)
+ {
+ for (var i = IndexOfLayerStart.Count - 1; i >= 0; i--)
+ {
+ var lineStart = IndexOfLayerStart[i];
+
+ if (instructionIndex >= lineStart)
+ {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ ///
+ /// Get the height of the top of this layer as measure from the bed
+ ///
+ ///
+ ///
+ public override double GetLayerTop(int layerIndex)
+ {
+ double total = 0;
+ for (int i = 0; i <= layerIndex; i++)
+ {
+ total += GetLayerHeight(i);
+ }
+ return total;
+ }
+
+ public override Vector2 GetWeightedCenter()
+ {
+ MatterHackers.VectorMath.Vector2 total = new MatterHackers.VectorMath.Vector2();
+ foreach (PrinterMachineInstruction state in GCodeCommandQueue)
+ {
+ total += new MatterHackers.VectorMath.Vector2(state.Position.X, state.Position.Y);
+ }
+
+ return total / GCodeCommandQueue.Count;
+ }
+
+ public void Insert(int insertIndex, PrinterMachineInstruction printerMachineInstruction)
+ {
+ for (int i = 0; i < IndexOfLayerStart.Count; i++)
+ {
+ if (insertIndex < IndexOfLayerStart[i])
+ {
+ IndexOfLayerStart[i]++;
+ }
+ }
+
+ GCodeCommandQueue.Insert(insertIndex, printerMachineInstruction);
+ }
+
+ public override PrinterMachineInstruction Instruction(int index)
+ {
+ return GCodeCommandQueue[index];
+ }
+
+ public override bool IsExtruding(int instructionIndexToCheck)
+ {
+ if (instructionIndexToCheck > 1 && instructionIndexToCheck < GCodeCommandQueue.Count)
+ {
+ double extrusionLength = GCodeCommandQueue[instructionIndexToCheck].EPosition - GCodeCommandQueue[instructionIndexToCheck - 1].EPosition;
+ if (extrusionLength > 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public (int toolIndex, double time) NextToolChange(int instructionIndex, int currentToolIndex = -1)
+ {
+ int nextToolChange = -1;
+ // find the first tool change that we are less than
+ for (int i = 0; i < toolChanges.Count; i++)
+ {
+ if (instructionIndex < toolChanges[i]
+ && GCodeCommandQueue[toolChanges[i]].ToolIndex != currentToolIndex)
+ {
+ nextToolChange = i;
+ break;
+ }
+ }
+
+ if (nextToolChange >= 0)
+ {
+ var toolIndex = GCodeCommandQueue[toolChanges[nextToolChange]].ToolIndex;
+ var time = GCodeCommandQueue[instructionIndex].SecondsToEndFromHere - GCodeCommandQueue[toolChanges[nextToolChange]].SecondsToEndFromHere;
+ return (toolIndex, time);
+ }
+
+ // there are no more tool changes
+ return (currentToolIndex, double.PositiveInfinity);
+ }
+
+ public override double PercentComplete(int instructionIndex)
+ {
+ if (GCodeCommandQueue.Count > 0)
+ {
+ return Math.Min(99.9, (double)instructionIndex / (double)GCodeCommandQueue.Count * 100);
+ }
+
+ return 100;
+ }
+
+ public override double Ratio0to1IntoContainedLayer(int instructionIndex)
+ {
+ int currentLayer = GetLayerIndex(instructionIndex);
+
+ if (currentLayer > -1)
+ {
+ int startIndex = IndexOfLayerStart[currentLayer];
+
+ int endIndex = LineCount - 1;
+
+ if (currentLayer < LayerCount - 1)
+ {
+ endIndex = IndexOfLayerStart[currentLayer + 1];
+ }
+ else
+ {
+ // Improved last layer percent complete - seek endIndex to 'MatterSlice Completed' line, otherwise leave at LineCount - 1
+ if (lastPrintLine == -1)
+ {
+ string line = "";
+ lastPrintLine = instructionIndex;
+ do
+ {
+ line = GCodeCommandQueue[Math.Min(GCodeCommandQueue.Count - 1, lastPrintLine)].Line;
+ lastPrintLine++;
+ } while (line != "; MatterSlice Completed Successfully"
+ && lastPrintLine < endIndex);
+ }
+
+ endIndex = lastPrintLine;
+ }
+
+ int deltaFromStart = Math.Max(0, instructionIndex - startIndex);
+ return deltaFromStart / (double)(endIndex - startIndex);
+ }
+
+ return 0;
+ }
+
+ public void Save(string dest)
+ {
+ using (StreamWriter file = new StreamWriter(dest))
+ {
+ foreach (PrinterMachineInstruction instruction in GCodeCommandQueue)
+ {
+ file.WriteLine(instruction.Line);
+ }
+ }
}
private static int CountNumLines(string gCodeString)
@@ -200,6 +478,22 @@ namespace MatterControl.Printing
return crCount + 1;
}
+ private static IEnumerable CustomSplit(string newtext, char splitChar)
+ {
+ int endOfLastFind = 0;
+ int positionOfSplitChar = newtext.IndexOf(splitChar);
+ while (positionOfSplitChar != -1)
+ {
+ string text = newtext.Substring(endOfLastFind, positionOfSplitChar - endOfLastFind).Trim();
+ yield return text;
+ endOfLastFind = positionOfSplitChar + 1;
+ positionOfSplitChar = newtext.IndexOf(splitChar, endOfLastFind);
+ }
+
+ string lastText = newtext.Substring(endOfLastFind);
+ yield return lastText;
+ }
+
private static GCodeMemoryFile ParseFileContents(string gCodeString,
Vector4 maxAccelerationMmPerS2,
Vector4 maxVelocityMmPerS,
@@ -288,11 +582,7 @@ namespace MatterControl.Printing
break;
default:
-#if DEBUG
- throw new NotImplementedException();
-#else
break;
-#endif
}
}
@@ -390,7 +680,7 @@ namespace MatterControl.Printing
}
}
- if(instruction.ToolIndex != currentTool)
+ if (instruction.ToolIndex != currentTool)
{
toolChanges.Add(lineIndex);
currentTool = instruction.ToolIndex;
@@ -436,34 +726,160 @@ namespace MatterControl.Printing
}
}
- public override double PercentComplete(int instructionIndex)
+ private bool FindDiameter(int lineIndex, ref double filamentDiameterCache)
{
- if (GCodeCommandQueue.Count > 0)
+ if (GetFirstNumberAfter("filamentDiameter = ", GCodeCommandQueue[lineIndex].Line, ref filamentDiameterCache, 0, ""))
{
- return Math.Min(99.9, (double)instructionIndex / (double)GCodeCommandQueue.Count * 100);
+ return true;
}
- return 100;
- }
-
- public override int GetFirstLayerInstruction(int layerIndex)
- {
- if (layerIndex < IndexOfLayerStart.Count)
+ if (GetFirstNumberAfter("; filament_diameter = ", GCodeCommandQueue[lineIndex].Line, ref filamentDiameterCache, 0, ""))
{
- return IndexOfLayerStart[layerIndex];
+ return true;
}
- // else return the last instruction
- return GCodeCommandQueue.Count - 1;
+ return false;
}
- public override int LayerCount
+ private void ParseGLine(string lineString, PrinterMachineInstruction processingMachineState)
{
- get { return IndexOfLayerStart.Count; }
- }
+ // take off any comments before we check its length
+ int commentIndex = lineString.IndexOf(';');
+ if (commentIndex != -1)
+ {
+ lineString = lineString.Substring(0, commentIndex);
+ }
- public HashSet Speeds { get; private set; }
- public List IndexOfLayerStart { get; set; } = new List();
+ string[] splitOnSpace = lineString.Split(' ');
+ string onlyNumber = splitOnSpace[0].Substring(1).Trim();
+ switch (onlyNumber)
+ {
+ case "0":
+ goto case "1";
+
+ case "4":
+ case "04":
+ // wait a given number of milliseconds
+ break;
+
+ case "1":
+ // get the x y z to move to
+ {
+ double ePosition = processingMachineState.EPosition;
+ var position = processingMachineState.Position;
+ if (processingMachineState.MovementType == PrinterMachineInstruction.MovementTypes.Relative)
+ {
+ position = Vector3.Zero;
+ ePosition = 0;
+ }
+
+ GCodeFile.GetFirstNumberAfter("X", lineString, ref position.X);
+ GCodeFile.GetFirstNumberAfter("Y", lineString, ref position.Y);
+ GCodeFile.GetFirstNumberAfter("Z", lineString, ref position.Z);
+ GCodeFile.GetFirstNumberAfter("E", lineString, ref ePosition);
+
+ double feedrate = 0;
+ if (GCodeFile.GetFirstNumberAfter("F", lineString, ref feedrate))
+ {
+ processingMachineState.FeedRate = (float)feedrate;
+ }
+
+ if (processingMachineState.MovementType == PrinterMachineInstruction.MovementTypes.Absolute)
+ {
+ processingMachineState.Position = position;
+ processingMachineState.EPosition = (float)ePosition;
+ }
+ else
+ {
+ processingMachineState.Position += position;
+ processingMachineState.EPosition += (float)ePosition;
+ }
+ }
+
+ if (!gcodeHasExplicitLayerChangeInfo)
+ {
+ if (processingMachineState.Z != parsingLastZ || IndexOfLayerStart.Count == 0)
+ {
+ // if we changed z or there is a movement and we have never started a layer index
+ IndexOfLayerStart.Add(GCodeCommandQueue.Count);
+ }
+ }
+ parsingLastZ = processingMachineState.Position.Z;
+ break;
+
+ case "10": // firmware retract
+ break;
+
+ case "11": // firmware unretract
+ break;
+
+ case "21":
+ // set to metric
+ break;
+
+ case "28":
+ // G28 Return to home position (machine zero, aka machine reference point)
+ break;
+
+ case "29":
+ // G29 Probe the z-bed in 3 places
+ break;
+
+ case "30":
+ // G30 Probe z in current position
+ break;
+
+ case "90": // G90 is Absolute Distance Mode
+ processingMachineState.MovementType = PrinterMachineInstruction.MovementTypes.Absolute;
+ break;
+
+ case "91": // G91 is Incremental Distance Mode
+ processingMachineState.MovementType = PrinterMachineInstruction.MovementTypes.Relative;
+ break;
+
+ case "92":
+ {
+ // set current head position values (used to reset origin)
+ double value = 0;
+ if (GCodeFile.GetFirstNumberAfter("X", lineString, ref value))
+ {
+ processingMachineState.PositionSet |= PositionSet.X;
+ processingMachineState.X = value;
+ }
+ if (GCodeFile.GetFirstNumberAfter("Y", lineString, ref value))
+ {
+ processingMachineState.PositionSet |= PositionSet.Y;
+ processingMachineState.Y = value;
+ }
+ if (GCodeFile.GetFirstNumberAfter("Z", lineString, ref value))
+ {
+ processingMachineState.PositionSet |= PositionSet.Z;
+ processingMachineState.Z = value;
+ }
+ if (GCodeFile.GetFirstNumberAfter("E", lineString, ref value))
+ {
+ processingMachineState.PositionSet |= PositionSet.E;
+ processingMachineState.EPosition = (float)value;
+ }
+ }
+ break;
+
+ case "130":
+ //Set Digital Potentiometer value
+ break;
+
+ case "161":
+ // home x,y axis minimum
+ break;
+
+ case "162":
+ // home z axis maximum
+ break;
+
+ default:
+ break;
+ }
+ }
private void ParseMLine(string lineString, PrinterMachineInstruction processingMachineState)
{
@@ -629,10 +1045,13 @@ namespace MatterControl.Printing
case "565": // M565: Set Z probe offset
break;
+
case "1200"://M1200 Makerbot Fake gCode command for start build notification
break;
+
case "1201"://M1201 Makerbot Fake gCode command for end build notification
break;
+
case "1202"://M1202 Makerbot Fake gCode command for reset board
break;
@@ -640,427 +1059,5 @@ namespace MatterControl.Printing
break;
}
}
-
- private void ParseGLine(string lineString, PrinterMachineInstruction processingMachineState)
- {
- // take off any comments before we check its length
- int commentIndex = lineString.IndexOf(';');
- if (commentIndex != -1)
- {
- lineString = lineString.Substring(0, commentIndex);
- }
-
- string[] splitOnSpace = lineString.Split(' ');
- string onlyNumber = splitOnSpace[0].Substring(1).Trim();
- switch (onlyNumber)
- {
- case "0":
- goto case "1";
-
- case "4":
- case "04":
- // wait a given number of milliseconds
- break;
-
- case "1":
- // get the x y z to move to
- {
- double ePosition = processingMachineState.EPosition;
- var position = processingMachineState.Position;
- if (processingMachineState.MovementType == PrinterMachineInstruction.MovementTypes.Relative)
- {
- position = Vector3.Zero;
- ePosition = 0;
- }
-
- GCodeFile.GetFirstNumberAfter("X", lineString, ref position.X);
- GCodeFile.GetFirstNumberAfter("Y", lineString, ref position.Y);
- GCodeFile.GetFirstNumberAfter("Z", lineString, ref position.Z);
- GCodeFile.GetFirstNumberAfter("E", lineString, ref ePosition);
-
- double feedrate = 0;
- if (GCodeFile.GetFirstNumberAfter("F", lineString, ref feedrate))
- {
- processingMachineState.FeedRate = (float)feedrate;
- }
-
- if (processingMachineState.MovementType == PrinterMachineInstruction.MovementTypes.Absolute)
- {
- processingMachineState.Position = position;
- processingMachineState.EPosition = (float)ePosition;
- }
- else
- {
- processingMachineState.Position += position;
- processingMachineState.EPosition += (float)ePosition;
- }
- }
-
- if (!gcodeHasExplicitLayerChangeInfo)
- {
- if (processingMachineState.Z != parsingLastZ || IndexOfLayerStart.Count == 0)
- {
- // if we changed z or there is a movement and we have never started a layer index
- IndexOfLayerStart.Add(GCodeCommandQueue.Count);
- }
- }
- parsingLastZ = processingMachineState.Position.Z;
- break;
-
- case "10": // firmware retract
- break;
-
- case "11": // firmware unretract
- break;
-
- case "21":
- // set to metric
- break;
-
- case "28":
- // G28 Return to home position (machine zero, aka machine reference point)
- break;
-
- case "29":
- // G29 Probe the z-bed in 3 places
- break;
-
- case "30":
- // G30 Probe z in current position
- break;
-
- case "90": // G90 is Absolute Distance Mode
- processingMachineState.MovementType = PrinterMachineInstruction.MovementTypes.Absolute;
- break;
-
- case "91": // G91 is Incremental Distance Mode
- processingMachineState.MovementType = PrinterMachineInstruction.MovementTypes.Relative;
- break;
-
- case "92":
- {
- // set current head position values (used to reset origin)
- double value = 0;
- if (GCodeFile.GetFirstNumberAfter("X", lineString, ref value))
- {
- processingMachineState.PositionSet |= PositionSet.X;
- processingMachineState.X = value;
- }
- if (GCodeFile.GetFirstNumberAfter("Y", lineString, ref value))
- {
- processingMachineState.PositionSet |= PositionSet.Y;
- processingMachineState.Y = value;
- }
- if (GCodeFile.GetFirstNumberAfter("Z", lineString, ref value))
- {
- processingMachineState.PositionSet |= PositionSet.Z;
- processingMachineState.Z = value;
- }
- if (GCodeFile.GetFirstNumberAfter("E", lineString, ref value))
- {
- processingMachineState.PositionSet |= PositionSet.E;
- processingMachineState.EPosition = (float)value;
- }
- }
- break;
-
- case "130":
- //Set Digital Potentiometer value
- break;
-
- case "161":
- // home x,y axis minimum
- break;
-
- case "162":
- // home z axis maximum
- break;
-
- default:
- break;
- }
- }
-
- public override Vector2 GetWeightedCenter()
- {
- MatterHackers.VectorMath.Vector2 total = new MatterHackers.VectorMath.Vector2();
- foreach (PrinterMachineInstruction state in GCodeCommandQueue)
- {
- total += new MatterHackers.VectorMath.Vector2(state.Position.X, state.Position.Y);
- }
-
- return total / GCodeCommandQueue.Count;
- }
-
- public override RectangleDouble GetBounds()
- {
- RectangleDouble bounds = new RectangleDouble(double.MaxValue, double.MaxValue, double.MinValue, double.MinValue);
- foreach (PrinterMachineInstruction state in GCodeCommandQueue)
- {
- bounds.Left = Math.Min(state.Position.X, bounds.Left);
- bounds.Right = Math.Max(state.Position.X, bounds.Right);
- bounds.Bottom = Math.Min(state.Position.Y, bounds.Bottom);
- bounds.Top = Math.Max(state.Position.Y, bounds.Top);
- }
-
- return bounds;
- }
-
- public override bool IsExtruding(int instructionIndexToCheck)
- {
- if (instructionIndexToCheck > 1 && instructionIndexToCheck < GCodeCommandQueue.Count)
- {
- double extrusionLength = GCodeCommandQueue[instructionIndexToCheck].EPosition - GCodeCommandQueue[instructionIndexToCheck - 1].EPosition;
- if (extrusionLength > 0)
- {
- return true;
- }
- }
-
- return false;
- }
-
- public override double GetFilamentUsedMm(double filamentDiameter)
- {
- if (filamentUsedMmCache == 0 || filamentDiameter != diameterOfFilamentUsedMmCache)
- {
- double lastEPosition = 0;
- double filamentMm = 0;
- for (int i = 0; i < GCodeCommandQueue.Count; i++)
- {
- PrinterMachineInstruction instruction = GCodeCommandQueue[i];
- //filamentMm += instruction.EPosition;
-
- string lineToParse = instruction.Line;
- if (lineToParse.StartsWith("G0") || lineToParse.StartsWith("G1"))
- {
- double ePosition = lastEPosition;
- if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
- {
- if (instruction.MovementType == PrinterMachineInstruction.MovementTypes.Absolute)
- {
- double deltaEPosition = ePosition - lastEPosition;
- filamentMm += deltaEPosition;
- }
- else
- {
- filamentMm += ePosition;
- }
-
- lastEPosition = ePosition;
- }
- }
- else if (lineToParse.StartsWith("G92"))
- {
- double ePosition = 0;
- if (GetFirstNumberAfter("E", lineToParse, ref ePosition))
- {
- lastEPosition = ePosition;
- }
- }
- }
-
- filamentUsedMmCache = filamentMm;
- diameterOfFilamentUsedMmCache = filamentDiameter;
- }
-
- return filamentUsedMmCache;
- }
-
- public override double GetFilamentCubicMm(double filamentDiameterMm)
- {
- double filamentUsedMm = GetFilamentUsedMm(filamentDiameterMm);
- double filamentRadius = filamentDiameterMm / 2;
- double areaSquareMm = (filamentRadius * filamentRadius) * Math.PI;
-
- return areaSquareMm * filamentUsedMm;
- }
-
- public override double GetFilamentWeightGrams(double filamentDiameterMm, double densityGramsPerCubicCm)
- {
- double cubicMmPerCubicCm = 1000;
- double gramsPerCubicMm = densityGramsPerCubicCm / cubicMmPerCubicCm;
- double cubicMms = GetFilamentCubicMm(filamentDiameterMm);
- return cubicMms * gramsPerCubicMm;
- }
-
- public void Save(string dest)
- {
- using (StreamWriter file = new StreamWriter(dest))
- {
- foreach (PrinterMachineInstruction instruction in GCodeCommandQueue)
- {
- file.WriteLine(instruction.Line);
- }
- }
- }
-
- double filamentDiameterCache = 0;
- public override double GetFilamentDiameter()
- {
- if (filamentDiameterCache == 0)
- {
- // check the beginning of the file for the filament diameter
- for (int i = 0; i < Math.Min(100, GCodeCommandQueue.Count); i++)
- {
- if (FindDiameter(i, ref filamentDiameterCache))
- {
- break;
- }
- }
-
- // check the end of the file for the filament diameter
- if (filamentDiameterCache == 0)
- {
- // didn't find it, so look at the end of the file for filament_diameter =
- for (int i = GCodeCommandQueue.Count - 1; i > Math.Max(0, GCodeCommandQueue.Count - 100); i--)
- {
- if (FindDiameter(i, ref filamentDiameterCache))
- {
- break;
- }
- }
- }
-
- if (filamentDiameterCache == 0)
- {
- // it is still 0 so set it to something so we render
- filamentDiameterCache = 1.75;
- }
- }
-
- return filamentDiameterCache;
- }
-
- private bool FindDiameter(int lineIndex, ref double filamentDiameterCache)
- {
- if (GetFirstNumberAfter("filamentDiameter = ", GCodeCommandQueue[lineIndex].Line, ref filamentDiameterCache, 0, ""))
- {
- return true;
- }
-
- if (GetFirstNumberAfter("; filament_diameter = ", GCodeCommandQueue[lineIndex].Line, ref filamentDiameterCache, 0, ""))
- {
- return true;
- }
-
- return false;
- }
-
- ///
- /// Get the height of this layer (from the top of the previous layer to the top of this layer).
- ///
- ///
- ///
- public override double GetLayerHeight(int layerIndex)
- {
- if (layerHeights.Count > 0)
- {
- if (layerIndex < layerHeights.Count)
- {
- return layerHeights[layerIndex];
- }
-
- return 0;
- }
-
- if (IndexOfLayerStart.Count > 2)
- {
- return GCodeCommandQueue[IndexOfLayerStart[2]].Z - GCodeCommandQueue[IndexOfLayerStart[1]].Z;
- }
-
- return .5;
- }
-
- ///
- /// Get the height of the top of this layer as measure from the bed
- ///
- ///
- ///
- public override double GetLayerTop(int layerIndex)
- {
- double total = 0;
- for (int i = 0; i <= layerIndex; i++)
- {
- total += GetLayerHeight(i);
- }
- return total;
- }
-
- ///
- /// Get the height of the bottom of this layer as measure from the bed
- ///
- ///
- ///
- 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
- && instructionIndex <= LineCount)
- {
- for (var i = IndexOfLayerStart.Count - 1; i >= 0; i--)
- {
- var lineStart = IndexOfLayerStart[i];
-
- if (instructionIndex >= lineStart)
- {
- return i;
- }
- }
- }
-
- return -1;
- }
-
- private static int lastPrintLine = -1;
-
- public override double Ratio0to1IntoContainedLayer(int instructionIndex)
- {
- int currentLayer = GetLayerIndex(instructionIndex);
-
- if (currentLayer > -1)
- {
- int startIndex = IndexOfLayerStart[currentLayer];
-
- int endIndex = LineCount - 1;
-
- if (currentLayer < LayerCount - 1)
- {
- endIndex = IndexOfLayerStart[currentLayer + 1];
- }
- else
- {
- // Improved last layer percent complete - seek endIndex to 'MatterSlice Completed' line, otherwise leave at LineCount - 1
- if (lastPrintLine == -1)
- {
- string line = "";
- lastPrintLine = instructionIndex;
- do
- {
- line = GCodeCommandQueue[Math.Min(GCodeCommandQueue.Count - 1, lastPrintLine)].Line;
- lastPrintLine++;
-
- } while (line != "; MatterSlice Completed Successfully"
- && lastPrintLine < endIndex);
- }
-
- endIndex = lastPrintLine;
- }
-
- int deltaFromStart = Math.Max(0, instructionIndex - startIndex);
- return deltaFromStart / (double)(endIndex - startIndex);
- }
-
- return 0;
- }
}
}
\ No newline at end of file
diff --git a/MatterControlLib/Library/Export/GCodeExport.cs b/MatterControlLib/Library/Export/GCodeExport.cs
index 408b4e38e..0e3500bce 100644
--- a/MatterControlLib/Library/Export/GCodeExport.cs
+++ b/MatterControlLib/Library/Export/GCodeExport.cs
@@ -282,12 +282,13 @@ namespace MatterHackers.MatterControl.Library.Export
public static GCodeStream GetExportStream(PrinterConfig printer, GCodeStream gCodeBaseStream, bool applyLeveling)
{
- var queueStream = new QueuedCommandsStream(printer, gCodeBaseStream);
- GCodeStream accumulatedStream = queueStream;
+ var queuedCommandStream = new QueuedCommandsStream(printer, gCodeBaseStream);
+ GCodeStream accumulatedStream = queuedCommandStream;
if (printer.Settings.GetValue(SettingsKey.extruder_count) > 1)
{
- accumulatedStream = new ToolChangeStream(printer, accumulatedStream, queueStream);
+ accumulatedStream = new ToolChangeStream(printer, accumulatedStream, queuedCommandStream);
+ accumulatedStream = new HotendTemperatureStream(printer, accumulatedStream, queuedCommandStream);
}
accumulatedStream = new RelativeToAbsoluteStream(printer, accumulatedStream);
@@ -312,7 +313,7 @@ namespace MatterHackers.MatterControl.Library.Export
}
// this is added to ensure we are rewriting the G0 G1 commands as needed
- accumulatedStream = new ProcessWriteRegexStream(printer, accumulatedStream, queueStream);
+ accumulatedStream = new ProcessWriteRegexStream(printer, accumulatedStream, queuedCommandStream);
return accumulatedStream;
}
diff --git a/MatterControlLib/PartPreviewWindow/GCodeDetails/GCodeDebugView.cs b/MatterControlLib/PartPreviewWindow/GCodeDetails/GCodeDebugView.cs
index de3429741..a0f30aea6 100644
--- a/MatterControlLib/PartPreviewWindow/GCodeDetails/GCodeDebugView.cs
+++ b/MatterControlLib/PartPreviewWindow/GCodeDetails/GCodeDebugView.cs
@@ -38,8 +38,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class GCodeDebugView : GCodeDetailsPanel
{
+ private GCodeFile gCodeFile;
private PrinterTabPage printerTabPage;
private ISceneContext sceneContext;
+ private GCodeMemoryFile gCodeMemoryFile;
private TextWidget startPointWidget;
private TextWidget endPointWidget;
private TextWidget slopeWidget;
@@ -47,20 +49,31 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private TextWidget yInterceptWidget;
private TextWidget xInterceptWidget;
private TextWidget timeToToolChange;
+ private TextWidget rawLine;
- public GCodeDebugView(PrinterTabPage printerTabPage, GCodeFile gCodeMemoryFile, ISceneContext sceneContext, ThemeConfig theme)
+ public GCodeDebugView(PrinterTabPage printerTabPage, GCodeFile gCodeFile, ISceneContext sceneContext, ThemeConfig theme)
: base(theme)
{
+ this.gCodeFile = gCodeFile;
this.printerTabPage = printerTabPage;
this.sceneContext = sceneContext;
+ gCodeMemoryFile = gCodeFile as GCodeMemoryFile;
+ if (gCodeMemoryFile != null)
+ {
+ rawLine = this.AddSetting("G-Code Line".Localize(), "");
+ }
+
startPointWidget = this.AddSetting("Start".Localize(), "");
endPointWidget = this.AddSetting("End".Localize(), "");
lengthWidget = this.AddSetting("Length".Localize(), "");
- slopeWidget = this.AddSetting("Slope".Localize(), "");
- yInterceptWidget = this.AddSetting("Y Intercept".Localize(), "");
- xInterceptWidget = this.AddSetting("X Intercept".Localize(), "");
- timeToToolChange = this.AddSetting("Tool Change".Localize(), "");
+ //slopeWidget = this.AddSetting("Slope".Localize(), "");
+ //yInterceptWidget = this.AddSetting("Y Intercept".Localize(), "");
+ //xInterceptWidget = this.AddSetting("X Intercept".Localize(), "");
+ if (gCodeMemoryFile != null)
+ {
+ timeToToolChange = this.AddSetting("Time to Tool Change".Localize(), "");
+ }
// Register listeners
printerTabPage.LayerFeaturesScrollbar.SecondValueChanged += this.LayerFeaturesScrollbar_SecondValueChanged;
@@ -85,6 +98,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (sceneContext.GCodeRenderer[layerIndex, activeFeatureIndex] is RenderFeatureTravel line)
{
+ if (rawLine != null)
+ {
+ rawLine.Text = gCodeMemoryFile.Instruction(line.InstructionIndex).Line;
+ }
+
var start = line.Start;
var end = line.End;
@@ -101,20 +119,37 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// n = -x_1 * (y_2 - y_1) / (x_2 - x_1) + y_1
var slope = (end.Y - start.Y) / (end.X - start.X);
- slopeWidget.Text = $"{slope:0.###}";
+ if (slopeWidget != null)
+ {
+ slopeWidget.Text = $"{slope:0.###}";
+ }
- // -x_1 * (y_2 - y_1) / (x_2 - x_1) + y_1
- var yIntercept = -start.X * slope + start.Y;
- yInterceptWidget.Text = $"{yIntercept:0.###}";
+ if (yInterceptWidget != null)
+ {
+ // -x_1 * (y_2 - y_1) / (x_2 - x_1) + y_1
+ var yIntercept = -start.X * slope + start.Y;
+ yInterceptWidget.Text = $"{yIntercept:0.###}";
+ }
- // x_1 - y_1*(x_2-x_1)/(y_2-y_1)
- var xIntercept = start.X - start.Y * (end.X - start.X) / (end.Y - start.Y);
- xInterceptWidget.Text = $"{xIntercept:0.###}";
+ if (xInterceptWidget != null)
+ {
+ // x_1 - y_1*(x_2-x_1)/(y_2-y_1)
+ var xIntercept = start.X - start.Y * (end.X - start.X) / (end.Y - start.Y);
+ xInterceptWidget.Text = $"{xIntercept:0.###}";
+ }
// put in the time until the next tool change
- if(timeToToolChange != null)
+ if (timeToToolChange != null)
{
-
+ var toolChange = gCodeMemoryFile.NextToolChange(line.InstructionIndex);
+ if (toolChange.time < double.PositiveInfinity)
+ {
+ timeToToolChange.Text = $"T{toolChange.toolIndex} : {toolChange.time:0.00}s";
+ }
+ else
+ {
+ timeToToolChange.Text = $"No More Changes";
+ }
}
}
}
diff --git a/MatterControlLib/PrinterCommunication/Io/HotendTemperatureStream.cs b/MatterControlLib/PrinterCommunication/Io/HotendTemperatureStream.cs
new file mode 100644
index 000000000..11d834750
--- /dev/null
+++ b/MatterControlLib/PrinterCommunication/Io/HotendTemperatureStream.cs
@@ -0,0 +1,121 @@
+/*
+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 MatterControl.Printing;
+using MatterHackers.MatterControl.SlicerConfiguration;
+
+namespace MatterHackers.MatterControl.PrinterCommunication.Io
+{
+ public class HotendTemperatureStream : GCodeStreamProxy
+ {
+ private bool haveSeenMultipleExtruders;
+ private int extruderIndex;
+ private QueuedCommandsStream queuedCommandsStream;
+ int extruderCount = 0;
+
+ public HotendTemperatureStream(PrinterConfig printer, GCodeStream internalStream, QueuedCommandsStream queuedCommandsStream)
+ : base(printer, internalStream)
+ {
+ this.queuedCommandsStream = queuedCommandsStream;
+ extruderCount = printer.Settings.GetValue(SettingsKey.extruder_count);
+ extruderIndex = printer.Connection.ActiveExtruderIndex;
+ }
+
+ public override string DebugInfo
+ {
+ get
+ {
+ return $"";
+ }
+ }
+
+ public override string ReadLine()
+ {
+ string lineToSend = base.ReadLine();
+
+ if (lineToSend != null
+ && lineToSend.EndsWith("; NO_PROCESSING"))
+ {
+ return lineToSend;
+ }
+
+ TrackExtruderState(lineToSend);
+
+ // when we are actively printing manage the extruder temperature
+ if (haveSeenMultipleExtruders
+ && printer.Connection.Printing)
+ {
+ // get the time to the next extruder switch
+ var toolChange = printer.Connection.NextToolChange();
+
+ // if we do not switch again
+ if (toolChange.time == double.PositiveInfinity)
+ {
+ // we do not switch extruders again, turn off any that are not currently printing
+ for (int i = 0; i < extruderCount; i++)
+ {
+ if(i != extruderIndex)
+ {
+ printer.Connection.SetTargetHotendTemperature(i, 0, true);
+ }
+ }
+ }
+
+ // don't keep checking if need to turn off extruders
+ haveSeenMultipleExtruders = false;
+ }
+
+ return lineToSend;
+ }
+
+ private void TrackExtruderState(string line)
+ {
+ if (line == null)
+ {
+ return;
+ }
+
+ if (line.StartsWith("G28)"))
+ {
+ extruderIndex = 0;
+ }
+
+ if (line.StartsWith("T"))
+ {
+ var newExtruder = extruderIndex;
+ GCodeFile.GetFirstNumberAfter("T", line, ref newExtruder);
+ if(newExtruder != extruderIndex)
+ {
+ haveSeenMultipleExtruders = true;
+ extruderIndex = newExtruder;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs
index 9126e3c3a..624962e8f 100644
--- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs
+++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs
@@ -322,6 +322,20 @@ namespace MatterHackers.MatterControl.PrinterCommunication
});
}
+ ///
+ /// seconds until the next tool change while printing
+ ///
+ ///
+ public (int toolIndex, double time) NextToolChange()
+ {
+ if (gCodeFileSwitcher.GCodeFile is GCodeMemoryFile gCodeMemoryFile)
+ {
+ return gCodeMemoryFile.NextToolChange(gCodeFileSwitcher.LineIndex);
+ }
+
+ return (0, 0);
+ }
+
private void ExtruderIndexSet(string line)
{
double extruderBeingSet = 0;
@@ -2159,6 +2173,7 @@ You will then need to logout and log back in to the computer for the changes to
if (ExtruderCount > 1)
{
accumulatedStream = new ToolChangeStream(Printer, accumulatedStream, queuedCommandStream);
+ accumulatedStream = new HotendTemperatureStream(Printer, accumulatedStream, queuedCommandStream);
}
accumulatedStream = new BabyStepsStream(Printer, accumulatedStream);