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-05-20 07:12:18 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-05-20 07:12:18 +0300
commitad92a0aa5cef5a9be46e2ba20ac5482fc9030015 (patch)
tree113d66f4d0b5f63924e3f089c412fb47f8f493bd
parentc43badb9c15b22a27b1cae5e386f158c6c2f3b11 (diff)
v2.12.2v2.12.2
- (Add) Layer action - Export layers to heat map: Export a layer range to a grayscale heat map image that represents the median of the mass in the Z depth/perception. The pixel brightness/intensity shows where the most mass are concentrated.
-rw-r--r--CHANGELOG.md4
-rw-r--r--UVtools.Core/Operations/Operation.cs2
-rw-r--r--UVtools.Core/Operations/OperationLayerExportHeatMap.cs159
-rw-r--r--UVtools.Core/Operations/OperationLayerImport.cs2
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.WPF/Assets/Icons/file-gif-16x16.png (renamed from UVtools.WPF/Assets/Icons/gif-16x16.png)bin266 -> 266 bytes
-rw-r--r--UVtools.WPF/Controls/Helpers.cs43
-rw-r--r--UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml32
-rw-r--r--UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml.cs37
-rw-r--r--UVtools.WPF/MainWindow.axaml.cs10
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj10
-rw-r--r--build/CreateRelease.WPF.ps12
12 files changed, 287 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 923fad4..6702ea2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## /05/2021 - v2.12.2
+
+- (Add) Layer action - Export layers to heat map: Export a layer range to a grayscale heat map image that represents the median of the mass in the Z depth/perception. The pixel brightness/intensity shows where the most mass are concentrated.
+
## 19/05/2021 - v2.12.1
- (Upgrade) AvaloniaUI from 0.10.4 to 0.10.5
diff --git a/UVtools.Core/Operations/Operation.cs b/UVtools.Core/Operations/Operation.cs
index 5cb7cad..f8b9b10 100644
--- a/UVtools.Core/Operations/Operation.cs
+++ b/UVtools.Core/Operations/Operation.cs
@@ -405,7 +405,7 @@ namespace UVtools.Core.Operations
{
if (!HaveMask) return null;
- var mask = mat.CloneBlank();
+ var mask = EmguExtensions.InitMat(mat.Size);
using VectorOfVectorOfPoint vec = new(points);
CvInvoke.DrawContours(mask, vec, -1, EmguExtensions.WhiteByte, -1);
return GetRoiOrDefault(mask);
diff --git a/UVtools.Core/Operations/OperationLayerExportHeatMap.cs b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs
new file mode 100644
index 0000000..eb6482c
--- /dev/null
+++ b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs
@@ -0,0 +1,159 @@
+/*
+ * 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.Text;
+using System.Threading.Tasks;
+using Emgu.CV;
+using Emgu.CV.CvEnum;
+using UVtools.Core.Extensions;
+using UVtools.Core.FileFormats;
+
+namespace UVtools.Core.Operations
+{
+ [Serializable]
+ public sealed class OperationLayerExportHeatMap : Operation
+ {
+ #region Members
+ private string _filePath;
+ private bool _cropByRoi = true;
+
+ #endregion
+
+ #region Overrides
+
+ public override bool CanHaveProfiles => false;
+ public override string Title => "Export layers to heat map";
+
+ public override string Description =>
+ "Export a layer range to a grayscale heat map image that represents the median of the mass in the Z depth/perception\n" +
+ "The pixel brightness/intensity shows where the most mass are concentrated.";
+
+ public override string ConfirmationText =>
+ $"generate a heatmap from layers {LayerIndexStart} through {LayerIndexEnd}?";
+
+ public override string ProgressTitle =>
+ $"Generating a heatmap from layers {LayerIndexStart} through {LayerIndexEnd}";
+
+ public override string ProgressAction => "Packed layers";
+
+ public override string ValidateInternally()
+ {
+ var sb = new StringBuilder();
+
+ if (LayerRangeCount < 2)
+ {
+ sb.AppendLine("To generate a heat map at least two layers are required.");
+ }
+
+ return sb.ToString();
+ }
+
+ public override string ToString()
+ {
+ var result = $"[Crop by ROI: {_cropByRoi}]" +
+ LayerRangeString;
+ if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
+ return result;
+ }
+
+ #endregion
+
+ #region Properties
+
+ public string FilePath
+ {
+ get => _filePath;
+ set => RaiseAndSetIfChanged(ref _filePath, value);
+ }
+
+ public bool CropByROI
+ {
+ get => _cropByRoi;
+ set => RaiseAndSetIfChanged(ref _cropByRoi, value);
+ }
+
+ #endregion
+
+ #region Constructor
+
+ public OperationLayerExportHeatMap()
+ { }
+
+ public OperationLayerExportHeatMap(FileFormat slicerFile) : base(slicerFile)
+ {
+ _filePath = SlicerFile.FileFullPath + ".heatmap.png";
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected override bool ExecuteInternally(OperationProgress progress)
+ {
+ using var sumMat32 = EmguExtensions.InitMat(SlicerFile.Resolution, 1, DepthType.Cv32S);
+ var sumMat32Roi = GetRoiOrDefault(sumMat32);
+ using var mask = GetMask(sumMat32);
+
+
+ Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex =>
+ {
+ if (progress.Token.IsCancellationRequested) return;
+
+ using var mat = SlicerFile[layerIndex].LayerMat;
+ using var mat32 = new Mat();
+ mat.ConvertTo(mat32, DepthType.Cv32S);
+ var mat32Roi = GetRoiOrDefault(mat32);
+
+ lock (progress.Mutex)
+ {
+ CvInvoke.Add(sumMat32Roi, mat32Roi, sumMat32Roi, mask);
+ progress++;
+ }
+ });
+
+ if (!progress.Token.IsCancellationRequested)
+ {
+ using var sumMat = EmguExtensions.InitMat(sumMat32.Size);
+ sumMat32.ConvertTo(sumMat, DepthType.Cv8U, 1.0 / LayerRangeCount);
+ if (_cropByRoi && HaveROI)
+ {
+ var sumMatRoi = GetRoiOrDefault(sumMat);
+ sumMatRoi.Save(_filePath);
+ }
+ else
+ {
+ sumMat.Save(_filePath);
+ }
+ }
+
+ return !progress.Token.IsCancellationRequested;
+ }
+
+ #endregion
+
+ #region Equality
+
+ private bool Equals(OperationLayerExportHeatMap other)
+ {
+ return _filePath == other._filePath && _cropByRoi == other._cropByRoi;
+ }
+
+ public override bool Equals(object obj)
+ {
+ return ReferenceEquals(this, obj) || obj is OperationLayerExportHeatMap other && Equals(other);
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(_filePath, _cropByRoi);
+ }
+
+ #endregion
+ }
+}
diff --git a/UVtools.Core/Operations/OperationLayerImport.cs b/UVtools.Core/Operations/OperationLayerImport.cs
index c1be566..5f10340 100644
--- a/UVtools.Core/Operations/OperationLayerImport.cs
+++ b/UVtools.Core/Operations/OperationLayerImport.cs
@@ -53,7 +53,7 @@ namespace UVtools.Core.Operations
public override Enumerations.LayerRangeSelection StartLayerRangeSelection => Enumerations.LayerRangeSelection.None;
public override bool CanROI => false;
- public override string Title => "Import Layers";
+ public override string Title => "Import layers";
public override string Description =>
"Import layers from local files into the model at a selected layer height.\n" +
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index 9dedee7..5a6763a 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.12.1</Version>
+ <Version>2.12.2</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.WPF/Assets/Icons/gif-16x16.png b/UVtools.WPF/Assets/Icons/file-gif-16x16.png
index ac06f8c..ac06f8c 100644
--- a/UVtools.WPF/Assets/Icons/gif-16x16.png
+++ b/UVtools.WPF/Assets/Icons/file-gif-16x16.png
Binary files differ
diff --git a/UVtools.WPF/Controls/Helpers.cs b/UVtools.WPF/Controls/Helpers.cs
index 61046f2..ed5d288 100644
--- a/UVtools.WPF/Controls/Helpers.cs
+++ b/UVtools.WPF/Controls/Helpers.cs
@@ -24,9 +24,48 @@ namespace UVtools.WPF.Controls
"bmp",
"jpeg",
"jpg",
- "gif"
+ "tif",
+ "tiff",
}
- }
+ },
+ };
+
+ public static readonly List<FileDialogFilter> ImagesFullFileFilter = new()
+ {
+ new()
+ {
+ Name = "PNG Files",
+ Extensions = new List<string>
+ {
+ "png"
+ }
+ },
+ new()
+ {
+ Name = "JPG Files",
+ Extensions = new List<string>
+ {
+ "jpg",
+ "jpeg"
+ }
+ },
+ new()
+ {
+ Name = "BMP Files",
+ Extensions = new List<string>
+ {
+ "bmp",
+ }
+ },
+ new()
+ {
+ Name = "TIF Files",
+ Extensions = new List<string>
+ {
+ "tif",
+ "tiff",
+ }
+ },
};
public static readonly List<FileDialogFilter> PngFileFilter = new()
diff --git a/UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml b/UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml
new file mode 100644
index 0000000..cb9dcc1
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml
@@ -0,0 +1,32 @@
+<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.ToolLayerExportHeatMapControl">
+
+ <StackPanel Spacing="10">
+
+ <StackPanel Orientation="Horizontal" Spacing="5">
+ <TextBox
+ Watermark="Output filepath"
+ UseFloatingWatermark="True"
+ VerticalAlignment="Center"
+ IsReadOnly="True"
+ Width="500"
+ Text="{Binding Operation.FilePath}"/>
+ <Button
+ VerticalAlignment="Stretch"
+ Command="{Binding ChooseFilePath}">
+ <Image Source="/Assets/Icons/open-16x16.png"/>
+ </Button>
+ </StackPanel>
+
+ <CheckBox
+ Content="Crop image by selected ROI"
+ IsVisible="{Binding ParentWindow.IsROIVisible}"
+ IsChecked="{Binding Operation.CropByROI}"/>
+
+ </StackPanel>
+
+</UserControl>
diff --git a/UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml.cs
new file mode 100644
index 0000000..6c6d74e
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolLayerExportHeatMapControl.axaml.cs
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+using System.IO;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using UVtools.Core.Operations;
+
+namespace UVtools.WPF.Controls.Tools
+{
+ public partial class ToolLayerExportHeatMapControl : ToolControl
+ {
+ public OperationLayerExportHeatMap Operation => BaseOperation as OperationLayerExportHeatMap;
+ public ToolLayerExportHeatMapControl()
+ {
+ InitializeComponent();
+ BaseOperation = new OperationLayerExportHeatMap(SlicerFile);
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public async void ChooseFilePath()
+ {
+ var dialog = new SaveFileDialog
+ {
+ Filters = Helpers.ImagesFullFileFilter,
+ InitialFileName = Path.GetFileName(SlicerFile.FileFullPath) + ".heatmap.png",
+ Directory = Path.GetDirectoryName(SlicerFile.FileFullPath),
+ };
+ var file = await dialog.ShowAsync(ParentWindow);
+ if (string.IsNullOrWhiteSpace(file)) return;
+ Operation.FilePath = file;
+ }
+ }
+}
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index d0ffafc..14750fc 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -338,7 +338,15 @@ namespace UVtools.WPF
Tag = new OperationLayerExportGif(),
Icon = new Avalonia.Controls.Image
{
- Source = new Bitmap(App.GetAsset("/Assets/Icons/gif-16x16.png"))
+ Source = new Bitmap(App.GetAsset("/Assets/Icons/file-gif-16x16.png"))
+ }
+ },
+ new()
+ {
+ Tag = new OperationLayerExportHeatMap(),
+ Icon = new Avalonia.Controls.Image
+ {
+ Source = new Bitmap(App.GetAsset("/Assets/Icons/file-image-16x16.png"))
}
},
};
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index 564edcf..e54e0d5 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.12.1</Version>
+ <Version>2.12.2</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -73,12 +73,4 @@
</AvaloniaResource>
<AvaloniaResource Include="Assets\Icons\*" />
</ItemGroup>
- <ItemGroup>
- <Compile Update="Controls\Tools\ToolLayerArithmeticControl.axaml.cs">
- <DependentUpon>ToolLayerArithmeticControl.axaml</DependentUpon>
- </Compile>
- <Compile Update="Windows\PrusaSlicerManagerWindow.axaml.cs">
- <DependentUpon>PrusaSlicerManagerWindow.axaml</DependentUpon>
- </Compile>
- </ItemGroup>
</Project>
diff --git a/build/CreateRelease.WPF.ps1 b/build/CreateRelease.WPF.ps1
index 086b533..f15382f 100644
--- a/build/CreateRelease.WPF.ps1
+++ b/build/CreateRelease.WPF.ps1
@@ -34,7 +34,7 @@ Set-Location $PSScriptRoot\..
####################################
$enableMSI = $true
#$buildOnly = $null
-$buildOnly = "win-x64"
+#$buildOnly = "win-x64"
# Profilling
$stopWatch = New-Object -TypeName System.Diagnostics.Stopwatch
$deployStopWatch = New-Object -TypeName System.Diagnostics.Stopwatch