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:
Diffstat (limited to 'UVtools.Core/Operations/OperationRaftRelief.cs')
-rw-r--r--UVtools.Core/Operations/OperationRaftRelief.cs191
1 files changed, 169 insertions, 22 deletions
diff --git a/UVtools.Core/Operations/OperationRaftRelief.cs b/UVtools.Core/Operations/OperationRaftRelief.cs
index 4c5a90a..c76b55a 100644
--- a/UVtools.Core/Operations/OperationRaftRelief.cs
+++ b/UVtools.Core/Operations/OperationRaftRelief.cs
@@ -7,17 +7,39 @@
*/
using System;
+using System.Drawing;
+using System.Threading.Tasks;
+using Emgu.CV;
+using Emgu.CV.CvEnum;
+using Emgu.CV.Structure;
+using UVtools.Core.Extensions;
+using UVtools.Core.FileFormats;
namespace UVtools.Core.Operations
{
[Serializable]
public class OperationRaftRelief : Operation
{
+ #region Enums
+ public enum RaftReliefTypes : byte
+ {
+ Relief,
+ Dimming,
+ Decimate
+ }
+ #endregion
+
+ #region Members
private RaftReliefTypes _reliefType = RaftReliefTypes.Relief;
+ private byte _ignoreFirstLayers;
+ private byte _brightness;
private byte _dilateIterations = 10;
private byte _wallMargin = 20;
private byte _holeDiameter = 50;
private byte _holeSpacing = 20;
+ #endregion
+
+ #region Overrides
public override string Title => "Raft relief";
public override string Description =>
"Relief raft by adding holes in between to reduce FEP suction, save resin and easier to remove the prints.";
@@ -32,33 +54,52 @@ namespace UVtools.Core.Operations
public override Enumerations.LayerRangeSelection StartLayerRangeSelection =>
Enumerations.LayerRangeSelection.None;
-
-
- public OperationRaftRelief()
- {
- }
-
+
public override string ToString()
{
- var result = $"[{_reliefType}] [Dilate: {_dilateIterations}] [Wall margin: {_wallMargin}] [Hole diameter: {_holeDiameter}] [Hole spacing: {_holeSpacing}]";
+ var result = $"[{_reliefType}] [Ignore: {_ignoreFirstLayers}] [B: {_brightness}] [Dilate: {_dilateIterations}] [Wall margin: {_wallMargin}] [Hole diameter: {_holeDiameter}] [Hole spacing: {_holeSpacing}]";
if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
return result;
}
+ #endregion
- public enum RaftReliefTypes : byte
- {
- Relief,
- Decimate
- }
-
+ #region Properties
public static Array RaftReliefItems => Enum.GetValues(typeof(RaftReliefTypes));
public RaftReliefTypes ReliefType
{
get => _reliefType;
- set => RaiseAndSetIfChanged(ref _reliefType, value);
+ set
+ {
+ if(!RaiseAndSetIfChanged(ref _reliefType, value)) return;
+ RaisePropertyChanged(nameof(IsRelief));
+ RaisePropertyChanged(nameof(IsDimming));
+ RaisePropertyChanged(nameof(IsDecimate));
+ }
+ }
+
+ public bool IsRelief => _reliefType == RaftReliefTypes.Relief;
+ public bool IsDimming => _reliefType == RaftReliefTypes.Dimming;
+ public bool IsDecimate => _reliefType == RaftReliefTypes.Decimate;
+
+ public byte IgnoreFirstLayers
+ {
+ get => _ignoreFirstLayers;
+ set => RaiseAndSetIfChanged(ref _ignoreFirstLayers, value);
+ }
+
+ public byte Brightness
+ {
+ get => _brightness;
+ set
+ {
+ if (!RaiseAndSetIfChanged(ref _brightness, value)) return;
+ RaisePropertyChanged(nameof(BrightnessPercent));
+ }
}
+ public decimal BrightnessPercent => Math.Round(_brightness * 100 / 255M, 2);
+
public byte DilateIterations
{
get => _dilateIterations;
@@ -82,12 +123,13 @@ namespace UVtools.Core.Operations
get => _holeSpacing;
set => RaiseAndSetIfChanged(ref _holeSpacing, value);
}
+ #endregion
#region Equality
protected bool Equals(OperationRaftRelief other)
{
- return _reliefType == other._reliefType && _dilateIterations == other._dilateIterations && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing && _wallMargin == other._wallMargin;
+ return _reliefType == other._reliefType && _ignoreFirstLayers == other._ignoreFirstLayers && _brightness == other._brightness && _dilateIterations == other._dilateIterations && _wallMargin == other._wallMargin && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing;
}
public override bool Equals(object obj)
@@ -100,15 +142,120 @@ namespace UVtools.Core.Operations
public override int GetHashCode()
{
- unchecked
+ return HashCode.Combine((int) _reliefType, _ignoreFirstLayers, _brightness, _dilateIterations, _wallMargin, _holeDiameter, _holeSpacing);
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override bool Execute(FileFormat slicerFile, OperationProgress progress = null)
+ {
+ const uint minLength = 5;
+ progress ??= new OperationProgress();
+ //progress.Reset(operation.ProgressAction);
+
+ Mat supportsMat = null;
+ var anchor = new Point(-1, -1);
+ var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor);
+
+
+ uint firstSupportLayerIndex = 0;
+ for (; firstSupportLayerIndex < slicerFile.LayerCount; firstSupportLayerIndex++)
{
- var hashCode = (int) _reliefType;
- hashCode = (hashCode * 397) ^ _dilateIterations.GetHashCode();
- hashCode = (hashCode * 397) ^ _holeDiameter.GetHashCode();
- hashCode = (hashCode * 397) ^ _holeSpacing.GetHashCode();
- hashCode = (hashCode * 397) ^ _wallMargin.GetHashCode();
- return hashCode;
+ progress.Reset("Tracing raft", slicerFile.LayerCount, firstSupportLayerIndex);
+ if (progress.Token.IsCancellationRequested) return false;
+ supportsMat = GetRoiOrDefault(slicerFile[firstSupportLayerIndex].LayerMat);
+ var circles = CvInvoke.HoughCircles(supportsMat, HoughModes.Gradient, 1, 20, 100, 30, 5, 200);
+ if (circles.Length >= minLength) break;
+
+ supportsMat.Dispose();
+ supportsMat = null;
+ }
+
+ if (supportsMat is null) return false;
+ Mat patternMat = null;
+
+ if (DilateIterations > 0)
+ {
+ CvInvoke.Dilate(supportsMat, supportsMat,
+ CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(3, 3), new Point(-1, -1)),
+ new Point(-1, -1), DilateIterations, BorderType.Reflect101, new MCvScalar());
}
+
+ var color = new MCvScalar(255 - Brightness);
+
+ switch (ReliefType)
+ {
+ case OperationRaftRelief.RaftReliefTypes.Relief:
+ patternMat = EmguExtensions.InitMat(supportsMat.Size);
+ int shapeSize = HoleDiameter + HoleSpacing;
+ using (var shape = EmguExtensions.InitMat(new Size(shapeSize, shapeSize)))
+ {
+
+ int center = HoleDiameter / 2;
+ //int centerTwo = operation.HoleDiameter + operation.HoleSpacing + operation.HoleDiameter / 2;
+ int radius = center;
+ CvInvoke.Circle(shape, new Point(shapeSize / 2, shapeSize / 2), radius, color, -1);
+ CvInvoke.Circle(shape, new Point(0, 0), radius / 2, color, -1);
+ CvInvoke.Circle(shape, new Point(0, shapeSize), radius / 2, color, -1);
+ CvInvoke.Circle(shape, new Point(shapeSize, 0), radius / 2, color, -1);
+ CvInvoke.Circle(shape, new Point(shapeSize, shapeSize), radius / 2, color, -1);
+
+ CvInvoke.Repeat(shape, supportsMat.Height / shape.Height + 1, supportsMat.Width / shape.Width + 1, patternMat);
+
+ patternMat = new Mat(patternMat, new Rectangle(0, 0, supportsMat.Width, supportsMat.Height));
+ }
+
+ break;
+ case OperationRaftRelief.RaftReliefTypes.Dimming:
+ patternMat = EmguExtensions.InitMat(supportsMat.Size, color);
+ break;
+ }
+
+ progress.Reset(ProgressAction, firstSupportLayerIndex);
+ Parallel.For(IgnoreFirstLayers, firstSupportLayerIndex, layerIndex =>
+ {
+ using (Mat dst = slicerFile[layerIndex].LayerMat)
+ {
+ var target = GetRoiOrDefault(dst);
+
+ switch (ReliefType)
+ {
+ case RaftReliefTypes.Relief:
+ case RaftReliefTypes.Dimming:
+ using (Mat mask = new Mat())
+ {
+ /*CvInvoke.Subtract(target, supportsMat, mask);
+ CvInvoke.Erode(mask, mask, kernel, anchor, operation.WallMargin, BorderType.Reflect101, new MCvScalar());
+ CvInvoke.Subtract(target, patternMat, target, mask);*/
+
+ CvInvoke.Erode(target, mask, kernel, anchor, WallMargin, BorderType.Reflect101, default);
+ CvInvoke.Subtract(mask, supportsMat, mask);
+ CvInvoke.Subtract(target, patternMat, target, mask);
+ }
+
+ break;
+ case RaftReliefTypes.Decimate:
+ supportsMat.CopyTo(target);
+ break;
+ }
+
+
+ slicerFile[layerIndex].LayerMat = dst;
+ }
+
+ lock (progress.Mutex)
+ {
+ progress++;
+ }
+ });
+
+
+ supportsMat.Dispose();
+ patternMat?.Dispose();
+
+ return true;
}
#endregion