From f1dea71c601ccb6472cb32480d6bc57572d03809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Wed, 17 Feb 2021 05:26:53 +0000 Subject: v2.4.7 * (Add) Computed used material milliliters for each layer, it will dynamic change if pixels are added or subtracted * (Add) Computed used material milliliters for whole model, it will dynamic change if pixels are added or subtracted * (Improvement) Round cost, material ml and grams from 2 to 3 decimals * (Improvement) Operation profiles: Allow to save and get a custom layer range instead of pre-defined ranges * **(Improvement)** PhotonWorkshop files: (#149) * Fill in the display width, height and MaxZ values for the printers * Fill in the xy pixel size values for the printers * Change ResinType to PriceCurrencyDec and Add PriceCurrencySymbol * Change Offset1 on header to PrintTime * Change Offset1 on layer table as NonZeroPixelCount, the number of white pixels on the layer * Fix LayerPositionZ to calculate the correct value based on each layer height and fix internal layer layer height which was been set to position z * Force PerLayerOverride to be always 1 after save the file * (Fix) Actions - Remove and clone layers was selecting all layer range instead of the current layer * (Fix) Redo last action was not getting back the layer range on some cases --- CHANGELOG.md | 17 ++ CREDITS.md | 3 +- CreateRelease.WPF.ps1 | 2 +- UVtools.Core/Extensions/DrawingExtensions.cs | 15 -- UVtools.Core/Extensions/SizeExtensions.cs | 31 +++ UVtools.Core/FileFormats/CWSFile.cs | 1 - UVtools.Core/FileFormats/ChituboxFile.cs | 17 +- UVtools.Core/FileFormats/ChituboxZipFile.cs | 21 +- UVtools.Core/FileFormats/FDGFile.cs | 19 +- UVtools.Core/FileFormats/FileFormat.cs | 98 +++++--- UVtools.Core/FileFormats/PHZFile.cs | 19 +- UVtools.Core/FileFormats/PhotonSFile.cs | 17 +- UVtools.Core/FileFormats/PhotonWorkshopFile.cs | 251 +++++++++++++++++---- UVtools.Core/FileFormats/SL1File.cs | 17 +- UVtools.Core/FileFormats/ZCodexFile.cs | 15 +- UVtools.Core/Layer/Layer.cs | 22 +- UVtools.Core/Layer/LayerManager.cs | 4 +- UVtools.Core/Operations/Operation.cs | 10 + .../Operations/OperationDynamicLayerHeight.cs | 2 +- UVtools.Core/Operations/OperationSolidify.cs | 4 +- UVtools.Core/UVtools.Core.csproj | 2 +- UVtools.WPF/Controls/Tools/ToolControl.axaml.cs | 4 +- UVtools.WPF/MainWindow.Information.cs | 33 +-- UVtools.WPF/MainWindow.LayerPreview.cs | 4 +- UVtools.WPF/UVtools.WPF.csproj | 2 +- UVtools.WPF/Windows/ToolWindow.axaml.cs | 24 +- 26 files changed, 479 insertions(+), 175 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f1166..f8716ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 17/02/2021 - v2.4.7 + +* (Add) Computed used material milliliters for each layer, it will dynamic change if pixels are added or subtracted +* (Add) Computed used material milliliters for whole model, it will dynamic change if pixels are added or subtracted +* (Improvement) Round cost, material ml and grams from 2 to 3 decimals +* (Improvement) Operation profiles: Allow to save and get a custom layer range instead of pre-defined ranges +* **(Improvement)** PhotonWorkshop files: (#149) + * Fill in the display width, height and MaxZ values for the printers + * Fill in the xy pixel size values for the printers + * Change ResinType to PriceCurrencyDec and Add PriceCurrencySymbol + * Change Offset1 on header to PrintTime + * Change Offset1 on layer table as NonZeroPixelCount, the number of white pixels on the layer + * Fix LayerPositionZ to calculate the correct value based on each layer height and fix internal layer layer height which was been set to position z + * Force PerLayerOverride to be always 1 after save the file +* (Fix) Actions - Remove and clone layers was selecting all layer range instead of the current layer +* (Fix) Redo last action was not getting back the layer range on some cases + ## 15/02/2021 - v2.4.6 * **(Improvement) Calibration - Elephant Foot:** (#145) diff --git a/CREDITS.md b/CREDITS.md index 3fdba55..3cb1d24 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -47,4 +47,5 @@ * Chris Taatgen * Andrew Griffiths * Abhinav Sinha -* Randy Savell \ No newline at end of file +* Randy Savell +* Steve Clynes \ No newline at end of file diff --git a/CreateRelease.WPF.ps1 b/CreateRelease.WPF.ps1 index ded2d46..5e324f0 100644 --- a/CreateRelease.WPF.ps1 +++ b/CreateRelease.WPF.ps1 @@ -29,7 +29,7 @@ class FixedEncoder : System.Text.UTF8Encoding { #################################### ### Configuration ### #################################### -$enableMSI = $false +$enableMSI = $true $buildOnly = $null #$buildOnly = "osx-x64"#"win-x64" # Profilling diff --git a/UVtools.Core/Extensions/DrawingExtensions.cs b/UVtools.Core/Extensions/DrawingExtensions.cs index 33406a5..f98529c 100644 --- a/UVtools.Core/Extensions/DrawingExtensions.cs +++ b/UVtools.Core/Extensions/DrawingExtensions.cs @@ -20,20 +20,5 @@ namespace UVtools.Core.Extensions Math.Min(Math.Max(min, color.B * factor), max)); return Color.FromArgb(r, g, b); } - - public static int GetArea(this Rectangle rect) - { - return rect.Width * rect.Height; - } - - public static int GetArea(this Size size) - { - return size.Width * size.Height; - } - - public static int GetMaximum(this Size size) - { - return Math.Max(size.Width, size.Height); - } } } diff --git a/UVtools.Core/Extensions/SizeExtensions.cs b/UVtools.Core/Extensions/SizeExtensions.cs index 455dfee..3f7f5a4 100644 --- a/UVtools.Core/Extensions/SizeExtensions.cs +++ b/UVtools.Core/Extensions/SizeExtensions.cs @@ -38,5 +38,36 @@ namespace UVtools.Core.Extensions public static Size Inflate(this Size size, int pixels) => new (size.Width + pixels, size.Height + pixels); public static Size Inflate(this Size size, int width, int height) => new (size.Width + width, size.Height + height); + + public static int Area(this Rectangle rect) + { + return rect.Width * rect.Height; + } + + public static int Area(this Size size) + { + return size.Width * size.Height; + } + + public static int Max(this Size size) + { + return Math.Max(size.Width, size.Height); + } + + public static float Area(this RectangleF rect) + { + return rect.Width * rect.Height; + } + + public static float Area(this SizeF size) + { + return size.Width * size.Height; + } + + public static float Max(this SizeF size) + { + return Math.Max(size.Width, size.Height); + } + } } diff --git a/UVtools.Core/FileFormats/CWSFile.cs b/UVtools.Core/FileFormats/CWSFile.cs index 2312168..896a1c3 100644 --- a/UVtools.Core/FileFormats/CWSFile.cs +++ b/UVtools.Core/FileFormats/CWSFile.cs @@ -9,7 +9,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs index d854ebb..9261a1d 100644 --- a/UVtools.Core/FileFormats/ChituboxFile.cs +++ b/UVtools.Core/FileFormats/ChituboxFile.cs @@ -1270,11 +1270,16 @@ namespace UVtools.Core.FileFormats public override float MaterialMilliliters { - get => (float) Math.Round(PrintParametersSettings.VolumeMl, 2); + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : PrintParametersSettings.VolumeMl; + } set { - PrintParametersSettings.VolumeMl = (float) Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + PrintParametersSettings.VolumeMl = (float) Math.Round(value, 3); + base.MaterialMilliliters = PrintParametersSettings.VolumeMl; } } @@ -1283,17 +1288,17 @@ namespace UVtools.Core.FileFormats get => PrintParametersSettings.WeightG; set { - PrintParametersSettings.WeightG = (float)Math.Round(value, 2); + PrintParametersSettings.WeightG = (float)Math.Round(value, 3); RaisePropertyChanged(); } } public override float MaterialCost { - get => (float) Math.Round(PrintParametersSettings.CostDollars, 2); + get => (float) Math.Round(PrintParametersSettings.CostDollars, 3); set { - PrintParametersSettings.CostDollars = (float) Math.Round(value, 2); + PrintParametersSettings.CostDollars = (float) Math.Round(value, 3); RaisePropertyChanged(); } } diff --git a/UVtools.Core/FileFormats/ChituboxZipFile.cs b/UVtools.Core/FileFormats/ChituboxZipFile.cs index fc011a0..81f4eaf 100644 --- a/UVtools.Core/FileFormats/ChituboxZipFile.cs +++ b/UVtools.Core/FileFormats/ChituboxZipFile.cs @@ -53,7 +53,7 @@ namespace UVtools.Core.FileFormats [DisplayName("fileName")] public string Filename { get; set; } = string.Empty; [DisplayName("machineType")] public string MachineType { get; set; } = "Default"; [DisplayName("estimatedPrintTime")] public float EstimatedPrintTime { get; set; } - [DisplayName("volume")] public float Volume { get; set; } + [DisplayName("volume")] public float VolumeMl { get; set; } [DisplayName("resin")] public string Resin { get; set; } = "Normal"; [DisplayName("weight")] public float WeightG { get; set; } [DisplayName("price")] public float Price { get; set; } @@ -344,30 +344,35 @@ namespace UVtools.Core.FileFormats public override float MaterialMilliliters { - get => HeaderSettings.Volume; + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : HeaderSettings.VolumeMl; + } set { - HeaderSettings.Volume = (float)Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + HeaderSettings.VolumeMl = (float)Math.Round(value, 3); + base.MaterialMilliliters = HeaderSettings.VolumeMl; } } public override float MaterialGrams { - get => HeaderSettings.WeightG; + get => (float) Math.Round(HeaderSettings.WeightG, 3); set { - HeaderSettings.WeightG = (float)Math.Round(value, 2); + HeaderSettings.WeightG = (float)Math.Round(value, 3); RaisePropertyChanged(); } } public override float MaterialCost { - get => HeaderSettings.Price; + get => (float) Math.Round(HeaderSettings.Price, 3); set { - HeaderSettings.Price = (float)Math.Round(value, 2); + HeaderSettings.Price = (float)Math.Round(value, 3); RaisePropertyChanged(); } } diff --git a/UVtools.Core/FileFormats/FDGFile.cs b/UVtools.Core/FileFormats/FDGFile.cs index 53d5bd1..8a3971b 100644 --- a/UVtools.Core/FileFormats/FDGFile.cs +++ b/UVtools.Core/FileFormats/FDGFile.cs @@ -935,30 +935,35 @@ namespace UVtools.Core.FileFormats public override float MaterialMilliliters { - get => (float) Math.Round(HeaderSettings.VolumeMl, 2); + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : HeaderSettings.VolumeMl; + } set { - HeaderSettings.VolumeMl = (float)Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + HeaderSettings.VolumeMl = (float)Math.Round(value, 3); + base.MaterialMilliliters = HeaderSettings.VolumeMl; } } public override float MaterialGrams { - get => HeaderSettings.WeightG; + get => (float)Math.Round(HeaderSettings.WeightG, 3); set { - HeaderSettings.WeightG = (float)Math.Round(value, 2); + HeaderSettings.WeightG = (float)Math.Round(value, 3); RaisePropertyChanged(); } } public override float MaterialCost { - get => (float) Math.Round(HeaderSettings.CostDollars, 2); + get => (float) Math.Round(HeaderSettings.CostDollars, 3); set { - HeaderSettings.CostDollars = (float)Math.Round(value, 2); + HeaderSettings.CostDollars = (float)Math.Round(value, 3); RaisePropertyChanged(); } } diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 69cb349..1fca133 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -456,6 +456,16 @@ namespace UVtools.Core.FileFormats { LayerCount = _layerManager.Count; } + + // Recalculate changes + PrintHeight = PrintHeight; + PrintTime = PrintTimeComputed; + MaterialMilliliters = 0; + + if (SuppressRebuildProperties) return; + if (LayerCount == 0 || this[LayerCount - 1] is null) return; // Not initialized + LayerManager.RebuildLayersProperties(); + RebuildGCode(); } } @@ -574,26 +584,55 @@ namespace UVtools.Core.FileFormats } } + /// + /// Gets the pixel width in millimeters + /// + public float PixelWidth => DisplayWidth > 0 ? (float) Math.Round(DisplayWidth / ResolutionX, 3) : 0; + + /// + /// Gets the pixel height in millimeters + /// + public float PixelHeight => DisplayHeight > 0 ? (float) Math.Round(DisplayHeight / ResolutionY, 3) : 0; + + /// + /// Gets the pixel size in millimeters + /// + public SizeF PixelSize => new(PixelWidth, PixelHeight); + + /// + /// Gets the maximum pixel between width and height in millimeters + /// + public float PixelSizeMax => PixelSize.Max(); + + /// + /// Gets the pixel area in millimeters + /// + public float PixelArea => PixelSize.Area(); + + /// + /// Gets the pixel width in microns + /// + public float PixelWidthMicrons => DisplayWidth > 0 ? (float)Math.Round(DisplayWidth / ResolutionX * 1000, 3) : 0; /// - /// Gets the printer XY pixel resolution + /// Gets the pixel height in microns /// - public decimal XYResolution => DisplayWidth > 0 || DisplayHeight > 0 ? - (decimal) Math.Round(Math.Max( - DisplayWidth / ResolutionX, - DisplayHeight / ResolutionY - ), 3) - : 0; + public float PixelHeightMicrons => DisplayHeight > 0 ? (float)Math.Round(DisplayHeight / ResolutionY * 1000, 3) : 0; /// - /// Gets the printer XY pixel resolution in microns + /// Gets the pixel size in microns /// - public decimal XYResolutionUm => DisplayWidth > 0 || DisplayHeight > 0 ? - (decimal)Math.Round(Math.Max( - DisplayWidth / ResolutionX, - DisplayHeight / ResolutionY - ), 3) * 1000 - : 0; + public SizeF PixelSizeMicrons => new(PixelWidthMicrons, PixelHeightMicrons); + + /// + /// Gets the maximum pixel between width and height in microns + /// + public float PixelSizeMicronsMax => PixelSizeMicrons.Max(); + + /// + /// Gets the pixel area in millimeters + /// + public float PixelAreaMicrons => PixelSizeMicrons.Area(); /// /// Checks if this file have AntiAliasing @@ -796,7 +835,19 @@ namespace UVtools.Core.FileFormats /// /// Gets the estimate used material in ml /// - public virtual float MaterialMilliliters { get; set; } + public virtual float MaterialMilliliters { + get + { + float pixelArea = PixelArea; + float materialMl = 0; + if (pixelArea <= 0) return materialMl; + + materialMl = this.Where(layer => layer is not null).Sum(layer => pixelArea * LayerHeight * layer.NonZeroPixelCount); + + return (float) Math.Round(materialMl / 1000, 3); + } + set => RaisePropertyChanged(); + } /// /// Gets the estimate material in grams @@ -853,20 +904,7 @@ namespace UVtools.Core.FileFormats private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { - if (e.PropertyName == nameof(LayerCount)) - { - PrintHeight = PrintHeight; - } - if (SuppressRebuildProperties) return; - if (e.PropertyName == nameof(LayerCount)) - { - if (LayerCount == 0 || this[LayerCount - 1] is null) return; // Not initialized - LayerManager.RebuildLayersProperties(); - RebuildGCode(); - PrintTime = PrintTimeComputed; - return; - } if ( e.PropertyName == nameof(BottomLayerCount) || e.PropertyName == nameof(BottomExposureTime) || @@ -1048,11 +1086,11 @@ namespace UVtools.Core.FileFormats default: if (largest) { - return Thumbnails[0].Size.GetArea() >= Thumbnails[1].Size.GetArea() ? Thumbnails[0] : Thumbnails[1]; + return Thumbnails[0].Size.Area() >= Thumbnails[1].Size.Area() ? Thumbnails[0] : Thumbnails[1]; } else { - return Thumbnails[0].Size.GetArea() <= Thumbnails[1].Size.GetArea() ? Thumbnails[0] : Thumbnails[1]; + return Thumbnails[0].Size.Area() <= Thumbnails[1].Size.Area() ? Thumbnails[0] : Thumbnails[1]; } } } diff --git a/UVtools.Core/FileFormats/PHZFile.cs b/UVtools.Core/FileFormats/PHZFile.cs index 76b45ea..073bead 100644 --- a/UVtools.Core/FileFormats/PHZFile.cs +++ b/UVtools.Core/FileFormats/PHZFile.cs @@ -953,30 +953,35 @@ namespace UVtools.Core.FileFormats public override float MaterialMilliliters { - get => (float) Math.Round(HeaderSettings.VolumeMl, 2); + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : HeaderSettings.VolumeMl; + } set { - HeaderSettings.VolumeMl = (float)Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + HeaderSettings.VolumeMl = (float)Math.Round(value, 3); + base.MaterialMilliliters = HeaderSettings.VolumeMl; } } public override float MaterialGrams { - get => HeaderSettings.WeightG; + get => (float) Math.Round(HeaderSettings.WeightG, 3); set { - HeaderSettings.WeightG = (float) Math.Round(value, 2); + HeaderSettings.WeightG = (float) Math.Round(value, 3); RaisePropertyChanged(); } } public override float MaterialCost { - get => (float) Math.Round(HeaderSettings.CostDollars, 2); + get => (float) Math.Round(HeaderSettings.CostDollars, 3); set { - HeaderSettings.CostDollars = (float)Math.Round(value, 2); + HeaderSettings.CostDollars = (float)Math.Round(value, 3); RaisePropertyChanged(); } } diff --git a/UVtools.Core/FileFormats/PhotonSFile.cs b/UVtools.Core/FileFormats/PhotonSFile.cs index c36ec5f..d4feba8 100644 --- a/UVtools.Core/FileFormats/PhotonSFile.cs +++ b/UVtools.Core/FileFormats/PhotonSFile.cs @@ -54,7 +54,7 @@ namespace UVtools.Core.FileFormats [FieldOrder(8)] [FieldEndianness(Endianness.Big)] public double LiftHeight { get; set; } // mm [FieldOrder(9)] [FieldEndianness(Endianness.Big)] public double LiftSpeed { get; set; } // mm/s [FieldOrder(10)] [FieldEndianness(Endianness.Big)] public double RetractSpeed { get; set; } // mm/s - [FieldOrder(11)] [FieldEndianness(Endianness.Big)] public double Volume { get; set; } // ml + [FieldOrder(11)] [FieldEndianness(Endianness.Big)] public double VolumeMl { get; set; } // ml [FieldOrder(12)] [FieldEndianness(Endianness.Big)] public uint PreviewResolutionX { get; set; } = 225; [FieldOrder(13)] [FieldEndianness(Endianness.Big)] public uint Unknown2 { get; set; } = 42; [FieldOrder(14)] [FieldEndianness(Endianness.Big)] public uint PreviewResolutionY { get; set; } = 168; @@ -62,7 +62,7 @@ namespace UVtools.Core.FileFormats public override string ToString() { - return $"{nameof(Tag1)}: {Tag1}, {nameof(Tag2)}: {Tag2}, {nameof(XYPixelSize)}: {XYPixelSize}, {nameof(LayerHeight)}: {LayerHeight}, {nameof(ExposureSeconds)}: {ExposureSeconds}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(BottomExposureSeconds)}: {BottomExposureSeconds}, {nameof(BottomLayerCount)}: {BottomLayerCount}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(Volume)}: {Volume}, {nameof(PreviewResolutionX)}: {PreviewResolutionX}, {nameof(Unknown2)}: {Unknown2}, {nameof(PreviewResolutionY)}: {PreviewResolutionY}, {nameof(Unknown4)}: {Unknown4}"; + return $"{nameof(Tag1)}: {Tag1}, {nameof(Tag2)}: {Tag2}, {nameof(XYPixelSize)}: {XYPixelSize}, {nameof(LayerHeight)}: {LayerHeight}, {nameof(ExposureSeconds)}: {ExposureSeconds}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(BottomExposureSeconds)}: {BottomExposureSeconds}, {nameof(BottomLayerCount)}: {BottomLayerCount}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(VolumeMl)}: {VolumeMl}, {nameof(PreviewResolutionX)}: {PreviewResolutionX}, {nameof(Unknown2)}: {Unknown2}, {nameof(PreviewResolutionY)}: {PreviewResolutionY}, {nameof(Unknown4)}: {Unknown4}"; } } @@ -373,11 +373,16 @@ namespace UVtools.Core.FileFormats public override float MaterialMilliliters { - get => (float) HeaderSettings.Volume; + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : (float) HeaderSettings.VolumeMl; + } set { - HeaderSettings.Volume = Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + HeaderSettings.VolumeMl = (float)Math.Round(value, 3); + base.MaterialMilliliters = (float) HeaderSettings.VolumeMl; } } @@ -503,7 +508,7 @@ namespace UVtools.Core.FileFormats } HeaderSettings.LayerHeight = Math.Round(HeaderSettings.LayerHeight, 2); - HeaderSettings.Volume = Math.Round(HeaderSettings.Volume, 2); + HeaderSettings.VolumeMl = Math.Round(HeaderSettings.VolumeMl, 2); int previewSize = (int) (HeaderSettings.PreviewResolutionX * HeaderSettings.PreviewResolutionY * 2); byte[] previewData = new byte[previewSize]; diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs index 5447c13..aa32532 100644 --- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs +++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs @@ -71,6 +71,16 @@ namespace UVtools.Core.FileFormats PWS, PW0 } + + public enum AnyCubicMachine : byte + { + AnyCubicPhotonS, + AnyCubicPhotonZero, + AnyCubicPhotonX, + AnyCubicPhotonMono, + AnyCubicPhotonMonoSE, + AnyCubicPhotonMonoX, + } #endregion #region Sub Classes @@ -198,7 +208,7 @@ namespace UVtools.Core.FileFormats public const string SectionMark = "HEADER"; [FieldOrder(0)] public SectionHeader Section { get; set; } - [FieldOrder(1)] public float PixelSize { get; set; } = 0.04725f; + [FieldOrder(1)] public float PixelSizeUm { get; set; } = 47.25f; [FieldOrder(2)] public float LayerHeight { get; set; } [FieldOrder(3)] public float LayerExposureTime { get; set; } [FieldOrder(4)] public float LightOffDelay { get; set; } = 1; @@ -214,24 +224,25 @@ namespace UVtools.Core.FileFormats /// Gets the retract speed in mm/s /// [FieldOrder(9)] public float RetractSpeed { get; set; } = 3; // mm/s - [FieldOrder(10)] public float Volume { get; set; } + [FieldOrder(10)] public float VolumeMl { get; set; } [FieldOrder(11)] public uint AntiAliasing { get; set; } = 1; [FieldOrder(12)] public uint ResolutionX { get; set; } [FieldOrder(13)] public uint ResolutionY { get; set; } [FieldOrder(14)] public float WeightG { get; set; } [FieldOrder(15)] public float Price { get; set; } - [FieldOrder(16)] public uint ResinType { get; set; } // 0x24 ? + [FieldOrder(16)] public uint PriceCurrencyDec { get; set; } // 0x24 $ or ¥ 0xC2A5 + [Ignore] public string PriceCurrencySymbol => char.ConvertFromUtf32((int) PriceCurrencyDec); [FieldOrder(17)] public uint PerLayerOverride { get; set; } = 1; // bool - [FieldOrder(18)] public uint Offset1 { get; set; } - [FieldOrder(19)] public uint Offset2 { get; set; } - [FieldOrder(20)] public uint Offset3 { get; set; } + [FieldOrder(18)] public uint PrintTime { get; set; } + [FieldOrder(19)] public uint Offset1 { get; set; } + [FieldOrder(20)] public uint Offset2 { get; set; } public Header() { Section = new SectionHeader(SectionMark, this); } - public override string ToString() => $"{nameof(Section)}: {Section}, {nameof(PixelSize)}: {PixelSize}, {nameof(LayerHeight)}: {LayerHeight}, {nameof(LayerExposureTime)}: {LayerExposureTime}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(BottomExposureSeconds)}: {BottomExposureSeconds}, {nameof(BottomLayersCount)}: {BottomLayersCount}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(Volume)}: {Volume}, {nameof(AntiAliasing)}: {AntiAliasing}, {nameof(ResolutionX)}: {ResolutionX}, {nameof(ResolutionY)}: {ResolutionY}, {nameof(WeightG)}: {WeightG}, {nameof(Price)}: {Price}, {nameof(ResinType)}: {ResinType}, {nameof(PerLayerOverride)}: {PerLayerOverride}, {nameof(Offset1)}: {Offset1}, {nameof(Offset2)}: {Offset2}, {nameof(Offset3)}: {Offset3}"; + public override string ToString() => $"{nameof(Section)}: {Section}, {nameof(PixelSizeUm)}: {PixelSizeUm}, {nameof(LayerHeight)}: {LayerHeight}, {nameof(LayerExposureTime)}: {LayerExposureTime}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(BottomExposureSeconds)}: {BottomExposureSeconds}, {nameof(BottomLayersCount)}: {BottomLayersCount}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(VolumeMl)}: {VolumeMl}, {nameof(AntiAliasing)}: {AntiAliasing}, {nameof(ResolutionX)}: {ResolutionX}, {nameof(ResolutionY)}: {ResolutionY}, {nameof(WeightG)}: {WeightG}, {nameof(Price)}: {Price}, {nameof(PriceCurrencyDec)}: {PriceCurrencyDec}, {nameof(PerLayerOverride)}: {PerLayerOverride}, {nameof(PrintTime)}: {PrintTime}, {nameof(Offset1)}: {Offset1}, {nameof(Offset2)}: {Offset2}"; public void Validate() { @@ -344,7 +355,7 @@ namespace UVtools.Core.FileFormats public override string ToString() { - return $"{nameof(Section)}: {Section}, {nameof(Width)}: {Width}, {nameof(Resolution)}: {Resolution}, {nameof(Height)}: {Height}, {nameof(Data)}: {Data}"; + return $"{nameof(Section)}: {Section}, {nameof(Width)}: {Width}, {nameof(Resolution)}: {Resolution}, {nameof(Height)}: {Height}, {nameof(Data)}: {Data?.Length ?? 0}"; } public void Validate(int size) @@ -378,16 +389,16 @@ namespace UVtools.Core.FileFormats /// Gets the exposure time for this layer, in seconds. /// [FieldOrder(4)] - public float LayerExposure { get; set; } + public float ExposureTime { get; set; } /// - /// Gets the build platform Z position for this layer, measured in millimeters. + /// Gets the layer height for this layer, measured in millimeters. /// [FieldOrder(5)] - public float LayerPositionZ { get; set; } + public float LayerHeight { get; set; } - [FieldOrder(6)] public float Offset1 { get; set; } - [FieldOrder(7)] public float Offset2 { get; set; } + [FieldOrder(6)] public uint NonZeroPixelCount { get; set; } + [FieldOrder(7)] public uint Offset1 { get; set; } [Ignore] public byte[] EncodedRle { get; set; } [Ignore] public PhotonWorkshopFile Parent { get; set; } @@ -404,10 +415,11 @@ namespace UVtools.Core.FileFormats public void RefreshLayerData(uint layerIndex) { - LayerPositionZ = Parent[layerIndex].PositionZ; - LayerExposure = Parent[layerIndex].ExposureTime; + LayerHeight = Parent[layerIndex].LayerHeight; + ExposureTime = Parent[layerIndex].ExposureTime; LiftHeight = Parent[layerIndex].LiftHeight; LiftSpeed = (float) Math.Round(Parent[layerIndex].LiftSpeed / 60, 2); + NonZeroPixelCount = Parent[layerIndex].NonZeroPixelCount; } public Mat Decode(bool consumeData = true) @@ -706,6 +718,11 @@ namespace UVtools.Core.FileFormats { return CRCRle4(EncodedRle); } + + public override string ToString() + { + return $"{nameof(DataAddress)}: {DataAddress}, {nameof(DataLength)}: {DataLength}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(ExposureTime)}: {ExposureTime}, {nameof(LayerHeight)}: {LayerHeight}, {nameof(NonZeroPixelCount)}: {NonZeroPixelCount}, {nameof(Offset1)}: {Offset1}, {nameof(EncodedRle)}: {EncodedRle?.Length ?? 0}"; + } } #endregion @@ -760,15 +777,15 @@ namespace UVtools.Core.FileFormats #region Properties - public FileMark FileMarkSettings { get; protected internal set; } = new FileMark(); + public FileMark FileMarkSettings { get; protected internal set; } = new(); - public Header HeaderSettings { get; protected internal set; } = new Header(); + public Header HeaderSettings { get; protected internal set; } = new(); - public Preview PreviewSettings { get; protected internal set; } = new Preview(); + public Preview PreviewSettings { get; protected internal set; } = new(); - public LayerDefinition LayersDefinition { get; protected internal set; } = new LayerDefinition(); + public LayerDefinition LayersDefinition { get; protected internal set; } = new(); - public Dictionary LayersHash { get; } = new Dictionary(); + public Dictionary LayersHash { get; } = new(); public override FileFormatType FileType => FileFormatType.Binary; @@ -830,12 +847,75 @@ namespace UVtools.Core.FileFormats public override float DisplayWidth { - get => 0; + get + { + switch (PrinterModel) + { + case AnyCubicMachine.AnyCubicPhotonS: + return 68.04f; + case AnyCubicMachine.AnyCubicPhotonZero: + return 55.44f; + case AnyCubicMachine.AnyCubicPhotonX: + return 192; + case AnyCubicMachine.AnyCubicPhotonMono: + return 82.62f; + case AnyCubicMachine.AnyCubicPhotonMonoSE: + return 82.62f; + case AnyCubicMachine.AnyCubicPhotonMonoX: + return 192; + default: + return 0; + } + } set { } } public override float DisplayHeight { - get => 0; + get + { + switch (PrinterModel) + { + case AnyCubicMachine.AnyCubicPhotonS: + return 120.96f; + case AnyCubicMachine.AnyCubicPhotonZero: + return 98.637f; + case AnyCubicMachine.AnyCubicPhotonX: + return 120; + case AnyCubicMachine.AnyCubicPhotonMono: + return 130.56f; + case AnyCubicMachine.AnyCubicPhotonMonoSE: + return 130.56f; + case AnyCubicMachine.AnyCubicPhotonMonoX: + return 120; + default: + return 0; + } + } + set { } + } + + public override float MaxPrintHeight + { + get + { + switch (PrinterModel) + { + case AnyCubicMachine.AnyCubicPhotonS: + return 165; + case AnyCubicMachine.AnyCubicPhotonZero: + return 150; + case AnyCubicMachine.AnyCubicPhotonX: + return 245; + case AnyCubicMachine.AnyCubicPhotonMono: + return 165; + case AnyCubicMachine.AnyCubicPhotonMonoSE: + return 160; + case AnyCubicMachine.AnyCubicPhotonMonoX: + return 245; + default: + return 0; + } + } set { } } @@ -964,29 +1044,44 @@ namespace UVtools.Core.FileFormats } } + public override float PrintTime + { + get => HeaderSettings.PrintTime; + set + { + HeaderSettings.PrintTime = (uint)value; + base.PrintTime = value; + } + } + public override float MaterialMilliliters { - get => (float) Math.Round(HeaderSettings.Volume, 2); + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : HeaderSettings.VolumeMl; + } set { - HeaderSettings.Volume = (float)Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + HeaderSettings.VolumeMl = (float)Math.Round(value, 3); + base.MaterialMilliliters = HeaderSettings.VolumeMl; } } public override float MaterialGrams { - get => HeaderSettings.WeightG; + get => (float) Math.Round(HeaderSettings.WeightG, 3); set { - HeaderSettings.WeightG = (float) Math.Round(value, 2); + HeaderSettings.WeightG = (float) Math.Round(value, 3); RaisePropertyChanged(); } } public override float MaterialCost { - get => (float) Math.Round(HeaderSettings.Price, 2); + get => (float) Math.Round(HeaderSettings.Price, 3); set { HeaderSettings.Price = (float)Math.Round(value, 2); @@ -995,50 +1090,73 @@ namespace UVtools.Core.FileFormats } public override string MachineName + { + get + { + switch (PrinterModel) + { + case AnyCubicMachine.AnyCubicPhotonS: + return "AnyCubic Photon S"; + case AnyCubicMachine.AnyCubicPhotonZero: + return "AnyCubic Photon Zero"; + case AnyCubicMachine.AnyCubicPhotonX: + return "AnyCubic Photon X"; + case AnyCubicMachine.AnyCubicPhotonMono: + return "AnyCubic Photon Mono"; + case AnyCubicMachine.AnyCubicPhotonMonoSE: + return "AnyCubic Photon Mono SE"; + case AnyCubicMachine.AnyCubicPhotonMonoX: + return "AnyCubic Photon Mono X"; + default: + return base.MachineName; + } + } + } + + public override object[] Configs => new object[] { FileMarkSettings, HeaderSettings, PreviewSettings, LayersDefinition }; + + public LayerRleFormat LayerFormat => + FileFullPath.EndsWith(".pws") || FileFullPath.EndsWith($".pws{TemporaryFileAppend}") + ? LayerRleFormat.PWS + : LayerRleFormat.PW0; + + public AnyCubicMachine PrinterModel { get { if (FileFullPath.EndsWith(".pws") || FileFullPath.EndsWith($".pws{TemporaryFileAppend}")) { - return "AnyCubic Photon S"; + return AnyCubicMachine.AnyCubicPhotonS; } if (FileFullPath.EndsWith(".pw0") || FileFullPath.EndsWith($".pw0{TemporaryFileAppend}")) { - return "AnyCubic Photon Zero"; + return AnyCubicMachine.AnyCubicPhotonZero; } if (FileFullPath.EndsWith(".pwx") || FileFullPath.EndsWith($".pwx{TemporaryFileAppend}")) { - return "AnyCubic Photon X"; + return AnyCubicMachine.AnyCubicPhotonX; } if (FileFullPath.EndsWith(".pwmo") || FileFullPath.EndsWith($".pwmo{TemporaryFileAppend}")) { - return "AnyCubic Photon Mono"; + return AnyCubicMachine.AnyCubicPhotonMono; } if (FileFullPath.EndsWith(".pwms") || FileFullPath.EndsWith($".pwms{TemporaryFileAppend}")) { - return "AnyCubic Photon Mono SE"; + return AnyCubicMachine.AnyCubicPhotonMonoSE; } if (FileFullPath.EndsWith(".pwmx") || FileFullPath.EndsWith($".pwmx{TemporaryFileAppend}")) { - return "AnyCubic Photon Mono X"; + return AnyCubicMachine.AnyCubicPhotonMonoX; } - return base.MachineName; + return AnyCubicMachine.AnyCubicPhotonS; } - } - - public override object[] Configs => new object[] { FileMarkSettings, HeaderSettings, PreviewSettings, LayersDefinition }; - - public LayerRleFormat LayerFormat => - FileFullPath.EndsWith(".pws") || FileFullPath.EndsWith($".pws{TemporaryFileAppend}") - ? LayerRleFormat.PWS - : LayerRleFormat.PW0; - + } #endregion #region Constructors @@ -1058,9 +1176,36 @@ namespace UVtools.Core.FileFormats protected override void EncodeInternally(string fileFullPath, OperationProgress progress) { LayersHash.Clear(); - LayersDefinition = new LayerDefinition(LayerCount); + switch (PrinterModel) + { + case AnyCubicMachine.AnyCubicPhotonS: + HeaderSettings.PixelSizeUm = 47.25f; + break; + case AnyCubicMachine.AnyCubicPhotonZero: + HeaderSettings.PixelSizeUm = 115.5f; + break; + case AnyCubicMachine.AnyCubicPhotonX: + HeaderSettings.PixelSizeUm = 75; + break; + case AnyCubicMachine.AnyCubicPhotonMono: + HeaderSettings.PixelSizeUm = 51; + break; + case AnyCubicMachine.AnyCubicPhotonMonoSE: + HeaderSettings.PixelSizeUm = 51; + break; + case AnyCubicMachine.AnyCubicPhotonMonoX: + HeaderSettings.PixelSizeUm = 50; + break; + default: + HeaderSettings.PixelSizeUm = 47.25f; + break; + } + + HeaderSettings.PerLayerOverride = 1; + + uint currentOffset = FileMarkSettings.HeaderAddress = (uint) Helpers.Serializer.SizeOf(FileMarkSettings); using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write); outputFile.Seek((int) currentOffset, SeekOrigin.Begin); @@ -1190,6 +1335,7 @@ namespace UVtools.Core.FileFormats { LayersDefinition[i] = Helpers.Deserialize(inputFile); LayersDefinition[i].Parent = this; + Debug.WriteLine($"Layer {i}: {LayersDefinition[i]}"); } progress.Reset(OperationProgress.StatusGatherLayers, LayerCount); @@ -1219,8 +1365,8 @@ namespace UVtools.Core.FileFormats { this[layerIndex] = new Layer((uint) layerIndex, image, LayerManager) { - PositionZ = LayersDefinition[(uint)layerIndex].LayerPositionZ, - ExposureTime = LayersDefinition[(uint)layerIndex].LayerExposure, + PositionZ = (float) Math.Round(LayersDefinition[(uint)layerIndex].LayerHeight, 2), + ExposureTime = LayersDefinition[(uint)layerIndex].ExposureTime, LiftHeight = LayersDefinition[(uint)layerIndex].LiftHeight, LiftSpeed = (float)Math.Round(LayersDefinition[(uint)layerIndex].LiftSpeed * 60, 2), }; @@ -1231,6 +1377,15 @@ namespace UVtools.Core.FileFormats progress++; } }); + + // Fix position z height values + if (LayerCount > 0) + { + for (uint layerIndex = 1; layerIndex < LayerCount; layerIndex++) + { + this[layerIndex].PositionZ = (float)Math.Round(this[layerIndex-1].PositionZ + this[layerIndex].PositionZ, 2); + } + } } public override void SaveAs(string filePath = null, OperationProgress progress = null) @@ -1252,6 +1407,8 @@ namespace UVtools.Core.FileFormats FileFullPath = filePath; } + HeaderSettings.PerLayerOverride = 1; + using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write); outputFile.Seek(FileMarkSettings.HeaderAddress, SeekOrigin.Begin); Helpers.SerializeWriteFileStream(outputFile, HeaderSettings); diff --git a/UVtools.Core/FileFormats/SL1File.cs b/UVtools.Core/FileFormats/SL1File.cs index 398f874..23e0fb1 100644 --- a/UVtools.Core/FileFormats/SL1File.cs +++ b/UVtools.Core/FileFormats/SL1File.cs @@ -441,21 +441,26 @@ namespace UVtools.Core.FileFormats public override float MaterialMilliliters { - get => OutputConfigSettings.UsedMaterial; + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : OutputConfigSettings.UsedMaterial; + } set { - OutputConfigSettings.UsedMaterial = (float)Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + OutputConfigSettings.UsedMaterial = (float)Math.Round(value, 3); + base.MaterialMilliliters = OutputConfigSettings.UsedMaterial; } } - public override float MaterialGrams + public override float MaterialGrams { - get => (float) Math.Round(OutputConfigSettings.UsedMaterial * MaterialSettings.MaterialDensity, 2); + get => (float) Math.Round(OutputConfigSettings.UsedMaterial * MaterialSettings.MaterialDensity, 3); set { } } - public override float MaterialCost => MaterialSettings.BottleVolume > 0 ? (float) Math.Round(OutputConfigSettings.UsedMaterial * MaterialSettings.BottleCost / MaterialSettings.BottleVolume, 2) : 0; + public override float MaterialCost => MaterialSettings.BottleVolume > 0 ? (float) Math.Round(OutputConfigSettings.UsedMaterial * MaterialSettings.BottleCost / MaterialSettings.BottleVolume, 3) : 0; public override string MaterialName { diff --git a/UVtools.Core/FileFormats/ZCodexFile.cs b/UVtools.Core/FileFormats/ZCodexFile.cs index f29b907..6a366df 100644 --- a/UVtools.Core/FileFormats/ZCodexFile.cs +++ b/UVtools.Core/FileFormats/ZCodexFile.cs @@ -333,20 +333,25 @@ namespace UVtools.Core.FileFormats public override float MaterialMilliliters { - get => ResinMetadataSettings.TotalMaterialVolumeUsed; + get + { + var materialMl = base.MaterialMilliliters; + return materialMl > 0 ? materialMl : ResinMetadataSettings.TotalMaterialVolumeUsed; + } set { - UserSettings.MaterialVolume = ResinMetadataSettings.TotalMaterialVolumeUsed = (float) Math.Round(value, 2); - RaisePropertyChanged(); + if (value <= 0) value = base.MaterialMilliliters; + ResinMetadataSettings.TotalMaterialVolumeUsed = (float)Math.Round(value, 3); + base.MaterialMilliliters = ResinMetadataSettings.TotalMaterialVolumeUsed; } } public override float MaterialGrams { - get => ResinMetadataSettings.TotalMaterialWeightUsed; + get => (float) Math.Round(ResinMetadataSettings.TotalMaterialWeightUsed, 3); set { - ResinMetadataSettings.TotalMaterialWeightUsed = (float) Math.Round(value, 2); + ResinMetadataSettings.TotalMaterialWeightUsed = (float) Math.Round(value, 3); RaisePropertyChanged(); } } diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs index 6da632c..4b65b64 100644 --- a/UVtools.Core/Layer/Layer.cs +++ b/UVtools.Core/Layer/Layer.cs @@ -57,7 +57,13 @@ namespace UVtools.Core public uint NonZeroPixelCount { get => _nonZeroPixelCount; - internal set => RaiseAndSetIfChanged(ref _nonZeroPixelCount, value); + internal set + { + if(!RaiseAndSetIfChanged(ref _nonZeroPixelCount, value)) return; + RaisePropertyChanged(nameof(MaterialMilliliters)); + if (SlicerFile is null) return; + SlicerFile.MaterialMilliliters = 0; + } } /// @@ -195,6 +201,18 @@ namespace UVtools.Core } } + /// + /// Gets the computed material milliliters spent on this layer + /// + public float MaterialMilliliters + { + get + { + if (ParentLayerManager?.SlicerFile is null) return 0; + return (float) Math.Round(ParentLayerManager.SlicerFile.PixelArea * LayerHeight * NonZeroPixelCount / 1000, 4); + } + } + /// /// Gets or sets layer image compressed data /// @@ -393,7 +411,7 @@ namespace UVtools.Core public Rectangle GetBoundingRectangle(Mat mat = null, bool reCalculate = false) { - if (NonZeroPixelCount > 0 && !reCalculate) + if (_nonZeroPixelCount > 0 && !reCalculate) { return BoundingRectangle; } diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs index 65127c4..a27386a 100644 --- a/UVtools.Core/Layer/LayerManager.cs +++ b/UVtools.Core/Layer/LayerManager.cs @@ -591,7 +591,7 @@ namespace UVtools.Core (int) ccStats.GetValue(i, (int) ConnectedComponentsTypes.Width), (int) ccStats.GetValue(i, (int) ConnectedComponentsTypes.Height)); - if (rect.GetArea() < islandConfig.RequiredAreaToProcessCheck) + if (rect.Area() < islandConfig.RequiredAreaToProcessCheck) continue; if (previousImage is null) @@ -794,7 +794,7 @@ namespace UVtools.Core continue; var rect = CvInvoke.BoundingRectangle(contours[i]); - if(rect.GetArea() < resinTrapConfig.RequiredAreaToProcessCheck) continue; + if(rect.Area() < resinTrapConfig.RequiredAreaToProcessCheck) continue; listHollowArea.Add(new LayerHollowArea(contours[i].ToArray(), rect, diff --git a/UVtools.Core/Operations/Operation.cs b/UVtools.Core/Operations/Operation.cs index f0d896d..2171e3b 100644 --- a/UVtools.Core/Operations/Operation.cs +++ b/UVtools.Core/Operations/Operation.cs @@ -123,6 +123,9 @@ namespace UVtools.Core.Operations /// public virtual string ProgressAction => Id; + /// + /// Gets if this operation have a action text + /// public bool HaveAction => !string.IsNullOrEmpty(ProgressAction); /// @@ -171,6 +174,12 @@ namespace UVtools.Core.Operations } public bool HaveROI => !ROI.IsEmpty; + + /// + /// Gets if this operation have been executed once + /// + [XmlIgnore] + public bool HaveExecuted { get; private set; } #endregion #region Constructor @@ -302,6 +311,7 @@ namespace UVtools.Core.Operations if (_slicerFile is null) throw new InvalidOperationException($"{Title} can't execute due the lacking of file parent."); progress ??= new OperationProgress(); progress.Reset(ProgressAction, LayerRangeCount); + HaveExecuted = true; var result = ExecuteInternally(progress); diff --git a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs index 27d7eaf..c39b12a 100644 --- a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs +++ b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs @@ -219,7 +219,7 @@ namespace UVtools.Core.Operations } } - public uint CacheObjectCount => (uint) (_cacheRamSize * 1000000000L / SlicerFile.Resolution.GetArea() / ObjectsPerCache); + public uint CacheObjectCount => (uint) (_cacheRamSize * 1000000000L / SlicerFile.Resolution.Area() / ObjectsPerCache); public decimal CacheRAMSize { diff --git a/UVtools.Core/Operations/OperationSolidify.cs b/UVtools.Core/Operations/OperationSolidify.cs index e7e8e4d..056f930 100644 --- a/UVtools.Core/Operations/OperationSolidify.cs +++ b/UVtools.Core/Operations/OperationSolidify.cs @@ -120,11 +120,11 @@ namespace UVtools.Core.Operations var rectangle = CvInvoke.BoundingRectangle(contours[i]); if (AreaCheckType == AreaCheckTypes.More) { - if (rectangle.GetArea() < MinimumArea) continue; + if (rectangle.Area() < MinimumArea) continue; } else { - if (rectangle.GetArea() > MinimumArea) continue; + if (rectangle.Area() > MinimumArea) continue; } } diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index e9bad39..a9b49ca 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.4.6 + 2.4.7 Copyright © 2020 PTRTECH UVtools.png AnyCPU;x64 diff --git a/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs index 7f7270d..e88db59 100644 --- a/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolControl.axaml.cs @@ -1,6 +1,5 @@ using System.Threading.Tasks; using Avalonia.Markup.Xaml; -using UVtools.Core.FileFormats; using UVtools.Core.Objects; using UVtools.Core.Operations; using UVtools.WPF.Extensions; @@ -17,7 +16,8 @@ namespace UVtools.WPF.Controls.Tools get => _baseOperation; set { - if(!RaiseAndSetIfChanged(ref _baseOperation, value)) return; + _baseOperation = value; + RaisePropertyChanged(); if (DataContext is null) return; ResetDataContext(); } diff --git a/UVtools.WPF/MainWindow.Information.cs b/UVtools.WPF/MainWindow.Information.cs index 9b0bb1a..2c4b169 100644 --- a/UVtools.WPF/MainWindow.Information.cs +++ b/UVtools.WPF/MainWindow.Information.cs @@ -344,20 +344,25 @@ namespace UVtools.WPF //CurrentLayerProperties.Add(new StringTag(nameof(layer.NonZeroPixelCount), layer.NonZeroPixelCount.ToString())); CurrentLayerProperties.Add(new StringTag(nameof(layer.ExposureTime), $"{layer.ExposureTime:F2}s")); - if (ReferenceEquals(SlicerFile.PrintParameterPerLayerModifiers, null)) return; - - if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.LiftHeight)) - CurrentLayerProperties.Add(new StringTag(nameof(layer.LiftHeight), - $"{layer.LiftHeight.ToString(CultureInfo.InvariantCulture)}mm @ {layer.LiftSpeed.ToString(CultureInfo.InvariantCulture)}mm/min")); - //CurrentLayerProperties.Adnew StringTagg>(nameof(layer.LiftSpeed), $"{layer.LiftSpeed.ToString(CultureInfo.InvariantCulture)}mm/min")); - if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.RetractSpeed)) - CurrentLayerProperties.Add(new StringTag(nameof(layer.RetractSpeed), - $"{layer.RetractSpeed.ToString(CultureInfo.InvariantCulture)}mm/min")); - if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.LightOffDelay)) - CurrentLayerProperties.Add(new StringTag(nameof(layer.LightOffDelay), - $"{layer.LightOffDelay.ToString(CultureInfo.InvariantCulture)}s")); - if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.LightPWM)) - CurrentLayerProperties.Add(new StringTag(nameof(layer.LightPWM), layer.LightPWM.ToString())); + if (SlicerFile.PrintParameterPerLayerModifiers is not null) + { + + if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.LiftHeight)) + CurrentLayerProperties.Add(new StringTag(nameof(layer.LiftHeight), + $"{layer.LiftHeight.ToString(CultureInfo.InvariantCulture)}mm @ {layer.LiftSpeed.ToString(CultureInfo.InvariantCulture)}mm/min")); + //CurrentLayerProperties.Adnew StringTagg>(nameof(layer.LiftSpeed), $"{layer.LiftSpeed.ToString(CultureInfo.InvariantCulture)}mm/min")); + if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.RetractSpeed)) + CurrentLayerProperties.Add(new StringTag(nameof(layer.RetractSpeed), + $"{layer.RetractSpeed}mm/min")); + if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.LightOffDelay) + ) + CurrentLayerProperties.Add(new StringTag(nameof(layer.LightOffDelay), + $"{layer.LightOffDelay}s")); + if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.LightPWM)) + CurrentLayerProperties.Add(new StringTag(nameof(layer.LightPWM), layer.LightPWM.ToString())); + } + + CurrentLayerProperties.Add(new StringTag(nameof(layer.MaterialMilliliters), $"{layer.MaterialMilliliters:F4}ml")); } #endregion } diff --git a/UVtools.WPF/MainWindow.LayerPreview.cs b/UVtools.WPF/MainWindow.LayerPreview.cs index dc5f29f..feb6439 100644 --- a/UVtools.WPF/MainWindow.LayerPreview.cs +++ b/UVtools.WPF/MainWindow.LayerPreview.cs @@ -307,13 +307,13 @@ namespace UVtools.WPF } } - public string LayerBoundsStr => LayerCache.Layer is null ? "NS" : $"{LayerCache.Layer.BoundingRectangle} ({LayerCache.Layer.BoundingRectangle.GetArea()}px²)"; + public string LayerBoundsStr => LayerCache.Layer is null ? "NS" : $"{LayerCache.Layer.BoundingRectangle} ({LayerCache.Layer.BoundingRectangle.Area()}px²)"; public string LayerROIStr { get { var roi = ROI; - return roi.IsEmpty ? "NS" : $"{roi} ({roi.GetArea()}px²)"; + return roi.IsEmpty ? "NS" : $"{roi} ({roi.Area()}px²)"; } } diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 170a4a5..f2b6a94 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ LICENSE https://github.com/sn4k3/UVtools Git - 2.4.6 + 2.4.7 diff --git a/UVtools.WPF/Windows/ToolWindow.axaml.cs b/UVtools.WPF/Windows/ToolWindow.axaml.cs index 2eb4725..e3936d3 100644 --- a/UVtools.WPF/Windows/ToolWindow.axaml.cs +++ b/UVtools.WPF/Windows/ToolWindow.axaml.cs @@ -1,10 +1,8 @@ using System; using System.Collections.ObjectModel; -using System.Diagnostics; using System.Drawing; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Markup.Xaml; using Avalonia.Threading; @@ -109,7 +107,7 @@ namespace UVtools.WPF.Windows get => _layerIndexStart; set { - if (!(ToolControl?.BaseOperation is null)) + if (ToolControl?.BaseOperation is not null) { ToolControl.BaseOperation.LayerRangeSelection = Enumerations.LayerRangeSelection.None; ToolControl.BaseOperation.LayerIndexStart = value; @@ -294,7 +292,17 @@ namespace UVtools.WPF.Windows operation.ProfileName = null; operation.SlicerFile = App.SlicerFile; ToolControl.BaseOperation = operation; - SelectLayers(operation.LayerRangeSelection); + switch (operation.LayerRangeSelection) + { + case Enumerations.LayerRangeSelection.None: + LayerIndexStart = operation.LayerIndexStart; + LayerIndexEnd = operation.LayerIndexEnd; + break; + default: + SelectLayers(operation.LayerRangeSelection); + break; + } + ToolControl.Callback(Callbacks.ProfileLoaded); ToolControl.ResetDataContext(); } @@ -504,14 +512,14 @@ namespace UVtools.WPF.Windows _buttonOkText = toolControl.BaseOperation.ButtonOkText; _buttonOkVisible = ButtonOkEnabled = toolControl.BaseOperation.HaveAction; - if (toolControl.BaseOperation.LayerIndexStart == 0 && toolControl.BaseOperation.LayerIndexEnd == 0) + if (toolControl.BaseOperation.HaveExecuted) // Come from a redo or something { - SelectLayers(toolControl.BaseOperation.StartLayerRangeSelection); + LayerIndexStart = toolControl.BaseOperation.LayerIndexStart; + LayerIndexEnd = toolControl.BaseOperation.LayerIndexEnd; } else { - LayerIndexStart = toolControl.BaseOperation.LayerIndexStart; - LayerIndexEnd = toolControl.BaseOperation.LayerIndexEnd; + SelectLayers(toolControl.BaseOperation.StartLayerRangeSelection); } //RaisePropertyChanged(nameof(IsContentVisible)); -- cgit v1.2.3