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:
Lars Brubaker 2018-05-08 15:19:06 -07:00
parent ab560448aa
commit c2d2509195
14 changed files with 500 additions and 200 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

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

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

View file

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

View 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