Got the per layer info to show up in gcode view
Fixed bugs with gcode parsing Moved classes into separate files
This commit is contained in:
parent
ab560448aa
commit
c2d2509195
14 changed files with 500 additions and 200 deletions
|
|
@ -130,11 +130,7 @@ namespace MatterHackers.GCodeVisualizer
|
|||
{
|
||||
if (gCodeFileToDraw.IsExtruding(instructionIndex))
|
||||
{
|
||||
double layerThickness = gCodeFileToDraw.GetLayerHeight();
|
||||
if (layerToCreate == 0)
|
||||
{
|
||||
layerThickness = gCodeFileToDraw.GetFirstLayerHeight();
|
||||
}
|
||||
double layerThickness = gCodeFileToDraw.GetLayerHeight(layerToCreate);
|
||||
|
||||
Color extrusionColor = ExtrusionColors.GetColorForSpeed((float)currentInstruction.FeedRate);
|
||||
renderFeaturesForLayer.Add(new RenderFeatureExtrusion(previousInstruction.Position, currentInstruction.Position, currentInstruction.ExtruderIndex, currentInstruction.FeedRate, currentInstruction.EPosition - previousInstruction.EPosition, gCodeFileToDraw.GetFilamentDiameter(), layerThickness, extrusionColor));
|
||||
|
|
|
|||
|
|
@ -68,11 +68,11 @@ namespace MatterControl.Printing
|
|||
|
||||
public abstract double GetFilamentWeightGrams(double filamentDiameterMm, double density);
|
||||
|
||||
public abstract double GetFirstLayerHeight();
|
||||
|
||||
public abstract int GetInstructionIndexAtLayer(int layerIndex);
|
||||
|
||||
public abstract double GetLayerHeight();
|
||||
public abstract double GetLayerHeight(int layerIndex);
|
||||
|
||||
public abstract double GetLayerZOffset(int layerIndex);
|
||||
|
||||
public abstract int GetLayerIndex(int instructionIndex);
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ namespace MatterControl.Printing
|
|||
int stringPos = stringWithNumber.IndexOf(stringToCheckAfter, startIndex);
|
||||
int stopPos = stringWithNumber.IndexOf(stopCheckingString);
|
||||
if (stringPos != -1
|
||||
&& (stopPos == -1 || stringPos < stopPos))
|
||||
&& (stopPos == -1 || stringPos < stopPos || string.IsNullOrEmpty(stopCheckingString)))
|
||||
{
|
||||
stringPos += stringToCheckAfter.Length;
|
||||
readValue = agg_basics.ParseDouble(stringWithNumber, ref stringPos, true);
|
||||
|
|
|
|||
|
|
@ -144,12 +144,12 @@ namespace MatterControl.Printing
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override double GetLayerHeight()
|
||||
public override double GetLayerHeight(int layerIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override double GetFirstLayerHeight()
|
||||
public override double GetLayerZOffset(int layerIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,16 +42,15 @@ namespace MatterControl.Printing
|
|||
{
|
||||
private double amountOfAccumulatedEWhileParsing = 0;
|
||||
|
||||
private List<int> indexOfChangeInZ = new List<int>();
|
||||
private MatterHackers.VectorMath.Vector2 center = Vector2.Zero;
|
||||
private Vector2 center = Vector2.Zero;
|
||||
private double parsingLastZ;
|
||||
private bool gcodeHasExplicitLayerChangeInfo = false;
|
||||
private double firstLayerThickness;
|
||||
private double layerThickness;
|
||||
|
||||
private double filamentUsedMmCache = 0;
|
||||
private double diameterOfFilamentUsedMmCache = 0;
|
||||
private double filamentUsedMmCache = 0;
|
||||
private double diameterOfFilamentUsedMmCache = 0;
|
||||
|
||||
private List<double> layerZOffset = new List<double>();
|
||||
private List<double> layerHeights = new List<double>();
|
||||
private List<PrinterMachineInstruction> GCodeCommandQueue = new List<PrinterMachineInstruction>();
|
||||
|
||||
public GCodeMemoryFile(bool gcodeHasExplicitLayerChangeInfo = false)
|
||||
|
|
@ -76,7 +75,7 @@ namespace MatterControl.Printing
|
|||
cancellationToken, null);
|
||||
if (loadedFile != null)
|
||||
{
|
||||
this.indexOfChangeInZ = loadedFile.indexOfChangeInZ;
|
||||
this.IndexOfChangeInZ = loadedFile.IndexOfChangeInZ;
|
||||
this.center = loadedFile.center;
|
||||
this.parsingLastZ = loadedFile.parsingLastZ;
|
||||
this.GCodeCommandQueue = loadedFile.GCodeCommandQueue;
|
||||
|
|
@ -92,7 +91,7 @@ namespace MatterControl.Printing
|
|||
|
||||
public override void Clear()
|
||||
{
|
||||
indexOfChangeInZ.Clear();
|
||||
IndexOfChangeInZ.Clear();
|
||||
GCodeCommandQueue.Clear();
|
||||
}
|
||||
|
||||
|
|
@ -105,11 +104,11 @@ namespace MatterControl.Printing
|
|||
|
||||
public void Insert(int insertIndex, PrinterMachineInstruction printerMachineInstruction)
|
||||
{
|
||||
for (int i = 0; i < indexOfChangeInZ.Count; i++)
|
||||
for (int i = 0; i < IndexOfChangeInZ.Count; i++)
|
||||
{
|
||||
if (insertIndex < indexOfChangeInZ[i])
|
||||
if (insertIndex < IndexOfChangeInZ[i])
|
||||
{
|
||||
indexOfChangeInZ[i]++;
|
||||
IndexOfChangeInZ[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +270,10 @@ namespace MatterControl.Printing
|
|||
case ';':
|
||||
if (gcodeHasExplicitLayerChangeInfo && IsLayerChange(lineString))
|
||||
{
|
||||
if (lineString.EndsWith("LAYER:0"))
|
||||
// if we just found the start of the file and we have not added any layers yet
|
||||
// Make sure we start at the beginging
|
||||
if (lineString.EndsWith("LAYER:0")
|
||||
&& loadedGCodeFile.IndexOfChangeInZ.Count == 0)
|
||||
{
|
||||
loadedGCodeFile.IndexOfChangeInZ.Add(0);
|
||||
break;
|
||||
|
|
@ -279,13 +281,13 @@ namespace MatterControl.Printing
|
|||
|
||||
loadedGCodeFile.IndexOfChangeInZ.Add(loadedGCodeFile.GCodeCommandQueue.Count);
|
||||
}
|
||||
if (lineString.StartsWith("; layerThickness"))
|
||||
else if (lineString.StartsWith("; LAYER_HEIGHT:"))
|
||||
{
|
||||
loadedGCodeFile.layerThickness = double.Parse(lineString.Split('=')[1]);
|
||||
}
|
||||
else if (lineString.StartsWith("; firstLayerThickness") && loadedGCodeFile.firstLayerThickness == 0)
|
||||
{
|
||||
loadedGCodeFile.firstLayerThickness = double.Parse(lineString.Split('=')[1]);
|
||||
double layerWidth = 0;
|
||||
if (GetFirstNumberAfter("LAYER_HEIGHT:", lineString, ref layerWidth, 0, ""))
|
||||
{
|
||||
loadedGCodeFile.layerHeights.Add(layerWidth);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -437,20 +439,22 @@ namespace MatterControl.Printing
|
|||
|
||||
public override int GetInstructionIndexAtLayer(int layerIndex)
|
||||
{
|
||||
return IndexOfChangeInZ[layerIndex];
|
||||
}
|
||||
if (layerIndex < IndexOfChangeInZ.Count - 1)
|
||||
{
|
||||
return IndexOfChangeInZ[layerIndex];
|
||||
}
|
||||
|
||||
private List<int> IndexOfChangeInZ
|
||||
{
|
||||
get { return indexOfChangeInZ; }
|
||||
// else return the last instruction
|
||||
return GCodeCommandQueue.Count - 1;
|
||||
}
|
||||
|
||||
public override int LayerCount
|
||||
{
|
||||
get { return indexOfChangeInZ.Count; }
|
||||
get { return IndexOfChangeInZ.Count; }
|
||||
}
|
||||
|
||||
public HashSet<float> Speeds { get; private set; }
|
||||
public List<int> IndexOfChangeInZ { get; set; } = new List<int>();
|
||||
|
||||
private void ParseMLine(string lineString, PrinterMachineInstruction processingMachineState)
|
||||
{
|
||||
|
|
@ -688,10 +692,10 @@ namespace MatterControl.Printing
|
|||
|
||||
if (!gcodeHasExplicitLayerChangeInfo)
|
||||
{
|
||||
if (processingMachineState.Z != parsingLastZ || indexOfChangeInZ.Count == 0)
|
||||
if (processingMachineState.Z != parsingLastZ || IndexOfChangeInZ.Count == 0)
|
||||
{
|
||||
// if we changed z or there is a movement and we have never started a layer index
|
||||
indexOfChangeInZ.Add(GCodeCommandQueue.Count);
|
||||
IndexOfChangeInZ.Add(GCodeCommandQueue.Count);
|
||||
}
|
||||
}
|
||||
parsingLastZ = processingMachineState.Position.Z;
|
||||
|
|
@ -903,14 +907,19 @@ namespace MatterControl.Printing
|
|||
return filamentDiameterCache;
|
||||
}
|
||||
|
||||
public override double GetLayerHeight()
|
||||
public override double GetLayerHeight(int layerIndex)
|
||||
{
|
||||
if (layerThickness > 0)
|
||||
if (layerHeights.Count > 0)
|
||||
{
|
||||
return layerThickness;
|
||||
if (layerIndex < layerHeights.Count)
|
||||
{
|
||||
return layerHeights[layerIndex];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (indexOfChangeInZ.Count > 2)
|
||||
if (IndexOfChangeInZ.Count > 2)
|
||||
{
|
||||
return GCodeCommandQueue[IndexOfChangeInZ[2]].Z - GCodeCommandQueue[IndexOfChangeInZ[1]].Z;
|
||||
}
|
||||
|
|
@ -918,19 +927,14 @@ namespace MatterControl.Printing
|
|||
return .5;
|
||||
}
|
||||
|
||||
public override double GetFirstLayerHeight()
|
||||
public override double GetLayerZOffset(int layerIndex)
|
||||
{
|
||||
if (firstLayerThickness > 0)
|
||||
double total = 0;
|
||||
for (int i = 0; i <= layerIndex; i++)
|
||||
{
|
||||
return firstLayerThickness;
|
||||
total += GetLayerHeight(i);
|
||||
}
|
||||
|
||||
if (indexOfChangeInZ.Count > 1)
|
||||
{
|
||||
return GCodeCommandQueue[IndexOfChangeInZ[1]].Z - GCodeCommandQueue[IndexOfChangeInZ[0]].Z;
|
||||
}
|
||||
|
||||
return .5;
|
||||
return total;
|
||||
}
|
||||
|
||||
public override int GetLayerIndex(int instructionIndex)
|
||||
|
|
@ -940,7 +944,7 @@ namespace MatterControl.Printing
|
|||
{
|
||||
for(var i = IndexOfChangeInZ.Count - 1; i >=0; i--)
|
||||
{
|
||||
var lineStart = indexOfChangeInZ[i];
|
||||
var lineStart = IndexOfChangeInZ[i];
|
||||
|
||||
if (instructionIndex >= lineStart)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
<Compile Include="Library\Providers\MatterControl\LibraryCollectionContainer.cs" />
|
||||
<Compile Include="Library\Providers\MatterControl\PartHistoryContainer.cs" />
|
||||
<Compile Include="Library\Providers\MatterControl\RootHistoryContainer.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetails\BoolOption.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetails\GCodeLayerDetailsView.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetails\GCodeOptionsPanel.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetails\IToggleOption.cs" />
|
||||
<Compile Include="PrinterControls\ControlWidgets\CalibrationControls.cs" />
|
||||
<Compile Include="ConfigurationPage\PrintLeveling\LevelingFunctions.cs" />
|
||||
<Compile Include="ConfigurationPage\PrintLeveling\ProbeCalibrationWizard.cs" />
|
||||
|
|
@ -294,8 +298,8 @@
|
|||
<Compile Include="Library\Providers\Zip\LocalZipContainerLink.cs" />
|
||||
<Compile Include="Library\Providers\Zip\ZipMemoryItem.cs" />
|
||||
<Compile Include="Library\Providers\Zip\ZipMemoryContainer.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetails.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetailsView.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetails\GCodeDetails.cs" />
|
||||
<Compile Include="PartPreviewWindow\GCodeDetails\GCodeDetailsView.cs" />
|
||||
<Compile Include="PartPreviewWindow\PlusTab\PlusTabPage.cs" />
|
||||
<Compile Include="PartPreviewWindow\Tabs.cs" />
|
||||
<Compile Include="PartPreviewWindow\PrinterTabPage.cs" />
|
||||
|
|
|
|||
|
|
@ -100,23 +100,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
if (sceneContext.LoadedGCode?.LineCount > 0)
|
||||
{
|
||||
loadedGCodeSection.AddChild(
|
||||
new SectionWidget(
|
||||
"Details".Localize(),
|
||||
new GCodeDetailsView(new GCodeDetails(printer, printer.Bed.LoadedGCode), theme.FontSize12, theme.FontSize9)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(bottom: 3),
|
||||
Padding = new BorderDouble(15, 4)
|
||||
},
|
||||
theme)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit
|
||||
});
|
||||
|
||||
bool renderSpeeds = printer.Bed.RendererOptions.GCodeLineColorStyle == "Speeds";
|
||||
|
||||
loadedGCodeSection.AddChild(
|
||||
speedsWidget = new SectionWidget(
|
||||
"Speeds".Localize(),
|
||||
|
|
@ -133,6 +117,36 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
});
|
||||
|
||||
speedsWidget.Visible = renderSpeeds;
|
||||
|
||||
loadedGCodeSection.AddChild(
|
||||
new SectionWidget(
|
||||
"Details".Localize(),
|
||||
new GCodeDetailsView(new GCodeDetails(printer, printer.Bed.LoadedGCode), theme.FontSize12, theme.FontSize9)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(bottom: 3),
|
||||
Padding = new BorderDouble(15, 4)
|
||||
},
|
||||
theme)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit
|
||||
});
|
||||
|
||||
loadedGCodeSection.AddChild(
|
||||
new SectionWidget(
|
||||
"Layer".Localize(),
|
||||
new GCodeLayerDetailsView(new GCodeDetails(printer, printer.Bed.LoadedGCode), sceneContext, theme.FontSize12, theme.FontSize9)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(bottom: 3),
|
||||
Padding = new BorderDouble(15, 4)
|
||||
},
|
||||
theme)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit
|
||||
});
|
||||
}
|
||||
|
||||
// Enforce panel padding in sidebar
|
||||
|
|
|
|||
57
PartPreviewWindow/GCodeDetails/BoolOption.cs
Normal file
57
PartPreviewWindow/GCodeDetails/BoolOption.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Copyright (c) 2017, 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;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow
|
||||
{
|
||||
public class BoolOption : IToggleOption
|
||||
{
|
||||
public string Title { get; }
|
||||
|
||||
public Func<bool> IsChecked { get; }
|
||||
|
||||
public Func<bool> IsVisible { get; }
|
||||
|
||||
public Action<bool> SetValue { get; }
|
||||
|
||||
public BoolOption(string title, Func<bool> isChecked, Action<bool> setValue)
|
||||
: this(title, isChecked, setValue, () => true)
|
||||
{
|
||||
}
|
||||
|
||||
public BoolOption(string title, Func<bool> isChecked, Action<bool> setValue, Func<bool> isVisible)
|
||||
{
|
||||
this.Title = title;
|
||||
this.IsChecked = isChecked;
|
||||
this.SetValue = setValue;
|
||||
this.IsVisible = isVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using MatterControl.Printing;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
|
||||
|
|
@ -43,6 +44,28 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
this.loadedGCode = loadedGCode;
|
||||
}
|
||||
|
||||
public string SecondsToTime(double seconds)
|
||||
{
|
||||
int secondsRemaining = (int)seconds;
|
||||
int hoursRemaining = (int)(secondsRemaining / (60 * 60));
|
||||
int minutesRemaining = (int)((secondsRemaining + 30) / 60 - hoursRemaining * 60); // +30 for rounding
|
||||
|
||||
secondsRemaining = secondsRemaining % 60;
|
||||
|
||||
if (hoursRemaining > 0)
|
||||
{
|
||||
return $"{hoursRemaining} h, {minutesRemaining} min";
|
||||
}
|
||||
else if(minutesRemaining > 10)
|
||||
{
|
||||
return $"{minutesRemaining} min";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{minutesRemaining} min {secondsRemaining} s";
|
||||
}
|
||||
}
|
||||
|
||||
public string EstimatedPrintTime
|
||||
{
|
||||
get
|
||||
|
|
@ -52,20 +75,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
return "---";
|
||||
}
|
||||
|
||||
int secondsRemaining = (int)loadedGCode.Instruction(0).secondsToEndFromHere;
|
||||
int hoursRemaining = (int)(secondsRemaining / (60 * 60));
|
||||
int minutesRemaining = (int)((secondsRemaining + 30) / 60 - hoursRemaining * 60); // +30 for rounding
|
||||
|
||||
secondsRemaining = secondsRemaining % 60;
|
||||
|
||||
if (hoursRemaining > 0)
|
||||
{
|
||||
return $"{hoursRemaining} h, {minutesRemaining} min";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{minutesRemaining} min";
|
||||
}
|
||||
return SecondsToTime(loadedGCode.Instruction(0).secondsToEndFromHere);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +98,68 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
}
|
||||
|
||||
public double GetLayerHeight(int layerIndex)
|
||||
{
|
||||
return loadedGCode.GetLayerHeight(layerIndex);
|
||||
}
|
||||
|
||||
internal object GetLayerZOffset(int layerIndex)
|
||||
{
|
||||
return loadedGCode.GetLayerZOffset(layerIndex);
|
||||
}
|
||||
|
||||
public string LayerTime(int activeLayerIndex)
|
||||
{
|
||||
if (loadedGCode == null)
|
||||
{
|
||||
return "---";
|
||||
}
|
||||
|
||||
int startInstruction = Math.Min(loadedGCode.LayerCount - 1, loadedGCode.GetInstructionIndexAtLayer(activeLayerIndex));
|
||||
int endInstruction = loadedGCode.GetInstructionIndexAtLayer(activeLayerIndex + 1);
|
||||
var secondsToEndFromStart = loadedGCode.Instruction(startInstruction).secondsToEndFromHere;
|
||||
var secondsToEndFromEnd = loadedGCode.Instruction(endInstruction).secondsToEndFromHere;
|
||||
return SecondsToTime(secondsToEndFromStart - secondsToEndFromEnd);
|
||||
}
|
||||
|
||||
internal string GetLayerFanSpeeds(int activeLayerIndex)
|
||||
{
|
||||
if (loadedGCode == null)
|
||||
{
|
||||
return "---";
|
||||
}
|
||||
|
||||
int startInstruction = loadedGCode.GetInstructionIndexAtLayer(activeLayerIndex);
|
||||
if(activeLayerIndex == 0)
|
||||
{
|
||||
startInstruction = 0;
|
||||
}
|
||||
int endInstruction = loadedGCode.GetInstructionIndexAtLayer(activeLayerIndex + 1);
|
||||
|
||||
string separator = "";
|
||||
string fanSpeeds = "";
|
||||
for (int i = startInstruction; i < endInstruction; i++)
|
||||
{
|
||||
var line = loadedGCode.Instruction(i).Line;
|
||||
if (line.StartsWith("M107")) // fan off
|
||||
{
|
||||
fanSpeeds += separator + "Off";
|
||||
separator = ", ";
|
||||
}
|
||||
else if(line.StartsWith("M106")) // fan on
|
||||
{
|
||||
double speed = 0;
|
||||
if (GCodeFile.GetFirstNumberAfter("M106", line, ref speed, 0, ""))
|
||||
{
|
||||
fanSpeeds += separator + $"{speed/255*100:0}%";
|
||||
separator = ", ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fanSpeeds;
|
||||
}
|
||||
|
||||
public double TotalCost
|
||||
{
|
||||
get
|
||||
120
PartPreviewWindow/GCodeDetails/GCodeDetailsView.cs
Normal file
120
PartPreviewWindow/GCodeDetails/GCodeDetailsView.cs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
Copyright (c) 2017, 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 System.Collections.ObjectModel;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow
|
||||
{
|
||||
public class GCodeDetailsView : FlowLayoutWidget
|
||||
{
|
||||
private TextWidget massTextWidget;
|
||||
private TextWidget costTextWidget;
|
||||
|
||||
private EventHandler unregisterEvents;
|
||||
|
||||
public GCodeDetailsView(GCodeDetails gcodeDetails, int dataPointSize, int headingPointSize)
|
||||
: base(FlowDirection.TopToBottom)
|
||||
{
|
||||
var margin = new BorderDouble(0, 9, 0, 3);
|
||||
|
||||
TextWidget AddSetting(string title, string value, GuiWidget parentWidget)
|
||||
{
|
||||
parentWidget.AddChild(
|
||||
new TextWidget(title + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: headingPointSize)
|
||||
{
|
||||
HAnchor = HAnchor.Left
|
||||
});
|
||||
|
||||
var textWidget = new TextWidget(value, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: dataPointSize)
|
||||
{
|
||||
HAnchor = HAnchor.Left,
|
||||
Margin = margin
|
||||
};
|
||||
|
||||
parentWidget.AddChild(textWidget);
|
||||
|
||||
return textWidget;
|
||||
}
|
||||
|
||||
// put in the print time
|
||||
AddSetting("Print Time".Localize(), gcodeDetails.EstimatedPrintTime, this);
|
||||
|
||||
// show the filament used
|
||||
AddSetting("Filament Length".Localize(), gcodeDetails.FilamentUsed, this);
|
||||
|
||||
AddSetting("Filament Volume".Localize(), gcodeDetails.FilamentVolume, this);
|
||||
|
||||
massTextWidget = AddSetting("Estimated Mass".Localize(), gcodeDetails.EstimatedMass, this);
|
||||
|
||||
// Cost info is only displayed when available - conditionalCostPanel is invisible when cost <= 0
|
||||
var conditionalCostPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit,
|
||||
Visible = gcodeDetails.TotalCost > 0
|
||||
};
|
||||
this.AddChild(conditionalCostPanel);
|
||||
|
||||
costTextWidget = AddSetting("Estimated Cost".Localize(), gcodeDetails.EstimatedCost, conditionalCostPanel);
|
||||
|
||||
ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
|
||||
{
|
||||
if (e is StringEventArgs stringEvent)
|
||||
{
|
||||
if (stringEvent.Data == SettingsKey.filament_cost
|
||||
|| stringEvent.Data == SettingsKey.filament_diameter
|
||||
|| stringEvent.Data == SettingsKey.filament_density)
|
||||
{
|
||||
massTextWidget.Text = gcodeDetails.EstimatedMass;
|
||||
conditionalCostPanel.Visible = gcodeDetails.TotalCost > 0;
|
||||
|
||||
if (gcodeDetails.TotalCost > 0)
|
||||
{
|
||||
costTextWidget.Text = gcodeDetails.EstimatedCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ref unregisterEvents);
|
||||
}
|
||||
|
||||
public override void OnClosed(ClosedEventArgs e)
|
||||
{
|
||||
unregisterEvents?.Invoke(this, null);
|
||||
base.OnClosed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
107
PartPreviewWindow/GCodeDetails/GCodeLayerDetailsView.cs
Normal file
107
PartPreviewWindow/GCodeDetails/GCodeLayerDetailsView.cs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright (c) 2017, 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 System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.Platform;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.ConfigurationPage;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow
|
||||
{
|
||||
public class GCodeLayerDetailsView : FlowLayoutWidget
|
||||
{
|
||||
private TextWidget massTextWidget;
|
||||
private TextWidget costTextWidget;
|
||||
private BedConfig sceneContext;
|
||||
|
||||
private EventHandler unregisterEvents;
|
||||
|
||||
public GCodeLayerDetailsView(GCodeDetails gcodeDetails, BedConfig sceneContext, int dataPointSize, int headingPointSize)
|
||||
: base(FlowDirection.TopToBottom)
|
||||
{
|
||||
this.sceneContext = sceneContext;
|
||||
var margin = new BorderDouble(0, 9, 0, 3);
|
||||
|
||||
// local function to add setting
|
||||
TextWidget AddSetting(string title, string value, GuiWidget parentWidget)
|
||||
{
|
||||
parentWidget.AddChild(
|
||||
new TextWidget(title + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: headingPointSize)
|
||||
{
|
||||
HAnchor = HAnchor.Left
|
||||
});
|
||||
|
||||
var textWidget = new TextWidget(value, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: dataPointSize)
|
||||
{
|
||||
HAnchor = HAnchor.Left,
|
||||
Margin = margin,
|
||||
AutoExpandBoundsToText = true
|
||||
};
|
||||
|
||||
parentWidget.AddChild(textWidget);
|
||||
|
||||
return textWidget;
|
||||
}
|
||||
|
||||
GuiWidget layerTime = AddSetting("Time".Localize(), "", this);
|
||||
GuiWidget layerHeight = AddSetting("Height".Localize(), "", this);
|
||||
GuiWidget layerWidth = AddSetting("Z Offset".Localize(), "", this);
|
||||
GuiWidget layerFanSpeeds = AddSetting("Fan Speed".Localize(), "", this);
|
||||
|
||||
void UpdateLayerDisplay(object sender, EventArgs e)
|
||||
{
|
||||
layerTime.Text = gcodeDetails.LayerTime(sceneContext.ActiveLayerIndex);
|
||||
layerHeight.Text = $"{gcodeDetails.GetLayerHeight(sceneContext.ActiveLayerIndex):0.###}";
|
||||
layerWidth.Text = $"{gcodeDetails.GetLayerZOffset(sceneContext.ActiveLayerIndex):0.###}";
|
||||
var fanSpeed = gcodeDetails.GetLayerFanSpeeds(sceneContext.ActiveLayerIndex);
|
||||
layerFanSpeeds.Text = string.IsNullOrWhiteSpace(fanSpeed) ? "Unchanged" : fanSpeed;
|
||||
}
|
||||
|
||||
sceneContext.ActiveLayerChanged += UpdateLayerDisplay;
|
||||
// and do the initial setting
|
||||
UpdateLayerDisplay(this, null);
|
||||
}
|
||||
|
||||
public override void OnClosed(ClosedEventArgs e)
|
||||
{
|
||||
unregisterEvents?.Invoke(this, null);
|
||||
base.OnClosed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,8 +27,6 @@ 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.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
|
@ -39,42 +37,9 @@ using MatterHackers.Localizations;
|
|||
using MatterHackers.MatterControl.ConfigurationPage;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow
|
||||
{
|
||||
public interface IToggleOption
|
||||
{
|
||||
string Title { get; }
|
||||
Func<bool> IsChecked { get; }
|
||||
Action<bool> SetValue { get; }
|
||||
}
|
||||
|
||||
public class BoolOption : IToggleOption
|
||||
{
|
||||
public string Title { get; }
|
||||
|
||||
public Func<bool> IsChecked { get; }
|
||||
|
||||
public Func<bool> IsVisible { get; }
|
||||
|
||||
public Action<bool> SetValue { get; }
|
||||
|
||||
public BoolOption(string title, Func<bool> isChecked, Action<bool> setValue)
|
||||
: this(title, isChecked, setValue, () => true)
|
||||
{
|
||||
}
|
||||
|
||||
public BoolOption(string title, Func<bool> isChecked, Action<bool> setValue, Func<bool> isVisible)
|
||||
{
|
||||
this.Title = title;
|
||||
this.IsChecked = isChecked;
|
||||
this.SetValue = setValue;
|
||||
this.IsVisible = isVisible;
|
||||
}
|
||||
}
|
||||
|
||||
public class GCodeOptionsPanel : FlowLayoutWidget
|
||||
{
|
||||
private RadioIconButton speedsButton;
|
||||
|
|
@ -324,83 +289,4 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GCodeDetailsView : FlowLayoutWidget
|
||||
{
|
||||
private TextWidget massTextWidget;
|
||||
private TextWidget costTextWidget;
|
||||
|
||||
private EventHandler unregisterEvents;
|
||||
|
||||
public GCodeDetailsView(GCodeDetails gcodeDetails, int dataPointSize, int headingPointSize)
|
||||
: base(FlowDirection.TopToBottom)
|
||||
{
|
||||
var margin = new BorderDouble(0, 9, 0, 3);
|
||||
|
||||
TextWidget AddSetting(string title, string value, GuiWidget parentWidget)
|
||||
{
|
||||
parentWidget.AddChild(
|
||||
new TextWidget(title + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: headingPointSize)
|
||||
{
|
||||
HAnchor = HAnchor.Left
|
||||
});
|
||||
|
||||
var textWidget = new TextWidget(value, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: dataPointSize)
|
||||
{
|
||||
HAnchor = HAnchor.Left,
|
||||
Margin = margin
|
||||
};
|
||||
|
||||
parentWidget.AddChild(textWidget);
|
||||
|
||||
return textWidget;
|
||||
}
|
||||
|
||||
// put in the print time
|
||||
AddSetting("Print Time".Localize(), gcodeDetails.EstimatedPrintTime, this);
|
||||
|
||||
// show the filament used
|
||||
AddSetting("Filament Length".Localize(), gcodeDetails.FilamentUsed, this);
|
||||
|
||||
AddSetting("Filament Volume".Localize(), gcodeDetails.FilamentVolume, this);
|
||||
|
||||
massTextWidget = AddSetting("Estimated Mass".Localize(), gcodeDetails.EstimatedMass, this);
|
||||
|
||||
// Cost info is only displayed when available - conditionalCostPanel is invisible when cost <= 0
|
||||
var conditionalCostPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit,
|
||||
Visible = gcodeDetails.TotalCost > 0
|
||||
};
|
||||
this.AddChild(conditionalCostPanel);
|
||||
|
||||
costTextWidget = AddSetting("Estimated Cost".Localize(), gcodeDetails.EstimatedCost, conditionalCostPanel);
|
||||
|
||||
ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
|
||||
{
|
||||
if (e is StringEventArgs stringEvent)
|
||||
{
|
||||
if (stringEvent.Data == SettingsKey.filament_cost
|
||||
|| stringEvent.Data == SettingsKey.filament_diameter
|
||||
|| stringEvent.Data == SettingsKey.filament_density)
|
||||
{
|
||||
massTextWidget.Text = gcodeDetails.EstimatedMass;
|
||||
conditionalCostPanel.Visible = gcodeDetails.TotalCost > 0;
|
||||
|
||||
if (gcodeDetails.TotalCost > 0)
|
||||
{
|
||||
costTextWidget.Text = gcodeDetails.EstimatedCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ref unregisterEvents);
|
||||
}
|
||||
|
||||
public override void OnClosed(ClosedEventArgs e)
|
||||
{
|
||||
unregisterEvents?.Invoke(this, null);
|
||||
base.OnClosed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
40
PartPreviewWindow/GCodeDetails/IToggleOption.cs
Normal file
40
PartPreviewWindow/GCodeDetails/IToggleOption.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright (c) 2017, 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;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow
|
||||
{
|
||||
public interface IToggleOption
|
||||
{
|
||||
string Title { get; }
|
||||
Func<bool> IsChecked { get; }
|
||||
Action<bool> SetValue { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 4361510b6188eea9d2b45f99fcab72c542a82dd9
|
||||
Subproject commit 1cec8e732bb95f09fdad483470f8afa84de670e8
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit a7bdd9279952b7bf880bffa25c796c0c8af79030
|
||||
Subproject commit 1ec9397907ccc1a191421c10278ceec0d99b7687
|
||||
Loading…
Add table
Add a link
Reference in a new issue