diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-08-28 18:12:25 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-08-28 18:12:25 +0300 |
commit | e7d474bcca78aca4ba6ea659fac46a2a83630d62 (patch) | |
tree | 056b58e51972cf1cb1a50c24bdc79a172bb270aa | |
parent | ffd359e79e6dd31923203d432b1e3539c8c9ddb5 (diff) |
v2.20.3v2.20.3
- **Tool - Dynamic Layer Height:**
- (Add) Option to strip anti-aliasing: Use this option if you get flashy layers or if you want to enhancement the results
- (Add) Option to reconstruct anti-aliasing: Use this option with "Strip anti-aliasing" to reconstruct the layer anti-aliasing via an gaussian blur
- (Add) Maximum wide difference: The maximum number of pixels wide difference to be able to stack layers, where one pixel difference is a whole perimeter of the object to be eroded.
0 = Stack only equal layers
n = Stack equal layers or with a n perimeter of difference between the sum of the stack (#274)
- (Add) Allow to change the base exposure times for the auto generation (#274)
- (Add) Option to switch between: "Set the same base time for all bottoms" or "Calculate and iterate bottom exposures"
- (Add) Button to: Copy automatic table data into manual table
- (Improvement) Auto fill all layer height exposures times on manual entry
- (Fix) When "Exposure set type = Multiplier" bottom exposure is being used for normal exposure (#274)
- (Fix) Do not sum equal layers on the stack
- (Fix) Recalculate the material milliliters per layer when replacing a layer collection (#273)
-rw-r--r-- | CHANGELOG.md | 16 | ||||
-rw-r--r-- | UVtools.Core/Layer/Layer.cs | 7 | ||||
-rw-r--r-- | UVtools.Core/Layer/LayerManager.cs | 4 | ||||
-rw-r--r-- | UVtools.Core/Operations/OperationDynamicLayerHeight.cs | 273 | ||||
-rw-r--r-- | UVtools.Core/UVtools.Core.csproj | 2 | ||||
-rw-r--r-- | UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml | 160 | ||||
-rw-r--r-- | UVtools.WPF/UVtools.WPF.csproj | 2 |
7 files changed, 344 insertions, 120 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c7c0ed5..a5bd8f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 28/08/2021 - v2.20.3 + +- **Tool - Dynamic Layer Height:** + - (Add) Option to strip anti-aliasing: Use this option if you get flashy layers or if you want to enhancement the results + - (Add) Option to reconstruct anti-aliasing: Use this option with "Strip anti-aliasing" to reconstruct the layer anti-aliasing via an gaussian blur + - (Add) Maximum wide difference: The maximum number of pixels wide difference to be able to stack layers, where one pixel difference is a whole perimeter of the object to be eroded. + 0 = Stack only equal layers + n = Stack equal layers or with a n perimeter of difference between the sum of the stack (#274) + - (Add) Allow to change the base exposure times for the auto generation (#274) + - (Add) Option to switch between: "Set the same base time for all bottoms" or "Calculate and iterate bottom exposures" + - (Add) Button to: Copy automatic table data into manual table + - (Improvement) Auto fill all layer height exposures times on manual entry + - (Fix) When "Exposure set type = Multiplier" bottom exposure is being used for normal exposure (#274) + - (Fix) Do not sum equal layers on the stack +- (Fix) Recalculate the material milliliters per layer when replacing a layer collection (#273) + ## 27/08/2021 - v2.20.2 - **(Fix) Layers:** diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs index 1399440..5d83c02 100644 --- a/UVtools.Core/Layer/Layer.cs +++ b/UVtools.Core/Layer/Layer.cs @@ -7,7 +7,6 @@ */ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Drawing; using System.Linq; using Emgu.CV; @@ -124,7 +123,7 @@ namespace UVtools.Core } } - public bool IsBottomLayer => (uint)(PositionZ / SlicerFile.LayerHeight) <= ParentLayerManager.SlicerFile.BottomLayerCount; + public bool IsBottomLayer => (uint)(PositionZ / SlicerFile.LayerHeight) <= SlicerFile.BottomLayerCount; public bool IsNormalLayer => !IsBottomLayer; /// <summary> @@ -155,7 +154,7 @@ namespace UVtools.Core { if (!RaiseAndSetIfChanged(ref _positionZ, RoundHeight(value))) return; RaisePropertyChanged(nameof(LayerHeight)); - MaterialMilliliters = 0; // Recalculate + //MaterialMilliliters = 0; // Recalculate } } @@ -415,7 +414,7 @@ namespace UVtools.Core public float MaterialMilliliters { get => _materialMilliliters; - private set + internal set { if (SlicerFile is null) return; //var globalMilliliters = SlicerFile.MaterialMilliliters - _materialMilliliters; diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs index 47a8d10..965ed40 100644 --- a/UVtools.Core/Layer/LayerManager.cs +++ b/UVtools.Core/Layer/LayerManager.cs @@ -500,7 +500,7 @@ namespace UVtools.Core var layer = this[layerIndex]; layer.Index = layerIndex; layer.ParentLayerManager = this; - + if (property != string.Empty) { if (property is null or nameof(SlicerFile.BottomLayerCount)) @@ -575,6 +575,8 @@ namespace UVtools.Core { layer.PositionZ = SlicerFile.GetHeightFromLayer(layerIndex); } + + layer.MaterialMilliliters = 0; // Recalculate this value to be sure } SlicerFile?.RebuildGCode(); diff --git a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs index 5016657..e503ab6 100644 --- a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs +++ b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs @@ -28,13 +28,51 @@ namespace UVtools.Core.Operations #region Sub Classes public sealed class Report { - public uint OldLayerCount { get; set; } - public uint NewLayerCount { get; set; } - public uint StackedLayers { get; set; } + private uint _oldLayerCount; + private uint _newLayerCount; + private uint _stackedLayers; + private float _maximumLayerHeight1; + private float _oldPrintTime; + private float _newPrintTime; + + public uint OldLayerCount + { + get => _oldLayerCount; + set => _oldLayerCount = value; + } + + public uint NewLayerCount + { + get => _newLayerCount; + set => _newLayerCount = value; + } + + public uint StackedLayers + { + get => _stackedLayers; + set => _stackedLayers = value; + } + public uint ReusedLayers => OldLayerCount - StackedLayers; - public float MaximumLayerHeight { get; set; } - public float OldPrintTime { get; set; } - public float NewPrintTime { get; set; } + + public float MaximumLayerHeight + { + get => _maximumLayerHeight1; + set => _maximumLayerHeight1 = value; + } + + public float OldPrintTime + { + get => _oldPrintTime; + set => _oldPrintTime = value; + } + + public float NewPrintTime + { + get => _newPrintTime; + set => _newPrintTime = value; + } + public double SparedPrintTime => Math.Round(OldPrintTime - NewPrintTime, 2); public double CompressionRatio => Math.Round((double)OldLayerCount / NewLayerCount * 100.0, 2); @@ -61,12 +99,17 @@ namespace UVtools.Core.Operations #region Members - //private decimal _displayWidth; - //private decimal _displayHeight; + private decimal _cacheRamSize = 1.5m; private decimal _minimumLayerHeight = 0.03m; private decimal _maximumLayerHeight = 0.10m; - private decimal _cacheRamSize = 1.5m; + private bool _stripAntiAliasing; + private bool _reconstructAntiAliasing; + private byte _maximumErodes = 10; + private ExposureSetTypes _exposureSetType = ExposureSetTypes.Linear; + private bool _iterateBottomExposureTime; + private decimal _bottomExposureTime; + private decimal _exposureTime; private decimal _bottomExposureStep = 0.5m; private decimal _exposureStep = 0.2m; private RangeObservableCollection<ExposureItem> _automaticExposureTable = new(); @@ -166,7 +209,12 @@ namespace UVtools.Core.Operations public override string ToString() { - var result = $"[Layer Height: Min: {_minimumLayerHeight}mm Max: {_maximumLayerHeight}mm] [RAM: {_cacheRamSize}Gb] [Exposure type: {_exposureSetType}, Steps: {_bottomExposureStep}s/{_exposureStep}s]" + LayerRangeString; + var result = $"[RAM: {_cacheRamSize}Gb] " + + $"[Layer Height: Min: {_minimumLayerHeight}mm Max: {_maximumLayerHeight}mm] " + + $"[Strip AA: {_stripAntiAliasing} Reconstruct AA: {_reconstructAntiAliasing}] " + + $"[Difference: {_maximumErodes}px] " + + $"[Bottom Exposure: {_bottomExposureTime}s Normal Exposure: {_exposureTime}s] " + + $"[Exposure type: {_exposureSetType}, Steps: {_bottomExposureStep}s/{_exposureStep}s]" + LayerRangeString; if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}"; return result; } @@ -189,33 +237,17 @@ namespace UVtools.Core.Operations #region Properties - /*public decimal DisplayWidth - { - get => _displayWidth; - set - { - if (!RaiseAndSetIfChanged(ref _displayWidth, Math.Round(value, 2))) return; - //RaisePropertyChanged(nameof(XYResolutionUm)); - } - } - - public decimal DisplayHeight + public decimal CacheRAMSize { - get => _displayHeight; + get => _cacheRamSize; set { - if (!RaiseAndSetIfChanged(ref _displayHeight, Math.Round(value, 2))) return; - //RaisePropertyChanged(nameof(XYResolutionUm)); + if (!RaiseAndSetIfChanged(ref _cacheRamSize, Math.Round(value, 2))) return; + RaisePropertyChanged(nameof(CacheObjectCount)); } } - public decimal XYResolutionUm => DisplayWidth > 0 || DisplayHeight > 0 ? - Math.Round(Math.Max( - DisplayWidth / SlicerFile.ResolutionX, - DisplayHeight / SlicerFile.ResolutionY - ), 3) * 1000 - : 0; - */ + public uint CacheObjectCount => (uint)(_cacheRamSize * 1000000000L / SlicerFile.Resolution.Area() / ObjectsPerCache); public decimal MinimumLayerHeight { @@ -239,16 +271,22 @@ namespace UVtools.Core.Operations } } - public uint CacheObjectCount => (uint) (_cacheRamSize * 1000000000L / SlicerFile.Resolution.Area() / ObjectsPerCache); + public bool StripAntiAliasing + { + get => _stripAntiAliasing; + set => RaiseAndSetIfChanged(ref _stripAntiAliasing, value); + } + + public bool ReconstructAntiAliasing + { + get => _reconstructAntiAliasing; + set => RaiseAndSetIfChanged(ref _reconstructAntiAliasing, value); + } - public decimal CacheRAMSize + public byte MaximumErodes { - get => _cacheRamSize; - set - { - if(!RaiseAndSetIfChanged(ref _cacheRamSize, Math.Round(value, 2))) return; - RaisePropertyChanged(nameof(CacheObjectCount)); - } + get => _maximumErodes; + set => RaiseAndSetIfChanged(ref _maximumErodes, value); } public ExposureSetTypes ExposureSetType @@ -267,6 +305,37 @@ namespace UVtools.Core.Operations public bool IsExposureSetTypeManual => _exposureSetType == ExposureSetTypes.Manual; + public bool IterateBottomExposureTime + { + get => _iterateBottomExposureTime; + set + { + if(!RaiseAndSetIfChanged(ref _iterateBottomExposureTime, value)) return; + if (!IsExposureSetTypeManual) RebuildAutoExposureTable(); + } + } + + public decimal BottomExposureTime + { + get => _bottomExposureTime; + set + { + if(!RaiseAndSetIfChanged(ref _bottomExposureTime, value)) return; + if (!IsExposureSetTypeManual) RebuildAutoExposureTable(); + } + } + + public decimal ExposureTime + { + get => _exposureTime; + set + { + if(!RaiseAndSetIfChanged(ref _exposureTime, value)) return; + if (!IsExposureSetTypeManual) RebuildAutoExposureTable(); + } + + } + public decimal BottomExposureStep { get => _bottomExposureStep; @@ -340,12 +409,12 @@ namespace UVtools.Core.Operations switch (_exposureSetType) { case ExposureSetTypes.Linear: - bottomExposure = (decimal)SlicerFile.BottomExposureTime + count * _bottomExposureStep; - exposure = (decimal)SlicerFile.ExposureTime + count * _exposureStep; + bottomExposure = _iterateBottomExposureTime ? _bottomExposureTime + count * _bottomExposureStep : _bottomExposureTime; + exposure = _exposureTime + count * _exposureStep; break; case ExposureSetTypes.Multiplier: - bottomExposure = (decimal)SlicerFile.BottomExposureTime + (decimal)SlicerFile.BottomExposureTime * count * layerHeight * _bottomExposureStep; - exposure = (decimal)SlicerFile.BottomExposureTime + (decimal)SlicerFile.ExposureTime * count * layerHeight * _exposureStep; + bottomExposure = _iterateBottomExposureTime ? _bottomExposureTime + _bottomExposureTime * count * layerHeight * _bottomExposureStep : _bottomExposureTime; + exposure = _exposureTime + _exposureTime * count * layerHeight * _exposureStep; break; case ExposureSetTypes.Manual: break; @@ -377,11 +446,6 @@ namespace UVtools.Core.Operations { base.InitWithSlicerFile(); - /*if (SlicerFile.DisplayWidth > 0) - _displayWidth = (decimal)SlicerFile.DisplayWidth; - if (SlicerFile.DisplayHeight > 0) - _displayHeight = (decimal)SlicerFile.DisplayHeight;*/ - var layerHeight = (decimal)SlicerFile.LayerHeight; if (_minimumLayerHeight < layerHeight) { @@ -391,6 +455,11 @@ namespace UVtools.Core.Operations { _maximumLayerHeight = Math.Min((decimal) FileFormat.MaximumLayerHeight, _maximumLayerHeight*2); } + if (_bottomExposureTime <= 0) + _bottomExposureTime = (decimal)SlicerFile.BottomExposureTime; + if (_exposureTime <= 0) + _exposureTime = (decimal)SlicerFile.ExposureTime; + } public void InitManualTable() @@ -399,12 +468,13 @@ namespace UVtools.Core.Operations layerHeight <= (decimal) FileFormat.MaximumLayerHeight; layerHeight += (decimal)FileFormat.MinimumLayerHeight) { - var item = new ExposureItem(layerHeight); - if (layerHeight == (decimal) SlicerFile.LayerHeight) + var item = new ExposureItem(layerHeight, _bottomExposureTime, _exposureTime); + //item.BottomExposure = _bottomExposureTime; + //item.Exposure = _exposureTime; + /*if (layerHeight == (decimal) SlicerFile.LayerHeight) { - item.BottomExposure = (decimal) SlicerFile.BottomExposureTime; - item.Exposure = (decimal) SlicerFile.ExposureTime; - } + + }*/ _manualExposureTable.Add(item); } } @@ -415,7 +485,7 @@ namespace UVtools.Core.Operations private bool Equals(OperationDynamicLayerHeight other) { - return _minimumLayerHeight == other._minimumLayerHeight && _maximumLayerHeight == other._maximumLayerHeight && _cacheRamSize == other._cacheRamSize && _exposureSetType == other._exposureSetType && _bottomExposureStep == other._bottomExposureStep && _exposureStep == other._exposureStep && Equals(_manualExposureTable, other._manualExposureTable); + return _cacheRamSize == other._cacheRamSize && _minimumLayerHeight == other._minimumLayerHeight && _maximumLayerHeight == other._maximumLayerHeight && _stripAntiAliasing == other._stripAntiAliasing && _reconstructAntiAliasing == other._reconstructAntiAliasing && _maximumErodes == other._maximumErodes && _exposureSetType == other._exposureSetType && _iterateBottomExposureTime == other._iterateBottomExposureTime && _bottomExposureTime == other._bottomExposureTime && _exposureTime == other._exposureTime && _bottomExposureStep == other._bottomExposureStep && _exposureStep == other._exposureStep && Equals(_manualExposureTable, other._manualExposureTable); } public override bool Equals(object obj) @@ -425,7 +495,21 @@ namespace UVtools.Core.Operations public override int GetHashCode() { - return HashCode.Combine(_minimumLayerHeight, _maximumLayerHeight, _cacheRamSize, (int) _exposureSetType, _bottomExposureStep, _exposureStep, _manualExposureTable); + var hashCode = new HashCode(); + hashCode.Add(_cacheRamSize); + hashCode.Add(_minimumLayerHeight); + hashCode.Add(_maximumLayerHeight); + hashCode.Add(_stripAntiAliasing); + hashCode.Add(_reconstructAntiAliasing); + hashCode.Add(_maximumErodes); + hashCode.Add((int)_exposureSetType); + hashCode.Add(_iterateBottomExposureTime); + hashCode.Add(_bottomExposureTime); + hashCode.Add(_exposureTime); + hashCode.Add(_bottomExposureStep); + hashCode.Add(_exposureStep); + hashCode.Add(_manualExposureTable); + return hashCode.ToHashCode(); } #endregion @@ -444,12 +528,12 @@ namespace UVtools.Core.Operations switch (_exposureSetType) { case ExposureSetTypes.Linear: - bottomExposure = (decimal)SlicerFile.BottomExposureTime + count * _bottomExposureStep; - exposure = (decimal)SlicerFile.ExposureTime + count * _exposureStep; + bottomExposure = _iterateBottomExposureTime ? _bottomExposureTime + count * _bottomExposureStep : _bottomExposureTime; + exposure = _exposureTime + count * _exposureStep; break; case ExposureSetTypes.Multiplier: - bottomExposure = (decimal)SlicerFile.BottomExposureTime + (decimal)SlicerFile.BottomExposureTime * count * layerHeight * _bottomExposureStep; - exposure = (decimal)SlicerFile.BottomExposureTime + (decimal)SlicerFile.ExposureTime * count * layerHeight * _exposureStep; + bottomExposure = _iterateBottomExposureTime ? _bottomExposureTime + _bottomExposureTime * count * layerHeight * _bottomExposureStep : _bottomExposureTime; + exposure = _exposureTime + _exposureTime * count * layerHeight * _exposureStep; break; case ExposureSetTypes.Manual: break; @@ -461,6 +545,13 @@ namespace UVtools.Core.Operations } } + public void CopyAutomaticTableToManual() + { + ManualExposureTable.Clear(); + ManualExposureTable.AddRange(_automaticExposureTable); + ExposureSetType = ExposureSetTypes.Manual; + } + protected override bool ExecuteInternally(OperationProgress progress) { Report report = new() @@ -481,7 +572,6 @@ namespace UVtools.Core.Operations Mat matXorSum = null; Mat matSum = null; - const byte _maximumErodes = 10; //decimal xyResolutionUm = XYResolutionUm; //const double xyRes = 35; @@ -505,7 +595,13 @@ namespace UVtools.Core.Operations matThresholdCache[layerIndex] = new Mat(); // Clean AA - CvInvoke.Threshold(matCache[layerIndex], matThresholdCache[layerIndex], 128, 255, ThresholdType.Binary); + CvInvoke.Threshold(matCache[layerIndex], matThresholdCache[layerIndex], 127, 255, ThresholdType.Binary); + + if (_stripAntiAliasing) + { + matCache[layerIndex].Dispose(); + matCache[layerIndex] = matThresholdCache[layerIndex]; + } }); } @@ -523,6 +619,11 @@ namespace UVtools.Core.Operations void AddNewLayer(Mat mat, float layerHeight) { + if (_stripAntiAliasing && _reconstructAntiAliasing) + { + CvInvoke.GaussianBlur(mat, mat, new Size(3, 3), 0); + } + report.MaximumLayerHeight = Math.Max(report.MaximumLayerHeight, layerHeight); var positionZ = GetLastPositionZ(layerHeight); var layer = new Layer((uint) layers.Count, mat, SlicerFile) @@ -536,10 +637,25 @@ namespace UVtools.Core.Operations void ReUseLayer(uint layerIndex) { - SlicerFile[layerIndex].PositionZ = GetLastPositionZ(SlicerFile.LayerHeight); - SlicerFile[layerIndex].Index = (uint) layers.Count; - SlicerFile[layerIndex].IsModified = true; - layers.Add(SlicerFile[layerIndex]); + var layer = SlicerFile[layerIndex]; + layer.PositionZ = GetLastPositionZ(SlicerFile.LayerHeight); + layer.Index = (uint) layers.Count; + layer.IsModified = true; + if (_stripAntiAliasing) + { + var (mat, matThreshold) = GetLayer(layerIndex); + if (_reconstructAntiAliasing) + { + var blurMat = new Mat(); + CvInvoke.GaussianBlur(matThreshold, blurMat, new Size(3, 3), 0); + layer.LayerMat = blurMat; + } + else + { + layer.LayerMat = matThreshold; + } + } + layers.Add(layer); } for (uint layerIndex = 0; layerIndex < LayerIndexStart; layerIndex++) // Skip layers and re-use layers @@ -567,7 +683,7 @@ namespace UVtools.Core.Operations matXorSum?.Dispose(); matXorSum = null; - while (true) + while (true) // In a stack { progress.Token.ThrowIfCancellationRequested(); progress.ProcessedItems = layerIndex; @@ -601,13 +717,15 @@ namespace UVtools.Core.Operations CvInvoke.Add(matXorSum, matXor, matXorSum); } - var currentLayerHeigthUm = currentLayerHeight * 1000.0; + //var currentLayerHeigthUm = currentLayerHeight * 1000.0; if (CvInvoke.CountNonZero(matXorSum) > 0) // Layers are different { + //byte innerErodeCount = 0; bool meetRequirement = false; - for (; erodeCount <= _maximumErodes; ) + while (erodeCount < _maximumErodes) { + //innerErodeCount++; erodeCount++; //maxErodeCount = Math.Max(maxErodeCount, erodeCount); @@ -637,6 +755,11 @@ namespace UVtools.Core.Operations Debug.WriteLine(string.Empty); break; } + + if (erodeCount > 0) // Sum only if layers are different from the stack + { + CvInvoke.Add(matSum, mat2, matSum); + } } else { @@ -645,7 +768,7 @@ namespace UVtools.Core.Operations } layerSum++; - CvInvoke.Add(matSum, mat2, matSum); + Debug.WriteLine(string.Empty); } @@ -677,6 +800,8 @@ namespace UVtools.Core.Operations SlicerFile.SuppressRebuildPropertiesWork(() => { + SlicerFile.BottomExposureTime = (float)_bottomExposureTime; + SlicerFile.ExposureTime = (float)_exposureTime; SlicerFile.LayerManager.Layers = layers.ToArray(); }, true, false); @@ -685,15 +810,15 @@ namespace UVtools.Core.Operations for (uint layerIndex = 0; layerIndex < SlicerFile.LayerCount; layerIndex++) { var layer = SlicerFile[layerIndex]; - float bottomExposure = SlicerFile.BottomExposureTime; - float exposure = SlicerFile.ExposureTime; + var bottomExposure = _bottomExposureTime; + var exposure = _exposureTime; if(exposureDictionary.TryGetValue((decimal)layer.LayerHeight, out var item)) { - bottomExposure = (float) item.BottomExposure; - exposure = (float) item.Exposure; + bottomExposure = item.BottomExposure; + exposure = item.Exposure; } - layer.ExposureTime = SlicerFile.GetBottomOrNormalValue(layer, bottomExposure, exposure); + layer.ExposureTime = (float)SlicerFile.GetBottomOrNormalValue(layer, bottomExposure, exposure); } //var layer = slicerFile.LayerManager.Layers[^1]; diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 50389f8..f388343 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, calibration, repair, conversion and manipulation</Description> - <Version>2.20.2</Version> + <Version>2.20.3</Version> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageIcon>UVtools.png</PackageIcon> <Platforms>AnyCPU;x64</Platforms> diff --git a/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml b/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml index 731d1e6..c6eb40a 100644 --- a/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml +++ b/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml @@ -7,9 +7,39 @@ <StackPanel Spacing="10"> - <Grid RowDefinitions="Auto,0,Auto,10,Auto,10,Auto,10,Auto" + <Grid RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto" ColumnDefinitions="Auto,10,150,5,Auto,20,Auto,10,150,5,Auto"> + <TextBlock Grid.Row="0" Grid.Column="0" + VerticalAlignment="Center" + ToolTip.Tip="This operation needs to run sequentially, to boost speed up, a group of layers will be cached (decoded and transformed in parallel to latter use). +
The more layers you can cache the faster it will run but more RAM is used. +
As a rule of thumb, never use less layers than CPU core count x 2 and allow some free margin or SWAP will be used and slow down the operation. +
When allocate more layers than the required, that memory will not be used and kept free." + Text="Cache RAM:"/> + + <NumericUpDown Grid.Row="0" Grid.Column="2" + VerticalAlignment="Center" + HorizontalAlignment="Stretch" + Minimum="0.5" + Maximum="128" + Increment="0.5" + FormatString="F2" + Value="{Binding Operation.CacheRAMSize}"/> + + <TextBlock Grid.Row="0" Grid.Column="4" + VerticalAlignment="Center" + Text="GB"/> + + <TextBlock Grid.Row="0" Grid.Column="6" + HorizontalAlignment="Right" + VerticalAlignment="Center" + Text="Cache layers:"/> + + <TextBlock Grid.Row="0" Grid.Column="8" + VerticalAlignment="Center" + Text="{Binding Operation.CacheObjectCount, StringFormat=±\{0\}}"/> + <TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" ToolTip.Tip="Never use less than this minimum layer height, layers will always stack at least to this height." @@ -45,57 +75,101 @@ VerticalAlignment="Center" Text="mm"/> - <TextBlock Grid.Row="4" Grid.Column="0" - VerticalAlignment="Center" - ToolTip.Tip="This operation needs to run sequentially, to boost speed up, a group of layers will be cached (decoded and transformed in parallel to latter use). -
The more layers you can cache the faster it will run but more RAM is used. -
As a rule of thumb, never use less layers than CPU core count x 2 and allow some free margin or SWAP will be used and slow down the operation. -
When allocate more layers than the required, that memory will not be used and kept free." - Text="Cache RAM:"/> - - <NumericUpDown Grid.Row="4" Grid.Column="2" - VerticalAlignment="Center" - HorizontalAlignment="Stretch" - Minimum="0.5" - Maximum="128" - Increment="0.5" - FormatString="F2" - Value="{Binding Operation.CacheRAMSize}"/> - - <TextBlock Grid.Row="4" Grid.Column="4" - VerticalAlignment="Center" - Text="GB"/> - - <TextBlock Grid.Row="4" Grid.Column="6" - HorizontalAlignment="Right" - VerticalAlignment="Center" - Text="Cache layers:"/> - - <TextBlock Grid.Row="4" Grid.Column="8" - VerticalAlignment="Center" - Text="{Binding Operation.CacheObjectCount, StringFormat=±\{0\}}"/> - + <CheckBox Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3" + VerticalAlignment="Center" + ToolTip.Tip="Use this option if you get flashy layers or if you want to enhancement the results." + Content="Strip anti-aliasing" + IsChecked="{Binding Operation.StripAntiAliasing}"/> + + <CheckBox Grid.Row="4" Grid.Column="6" Grid.ColumnSpan="3" + VerticalAlignment="Center" + ToolTip.Tip="Use this option with 'Strip anti-aliasing' to reconstruct the layer anti-aliasing via an gaussian blur." + Content="Reconstruct anti-aliasing" + IsEnabled="{Binding Operation.StripAntiAliasing}" + IsChecked="{Binding Operation.ReconstructAntiAliasing}"/> + + <TextBlock Grid.Row="6" Grid.Column="0" + VerticalAlignment="Center" + ToolTip.Tip="The maximum number of pixels wide difference to be able to stack layers, where one pixel difference is a whole perimeter of the object to be eroded. +
0 = Stack only equal layers. +
n = Stack equal layers or with a n perimeter of difference between the sum of the stack." + Text="Maximum wide difference:"/> + <NumericUpDown Grid.Row="6" Grid.Column="2" + VerticalAlignment="Center" + HorizontalAlignment="Stretch" + Minimum="0" + Maximum="30" + Increment="1" + Value="{Binding Operation.MaximumErodes}"/> + <TextBlock Grid.Row="6" Grid.Column="4" + VerticalAlignment="Center" + Text="px"/> - <TextBlock Grid.Row="6" Grid.Column="0" + <TextBlock Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" ToolTip.Tip="Linear: Current exposure + number of stacked layers * step.
 Multiplier: Current exposure * layer height * number of stacked layers * step.
 Manual: User defined exposure per layer height" Text="Exposure set type:"/> - <ComboBox Grid.Row="6" Grid.Column="2" + <ComboBox Grid.Row="8" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Items="{Binding Operation.ExposureSetTypeItems}" SelectedItem="{Binding Operation.ExposureSetType}"/> - <TextBlock Grid.Row="8" Grid.Column="0" + <ToggleSwitch Grid.Row="8" Grid.Column="6" Grid.ColumnSpan="5" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + OffContent="Set the same base time for all bottoms" + OnContent="Calculate and iterate bottom exposures" + IsChecked="{Binding Operation.IterateBottomExposureTime}"/> + + <TextBlock Grid.Row="10" Grid.Column="0" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + VerticalAlignment="Center" + Text="Bottom exposure:"/> + + <NumericUpDown Grid.Row="10" Grid.Column="2" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + VerticalAlignment="Center" + HorizontalAlignment="Stretch" + Increment="0.5" + Minimum="0.1" + Maximum="200" + FormatString="F2" + Value="{Binding Operation.BottomExposureTime}"/> + <TextBlock Grid.Row="10" Grid.Column="4" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + VerticalAlignment="Center" + Text="s"/> + + <TextBlock Grid.Row="10" Grid.Column="6" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + VerticalAlignment="Center" + HorizontalAlignment="Right" + Text="Normal exposure:"/> + + <NumericUpDown Grid.Row="10" Grid.Column="8" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + VerticalAlignment="Center" + HorizontalAlignment="Stretch" + Increment="0.5" + Minimum="0.1" + Maximum="200" + FormatString="F2" + Value="{Binding Operation.ExposureTime}"/> + <TextBlock Grid.Row="10" Grid.Column="10" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + VerticalAlignment="Center" + Text="s"/> + + <TextBlock Grid.Row="12" Grid.Column="0" IsVisible="{Binding !Operation.IsExposureSetTypeManual}" VerticalAlignment="Center" ToolTip.Tip="Bottom exposure increment per layer height" Text="Bottom exposure step:"/> - <NumericUpDown Grid.Row="8" Grid.Column="2" + <NumericUpDown Grid.Row="12" Grid.Column="2" IsVisible="{Binding !Operation.IsExposureSetTypeManual}" VerticalAlignment="Center" HorizontalAlignment="Stretch" @@ -104,19 +178,19 @@ Manual: User defined exposure per layer height" Increment="0.01" FormatString="F2" Value="{Binding Operation.BottomExposureStep}"/> - <TextBlock Grid.Row="8" Grid.Column="4" + <TextBlock Grid.Row="12" Grid.Column="4" IsVisible="{Binding !Operation.IsExposureSetTypeManual}" VerticalAlignment="Center" Text="s"/> - <TextBlock Grid.Row="8" Grid.Column="6" + <TextBlock Grid.Row="12" Grid.Column="6" IsVisible="{Binding !Operation.IsExposureSetTypeManual}" HorizontalAlignment="Right" VerticalAlignment="Center" ToolTip.Tip="Exposure increment per layer height" Text="Exposure step:"/> - <NumericUpDown Grid.Row="8" Grid.Column="8" + <NumericUpDown Grid.Row="12" Grid.Column="8" IsVisible="{Binding !Operation.IsExposureSetTypeManual}" VerticalAlignment="Center" HorizontalAlignment="Stretch" @@ -126,11 +200,19 @@ Manual: User defined exposure per layer height" FormatString="F2" Value="{Binding Operation.ExposureStep}"/> - <TextBlock Grid.Row="8" Grid.Column="10" + <TextBlock Grid.Row="12" Grid.Column="10" IsVisible="{Binding !Operation.IsExposureSetTypeManual}" VerticalAlignment="Center" Text="s"/> + <Button Grid.Row="14" Grid.Column="2" Grid.ColumnSpan="7" + IsVisible="{Binding !Operation.IsExposureSetTypeManual}" + VerticalAlignment="Center" + HorizontalAlignment="Stretch" + HorizontalContentAlignment="Center" + Content="Copy automatic table data into manual table" + Command="{Binding Operation.CopyAutomaticTableToManual}"/> + </Grid> <TextBlock Text="Exposure Table:" diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index e7dc131..e848ffb 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>2.20.2</Version> + <Version>2.20.3</Version> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |