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