diff --git a/CHANGELOG.md b/CHANGELOG.md index e608509..075759b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 27/04/2023 - v3.13.1 + +- (Change) `Layer.IsBottomLayer` no longer calculate the value using the position of the layer, a new property `IsBottomLayerByHeight` is now used to get that result +- (Improvement) Tool - Double exposure: Increase the bottom layer count per cloned bottom layer +- (Improvement) Calibration - Exposure time finder: Set the absolute bottom layer count accordingly when also testing for bottom time +- (Improvement) Goo: Enforce Wait times or Light-off-delay flag based on property set +- (Fix) AnyCubic and Goo: `PerLayerSetting` flag was set inverted causing printer not to follow layer settings when it should and also the otherwise (#689) +- (Fix) Tool - Scripting: Prevent from reload UI multiple times when using profiles (#694) + ## 23/04/2023 - v3.13.0 - **Benchmark tool:** diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 20e79bc..b3f4878 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,12 +1,7 @@ -- **Benchmark tool:** - - (Add) Reference machine Intel� Core� i9-13900K @ 5.5 GHz - - (Improvement) Layout and arrangement -- **Windows MSI:** - - (Improvement) Move registry keys from HKCU to HKLM - - (Improvement) Sign MSI package - - (Upgrade) Windows MSI: Wix 3 to 4 -- (Fix) SL1: Change `SupportPillarWideningFactor` from ushort to float -- (Fix) PCB exposure: Implement G02 and G03 arcs (#692) -- (Upgrade) .NET from 6.0.15 to 6.0.16 -- (Upgrade) openCV from 4.6.0 to 4.7.0 +- (Change) `Layer.IsBottomLayer` no longer calculate the value using the position of the layer, a new property `IsBottomLayerByHeight` is now used to get that result +- (Improvement) Tool - Double exposure: Increase the bottom layer count per cloned bottom layer +- (Improvement) Calibration - Exposure time finder: Set the absolute bottom layer count accordingly when also testing for bottom time +- (Improvement) Goo: Enforce Wait times or Light-off-delay flag based on property set +- (Fix) AnyCubic and Goo: `PerLayerSetting` flag was set inverted causing printer not to follow layer settings when it should and also the otherwise (#689) +- (Fix) Tool - Scripting: Prevent from reload UI multiple times when using profiles (#694) diff --git a/Scripts/010 Editor/goo.bt b/Scripts/010 Editor/goo.bt index dcb7952..9fa37b5 100644 --- a/Scripts/010 Editor/goo.bt +++ b/Scripts/010 Editor/goo.bt @@ -36,7 +36,7 @@ struct HEADER { float MachineZ ; float LayerHeight ; float ExposureTime ; - enum { WaitTime, LightOffDelay } DelayMode ; // 1: wait time mode , 0: light off delay mode + enum { LightOffDelay, WaitTime } DelayMode ; // 0: light off delay mode | 1: wait time mode float LightOffDelay ; float BottomWaitTimeAfterCure ; float BottomWaitTimeAfterLift ; diff --git a/UVtools.Core/Extensions/EmguExtensions.cs b/UVtools.Core/Extensions/EmguExtensions.cs index 74ae127..ff74211 100644 --- a/UVtools.Core/Extensions/EmguExtensions.cs +++ b/UVtools.Core/Extensions/EmguExtensions.cs @@ -415,10 +415,7 @@ public static class EmguExtensions /// Byte array public static byte[] GetBytes(this Mat mat) { - var data = new byte[mat.GetLength()]; - //Marshal.Copy(mat.DataPointer, data, 0, data.Length); - mat.CopyTo(data); - return data; + return mat.GetRawData(); } /// diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index b90730d..0092ff7 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -1474,6 +1474,12 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable public bool AllLayersAreUsingGlobalParameters => this.All(layer => layer.IsUsingGlobalParameters); + /// + /// True if there are one or more layer(s) using different settings than the global settings, otherwise false + /// Same as negated + /// + public bool UsingPerLayerSettings => !AllLayersAreUsingGlobalParameters; + /// /// True if any layer is using TSMC, otherwise false when none of layers is using TSMC /// @@ -1849,7 +1855,7 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable false; - public int Count => _layers?.Length ?? 0; + public int Count => _layers.Length; /// /// Gets or sets the layer count @@ -5554,6 +5560,21 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable= 0 && layerIndex < Count; + } + + public bool ContainsLayer(uint layerIndex) + { + return layerIndex < LayerCount; + } + + public bool ContainsLayer(Layer layer) + { + return _layers.Contains(layer); + } + public bool Contains(Layer layer) { return _layers.Contains(layer); diff --git a/UVtools.Core/FileFormats/GooFile.cs b/UVtools.Core/FileFormats/GooFile.cs index de5003f..c097386 100644 --- a/UVtools.Core/FileFormats/GooFile.cs +++ b/UVtools.Core/FileFormats/GooFile.cs @@ -32,6 +32,21 @@ public sealed class GooFile : FileFormat #endregion + #region Enums + public enum DelayModes : byte + { + /// + /// Time with motor movement + /// + LightOff = 0, + + /// + /// Absolute time to wait + /// + WaitTime = 1 + } + #endregion + #region Sub Classes public class FileHeader @@ -64,7 +79,7 @@ public sealed class GooFile : FileFormat /// /// 0: Light off delay mode | 1:Wait time mode /// - [FieldEndianness(Endianness.Big)] [FieldOrder(25)] public byte DelayMode { get; set; } = 1; + [FieldEndianness(Endianness.Big)] [FieldOrder(25)] public DelayModes DelayMode { get; set; } = DelayModes.WaitTime; [FieldEndianness(Endianness.Big)] [FieldOrder(26)] public float LightOffDelay { get; set; } [FieldEndianness(Endianness.Big)] [FieldOrder(27)] public float BottomWaitTimeAfterCure { get; set; } [FieldEndianness(Endianness.Big)] [FieldOrder(28)] public float BottomWaitTimeAfterLift { get; set; } @@ -670,13 +685,24 @@ public sealed class GooFile : FileFormat public override float LightOffDelay { get => Header.LightOffDelay; - set => base.LightOffDelay = Header.LightOffDelay = (float)Math.Round(value, 2); + set + { + base.LightOffDelay = Header.LightOffDelay = (float)Math.Round(value, 2); + if (value > 0) + { + Header.DelayMode = DelayModes.LightOff; + } + } } public override float BottomWaitTimeBeforeCure { get => base.BottomWaitTimeBeforeCure > 0 ? base.BottomWaitTimeBeforeCure : this.FirstOrDefault(layer => layer is { IsBottomLayer: true, IsDummy: false })?.WaitTimeBeforeCure ?? 0; - set => base.BottomWaitTimeBeforeCure = value; + set + { + base.BottomWaitTimeBeforeCure = value; + Header.DelayMode = DelayModes.WaitTime; + } } @@ -691,6 +717,7 @@ public sealed class GooFile : FileFormat BottomLightOffDelay = 0; LightOffDelay = 0; } + Header.DelayMode = DelayModes.WaitTime; } } @@ -703,7 +730,11 @@ public sealed class GooFile : FileFormat public override float BottomWaitTimeAfterCure { get => base.BottomWaitTimeAfterCure > 0 ? base.BottomWaitTimeAfterCure : this.FirstOrDefault(layer => layer is { IsBottomLayer: true, IsDummy: false })?.WaitTimeAfterCure ?? 0; - set => base.BottomWaitTimeAfterCure = value; + set + { + base.BottomWaitTimeAfterCure = value; + Header.DelayMode = DelayModes.WaitTime; + } } public override float WaitTimeAfterCure @@ -717,6 +748,7 @@ public sealed class GooFile : FileFormat BottomLightOffDelay = 0; LightOffDelay = 0; } + Header.DelayMode = DelayModes.WaitTime; } } @@ -777,7 +809,11 @@ public sealed class GooFile : FileFormat public override float BottomWaitTimeAfterLift { get => base.BottomWaitTimeAfterLift > 0 ? base.BottomWaitTimeAfterLift : this.FirstOrDefault(layer => layer is { IsBottomLayer: true, IsDummy: false })?.WaitTimeAfterLift ?? 0; - set => base.BottomWaitTimeAfterLift = value; + set + { + base.BottomWaitTimeAfterLift = value; + Header.DelayMode = DelayModes.WaitTime; + } } public override float WaitTimeAfterLift @@ -791,6 +827,7 @@ public sealed class GooFile : FileFormat BottomLightOffDelay = 0; LightOffDelay = 0; } + Header.DelayMode = DelayModes.WaitTime; } } @@ -963,7 +1000,7 @@ public sealed class GooFile : FileFormat protected override void OnBeforeEncode(bool isPartialEncode) { - Header.PerLayerSettings = AllLayersAreUsingGlobalParameters; + Header.PerLayerSettings = UsingPerLayerSettings; Header.Volume = Volume; Header.MaterialGrams = MaterialMilliliters; } diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs index f46f02a..3f3f1fe 100644 --- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs +++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs @@ -295,7 +295,7 @@ public sealed class PhotonWorkshopFile : FileFormat /// /// 80 /// - [FieldOrder(17)] public uint PerLayerOverride { get; set; } // bool + [FieldOrder(17)] [SerializeAs(SerializedType.UInt4)] public bool PerLayerOverride { get; set; } // bool [FieldOrder(18)] public uint PrintTime { get; set; } @@ -1292,11 +1292,9 @@ public sealed class PhotonWorkshopFile : FileFormat set => base.BottomLayerCount = (ushort) (HeaderSettings.BottomLayersCount = value); } - public override TransitionLayerTypes TransitionLayerType => TransitionLayerTypes.Firmware; - public override ushort TransitionLayerCount { - get => (ushort)(Version >= VERSION_516 ? HeaderSettings.TransitionLayerCount : 0); + get => (ushort)HeaderSettings.TransitionLayerCount; set => base.TransitionLayerCount = (ushort)(HeaderSettings.TransitionLayerCount = Math.Min(value, MaximumPossibleTransitionLayerCount)); } @@ -2036,7 +2034,7 @@ public sealed class PhotonWorkshopFile : FileFormat protected override void OnBeforeEncode(bool isPartialEncode) { - HeaderSettings.PerLayerOverride = System.Convert.ToUInt32(AllLayersAreUsingGlobalParameters); + HeaderSettings.PerLayerOverride = UsingPerLayerSettings; MachineSettings.MaxFileVersion = PrinterModel switch { AnyCubicMachine.PhotonS => VERSION_1, diff --git a/UVtools.Core/Layers/Layer.cs b/UVtools.Core/Layers/Layer.cs index 1d7d07c..a7215e1 100644 --- a/UVtools.Core/Layers/Layer.cs +++ b/UVtools.Core/Layers/Layer.cs @@ -299,29 +299,17 @@ public class Layer : BindableBase, IEquatable, IEquatable /// /// Gets if is in the bottom layer group /// - public bool IsBottomLayer + public bool IsBottomLayer => _index < SlicerFile.BottomLayerCount; + + /// + /// Gets if is in the bottom layer group by count and height + /// + public bool IsBottomLayerByHeight { get { var bottomLayers = SlicerFile.BottomLayerCount; - if (_index < bottomLayers) return true; - - // For same positioned layers - /*uint layerCount = 1; - bool nullFallback = false; - for (uint layerIndex = 1; layerIndex < _index && layerCount < bottomLayers; layerIndex++) - { - if (SlicerFile[layerIndex] is null) - { - nullFallback = true; - break; - } - if (SlicerFile[layerIndex].RelativePositionZ != 0) layerCount++; - } - - if (nullFallback) return PositionZ / SlicerFile.LayerHeight <= bottomLayers; - return layerCount <= bottomLayers;*/ - return PositionZ / SlicerFile.LayerHeight <= bottomLayers; + return _index < bottomLayers || PositionZ / SlicerFile.LayerHeight <= bottomLayers; } } diff --git a/UVtools.Core/Managers/OperationSessionManager.cs b/UVtools.Core/Managers/OperationSessionManager.cs index 787b261..4fdb439 100644 --- a/UVtools.Core/Managers/OperationSessionManager.cs +++ b/UVtools.Core/Managers/OperationSessionManager.cs @@ -33,11 +33,6 @@ public class OperationSessionManager : IList private readonly List _operations = new(); - #endregion - - #region Properties - - #endregion #region Constructor @@ -73,6 +68,7 @@ public class OperationSessionManager : IList if (item is null) return; _operations.RemoveAll(operation => operation.GetType() == item.GetType()); var operation = item.Clone(); + operation.ClearPropertyChangedListeners(); operation.ClearROIandMasks(); operation.ImportedFrom = Operation.OperationImportFrom.Session; _operations.Add(operation); @@ -112,6 +108,8 @@ public class OperationSessionManager : IList if (item is null) return; _operations.RemoveAll(operation => operation.GetType() == item.GetType()); var operation = item.Clone(); + operation.ClearPropertyChangedListeners(); + operation.ClearROIandMasks(); operation.ImportedFrom = Operation.OperationImportFrom.Session; _operations.Insert(index, operation); } diff --git a/UVtools.Core/Objects/BindableBase.cs b/UVtools.Core/Objects/BindableBase.cs index 4e3c46e..7e02085 100644 --- a/UVtools.Core/Objects/BindableBase.cs +++ b/UVtools.Core/Objects/BindableBase.cs @@ -24,10 +24,25 @@ public abstract class BindableBase : INotifyPropertyChanged public event PropertyChangedEventHandler? PropertyChanged { - add => _propertyChanged += value; + add + { + _propertyChanged -= value; + _propertyChanged += value; + } remove => _propertyChanged -= value; } + public void ClearPropertyChangedListeners() + { + _propertyChanged = null; + /*var invocationList = _propertyChanged?.GetInvocationList(); + if (invocationList is null) return; + foreach (var t in invocationList) + { + _propertyChanged -= (PropertyChangedEventHandler)t; + }*/ + } + protected bool RaiseAndSetIfChanged(ref T field, T value, [CallerMemberName] string? propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs index e805061..5958ee4 100644 --- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs +++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs @@ -1890,6 +1890,7 @@ public sealed class OperationCalibrateExposureFinder : Operation var tableGrouped = table.GroupBy(pair => new {pair.Key.LayerHeight, pair.Key.BottomExposure, pair.Key.Exposure}).Distinct(); SlicerFile.BottomLayerCount = _bottomLayers; + ushort bottomLayerCount = 0; progress.ItemCount = (uint) (SlicerFile.LayerCount * table.Count); Parallel.For(0, SlicerFile.LayerCount, CoreSettings.GetParallelOptions(progress), layerIndex => { @@ -1898,6 +1899,7 @@ public sealed class OperationCalibrateExposureFinder : Operation using var mat = layer.LayerMat; var matRoi = new Mat(mat, boundingRectangle); int layerCountOnHeight = (int)(layer.PositionZ / SlicerFile.LayerHeight); + bool isBottomLayer = layerCountOnHeight <= _bottomLayers; foreach (var group in tableGrouped) { var newLayer = layer.Clone(); @@ -1955,7 +1957,6 @@ public sealed class OperationCalibrateExposureFinder : Operation } } } - newLayer.LayerMat = newMat; parallelLayers.Add(newLayer); @@ -1969,6 +1970,7 @@ public sealed class OperationCalibrateExposureFinder : Operation progress.ResetNameAndProcessed("Optimized layers"); Layer currentLayer = layers[0]; + if (currentLayer.IsBottomLayerByHeight) bottomLayerCount++; for (var layerIndex = 1; layerIndex < layers.Count; layerIndex++) { progress.PauseOrCancelIfRequested(); @@ -1978,6 +1980,7 @@ public sealed class OperationCalibrateExposureFinder : Operation currentLayer.ExposureTime != layer.ExposureTime) // Different layers, cache and continue { currentLayer = layer; + if (currentLayer.IsBottomLayerByHeight) bottomLayerCount++; continue; } @@ -1995,6 +1998,7 @@ public sealed class OperationCalibrateExposureFinder : Operation SlicerFile.SuppressRebuildPropertiesWork(() => { + SlicerFile.BottomLayerCount = (ushort)bottomLayerCount; SlicerFile.BottomExposureTime = (float)BottomExposure; SlicerFile.ExposureTime = (float)NormalExposure; SlicerFile.Layers = layers.ToArray(); @@ -2032,7 +2036,9 @@ public sealed class OperationCalibrateExposureFinder : Operation if (brightnesses.Length == 0 || !_multipleBrightness) brightnesses = new[] { byte.MaxValue }; ExposureItem? lastExposureItem = null; - decimal lastcurrentHeight = 0; + decimal lastCurrentHeight = 0; + + ushort bottomLayerCount = 0; void AddLayer(decimal currentHeight, decimal layerHeight, decimal bottomExposure, decimal normalExposure) { @@ -2051,7 +2057,7 @@ public sealed class OperationCalibrateExposureFinder : Operation bool reUseLastLayer = lastExposureItem is not null && - lastcurrentHeight == currentHeight && + lastCurrentHeight == currentHeight && lastExposureItem.LayerHeight == layerHeight && ( (isBottomLayer && lastExposureItem.BottomExposure == bottomExposure || !isBottomLayer && lastExposureItem.Exposure == normalExposure) || @@ -2060,7 +2066,7 @@ public sealed class OperationCalibrateExposureFinder : Operation using var mat = reUseLastLayer ? newLayers[^1].LayerMat : EmguExtensions.InitMat(SlicerFile.Resolution); - lastcurrentHeight = currentHeight; + lastCurrentHeight = currentHeight; foreach (var brightness in brightnesses) { @@ -2193,8 +2199,10 @@ public sealed class OperationCalibrateExposureFinder : Operation IsModified = true }; newLayers.Add(layer); + + if (isBottomLayer) bottomLayerCount++; } - + progress++; } @@ -2229,7 +2237,7 @@ public sealed class OperationCalibrateExposureFinder : Operation SlicerFile.LayerHeight = (float)LayerHeight; SlicerFile.BottomExposureTime = (float)BottomExposure; SlicerFile.ExposureTime = (float)NormalExposure; - SlicerFile.BottomLayerCount = BottomLayers; + SlicerFile.BottomLayerCount = bottomLayerCount; SlicerFile.TransitionLayerCount = 0; SlicerFile.Layers = newLayers.ToArray(); }); diff --git a/UVtools.Core/Operations/OperationDoubleExposure.cs b/UVtools.Core/Operations/OperationDoubleExposure.cs index 21f9377..6f08ca1 100644 --- a/UVtools.Core/Operations/OperationDoubleExposure.cs +++ b/UVtools.Core/Operations/OperationDoubleExposure.cs @@ -10,6 +10,7 @@ using Emgu.CV; using Emgu.CV.CvEnum; using System; using System.Text; +using System.Threading; using System.Threading.Tasks; using UVtools.Core.Extensions; using UVtools.Core.FileFormats; @@ -281,6 +282,8 @@ public class OperationDoubleExposure : Operation layers[i] = SlicerFile[i]; } + int bottomLayers = SlicerFile.BottomLayerCount; + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.GetParallelOptions(progress), layerIndex => { progress.PauseIfRequested(); @@ -288,6 +291,11 @@ public class OperationDoubleExposure : Operation var secondLayer = firstLayer.Clone(); var isBottomLayer = firstLayer.IsBottomLayer; + if (isBottomLayer) + { + Interlocked.Increment(ref bottomLayers); + } + firstLayer.ExposureTime = (float)( isBottomLayer ? _firstBottomExposure : _firstNormalExposure); secondLayer.ExposureTime = (float)(isBottomLayer ? _secondBottomExposure : _secondNormalExposure); @@ -390,6 +398,7 @@ public class OperationDoubleExposure : Operation SlicerFile.SuppressRebuildPropertiesWork(() => { + SlicerFile.BottomLayerCount = (ushort)bottomLayers; SlicerFile.Layers = layers; }); diff --git a/UVtools.Core/Operations/OperationLayerClone.cs b/UVtools.Core/Operations/OperationLayerClone.cs index 1386d38..1669e10 100644 --- a/UVtools.Core/Operations/OperationLayerClone.cs +++ b/UVtools.Core/Operations/OperationLayerClone.cs @@ -102,11 +102,6 @@ public sealed class OperationLayerClone : Operation #region Methods - void Increment() - { - - } - protected override bool ExecuteInternally(OperationProgress progress) { uint totalClones = (LayerIndexEnd - LayerIndexStart + 1) * Clones; diff --git a/UVtools.Core/Operations/OperationScripting.cs b/UVtools.Core/Operations/OperationScripting.cs index 240e002..c5ca91b 100644 --- a/UVtools.Core/Operations/OperationScripting.cs +++ b/UVtools.Core/Operations/OperationScripting.cs @@ -20,8 +20,18 @@ namespace UVtools.Core.Operations; public sealed class OperationScripting : Operation { #region Members + private EventHandler? _onScriptReloaded; + public event EventHandler? OnScriptReload + { + add + { + _onScriptReloaded = null; + //_onScriptReloaded -= value; + _onScriptReloaded += value; + } + remove => _onScriptReloaded -= value; + } - public event EventHandler? OnScriptReload; private string? _filePath; private string? _scriptText; private ScriptState? _scriptState; @@ -75,10 +85,6 @@ public sealed class OperationScripting : Operation #endregion - #region Enums - - #endregion - #region Properties [XmlIgnore] @@ -180,7 +186,7 @@ public sealed class OperationScripting : Operation var result = _scriptState.ContinueWithAsync("ScriptInit();").Result; RaisePropertyChanged(nameof(CanExecute)); - OnScriptReload?.Invoke(this, EventArgs.Empty); + _onScriptReloaded?.Invoke(this, EventArgs.Empty); } protected override bool ExecuteInternally(OperationProgress progress) diff --git a/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs b/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs index 08b10bd..3281b2c 100644 --- a/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs +++ b/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs @@ -54,7 +54,7 @@ public sealed class SuggestionTransitionLayerCount : Suggestion var suggestedTransitionLayerCount = TransitionLayerCount; if (actualTransitionLayerCount == suggestedTransitionLayerCount) return true; - + return _applyWhen switch { SuggestionApplyWhen.OutsideLimits => actualTransitionLayerCount >= _minimumTransitionLayerCount && @@ -86,9 +86,16 @@ public sealed class SuggestionTransitionLayerCount : Suggestion var suggestedTransitionDecrementTime = SlicerFile.GetTransitionStepTimeFromLayers(suggestedTransitionLayerCount); var bottomExposureTime = SlicerFile.LastBottomLayer?.ExposureTime ?? SlicerFile.BottomExposureTime; - var exposureTime = SlicerFile.TransitionLayerCount > 0 - ? SlicerFile[SlicerFile.BottomLayerCount + SlicerFile.TransitionLayerCount - 1].ExposureTime - : SlicerFile[SlicerFile.BottomLayerCount].ExposureTime; + var exposureTime = SlicerFile.ExposureTime; + + var layerIndex = SlicerFile.TransitionLayerCount > 0 + ? SlicerFile.BottomLayerCount + SlicerFile.TransitionLayerCount + : SlicerFile.BottomLayerCount; + + if (SlicerFile.ContainsLayer(layerIndex)) + { + exposureTime = SlicerFile[layerIndex].ExposureTime; + } return IsApplied ? $"{GlobalAppliedMessage}: {bottomExposureTime}s » {(actualTransitionDecrementTime <= 0 || actualTransitionLayerCount == 0 ? string.Empty : $"[-{actualTransitionDecrementTime}s/{actualTransitionLayerCount} layers] » ")}{exposureTime}s" @@ -116,12 +123,18 @@ public sealed class SuggestionTransitionLayerCount : Suggestion var suggestedTransitionDecrementTime = SlicerFile.GetTransitionStepTimeFromLayers(suggestedTransitionLayerCount); var bottomExposureTime = SlicerFile.LastBottomLayer?.ExposureTime ?? SlicerFile.BottomExposureTime; - var exposureTime = SlicerFile.TransitionLayerCount > 0 - ? SlicerFile[SlicerFile.BottomLayerCount + SlicerFile.TransitionLayerCount - 1].ExposureTime - : SlicerFile[SlicerFile.BottomLayerCount].ExposureTime; + var exposureTime = SlicerFile.ExposureTime; - return - $"{Title}: ({bottomExposureTime}s » {(actualTransitionDecrementTime <= 0 || actualTransitionLayerCount == 0 ? string.Empty : $"[-{actualTransitionDecrementTime}s/{actualTransitionLayerCount} layers] » ")}{exposureTime}s) » ({bottomExposureTime}s » {(suggestedTransitionDecrementTime <= 0 || suggestedTransitionLayerCount == 0 ? string.Empty : $"[-{suggestedTransitionDecrementTime}s/{suggestedTransitionLayerCount} layers] » ")}{exposureTime}s)"; + var layerIndex = SlicerFile.TransitionLayerCount > 0 + ? SlicerFile.BottomLayerCount + SlicerFile.TransitionLayerCount + : SlicerFile.BottomLayerCount; + + if (SlicerFile.ContainsLayer(layerIndex)) + { + exposureTime = SlicerFile[layerIndex].ExposureTime; + } + + return $"{Title}: ({bottomExposureTime}s » {(actualTransitionDecrementTime <= 0 || actualTransitionLayerCount == 0 ? string.Empty : $"[-{actualTransitionDecrementTime}s/{actualTransitionLayerCount} layers] » ")}{exposureTime}s) » ({bottomExposureTime}s » {(suggestedTransitionDecrementTime <= 0 || suggestedTransitionLayerCount == 0 ? string.Empty : $"[-{suggestedTransitionDecrementTime}s/{suggestedTransitionLayerCount} layers] » ")}{exposureTime}s)"; } } diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index e02fa27..3f1fc14 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 - 3.13.0 + 3.13.1 Copyright © 2020 PTRTECH UVtools.png AnyCPU;x64 diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateBloomingEffectControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateBloomingEffectControl.axaml.cs index 7754b11..1b50463 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateBloomingEffectControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateBloomingEffectControl.axaml.cs @@ -48,7 +48,7 @@ namespace UVtools.WPF.Controls.Calibrators switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml.cs index f2b296c..8f41314 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml.cs @@ -48,7 +48,7 @@ public class CalibrateElephantFootControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs index 0ea85e2..02aa9aa 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs @@ -59,7 +59,7 @@ public class CalibrateExposureFinderControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateGrayscaleControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateGrayscaleControl.axaml.cs index 6007c07..bf8572b 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateGrayscaleControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateGrayscaleControl.axaml.cs @@ -48,7 +48,7 @@ public class CalibrateGrayscaleControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateLiftHeightControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateLiftHeightControl.axaml.cs index f81b15c..18c29b6 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateLiftHeightControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateLiftHeightControl.axaml.cs @@ -48,7 +48,7 @@ public class CalibrateLiftHeightControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml.cs index 22eb53d..c1a2331 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml.cs @@ -26,7 +26,7 @@ public class CalibrateStressTowerControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: break; } }*/ diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml.cs index 37f4fab..18bc91a 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml.cs @@ -60,7 +60,7 @@ public class CalibrateToleranceControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateXYZAccuracyControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateXYZAccuracyControl.axaml.cs index 726560d..4fc1cb6 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateXYZAccuracyControl.axaml.cs +++ b/UVtools.WPF/Controls/Calibrators/CalibrateXYZAccuracyControl.axaml.cs @@ -58,7 +58,7 @@ public class CalibrateXYZAccuracyControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs index 741ea8b..6246bba 100644 --- a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml.cs @@ -34,7 +34,7 @@ public class ToolCalculatorControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.CalcLightOffDelay.PropertyChanged += (sender, e) => { if (e.PropertyName != nameof(Operation.CalcLightOffDelay.LightOffDelay) && diff --git a/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs index a225499..6b2f2d1 100644 --- a/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs @@ -18,13 +18,20 @@ public class ToolControl : UserControlEx set { bool wasNullBefore = _baseOperation is null; + + if (!wasNullBefore) + { + _baseOperation.ClearPropertyChangedListeners(); + Callback(ToolWindow.Callbacks.BeforeLoadProfile); + } + _baseOperation = value; _baseOperation.SlicerFile = SlicerFile; RaisePropertyChanged(); if (!wasNullBefore) { - Callback(ToolWindow.Callbacks.Loaded); + Callback(ToolWindow.Callbacks.AfterLoadProfile); } if (DataContext is null) return; diff --git a/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml.cs index da661c0..62ae7b6 100644 --- a/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolDynamicLayerHeightControl.axaml.cs @@ -49,7 +49,7 @@ public class ToolDynamicLayerHeightControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: /*Operation.PropertyChanged += (sender, e) => { if (e.PropertyName.Equals(nameof(Operation.CacheObjectCount))) diff --git a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs index bf9d92e..83ee009 100644 --- a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs @@ -184,7 +184,7 @@ public class ToolEditParametersControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: if (callback is ToolWindow.Callbacks.Init) { ParentWindow.SelectCurrentLayer(); diff --git a/UVtools.WPF/Controls/Tools/ToolFadeExposureTimeControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolFadeExposureTimeControl.axaml.cs index 9efe8b9..e0b167b 100644 --- a/UVtools.WPF/Controls/Tools/ToolFadeExposureTimeControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolFadeExposureTimeControl.axaml.cs @@ -25,7 +25,7 @@ public partial class ToolFadeExposureTimeControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: ParentWindow.LayerIndexEnd = Operation.LayerIndexStart + Operation.LayerCount - 1; Operation.PropertyChanged += (sender, e) => { diff --git a/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml.cs index ed17629..8d64585 100644 --- a/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml.cs @@ -25,7 +25,7 @@ public class ToolLayerArithmeticControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: if(ParentWindow is not null) ParentWindow.ButtonOkEnabled = !string.IsNullOrWhiteSpace(Operation.Sentence); Operation.PropertyChanged += (sender, e) => { diff --git a/UVtools.WPF/Controls/Tools/ToolLayerCloneControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerCloneControl.axaml.cs index 352a7d5..444b402 100644 --- a/UVtools.WPF/Controls/Tools/ToolLayerCloneControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolLayerCloneControl.axaml.cs @@ -1,4 +1,5 @@ -using Avalonia.Markup.Xaml; +using System.ComponentModel; +using Avalonia.Markup.Xaml; using UVtools.Core.Layers; using UVtools.Core.Operations; using UVtools.WPF.Windows; @@ -15,7 +16,7 @@ public class ToolLayerCloneControl : ToolControl get { uint extraLayers = Operation.ExtraLayers; - return $"Layers: {App.SlicerFile.LayerCount} → {SlicerFile.LayerCount + extraLayers} (+ {extraLayers})"; + return $"Layers: {SlicerFile.LayerCount} → {SlicerFile.LayerCount + extraLayers} (+ {extraLayers})"; } } @@ -24,7 +25,7 @@ public class ToolLayerCloneControl : ToolControl get { float extraHeight = Operation.KeepSamePositionZ ? 0 : Layer.RoundHeight(Operation.ExtraLayers * SlicerFile.LayerHeight); - return $"Height: {App.SlicerFile.PrintHeight}mm → {Layer.RoundHeight(SlicerFile.PrintHeight + extraHeight)}mm (+ {extraHeight}mm)"; + return $"Height: {SlicerFile.PrintHeight}mm → {Layer.RoundHeight(SlicerFile.PrintHeight + extraHeight)}mm (+ {extraHeight}mm)"; } } @@ -45,13 +46,15 @@ public class ToolLayerCloneControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: - Operation.PropertyChanged += (sender, args) => - { - RaisePropertyChanged(nameof(InfoLayersStr)); - RaisePropertyChanged(nameof(InfoHeightsStr)); - }; + case ToolWindow.Callbacks.AfterLoadProfile: + Operation.PropertyChanged += OnPropertyChanged; break; } } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs args) + { + RaisePropertyChanged(nameof(InfoLayersStr)); + RaisePropertyChanged(nameof(InfoHeightsStr)); + } } \ No newline at end of file diff --git a/UVtools.WPF/Controls/Tools/ToolLayerImportControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerImportControl.axaml.cs index 8e92310..70a73ba 100644 --- a/UVtools.WPF/Controls/Tools/ToolLayerImportControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolLayerImportControl.axaml.cs @@ -143,7 +143,7 @@ public class ToolLayerImportControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: RefreshGUI(); Operation.Files.CollectionChanged += (sender, args) => RefreshGUI(); Operation.PropertyChanged += (sender, args) => RefreshGUI(); diff --git a/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml.cs index ff0b217..767eff2 100644 --- a/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml.cs @@ -28,7 +28,7 @@ public class ToolLayerReHeightControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: if (ParentWindow is not null) ParentWindow.LayerRangeVisible = Operation.Method == OperationLayerReHeight.OperationLayerReHeightMethod.OffsetPositionZ; Operation.PropertyChanged += (sender, e) => { diff --git a/UVtools.WPF/Controls/Tools/ToolLayerRemoveControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerRemoveControl.axaml.cs index 7e13e7b..975ceb7 100644 --- a/UVtools.WPF/Controls/Tools/ToolLayerRemoveControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolLayerRemoveControl.axaml.cs @@ -52,7 +52,7 @@ public class ToolLayerRemoveControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, args) => { RaisePropertyChanged(nameof(InfoLayersStr)); diff --git a/UVtools.WPF/Controls/Tools/ToolLithophaneControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLithophaneControl.axaml.cs index 77830e5..d67c126 100644 --- a/UVtools.WPF/Controls/Tools/ToolLithophaneControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolLithophaneControl.axaml.cs @@ -46,7 +46,7 @@ namespace UVtools.WPF.Controls.Tools switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Tools/ToolMaskControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolMaskControl.axaml.cs index ed5468c..ac3363e 100644 --- a/UVtools.WPF/Controls/Tools/ToolMaskControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolMaskControl.axaml.cs @@ -85,7 +85,7 @@ public class ToolMaskControl : ToolControl case ToolWindow.Callbacks.Init: ParentWindow.ButtonOkEnabled = false; break; - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: case ToolWindow.Callbacks.ClearROI: Operation.Mask = null; MaskImage = null; diff --git a/UVtools.WPF/Controls/Tools/ToolMoveControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolMoveControl.axaml.cs index 8e2fb3b..9af06ce 100644 --- a/UVtools.WPF/Controls/Tools/ToolMoveControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolMoveControl.axaml.cs @@ -41,7 +41,7 @@ public class ToolMoveControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.ROI = App.MainWindow.ROI.IsEmpty ? SlicerFile.BoundingRectangle : App.MainWindow.ROI; break; case ToolWindow.Callbacks.ClearROI: diff --git a/UVtools.WPF/Controls/Tools/ToolPCBExposureControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolPCBExposureControl.axaml.cs index 4d03e65..73f3bf8 100644 --- a/UVtools.WPF/Controls/Tools/ToolPCBExposureControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolPCBExposureControl.axaml.cs @@ -88,7 +88,7 @@ namespace UVtools.WPF.Controls.Tools switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.PropertyChanged += (sender, e) => { _timer.Stop(); diff --git a/UVtools.WPF/Controls/Tools/ToolPatternControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolPatternControl.axaml.cs index 095fb2e..58a79bf 100644 --- a/UVtools.WPF/Controls/Tools/ToolPatternControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolPatternControl.axaml.cs @@ -32,7 +32,7 @@ public class ToolPatternControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.ROI = App.MainWindow.ROI.IsEmpty ? SlicerFile.BoundingRectangle : App.MainWindow.ROI; Operation.PropertyChanged += (sender, e) => { diff --git a/UVtools.WPF/Controls/Tools/ToolRedrawModelControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolRedrawModelControl.axaml.cs index 392422d..ebf4436 100644 --- a/UVtools.WPF/Controls/Tools/ToolRedrawModelControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolRedrawModelControl.axaml.cs @@ -27,7 +27,7 @@ public class ToolRedrawModelControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: ParentWindow.ButtonOkEnabled = !string.IsNullOrWhiteSpace(Operation.FilePath); Operation.PropertyChanged += (sender, e) => { diff --git a/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs index f779d2e..f5ad69c 100644 --- a/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs @@ -62,7 +62,7 @@ public class ToolRepairLayersControl : ToolControl SetFromUserSettings(); Operation.IssuesDetectionConfig = App.MainWindow.GetIssuesDetectionConfiguration(); break; - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: Operation.IssuesDetectionConfig = App.MainWindow.GetIssuesDetectionConfiguration(); break; case ToolWindow.Callbacks.Checkbox1: diff --git a/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs index c7e6e48..fb55c64 100644 --- a/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs @@ -4,6 +4,9 @@ using Avalonia.Layout; using Avalonia.Markup.Xaml; using Avalonia.Threading; using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; using System.Threading.Tasks; using UVtools.Core; using UVtools.Core.Operations; @@ -41,10 +44,10 @@ public class ToolScriptingControl : ToolControl switch (callback) { case ToolWindow.Callbacks.Init: - case ToolWindow.Callbacks.Loaded: + case ToolWindow.Callbacks.AfterLoadProfile: if(ParentWindow is not null) ParentWindow.ButtonOkEnabled = Operation.CanExecute; - ReloadGUI(); - Dispatcher.UIThread.Post(ReloadScript, DispatcherPriority.Loaded); + //ReloadGUI(); + if(callback == ToolWindow.Callbacks.AfterLoadProfile) Dispatcher.UIThread.Post(ReloadScript, DispatcherPriority.Loaded); Operation.PropertyChanged += (sender, e) => { if (e.PropertyName == nameof(Operation.CanExecute)) @@ -52,11 +55,21 @@ public class ToolScriptingControl : ToolControl ParentWindow.ButtonOkEnabled = Operation.CanExecute; } }; - Operation.OnScriptReload += (sender, e) => Dispatcher.UIThread.InvokeAsync(ReloadGUI); + Operation.OnScriptReload += OnScriptReload; + break; } } + private void OnScriptReload(object sender, EventArgs e) + { + if (!ReferenceEquals(sender, Operation)) + { + return; + } + Dispatcher.UIThread.InvokeAsync(ReloadGUI); + } + public async void LoadScript() { var dialog = new OpenFileDialog diff --git a/UVtools.WPF/Controls/WindowEx.cs b/UVtools.WPF/Controls/WindowEx.cs index a50d8bf..5c87fab 100644 --- a/UVtools.WPF/Controls/WindowEx.cs +++ b/UVtools.WPF/Controls/WindowEx.cs @@ -32,7 +32,7 @@ public class WindowEx : Window, INotifyPropertyChanged, IStyleable public new event PropertyChangedEventHandler PropertyChanged { - add { _propertyChanged += value; events.Add("added"); } + add { _propertyChanged -= value; _propertyChanged += value; events.Add("added"); } remove { _propertyChanged -= value; events.Add("removed"); } } diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index a162d84..8287738 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ LICENSE https://github.com/sn4k3/UVtools Git - 3.13.0 + 3.13.1 AnyCPU;x64 UVtools.png README.md @@ -48,9 +48,9 @@ - - - + + + diff --git a/UVtools.WPF/Windows/ToolWindow.axaml.cs b/UVtools.WPF/Windows/ToolWindow.axaml.cs index ed8f289..ad60720 100644 --- a/UVtools.WPF/Windows/ToolWindow.axaml.cs +++ b/UVtools.WPF/Windows/ToolWindow.axaml.cs @@ -32,7 +32,8 @@ public class ToolWindow : WindowEx { Init, ClearROI, - Loaded, + BeforeLoadProfile, + AfterLoadProfile, Button1, // Reset to defaults Checkbox1, // Show Advanced } @@ -381,6 +382,7 @@ public class ToolWindow : WindowEx if (ToolControl is null) return; var operation = _selectedProfileItem.Clone(); operation.ProfileName = null; + operation.ClearPropertyChangedListeners(); operation.ImportedFrom = Operation.OperationImportFrom.Profile; ToolControl.BaseOperation = operation; switch (operation.LayerRangeSelection) @@ -394,7 +396,7 @@ public class ToolWindow : WindowEx break; } - //ToolControl.Callback(Callbacks.Loaded); + //ToolControl.Callback(Callbacks.AfterLoadProfile); //ToolControl.ResetDataContext(); } } @@ -425,6 +427,7 @@ public class ToolWindow : WindowEx var toAdd = ToolControl.BaseOperation.Clone(); toAdd.ProfileName = string.IsNullOrWhiteSpace(_profileText) ? null : _profileText.Trim(); + toAdd.ClearPropertyChangedListeners(); OperationProfiles.AddProfile(toAdd); Profiles.Insert(0, toAdd); diff --git a/documentation/UVtools.Core.xml b/documentation/UVtools.Core.xml index 2f1171b..8d63784 100644 --- a/documentation/UVtools.Core.xml +++ b/documentation/UVtools.Core.xml @@ -2706,6 +2706,12 @@ True if all layers are using same value parameters as global settings, otherwise false + + + True if there are one or more layer(s) using different settings than the global settings, otherwise false + Same as negated + + True if any layer is using TSMC, otherwise false when none of layers is using TSMC @@ -4008,6 +4014,16 @@ Gets the Y dimension of the preview image, in pixels. + + + Time with motor movement + + + + + Absolute time to wait + + 0: Light off delay mode | 1:Wait time mode @@ -5045,6 +5061,11 @@ Gets if is in the bottom layer group + + + Gets if is in the bottom layer group by count and height + + Gets if is in the normal layer group