Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Conceição <Tiago_caza@hotmail.com>2020-06-20 01:52:08 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2020-06-20 01:52:08 +0300
commitfc73f2ff7546f3f66ec4ada7b975534487001fac (patch)
tree2a1364c37afda2251d84b3695aaa6a1eb403042c
parent93e548c7de7611ae2bd34f36a7be6d596558fe90 (diff)
v0.5.2v0.5.2
* (Add) Resin Trap issue validator and repairer - Experimental Feature (#3) * (Add) Layer Repair tool can now fix Resin Traps when selected * (Add) "Remove" issues button fix selected Resin traps, the operation now run under a thread and in a parallel way, preventing the GUI from freeze * (Change) "Repair Layers" button renamed to "Repair Layers and Issues" * (Fix) When do a "repair layers" before open the Issue tab, when open next it will recompute issues without the need
-rw-r--r--CHANGELOG.md8
-rw-r--r--UVtools.GUI/Forms/FrmRepairLayers.Designer.cs60
-rw-r--r--UVtools.GUI/Forms/FrmRepairLayers.cs13
-rw-r--r--UVtools.GUI/Forms/FrmRepairLayers.resx3
-rw-r--r--UVtools.GUI/FrmMain.Designer.cs8
-rw-r--r--UVtools.GUI/FrmMain.cs432
-rw-r--r--UVtools.GUI/FrmMain.resx83
-rw-r--r--UVtools.GUI/Properties/AssemblyInfo.cs4
-rw-r--r--UVtools.Parser/LayerManager.cs16
-rw-r--r--UVtools.Parser/UVtools.Parser.csproj6
10 files changed, 345 insertions, 288 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a448e8b..b2e9d83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 19/06/2020 - v0.5.2
+
+* (Add) Resin Trap issue validator and repairer - Experimental Feature (#3)
+* (Add) Layer Repair tool can now fix Resin Traps when selected
+* (Add) "Remove" issues button fix selected Resin traps, the operation now run under a thread and in a parallel way, preventing the GUI from freeze
+* (Change) "Repair Layers" button renamed to "Repair Layers and Issues"
+* (Fix) When do a "repair layers" before open the Issue tab, when open next it will recompute issues without the need
+
## 18/06/2020 - v0.5.1.3
* (Add) Button save layer image to Clipboard
diff --git a/UVtools.GUI/Forms/FrmRepairLayers.Designer.cs b/UVtools.GUI/Forms/FrmRepairLayers.Designer.cs
index d5227c9..e9a4e0f 100644
--- a/UVtools.GUI/Forms/FrmRepairLayers.Designer.cs
+++ b/UVtools.GUI/Forms/FrmRepairLayers.Designer.cs
@@ -46,12 +46,12 @@ namespace UVtools.GUI.Forms
this.btnLayerRangeNormalLayers = new System.Windows.Forms.ToolStripMenuItem();
this.btnCancel = new System.Windows.Forms.Button();
this.btnRepair = new System.Windows.Forms.Button();
- this.cbRepairLayers = new System.Windows.Forms.CheckBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
- this.cbRepairIslands = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
+ this.cbRepairIslands = new System.Windows.Forms.CheckBox();
this.numOpeningIterations = new System.Windows.Forms.NumericUpDown();
- this.btnLayerRangeSelect = new SplitButton();
+ this.cbRepairResinTraps = new System.Windows.Forms.CheckBox();
+ this.btnLayerRangeSelect = new UVtools.GUI.Controls.SplitButton();
((System.ComponentModel.ISupportInitialize)(this.numClosingIterations)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).BeginInit();
@@ -217,19 +217,6 @@ namespace UVtools.GUI.Forms
this.btnRepair.UseVisualStyleBackColor = true;
this.btnRepair.Click += new System.EventHandler(this.ItemClicked);
//
- // cbRepairLayers
- //
- this.cbRepairLayers.AutoSize = true;
- this.cbRepairLayers.Checked = true;
- this.cbRepairLayers.CheckState = System.Windows.Forms.CheckState.Checked;
- this.cbRepairLayers.Enabled = false;
- this.cbRepairLayers.Location = new System.Drawing.Point(17, 242);
- this.cbRepairLayers.Name = "cbRepairLayers";
- this.cbRepairLayers.Size = new System.Drawing.Size(126, 24);
- this.cbRepairLayers.TabIndex = 15;
- this.cbRepairLayers.Text = "Repair Layers";
- this.cbRepairLayers.UseVisualStyleBackColor = true;
- //
// toolTip
//
this.toolTip.AutoPopDelay = 32767;
@@ -239,19 +226,6 @@ namespace UVtools.GUI.Forms
this.toolTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info;
this.toolTip.ToolTipTitle = "Information";
//
- // cbRepairIslands
- //
- this.cbRepairIslands.AutoSize = true;
- this.cbRepairIslands.Checked = true;
- this.cbRepairIslands.CheckState = System.Windows.Forms.CheckState.Checked;
- this.cbRepairIslands.Enabled = false;
- this.cbRepairIslands.Location = new System.Drawing.Point(17, 272);
- this.cbRepairIslands.Name = "cbRepairIslands";
- this.cbRepairIslands.Size = new System.Drawing.Size(130, 24);
- this.cbRepairIslands.TabIndex = 16;
- this.cbRepairIslands.Text = "Repair Islands";
- this.cbRepairIslands.UseVisualStyleBackColor = true;
- //
// label1
//
this.label1.AutoSize = true;
@@ -263,6 +237,18 @@ namespace UVtools.GUI.Forms
this.label1.Text = "Opening Iterations:";
this.toolTip.SetToolTip(this.label1, resources.GetString("label1.ToolTip"));
//
+ // cbRepairIslands
+ //
+ this.cbRepairIslands.AutoSize = true;
+ this.cbRepairIslands.Checked = true;
+ this.cbRepairIslands.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.cbRepairIslands.Location = new System.Drawing.Point(17, 246);
+ this.cbRepairIslands.Name = "cbRepairIslands";
+ this.cbRepairIslands.Size = new System.Drawing.Size(194, 24);
+ this.cbRepairIslands.TabIndex = 16;
+ this.cbRepairIslands.Text = "Repair Layers + Islands";
+ this.cbRepairIslands.UseVisualStyleBackColor = true;
+ //
// numOpeningIterations
//
this.numOpeningIterations.Location = new System.Drawing.Point(459, 208);
@@ -276,6 +262,18 @@ namespace UVtools.GUI.Forms
0,
0});
//
+ // cbRepairResinTraps
+ //
+ this.cbRepairResinTraps.AutoSize = true;
+ this.cbRepairResinTraps.Checked = true;
+ this.cbRepairResinTraps.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.cbRepairResinTraps.Location = new System.Drawing.Point(17, 272);
+ this.cbRepairResinTraps.Name = "cbRepairResinTraps";
+ this.cbRepairResinTraps.Size = new System.Drawing.Size(164, 24);
+ this.cbRepairResinTraps.TabIndex = 19;
+ this.cbRepairResinTraps.Text = "Repair Resin Traps";
+ this.cbRepairResinTraps.UseVisualStyleBackColor = true;
+ //
// btnLayerRangeSelect
//
this.btnLayerRangeSelect.Location = new System.Drawing.Point(459, 168);
@@ -292,10 +290,10 @@ namespace UVtools.GUI.Forms
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(606, 308);
+ this.Controls.Add(this.cbRepairResinTraps);
this.Controls.Add(this.numOpeningIterations);
this.Controls.Add(this.label1);
this.Controls.Add(this.cbRepairIslands);
- this.Controls.Add(this.cbRepairLayers);
this.Controls.Add(this.btnLayerRangeSelect);
this.Controls.Add(this.lbLayerRangeTo);
this.Controls.Add(this.nmLayerRangeEnd);
@@ -344,10 +342,10 @@ namespace UVtools.GUI.Forms
private System.Windows.Forms.ToolStripMenuItem btnLayerRangeCurrentLayer;
private System.Windows.Forms.ToolStripMenuItem btnLayerRangeBottomLayers;
private System.Windows.Forms.ToolStripMenuItem btnLayerRangeNormalLayers;
- private System.Windows.Forms.CheckBox cbRepairLayers;
private System.Windows.Forms.ToolTip toolTip;
private System.Windows.Forms.CheckBox cbRepairIslands;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown numOpeningIterations;
+ private System.Windows.Forms.CheckBox cbRepairResinTraps;
}
} \ No newline at end of file
diff --git a/UVtools.GUI/Forms/FrmRepairLayers.cs b/UVtools.GUI/Forms/FrmRepairLayers.cs
index e065d1a..3e197e0 100644
--- a/UVtools.GUI/Forms/FrmRepairLayers.cs
+++ b/UVtools.GUI/Forms/FrmRepairLayers.cs
@@ -44,6 +44,12 @@ namespace UVtools.GUI.Forms
get => cbRepairIslands.Checked;
set => cbRepairIslands.Checked = value;
}
+
+ public bool RepairResinTraps
+ {
+ get => cbRepairResinTraps.Checked;
+ set => cbRepairResinTraps.Checked = value;
+ }
#endregion
#region Constructors
@@ -154,6 +160,13 @@ namespace UVtools.GUI.Forms
numClosingIterations.Select();
return;
}
+
+ if (!cbRepairIslands.Enabled && !cbRepairResinTraps.Enabled)
+ {
+ MessageBox.Show("You must select at least one repair operation.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+
if (MessageBox.Show("Are you sure you want to attempt this repair?", Text, MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
diff --git a/UVtools.GUI/Forms/FrmRepairLayers.resx b/UVtools.GUI/Forms/FrmRepairLayers.resx
index b58bc91..8d221ec 100644
--- a/UVtools.GUI/Forms/FrmRepairLayers.resx
+++ b/UVtools.GUI/Forms/FrmRepairLayers.resx
@@ -138,9 +138,6 @@ Note: "Layer Start" start can't be higher than "Layer End".</value>
<metadata name="cmLayerRange.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
- <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>148, 17</value>
- </metadata>
<data name="label1.ToolTip" xml:space="preserve">
<value>Selects the number of iterations/passes to perform on each layer.
Choose 0 to disable this step.
diff --git a/UVtools.GUI/FrmMain.Designer.cs b/UVtools.GUI/FrmMain.Designer.cs
index 17f2258..f9513c9 100644
--- a/UVtools.GUI/FrmMain.Designer.cs
+++ b/UVtools.GUI/FrmMain.Designer.cs
@@ -320,8 +320,8 @@
this.menuToolsRepairLayers.Name = "menuToolsRepairLayers";
this.menuToolsRepairLayers.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Alt)
| System.Windows.Forms.Keys.R)));
- this.menuToolsRepairLayers.Size = new System.Drawing.Size(204, 22);
- this.menuToolsRepairLayers.Text = "&Repair layers";
+ this.menuToolsRepairLayers.Size = new System.Drawing.Size(261, 22);
+ this.menuToolsRepairLayers.Text = "&Repair layers and Issues";
this.menuToolsRepairLayers.Click += new System.EventHandler(this.EventClick);
//
// viewToolStripMenuItem
@@ -1041,7 +1041,9 @@
this.tsIssueRemove.Name = "tsIssueRemove";
this.tsIssueRemove.Size = new System.Drawing.Size(70, 22);
this.tsIssueRemove.Text = "Remove";
- this.tsIssueRemove.ToolTipText = "Remove selected issue when possible";
+ this.tsIssueRemove.ToolTipText = "Remove selected issue when possible\r\nIslands: All pixels are removed (turn black)" +
+ "\r\nResinTrap: All trap areas are filled with white pixels.\r\nTouchingBounds: No ac" +
+ "tion, need reslice.";
this.tsIssueRemove.Click += new System.EventHandler(this.EventClick);
//
// toolStripSeparator12
diff --git a/UVtools.GUI/FrmMain.cs b/UVtools.GUI/FrmMain.cs
index 7905296..3cc5222 100644
--- a/UVtools.GUI/FrmMain.cs
+++ b/UVtools.GUI/FrmMain.cs
@@ -553,6 +553,8 @@ namespace UVtools.GUI
uint layerEnd;
uint closingIterations;
uint openingIterations;
+ bool repairIslands;
+ bool repairResinTraps;
using (var frmRepairLayers = new FrmRepairLayers(2))
{
if (frmRepairLayers.ShowDialog() != DialogResult.OK) return;
@@ -561,10 +563,17 @@ namespace UVtools.GUI
layerEnd = frmRepairLayers.LayerRangeEnd;
closingIterations = frmRepairLayers.ClosingIterations;
openingIterations = frmRepairLayers.OpeningIterations;
+ repairIslands = frmRepairLayers.RepairIslands;
+ repairResinTraps = frmRepairLayers.RepairResinTraps;
+ }
+
+ if (repairResinTraps && ReferenceEquals(Issues, null))
+ {
+ ComputeIssues();
}
DisableGUI();
- FrmLoading.SetDescription("Reparing Layers");
+ FrmLoading.SetDescription("Reparing Layers and Issues");
Task<bool> task = Task<bool>.Factory.StartNew(() =>
{
@@ -572,26 +581,43 @@ namespace UVtools.GUI
try
{
- Parallel.For(layerStart, layerEnd + 1, i =>
+ Parallel.For(layerStart, layerEnd + 1, layerIndex =>
{
- Layer layer = SlicerFile[i];
- var image = layer.Image;
- var imageEgmu = image.ToEmguImage();
-
- if (closingIterations > 0)
+ Layer layer = SlicerFile[layerIndex];
+ using (var image = layer.Image)
{
- imageEgmu = imageEgmu.Dilate((int) closingIterations);
- imageEgmu = imageEgmu.Erode((int) closingIterations);
- }
+ var imageEgmu = image.ToEmguImage();
- if (openingIterations > 0)
- {
- imageEgmu = imageEgmu.Erode((int) openingIterations);
- imageEgmu = imageEgmu.Dilate((int) openingIterations);
- }
+ if (repairResinTraps)
+ {
+ if (Issues.TryGetValue((uint) layerIndex, out var issues))
+ {
+ foreach (var issue in issues)
+ {
+ if(issue.Type != LayerIssue.IssueType.ResinTrap) continue;
+ imageEgmu.Draw(new VectorOfVectorOfPoint(new VectorOfPoint(issue.Pixels)), -1, new Gray(255), -1);
+ }
+ }
+ }
+
+ if (repairIslands)
+ {
+ if (closingIterations > 0)
+ {
+ imageEgmu = imageEgmu.Dilate((int) closingIterations);
+ imageEgmu = imageEgmu.Erode((int) closingIterations);
+ }
+
+ if (openingIterations > 0)
+ {
+ imageEgmu = imageEgmu.Erode((int) openingIterations);
+ imageEgmu = imageEgmu.Dilate((int) openingIterations);
+ }
+ }
- layer.Image = imageEgmu.ToImageSharpL8();
- imageEgmu.Dispose();
+ layer.Image = imageEgmu.ToImageSharpL8();
+ imageEgmu.Dispose();
+ }
});
result = true;
}
@@ -870,43 +896,105 @@ namespace UVtools.GUI
if (MessageBox.Show("Are you sure you want to remove all selected issues from image?\n" +
"Warning: Removing a island can cause another issues to appears if the next layer have land in top of the removed island.\n" +
"Always check previous and next layer before perform a island removal to ensure safe operation.",
- "Remove islands?",
+ "Remove Issues?",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;
+ Dictionary<uint, List<LayerIssue>> processIssues = new Dictionary<uint, List<LayerIssue>>();
+
foreach (ListViewItem item in lvIssues.SelectedItems)
{
if (!(item.Tag is LayerIssue issue)) continue;
+ if (!issue.HaveValidPoint) continue;
- var image = ActualLayer == issue.Layer.Index ? ActualLayerImage : issue.Layer.Image;
+ if (!processIssues.TryGetValue(issue.Layer.Index, out var issueList))
+ {
+ issueList = new List<LayerIssue>();
+ processIssues.Add(issue.Layer.Index, issueList);
+ }
- if(!issue.HaveValidPoint) continue;
-
- foreach (var pixel in issue)
+ issueList.Add(issue);
+ }
+
+
+ DisableGUI();
+ FrmLoading.SetDescription("Removing selected issues");
+
+ Task<bool> task = Task<bool>.Factory.StartNew(() =>
+ {
+ bool result = false;
+ try
{
- image[pixel.X, pixel.Y] = Helpers.L8Black;
- if (ActualLayer == issue.Layer.Index)
+ Parallel.ForEach(processIssues, layerIssues =>
{
- int x = pixel.X;
- int y = pixel.Y;
-
- if (tsLayerImageRotate.Checked)
+ using (var image = SlicerFile[layerIssues.Key].Image)
{
- x = ActualLayerImage.Height - 1 - pixel.Y;
- y = pixel.X;
- }
+ using (var imageEmgu = image.ToEmguImage())
+ {
+ var data = imageEmgu.Data;
- ((Bitmap) pbLayer.Image).SetPixel(x, y, Color.DarkRed);
- }
+ bool edited = false;
+
+ foreach (var issue in layerIssues.Value)
+ {
+ if (issue.Type == LayerIssue.IssueType.Island)
+ {
+ foreach (var pixel in issue)
+ {
+ data[pixel.Y, pixel.X, 0] = 0;
+ }
+
+ edited = true;
+ }
+ else if (issue.Type == LayerIssue.IssueType.ResinTrap)
+ {
+ imageEmgu.Draw(new VectorOfVectorOfPoint(new VectorOfPoint(issue.Pixels)),
+ -1, new Gray(255), -1);
+ edited = true;
+ }
+
+ }
+
+ if (!edited) return;
+ SlicerFile[layerIssues.Key].Image = imageEmgu.ToImageSharpL8();
+ result = true;
+ }
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Unsuccessful Removal", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
+ finally
+ {
+ Invoke((MethodInvoker)delegate {
+ // Running on the UI thread
+ EnableGUI(true);
+ });
+ }
+
+ return result;
+ });
+
+ FrmLoading.ShowDialog();
- if (ActualLayer == issue.Layer.Index) pbLayer.Invalidate();
+ if (!task.Result) return;
+
+ // Update GUI
+ lvIssues.BeginUpdate();
+ foreach (ListViewItem item in lvIssues.SelectedItems)
+ {
+ if (!(item.Tag is LayerIssue issue)) continue;
+ if (!issue.HaveValidPoint) continue;
+ if (issue.Type == LayerIssue.IssueType.TouchingBound) continue;
- issue.Layer.Image = image;
Issues[issue.Layer.Index].Remove(issue);
- TotalIssues--;
item.Remove();
+ TotalIssues--;
}
+ lvIssues.EndUpdate();
+ ShowLayer();
UpdateIssuesInfo();
menuFileSave.Enabled =
menuFileSaveAs.Enabled = true;
@@ -1181,7 +1269,7 @@ namespace UVtools.GUI
}
pbLayer.ZoomToRegion(x, y, 5, 5);
- //pbLayer.ZoomOut(true);
+ pbLayer.ZoomOut(true);
}
else
{
@@ -1191,6 +1279,7 @@ namespace UVtools.GUI
tsLayerImageRotate.Checked ? issue.BoundingRectangle.Height : issue.BoundingRectangle.Width,
tsLayerImageRotate.Checked ? issue.BoundingRectangle.Width : issue.BoundingRectangle.Height
);
+ pbLayer.ZoomOut(true);
}
}
@@ -1629,19 +1718,23 @@ namespace UVtools.GUI
Image<Gray, byte> greyscale = ActualLayerImage.ToEmguImage();
#if DEBUG
- grayscale = grayscale.ThresholdBinary(new Gray(254), new Gray(255));
+ greyscale = greyscale.ThresholdBinary(new Gray(254), new Gray(255));
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
Mat external = new Mat();
- CvInvoke.FindContours(grayscale, contours, external, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
+ CvInvoke.FindContours(greyscale, contours, external, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
var arr = external.GetData();
for (int i = 0; i < contours.Size; i++)
{
if ((int)arr.GetValue(0, i, 2) != -1 || (int)arr.GetValue(0, i, 3) == -1) continue;
var r = CvInvoke.BoundingRectangle(contours[i]);
- CvInvoke.Rectangle(grayscale, r, new MCvScalar(125), 10);
+ CvInvoke.Rectangle(greyscale, r, new MCvScalar(80), 3);
+
+ greyscale.Draw(contours, i, new Gray(125), -1);
+
}
+
#else
greyscale = greyscale.Canny(80, 40, 3, true);
#endif
@@ -1738,8 +1831,9 @@ namespace UVtools.GUI
using (var dummyImage = new Image<Gray, byte>(ActualLayerImage.Width,
ActualLayerImage.Height))
{
- dummyImage.FillConvexPoly(issue.Pixels, new Gray(255));
- dummyImage.DrawPolyline(issue.Pixels, true, new Gray(125), 2);
+ dummyImage.Draw(new VectorOfVectorOfPoint(new VectorOfPoint(issue.Pixels)), -1, new Gray(255), -1);
+ //dummyImage.FillConvexPoly(issue.Pixels, new Gray(255));
+ dummyImage.DrawPolyline(issue.Pixels, true, new Gray(125), 1);
byte[,,] data = dummyImage.Data;
for (int y = issue.BoundingRectangle.Y; y < issue.BoundingRectangle.Bottom; y++)
{
@@ -1884,7 +1978,6 @@ namespace UVtools.GUI
if(ReferenceEquals(tabControlLeft.SelectedTab, tabPageIssues))
{
if (!ReferenceEquals(tabPageIssues.Tag, null)) return;
- tabPageIssues.Tag = true;
ComputeIssues();
}
return;
@@ -2144,7 +2237,7 @@ namespace UVtools.GUI
imageEgmu = resizedImage.Copy(new Rectangle(0, 0, image.Width, image.Height));
break;
case Mutation.Mutates.Solidify:
- for (byte pass = 0; pass < 2; pass++) // Passes
+ for (byte pass = 0; pass < 1; pass++) // Passes
{
var imageThreshold = imageEgmu.ThresholdBinary(new Gray(254), new Gray(255)); // Clean AA
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
@@ -2164,9 +2257,9 @@ namespace UVtools.GUI
{
if ((int)arr.GetValue(0, i, 2) != -1 || (int)arr.GetValue(0, i, 3) == -1) continue;
var r = CvInvoke.BoundingRectangle(contours[i]);
- imageEgmu.FillConvexPoly(contours[i].ToArray(), new Gray(255));
+ //imageEgmu.FillConvexPoly(contours[i].ToArray(), new Gray(255));
//imageThreshold.FillConvexPoly(contours[i].ToArray(), new Gray(255));
- //CvInvoke.po
+ imageEgmu.Draw(contours, i, new Gray(255), -1);
}
// Attempt to close any tiny region
@@ -2276,6 +2369,7 @@ namespace UVtools.GUI
private void ComputeIssues()
{
+ tabPageIssues.Tag = true;
TotalIssues = 0;
lvIssues.BeginUpdate();
lvIssues.Items.Clear();
@@ -2290,23 +2384,24 @@ namespace UVtools.GUI
bool result = false;
try
{
- var issues = SlicerFile.LayerManager.GetAllIssues();
- Issues = new Dictionary<uint, List<LayerIssue>>();
-
- for (uint i = 0; i < SlicerFile.LayerCount; i++)
+ Task taskGenericIssues = Task.Factory.StartNew(() =>
{
- if (issues.TryGetValue(i, out var list))
+ var issues = SlicerFile.LayerManager.GetAllIssues();
+ Issues = new Dictionary<uint, List<LayerIssue>>();
+
+ for (uint i = 0; i < SlicerFile.LayerCount; i++)
{
- Issues.Add(i, list);
+ if (issues.TryGetValue(i, out var list))
+ {
+ Issues.Add(i, list);
+ }
}
- }
+ });
+
- return true;
var layerHollowAreas = new ConcurrentDictionary<uint, List<LayerHollowArea>>();
- Stopwatch sw = new Stopwatch();
- sw.Start();
Parallel.ForEach(SlicerFile,
//new ParallelOptions{MaxDegreeOfParallelism = 1},
layer =>
@@ -2344,95 +2439,119 @@ namespace UVtools.GUI
}
});
- List<LayerHollowArea> linkedAreas = new List<LayerHollowArea>();
- LayerHollowArea lastCheckedArea;
+
for (uint layerIndex = 1; layerIndex < SlicerFile.LayerCount-1; layerIndex++) // Ignore first and last layers, always drains
{
if(!layerHollowAreas.TryGetValue(layerIndex, out var areas)) continue; // No hollow areas in this layer, ignore
byte areaCount = 0;
- foreach (var area in areas)
+ //foreach (var area in areas)
+ Parallel.ForEach(areas, area =>
{
- if (area.Type != LayerHollowArea.AreaType.Unknown) continue; // processed, ignore
+ if (area.Type != LayerHollowArea.AreaType.Unknown) return; // processed, ignore
area.Type = LayerHollowArea.AreaType.Trap;
areaCount++;
- linkedAreas.Clear();
-
+ List<LayerHollowArea> linkedAreas = new List<LayerHollowArea>();
+
for (sbyte dir = 1; dir >= -1 && area.Type != LayerHollowArea.AreaType.Drain; dir -= 2)
+ //Parallel.ForEach(dirs, new ParallelOptions {MaxDegreeOfParallelism = 2}, dir =>
{
Queue<LayerHollowArea> queue = new Queue<LayerHollowArea>();
queue.Enqueue(area);
+ area.Processed = false;
int nextLayerIndex = (int) layerIndex;
while (queue.Count > 0 && area.Type != LayerHollowArea.AreaType.Drain)
{
- lastCheckedArea = queue.Dequeue();
+ LayerHollowArea checkArea = queue.Dequeue();
+ if (checkArea.Processed) continue;
+ checkArea.Processed = true;
nextLayerIndex += dir;
- Debug.WriteLine($"Area Count: {areaCount} | Layer: {layerIndex} | Next Layer: {nextLayerIndex} | Dir: {dir}");
- if (nextLayerIndex < 0 && nextLayerIndex >= SlicerFile.LayerCount) break; // Exhaust layers
- bool haveNextAreas = layerHollowAreas.TryGetValue((uint)nextLayerIndex, out var nextAreas);
+ Debug.WriteLine(
+ $"Area Count: {areaCount} | Layer: {layerIndex} | Next Layer: {nextLayerIndex} | Dir: {dir}");
+ if (nextLayerIndex < 0 && nextLayerIndex >= SlicerFile.LayerCount)
+ break; // Exhaust layers
+ bool haveNextAreas =
+ layerHollowAreas.TryGetValue((uint) nextLayerIndex, out var nextAreas);
using (var image = SlicerFile[nextLayerIndex].Image)
{
- using (var emguImage = new Image<Gray, byte>(ActualLayerImage.Width, ActualLayerImage.Height))
+ using (var emguImage = new Image<Gray, byte>(ActualLayerImage.Width,
+ ActualLayerImage.Height))
{
image.TryGetSinglePixelSpan(out var span);
- emguImage.FillConvexPoly(lastCheckedArea.Contour, new Gray(255));
+ //emguImage.FillConvexPoly(checkArea.Contour, new Gray(255));
+ emguImage.Draw(new VectorOfVectorOfPoint(new VectorOfPoint(checkArea.Contour)), -1,
+ new Gray(255), -1);
bool exitPixelLoop = false;
+ uint blackCount = 0;
byte[,,] data = emguImage.Data;
- for (int y = lastCheckedArea.BoundingRectangle.Y;
- y <= lastCheckedArea.BoundingRectangle.Bottom && area.Type != LayerHollowArea.AreaType.Drain && !exitPixelLoop;
+ for (int y = checkArea.BoundingRectangle.Y;
+ y <= checkArea.BoundingRectangle.Bottom &&
+ area.Type != LayerHollowArea.AreaType.Drain && !exitPixelLoop;
y++)
{
- for (int x = lastCheckedArea.BoundingRectangle.X;
- x <= lastCheckedArea.BoundingRectangle.Right && area.Type != LayerHollowArea.AreaType.Drain && !exitPixelLoop;
+ for (int x = checkArea.BoundingRectangle.X;
+ x <= checkArea.BoundingRectangle.Right &&
+ area.Type != LayerHollowArea.AreaType.Drain && !exitPixelLoop;
x++)
{
if (data[y, x, 0] != 255) continue;
+ if (span[y * image.Width + x].PackedValue > 30) continue;
+ blackCount++;
- if (span[y * image.Width + x] == Helpers.L8Black) // Found a black pixel: Drain or trap
+ if (haveNextAreas
+ ) // Have areas, can be on same area path or not
{
- if (haveNextAreas)
+ foreach (var nextArea in nextAreas)
{
- foreach (var nextArea in nextAreas)
+ /*if (!area.BoundingRectangle.IntersectsWith(nextArea.BoundingRectangle)) // If not intersect futher ispection is useless
+ {
+ continue;
+ }*/
+ if (!(CvInvoke.PointPolygonTest(
+ new VectorOfPoint(nextArea.Contour),
+ new PointF(x, y), false) >= 0)) continue;
+ if (nextArea.Type == LayerHollowArea.AreaType.Drain
+ ) // Found a drain, stop query
{
- if (!area.BoundingRectangle.IntersectsWith(nextArea.BoundingRectangle)) // If not intersect futher ispection is useless
- {
- continue;
- }
- if (CvInvoke.PointPolygonTest(new VectorOfPoint(nextArea.Contour),
- new PointF(x, y), false) >= 0)
- {
- if (nextArea.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
- {
- area.Type = LayerHollowArea.AreaType.Drain;
- }
- else
- {
- queue.Enqueue(nextArea);
- }
-
- linkedAreas.Add(nextArea);
-
- exitPixelLoop = true;
- break;
- }
+ area.Type = LayerHollowArea.AreaType.Drain;
}
- }
- else // Black pixel without next areas = Drain
- {
- area.Type = LayerHollowArea.AreaType.Drain;
+ else
+ {
+ queue.Enqueue(nextArea);
+ }
+
+ linkedAreas.Add(nextArea);
+
exitPixelLoop = true;
break;
}
- } // black check
+ }
+ else if(blackCount > Math.Min(checkArea.Contour.Length / 2, 10)) // Black pixel without next areas = Drain
+ {
+ area.Type = LayerHollowArea.AreaType.Drain;
+ exitPixelLoop = true;
+ break;
+ }
} // X loop
} // Y loop
+
+ if (queue.Count == 0 && blackCount > Math.Min(checkArea.Contour.Length / 2, 10))
+ {
+ /*Invoke((MethodInvoker)delegate
+ {
+ // Running on the UI thread
+ ShowLayer((uint)nextLayerIndex);
+ });*/
+ area.Type = LayerHollowArea.AreaType.Drain;
+ }
+
} // Dispose emgu image
} // Dispose image
} // Areas loop
@@ -2442,101 +2561,11 @@ namespace UVtools.GUI
{
linkedArea.Type = area.Type;
}
-
- /*for (sbyte dir = 1; dir >= -1; dir-=2)
- {
- Debug.WriteLine($"dir: {dir}");
- for (int nextLayerIndex = (int) (layerIndex + dir); nextLayerIndex >= 0 && nextLayerIndex < SlicerFile.LayerCount; nextLayerIndex+= dir) // Search on next layer
- {
- Debug.WriteLine($"Next Layer: {nextLayerIndex}");
- bool nextHaveAreas = layerHollowAreas.TryGetValue((uint) nextLayerIndex, out var nextList);
- // if (!layerHollowAreas.TryGetValue((uint) i, out var nextList)) // No areas found on next layer, check for tops
- // {
- area.Type = LayerHollowArea.AreaType.Trap;
- using (var image = SlicerFile[nextLayerIndex].Image)
- {
- using (var emguImage = new Image<Gray, byte>(ActualLayerImage.Width, ActualLayerImage.Height))
- {
- image.TryGetSinglePixelSpan(out var span);
- emguImage.FillConvexPoly(lastCheckedArea.Contour, new Gray(255));
-
- byte[,,] data = emguImage.Data;
- for (int y = lastCheckedArea.BoundingRectangle.Y;
- y < lastCheckedArea.BoundingRectangle.Bottom && area.Type != LayerHollowArea.AreaType.Drain;
- y++)
- {
- for (int x = lastCheckedArea.BoundingRectangle.X;
- x < lastCheckedArea.BoundingRectangle.Right && area.Type != LayerHollowArea.AreaType.Drain;
- x++)
- {
-
- if (data[y, x, 0] != 255) continue;
-
- var pixelIndex = y * image.Width + x;
- if (span[pixelIndex] == Helpers.L8Black) // Found a black pixel: Drain
- {
- if (nextHaveAreas)
- {
- foreach (var nextArea in nextList)
- {
- if (CvInvoke.PointPolygonTest(new VectorOfPoint(nextArea.Contour),
- new PointF(x, y), false) > 0)
- {
- linkedAreas.Add(nextArea);
- if (nextArea.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
- {
- area.Type = nextArea.Type;
- }
-
- break;
- }
- }
- }
- else
- {
- area.Type = LayerHollowArea.AreaType.Drain;
- break;
- }
- }
- }
- }
- }
- }
-
-
- if (area.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
- {
- break;
- }
- //}
-
- /*foreach (var nextArea in nextList)
- {
- if (area.BoundingRectangle.IntersectsWith(nextArea.BoundingRectangle))
- {
- lastCheckedArea = nextArea;
- linkedAreas.Add(nextArea);
- if (nextArea.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
- {
- area.Type = nextArea.Type;
- break;
- }
- }
- }*/
- /*}
-
- if(area.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
- break;
- }
-
- foreach (var linkedArea in linkedAreas) // Update linked areas
- {
- linkedArea.Type = area.Type;
- }*/
- }
+ });
}
- Issues = new Dictionary<uint, List<LayerIssue>>();
+ taskGenericIssues.Wait();
+
for (uint layerIndex = 0; layerIndex < SlicerFile.LayerCount; layerIndex++)
{
if (!layerHollowAreas.TryGetValue(layerIndex, out var list)) continue;
@@ -2552,15 +2581,20 @@ namespace UVtools.GUI
}
}
- if (issues.Count > 0)
+ if (issuesHollow.Count > 0)
{
- Issues.Add(layerIndex, issuesHollow);
+ if (Issues.TryGetValue(layerIndex, out var currentIssue))
+ {
+ currentIssue.AddRange(issuesHollow);
+ }
+ else
+ {
+ Issues.Add(layerIndex, issuesHollow);
+ }
}
}
}
- sw.Stop();
- Debug.WriteLine($"RectSearch: {sw.ElapsedMilliseconds}ms");
result = true;
}
@@ -2615,8 +2649,8 @@ namespace UVtools.GUI
}
lvIssues.EndUpdate();
-
UpdateIssuesInfo();
+ ShowLayer();
}
private void EventMouseDown(object sender, MouseEventArgs e)
diff --git a/UVtools.GUI/FrmMain.resx b/UVtools.GUI/FrmMain.resx
index fb7b729..a2492a8 100644
--- a/UVtools.GUI/FrmMain.resx
+++ b/UVtools.GUI/FrmMain.resx
@@ -126,6 +126,12 @@
<metadata name="tsLayer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>201, 17</value>
</metadata>
+ <metadata name="tsThumbnails.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>291, 17</value>
+ </metadata>
+ <metadata name="tsProperties.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>649, 17</value>
+ </metadata>
<metadata name="tsGCode.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>551, 17</value>
</metadata>
@@ -140,84 +146,69 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA4
- DgAAAk1TRnQBSQFMAgEBBAEAASABBAEgAQQBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ DgAAAk1TRnQBSQFMAgEBBAEAAUABBAFAAQQBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AZgADUAGjA1IBqQNS
- AakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1ABo1wAAxUBHQFCAXABgAH1
- AUABhQGMAfcDQwF3A1sByAJCAXsB9QJYAV8B4wNKAYwDCgENBAADVQG0A1kBxwMvAUkDAAEBAxsBJgMc
+ AakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1ABo1wAAxUBHQFCAWwBcwH1
+ AUgBgQGHAfcDQwF3A1sByAJCAW8B9QJYAV8B4wNKAYwDCgENBAADVQG0A1kBxwMvAUkDAAEBAxsBJgMc
AScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDAgEDBAADUgGpMAADUgGpEAADJwE6
AzABTAMwAUwDMAFMAzABTAMwAUwDMAFMAzABTAMwAUwDJwE6FAADBQEHA0wBkgFWAlgBwQMVAR0DPQFp
- AQkByAHzAf8BFwGQAeYB/wItAdwB/wItAd0B/wJiAeMB/wI4Ad4B/wItAd0B/wJYAVsBywMGAQgDAAH/
+ AQUByAHzAf8BEwGQAeYB/wIpAdwB/wIpAd0B/wJeAeMB/wI0Ad4B/wIpAd0B/wJYAVsBywMGAQgDAAH/
AwAB/wNDAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMgFR
BAADUgGpBAADUAGdA1MBqgNTAaoDUwGqA1MBqgNTAaoDUwGqA1ABnQwAA1IBqRAAA04B+wMAAf8DAAH/
- AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A04B+xQAATACMQFNAQoByQHzAf8BCgHJAfQB/wFZAWcBaQHr
- AVsCXgHZAQ0BwAHxAf8BLgE2Ad8B/wIwAeAB/wIwAeAB/wJpAekB/wI7AeIB/wIwAeAB/wIwAeAB/wNA
+ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A04B+xQAATACMQFNAQYByQHzAf8BBgHJAfQB/wFZAWIBZAHr
+ AVsCXgHZAQkBwAHxAf8BKgEyAd8B/wIsAeAB/wIsAeAB/wJlAekB/wI3AeIB/wIsAeAB/wIsAeAB/wNA
AXEDUQGiA1YBtgMqAUAEAAMQARUDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEAEW
CAADUgGpBAADUAGdA1MBqgNTAaoDHwEsHAADUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
- Af8DAAH/AwAB/xQAAwcBCgFPAXIBeQHyAQwBygH0Af8BDAHKAfQB/wEMAcoB9AH/ARgBoQHuAf8CMwHj
- Af8CMwHjAf8CMwHjAf8CqQHvAf8COgHjAf8CMwHjAf8CMwHjAf8CVgFYAbkDCgEOAxEBFwMAAQE4AANS
+ Af8DAAH/AwAB/xQAAwcBCgFWAWkBbwHyAQgBygH0Af8BCAHKAfQB/wEIAcoB9AH/ARQBoQHuAf8CLwHj
+ Af8CLwHjAf8CLwHjAf8CqQHvAf8CNgHjAf8CLwHjAf8CLwHjAf8CVgFYAbkDCgEOAxEBFwMAAQE4AANS
AakwAANSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADFQEdAz0BaQM6
- AWIBXAJgAdQBDQHLAfUB/wENAcsB9QH/AQ0BywH1Af8BGwGgAfAB/wI2AeYB/wI2AeYB/wI2AeYB/wLC
- AfYB/wJOAegB/wI2AeYB/wI2AeYB/wJXAVkBvwNSAfQDAAH/Az4BbAMOARMDQgF2A0MBdwNDAXcDQwF3
+ AWIBXAJgAdQBCQHLAfUB/wEJAcsB9QH/AQkBywH1Af8BFwGgAfAB/wIyAeYB/wIyAeYB/wIyAeYB/wLC
+ AfYB/wJKAegB/wIyAeYB/wIyAeYB/wJXAVkBvwNSAfQDAAH/Az4BbAMOARMDQgF2A0MBdwNDAXcDQwF3
A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0IBdgMUARsEAANSAakDIgEyA1IBqQNSAakDUgGpA1IBqQNS
AakDUgGpA1IBqQNSAakDUgGpA1IBqQMiATIDUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
- Af8DAAH/AwAB/wwAAUsCTAGQAQ4BywH2Af8BDgHLAfYB/wEOAcsB9gH/AQ4BywH2Af8BKQGSAaQB+gND
- AXgDIgEyAksBogH7AjkB6QH/AjkB6QH/As0B+AH/Al0B7QH/AjkB6QH/AjkB6QH/A1ABngMAAf4DAAH/
+ Af8DAAH/AwAB/wwAAUsCTAGQAQoBywH2Af8BCgHLAfYB/wEKAcsB9gH/AQoBywH2Af8BKQGGAZwB+gND
+ AXgDIgEyAksBmAH7AjUB6QH/AjUB6QH/As0B+AH/AlkB7QH/AjUB6QH/AjUB6QH/A1ABngMAAf4DAAH/
A0MBdwMeASsDVwHFA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1gBxgMmATkEAANS
AakDNAFVAzQBVSAAAzQBVQM0AVUDUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/
- AwAB/wwAA1EBoAEQAcwB9wH/ARABzAH3Af8BEAHMAfcB/wEQAcwB9wH/A0MBdwgAA0oBjQI8AewB/wI8
- AewB/wJYAe8B/wJAAewB/wI8AewB/wE4AUkB7QH/AVICUwGoAzMBUwM8AWcDFAEcOAADUgGpAzQBVQM0
+ AwAB/wwAA1EBoAEMAcwB9wH/AQwBzAH3Af8BDAHMAfcB/wEMAcwB9wH/A0MBdwgAA0oBjQI4AewB/wI4
+ AewB/wJUAe8B/wI8AewB/wI4AewB/wE0AUUB7QH/AVICUwGoAzMBUwM8AWcDFAEcOAADUgGpAzQBVQM0
AVUDRgGAA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA0UBfwM0AVUDNAFVA1IBqRMAAf8DAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8PAAEBAT8CQAFvAT4BiwGYAfgBEQHNAfcB/wERAc0B9wH/
- AxIBGAgAAwEBAgNGAX4CUgFsAfACPwHuAf8BPwFAAe4B/wFAAVIBvgH9AUUCRgF+AwMBBAMzAVMDPAFn
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8PAAEBAT8CQAFvAT4BfwGQAfgBDQHNAfcB/wENAc0B9wH/
+ AxIBGAgAAwEBAgNGAX4CUgFnAfACOwHuAf8BOwE8Ae4B/wFAAU4BugH9AUUCRgF+AwMBBAMzAVMDPAFn
AxQBHDgAA1IBqQM0AVUDNAFVAz8BbgMyAVAQAAMnATsDRAF8AzQBVQM0AVUDUgGpEwAB/wMAAf8DAAH/
- AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/w8AAQEBPwJAAW8BPgGLAZgB+AESAc4B+AH/ARIBzgH4
- Af8DEgEYEAADFwEgARkBvAH3Af8BFgHEAfcB/wE2AbIBwgH9AUUCRgF+AwMBBAMAAf4DAAH/A0MBdwMf
+ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/w8AAQEBPwJAAW8BPgF/AZAB+AEOAc4B+AH/AQ4BzgH4
+ Af8DEgEYEAADFwEgARUBvAH3Af8BEgHEAfcB/wE6Aa4BvAH9AUUCRgF+AwMBBAMAAf4DAAH/A0MBdwMf
ASwDVwHFA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1gBxgMmATkEAANSAakDNAFV
AzQBVQMFAQcDVQG1AxEBFwNSAakDKQE+BAADUAGfAxEBFwM0AVUDNAFVA1IBqRMAAf8DAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8MAANRAaABFAHOAfgB/wEUAc8B+QH/ARQBzwH5Af8BFAHP
- AfkB/wNDAXcQAANEAXoBFAHPAfkB/wEUAc8B+QH/ARQBzwH5Af8BFAHOAfgB/wFSAlMBqANSAfQDAAH/
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8MAANRAaABEAHOAfgB/wEQAc8B+QH/ARABzwH5Af8BEAHP
+ AfkB/wNDAXcQAANEAXoBEAHPAfkB/wEQAc8B+QH/ARABzwH5Af8BEAHOAfgB/wFSAlMBqANSAfQDAAH/
Az4BbAMOARMDQgF1A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwMUARsEAANS
AakDNAFVAzQBVQQAAzwBaANWAb4DIwE0A1UBtQMSARkDUQGgBAADNAFVAzQBVQNSAakTAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfDAABSwJMAZABFQHQAfoB/wEVAdAB+gH/ARUB0AH6
- Af8BFQHQAfoB/wEpAZIBpAH6A0MBeAMSARkDEwEaA0QBegEoAZUBqwH7ARUB0AH6Af8BFQHQAfoB/wEV
- AdAB+gH/ARUB0AH6Af8DSgGMAwoBDgMRARcDAAEBOAADUgGpAzQBVQM0AVUDAAEBAy0BRgMKAQ4EAAM5
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfDAABSwJMAZABEQHQAfoB/wERAdAB+gH/AREB0AH6
+ Af8BEQHQAfoB/wEpAYYBnAH6A0MBeAMSARkDEwEaA0QBegEoAZEBnQH7AREB0AH6Af8BEQHQAfoB/wER
+ AdAB+gH/AREB0AH6Af8DSgGMAwoBDgMRARcDAAEBOAADUgGpAzQBVQM0AVUDAAEBAy0BRgMKAQ4EAAM5
AV8DXAHOAygBPAQAAzQBVQM0AVUDUgGpEwAB/wOCAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHf
- AxcBIAwAAxUBHQM9AWkDOgFiAVwCYAHUARYB0QH6Af8BFgHRAfoB/wEWAdAB+gH/ARYBywHzAf8BFgHL
- AfMB/wEWAdAB+gH/ARYB0QH6Af8BFgHRAfoB/wFdAmEB4gM6AWIDPQFpAxQBHANRAaIDVgG2AyoBQAQA
+ AxcBIAwAAxUBHQM9AWkDOgFiAVwCYAHUARIB0QH6Af8BEgHRAfoB/wESAdAB+gH/ARIBywHzAf8BEgHL
+ AfMB/wESAdAB+gH/ARIB0QH6Af8BEgHRAfoB/wFdAmEB4gM6AWIDPQFpAxQBHANRAaIDVgG2AyoBQAQA
AxABFQMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMQARYIAANSAakDNAFVAzQBVQMz
AVMDUgGmA0oBjAcAAQEDRwGDCAADNAFVAzQBVQNSAakTAAH/A5kB/wOFAf8DAAH/AwAB/wMAAf8DAAH/
- A1wB3wMXASAYAAMHAQoBUwFyAXkB8gEYAdIB+wH/ARgB0gH7Af8BGAHSAfsB/wEYAdIB+wH/ARgB0gH7
- Af8BGAHSAfsB/wEYAdIB+wH/ARgB0gH7Af8BKwGWAasB+wMRARcLAAH/AwAB/wNDAXcDKQE+AwAB/wMA
+ A1wB3wMXASAYAAMHAQoBWAFpAW8B8gEUAdIB+wH/ARQB0gH7Af8BFAHSAfsB/wEUAdIB+wH/ARQB0gH7
+ Af8BFAHSAfsB/wEUAdIB+wH/ARQB0gH7Af8BKwGSAZ0B+wMRARcLAAH/AwAB/wNDAXcDKQE+AwAB/wMA
Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMgFRBAADUgGpAzQBVQM0AVUDEQEX
A1ABngMkATYUAAM0AVUDNAFVA1IBqRAAA1AB+wMAAf8DAAH/AwAB/wMAAf8DAAH/A1wB3wMXASAcAAEw
- AjEBTQEZAdIB/AH/ARkB0gH8Af8BWQFoAWoB6wFbAl4B2QEZAdIB/AH/ARkB0gH8Af8BWwJhAeEBXQJh
- AeIBGQHSAfwB/wEZAdIB/AH/AzgBXggAA1UBtANZAccDLwFJAwABAQMbASYDHAEnAxwBJwMcAScDHAEn
+ AjEBTQEVAdIB/AH/ARUB0gH8Af8BWQFjAWYB6wFbAl4B2QEVAdIB/AH/ARUB0gH8Af8BWwJhAeEBXQJh
+ AeIBFQHSAfwB/wEVAdIB/AH/AzgBXggAA1UBtANZAccDLwFJAwABAQMbASYDHAEnAxwBJwMcAScDHAEn
AxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAwIBAwQAA1IBqQMiATIDUgGpA1IBqQNSAakDUgGpA1IBqQNS
AakDUgGpA1IBqQNSAakDUgGpAyIBMgNSAakQAAMgAS4DKQE/AykBPwMpAT8DKQE/AykBPwMRARcgAAMF
- AQcDTAGSAVYCWAHBAxUBHQM9AWkBGgHTAfwB/wEaAdMB/AH/AUUCRgF/AxABFQNWAbMBSwJMAY8DBAEG
+ AQcDTAGSAVYCWAHBAxUBHQM9AWkBFgHTAfwB/wEWAdMB/AH/AUUCRgF/AxABFQNWAbMBSwJMAY8DBAEG
TAADUAGjA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1ABo1wA
- AxUBHQFCAXsBhAH1AUoBiQGWAfcDIAEvGAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEB
+ AxUBHQFCAW8BewH1AVEBhQGKAfcDIAEvGAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEB
FgAD/4EAAv8BgAEBAv8B/AEBAgABvwH9AeABBwHAAwABoAEdAeABBwHAAQABEAEBAaEB/QHgAQcBwAEA
AR8B/wG/Af0B4AEHBAABgAEBAeABBwQAAY8B8QHgAQcBAwEAAR8B/wGAAQEB4AEHAQMBAAEfAf8BgwHB
AeABBwEDAcACAAGAAUEB4AEHAQMBwAIAAYgBEQHgAQcCAAEfAf8BgQERAeABBwIAARABAQGBATEB4AEP
AcABAwIAAYEB8QHgAR8BwAEDAgABgAEBAeABPwHAAQMC/wGAAQEC/wH8AT8L
</value>
</data>
- <metadata name="tsThumbnails.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>291, 17</value>
- </metadata>
- <metadata name="tsProperties.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>649, 17</value>
- </metadata>
- <metadata name="tsGCode.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>551, 17</value>
- </metadata>
- <metadata name="tsIssues.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>765, 17</value>
- </metadata>
- <metadata name="toolTipInformation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>863, 17</value>
- </metadata>
<metadata name="toolTipInformation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>863, 17</value>
</metadata>
diff --git a/UVtools.GUI/Properties/AssemblyInfo.cs b/UVtools.GUI/Properties/AssemblyInfo.cs
index 04bc2a1..2e37d79 100644
--- a/UVtools.GUI/Properties/AssemblyInfo.cs
+++ b/UVtools.GUI/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.5.1.3")]
-[assembly: AssemblyFileVersion("0.5.1.3")]
+[assembly: AssemblyVersion("0.5.2.0")]
+[assembly: AssemblyFileVersion("0.5.2.0")]
diff --git a/UVtools.Parser/LayerManager.cs b/UVtools.Parser/LayerManager.cs
index 0403e49..9f84489 100644
--- a/UVtools.Parser/LayerManager.cs
+++ b/UVtools.Parser/LayerManager.cs
@@ -9,6 +9,7 @@ using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Dynamic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
@@ -70,7 +71,18 @@ namespace UVtools.Parser
/// <summary>
/// Gets the number of pixels on this issue
/// </summary>
- public uint Size => (uint) (Pixels?.Length ?? 0);
+ public uint Size {
+ get
+ {
+ if (Type == IssueType.ResinTrap && !BoundingRectangle.IsEmpty)
+ {
+ return (uint) (BoundingRectangle.Width * BoundingRectangle.Height);
+ }
+
+ if (ReferenceEquals(Pixels, null)) return 0;
+ return (uint) Pixels.Length;
+ }
+ }
/// <summary>
/// Check if this issue have a valid start point to show
@@ -125,6 +137,8 @@ namespace UVtools.Parser
public AreaType Type { get; set; } = AreaType.Unknown;
+ public bool Processed { get; set; }
+
#region Indexers
public Point this[uint index]
{
diff --git a/UVtools.Parser/UVtools.Parser.csproj b/UVtools.Parser/UVtools.Parser.csproj
index 752f6d5..b23027e 100644
--- a/UVtools.Parser/UVtools.Parser.csproj
+++ b/UVtools.Parser/UVtools.Parser.csproj
@@ -7,9 +7,9 @@
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<PackageIcon></PackageIcon>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
- <AssemblyVersion>0.5.1.3</AssemblyVersion>
- <FileVersion>0.5.1.3</FileVersion>
- <Version>0.5.1.3</Version>
+ <AssemblyVersion>0.5.2.0</AssemblyVersion>
+ <FileVersion>0.5.2.0</FileVersion>
+ <Version>0.5.2</Version>
<Description>MSLA/DLP, file analysis, repair, conversion and manipulation</Description>
<PackageId>UVtoolsParser</PackageId>
<PackageLicenseFile>LICENSE</PackageLicenseFile>