diff --git a/UVtools.Core/CoreSettings.cs b/UVtools.Core/CoreSettings.cs index 62824f6..1301579 100644 --- a/UVtools.Core/CoreSettings.cs +++ b/UVtools.Core/CoreSettings.cs @@ -39,7 +39,7 @@ namespace UVtools.Core public static ParallelOptions ParallelOptions => new() {MaxDegreeOfParallelism = _maxDegreeOfParallelism}; /// - /// Gets or sets if operations run via cuda when possible + /// Gets or sets if operations run via CUDA when possible /// public static bool EnableCuda { get; set; } diff --git a/UVtools.Core/Extensions/MathExtensions.cs b/UVtools.Core/Extensions/MathExtensions.cs index f38bc90..5916926 100644 --- a/UVtools.Core/Extensions/MathExtensions.cs +++ b/UVtools.Core/Extensions/MathExtensions.cs @@ -114,5 +114,45 @@ namespace UVtools.Core.Extensions public static bool IsInteger(this float val, float tolerance = 0.0001f) => Math.Abs(val - Math.Floor(val)) < tolerance; public static bool IsInteger(this double val, double tolerance = 0.0001) => Math.Abs(val - Math.Floor(val)) < tolerance; public static bool IsInteger(this decimal val) => val == Math.Floor(val); + + public static int GCD(int a, int b) + { + while (a != 0 && b != 0) + { + if (a > b) + a %= b; + else + b %= a; + } + + return a | b; + } + + public static uint GCD(uint a, uint b) + { + while (a != 0 && b != 0) + { + if (a > b) + a %= b; + else + b %= a; + } + + return a | b; + } + + public static ulong GCD(ulong a, ulong b) + { + while (a != 0 && b != 0) + { + if (a > b) + a %= b; + else + b %= a; + } + + return a | b; + } + } } diff --git a/UVtools.Core/Extensions/UnitExtensions.cs b/UVtools.Core/Extensions/UnitExtensions.cs new file mode 100644 index 0000000..765c198 --- /dev/null +++ b/UVtools.Core/Extensions/UnitExtensions.cs @@ -0,0 +1,20 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System; + +namespace UVtools.Core.Extensions +{ + public static class UnitExtensions + { + /// + /// 1 mm to 1 inch + /// + public const double MillimeterInInch = 0.0393700787; + } +} diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 871951b..c744425 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -1003,6 +1003,37 @@ namespace UVtools.Core.FileFormats /// public virtual float DisplayHeight { get; set; } + /// + /// Gets the display diagonal in millimeters + /// + public float DisplayDiagonal => (float)Math.Round(Math.Sqrt(Math.Pow(DisplayWidth, 2) + Math.Pow(DisplayHeight, 2)), 2); + + /// + /// Gets the display diagonal in inch's + /// + public float DisplayDiagonalInches => (float)Math.Round(Math.Sqrt(Math.Pow(DisplayWidth, 2) + Math.Pow(DisplayHeight, 2)) * UnitExtensions.MillimeterInInch, 2); + + /// + /// Gets the display ratio + /// + public Size DisplayAspectRatio + { + get + { + var gcd = MathExtensions.GCD(ResolutionX, ResolutionY); + return new((int)(ResolutionX / gcd), (int)(ResolutionY / gcd)); + } + } + + public string DisplayAspectRatioStr + { + get + { + var aspect = DisplayAspectRatio; + return $"{aspect.Width}:{aspect.Height}"; + } + } + /// /// Gets or sets if images need to be mirrored on lcd to print on the correct orientation /// diff --git a/UVtools.Core/Layers/LayerManager.cs b/UVtools.Core/Layers/LayerManager.cs index e77869d..fdfe19b 100644 --- a/UVtools.Core/Layers/LayerManager.cs +++ b/UVtools.Core/Layers/LayerManager.cs @@ -1002,7 +1002,7 @@ namespace UVtools.Core public Layer[] AllocateFromMat(Mat[] mats) { var layers = new Layer[mats.Length]; - Parallel.For(0L, mats.Length, CoreSettings.ParallelOptions, i => + Parallel.For(0, mats.Length, CoreSettings.ParallelOptions, i => { layers[i] = new Layer((uint)i, mats[i], this); }); diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs index acb3dae..2c6ff4f 100644 --- a/UVtools.WPF/MainWindow.axaml.cs +++ b/UVtools.WPF/MainWindow.axaml.cs @@ -1602,6 +1602,28 @@ namespace UVtools.WPF ZoomToFit(); } + var display = SlicerFile.Display; + if (!display.HaveZero() && + //SlicerFile is not LGSFile && + ((SlicerFile.ResolutionX > SlicerFile.ResolutionY && + SlicerFile.DisplayWidth < SlicerFile.DisplayHeight) + || (SlicerFile.ResolutionX < SlicerFile.ResolutionY && + SlicerFile.DisplayWidth > SlicerFile.DisplayHeight))) + { + var ppm = SlicerFile.Ppmm; + var ppmMax = ppm.Max(); + var xRatio = Math.Round(ppmMax - ppm.Width + 1); + var yRatio = Math.Round(ppmMax - ppm.Height + 1); + await this.MessageBoxWaring( + "It looks like this file was sliced with an incorrect image ratio.\n" + + "Printing this file may produce a stretched model with wrong proportions or a failed print.\n" + + "Please go back to Slicer configuration and validate the printer resolution and display size.\n\n" + + $"Resolution: {SlicerFile.Resolution}\n" + + $"Display: {display}\n" + + $"Ratio: {xRatio}:{yRatio}\n", + "Incorrect image ratio detected"); + } + if (mat.Size != SlicerFile.Resolution) { var result = await this.MessageBoxWaring($"Layer image resolution of {mat.Size} mismatch with printer resolution of {SlicerFile.Resolution}.\n" + diff --git a/UVtools.WPF/Program.cs b/UVtools.WPF/Program.cs index 05333ae..c00ec07 100644 --- a/UVtools.WPF/Program.cs +++ b/UVtools.WPF/Program.cs @@ -2,7 +2,6 @@ using System.Diagnostics; using System.Runtime.ExceptionServices; using Avalonia; -using Emgu.CV; using UVtools.WPF.Extensions; namespace UVtools.WPF @@ -20,7 +19,6 @@ namespace UVtools.WPF { ProgramStartupTime = Stopwatch.StartNew(); Args = args; - try { if (ConsoleArguments.ParseArgs(args)) return;