From 193748dcf7e7724be2b8570e031529bfbba2deb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Wed, 22 Sep 2021 17:05:12 +0100 Subject: [PATCH] Fixes and improvements - (Change) Allow touching bounds to have a bounding rectangle and zoom into the issue - (Fix) Touching bounds are reporting areas of 0 - (Fix) Draw crosshair for issues are called multiple times - (Fix) Issue:Equals --- UVtools.Core/Layers/Issue.cs | 2 +- UVtools.Core/Layers/LayerManager.cs | 1 - UVtools.Core/Managers/IssueManager.cs | 27 +++++++++++++- UVtools.Core/UVtools.Core.csproj | 2 +- UVtools.WPF/MainWindow.LayerPreview.cs | 51 +++++++++++++------------- UVtools.WPF/UVtools.WPF.csproj | 2 +- 6 files changed, 54 insertions(+), 31 deletions(-) diff --git a/UVtools.Core/Layers/Issue.cs b/UVtools.Core/Layers/Issue.cs index 1301dfc..cb9c980 100644 --- a/UVtools.Core/Layers/Issue.cs +++ b/UVtools.Core/Layers/Issue.cs @@ -19,7 +19,7 @@ namespace UVtools.Core.Layers /// public MainIssue Parent { get; internal set; } - public MainIssue.IssueType Type => Parent.Type; + public MainIssue.IssueType? Type => Parent?.Type; /// /// Gets the layer where this issue is present diff --git a/UVtools.Core/Layers/LayerManager.cs b/UVtools.Core/Layers/LayerManager.cs index 9499d41..e77869d 100644 --- a/UVtools.Core/Layers/LayerManager.cs +++ b/UVtools.Core/Layers/LayerManager.cs @@ -17,7 +17,6 @@ using System.Threading.Tasks; using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Structure; -using Emgu.CV.Util; using MoreLinq.Extensions; using UVtools.Core.EmguCV; using UVtools.Core.Extensions; diff --git a/UVtools.Core/Managers/IssueManager.cs b/UVtools.Core/Managers/IssueManager.cs index d1cf41e..8e1045b 100644 --- a/UVtools.Core/Managers/IssueManager.cs +++ b/UVtools.Core/Managers/IssueManager.cs @@ -219,7 +219,7 @@ namespace UVtools.Core.Managers using (var image = layer.LayerMat) { int step = image.Step; - var span = image.GetDataSpan(); + var span = image.GetDataByteSpan(); if (touchBoundConfig.Enabled) { @@ -230,6 +230,12 @@ namespace UVtools.Core.Managers bool touchLeft = layer.BoundingRectangle.Left <= touchBoundConfig.MarginLeft; bool touchRight = layer.BoundingRectangle.Right >= image.Width - touchBoundConfig.MarginRight; + + int minx = int.MaxValue; + int miny = int.MaxValue; + int maxx = 0; + int maxy = 0; + if (touchTop || touchBottom) { for (int x = 0; x < image.Width; x++) // Check Top and Bottom bounds @@ -242,6 +248,10 @@ namespace UVtools.Core.Managers touchBoundConfig.MinimumPixelBrightness) { pixels.Add(new Point(x, y)); + minx = Math.Min(minx, x); + miny = Math.Min(miny, y); + maxx = Math.Max(maxx, x); + maxy = Math.Max(maxy, y); } } } @@ -256,6 +266,10 @@ namespace UVtools.Core.Managers touchBoundConfig.MinimumPixelBrightness) { pixels.Add(new Point(x, y)); + minx = Math.Min(minx, x); + miny = Math.Min(miny, y); + maxx = Math.Max(maxx, x); + maxy = Math.Max(maxy, y); } } } @@ -277,6 +291,10 @@ namespace UVtools.Core.Managers touchBoundConfig.MinimumPixelBrightness) { pixels.Add(new Point(x, y)); + minx = Math.Min(minx, x); + miny = Math.Min(miny, y); + maxx = Math.Max(maxx, x); + maxy = Math.Max(maxy, y); } } } @@ -291,6 +309,10 @@ namespace UVtools.Core.Managers touchBoundConfig.MinimumPixelBrightness) { pixels.Add(new Point(x, y)); + minx = Math.Min(minx, x); + miny = Math.Min(miny, y); + maxx = Math.Max(maxx, x); + maxy = Math.Max(maxy, y); } } } @@ -299,7 +321,8 @@ namespace UVtools.Core.Managers if (pixels.Count > 0) { - AddIssue(new MainIssue(MainIssue.IssueType.TouchingBound, new IssueOfPoints(layer, pixels))); + AddIssue(new MainIssue(MainIssue.IssueType.TouchingBound, new IssueOfPoints(layer, pixels, + new Rectangle(minx, miny, maxx-minx+1, maxy-miny+1)))); } } diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 6772040..acf440a 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.23.0 + 2.23.1 Copyright © 2020 PTRTECH UVtools.png AnyCPU;x64 diff --git a/UVtools.WPF/MainWindow.LayerPreview.cs b/UVtools.WPF/MainWindow.LayerPreview.cs index 750a6f5..83b3393 100644 --- a/UVtools.WPF/MainWindow.LayerPreview.cs +++ b/UVtools.WPF/MainWindow.LayerPreview.cs @@ -141,13 +141,14 @@ namespace UVtools.WPF if (IssuesGrid.SelectedItems.Count == 0 || !IssuesGrid.SelectedItems.Cast().Any( mainIssue => // Find a valid candidate to update layer preview, otherwise quit mainIssue.IsIssueInBetween(_actualLayer) - && mainIssue.Type is not MainIssue.IssueType.EmptyLayer and not MainIssue.IssueType.TouchingBound)) return; + && mainIssue.Type is not MainIssue.IssueType.TouchingBound and not MainIssue.IssueType.EmptyLayer)) return; } else { if (!SlicerFile.IssueManager.Any( mainIssue => // Find a valid candidate to update layer preview, otherwise quit - mainIssue.IsIssueInBetween(_actualLayer) && mainIssue.Type is not MainIssue.IssueType.EmptyLayer and not MainIssue.IssueType.TouchingBound)) return; + mainIssue.IsIssueInBetween(_actualLayer) + && mainIssue.Type is not MainIssue.IssueType.TouchingBound and not MainIssue.IssueType.EmptyLayer)) return; } // A timer is used here rather than invoking ShowLayer directly to eliminate sublte visual flashing @@ -951,7 +952,10 @@ namespace UVtools.WPF if (_showLayerImageIssues && SlicerFile.IssueManager.Count > 0) { //var count = 0; - foreach (var issue in SlicerFile.IssueManager.GetIssuesBy(_actualLayer).Where(issue => issue.Parent.Type is not MainIssue.IssueType.PrintHeight and not MainIssue.IssueType.EmptyLayer)) + foreach (var issue in SlicerFile.IssueManager.GetIssuesBy(_actualLayer) + .Where(issue => issue.Parent.Type + is not MainIssue.IssueType.PrintHeight + and not MainIssue.IssueType.EmptyLayer)) { //count++; var color = Color.Empty; @@ -1269,17 +1273,15 @@ namespace UVtools.WPF { - foreach (MainIssue mainIssue in selectedIssues) + // Don't render crosshairs for selected issue that are not on the current layer, or for + // issue types that don't have a specific location or bounds. + foreach (var issue in SlicerFile.IssueManager.GetIssuesBy(_actualLayer) + .Where(issue => issue.Parent.Type + is not MainIssue.IssueType.TouchingBound + and not MainIssue.IssueType.PrintHeight + and not MainIssue.IssueType.EmptyLayer)) { - // Don't render crosshairs for selected issue that are not on the current layer, or for - // issue types that don't have a specific location or bounds. - foreach (var issue in SlicerFile.IssueManager.GetIssuesBy(_actualLayer) - .Where(issue => issue.Parent.Type is not MainIssue.IssueType.PrintHeight and not MainIssue.IssueType.EmptyLayer)) - { - DrawCrosshair(issue.BoundingRectangle); - } - - + DrawCrosshair(issue.BoundingRectangle); } } @@ -1334,10 +1336,10 @@ namespace UVtools.WPF // LEFT - var startPoint = new System.Drawing.Point(Math.Max(0, rect.X - Settings.LayerPreview.CrosshairMargin - 1), + var startPoint = new Point(Math.Max(0, rect.X - Settings.LayerPreview.CrosshairMargin - 1), rect.Y + rect.Height / 2); var endPoint = - new System.Drawing.Point( + new Point( Settings.LayerPreview.CrosshairLength == 0 ? 0 : (int)Math.Max(0, startPoint.X - Settings.LayerPreview.CrosshairLength + 1), @@ -1364,9 +1366,9 @@ namespace UVtools.WPF lineThickness); // TOP - startPoint = new System.Drawing.Point(rect.X + rect.Width / 2, + startPoint = new Point(rect.X + rect.Width / 2, Math.Max(0, rect.Y - Settings.LayerPreview.CrosshairMargin - 1)); - endPoint = new System.Drawing.Point(startPoint.X, + endPoint = new Point(startPoint.X, (int)(Settings.LayerPreview.CrosshairLength == 0 ? 0 : Math.Max(0, startPoint.Y - Settings.LayerPreview.CrosshairLength + 1))); @@ -1585,15 +1587,13 @@ namespace UVtools.WPF /// private void ZoomToIssue(Issue issue, bool forceRefreshLayer = false) { - if (issue.Type is MainIssue.IssueType.TouchingBound or MainIssue.IssueType.EmptyLayer || issue.BoundingRectangle.IsEmpty) + if (issue.Type is MainIssue.IssueType.EmptyLayer || issue.BoundingRectangle.IsEmpty) { ZoomToFit(); if (forceRefreshLayer) ForceUpdateActualLayer(issue.LayerIndex); return; } - if (issue.BoundingRectangle.IsEmpty) return; - if (Settings.LayerPreview.ZoomIssues ^ (_globalModifiers & KeyModifiers.Alt) != 0) { CenterLayerAt(GetTransposedIssueBounds(issue), AppSettings.LockedZoomLevel); @@ -1620,7 +1620,7 @@ namespace UVtools.WPF /// private void CenterAtIssue(Issue issue) { - if (issue.Parent.Type is MainIssue.IssueType.TouchingBound or MainIssue.IssueType.EmptyLayer || issue.BoundingRectangle.IsEmpty) + if (issue.Parent.Type is MainIssue.IssueType.EmptyLayer || issue.BoundingRectangle.IsEmpty) { ZoomToFit(); } @@ -1702,15 +1702,16 @@ namespace UVtools.WPF { //location = GetTransposedPoint(location); // If location clicked is within an issue, activate it. - foreach (var issue in SlicerFile.IssueManager.GetIssuesBy(_actualLayer).Reverse()) + var issues = SlicerFile.IssueManager.GetIssuesBy(_actualLayer); + for (var i = issues.Length-1; i >= 0; i--) { - if (!GetTransposedIssueBounds(issue).Contains(location)) continue; + if (!GetTransposedIssueBounds(issues[i]).Contains(location)) continue; SuppressIssueGridSelectionEvent = true; - IssuesGrid.SelectedItem = issue.Parent; + IssuesGrid.SelectedItem = issues[i].Parent; SuppressIssueGridSelectionEvent = false; - ZoomToIssue(issue, true); + ZoomToIssue(issues[i], true); SelectedTabItem = TabIssues; break; diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 86a7540..bcb11da 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.23.0 + 2.23.1 AnyCPU;x64