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