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-03-04 02:48:55 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-03-04 02:48:55 +0300
commit93d038128098bb4ea91f3e8e97d89c30c6736b12 (patch)
tree8df2f6808388112e64d06294c90bbb112f1f7f3c
parent5fc722e203ad7dfbee29b8348f698f665b23aafc (diff)
v2.6.1v2.6.1
* (Add) Setting: Auto repair layers and issues on file load * (Improvement) When ComputeIssuesOnLoad is enabled and issues are detected it will switch the view to the Issues tab * **(Improvement) Raft Relief:** * Add parameter "Mask layer index": Defines the mask layer to use and ignore the white blobs on the raft * Increase the automatic support detection allowance on more odd shapes * Prevent layer 0 to be used as a mask, if so it will quit * If the ignored layer number are set and equal or larger than mask layer index it will quit * Fix progress count when using ignored layers * Change supports dilate kernel from Elipse to Rectangle for a better coverage of the pad * Change the default values for a more conservative values * (Fix) When both ComputeIssuesOnLoad and ComputeIssuesOnClickTab are enabled, clicking the issues tab will rescan for issues * (Fix) Tools: Set a default profile insn't working * (Fix) Redoing the last operation was not recovering the custom ROI on the operation
-rw-r--r--CHANGELOG.md20
-rw-r--r--CREDITS.md3
-rw-r--r--UVtools.Core/Extensions/TypeExtensions.cs2
-rw-r--r--UVtools.Core/FileFormats/ChituboxFile.cs2
-rw-r--r--UVtools.Core/FileFormats/ChituboxZipFile.cs2
-rw-r--r--UVtools.Core/FileFormats/FDGFile.cs2
-rw-r--r--UVtools.Core/FileFormats/PHZFile.cs2
-rw-r--r--UVtools.Core/FileFormats/PhotonSFile.cs2
-rw-r--r--UVtools.Core/FileFormats/PhotonWorkshopFile.cs4
-rw-r--r--UVtools.Core/FileFormats/SL1File.cs2
-rw-r--r--UVtools.Core/FileFormats/ZCodeFile.cs2
-rw-r--r--UVtools.Core/Managers/ClipboardManager.cs9
-rw-r--r--UVtools.Core/Managers/MaterialManager.cs9
-rw-r--r--UVtools.Core/Objects/GCodeBuilder.cs180
-rw-r--r--UVtools.Core/Operations/OperationRaftRelief.cs63
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml61
-rw-r--r--UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs5
-rw-r--r--UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs22
-rw-r--r--UVtools.WPF/MainWindow.Clipboard.cs4
-rw-r--r--UVtools.WPF/MainWindow.Issues.cs6
-rw-r--r--UVtools.WPF/MainWindow.axaml.cs9
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj2
-rw-r--r--UVtools.WPF/UserSettings.cs13
-rw-r--r--UVtools.WPF/Windows/SettingsWindow.axaml9
-rw-r--r--UVtools.WPF/Windows/ToolWindow.axaml.cs2
26 files changed, 360 insertions, 79 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3edddee..74f3b78 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,29 @@
# Changelog
-## 25/02/2021 - v2.6.0
+## 03/03/2021 - v2.6.1
+
+* (Add) Setting: Auto repair layers and issues on file load
+* (Improvement) When ComputeIssuesOnLoad is enabled and issues are detected it will switch the view to the Issues tab
+* **(Improvement) Raft Relief:**
+ * Add parameter "Mask layer index": Defines the mask layer to use and ignore the white blobs on the raft
+ * Increase the automatic support detection allowance on more odd shapes
+ * Prevent layer 0 to be used as a mask, if so it will quit
+ * If the ignored layer number are set and equal or larger than mask layer index it will quit
+ * Fix progress count when using ignored layers
+ * Change supports dilate kernel from Elipse to Rectangle for a better coverage of the pad
+ * Change the default values for a more conservative values
+* (Fix) When both ComputeIssuesOnLoad and ComputeIssuesOnClickTab are enabled, clicking the issues tab will rescan for issues
+* (Fix) Tools: Set a default profile insn't working
+* (Fix) Redoing the last operation was not recovering the custom ROI on the operation
+
+## 02/03/2021 - v2.6.0
* (Add) File format: Zcode (Uniz IBEE)
* (Add) PrusaSlicer Printer: Uniz IBEE
* (Add) Extract: Output an "Layer.ini" file containing per layer data and include the Configuration.ini for Zip file formats
* (Improvement) Zip: Increase the GCode parsing performance
* (Fix) File formats: Wasn't set bottom / light off delay per individual layer on generic formats, defaulting every layer to 0
-* (Fix) Edit print paramenters: When changing bottom layer count, layers didnt update thier properties
+* (Fix) Edit print parameters: When changing bottom layer count, layers didnt update thier properties
## 25/02/2021 - v2.5.1
diff --git a/CREDITS.md b/CREDITS.md
index 3cb1d24..e29767e 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -48,4 +48,5 @@
* Andrew Griffiths
* Abhinav Sinha
* Randy Savell
-* Steve Clynes \ No newline at end of file
+* Steve Clynes
+* Nicholas Taylor \ No newline at end of file
diff --git a/UVtools.Core/Extensions/TypeExtensions.cs b/UVtools.Core/Extensions/TypeExtensions.cs
index 5b982dc..d46e2cf 100644
--- a/UVtools.Core/Extensions/TypeExtensions.cs
+++ b/UVtools.Core/Extensions/TypeExtensions.cs
@@ -32,6 +32,6 @@ namespace UVtools.Core.Extensions
return (T)Activator.CreateInstance(type);
}
- public static byte ToByte(this bool value) => value ? 1 : 0;
+ public static byte ToByte(this bool value) => (byte)(value ? 1 : 0);
}
}
diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs
index d682425..de24c76 100644
--- a/UVtools.Core/FileFormats/ChituboxFile.cs
+++ b/UVtools.Core/FileFormats/ChituboxFile.cs
@@ -1085,7 +1085,7 @@ namespace UVtools.Core.FileFormats
get => HeaderSettings.ProjectorType > 0;
set
{
- HeaderSettings.ProjectorType = value ? 1 : 0;
+ HeaderSettings.ProjectorType = value ? 1u : 0;
RaisePropertyChanged();
}
}
diff --git a/UVtools.Core/FileFormats/ChituboxZipFile.cs b/UVtools.Core/FileFormats/ChituboxZipFile.cs
index 66c6f9c..b5ce0fb 100644
--- a/UVtools.Core/FileFormats/ChituboxZipFile.cs
+++ b/UVtools.Core/FileFormats/ChituboxZipFile.cs
@@ -181,7 +181,7 @@ namespace UVtools.Core.FileFormats
set
{
HeaderSettings.ProjectType = value ? "LCD_mirror" : "Normal";
- HeaderSettings.Mirror = value ? 1 : 0;
+ HeaderSettings.Mirror = (byte)(value ? 1 : 0);
RaisePropertyChanged();
}
}
diff --git a/UVtools.Core/FileFormats/FDGFile.cs b/UVtools.Core/FileFormats/FDGFile.cs
index 10f96a1..5f4c04f 100644
--- a/UVtools.Core/FileFormats/FDGFile.cs
+++ b/UVtools.Core/FileFormats/FDGFile.cs
@@ -757,7 +757,7 @@ namespace UVtools.Core.FileFormats
get => HeaderSettings.ProjectorType > 0;
set
{
- HeaderSettings.ProjectorType = value ? 1 : 0;
+ HeaderSettings.ProjectorType = value ? 1u : 0;
RaisePropertyChanged();
}
}
diff --git a/UVtools.Core/FileFormats/PHZFile.cs b/UVtools.Core/FileFormats/PHZFile.cs
index bad77d1..ac28db9 100644
--- a/UVtools.Core/FileFormats/PHZFile.cs
+++ b/UVtools.Core/FileFormats/PHZFile.cs
@@ -775,7 +775,7 @@ namespace UVtools.Core.FileFormats
get => HeaderSettings.ProjectorType > 0;
set
{
- HeaderSettings.ProjectorType = value ? 1 : 0;
+ HeaderSettings.ProjectorType = value ? 1u : 0;
RaisePropertyChanged();
}
}
diff --git a/UVtools.Core/FileFormats/PhotonSFile.cs b/UVtools.Core/FileFormats/PhotonSFile.cs
index 0a1af1c..27fb6fa 100644
--- a/UVtools.Core/FileFormats/PhotonSFile.cs
+++ b/UVtools.Core/FileFormats/PhotonSFile.cs
@@ -126,7 +126,7 @@ namespace UVtools.Core.FileFormats
for (int i = 0; i < imageLength; i++)
{
//color = color <= 127 ? 0 : 255; // Sanitize no AA
- byte thisColor = spanMat[i] <= 127 ? 0 : 255; // Sanitize no AA
+ byte thisColor = spanMat[i] <= 127 ? byte.MinValue : byte.MaxValue; // Sanitize no AA
if (thisColor != color)
{
AddRep();
diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
index 7f5efd2..67f295f 100644
--- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
+++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
@@ -1318,7 +1318,7 @@ namespace UVtools.Core.FileFormats
break;
}
- HeaderSettings.PerLayerOverride = LayerManager.AllLayersHaveGlobalParameters ? 0 : 1;
+ HeaderSettings.PerLayerOverride = (byte)(LayerManager.AllLayersHaveGlobalParameters ? 0 : 1);
uint currentOffset = FileMarkSettings.HeaderAddress = (uint) Helpers.Serializer.SizeOf(FileMarkSettings);
@@ -1522,7 +1522,7 @@ namespace UVtools.Core.FileFormats
FileFullPath = filePath;
}
- HeaderSettings.PerLayerOverride = LayerManager.AllLayersHaveGlobalParameters ? 0 : 1;
+ HeaderSettings.PerLayerOverride = LayerManager.AllLayersHaveGlobalParameters ? 0 : 1u;
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(FileMarkSettings.HeaderAddress, SeekOrigin.Begin);
diff --git a/UVtools.Core/FileFormats/SL1File.cs b/UVtools.Core/FileFormats/SL1File.cs
index 3cfbd5f..e33b4e7 100644
--- a/UVtools.Core/FileFormats/SL1File.cs
+++ b/UVtools.Core/FileFormats/SL1File.cs
@@ -379,7 +379,7 @@ namespace UVtools.Core.FileFormats
public override byte AntiAliasing
{
- get => (byte)PrinterSettings.GammaCorrection > 0 ? 4 : 1;
+ get => (byte)(PrinterSettings.GammaCorrection > 0 ? 4 : 1);
set => PrinterSettings.GammaCorrection = value > 0 ? 1 : 0;
}
diff --git a/UVtools.Core/FileFormats/ZCodeFile.cs b/UVtools.Core/FileFormats/ZCodeFile.cs
index 2e0dea1..1dcb2fe 100644
--- a/UVtools.Core/FileFormats/ZCodeFile.cs
+++ b/UVtools.Core/FileFormats/ZCodeFile.cs
@@ -771,7 +771,7 @@ namespace UVtools.Core.FileFormats
byte[] data = Encoding.UTF8.GetBytes(line);
List<byte> padData = new(64) {0, 1, 0};
padData.AddRange(data);
-
+
if (padData.Count > 64)
{
throw new ArgumentOutOfRangeException($"Too long gcode line to encrypt, got: {padData.Count} bytes while expecting less than 64 bytes");
diff --git a/UVtools.Core/Managers/ClipboardManager.cs b/UVtools.Core/Managers/ClipboardManager.cs
index 364d5be..d27c512 100644
--- a/UVtools.Core/Managers/ClipboardManager.cs
+++ b/UVtools.Core/Managers/ClipboardManager.cs
@@ -1,4 +1,11 @@
-using System;
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
diff --git a/UVtools.Core/Managers/MaterialManager.cs b/UVtools.Core/Managers/MaterialManager.cs
index bd0446b..461e7b3 100644
--- a/UVtools.Core/Managers/MaterialManager.cs
+++ b/UVtools.Core/Managers/MaterialManager.cs
@@ -1,4 +1,11 @@
-using System;
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
diff --git a/UVtools.Core/Objects/GCodeBuilder.cs b/UVtools.Core/Objects/GCodeBuilder.cs
new file mode 100644
index 0000000..bf11994
--- /dev/null
+++ b/UVtools.Core/Objects/GCodeBuilder.cs
@@ -0,0 +1,180 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+using System.Text;
+
+namespace UVtools.Core.Objects
+{
+ public class GCodeBuilder : BindableBase
+ {
+ #region Enums
+
+ public enum GCodeTimeUnits : byte
+ {
+ Milliseconds,
+ Seconds
+ }
+
+ public enum GCodeSpeedUnits : byte
+ {
+ MillimetersPerSecond,
+ MillimetersPerMinute,
+ CentimetersPerMinute,
+ }
+ #endregion
+
+ #region Members
+ private readonly StringBuilder _gcode = new();
+
+ private bool _appendComma = true;
+ private bool _appendComment = true;
+ private bool _useAbsoluteCommands = true;
+ private GCodeTimeUnits _gCodeTimeUnit = GCodeTimeUnits.Milliseconds;
+ private GCodeSpeedUnits _gCodeSpeedUnit = GCodeSpeedUnits.MillimetersPerMinute;
+
+ #endregion
+
+ #region Properties
+
+ public bool UseAbsoluteCommands
+ {
+ get => _useAbsoluteCommands;
+ set => RaiseAndSetIfChanged(ref _useAbsoluteCommands, value);
+ }
+
+ public GCodeTimeUnits GCodeTimeUnit
+ {
+ get => _gCodeTimeUnit;
+ set => RaiseAndSetIfChanged(ref _gCodeTimeUnit, value);
+ }
+
+ public GCodeSpeedUnits GCodeSpeedUnit
+ {
+ get => _gCodeSpeedUnit;
+ set => RaiseAndSetIfChanged(ref _gCodeSpeedUnit, value);
+ }
+
+ public bool AppendComma
+ {
+ get => _appendComma;
+ set => RaiseAndSetIfChanged(ref _appendComma, value);
+ }
+
+ public bool AppendComment
+ {
+ get => _appendComment;
+ set => RaiseAndSetIfChanged(ref _appendComment, value);
+ }
+ #endregion
+
+ #region StringBuilder
+ public void AppendLine() => _gcode.AppendLine();
+ public void AppendLine(string line) => _gcode.AppendLine(line);
+ public void AppendFormat(string format, params object?[] args) => _gcode.AppendFormat(format, args);
+ public void Clear() => _gcode.Clear();
+ public override string ToString() => _gcode.ToString();
+ #endregion
+
+ #region Methods
+
+ public string FormatGCodeLine(string line, string comment)
+ {
+ if (_appendComma || _appendComment)
+ line += ';';
+ if (_appendComment)
+ line += comment;
+
+ return line;
+ }
+
+ public void AppendUnitsMmG21()
+ {
+ AppendLine(FormatGCodeLine("G21", "Set units to be mm"));
+ }
+
+ public void AppendPositioningType()
+ {
+ if (_useAbsoluteCommands)
+ {
+ AppendLine(FormatGCodeLine("G90", "Absolute positioning"));
+ }
+ else
+ {
+ AppendLine(FormatGCodeLine("G91", "Partial positioning"));
+ }
+ }
+
+ public void AppendEnableMotors()
+ {
+ AppendLine(FormatGCodeLine("M17", "Enable motors"));
+ }
+
+ public void AppendDisableMotors()
+ {
+ AppendLine(FormatGCodeLine("M18", "Disable motors"));
+ }
+
+ public void AppendTurnMotors(bool enable)
+ {
+ if (enable)
+ AppendEnableMotors();
+ else
+ AppendDisableMotors();
+ }
+
+ public void AppendHomeZG28()
+ {
+ AppendLine(FormatGCodeLine("G28 Z0", "Home Z"));
+ }
+
+
+ public void AppendMoveG0(float z, float feedRate)
+ {
+ AppendLine(FormatGCodeLine($"G0 Z{z} F{feedRate}", "Z Move"));
+ }
+
+ public void AppendLiftMoveG0(float upZ, float upFeedRate, float downZ, float downFeedRate)
+ {
+ AppendLine(FormatGCodeLine($"G0 Z{upZ} F{upFeedRate}", "Z Lift"));
+ AppendLine(FormatGCodeLine($"G0 Z{downZ} F{downFeedRate}", "Retract to layer height"));
+ }
+
+ public void AppendWaitG4(float time)
+ {
+ AppendLine(FormatGCodeLine($"G4 P{time}", "Delay"));
+ }
+
+ public void AppendTurnLightM106(ushort value)
+ {
+ AppendLine(FormatGCodeLine($"M106 S{value}", "Turn LED"));
+ }
+
+ public void AppendLightOffM106() => AppendTurnLightM106(0);
+ public void AppendLightFullM106() => AppendTurnLightM106(255);
+
+ public void AppendExposure(ushort value, float time)
+ {
+ if (time <= 0) return;
+
+ AppendTurnLightM106(value);
+ AppendWaitG4(time);
+ AppendLightOffM106();
+ }
+
+ public void AppendShowImageM6054(string name)
+ {
+ AppendLine(FormatGCodeLine($"M6054 \"{name}\"","Show image"));
+ }
+
+ public void AppendLineComment(string comment)
+ {
+ AppendLine($";{comment}");
+ }
+ }
+ #endregion
+}
diff --git a/UVtools.Core/Operations/OperationRaftRelief.cs b/UVtools.Core/Operations/OperationRaftRelief.cs
index d5634c6..c19bd91 100644
--- a/UVtools.Core/Operations/OperationRaftRelief.cs
+++ b/UVtools.Core/Operations/OperationRaftRelief.cs
@@ -31,12 +31,14 @@ namespace UVtools.Core.Operations
#region Members
private RaftReliefTypes _reliefType = RaftReliefTypes.Relief;
+ private uint _maskLayerIndex;
private byte _ignoreFirstLayers;
private byte _brightness;
- private byte _dilateIterations = 10;
- private byte _wallMargin = 20;
- private byte _holeDiameter = 50;
- private byte _holeSpacing = 20;
+ private byte _dilateIterations = 15;// +/- 1.5mm radius
+ private byte _wallMargin = 40; // +/- 2mm
+ private byte _holeDiameter = 80; // +/- 4mm
+ private byte _holeSpacing = 40; // +/- 2mm
+
#endregion
#region Overrides
@@ -57,7 +59,7 @@ namespace UVtools.Core.Operations
public override string ToString()
{
- var result = $"[{_reliefType}] [Ignore: {_ignoreFirstLayers}] [B: {_brightness}] [Dilate: {_dilateIterations}] [Wall margin: {_wallMargin}] [Hole diameter: {_holeDiameter}] [Hole spacing: {_holeSpacing}]";
+ var result = $"[{_reliefType}] [Mask layer: {_maskLayerIndex}] [Ignore: {_ignoreFirstLayers}] [B: {_brightness}] [Dilate: {_dilateIterations}] [Wall margin: {_wallMargin}] [Hole diameter: {_holeDiameter}] [Hole spacing: {_holeSpacing}]";
if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
return result;
}
@@ -90,6 +92,12 @@ namespace UVtools.Core.Operations
public bool IsDimming => _reliefType == RaftReliefTypes.Dimming;
public bool IsDecimate => _reliefType == RaftReliefTypes.Decimate;
+ public uint MaskLayerIndex
+ {
+ get => _maskLayerIndex;
+ set => RaiseAndSetIfChanged(ref _maskLayerIndex, value);
+ }
+
public byte IgnoreFirstLayers
{
get => _ignoreFirstLayers;
@@ -137,7 +145,7 @@ namespace UVtools.Core.Operations
protected bool Equals(OperationRaftRelief other)
{
- return _reliefType == other._reliefType && _ignoreFirstLayers == other._ignoreFirstLayers && _brightness == other._brightness && _dilateIterations == other._dilateIterations && _wallMargin == other._wallMargin && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing;
+ return _reliefType == other._reliefType && _maskLayerIndex == other._maskLayerIndex && _ignoreFirstLayers == other._ignoreFirstLayers && _brightness == other._brightness && _dilateIterations == other._dilateIterations && _wallMargin == other._wallMargin && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing;
}
public override bool Equals(object obj)
@@ -150,7 +158,7 @@ namespace UVtools.Core.Operations
public override int GetHashCode()
{
- return HashCode.Combine((int) _reliefType, _ignoreFirstLayers, _brightness, _dilateIterations, _wallMargin, _holeDiameter, _holeSpacing);
+ return HashCode.Combine((int) _reliefType, _maskLayerIndex, _ignoreFirstLayers, _brightness, _dilateIterations, _wallMargin, _holeDiameter, _holeSpacing);
}
#endregion
@@ -160,33 +168,43 @@ namespace UVtools.Core.Operations
protected override bool ExecuteInternally(OperationProgress progress)
{
progress.ItemCount = 0;
- const uint minLength = 5;
+ const uint minSupportsRequired = 5;
+ const uint maxLayerCount = 1000;
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++)
+ uint firstSupportLayerIndex = _maskLayerIndex;
+ if (firstSupportLayerIndex <= 0)
+ {
+ uint layerCount = Math.Min(SlicerFile.LayerCount, maxLayerCount);
+ progress.Reset("Tracing raft", layerCount, firstSupportLayerIndex);
+ for (; firstSupportLayerIndex < layerCount; firstSupportLayerIndex++)
+ {
+ if (progress.Token.IsCancellationRequested) return false;
+ progress++;
+ supportsMat = GetRoiOrDefault(SlicerFile[firstSupportLayerIndex].LayerMat);
+ var circles = CvInvoke.HoughCircles(supportsMat, HoughModes.Gradient, 1, 5, 80, 35, 5, 200);
+ if (circles.Length >= minSupportsRequired) break;
+
+ supportsMat.Dispose();
+ supportsMat = null;
+ }
+ }
+ else
{
- 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;
+ if (supportsMat is null || /*firstSupportLayerIndex == 0 ||*/ _ignoreFirstLayers >= firstSupportLayerIndex) return false;
Mat patternMat = null;
if (DilateIterations > 0)
{
CvInvoke.Dilate(supportsMat, supportsMat,
- CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(3, 3), new Point(-1, -1)),
+ CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), new Point(-1, -1)),
new Point(-1, -1), DilateIterations, BorderType.Reflect101, new MCvScalar());
}
@@ -220,8 +238,8 @@ namespace UVtools.Core.Operations
break;
}
- progress.Reset(ProgressAction, firstSupportLayerIndex);
- Parallel.For(IgnoreFirstLayers, firstSupportLayerIndex, layerIndex =>
+ progress.Reset(ProgressAction, firstSupportLayerIndex - _ignoreFirstLayers);
+ Parallel.For(_ignoreFirstLayers, firstSupportLayerIndex, layerIndex =>
{
if (progress.Token.IsCancellationRequested) return;
using (Mat dst = SlicerFile[layerIndex].LayerMat)
@@ -238,7 +256,8 @@ namespace UVtools.Core.Operations
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.Erode(target, mask, kernel, anchor, WallMargin, BorderType.Reflect101,
+ default);
CvInvoke.Subtract(mask, supportsMat, mask);
CvInvoke.Subtract(target, patternMat, target, mask);
}
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index 081889b..d180d78 100644
--- a/UVtools.Core/UVtools.Core.csproj
+++ b/UVtools.Core/UVtools.Core.csproj
@@ -10,7 +10,7 @@
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
- <Version>2.6.0</Version>
+ <Version>2.6.1</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml
index 7f1e337..b9d3020 100644
--- a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml
+++ b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml
@@ -8,7 +8,7 @@
<Grid
ColumnDefinitions="Auto,10,150,5,Auto"
- RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
+ RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
>
<TextBlock Text="Relief type:" VerticalAlignment="Center"/>
@@ -18,104 +18,125 @@
SelectedItem="{Binding Operation.ReliefType}"
Items="{Binding Operation.RaftReliefItems}"/>
-
<TextBlock
Grid.Row="2"
Grid.Column="0"
- Text="Ignore first:" VerticalAlignment="Center"/>
+ ToolTip.Tip="Defines the mask layer to use and ignore it white blobs on the raft.
+&#x0a;Often this is the first layer where raft ends and supports starts.
+&#x0a;Use '0' to auto detect the mask layer, otherwise if it fails or if you have multiple rafts with different heights
+you must manually input the layer index of the last raft where it ends and supports starts."
+ Text="Mask layer index:" VerticalAlignment="Center"/>
<NumericUpDown Grid.Row="2" Grid.Column="2"
Minimum="0"
+ Maximum="{Binding SlicerFile.LastLayerIndex}"
+ Value="{Binding Operation.MaskLayerIndex}"/>
+ <StackPanel Grid.Row="2" Grid.Column="4"
+ Orientation="Horizontal" Spacing="5">
+
+ <Button Content="Use current layer" Command="{Binding UseCurrentLayerAsMask}" />
+
+ <TextBlock VerticalAlignment="Center"
+ Text="(0 = Auto detect)" />
+ </StackPanel>
+
+ <TextBlock
+ Grid.Row="4"
+ Grid.Column="0"
+ Text="Ignore first:" VerticalAlignment="Center"/>
+
+ <NumericUpDown Grid.Row="4" Grid.Column="2"
+ Minimum="0"
Maximum="255"
Value="{Binding Operation.IgnoreFirstLayers}"/>
<TextBlock
- Grid.Row="2" Grid.Column="4"
+ Grid.Row="4" Grid.Column="4"
Text="layer(s)" VerticalAlignment="Center"/>
<TextBlock
- Grid.Row="4"
+ Grid.Row="6"
Grid.Column="0"
IsVisible="{Binding !Operation.IsDecimate}"
Text="Pixel brightness:" VerticalAlignment="Center"/>
- <NumericUpDown Grid.Row="4" Grid.Column="2"
+ <NumericUpDown Grid.Row="6" Grid.Column="2"
Minimum="0"
Maximum="255"
IsVisible="{Binding !Operation.IsDecimate}"
Value="{Binding Operation.Brightness}"/>
<TextBlock
- Grid.Row="4" Grid.Column="4"
+ Grid.Row="6" Grid.Column="4"
IsVisible="{Binding !Operation.IsDecimate}"
Text="{Binding Operation.BrightnessPercent, StringFormat=\{0:0.00\}%}" VerticalAlignment="Center"/>
<TextBlock
- Grid.Row="6"
+ Grid.Row="8"
IsVisible="{Binding !Operation.IsDecimate}"
Text="Supports margin:" VerticalAlignment="Center"/>
<TextBlock
- Grid.Row="6"
+ Grid.Row="8"
IsVisible="{Binding Operation.IsDecimate}"
ToolTip.Tip="Raft will be replaced by the present supports and then dilated by this value to thicken the supports and increase the adhesion.
&#x0a;Use large numbers with tiny supports for best adhesion."
Text="Dilate supports by:" VerticalAlignment="Center"/>
- <NumericUpDown Grid.Row="6" Grid.Column="2"
+ <NumericUpDown Grid.Row="8" Grid.Column="2"
Minimum="0"
Maximum="255"
Value="{Binding Operation.DilateIterations}"/>
<TextBlock
- Grid.Row="6" Grid.Column="4"
+ Grid.Row="8" Grid.Column="4"
Text="px" VerticalAlignment="Center"/>
<TextBlock
- Grid.Row="8"
+ Grid.Row="10"
Text="Wall margin:" VerticalAlignment="Center"
IsVisible="{Binding !Operation.IsDecimate}"
/>
- <NumericUpDown Grid.Row="8" Grid.Column="2"
+ <NumericUpDown Grid.Row="10" Grid.Column="2"
Minimum="1"
Maximum="255"
Value="{Binding Operation.WallMargin}"
IsVisible="{Binding !Operation.IsDecimate}"/>
<TextBlock
- Grid.Row="8" Grid.Column="4"
+ Grid.Row="10" Grid.Column="4"
Text="px" VerticalAlignment="Center"
IsVisible="{Binding !Operation.IsDecimate}"/>
<TextBlock
- Grid.Row="10"
+ Grid.Row="12"
Text="Hole diameter:" VerticalAlignment="Center"
IsVisible="{Binding Operation.IsRelief}"
/>
- <NumericUpDown Grid.Row="10" Grid.Column="2"
+ <NumericUpDown Grid.Row="12" Grid.Column="2"
Minimum="10"
Maximum="255"
Value="{Binding Operation.HoleDiameter}"
IsVisible="{Binding Operation.IsRelief}"/>
<TextBlock
- Grid.Row="10" Grid.Column="4"
+ Grid.Row="12" Grid.Column="4"
Text="px" VerticalAlignment="Center"
IsVisible="{Binding Operation.IsRelief}"/>
<TextBlock
- Grid.Row="12"
+ Grid.Row="14"
Text="Hole spacing:" VerticalAlignment="Center"
IsVisible="{Binding Operation.IsRelief}"
/>
- <NumericUpDown Grid.Row="12" Grid.Column="2"
+ <NumericUpDown Grid.Row="14" Grid.Column="2"
Minimum="10"
Maximum="255"
Value="{Binding Operation.HoleSpacing}"
IsVisible="{Binding Operation.IsRelief}"/>
<TextBlock
- Grid.Row="12" Grid.Column="4"
+ Grid.Row="14" Grid.Column="4"
Text="px" VerticalAlignment="Center"
IsVisible="{Binding Operation.IsRelief}"/>
diff --git a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs
index 58606b9..5d61417 100644
--- a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs
+++ b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs
@@ -17,5 +17,10 @@ namespace UVtools.WPF.Controls.Tools
{
AvaloniaXamlLoader.Load(this);
}
+
+ public void UseCurrentLayerAsMask()
+ {
+ Operation.MaskLayerIndex = App.MainWindow.ActualLayer;
+ }
}
}
diff --git a/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs
index 14ed006..0cefc50 100644
--- a/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs
+++ b/UVtools.WPF/Controls/Tools/ToolRepairLayersControl.axaml.cs
@@ -11,16 +11,7 @@ namespace UVtools.WPF.Controls.Tools
public ToolRepairLayersControl()
{
InitializeComponent();
- BaseOperation = new OperationRepairLayers(SlicerFile)
- {
- RepairIslands = UserSettings.Instance.LayerRepair.RepairIslands,
- RepairResinTraps = UserSettings.Instance.LayerRepair.RepairResinTraps,
- RemoveEmptyLayers = UserSettings.Instance.LayerRepair.RemoveEmptyLayers,
- RemoveIslandsBelowEqualPixelCount = UserSettings.Instance.LayerRepair.RemoveIslandsBelowEqualPixels,
- RemoveIslandsRecursiveIterations = UserSettings.Instance.LayerRepair.RemoveIslandsRecursiveIterations,
- GapClosingIterations = UserSettings.Instance.LayerRepair.ClosingIterations,
- NoiseRemovalIterations = UserSettings.Instance.LayerRepair.OpeningIterations,
- };
+ BaseOperation = GetOperationRepairLayers();
}
private void InitializeComponent()
@@ -28,6 +19,17 @@ namespace UVtools.WPF.Controls.Tools
AvaloniaXamlLoader.Load(this);
}
+ public static OperationRepairLayers GetOperationRepairLayers() => new (App.SlicerFile)
+ {
+ RepairIslands = UserSettings.Instance.LayerRepair.RepairIslands,
+ RepairResinTraps = UserSettings.Instance.LayerRepair.RepairResinTraps,
+ RemoveEmptyLayers = UserSettings.Instance.LayerRepair.RemoveEmptyLayers,
+ RemoveIslandsBelowEqualPixelCount = UserSettings.Instance.LayerRepair.RemoveIslandsBelowEqualPixels,
+ RemoveIslandsRecursiveIterations = UserSettings.Instance.LayerRepair.RemoveIslandsRecursiveIterations,
+ GapClosingIterations = UserSettings.Instance.LayerRepair.ClosingIterations,
+ NoiseRemovalIterations = UserSettings.Instance.LayerRepair.OpeningIterations,
+ };
+
public override void Callback(ToolWindow.Callbacks callback)
{
switch (callback)
diff --git a/UVtools.WPF/MainWindow.Clipboard.cs b/UVtools.WPF/MainWindow.Clipboard.cs
index bf8435d..7c536e5 100644
--- a/UVtools.WPF/MainWindow.Clipboard.cs
+++ b/UVtools.WPF/MainWindow.Clipboard.cs
@@ -70,6 +70,10 @@ namespace UVtools.WPF
return;
}
if (clip?.Operation is null) return;
+ if (clip.Operation.HaveROI)
+ {
+ ROI = GetTransposedRectangle(clip.Operation.ROI);
+ }
var operation = await ShowRunOperation(clip.Operation.GetType(), clip.Operation);
if (operation is null)
{
diff --git a/UVtools.WPF/MainWindow.Issues.cs b/UVtools.WPF/MainWindow.Issues.cs
index e1b2f76..87abea6 100644
--- a/UVtools.WPF/MainWindow.Issues.cs
+++ b/UVtools.WPF/MainWindow.Issues.cs
@@ -420,10 +420,10 @@ namespace UVtools.WPF
await ShowRunOperation(typeof(OperationRepairLayers));
}
- public void OnClickDetectIssues()
+ public async Task OnClickDetectIssues()
{
if (!IsFileLoaded) return;
- ComputeIssues(
+ await ComputeIssues(
GetIslandDetectionConfiguration(),
GetOverhangDetectionConfiguration(),
GetResinTrapDetectionConfiguration(),
@@ -431,7 +431,7 @@ namespace UVtools.WPF
Settings.Issues.ComputeEmptyLayers);
}
- private async void ComputeIssues(IslandDetectionConfiguration islandConfig = null,
+ private async Task ComputeIssues(IslandDetectionConfiguration islandConfig = null,
OverhangDetectionConfiguration overhangConfig = null,
ResinTrapDetectionConfiguration resinTrapConfig = null,
TouchingBoundDetectionConfiguration touchingBoundConfig = null, bool emptyLayersConfig = true)
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index 8553b3b..ba6d224 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -1120,7 +1120,14 @@ namespace UVtools.WPF
if (Settings.Issues.ComputeIssuesOnLoad)
{
- OnClickDetectIssues();
+ _firstTimeOnIssues = false;
+ await OnClickDetectIssues();
+ if (Issues.Count > 0)
+ {
+ SelectedTabItem = TabIssues;
+ if(Settings.Issues.AutoRepairIssuesOnLoad)
+ await RunOperation(ToolRepairLayersControl.GetOperationRepairLayers());
+ }
}
}
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index 7dc6c97..4356ed6 100644
--- a/UVtools.WPF/UVtools.WPF.csproj
+++ b/UVtools.WPF/UVtools.WPF.csproj
@@ -12,7 +12,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
- <Version>2.6.0</Version>
+ <Version>2.6.1</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
diff --git a/UVtools.WPF/UserSettings.cs b/UVtools.WPF/UserSettings.cs
index 53296cd..fd06445 100644
--- a/UVtools.WPF/UserSettings.cs
+++ b/UVtools.WPF/UserSettings.cs
@@ -572,7 +572,8 @@ namespace UVtools.WPF
[Serializable]
public sealed class IssuesUserSettings : BindableBase
{
- private bool _computeIssuesOnLoad = false;
+ private bool _computeIssuesOnLoad;
+ private bool _autoRepairIssuesOnLoad;
private bool _computeIssuesOnClickTab = true;
private bool _computeIslands = true;
private bool _computeOverhangs = true;
@@ -580,8 +581,8 @@ namespace UVtools.WPF
private bool _computeTouchingBounds = true;
private bool _computeEmptyLayers = true;
private bool _islandEnhancedDetection = true;
- private bool _islandAllowDiagonalBonds = false;
- private byte _islandBinaryThreshold = 0;
+ private bool _islandAllowDiagonalBonds;
+ private byte _islandBinaryThreshold;
private byte _islandRequiredAreaToProcessCheck = 1;
private byte _islandRequiredPixelBrightnessToProcessCheck = 1;
private byte _islandRequiredPixelsToSupport = 10;
@@ -606,6 +607,12 @@ namespace UVtools.WPF
set => RaiseAndSetIfChanged(ref _computeIssuesOnLoad, value);
}
+ public bool AutoRepairIssuesOnLoad
+ {
+ get => _autoRepairIssuesOnLoad;
+ set => RaiseAndSetIfChanged(ref _autoRepairIssuesOnLoad, value);
+ }
+
public bool ComputeIssuesOnClickTab
{
get => _computeIssuesOnClickTab;
diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml b/UVtools.WPF/Windows/SettingsWindow.axaml
index 2d87662..86bfb5b 100644
--- a/UVtools.WPF/Windows/SettingsWindow.axaml
+++ b/UVtools.WPF/Windows/SettingsWindow.axaml
@@ -692,9 +692,14 @@
<TextBlock Padding="10" Background="LightBlue" FontWeight="Bold" Text="Common"/>
+ <StackPanel Orientation="Horizontal" Spacing="20">
<CheckBox Margin="10,10" Content="Compute issues on file load"
- IsChecked="{Binding Settings.Issues.ComputeIssuesOnLoad}"
- />
+ IsChecked="{Binding Settings.Issues.ComputeIssuesOnLoad}"/>
+
+ <CheckBox Margin="0,10" Content="Auto repair layers and issues on file load"
+ IsEnabled="{Binding Settings.Issues.ComputeIssuesOnLoad}"
+ IsChecked="{Binding Settings.Issues.AutoRepairIssuesOnLoad}"/>
+ </StackPanel>
<CheckBox Margin="10,0,10,0" Content="Auto compute issues when the Issues tab is opened for the first time"
IsChecked="{Binding Settings.Issues.ComputeIssuesOnClickTab}"
diff --git a/UVtools.WPF/Windows/ToolWindow.axaml.cs b/UVtools.WPF/Windows/ToolWindow.axaml.cs
index e3936d3..14a1fb7 100644
--- a/UVtools.WPF/Windows/ToolWindow.axaml.cs
+++ b/UVtools.WPF/Windows/ToolWindow.axaml.cs
@@ -535,7 +535,7 @@ namespace UVtools.WPF.Windows
{
if (operation.ProfileIsDefault)
{
- _selectedProfileItem = operation;
+ SelectedProfileItem = operation;
break;
}
}