diff --git a/MatterControl.csproj b/MatterControl.csproj
index b570dd6d8..fc7314bf2 100644
--- a/MatterControl.csproj
+++ b/MatterControl.csproj
@@ -181,6 +181,7 @@
+
diff --git a/PartPreviewWindow/ViewGcodeWidget.cs b/PartPreviewWindow/ViewGcodeWidget.cs
index 9865c9a47..3139d48fe 100644
--- a/PartPreviewWindow/ViewGcodeWidget.cs
+++ b/PartPreviewWindow/ViewGcodeWidget.cs
@@ -336,44 +336,54 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
if (loadedGCode != null)
{
- Affine transform = TotalTransform;
+ using (new PerformanceTimer("GCode Timer", "Total"))
+ {
+ Affine transform = TotalTransform;
- CreateGrid(transform);
+ CreateGrid(transform);
- double gridLineWidths = 0.2 * layerScale;
- Stroke stroke = new Stroke(grid, gridLineWidths);
+ double gridLineWidths = 0.2 * layerScale;
+ Stroke stroke = new Stroke(grid, gridLineWidths);
- if (RenderGrid)
- {
- graphics2D.Render(stroke, new RGBA_Bytes(190, 190, 190, 255));
- }
+ if (RenderGrid)
+ {
+ using (new PerformanceTimer("GCode Timer", "Render Grid"))
+ {
+ graphics2D.Render(stroke, new RGBA_Bytes(190, 190, 190, 255));
+ }
+ }
- RenderType renderType = RenderType.Extrusions;
- if (RenderMoves)
- {
- renderType |= RenderType.Moves;
- }
- if (RenderRetractions)
- {
- renderType |= RenderType.Retractions;
- }
- if (RenderSpeeds)
- {
- renderType |= RenderType.SpeedColors;
- }
- if (SimulateExtrusion)
- {
- renderType |= RenderType.SimulateExtrusion;
- }
- if (HideExtruderOffsets)
- {
- renderType |= RenderType.HideExtruderOffsets;
- }
+ RenderType renderType = RenderType.Extrusions;
+ if (RenderMoves)
+ {
+ renderType |= RenderType.Moves;
+ }
+ if (RenderRetractions)
+ {
+ renderType |= RenderType.Retractions;
+ }
+ if (RenderSpeeds)
+ {
+ renderType |= RenderType.SpeedColors;
+ }
+ if (SimulateExtrusion)
+ {
+ renderType |= RenderType.SimulateExtrusion;
+ }
+ if (HideExtruderOffsets)
+ {
+ renderType |= RenderType.HideExtruderOffsets;
+ }
- GCodeRenderInfo renderInfo = new GCodeRenderInfo(activeLayerIndex, activeLayerIndex, transform, layerScale, renderType,
- FeatureToStartOnRatio0To1, FeatureToEndOnRatio0To1,
- new Vector2[] { ActiveSliceSettings.Instance.GetOffset(0), ActiveSliceSettings.Instance.GetOffset(1) });
- gCodeRenderer.Render(graphics2D, renderInfo);
+ GCodeRenderInfo renderInfo = new GCodeRenderInfo(activeLayerIndex, activeLayerIndex, transform, layerScale, renderType,
+ FeatureToStartOnRatio0To1, FeatureToEndOnRatio0To1,
+ new Vector2[] { ActiveSliceSettings.Instance.GetOffset(0), ActiveSliceSettings.Instance.GetOffset(1) });
+
+ using (new PerformanceTimer("GCode Timer", "Render"))
+ {
+ gCodeRenderer.Render(graphics2D, renderInfo);
+ }
+ }
}
base.OnDraw(graphics2D);
diff --git a/SlicerConfiguration/ActiveSliceSettings.cs b/SlicerConfiguration/ActiveSliceSettings.cs
index 26983cab8..5f36e523e 100644
--- a/SlicerConfiguration/ActiveSliceSettings.cs
+++ b/SlicerConfiguration/ActiveSliceSettings.cs
@@ -897,6 +897,16 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
return false;
}
+ if (FillDensity == 1
+ && GetActiveValue("infill_type") != "LINES")
+ {
+ string error = "Solid Infill works best when set to LINES.".Localize();
+ string details = string.Format("It is currently set to {0}.".Localize(), GetActiveValue("infill_type"));
+ string location = "Location: 'Settings & Controls' -> 'Settings' -> 'General' -> 'Infill Type'".Localize();
+ StyledMessageBox.ShowMessageBox(null, string.Format("{0}\n\n{1}\n\n{2}", error, details, location), "Slice Error".Localize());
+ return true;
+ }
+
string normalSpeedLocation = "Location: 'Settings & Controls' -> 'Settings' -> 'General' -> 'Speed'".Localize();
// If the given speed is part of the current slice engine then check that it is greater than 0.
if (!ValidateGoodSpeedSettingGreaterThan0("bridge_speed", normalSpeedLocation)) return false;
diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt
index aac9d7fae..5239b85d8 100644
--- a/StaticData/Translations/Master.txt
+++ b/StaticData/Translations/Master.txt
@@ -3835,3 +3835,12 @@ Translated:Calibration Settings
English:Software Print Leveling (enabled)
Translated:Software Print Leveling (enabled)
+English:Layer Height = {0}\nNozzle Diameter = {1}
+Translated:Layer Height = {0}\nNozzle Diameter = {1}
+
+English:Solid Infill works best when set tu LINES.
+Translated:Solid Infill works best when set tu LINES.
+
+English:Location: 'Settings & Controls' -> 'Settings' -> 'General' -> 'Infill Type'
+Translated:Location: 'Settings & Controls' -> 'Settings' -> 'General' -> 'Infill Type'
+
diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp
index 4f5b81ccd..4fe2fd156 160000
--- a/Submodules/agg-sharp
+++ b/Submodules/agg-sharp
@@ -1 +1 @@
-Subproject commit 4f5b81ccd096b9b08c61a054ecd5bd9866edda3b
+Subproject commit 4fe2fd15604adb7c6dffec6e6311873cdd303056
diff --git a/Utilities/PerformanceTimer.cs b/Utilities/PerformanceTimer.cs
new file mode 100644
index 000000000..60ac42a22
--- /dev/null
+++ b/Utilities/PerformanceTimer.cs
@@ -0,0 +1,110 @@
+/*
+Copyright (c) 2015, Lars Brubaker
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the FreeBSD Project.
+*/
+
+using MatterHackers.Agg;
+using MatterHackers.Agg.UI;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+
+namespace MatterHackers.MatterControl
+{
+ public class PerformanceResultsWindow : SystemWindow
+ {
+ Dictionary timers = new Dictionary();
+ FlowLayoutWidget topToBottom;
+
+ internal PerformanceResultsWindow()
+ : base(350, 200)
+ {
+ BackgroundColor = RGBA_Bytes.White;
+
+ topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom)
+ {
+ HAnchor = HAnchor.ParentLeftRight,
+ VAnchor = VAnchor.ParentBottomTop,
+ };
+
+ AddChild(topToBottom);
+ ShowAsSystemWindow();
+ }
+
+ public void SetTime(string name, double elapsedSeconds)
+ {
+ if (!timers.ContainsKey(name))
+ {
+ TextWidget newTimeWidget = new TextWidget("waiting")
+ {
+ AutoExpandBoundsToText = true,
+ };
+ newTimeWidget.Printer.DrawFromHintedCache = true;
+ timers.Add(name, newTimeWidget);
+ topToBottom.AddChild(newTimeWidget);
+ }
+
+ timers[name].Text = "{0:0.00} ms - {1}".FormatWith(elapsedSeconds * 1000, name);
+ }
+ }
+
+ public class PerformanceTimer : IDisposable
+ {
+ static int runningCount = 0;
+ static Dictionary resultsWindows = new Dictionary();
+
+ private PerformanceResultsWindow timingWindowToReportTo;
+ private string name;
+ Stopwatch timer;
+
+ public PerformanceTimer(string windowName, string name)
+ {
+ if(!resultsWindows.ContainsKey(windowName))
+ {
+ PerformanceResultsWindow timingWindowToReportTo = new PerformanceResultsWindow()
+ {
+ Title = windowName,
+ };
+ resultsWindows.Add(windowName, timingWindowToReportTo);
+ }
+
+ this.timingWindowToReportTo = resultsWindows[windowName];
+ this.name = name;
+ timer = Stopwatch.StartNew();
+ runningCount++;
+ }
+
+ public void Dispose()
+ {
+ timer.Stop();
+ runningCount--;
+ timingWindowToReportTo.SetTime(name, timer.Elapsed.TotalSeconds);
+ }
+ }
+}