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-12-08 06:30:02 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2020-12-08 06:30:02 +0300
commitde3d15f4c99a2595a50f56e2ef636ce7eb4fd064 (patch)
tree929e5ce12a784d1982b3f0e89a0086bf644698e5
parent5c5670f0b123c98ec2a343caf84fa0a96fd2eac1 (diff)
v1.4.0
* (Add) Tool - Raft relief: Relief raft by adding holes in between to reduce FEP suction, save resin and easier to remove the prints.
-rw-r--r--CHANGELOG.md4
-rw-r--r--UVtools.Core/Layer/LayerManager.cs102
-rw-r--r--UVtools.Core/Operations/OperationRaftRelief.cs116
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.WPF/Assets/Icons/dot-circle-16x16.pngbin0 -> 195 bytes
-rw-r--r--UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml95
-rw-r--r--UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs21
-rw-r--r--UVtools.WPF/MainWindow.axaml.cs11
-rw-r--r--UVtools.WPF/Structures/OperationProfiles.cs1
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj2
10 files changed, 350 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c2d3ba6..c655792 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 04/11/2020 - v1.4.0
+
+* (Add) Tool - Raft relief: Relief raft by adding holes in between to reduce FEP suction, save resin and easier to remove the prints.
+
## 04/11/2020 - v1.3.5
* (Add) Pixel Dimming: Chamfer - Allow the number of walls pixels to be gradually varied as the operation progresses from the starting layer to the ending layer (#106)
diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs
index 95f41a4..38dd145 100644
--- a/UVtools.Core/Layer/LayerManager.cs
+++ b/UVtools.Core/Layer/LayerManager.cs
@@ -540,8 +540,6 @@ namespace UVtools.Core
out var maxIteration
);
- Debug.WriteLine($"Steps: {iterationSteps}, Max iteration: {maxIteration}");
-
Parallel.For(operation.LayerIndexStart, operation.LayerIndexEnd + 1,
//new ParallelOptions {MaxDegreeOfParallelism = 1},
layerIndex =>
@@ -709,6 +707,106 @@ namespace UVtools.Core
progress.Token.ThrowIfCancellationRequested();
}*/
+ public void RaftRelief(OperationRaftRelief operation, OperationProgress progress)
+ {
+ const uint minLength = 5;
+ if (progress is null) progress = new OperationProgress();
+ //progress.Reset(operation.ProgressAction);
+
+ Mat supportsMat = null;
+
+ uint firstSupportLayerIndex = 0;
+ for (; firstSupportLayerIndex < Count; firstSupportLayerIndex++)
+ {
+ progress.Reset("Tracing raft", Count, firstSupportLayerIndex);
+ if (progress.Token.IsCancellationRequested) return;
+ supportsMat = operation.GetRoiOrDefault(this[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;
+ Mat patternMat = null;
+
+ switch (operation.ReliefType)
+ {
+ case OperationRaftRelief.RaftReliefTypes.Relief:
+ patternMat = EmguExtensions.InitMat(supportsMat.Size);
+ int shapeSize = operation.HoleDiameter + operation.HoleSpacing;
+ using (var shape = EmguExtensions.InitMat(new Size(shapeSize, shapeSize)))
+ {
+
+ int center = operation.HoleDiameter / 2;
+ int centerTwo = operation.HoleDiameter + operation.HoleSpacing + operation.HoleDiameter / 2;
+ int radius = center;
+ CvInvoke.Circle(shape, new Point(shapeSize / 2, shapeSize / 2), radius, EmguExtensions.WhiteByte, -1);
+ CvInvoke.Circle(shape, new Point(0, 0), radius / 2, EmguExtensions.WhiteByte, -1);
+ CvInvoke.Circle(shape, new Point(0, shapeSize), radius / 2, EmguExtensions.WhiteByte, -1);
+ CvInvoke.Circle(shape, new Point(shapeSize, 0), radius / 2, EmguExtensions.WhiteByte, -1);
+ CvInvoke.Circle(shape, new Point(shapeSize, shapeSize), radius / 2, EmguExtensions.WhiteByte, -1);
+
+ //shape.Save("D:\\shape.png");
+
+ 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.Decimate:
+ if (operation.DilateIterations <= 0) break;
+ CvInvoke.Dilate(supportsMat, supportsMat,
+ CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(3, 3), new Point(-1, -1)),
+ new Point(-1, -1), operation.DilateIterations, BorderType.Reflect101, new MCvScalar());
+ break;
+ }
+
+ progress.Reset(operation.ProgressAction, firstSupportLayerIndex);
+ Parallel.For(0, firstSupportLayerIndex, layerIndex =>
+ {
+ using (Mat dst = this[layerIndex].LayerMat)
+ {
+ var target = operation.GetRoiOrDefault(dst);
+
+ switch (operation.ReliefType)
+ {
+ case OperationRaftRelief.RaftReliefTypes.Relief:
+ using (Mat mask = new Mat())
+ {
+ CvInvoke.Subtract(target, supportsMat, mask);
+ //target.CopyTo(mask);
+ CvInvoke.Erode(mask, mask,
+ CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3),
+ new Point(-1, -1)),
+ new Point(-1, -1), operation.WallMargin, BorderType.Reflect101, new MCvScalar());
+ CvInvoke.Subtract(target, patternMat, target, mask);
+ }
+
+ break;
+ case OperationRaftRelief.RaftReliefTypes.Decimate:
+ supportsMat.CopyTo(target);
+ break;
+ }
+
+
+ this[layerIndex].LayerMat = dst;
+ }
+
+ lock (progress.Mutex)
+ {
+ progress++;
+ }
+ });
+
+
+ supportsMat.Dispose();
+ patternMat?.Dispose();
+ }
+
public void Arithmetic(OperationArithmetic operation, OperationProgress progress = null)
{
if (!operation.IsValid) return;
diff --git a/UVtools.Core/Operations/OperationRaftRelief.cs b/UVtools.Core/Operations/OperationRaftRelief.cs
new file mode 100644
index 0000000..55ce521
--- /dev/null
+++ b/UVtools.Core/Operations/OperationRaftRelief.cs
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+namespace UVtools.Core.Operations
+{
+ [Serializable]
+ public class OperationRaftRelief : Operation
+ {
+ private RaftReliefTypes _reliefType = RaftReliefTypes.Relief;
+ private byte _dilateIterations = 10;
+ private byte _wallMargin = 10;
+ private byte _holeDiameter = 50;
+ private byte _holeSpacing = 20;
+ 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.";
+
+ public override string ConfirmationText =>
+ $"relief the raft";
+
+ public override string ProgressTitle =>
+ $"Relieving raft";
+
+ public override string ProgressAction => "Relieved layers";
+
+ 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}]";
+ if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
+ return result;
+ }
+
+ public enum RaftReliefTypes : byte
+ {
+ Relief,
+ Decimate
+ }
+
+ public static Array RaftReliefItems => Enum.GetValues(typeof(RaftReliefTypes));
+
+ public RaftReliefTypes ReliefType
+ {
+ get => _reliefType;
+ set => RaiseAndSetIfChanged(ref _reliefType, value);
+ }
+
+ public byte DilateIterations
+ {
+ get => _dilateIterations;
+ set => RaiseAndSetIfChanged(ref _dilateIterations, value);
+ }
+
+ public byte WallMargin
+ {
+ get => _wallMargin;
+ set => RaiseAndSetIfChanged(ref _wallMargin, value);
+ }
+
+ public byte HoleDiameter
+ {
+ get => _holeDiameter;
+ set => RaiseAndSetIfChanged(ref _holeDiameter, value);
+ }
+
+ public byte HoleSpacing
+ {
+ get => _holeSpacing;
+ set => RaiseAndSetIfChanged(ref _holeSpacing, value);
+ }
+
+ #region Equality
+
+ protected bool Equals(OperationRaftRelief other)
+ {
+ return _reliefType == other._reliefType && _dilateIterations == other._dilateIterations && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing && _wallMargin == other._wallMargin;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != this.GetType()) return false;
+ return Equals((OperationRaftRelief) obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ 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;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index 566debb..2d8dfab 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, repair, conversion and manipulation</Description>
- <Version>1.3.5</Version>
+ <Version>1.4.0</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.WPF/Assets/Icons/dot-circle-16x16.png b/UVtools.WPF/Assets/Icons/dot-circle-16x16.png
new file mode 100644
index 0000000..d86c0b5
--- /dev/null
+++ b/UVtools.WPF/Assets/Icons/dot-circle-16x16.png
Binary files differ
diff --git a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml
new file mode 100644
index 0000000..3acf2cc
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml
@@ -0,0 +1,95 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+ x:Class="UVtools.WPF.Controls.Tools.ToolRaftReliefControl">
+
+
+ <Grid
+ ColumnDefinitions="Auto,10,Auto,5,Auto"
+ RowDefinitions="Auto,10,Auto,Auto,10,Auto,10,Auto"
+ >
+
+ <TextBlock Text="Relief type:" VerticalAlignment="Center"/>
+ <ComboBox
+ Name="ReliefType"
+ Grid.Column="2"
+ Width="100"
+ SelectedItem="{Binding Operation.ReliefType}"
+ Items="{Binding Operation.RaftReliefItems}"/>
+
+ <TextBlock
+ Grid.Row="2"
+ ToolTip.Tip="Raft will be replaced by the present supports and then dilated by this value.
+&#x0a;Use large numbers with tiny supports for best adhesion."
+ Text="Dilate supports by:" VerticalAlignment="Center"
+ IsVisible="{Binding #ReliefType.SelectedIndex}"
+ />
+
+ <NumericUpDown Grid.Row="2" Grid.Column="2"
+ Width="100"
+ Minimum="0"
+ Maximum="255"
+ Value="{Binding Operation.DilateIterations}"
+ IsVisible="{Binding #ReliefType.SelectedIndex}"/>
+ <TextBlock
+ Grid.Row="2" Grid.Column="4"
+ Text="px" VerticalAlignment="Center"
+ IsVisible="{Binding #ReliefType.SelectedIndex}"/>
+
+
+ <TextBlock
+ Grid.Row="3"
+ Text="Wall margin:" VerticalAlignment="Center"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"
+ />
+
+ <NumericUpDown Grid.Row="3" Grid.Column="2"
+ Width="100"
+ Minimum="1"
+ Maximum="255"
+ Value="{Binding Operation.WallMargin}"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"/>
+ <TextBlock
+ Grid.Row="3" Grid.Column="4"
+ Text="px" VerticalAlignment="Center"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"/>
+
+ <TextBlock
+ Grid.Row="5"
+ Text="Hole diameter:" VerticalAlignment="Center"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"
+ />
+
+ <NumericUpDown Grid.Row="5" Grid.Column="2"
+ Width="100"
+ Minimum="10"
+ Maximum="255"
+ Value="{Binding Operation.HoleDiameter}"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"/>
+ <TextBlock
+ Grid.Row="5" Grid.Column="4"
+ Text="px" VerticalAlignment="Center"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"/>
+
+ <TextBlock
+ Grid.Row="7"
+ Text="Hole spacing:" VerticalAlignment="Center"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"
+ />
+
+ <NumericUpDown Grid.Row="7" Grid.Column="2"
+ Width="100"
+ Minimum="10"
+ Maximum="255"
+ Value="{Binding Operation.HoleSpacing}"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"/>
+ <TextBlock
+ Grid.Row="7" Grid.Column="4"
+ Text="px" VerticalAlignment="Center"
+ IsVisible="{Binding !#ReliefType.SelectedIndex}"/>
+
+ </Grid>
+
+</UserControl>
diff --git a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs
new file mode 100644
index 0000000..aa333eb
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml.cs
@@ -0,0 +1,21 @@
+using Avalonia.Markup.Xaml;
+using UVtools.Core.Operations;
+
+namespace UVtools.WPF.Controls.Tools
+{
+ public class ToolRaftReliefControl : ToolControl
+ {
+ public OperationRaftRelief Operation => BaseOperation as OperationRaftRelief;
+
+ public ToolRaftReliefControl()
+ {
+ this.InitializeComponent();
+ BaseOperation = new OperationRaftRelief();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index 6cde099..9123232 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -120,6 +120,14 @@ namespace UVtools.WPF
},
new MenuItem
{
+ Tag = new OperationRaftRelief(),
+ Icon = new Avalonia.Controls.Image
+ {
+ Source = new Bitmap(App.GetAsset("/Assets/Icons/dot-circle-16x16.png"))
+ }
+ },
+ new MenuItem
+ {
Tag = new OperationThreshold(),
Icon = new Avalonia.Controls.Image
{
@@ -1268,6 +1276,9 @@ namespace UVtools.WPF
case OperationMorph operation:
SlicerFile.LayerManager.Morph(operation, BorderType.Default, new MCvScalar(), ProgressWindow.RestartProgress(operation.CanCancel));
break;
+ case OperationRaftRelief operation:
+ SlicerFile.LayerManager.RaftRelief(operation, ProgressWindow.RestartProgress(operation.CanCancel));
+ break;
case OperationThreshold operation:
SlicerFile.LayerManager.ThresholdPixels(operation, ProgressWindow.RestartProgress(operation.CanCancel));
break;
diff --git a/UVtools.WPF/Structures/OperationProfiles.cs b/UVtools.WPF/Structures/OperationProfiles.cs
index 8dd604e..1ce9503 100644
--- a/UVtools.WPF/Structures/OperationProfiles.cs
+++ b/UVtools.WPF/Structures/OperationProfiles.cs
@@ -30,6 +30,7 @@ namespace UVtools.WPF.Structures
//[XmlElement(typeof(OperationLayerRemove))]
//[XmlElement(typeof(OperationMask))]
[XmlElement(typeof(OperationMorph))]
+ [XmlElement(typeof(OperationRaftRelief))]
//[XmlElement(typeof(OperationMove))]
//[XmlElement(typeof(OperationPattern))]
[XmlElement(typeof(OperationPixelDimming))]
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index 70be849..22d8777 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>1.3.5</Version>
+ <Version>1.4.0</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">