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>2021-04-04 08:00:40 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-04-04 08:00:40 +0300
commit8b2f5b2e33981a73de89577cc67f9d37fc1aeb3b (patch)
tree3129bd4d7d06ea06f37430bdeae02ae175e7256e /UVtools.Core
parent7b44ea73a98537c485b03c52f7f26733a30ba589 (diff)
v2.8.1
* Clipboard Manager: As now full backups are made when removing or adding layers, the undo and redo no longer rebuilds layer properties nor Z heights * Resin traps: Improved the detection to group areas with cross paths and process them as one whole area, this also increase the detection speed and performance (#179, #13 ) * Action - Layer import: Fix a bug preventing to import layers of any kind
Diffstat (limited to 'UVtools.Core')
-rw-r--r--UVtools.Core/Layer/LayerIssue.cs173
-rw-r--r--UVtools.Core/Layer/LayerManager.cs73
-rw-r--r--UVtools.Core/Managers/ClipboardManager.cs6
-rw-r--r--UVtools.Core/Operations/OperationLayerImport.cs6
-rw-r--r--UVtools.Core/Operations/OperationScripting.cs2
5 files changed, 212 insertions, 48 deletions
diff --git a/UVtools.Core/Layer/LayerIssue.cs b/UVtools.Core/Layer/LayerIssue.cs
index 15f9cff..812479f 100644
--- a/UVtools.Core/Layer/LayerIssue.cs
+++ b/UVtools.Core/Layer/LayerIssue.cs
@@ -11,6 +11,8 @@ using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
+using System.Runtime.InteropServices.ComTypes;
+using UVtools.Core.Objects;
namespace UVtools.Core
{
@@ -453,11 +455,128 @@ namespace UVtools.Core
#region ResinTrapGround
- public sealed class ResinTrapGroup
+ public sealed class ResinTrapGroup : BindableBase, IList<LayerHollowArea>
{
- public List<List<LayerHollowArea>> Groups { get; } = new();
+ #region List Implementation
+ private readonly List<LayerHollowArea> hollowAreaList = new();
+ private LayerHollowArea.AreaType _currentAreaType = LayerHollowArea.AreaType.Trap;
- public int FindHollowArea(LayerHollowArea hollowArea)
+ public IEnumerator<LayerHollowArea> GetEnumerator()
+ {
+ return hollowAreaList.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable) hollowAreaList).GetEnumerator();
+ }
+
+ public void Add(LayerHollowArea item)
+ {
+ if (item.Type == LayerHollowArea.AreaType.Drain)
+ {
+ CurrentAreaType = LayerHollowArea.AreaType.Drain;
+ }
+ else if (_currentAreaType == LayerHollowArea.AreaType.Drain)
+ {
+ item.Type = LayerHollowArea.AreaType.Drain;
+ }
+ hollowAreaList.Add(item);
+ }
+
+ public void Add(ResinTrapGroup group)
+ {
+ foreach (var area in group)
+ {
+ Add(area);
+ }
+ }
+
+ public void Clear()
+ {
+ CurrentAreaType = LayerHollowArea.AreaType.Trap;
+ hollowAreaList.Clear();
+ }
+
+ public bool Contains(LayerHollowArea item)
+ {
+ return hollowAreaList.Contains(item);
+ }
+
+ public void CopyTo(LayerHollowArea[] array, int arrayIndex)
+ {
+ hollowAreaList.CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(LayerHollowArea item)
+ {
+ var result = hollowAreaList.Remove(item);
+ if (Count == 0) CurrentAreaType = LayerHollowArea.AreaType.Trap;
+ return result;
+ }
+
+ public int Count => hollowAreaList.Count;
+
+ public bool IsReadOnly => false;
+
+ public int IndexOf(LayerHollowArea item)
+ {
+ return hollowAreaList.IndexOf(item);
+ }
+
+ public void Insert(int index, LayerHollowArea item)
+ {
+ if (item.Type == LayerHollowArea.AreaType.Drain)
+ {
+ CurrentAreaType = LayerHollowArea.AreaType.Drain;
+ }
+ else if (_currentAreaType == LayerHollowArea.AreaType.Drain)
+ {
+ item.Type = LayerHollowArea.AreaType.Drain;
+ }
+ hollowAreaList.Insert(index, item);
+ }
+
+ public void RemoveAt(int index)
+ {
+ hollowAreaList.RemoveAt(index);
+ if (Count == 0) CurrentAreaType = LayerHollowArea.AreaType.Trap;
+ }
+
+ public LayerHollowArea this[int index]
+ {
+ get => hollowAreaList[index];
+ set => hollowAreaList[index] = value;
+ }
+ #endregion
+
+ #region Properties
+ public LayerHollowArea.AreaType CurrentAreaType
+ {
+ get => _currentAreaType;
+ set
+ {
+ if(!RaiseAndSetIfChanged(ref _currentAreaType, value)) return;
+ foreach (var area in this) // Update previous items
+ {
+ area.Type = _currentAreaType;
+ }
+ }
+ }
+ #endregion
+ }
+
+ public sealed class ResinTrapTree
+ {
+ public List<ResinTrapGroup> Groups { get; } = new();
+
+ public ResinTrapGroup FindHollowGroup(LayerHollowArea hollowArea)
+ {
+ var i = FindHollowGroupIndex(hollowArea);
+ return i >= 0 ? Groups[i] : null;
+ }
+
+ public int FindHollowGroupIndex(LayerHollowArea hollowArea)
{
for (var i = 0; i < Groups.Count; i++)
{
@@ -470,20 +589,54 @@ namespace UVtools.Core
return -1;
}
- public int Add(LayerHollowArea hollowArea)
+ public ResinTrapGroup AddRoot(LayerHollowArea hollowArea) => AddRoot(hollowArea, out _);
+ public ResinTrapGroup AddRoot(LayerHollowArea hollowArea, out int index)
{
- var index = FindHollowArea(hollowArea);
+ index = FindHollowGroupIndex(hollowArea);
if (index < 0) // Not found
{
index = Groups.Count;
- Groups.Add(new List<LayerHollowArea>{hollowArea});
- return index;
+ Groups.Add(new(){hollowArea});
+ }
+ else // Exists
+ {
+ Groups[index].Add(hollowArea);
}
- // Exists
- Groups[index].Add(hollowArea);
+ return Groups[index];
+ }
+
+ public ResinTrapGroup AddChild(ResinTrapGroup group, LayerHollowArea hollowArea)
+ {
+ // This will find if the area exists in any other group,
+ // If yes then the groups are merged, otherwise it will be added to the parent group
- return index;
+ var findGroup = FindHollowGroup(hollowArea);
+ if (findGroup is not null && !ReferenceEquals(group, findGroup))
+ {
+ return MergeGroups(group, findGroup, true);
+ }
+ if(group.IndexOf(hollowArea) == -1) group.Add(hollowArea);
+ return group;
+ }
+
+ /// <summary>
+ /// Merges two groups
+ /// </summary>
+ /// <param name="group1"></param>
+ /// <param name="group2"></param>
+ /// <param name="manageGroups">True to remove old groups and add the new to group list</param>
+ /// <returns>A new group instance holding group1 and group2 items</returns>
+ public ResinTrapGroup MergeGroups(ResinTrapGroup group1, ResinTrapGroup group2, bool manageGroups = false)
+ {
+ ResinTrapGroup newGroup = new (){group1, group2};
+ if (manageGroups)
+ {
+ Groups.Remove(group1);
+ Groups.Remove(group2);
+ Groups.Add(newGroup);
+ }
+ return newGroup;
}
}
#endregion
diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs
index ae4c9a0..f64330b 100644
--- a/UVtools.Core/Layer/LayerManager.cs
+++ b/UVtools.Core/Layer/LayerManager.cs
@@ -10,9 +10,11 @@ using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
@@ -1005,9 +1007,9 @@ namespace UVtools.Core
islandImage = image;
}
- using (Mat labels = new Mat())
- using (Mat stats = new Mat())
- using (Mat centroids = new Mat())
+ using (Mat labels = new())
+ using (Mat stats = new())
+ using (Mat centroids = new())
{
var numLabels = CvInvoke.ConnectedComponentsWithStats(islandImage, labels, stats,
centroids,
@@ -1028,7 +1030,7 @@ namespace UVtools.Core
//stats[i][3]: Height of Connected Component
//stats[i][4]: Total Area (in pixels) in Connected Component
- Span<int> labelSpan = labels.GetPixelSpan<int>();
+ var labelSpan = labels.GetPixelSpan<int>();
for (int i = 1; i < numLabels; i++)
{
@@ -1169,35 +1171,30 @@ namespace UVtools.Core
if (canProcessCheck)
{
- if (previousImage is null)
- {
- previousImage = this[layer.Index - 1].LayerMat;
- }
+ previousImage ??= this[layer.Index - 1].LayerMat;
- using (var subtractedImage = new Mat())
- using (var vecPoints = new VectorOfPoint())
- {
- var anchor = new Point(-1, -1);
+ using var subtractedImage = new Mat();
+ using var vecPoints = new VectorOfPoint();
+ var anchor = new Point(-1, -1);
- CvInvoke.Subtract(image, previousImage, subtractedImage);
- CvInvoke.Threshold(subtractedImage, subtractedImage, 127, 255,
- ThresholdType.Binary);
+ CvInvoke.Subtract(image, previousImage, subtractedImage);
+ CvInvoke.Threshold(subtractedImage, subtractedImage, 127, 255,
+ ThresholdType.Binary);
- CvInvoke.Erode(subtractedImage, subtractedImage,
- CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3),
- anchor),
- anchor, overhangConfig.ErodeIterations, BorderType.Default,
- new MCvScalar());
+ CvInvoke.Erode(subtractedImage, subtractedImage,
+ CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3),
+ anchor),
+ anchor, overhangConfig.ErodeIterations, BorderType.Default,
+ new MCvScalar());
- CvInvoke.FindNonZero(subtractedImage, vecPoints);
- if (vecPoints.Size >= overhangConfig.RequiredPixelsToConsider)
- {
- AddIssue(new LayerIssue(
- layer, LayerIssue.IssueType.Overhang, vecPoints.ToArray(),
- layer.BoundingRectangle
- ));
- }
+ CvInvoke.FindNonZero(subtractedImage, vecPoints);
+ if (vecPoints.Size >= overhangConfig.RequiredPixelsToConsider)
+ {
+ AddIssue(new LayerIssue(
+ layer, LayerIssue.IssueType.Overhang, vecPoints.ToArray(),
+ layer.BoundingRectangle
+ ));
}
}
}
@@ -1268,7 +1265,7 @@ namespace UVtools.Core
{
progress.Reset(OperationProgress.StatusResinTraps, LayerCount);
-
+ ResinTrapTree resinTrapTree = new();
for (uint layerIndex = 1; layerIndex < LayerCount - 1; layerIndex++) // First and Last layers, always drains
{
@@ -1290,7 +1287,9 @@ namespace UVtools.Core
areaCount++;
- List<LayerHollowArea> linkedAreas = new();
+ var trapGroup = resinTrapTree.AddRoot(area);
+
+ //List<LayerHollowArea> linkedAreas = new();
for (sbyte dir = 1; dir >= -1 && area.Type != LayerHollowArea.AreaType.Drain; dir -= 2)
//Parallel.ForEach(new sbyte[] {1, -1}, new ParallelOptions {MaxDegreeOfParallelism = 2}, dir =>
@@ -1386,7 +1385,9 @@ namespace UVtools.Core
queue.Enqueue(intersectingAreas[i]);
}
- linkedAreas.Add(intersectingAreas[i]);
+
+ trapGroup = resinTrapTree.AddChild(trapGroup, intersectingAreas[i]);
+ //linkedAreas.Add(intersectingAreas[i]);
intersectingAreas.Remove(i);
if (intersectingAreas.Count == 0
) // Intersection areas sweep end, quit this path
@@ -1433,7 +1434,8 @@ namespace UVtools.Core
resinTrapConfig.RequiredBlackPixelsToDrain)
) // Black pixel without next areas = Drain
{
- area.Type = LayerHollowArea.AreaType.Drain;
+ trapGroup.CurrentAreaType = LayerHollowArea.AreaType.Drain;
+ //area.Type = LayerHollowArea.AreaType.Drain;
exitPixelLoop = true;
break;
}
@@ -1443,7 +1445,8 @@ namespace UVtools.Core
if (queue.Count == 0 && blackCount > Math.Min(checkArea.Contour.Length / 2,
resinTrapConfig.RequiredBlackPixelsToDrain))
{
- area.Type = LayerHollowArea.AreaType.Drain;
+ trapGroup.CurrentAreaType = LayerHollowArea.AreaType.Drain;
+ //area.Type = LayerHollowArea.AreaType.Drain;
}
} // Dispose intersecting image
@@ -1452,10 +1455,10 @@ namespace UVtools.Core
} // Areas loop
} // Dir layer loop
- foreach (var linkedArea in linkedAreas) // Update linked areas
+ /*foreach (var linkedArea in linkedAreas) // Update linked areas
{
linkedArea.Type = area.Type;
- }
+ }*/
}//);
}
}
diff --git a/UVtools.Core/Managers/ClipboardManager.cs b/UVtools.Core/Managers/ClipboardManager.cs
index a436625..6577f6b 100644
--- a/UVtools.Core/Managers/ClipboardManager.cs
+++ b/UVtools.Core/Managers/ClipboardManager.cs
@@ -130,7 +130,11 @@ namespace UVtools.Core.Managers
SlicerFile.LayerHeight = clip.LayerHeight;
}
- SlicerFile.LayerManager.Layers = Layer.CloneLayers(layers);
+ SlicerFile.SuppressRebuildPropertiesWork(() =>
+ {
+ SlicerFile.LayerManager.Layers = Layer.CloneLayers(layers);
+ });
+
if (i == _currentIndex) break;
}
}
diff --git a/UVtools.Core/Operations/OperationLayerImport.cs b/UVtools.Core/Operations/OperationLayerImport.cs
index e77fc49..438cff4 100644
--- a/UVtools.Core/Operations/OperationLayerImport.cs
+++ b/UVtools.Core/Operations/OperationLayerImport.cs
@@ -469,7 +469,11 @@ namespace UVtools.Core.Operations
}
- progress.LockAndIncrement();
+ lock (progress.Mutex)
+ {
+ lastProcessedLayerIndex = Math.Max(lastProcessedLayerIndex, (int)layerIndex);
+ progress++;
+ }
});
fileFormat.Dispose();
diff --git a/UVtools.Core/Operations/OperationScripting.cs b/UVtools.Core/Operations/OperationScripting.cs
index ea95c47..7807d16 100644
--- a/UVtools.Core/Operations/OperationScripting.cs
+++ b/UVtools.Core/Operations/OperationScripting.cs
@@ -41,7 +41,7 @@ namespace UVtools.Core.Operations
$"Make sure to run only the scripts you trust! Or run UVtools in a sandbox while executing this.";
public override string ConfirmationText =>
- $"Run script from layers {LayerIndexStart} through {LayerIndexEnd}?";
+ $"run the {ScriptGlobals.Script.Name} script from layers {LayerIndexStart} through {LayerIndexEnd}?";
public override string ProgressTitle =>
$"Scripting from layers {LayerIndexStart} through {LayerIndexEnd}";