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;