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-09-06 03:34:58 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-09-06 03:34:58 +0300
commit08a5797f36867c9b4c9b58da94e61bbea6258ae1 (patch)
tree51bdf0a133dbdeff923a8566f67fdce000a93006
parent6a2a52ebcb3bcd98476d13f24d562383fc8756b4 (diff)
v2.21.1v2.21.1
- **(Add) Layer outline:** - Blob outline: Outline all separate blobs - Centroids: Draw a dot at the gemoetric center of a blob - (Add) Adjust layer height: Allow to change exposure time on the dialog and inform that different layer thickness require different exposure times - (Add) Resin trap detection: Allow to choose the starting layer index for resin trap detection which will also be considered a drain layer. Use this setting to bypass complicated rafts by selected the model first real layer (#221) - (Improvement) Disable mirroed preview when loading a file that is not mirroed
-rw-r--r--CHANGELOG.md10
-rw-r--r--UVtools.Core/EmguCV/Contour.cs14
-rw-r--r--UVtools.Core/Layer/LayerIssue.cs6
-rw-r--r--UVtools.Core/Layer/LayerManager.cs4
-rw-r--r--UVtools.Core/Operations/OperationDoubleExposure.cs2
-rw-r--r--UVtools.Core/Operations/OperationLayerReHeight.cs34
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.WPF/Controls/Tools/ToolDoubleExposureControl.axaml2
-rw-r--r--UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml31
-rw-r--r--UVtools.WPF/MainWindow.Issues.cs25
-rw-r--r--UVtools.WPF/MainWindow.LayerPreview.cs68
-rw-r--r--UVtools.WPF/MainWindow.axaml45
-rw-r--r--UVtools.WPF/MainWindow.axaml.cs9
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj2
-rw-r--r--UVtools.WPF/UserSettings.cs73
-rw-r--r--UVtools.WPF/Windows/SettingsWindow.axaml97
16 files changed, 381 insertions, 43 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c921ace..40444c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# Changelog
+## 06/09/2021 - v2.21.1
+
+- **(Add) Layer outline:**
+ - Blob outline: Outline all separate blobs
+ - Centroids: Draw a dot at the gemoetric center of a blob
+- (Add) Adjust layer height: Allow to change exposure time on the dialog and inform that different layer thickness require different exposure times
+- (Add) Resin trap detection: Allow to choose the starting layer index for resin trap detection which will also be considered a drain layer.
+ Use this setting to bypass complicated rafts by selected the model first real layer (#221)
+- (Improvement) Disable mirroed preview when loading a file that is not mirroed
+
## 03/09/2021 - v2.21.0
- **UI:**
diff --git a/UVtools.Core/EmguCV/Contour.cs b/UVtools.Core/EmguCV/Contour.cs
index 20d216e..291cad8 100644
--- a/UVtools.Core/EmguCV/Contour.cs
+++ b/UVtools.Core/EmguCV/Contour.cs
@@ -90,7 +90,7 @@ namespace UVtools.Core.EmguCV
/// <summary>
/// Gets the centroid of the contour
/// </summary>
- public Point Centroid => _centroid ??= Moments.M00 == 0 ? Point.Empty :
+ public Point Centroid => _centroid ??= Moments.M00 == 0 ? new Point(-1,-1) :
new Point(
(int)Math.Round(_moments.M10 / _moments.M00),
(int)Math.Round(_moments.M01 / _moments.M00));
@@ -211,6 +211,18 @@ namespace UVtools.Core.EmguCV
}*/
#endregion
+ #region Static methods
+ public static Point GetCentroid(VectorOfPoint points)
+ {
+ if (points is null || points.Length == 0) return new Point(-1, -1);
+ using var moments = CvInvoke.Moments(points);
+ return moments.M00 == 0 ? new Point(-1, -1) :
+ new Point(
+ (int)Math.Round(moments.M10 / moments.M00),
+ (int)Math.Round(moments.M01 / moments.M00));
+ }
+ #endregion
+
#region Implementations
public IEnumerator<Point> GetEnumerator()
diff --git a/UVtools.Core/Layer/LayerIssue.cs b/UVtools.Core/Layer/LayerIssue.cs
index 8b46e51..598231f 100644
--- a/UVtools.Core/Layer/LayerIssue.cs
+++ b/UVtools.Core/Layer/LayerIssue.cs
@@ -159,6 +159,12 @@ namespace UVtools.Core
public bool Enabled { get; set; } = true;
/// <summary>
+ /// Gets or sets the starting layer index for the detection which will also be considered a drain layer.
+ /// Use this setting to bypass complicated rafts by selected the model first real layer.
+ /// </summary>
+ public uint StartLayerIndex { get; set; }
+
+ /// <summary>
/// Gets or sets the binary threshold, all pixels below this value will turn in black, otherwise white
/// Set to 0 to disable this operation
/// </summary>
diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs
index 678c298..ba1ed48 100644
--- a/UVtools.Core/Layer/LayerManager.cs
+++ b/UVtools.Core/Layer/LayerManager.cs
@@ -1389,7 +1389,7 @@ namespace UVtools.Core
listHollowArea.Add(new LayerHollowArea(contours[i].ToArray(),
rect,
- layer.Index == 0 ||
+ layer.Index <= resinTrapConfig.StartLayerIndex ||
layer.Index == LayerCount - 1 // First and Last layers, always drains
? LayerHollowArea.AreaType.Drain
: LayerHollowArea.AreaType.Unknown));
@@ -1410,7 +1410,7 @@ namespace UVtools.Core
ResinTrapTree resinTrapTree = new();
- for (uint layerIndex = 1; layerIndex < LayerCount - 1; layerIndex++) // First and Last layers, always drains
+ for (uint layerIndex = resinTrapConfig.StartLayerIndex+1; layerIndex < LayerCount - 1; layerIndex++) // First and Last layers, always drains
{
if (progress.Token.IsCancellationRequested) break;
if (!layerHollowAreas.TryGetValue(layerIndex, out var areas))
diff --git a/UVtools.Core/Operations/OperationDoubleExposure.cs b/UVtools.Core/Operations/OperationDoubleExposure.cs
index 5de3e0e..96068d9 100644
--- a/UVtools.Core/Operations/OperationDoubleExposure.cs
+++ b/UVtools.Core/Operations/OperationDoubleExposure.cs
@@ -45,7 +45,7 @@ namespace UVtools.Core.Operations
"The double exposure method clones the selected layer range and print the same layer twice with different exposure times and strategies.\n" +
"Can be used to eliminate the elephant foot effect or to harden a layer in two steps.\n" +
"After this, do not apply any modification which reconstruct the z positions of the layers.\n" +
- "Note: To eliminate the elephant foot effect, the use of wall dimming method recommended.";
+ "Note: To eliminate the elephant foot effect, the use of wall dimming method is recommended.";
public override string ConfirmationText =>
$"double exposure model layers {LayerIndexStart} through {LayerIndexEnd}";
diff --git a/UVtools.Core/Operations/OperationLayerReHeight.cs b/UVtools.Core/Operations/OperationLayerReHeight.cs
index 44f153d..f9a86a6 100644
--- a/UVtools.Core/Operations/OperationLayerReHeight.cs
+++ b/UVtools.Core/Operations/OperationLayerReHeight.cs
@@ -38,6 +38,8 @@ namespace UVtools.Core.Operations
#region Members
private OperationLayerReHeightItem _selectedItem;
private OperationLayerReHeightAntiAliasingType _antiAliasingType;
+ private decimal _bottomExposure;
+ private decimal _normalExposure;
#endregion
@@ -49,7 +51,8 @@ namespace UVtools.Core.Operations
public override string Description =>
"Adjust the layer height of the model.\n\n" +
"Adjusting to values lower than current height will reduce layer lines, adjusting to values higher" +
- " than current height will reduce model detail.\n\n" +
+ " than current height will reduce model detail.\n" +
+ "Different layer thickness will require different exposure times, adjust accordingly.\n\n" +
"Note: Using dedicated slicer software to re-slice will usually yeild better results.";
public override string ConfirmationText =>
$"adjust layer height to {SelectedItem.LayerHeight}mm?";
@@ -87,7 +90,9 @@ namespace UVtools.Core.Operations
public override string ToString()
{
- var result = $"[Layer Count: {SelectedItem.LayerCount}] [Layer Height: {SelectedItem.LayerHeight}]" + LayerRangeString;
+ var result = $"[Layer Count: {SelectedItem.LayerCount}] " +
+ $"[Layer Height: {SelectedItem.LayerHeight}] " +
+ $"[Exposure: {_bottomExposure}/{_normalExposure}s]" + LayerRangeString;
if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
return result;
}
@@ -115,6 +120,18 @@ namespace UVtools.Core.Operations
set => RaiseAndSetIfChanged(ref _antiAliasingType, value);
}
+ public decimal BottomExposure
+ {
+ get => _bottomExposure;
+ set => RaiseAndSetIfChanged(ref _bottomExposure, Math.Round(value, 2));
+ }
+
+ public decimal NormalExposure
+ {
+ get => _normalExposure;
+ set => RaiseAndSetIfChanged(ref _normalExposure, Math.Round(value, 2));
+ }
+
public static OperationLayerReHeightItem[] GetItems(uint layerCount, decimal layerHeight)
{
@@ -158,6 +175,9 @@ namespace UVtools.Core.Operations
{
_selectedItem = Presets[0];
}
+
+ if (_bottomExposure <= 0) _bottomExposure = (decimal)SlicerFile.BottomExposureTime;
+ if (_normalExposure <= 0) _normalExposure = (decimal)SlicerFile.ExposureTime;
}
#endregion
@@ -297,8 +317,14 @@ namespace UVtools.Core.Operations
progress.Token.ThrowIfCancellationRequested();
- SlicerFile.LayerHeight = (float)SelectedItem.LayerHeight;
- SlicerFile.LayerManager.Layers = layers;
+ SlicerFile.SuppressRebuildPropertiesWork(() =>
+ {
+ SlicerFile.LayerHeight = (float)SelectedItem.LayerHeight;
+ SlicerFile.BottomExposureTime = (float)_bottomExposure;
+ SlicerFile.ExposureTime = (float)_normalExposure;
+ SlicerFile.LayerManager.Layers = layers;
+ }, true);
+
return !progress.Token.IsCancellationRequested;
}
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index fc4b636..268f850 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.21.0</Version>
+ <Version>2.21.1</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.WPF/Controls/Tools/ToolDoubleExposureControl.axaml b/UVtools.WPF/Controls/Tools/ToolDoubleExposureControl.axaml
index 56dd8ef..063ff3c 100644
--- a/UVtools.WPF/Controls/Tools/ToolDoubleExposureControl.axaml
+++ b/UVtools.WPF/Controls/Tools/ToolDoubleExposureControl.axaml
@@ -153,7 +153,7 @@
IsEnabled="{Binding Operation.SecondLayerDifference}"
ToolTip.Tip="When the 'Exposure the difference between first and second layer for the second layer' is active,
this setting will further erode the layer producing a overlap of n pixel perimeters over the previous layer"
- Text="Difference overlap margin:"/>
+ Text="Difference overlap by:"/>
<NumericUpDown
Grid.Row="0" Grid.Column="2"
VerticalAlignment="Center"
diff --git a/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml
index 168ac75..6a886f6 100644
--- a/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml
+++ b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml
@@ -9,22 +9,41 @@
<StackPanel Orientation="Vertical" Spacing="10">
<TextBlock VerticalAlignment="Center" Text="{Binding CurrentLayers}"/>
- <Grid RowDefinitions="Auto,10,Auto"
- ColumnDefinitions="Auto,10,Auto">
+ <Grid RowDefinitions="Auto,10,Auto,10,Auto"
+ ColumnDefinitions="Auto,10,Auto,5,Auto,20,Auto,10,Auto,5,Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Text="Modifier:"/>
<ComboBox
- Grid.Row="0" Grid.Column="2" Width="500"
+ Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="9"
+ Width="430"
SelectedItem="{Binding Operation.SelectedItem}"
- Items="{Binding Operation.Presets}"
- />
+ Items="{Binding Operation.Presets}"/>
<TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Text="Anti-Aliasing:"/>
- <ComboBox Grid.Row="2" Grid.Column="2" Width="500"
+ <ComboBox Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="9"
+ Width="430"
IsEnabled="{Binding Operation.CanAntiAliasing}"
Items="{Binding Operation.AntiAliasingType, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
SelectedItem="{Binding Operation.AntiAliasingType, Converter={StaticResource FromValueDescriptionToEnumConverter}}">
</ComboBox>
+
+ <TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Text="Bottom exposure:"/>
+ <NumericUpDown Grid.Row="4" Grid.Column="2"
+ VerticalAlignment="Center"
+ Minimum="0.01"
+ Maximum="1000"
+ Increment="0.5"
+ Value="{Binding Operation.BottomExposure}"/>
+ <TextBlock Grid.Row="4" Grid.Column="4" VerticalAlignment="Center" Text="s"/>
+
+ <TextBlock Grid.Row="4" Grid.Column="6" VerticalAlignment="Center" Text="Normal exposure:"/>
+ <NumericUpDown Grid.Row="4" Grid.Column="8"
+ VerticalAlignment="Center"
+ Minimum="0.01"
+ Maximum="1000"
+ Increment="0.5"
+ Value="{Binding Operation.NormalExposure}"/>
+ <TextBlock Grid.Row="4" Grid.Column="10" VerticalAlignment="Center" Text="s"/>
</Grid>
</StackPanel>
diff --git a/UVtools.WPF/MainWindow.Issues.cs b/UVtools.WPF/MainWindow.Issues.cs
index 1308b0e..8acfc62 100644
--- a/UVtools.WPF/MainWindow.Issues.cs
+++ b/UVtools.WPF/MainWindow.Issues.cs
@@ -44,9 +44,17 @@ namespace UVtools.WPF
}
public readonly List<LayerIssue> IgnoredIssues = new();
+ private uint _resinTrapDetectionStartLayer;
public bool IssueCanGoPrevious => Issues.Count > 0 && _issueSelectedIndex > 0;
public bool IssueCanGoNext => Issues.Count > 0 && _issueSelectedIndex < Issues.Count - 1;
+
+ public uint ResinTrapDetectionStartLayer
+ {
+ get => _resinTrapDetectionStartLayer;
+ set => RaiseAndSetIfChanged(ref _resinTrapDetectionStartLayer, value);
+ }
+
#endregion
#region Methods
@@ -526,7 +534,21 @@ namespace UVtools.WPF
if(clearIgnored) IgnoredIssues.Clear();
}
-
+ public void SetResinTrapDetectionStartLayer(char which)
+ {
+ switch (which)
+ {
+ case 'N':
+ ResinTrapDetectionStartLayer = SlicerFile.FirstNormalLayer.Index;
+ break;
+ case 'C':
+ ResinTrapDetectionStartLayer = ActualLayer;
+ break;
+ }
+ }
+
+
+
public IslandDetectionConfiguration GetIslandDetectionConfiguration(bool enable)
{
return new()
@@ -561,6 +583,7 @@ namespace UVtools.WPF
return new()
{
Enabled = enable,
+ StartLayerIndex = _resinTrapDetectionStartLayer,
BinaryThreshold = Settings.Issues.ResinTrapBinaryThreshold,
RequiredAreaToProcessCheck = Settings.Issues.ResinTrapRequiredAreaToProcessCheck,
RequiredBlackPixelsToDrain = Settings.Issues.ResinTrapRequiredBlackPixelsToDrain,
diff --git a/UVtools.WPF/MainWindow.LayerPreview.cs b/UVtools.WPF/MainWindow.LayerPreview.cs
index fd53e1d..06097c1 100644
--- a/UVtools.WPF/MainWindow.LayerPreview.cs
+++ b/UVtools.WPF/MainWindow.LayerPreview.cs
@@ -26,6 +26,7 @@ using Emgu.CV.Structure;
using Emgu.CV.Util;
using UVtools.AvaloniaControls;
using UVtools.Core;
+using UVtools.Core.EmguCV;
using UVtools.Core.Extensions;
using UVtools.Core.PixelEditor;
using UVtools.WPF.Controls;
@@ -74,7 +75,9 @@ namespace UVtools.WPF
private bool _isPixelEditorActive;
private bool _showLayerOutlinePrintVolumeBoundary;
private bool _showLayerOutlineLayerBoundary;
+ private bool _showLayerOutlineContourBoundary;
private bool _showLayerOutlineHollowAreas;
+ private bool _showLayerOutlineCentroids;
private bool _showLayerOutlineEdgeDetection;
private bool _showLayerOutlineDistanceDetection;
private bool _showLayerOutlineSkeletonize;
@@ -107,7 +110,9 @@ namespace UVtools.WPF
_showLayerImageDifference = Settings.LayerPreview.ShowLayerDifference;
_showLayerOutlinePrintVolumeBoundary = Settings.LayerPreview.VolumeBoundsOutline;
_showLayerOutlineLayerBoundary = Settings.LayerPreview.LayerBoundsOutline;
+ _showLayerOutlineContourBoundary = Settings.LayerPreview.ContourBoundsOutline;
_showLayerOutlineHollowAreas = Settings.LayerPreview.HollowOutline;
+ _showLayerOutlineCentroids = Settings.LayerPreview.CentroidOutline;
LayerImageBox.ZoomLevels = new AdvancedImageBox.ZoomLevelCollection(AppSettings.ZoomLevels);
@@ -370,6 +375,16 @@ namespace UVtools.WPF
}
}
+ public bool ShowLayerOutlineContourBoundary
+ {
+ get => _showLayerOutlineContourBoundary;
+ set
+ {
+ if (!RaiseAndSetIfChanged(ref _showLayerOutlineContourBoundary, value)) return;
+ ShowLayer();
+ }
+ }
+
public bool ShowLayerOutlineHollowAreas
{
get => _showLayerOutlineHollowAreas;
@@ -380,6 +395,16 @@ namespace UVtools.WPF
}
}
+ public bool ShowLayerOutlineCentroids
+ {
+ get => _showLayerOutlineCentroids;
+ set
+ {
+ if (!RaiseAndSetIfChanged(ref _showLayerOutlineCentroids, value)) return;
+ ShowLayer();
+ }
+ }
+
public bool ShowLayerOutlineEdgeDetection
{
get => _showLayerOutlineEdgeDetection;
@@ -983,6 +1008,21 @@ namespace UVtools.WPF
Settings.LayerPreview.LayerBoundsOutlineThickness);
}
+ if (_showLayerOutlineContourBoundary)
+ {
+ for (int i = 0; i < LayerCache.LayerContours.Size; i++)
+ {
+ if ((int)LayerCache.LayerHierarchyJagged.GetValue(0, i, 2) == -1 &&
+ (int)LayerCache.LayerHierarchyJagged.GetValue(0, i, 3) != -1) continue;
+ CvInvoke.Rectangle(LayerCache.ImageBgr, CvInvoke.BoundingRectangle(LayerCache.LayerContours[i]),
+ new MCvScalar(
+ Settings.LayerPreview.ContourBoundsOutlineColor.B,
+ Settings.LayerPreview.ContourBoundsOutlineColor.G,
+ Settings.LayerPreview.ContourBoundsOutlineColor.R),
+ Settings.LayerPreview.ContourBoundsOutlineThickness);
+ }
+ }
+
if (_showLayerOutlineHollowAreas)
{
//CvInvoke.Threshold(ActualLayerImage, grayscale, 1, 255, ThresholdType.Binary);
@@ -1009,6 +1049,34 @@ namespace UVtools.WPF
}
}
+ if (_showLayerOutlineCentroids)
+ {
+ for (int i = 0; i < LayerCache.LayerContours.Size; i++)
+ {
+ if ((int)LayerCache.LayerHierarchyJagged.GetValue(0, i, 2) == -1 &&
+ (int)LayerCache.LayerHierarchyJagged.GetValue(0, i, 3) != -1)
+ {
+ if (Settings.LayerPreview.CentroidOutlineHollow)
+ {
+ CvInvoke.Circle(LayerCache.ImageBgr, Contour.GetCentroid(LayerCache.LayerContours[i]),
+ Settings.LayerPreview.CentroidOutlineDiameter / 2, new MCvScalar(
+ Settings.LayerPreview.HollowOutlineColor.B,
+ Settings.LayerPreview.HollowOutlineColor.G,
+ Settings.LayerPreview.HollowOutlineColor.R), 1, LineType.AntiAlias);
+ }
+ }
+ else
+ {
+ CvInvoke.Circle(LayerCache.ImageBgr, Contour.GetCentroid(LayerCache.LayerContours[i]),
+ Settings.LayerPreview.CentroidOutlineDiameter / 2, new MCvScalar(
+ Settings.LayerPreview.CentroidOutlineColor.B,
+ Settings.LayerPreview.CentroidOutlineColor.G,
+ Settings.LayerPreview.CentroidOutlineColor.R), -1, LineType.AntiAlias);
+ }
+
+ }
+ }
+
if (_maskPoints is not null && _maskPoints.Count > 0)
{
using var vec = new VectorOfVectorOfPoint(_maskPoints.ToArray());
diff --git a/UVtools.WPF/MainWindow.axaml b/UVtools.WPF/MainWindow.axaml
index 6c98575..35fe48c 100644
--- a/UVtools.WPF/MainWindow.axaml
+++ b/UVtools.WPF/MainWindow.axaml
@@ -786,9 +786,39 @@
<CheckBox
IsChecked="{Binding Settings.Issues.ComputeOverhangs}"
Content="Overhangs"/>
- <CheckBox
- IsChecked="{Binding Settings.Issues.ComputeResinTraps}"
- Content="Resin traps"/>
+ <StackPanel Orientation="Horizontal">
+ <CheckBox
+ VerticalAlignment="Center"
+ IsChecked="{Binding Settings.Issues.ComputeResinTraps}"
+ Content="Resin traps"/>
+
+ <NumericUpDown
+ VerticalAlignment="Center"
+ Margin="10,0,0,0"
+ ToolTip.Tip="Starting layer index for resin trap detection which will also be considered a drain layer.
+&#x0a;Use this setting to bypass complicated rafts by selected the model first real layer."
+ Minimum="0"
+ Maximum="{Binding SlicerFile.LastLayerIndex}"
+ Increment="1"
+ Width="110"
+ Value="{Binding ResinTrapDetectionStartLayer}"/>
+
+ <Button
+ VerticalAlignment="Center"
+ Margin="2,0,0,0"
+ ToolTip.Tip="Set to the first normal layer"
+ Content="N"
+ Command="{Binding SetResinTrapDetectionStartLayer}"
+ CommandParameter="N"/>
+ <Button
+ VerticalAlignment="Center"
+ Margin="2,0,0,0"
+ ToolTip.Tip="Set to the current layer"
+ Content="C"
+ Command="{Binding SetResinTrapDetectionStartLayer}"
+ CommandParameter="C"/>
+ </StackPanel>
+
<CheckBox
IsChecked="{Binding Settings.Issues.ComputeTouchingBounds}"
Content="Touching bounds"/>
@@ -1948,8 +1978,7 @@
Command="{Binding OpenContextMenu}"
CommandParameter="LayerPreviewOutline"
VerticalAlignment="Stretch"
- Margin="1,0,0,0"
- >
+ Margin="1,0,0,0">
<Button.ContextMenu>
<ContextMenu Name="LayerPreviewOutlineContextMenu" PlacementMode="Bottom">
<CheckBox
@@ -1959,9 +1988,15 @@
IsChecked="{Binding ShowLayerOutlineLayerBoundary}"
Content="Layer boundary"/>
<CheckBox
+ IsChecked="{Binding ShowLayerOutlineContourBoundary}"
+ Content="Blob boundary"/>
+ <CheckBox
IsChecked="{Binding ShowLayerOutlineHollowAreas}"
Content="Hollow areas"/>
<CheckBox
+ IsChecked="{Binding ShowLayerOutlineCentroids}"
+ Content="Centroids"/>
+ <CheckBox
IsChecked="{Binding ShowLayerOutlineEdgeDetection}"
Content="Edge detection">
<CheckBox.IsEnabled>
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index 72ef210..efe024e 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -712,7 +712,7 @@ namespace UVtools.WPF
{
ProcessFile(Path.Combine(App.ApplicationPath, About.DemoFile));
}
-
+
DispatcherTimer.Run(() =>
{
UpdateTitle();
@@ -967,6 +967,7 @@ namespace UVtools.WPF
_actualLayer = 0;
LayerCache.Clear();
+ _resinTrapDetectionStartLayer = 0;
VisibleThumbnailIndex = 0;
@@ -1389,7 +1390,11 @@ namespace UVtools.WPF
_showLayerImageRotated = mat.Height > mat.Width;
}
- if (SlicerFile.DisplayMirror != Enumerations.FlipDirection.None)
+ if (SlicerFile.DisplayMirror == Enumerations.FlipDirection.None)
+ {
+ _showLayerImageFlipped = false;
+ }
+ else
{
_showLayerImageFlipped = true;
_showLayerImageFlippedHorizontally = SlicerFile.DisplayMirror is Enumerations.FlipDirection.Horizontally or Enumerations.FlipDirection.Both;
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index fb90318..56a2dd8 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.21.0</Version>
+ <Version>2.21.1</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
diff --git a/UVtools.WPF/UserSettings.cs b/UVtools.WPF/UserSettings.cs
index b76150e..a1aa260 100644
--- a/UVtools.WPF/UserSettings.cs
+++ b/UVtools.WPF/UserSettings.cs
@@ -183,12 +183,19 @@ namespace UVtools.WPF
private Color _volumeBoundsOutlineColor = new(255, 0, 255, 0);
private byte _volumeBoundsOutlineThickness = 3;
private bool _volumeBoundsOutline = true;
- private Color _layerBoundsOutlineColor = new(255, 0, 255, 0);
+ private Color _layerBoundsOutlineColor = new(255, 45, 150, 45);
private byte _layerBoundsOutlineThickness = 3;
private bool _layerBoundsOutline = false;
+ private Color _contourBoundsOutlineColor = new(255, 50, 100, 50);
+ private byte _contourBoundsOutlineThickness = 2;
+ private bool _contourBoundsOutline = false;
private Color _hollowOutlineColor = new(255, 255, 165, 0);
private sbyte _hollowOutlineLineThickness = 5;
private bool _hollowOutline = false;
+ private Color _centroidOutlineColor = new(255, 255, 0, 0);
+ private byte _centroidOutlineDiameter = 8;
+ private bool _centroidOutlineHollow = false;
+ private bool _centroidOutline = true;
private Color _maskOutlineColor = new(255, 42, 157, 244);
private sbyte _maskOutlineLineThickness = 10;
private bool _maskClearRoiAfterSet = true;
@@ -298,6 +305,35 @@ namespace UVtools.WPF
set => RaiseAndSetIfChanged(ref _layerBoundsOutline, value);
}
+ public Color ContourBoundsOutlineColor
+ {
+ get => _contourBoundsOutlineColor;
+ set
+ {
+ RaiseAndSetIfChanged(ref _contourBoundsOutlineColor, value);
+ RaisePropertyChanged(nameof(ContourBoundsOutlineBrush));
+ }
+ }
+
+ [XmlIgnore]
+ public SolidColorBrush ContourBoundsOutlineBrush
+ {
+ get => new(_contourBoundsOutlineColor.ToAvalonia());
+ set => ContourBoundsOutlineColor = new Color(value);
+ }
+
+ public byte ContourBoundsOutlineThickness
+ {
+ get => _contourBoundsOutlineThickness;
+ set => RaiseAndSetIfChanged(ref _contourBoundsOutlineThickness, value);
+ }
+
+ public bool ContourBoundsOutline
+ {
+ get => _contourBoundsOutline;
+ set => RaiseAndSetIfChanged(ref _contourBoundsOutline, value);
+ }
+
public Color HollowOutlineColor
{
get => _hollowOutlineColor;
@@ -327,6 +363,41 @@ namespace UVtools.WPF
set => RaiseAndSetIfChanged(ref _hollowOutline, value);
}
+ public Color CentroidOutlineColor
+ {
+ get => _centroidOutlineColor;
+ set
+ {
+ RaiseAndSetIfChanged(ref _centroidOutlineColor, value);
+ RaisePropertyChanged(nameof(CentroidOutlineBrush));
+ }
+ }
+
+ [XmlIgnore]
+ public SolidColorBrush CentroidOutlineBrush
+ {
+ get => new(_centroidOutlineColor.ToAvalonia());
+ set => CentroidOutlineColor = new Color(value);
+ }
+
+ public byte CentroidOutlineDiameter
+ {
+ get => _centroidOutlineDiameter;
+ set => RaiseAndSetIfChanged(ref _centroidOutlineDiameter, value);
+ }
+
+ public bool CentroidOutlineHollow
+ {
+ get => _centroidOutlineHollow;
+ set => RaiseAndSetIfChanged(ref _centroidOutlineHollow, value);
+ }
+
+ public bool CentroidOutline
+ {
+ get => _centroidOutline;
+ set => RaiseAndSetIfChanged(ref _centroidOutline, value);
+ }
+
public Color MaskOutlineColor
{
get => _maskOutlineColor;
diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml b/UVtools.WPF/Windows/SettingsWindow.axaml
index 6389676..325cf21 100644
--- a/UVtools.WPF/Windows/SettingsWindow.axaml
+++ b/UVtools.WPF/Windows/SettingsWindow.axaml
@@ -345,7 +345,7 @@
<StackPanel Orientation="Vertical">
<TextBlock Padding="10" Background="LightBlue" FontWeight="Bold" Text="Layer colors"/>
- <Grid Margin="10" RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto" ColumnDefinitions="Auto,Auto,Auto,Auto,*">
+ <Grid Margin="10" RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto" ColumnDefinitions="Auto,Auto,Auto,Auto,*">
<!--Tooltip overlay-->
<TextBlock Grid.Row="0" Grid.Column="0"
@@ -417,16 +417,14 @@
VerticalAlignment="Center"
Background="{Binding Settings.LayerPreview.LayerBoundsOutlineBrush}"
Command="{Binding SelectColor}"
- CommandParameter="LayerBoundsOutlineColor"
- />
+ CommandParameter="LayerBoundsOutlineColor"/>
<NumericUpDown Grid.Row="4" Grid.Column="2"
Margin="10,0,0,0"
VerticalAlignment="Center"
Minimum="1"
Maximum="50"
- Value="{Binding Settings.LayerPreview.LayerBoundsOutlineThickness}"
- />
+ Value="{Binding Settings.LayerPreview.LayerBoundsOutlineThickness}"/>
<TextBlock Grid.Row="4" Grid.Column="3"
Margin="5,0,0,0"
VerticalAlignment="Center"
@@ -436,15 +434,44 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="Show by default"
- IsChecked="{Binding Settings.LayerPreview.LayerBoundsOutline}"
- />
+ IsChecked="{Binding Settings.LayerPreview.LayerBoundsOutline}"/>
+
+ <!--Blob boundary-->
+ <TextBlock Grid.Row="6" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Blob boundary:"/>
+ <Button Grid.Row="6" Grid.Column="1"
+ Margin="10,0,0,0"
+ Padding="10"
+ BorderBrush="Black"
+ BorderThickness="2"
+ VerticalAlignment="Center"
+ Background="{Binding Settings.LayerPreview.ContourBoundsOutlineBrush}"
+ Command="{Binding SelectColor}"
+ CommandParameter="LayerBoundsOutlineColor"/>
+ <NumericUpDown Grid.Row="6" Grid.Column="2"
+ Margin="10,0,0,0"
+ VerticalAlignment="Center"
+ Minimum="1"
+ Maximum="50"
+ Value="{Binding Settings.LayerPreview.ContourBoundsOutlineThickness}"/>
+ <TextBlock Grid.Row="6" Grid.Column="3"
+ Margin="5,0,0,0"
+ VerticalAlignment="Center"
+ Text="Line thickness"/>
+ <CheckBox Grid.Row="6" Grid.Column="4"
+ Margin="10,0,0,0"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center"
+ Content="Show by default"
+ IsChecked="{Binding Settings.LayerPreview.ContourBoundsOutline}"/>
<!--Hallow area boundary-->
- <TextBlock Grid.Row="6" Grid.Column="0"
+ <TextBlock Grid.Row="8" Grid.Column="0"
VerticalAlignment="Center"
Text="Hollow area outline:"/>
- <Button Grid.Row="6" Grid.Column="1"
+ <Button Grid.Row="8" Grid.Column="1"
Margin="10,0,0,0"
Padding="10"
BorderBrush="Black"
@@ -453,29 +480,65 @@
Background="{Binding Settings.LayerPreview.HollowOutlineBrush}"
Command="{Binding SelectColor}"
CommandParameter="HollowOutlineColor"/>
- <NumericUpDown Grid.Row="6" Grid.Column="2"
+ <NumericUpDown Grid.Row="8" Grid.Column="2"
Margin="10,0,0,0"
VerticalAlignment="Center"
Minimum="-1"
Maximum="127"
Value="{Binding Settings.LayerPreview.HollowOutlineLineThickness}"/>
- <TextBlock Grid.Row="6" Grid.Column="3"
+ <TextBlock Grid.Row="8" Grid.Column="3"
Margin="5,0,0,0"
VerticalAlignment="Center"
ToolTip.Tip="Set -1 to fill the area"
Text="Line thickness"/>
- <CheckBox Grid.Row="6" Grid.Column="4"
+ <CheckBox Grid.Row="8" Grid.Column="4"
Margin="10,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="Show by default"
IsChecked="{Binding Settings.LayerPreview.HollowOutline}"/>
+ <!--Blob boundary-->
+ <TextBlock Grid.Row="10" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Centroids:"/>
+ <Button Grid.Row="10" Grid.Column="1"
+ Margin="10,0,0,0"
+ Padding="10"
+ BorderBrush="Black"
+ BorderThickness="2"
+ VerticalAlignment="Center"
+ Background="{Binding Settings.LayerPreview.CentroidOutlineBrush}"
+ Command="{Binding SelectColor}"
+ CommandParameter="LayerBoundsOutlineColor"/>
+ <NumericUpDown Grid.Row="10" Grid.Column="2"
+ Margin="10,0,0,0"
+ VerticalAlignment="Center"
+ Minimum="1"
+ Maximum="50"
+ Value="{Binding Settings.LayerPreview.CentroidOutlineDiameter}"/>
+ <TextBlock Grid.Row="10" Grid.Column="3"
+ Margin="5,0,0,0"
+ VerticalAlignment="Center"
+ Text="Diameter"/>
+
+ <StackPanel
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center"
+ Grid.Row="10" Grid.Column="3" Grid.ColumnSpan="2" Orientation="Horizontal" Spacing="10">
+ <CheckBox Content="Hollow centroids"
+ IsChecked="{Binding Settings.LayerPreview.CentroidOutlineHollow}"/>
+
+ <CheckBox Content="Show by default"
+ IsChecked="{Binding Settings.LayerPreview.CentroidOutline}"/>
+ </StackPanel>
+
+
<!--Masks-->
- <TextBlock Grid.Row="8" Grid.Column="0"
+ <TextBlock Grid.Row="12" Grid.Column="0"
VerticalAlignment="Center"
Text="Mask area outline:"/>
- <Button Grid.Row="8" Grid.Column="1"
+ <Button Grid.Row="12" Grid.Column="1"
Margin="10,0,0,0"
Padding="10"
BorderBrush="Black"
@@ -484,18 +547,18 @@
Background="{Binding Settings.LayerPreview.MaskOutlineBrush}"
Command="{Binding SelectColor}"
CommandParameter="MaskOutlineColor"/>
- <NumericUpDown Grid.Row="8" Grid.Column="2"
+ <NumericUpDown Grid.Row="12" Grid.Column="2"
Margin="10,0,0,0"
VerticalAlignment="Center"
Minimum="-1"
Maximum="127"
Value="{Binding Settings.LayerPreview.MaskOutlineLineThickness}"/>
- <TextBlock Grid.Row="8" Grid.Column="3"
+ <TextBlock Grid.Row="12" Grid.Column="3"
Margin="5,0,0,0"
VerticalAlignment="Center"
ToolTip.Tip="Set -1 to fill the area"
Text="Line thickness"/>
- <CheckBox Grid.Row="8" Grid.Column="4"
+ <CheckBox Grid.Row="12" Grid.Column="4"
Margin="10,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"