diff options
-rw-r--r-- | CHANGELOG.md | 10 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/ChituboxFile.cs | 2 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/ChituboxZipFile.cs | 6 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/FileFormat.cs | 74 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/IFileFormat.cs | 20 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/PHZFile.cs | 2 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/SL1File.cs | 6 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/ZCodexFile.cs | 2 | ||||
-rw-r--r-- | UVtools.Core/Layer/Layer.cs | 90 | ||||
-rw-r--r-- | UVtools.Core/Operations/OperationInfill.cs | 3 | ||||
-rw-r--r-- | UVtools.Core/UVtools.Core.csproj | 2 | ||||
-rw-r--r-- | UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml | 18 | ||||
-rw-r--r-- | UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs | 25 | ||||
-rw-r--r-- | UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs | 3 | ||||
-rw-r--r-- | UVtools.WPF/UVtools.WPF.csproj | 2 |
15 files changed, 203 insertions, 62 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 63d82d9..002984f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,19 @@ # Changelog +## 26/11/2020 - v1.3.4 + +* (Add) Infill: CubicDynamicLink - Alternates centers with lateral links, consume same resin as center linked and make model/infill stronger. +* (Add) Update estimate print time when modify dependent parameters (#103) +* (Add) Tool - Calculator: Old and new print time estimation (#103) +* (Fix) Print time calculation was using normal layers with bottom layer off time +* (Fix) Calculate print time based on each layer setting instead of global settings + ## 25/11/2020 - v1.3.3 * (Add) Improved island detection: Combines the island and overhang detections for a better more realistic detection and to discard false-positives. (Slower) If enabled, and when a island is found, it will check for overhangs on that same island, if no overhang found then the island will be discarded and considered safe, otherwise it will flag as an island issue. Note: Overhangs settings will be used to configure the detection. Enabling Overhangs is not required for this procedure to work. - Enabled by default, + Enabled by default. * (Add) More information on the About box: Operative system and architecture, framework, processor count and screens * (Fix) Overhangs: Include islands when detecting overhangs were not skip when found a island * (Fix) Decode CWS from Wanhao Workshop fails on number of slices (#102) diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs index 6dea713..19e89c0 100644 --- a/UVtools.Core/FileFormats/ChituboxFile.cs +++ b/UVtools.Core/FileFormats/ChituboxFile.cs @@ -1215,7 +1215,7 @@ namespace UVtools.Core.FileFormats set { HeaderSettings.PrintTime = (uint) value; - RaisePropertyChanged(); + base.PrintTime = value; } } diff --git a/UVtools.Core/FileFormats/ChituboxZipFile.cs b/UVtools.Core/FileFormats/ChituboxZipFile.cs index 7fcaf1c..f28268b 100644 --- a/UVtools.Core/FileFormats/ChituboxZipFile.cs +++ b/UVtools.Core/FileFormats/ChituboxZipFile.cs @@ -320,11 +320,7 @@ namespace UVtools.Core.FileFormats public override float PrintTime { get => HeaderSettings.EstimatedPrintTime; - set - { - HeaderSettings.EstimatedPrintTime = value; - RaisePropertyChanged(); - } + set => base.PrintTime = HeaderSettings.EstimatedPrintTime = value; } public override float UsedMaterial diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 8e7a4a0..9d45cfa 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -10,6 +10,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; @@ -29,6 +30,7 @@ namespace UVtools.Core.FileFormats public abstract class FileFormat : BindableBase, IFileFormat, IDisposable, IEquatable<FileFormat>, IEnumerable<Layer> { public const string TemporaryFileAppend = ".tmp"; + public const ushort ExtraPrintTime = 300; #region Enums /// <summary> @@ -374,6 +376,7 @@ namespace UVtools.Core.FileFormats private bool _haveModifiedLayers; private LayerManager _layerManager; + private float _printTime; /// <summary> /// Gets or sets if modifications require a full encode to save @@ -412,6 +415,38 @@ namespace UVtools.Core.FileFormats public abstract float DisplayWidth { get; set; } public abstract float DisplayHeight { get; set; } + + public float Xppmm + { + get => DisplayWidth > 0 ? ResolutionX / DisplayWidth : 0; + set + { + RaisePropertyChanged(nameof(Xppmm)); + RaisePropertyChanged(nameof(Ppmm)); + } + } + + public float Yppmm + { + get => DisplayHeight > 0 ? ResolutionY / DisplayHeight : 0; + set + { + RaisePropertyChanged(nameof(Yppmm)); + RaisePropertyChanged(nameof(Ppmm)); + } + } + + public SizeF Ppmm + { + get => new SizeF(Xppmm, Yppmm); + set + { + Xppmm = value.Width; + Yppmm = value.Height; + } + } + + public bool HaveAntiAliasing => AntiAliasing > 1; public abstract byte AntiAliasing { get; } @@ -443,17 +478,39 @@ namespace UVtools.Core.FileFormats public virtual byte LightPWM { get; set; } = DefaultLightPWM; - public virtual float PrintTime { get; set; } + public virtual float PrintTime + { + get => _printTime; + set + { + _printTime = value; + RaisePropertyChanged(); + RaisePropertyChanged(nameof(PrintTimeOrComputed)); + RaisePropertyChanged(nameof(PrintTimeComputed)); + RaisePropertyChanged(nameof(PrintTimeHours)); + } + } + //(header.numberOfLayers - header.bottomLayers) * (double) header.exposureTimeSeconds + (double) header.bottomLayers * (double) header.exposureBottomTimeSeconds + (double) header.offTimeSeconds * (double) header.numberOfLayers); - public virtual float PrintTimeOrComputed + public float PrintTimeOrComputed => PrintTime > 0 ? PrintTime : PrintTimeComputed; + + public float PrintTimeComputed { get { - if (PrintTime > 0) return PrintTime; - return NormalLayerCount * ExposureTime + - NormalLayerCount * LayerOffTime + - BottomLayerCount * BottomExposureTime + - NormalLayerCount * BottomLayerOffTime; + float time = ExtraPrintTime; + + foreach (var layer in this) + { + var layerOff = OperationCalculator.LightOffDelayC.CalculateSeconds(layer.LiftHeight, layer.LiftSpeed, layer.RetractSpeed); + time += layer.ExposureTime; + if (layerOff >= layer.LayerOffTime) + time += layerOff; + else + time += layer.LayerOffTime; + } + + return (float) Math.Round(time, 2); } } @@ -492,6 +549,7 @@ namespace UVtools.Core.FileFormats if (this[LayerCount - 1] is null) return; // Not initialized LayerManager.RebuildLayersProperties(); RebuildGCode(); + PrintTime = PrintTimeComputed; return; } if ( @@ -511,6 +569,8 @@ namespace UVtools.Core.FileFormats { LayerManager.RebuildLayersProperties(false); RebuildGCode(); + if(e.PropertyName != nameof(BottomLightPWM) && e.PropertyName != nameof(LightPWM)) + PrintTime = PrintTimeComputed; return; } } diff --git a/UVtools.Core/FileFormats/IFileFormat.cs b/UVtools.Core/FileFormats/IFileFormat.cs index 91893e1..e690512 100644 --- a/UVtools.Core/FileFormats/IFileFormat.cs +++ b/UVtools.Core/FileFormats/IFileFormat.cs @@ -118,6 +118,21 @@ namespace UVtools.Core.FileFormats /// </summary> float DisplayHeight { get; set; } + /// <summary> + /// Gets or sets the pixels per mm on X direction + /// </summary> + float Xppmm { get; set; } + + /// <summary> + /// Gets or sets the pixels per mm on Y direction + /// </summary> + float Yppmm { get; set; } + + /// <summary> + /// Gets or sets the pixels per mm + /// </summary> + SizeF Ppmm { get; set; } + bool HaveAntiAliasing { get; } /// <summary> @@ -229,6 +244,11 @@ namespace UVtools.Core.FileFormats float PrintTimeOrComputed { get; } /// <summary> + /// Gets the calculated estimate print time in seconds + /// </summary> + float PrintTimeComputed { get; } + + /// <summary> /// Gets the estimate print time in hours /// </summary> float PrintTimeHours { get; } diff --git a/UVtools.Core/FileFormats/PHZFile.cs b/UVtools.Core/FileFormats/PHZFile.cs index 51bccb2..ac485cf 100644 --- a/UVtools.Core/FileFormats/PHZFile.cs +++ b/UVtools.Core/FileFormats/PHZFile.cs @@ -909,7 +909,7 @@ namespace UVtools.Core.FileFormats set { HeaderSettings.PrintTime = (uint) value; - RaisePropertyChanged(); + base.PrintTime = value; } } diff --git a/UVtools.Core/FileFormats/SL1File.cs b/UVtools.Core/FileFormats/SL1File.cs index 72a2672..0db56ef 100644 --- a/UVtools.Core/FileFormats/SL1File.cs +++ b/UVtools.Core/FileFormats/SL1File.cs @@ -410,11 +410,7 @@ namespace UVtools.Core.FileFormats public override float PrintTime { get => OutputConfigSettings.PrintTime; - set - { - OutputConfigSettings.PrintTime = value; - RaisePropertyChanged(); - } + set => base.PrintTime = OutputConfigSettings.PrintTime = value; } public override float UsedMaterial diff --git a/UVtools.Core/FileFormats/ZCodexFile.cs b/UVtools.Core/FileFormats/ZCodexFile.cs index 944a694..79d738a 100644 --- a/UVtools.Core/FileFormats/ZCodexFile.cs +++ b/UVtools.Core/FileFormats/ZCodexFile.cs @@ -287,7 +287,7 @@ namespace UVtools.Core.FileFormats set { ResinMetadataSettings.PrintTime = (uint) value; - RaisePropertyChanged(); + base.PrintTime = value; } } diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs index ff55f16..55db86d 100644 --- a/UVtools.Core/Layer/Layer.cs +++ b/UVtools.Core/Layer/Layer.cs @@ -936,6 +936,7 @@ namespace UVtools.Core } else*/ if (operation.InfillType == OperationInfill.InfillAlgorithm.Cubic || operation.InfillType == OperationInfill.InfillAlgorithm.CubicCenterLink || + operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink || operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked) { using (var infillPattern = EmguExtensions.InitMat(new Size(operation.InfillSpacing, operation.InfillSpacing))) @@ -944,8 +945,10 @@ namespace UVtools.Core bool firstPattern = true; uint accumulator = 0; uint step = 0; + bool dynamicCenter = false; while (accumulator < layerIndex) { + dynamicCenter = !dynamicCenter; firstPattern = true; accumulator += operation.InfillSpacing; @@ -978,65 +981,82 @@ namespace UVtools.Core thickness, thickness), infillColor, -1); + // Center cross + int margin = (int)(operation.InfillSpacing - accumulator + layerIndex) - thickness; + int marginInv = (int)(accumulator - layerIndex) - thickness; + if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicCenterLink || + (operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink && + dynamicCenter) || operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked) { - // Center cross - int margin = (int) (operation.InfillSpacing - accumulator + layerIndex) - thickness; - int marginInv = (int) (accumulator - layerIndex) - thickness; + CvInvoke.Rectangle(infillPattern, new Rectangle(margin, margin, operation.InfillThickness, operation.InfillThickness), infillColor, -1); CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, marginInv, operation.InfillThickness, operation.InfillThickness), + new Rectangle(marginInv, marginInv, operation.InfillThickness, + operation.InfillThickness), infillColor, -1); CvInvoke.Rectangle(infillPattern, - new Rectangle(margin, marginInv, operation.InfillThickness, operation.InfillThickness), + new Rectangle(margin, marginInv, operation.InfillThickness, + operation.InfillThickness), infillColor, -1); CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, margin, operation.InfillThickness, operation.InfillThickness), + new Rectangle(marginInv, margin, operation.InfillThickness, + operation.InfillThickness), infillColor, -1); + } - if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked) - { - CvInvoke.Rectangle(infillPattern, - new Rectangle(margin, -thickness, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, -thickness, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); + if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked || + (operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink && !dynamicCenter)) + { + CvInvoke.Rectangle(infillPattern, + new Rectangle(margin, -thickness, operation.InfillThickness, + operation.InfillThickness), + infillColor, -1); - CvInvoke.Rectangle(infillPattern, - new Rectangle(-thickness, margin, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); + CvInvoke.Rectangle(infillPattern, + new Rectangle(marginInv, -thickness, operation.InfillThickness, + operation.InfillThickness), + infillColor, -1); - CvInvoke.Rectangle(infillPattern, - new Rectangle(-thickness, marginInv, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(operation.InfillSpacing - thickness, margin, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); + CvInvoke.Rectangle(infillPattern, + new Rectangle(-thickness, margin, operation.InfillThickness, + operation.InfillThickness), + infillColor, -1); - CvInvoke.Rectangle(infillPattern, - new Rectangle(operation.InfillSpacing - thickness, marginInv, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); + CvInvoke.Rectangle(infillPattern, + new Rectangle(-thickness, marginInv, operation.InfillThickness, + operation.InfillThickness), + infillColor, -1); - CvInvoke.Rectangle(infillPattern, - new Rectangle(margin, operation.InfillSpacing - thickness, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); + CvInvoke.Rectangle(infillPattern, + new Rectangle(operation.InfillSpacing - thickness, margin, + operation.InfillThickness, operation.InfillThickness), + infillColor, -1); - CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, operation.InfillSpacing - thickness, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - } + CvInvoke.Rectangle(infillPattern, + new Rectangle(operation.InfillSpacing - thickness, marginInv, + operation.InfillThickness, operation.InfillThickness), + infillColor, -1); + + CvInvoke.Rectangle(infillPattern, + new Rectangle(margin, operation.InfillSpacing - thickness, + operation.InfillThickness, operation.InfillThickness), + infillColor, -1); + + CvInvoke.Rectangle(infillPattern, + new Rectangle(marginInv, operation.InfillSpacing - thickness, + operation.InfillThickness, operation.InfillThickness), + infillColor, -1); } - + } else { diff --git a/UVtools.Core/Operations/OperationInfill.cs b/UVtools.Core/Operations/OperationInfill.cs index 3e0f0db..e305338 100644 --- a/UVtools.Core/Operations/OperationInfill.cs +++ b/UVtools.Core/Operations/OperationInfill.cs @@ -13,7 +13,7 @@ namespace UVtools.Core.Operations [Serializable] public sealed class OperationInfill : Operation { - private InfillAlgorithm _infillType = InfillAlgorithm.CubicCenterLink; + private InfillAlgorithm _infillType = InfillAlgorithm.CubicDynamicLink; private ushort _wallThickness = 64; private ushort _infillThickness = 45; private ushort _infillSpacing = 160; @@ -42,6 +42,7 @@ namespace UVtools.Core.Operations //Rhombus, Cubic, CubicCenterLink, + CubicDynamicLink, CubicInterlinked, } #endregion diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 6825a71..d7b51a1 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -10,7 +10,7 @@ <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl> <Description>MSLA/DLP, file analysis, repair, conversion and manipulation</Description> - <Version>1.3.3</Version> + <Version>1.3.4</Version> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageIcon>UVtools.png</PackageIcon> <Platforms>AnyCPU;x64</Platforms> diff --git a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml index c9fa7fd..ecd84b5 100644 --- a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml +++ b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml @@ -249,7 +249,7 @@ <Grid Grid.Row="2" - RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto" + RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto" ColumnDefinitions="Auto,10,100,5,Auto,30,Auto,10,100,5,Auto" > @@ -373,6 +373,22 @@ VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding SlicerFile.LayerOffTime, StringFormat=Current value: \{0\}}"/> + + <TextBlock + Grid.Row="14" + Grid.Column="0" + Grid.ColumnSpan="11" + VerticalAlignment="Center" + HorizontalAlignment="Center" + Text="{Binding SlicerFile.PrintTimeHours, StringFormat=Old print time: \{0\}h}"/> + + <TextBlock + Grid.Row="16" + Grid.Column="0" + Grid.ColumnSpan="11" + VerticalAlignment="Center" + HorizontalAlignment="Center" + Text="{Binding LightOffDelayPrintTimeHours, StringFormat=New print time: \{0\}h}"/> <!-- Bottom --> diff --git a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs index c342418..71c173d 100644 --- a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs @@ -1,4 +1,5 @@ -using Avalonia.Markup.Xaml; +using System; +using Avalonia.Markup.Xaml; using UVtools.Core.FileFormats; using UVtools.Core.Operations; @@ -6,10 +7,17 @@ namespace UVtools.WPF.Controls.Tools { public class ToolCalculatorControl : ToolControl { + private decimal _lightOffDelayPrintTimeHours; public OperationCalculator Operation => BaseOperation as OperationCalculator; public FileFormat SlicerFile => App.SlicerFile; + public decimal LightOffDelayPrintTimeHours + { + get => _lightOffDelayPrintTimeHours; + set => RaiseAndSetIfChanged(ref _lightOffDelayPrintTimeHours, value); + } + public ToolCalculatorControl() { InitializeComponent(); @@ -21,6 +29,19 @@ namespace UVtools.WPF.Controls.Tools (decimal)SlicerFile.LiftSpeed, (decimal)SlicerFile.BottomLiftSpeed, (decimal)SlicerFile.RetractSpeed, (decimal)SlicerFile.RetractSpeed) }; + + Operation.CalcLightOffDelay.PropertyChanged += (sender, e) => + { + if (e.PropertyName != nameof(Operation.CalcLightOffDelay.LightOffDelay) && + e.PropertyName != nameof(Operation.CalcLightOffDelay.BottomLightOffDelay)) return; + LightOffDelayPrintTimeHours = Math.Round( + (FileFormat.ExtraPrintTime + + SlicerFile.BottomLayerCount * (Operation.CalcLightOffDelay.BottomLightOffDelay + (decimal) SlicerFile.BottomExposureTime) + + SlicerFile.NormalLayerCount * (Operation.CalcLightOffDelay.LightOffDelay + (decimal)SlicerFile.ExposureTime)) + / 3600, 2); + }; + + _lightOffDelayPrintTimeHours = (decimal) SlicerFile.PrintTimeHours; } private void InitializeComponent() @@ -45,6 +66,8 @@ namespace UVtools.WPF.Controls.Tools SlicerFile.LayerOffTime = (float)Operation.CalcLightOffDelay.LightOffDelay; } + LightOffDelayPrintTimeHours = (decimal)SlicerFile.PrintTimeHours; + App.MainWindow.CanSave = true; } } diff --git a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs index ba83fec..9f45a89 100644 --- a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 5747b83..bbc8ed9 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ <PackageLicenseFile>LICENSE</PackageLicenseFile> <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <RepositoryType>Git</RepositoryType> - <Version>1.3.3</Version> + <Version>1.3.4</Version> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |