From fe18398e11dc9916ae5f2907ccd401be06e4bf4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Wed, 15 Sep 2021 06:13:54 +0100 Subject: [PATCH] Layout & Overlap resin trap --- UVtools.Core/Layer/LayerManager.cs | 6 +- .../OperationCalibrateStressTower.cs | 1 - .../Operations/OperationDynamicLifts.cs | 59 ++- .../Operations/OperationRepairLayers.cs | 11 + UVtools.Core/UVtools.Core.csproj | 2 +- UVtools.WPF/Assets/Styles/Styles.xaml | 157 +++++++- .../CalibrateGrayscaleControl.axaml | 125 +++--- .../CalibrateLiftHeightControl.axaml | 59 +-- .../CalibrateStressTowerControl.axaml | 102 ++--- .../Tools/ToolDoubleExposureControl.axaml | 205 ++++------ .../Tools/ToolDynamicLayerHeightControl.axaml | 60 +-- .../Tools/ToolDynamicLiftsControl.axaml | 376 ++++++++---------- .../Tools/ToolFadeExposureTimeControl.axaml | 42 +- .../Controls/Tools/ToolInfillControl.axaml | 106 ++--- .../Tools/ToolLayerReHeightControl.axaml | 22 +- .../Controls/Tools/ToolMaskControl.axaml | 63 ++- .../Controls/Tools/ToolMoveControl.axaml | 8 +- .../Tools/ToolPixelArithmeticControl.axaml | 19 +- .../Tools/ToolRaftReliefControl.axaml | 33 +- .../Tools/ToolRaiseOnPrintFinishControl.axaml | 18 +- .../Tools/ToolRedrawModelControl.axaml | 1 + .../Tools/ToolRepairLayersControl.axaml | 139 ++++--- .../Tools/ToolRepairLayersControl.axaml.cs | 2 + .../Controls/Tools/ToolResizeControl.axaml | 10 +- .../Controls/Tools/ToolRotateControl.axaml | 3 +- .../Controls/Tools/ToolSolidifyControl.axaml | 9 +- UVtools.WPF/MainWindow.Issues.cs | 4 + UVtools.WPF/MainWindow.axaml | 222 ++++------- UVtools.WPF/UVtools.WPF.csproj | 2 +- UVtools.WPF/UserSettings.cs | 7 + .../Windows/MaterialManagerWindow.axaml | 53 ++- UVtools.WPF/Windows/SettingsWindow.axaml | 89 ++--- 32 files changed, 916 insertions(+), 1099 deletions(-) diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs index 1e7449c..3d385ce 100644 --- a/UVtools.Core/Layer/LayerManager.cs +++ b/UVtools.Core/Layer/LayerManager.cs @@ -1228,9 +1228,9 @@ namespace UVtools.Core { matCache[i] = this[i].LayerMat; matTargetCache[i] = new Mat(matCache[i], BoundingRectangle); - if (resinTrapConfig.BinaryThreshold > 0) + if (resinTrapConfig.MaximumPixelBrightnessToDrain > 0) { - CvInvoke.Threshold(matTargetCache[i], matTargetCache[i], resinTrapConfig.BinaryThreshold, byte.MaxValue, ThresholdType.Binary); + CvInvoke.Threshold(matTargetCache[i], matTargetCache[i], resinTrapConfig.MaximumPixelBrightnessToDrain, byte.MaxValue, ThresholdType.Binary); } }); } @@ -1349,7 +1349,7 @@ namespace UVtools.Core currentAirMap = null; } - for (var layerIndex = resinTraps.Length - 1; layerIndex >= resinTrapConfig.StartLayerIndex; layerIndex--) + for (int layerIndex = (int)(LayerCount - 1); layerIndex >= resinTrapConfig.StartLayerIndex; layerIndex--) { if (progress.Token.IsCancellationRequested) return result.OrderBy(issue => issue.Type).ThenBy(issue => issue.LayerIndex).ThenBy(issue => issue.Area).ToList(); diff --git a/UVtools.Core/Operations/OperationCalibrateStressTower.cs b/UVtools.Core/Operations/OperationCalibrateStressTower.cs index 9f8c8b6..de932d9 100644 --- a/UVtools.Core/Operations/OperationCalibrateStressTower.cs +++ b/UVtools.Core/Operations/OperationCalibrateStressTower.cs @@ -15,7 +15,6 @@ using Emgu.CV.CvEnum; using Emgu.CV.Structure; using UVtools.Core.Extensions; using UVtools.Core.FileFormats; -using UVtools.Core.Objects; namespace UVtools.Core.Operations { diff --git a/UVtools.Core/Operations/OperationDynamicLifts.cs b/UVtools.Core/Operations/OperationDynamicLifts.cs index ff533a4..6c0aed8 100644 --- a/UVtools.Core/Operations/OperationDynamicLifts.cs +++ b/UVtools.Core/Operations/OperationDynamicLifts.cs @@ -20,6 +20,13 @@ namespace UVtools.Core.Operations public sealed class OperationDynamicLifts : Operation { #region Enums + + public enum DynamicLiftsSetMethod : byte + { + Traditional, + FullRange + } + public enum DynamicLiftsLightOffDelaySetMode : byte { [Description("Set the light-off with an extra delay")] @@ -34,6 +41,8 @@ namespace UVtools.Core.Operations #endregion #region Members + + private DynamicLiftsSetMethod _setMethod; private float _minBottomLiftHeight; private float _maxBottomLiftHeight; private float _minLiftHeight; @@ -115,7 +124,8 @@ namespace UVtools.Core.Operations public override string ToString() { var result = - $"[Bottom height: {_minBottomLiftHeight}/{_maxBottomLiftHeight}mm]" + + $"[Method: {_setMethod}]" + + $" [Bottom height: {_minBottomLiftHeight}/{_maxBottomLiftHeight}mm]" + $" [Bottom speed: {_minBottomLiftSpeed}/{_maxBottomLiftSpeed}mm/min]" + $" [Height: {_minLiftHeight}/{_maxLiftHeight}mm]" + $" [Speed: {_minLiftSpeed}/{_maxLiftSpeed}mm/min]" + @@ -129,6 +139,12 @@ namespace UVtools.Core.Operations #region Properties + public DynamicLiftsSetMethod SetMethod + { + get => _setMethod; + set => RaiseAndSetIfChanged(ref _setMethod, value); + } + public float MinBottomLiftHeight { get => _minBottomLiftHeight; @@ -296,10 +312,10 @@ namespace UVtools.Core.Operations { } - float liftHeight; - float liftSpeed; + float liftHeight = 0; + float liftSpeed = 0; - uint max = (from layer in SlicerFile where !layer.IsBottomLayer where !layer.IsEmpty where layer.Index >= LayerIndexStart where layer.Index <= LayerIndexEnd select layer).Aggregate(0, (current, layer) => Math.Max(layer.NonZeroPixelCount, current)); + //uint max = (from layer in SlicerFile where !layer.IsBottomLayer where !layer.IsEmpty where layer.Index >= LayerIndexStart where layer.Index <= LayerIndexEnd select layer).Aggregate(0, (current, layer) => Math.Max(layer.NonZeroPixelCount, current)); for (uint layerIndex = LayerIndexStart; layerIndex <= LayerIndexEnd; layerIndex++) { @@ -316,13 +332,34 @@ namespace UVtools.Core.Operations if (layer.IsBottomLayer) { - liftHeight = (_maxBottomLiftHeight * layer.NonZeroPixelCount / maxBottomPixels).Clamp(_minBottomLiftHeight, _maxBottomLiftHeight); - liftSpeed = (_maxBottomLiftSpeed - (_maxBottomLiftSpeed * layer.NonZeroPixelCount / maxNormalPixels)).Clamp(_minBottomLiftSpeed, _maxBottomLiftSpeed); + switch (_setMethod) + { + case DynamicLiftsSetMethod.Traditional: + liftHeight = (_maxBottomLiftHeight * layer.NonZeroPixelCount / maxBottomPixels).Clamp(_minBottomLiftHeight, _maxBottomLiftHeight); + liftSpeed = (_maxBottomLiftSpeed - (_maxBottomLiftSpeed * layer.NonZeroPixelCount / maxBottomPixels)).Clamp(_minBottomLiftSpeed, _maxBottomLiftSpeed); + break; + case DynamicLiftsSetMethod.FullRange: + var pixelRatio = (layer.NonZeroPixelCount - minBottomPixels) / (float)(maxBottomPixels - minBottomPixels); // pixel_ratio is between 0 and 1 + liftHeight = (_minBottomLiftHeight + ((_maxBottomLiftHeight - _minBottomLiftHeight) * pixelRatio)).Clamp(_minBottomLiftHeight, _maxBottomLiftHeight); + liftSpeed = (_maxBottomLiftSpeed - ((_maxBottomLiftSpeed - _minBottomLiftSpeed) * pixelRatio)).Clamp(_minBottomLiftSpeed, _maxBottomLiftSpeed); + break; + } + } else { - liftHeight = (_maxLiftHeight * layer.NonZeroPixelCount / maxNormalPixels).Clamp(_minLiftHeight, _maxLiftHeight); - liftSpeed = (_maxLiftSpeed - (_maxLiftSpeed * layer.NonZeroPixelCount / maxNormalPixels)).Clamp(_minLiftSpeed, _maxLiftSpeed); + switch (_setMethod) + { + case DynamicLiftsSetMethod.Traditional: + liftHeight = (_maxLiftHeight * layer.NonZeroPixelCount / maxNormalPixels).Clamp(_minLiftHeight, _maxLiftHeight); + liftSpeed = (_maxLiftSpeed - (_maxLiftSpeed * layer.NonZeroPixelCount / maxNormalPixels)).Clamp(_minLiftSpeed, _maxLiftSpeed); + break; + case DynamicLiftsSetMethod.FullRange: + var pixelRatio = (layer.NonZeroPixelCount - minNormalPixels) / (float)(maxNormalPixels - minNormalPixels); // pixel_ratio is between 0 and 1 + liftHeight = (_minLiftHeight + ((_maxLiftHeight - _minLiftHeight) * pixelRatio)).Clamp(_minLiftHeight, _maxLiftHeight); + liftSpeed = (_maxLiftSpeed - ((_maxLiftSpeed - _minLiftSpeed) * pixelRatio)).Clamp(_minLiftSpeed, _maxLiftSpeed); + break; + } } layer.RetractHeight2 = 0; @@ -365,9 +402,10 @@ namespace UVtools.Core.Operations #region Equality + private bool Equals(OperationDynamicLifts other) { - return _minBottomLiftHeight.Equals(other._minBottomLiftHeight) && _maxBottomLiftHeight.Equals(other._maxBottomLiftHeight) && _minLiftHeight.Equals(other._minLiftHeight) && _maxLiftHeight.Equals(other._maxLiftHeight) && _minBottomLiftSpeed.Equals(other._minBottomLiftSpeed) && _maxBottomLiftSpeed.Equals(other._maxBottomLiftSpeed) && _minLiftSpeed.Equals(other._minLiftSpeed) && _maxLiftSpeed.Equals(other._maxLiftSpeed) && _lightOffDelayBottomExtraTime.Equals(other._lightOffDelayBottomExtraTime) && _lightOffDelayExtraTime.Equals(other._lightOffDelayExtraTime) && _lightOffDelaySetMode == other._lightOffDelaySetMode; + return _setMethod == other._setMethod && _minBottomLiftHeight.Equals(other._minBottomLiftHeight) && _maxBottomLiftHeight.Equals(other._maxBottomLiftHeight) && _minLiftHeight.Equals(other._minLiftHeight) && _maxLiftHeight.Equals(other._maxLiftHeight) && _minBottomLiftSpeed.Equals(other._minBottomLiftSpeed) && _maxBottomLiftSpeed.Equals(other._maxBottomLiftSpeed) && _minLiftSpeed.Equals(other._minLiftSpeed) && _maxLiftSpeed.Equals(other._maxLiftSpeed) && _lightOffDelayBottomExtraTime.Equals(other._lightOffDelayBottomExtraTime) && _lightOffDelayExtraTime.Equals(other._lightOffDelayExtraTime) && _lightOffDelaySetMode == other._lightOffDelaySetMode; } public override bool Equals(object obj) @@ -378,6 +416,7 @@ namespace UVtools.Core.Operations public override int GetHashCode() { var hashCode = new HashCode(); + hashCode.Add((int)_setMethod); hashCode.Add(_minBottomLiftHeight); hashCode.Add(_maxBottomLiftHeight); hashCode.Add(_minLiftHeight); @@ -388,7 +427,7 @@ namespace UVtools.Core.Operations hashCode.Add(_maxLiftSpeed); hashCode.Add(_lightOffDelayBottomExtraTime); hashCode.Add(_lightOffDelayExtraTime); - hashCode.Add((int) _lightOffDelaySetMode); + hashCode.Add((int)_lightOffDelaySetMode); return hashCode.ToHashCode(); } diff --git a/UVtools.Core/Operations/OperationRepairLayers.cs b/UVtools.Core/Operations/OperationRepairLayers.cs index 425e1f2..1ed7331 100644 --- a/UVtools.Core/Operations/OperationRepairLayers.cs +++ b/UVtools.Core/Operations/OperationRepairLayers.cs @@ -34,6 +34,7 @@ namespace UVtools.Core.Operations private ushort _removeIslandsBelowEqualPixelCount = 5; private ushort _removeIslandsRecursiveIterations = 4; private ushort _attachIslandsBelowLayers = 2; + private byte _resinTrapsOverlapBy = 5; private uint _gapClosingIterations = 1; private uint _noiseRemovalIterations; @@ -111,6 +112,12 @@ namespace UVtools.Core.Operations set => RaiseAndSetIfChanged(ref _attachIslandsBelowLayers, value); } + public byte ResinTrapsOverlapBy + { + get => _resinTrapsOverlapBy; + set => RaiseAndSetIfChanged(ref _resinTrapsOverlapBy, value); + } + public uint GapClosingIterations { get => _gapClosingIterations; @@ -360,6 +367,10 @@ namespace UVtools.Core.Operations initImage(); using var vec = new VectorOfVectorOfPoint(issue.Contours); CvInvoke.DrawContours(image, vec, -1, EmguExtensions.WhiteColor, -1); + if (_resinTrapsOverlapBy > 0) + { + CvInvoke.DrawContours(image, vec, -1, EmguExtensions.WhiteColor, _resinTrapsOverlapBy * 2 + 1); + } } } } diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index bf80391..a92cb12 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -10,7 +10,7 @@ https://github.com/sn4k3/UVtools https://github.com/sn4k3/UVtools MSLA/DLP, file analysis, calibration, repair, conversion and manipulation - 2.21.2 + 2.22.0 Copyright © 2020 PTRTECH UVtools.png AnyCPU;x64 diff --git a/UVtools.WPF/Assets/Styles/Styles.xaml b/UVtools.WPF/Assets/Styles/Styles.xaml index a513a8a..6cddcb1 100644 --- a/UVtools.WPF/Assets/Styles/Styles.xaml +++ b/UVtools.WPF/Assets/Styles/Styles.xaml @@ -29,14 +29,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +