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-07-28 05:56:49 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2020-07-28 05:56:49 +0300
commit858bc33d2d8518ac0aa0ad06be7c65c68071434e (patch)
tree19586b232404dffe58cff9ed969eecf69fc3556d
parentc76a68c29bc041c571b30995ec59c03d27b4ceea (diff)
v0.6.3.4v0.6.3.4
* (Add) Mutator: Threshold pixels * (Change) Mutator: PyrDownUp - Name to "Big Blur" and add better description of the effect * (Change) Mutator: SmoothMedian - Better description * (Change) Mutator: SmoothGaussian - Better description * (Fix) Tool: Layer Re-Height - When go lower heights the pixels count per layer statistics are lost * (Fix) "Pixel Edit" has the old tooltip text (#14) * (Fix) Readme: Text fixes (#14)
-rw-r--r--CHANGELOG.md10
-rw-r--r--README.md4
-rw-r--r--UVtools.Core/Layer/Layer.cs12
-rw-r--r--UVtools.Core/Layer/LayerManager.cs22
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.GUI/Forms/FrmMutation.cs3
-rw-r--r--UVtools.GUI/Forms/FrmMutationThreshold.Designer.cs395
-rw-r--r--UVtools.GUI/Forms/FrmMutationThreshold.cs213
-rw-r--r--UVtools.GUI/Forms/FrmMutationThreshold.resx131
-rw-r--r--UVtools.GUI/FrmMain.Designer.cs7
-rw-r--r--UVtools.GUI/FrmMain.cs41
-rw-r--r--UVtools.GUI/FrmMain.resx149
-rw-r--r--UVtools.GUI/Properties/AssemblyInfo.cs4
-rw-r--r--UVtools.GUI/UVtools.GUI.csproj9
14 files changed, 906 insertions, 96 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cbcb13d..897cd18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# Changelog
+## 28/07/2020 - v0.6.3.4
+
+* (Add) Mutator: Threshold pixels
+* (Change) Mutator: PyrDownUp - Name to "Big Blur" and add better description of the effect
+* (Change) Mutator: SmoothMedian - Better description
+* (Change) Mutator: SmoothGaussian - Better description
+* (Fix) Tool: Layer Re-Height - When go lower heights the pixels count per layer statistics are lost
+* (Fix) "Pixel Edit" has the old tooltip text (#14)
+* (Fix) Readme: Text fixes (#14)
+
## 26/07/2020 - v0.6.3.3
* (Add) Allow to save properties to clipboard
diff --git a/README.md b/README.md
index 1e8c6cf..ee27996 100644
--- a/README.md
+++ b/README.md
@@ -109,7 +109,7 @@ But also, i need victims for test subject. Proceed at your own risk!
* Choose SL1 printer
1. Close PrusaSlicer
1. Open UVtools if not already
- * Under Menu click -> About -> Install profiles into PrusaSlicer
+ * Under Menu click -> Help -> Install profiles into PrusaSlicer
1. Open PrusaSlicer and check if profiles are there
1. To clean up interface remove printers that you will not use (OPTIONAL)
1. Duplicate and/or create your printer and tune the values if required
@@ -149,7 +149,7 @@ There are multiple ways to open your file:
## Library -> Developers
-Are you a developer? This project include a .NET Core library (PrusaSL1Reader) that can be referenced in your application to make use of my work. Easy to use calls that allow you work with the formats. For more information navigate main code.
+Are you a developer? This project include a .NET Standard library (UVtools.Core) that can be referenced in your application to make use of my work. Easy to use calls that allow you work with the formats. For more information navigate main code.
## TODO
diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs
index ed221c1..f39db24 100644
--- a/UVtools.Core/Layer/Layer.cs
+++ b/UVtools.Core/Layer/Layer.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
+using System.IO.Compression;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
@@ -35,7 +36,7 @@ namespace UVtools.Core
/// <summary>
/// Gets the number of non zero pixels on this layer image
/// </summary>
- public uint NonZeroPixelCount { get; private protected set; }
+ public uint NonZeroPixelCount { get; internal set; }
/// <summary>
/// Gets the bounding rectangle for the image area
@@ -722,6 +723,15 @@ namespace UVtools.Core
}
}
+ public void MutateThresholdPixels(byte threshold, byte maximum, ThresholdType thresholdType)
+ {
+ using (Mat dst = LayerMat)
+ {
+ CvInvoke.Threshold(dst, dst, threshold, maximum, thresholdType);
+ LayerMat = dst;
+ }
+ }
+
public void MutatePyrDownUp(BorderType borderType = BorderType.Reflect101)
{
using (Mat dst = LayerMat)
diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs
index d38383f..f568714 100644
--- a/UVtools.Core/Layer/LayerManager.cs
+++ b/UVtools.Core/Layer/LayerManager.cs
@@ -37,7 +37,6 @@ namespace UVtools.Core
Rotate,
Solidify,
PixelDimming,
- //LayerSmash,
Erode,
Dilate,
Opening,
@@ -46,6 +45,7 @@ namespace UVtools.Core
TopHat,
BlackHat,
HitMiss,
+ ThresholdPixels,
PyrDownUp,
SmoothMedian,
SmoothGaussian,
@@ -53,7 +53,7 @@ namespace UVtools.Core
#endregion
#region Properties
- public FileFormats.FileFormat SlicerFile { get; private set; }
+ public FileFormat SlicerFile { get; private set; }
/// <summary>
/// Layers List
@@ -620,6 +620,22 @@ namespace UVtools.Core
progress.Token.ThrowIfCancellationRequested();
}
+ public void MutateThresholdPixels(uint startLayerIndex, uint endLayerIndex, byte threshold, byte maximum, ThresholdType thresholdType, OperationProgress progress)
+ {
+ if (ReferenceEquals(progress, null)) progress = new OperationProgress();
+ progress.Reset("Thresholding", endLayerIndex - startLayerIndex + 1);
+ Parallel.For(startLayerIndex, endLayerIndex + 1, layerIndex =>
+ {
+ if (progress.Token.IsCancellationRequested) return;
+ this[layerIndex].MutateThresholdPixels(threshold, maximum, thresholdType);
+ lock (progress.Mutex)
+ {
+ progress++;
+ }
+ });
+ progress.Token.ThrowIfCancellationRequested();
+ }
+
public void MutatePyrDownUp(uint startLayerIndex, uint endLayerIndex, BorderType borderType = BorderType.Default, OperationProgress progress = null)
{
if (ReferenceEquals(progress, null)) progress = new OperationProgress();
@@ -1480,6 +1496,8 @@ namespace UVtools.Core
PositionZ = (float) (operation.LayerHeight * (newLayerIndex + 1)),
ExposureTime = oldLayer.ExposureTime,
BoundingRectangle = oldLayer.BoundingRectangle,
+ NonZeroPixelCount = oldLayer.NonZeroPixelCount
+
};
newLayerIndex++;
progress++;
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index d3fb17f..0d88914 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>0.6.3.3</Version>
+ <Version>0.6.3.4</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.GUI/Forms/FrmMutation.cs b/UVtools.GUI/Forms/FrmMutation.cs
index e8ba854..24035e4 100644
--- a/UVtools.GUI/Forms/FrmMutation.cs
+++ b/UVtools.GUI/Forms/FrmMutation.cs
@@ -207,7 +207,8 @@ namespace UVtools.GUI.Forms
}
}
- if (MessageBox.Show($"Are you sure you want to {Mutation.Mutate}?", Text, MessageBoxButtons.YesNo,
+ var operationName = string.IsNullOrEmpty(Mutation.MenuName) ? Mutation.Mutate.ToString() : Mutation.MenuName;
+ if (MessageBox.Show($"Are you sure you want to {operationName}?", Text, MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
DialogResult = DialogResult.OK;
diff --git a/UVtools.GUI/Forms/FrmMutationThreshold.Designer.cs b/UVtools.GUI/Forms/FrmMutationThreshold.Designer.cs
new file mode 100644
index 0000000..c6c87ac
--- /dev/null
+++ b/UVtools.GUI/Forms/FrmMutationThreshold.Designer.cs
@@ -0,0 +1,395 @@
+using UVtools.GUI.Controls;
+
+namespace UVtools.GUI.Forms
+{
+ partial class FrmMutationThreshold
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMutationThreshold));
+ this.lbDescription = new System.Windows.Forms.Label();
+ this.lbLayerRange = new System.Windows.Forms.Label();
+ this.nmLayerRangeStart = new System.Windows.Forms.NumericUpDown();
+ this.nmLayerRangeEnd = new System.Windows.Forms.NumericUpDown();
+ this.lbLayerRangeTo = new System.Windows.Forms.Label();
+ this.cmLayerRange = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.btnLayerRangeAllLayers = new System.Windows.Forms.ToolStripMenuItem();
+ this.btnLayerRangeCurrentLayer = new System.Windows.Forms.ToolStripMenuItem();
+ this.btnLayerRangeBottomLayers = new System.Windows.Forms.ToolStripMenuItem();
+ this.btnLayerRangeNormalLayers = new System.Windows.Forms.ToolStripMenuItem();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.btnMutate = new System.Windows.Forms.Button();
+ this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.cbThresholdType = new System.Windows.Forms.ComboBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.nmThreshold = new System.Windows.Forms.NumericUpDown();
+ this.nmMaximum = new System.Windows.Forms.NumericUpDown();
+ this.label2 = new System.Windows.Forms.Label();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.btnPresetSetPixelsBrightness = new System.Windows.Forms.Button();
+ this.btnPresetFreeUse = new System.Windows.Forms.Button();
+ this.btnPresetStripAntiAliasing = new System.Windows.Forms.Button();
+ this.btnLayerRangeSelect = new UVtools.GUI.Controls.SplitButton();
+ ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).BeginInit();
+ this.cmLayerRange.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.nmThreshold)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.nmMaximum)).BeginInit();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // lbDescription
+ //
+ this.lbDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.lbDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lbDescription.Location = new System.Drawing.Point(13, 14);
+ this.lbDescription.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.lbDescription.Name = "lbDescription";
+ this.lbDescription.Size = new System.Drawing.Size(573, 128);
+ this.lbDescription.TabIndex = 0;
+ this.lbDescription.Text = "Description";
+ //
+ // lbLayerRange
+ //
+ this.lbLayerRange.AutoSize = true;
+ this.lbLayerRange.Location = new System.Drawing.Point(13, 150);
+ this.lbLayerRange.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.lbLayerRange.Name = "lbLayerRange";
+ this.lbLayerRange.Size = new System.Drawing.Size(97, 20);
+ this.lbLayerRange.TabIndex = 9;
+ this.lbLayerRange.Text = "Layer range:";
+ this.toolTip.SetToolTip(this.lbLayerRange, resources.GetString("lbLayerRange.ToolTip"));
+ //
+ // nmLayerRangeStart
+ //
+ this.nmLayerRangeStart.Location = new System.Drawing.Point(118, 147);
+ this.nmLayerRangeStart.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.nmLayerRangeStart.Maximum = new decimal(new int[] {
+ 100000,
+ 0,
+ 0,
+ 0});
+ this.nmLayerRangeStart.Name = "nmLayerRangeStart";
+ this.nmLayerRangeStart.Size = new System.Drawing.Size(120, 26);
+ this.nmLayerRangeStart.TabIndex = 0;
+ //
+ // nmLayerRangeEnd
+ //
+ this.nmLayerRangeEnd.Location = new System.Drawing.Point(314, 147);
+ this.nmLayerRangeEnd.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.nmLayerRangeEnd.Maximum = new decimal(new int[] {
+ 100000,
+ 0,
+ 0,
+ 0});
+ this.nmLayerRangeEnd.Name = "nmLayerRangeEnd";
+ this.nmLayerRangeEnd.Size = new System.Drawing.Size(120, 26);
+ this.nmLayerRangeEnd.TabIndex = 1;
+ //
+ // lbLayerRangeTo
+ //
+ this.lbLayerRangeTo.AutoSize = true;
+ this.lbLayerRangeTo.Location = new System.Drawing.Point(275, 150);
+ this.lbLayerRangeTo.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.lbLayerRangeTo.Name = "lbLayerRangeTo";
+ this.lbLayerRangeTo.Size = new System.Drawing.Size(31, 20);
+ this.lbLayerRangeTo.TabIndex = 12;
+ this.lbLayerRangeTo.Text = "To:";
+ //
+ // cmLayerRange
+ //
+ this.cmLayerRange.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.btnLayerRangeAllLayers,
+ this.btnLayerRangeCurrentLayer,
+ this.btnLayerRangeBottomLayers,
+ this.btnLayerRangeNormalLayers});
+ this.cmLayerRange.Name = "cmLayerRange";
+ this.cmLayerRange.Size = new System.Drawing.Size(226, 92);
+ //
+ // btnLayerRangeAllLayers
+ //
+ this.btnLayerRangeAllLayers.Name = "btnLayerRangeAllLayers";
+ this.btnLayerRangeAllLayers.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
+ | System.Windows.Forms.Keys.A)));
+ this.btnLayerRangeAllLayers.Size = new System.Drawing.Size(225, 22);
+ this.btnLayerRangeAllLayers.Text = "&All Layers";
+ this.btnLayerRangeAllLayers.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnLayerRangeCurrentLayer
+ //
+ this.btnLayerRangeCurrentLayer.Name = "btnLayerRangeCurrentLayer";
+ this.btnLayerRangeCurrentLayer.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
+ | System.Windows.Forms.Keys.C)));
+ this.btnLayerRangeCurrentLayer.Size = new System.Drawing.Size(225, 22);
+ this.btnLayerRangeCurrentLayer.Text = "&Current Layer";
+ this.btnLayerRangeCurrentLayer.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnLayerRangeBottomLayers
+ //
+ this.btnLayerRangeBottomLayers.Name = "btnLayerRangeBottomLayers";
+ this.btnLayerRangeBottomLayers.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
+ | System.Windows.Forms.Keys.B)));
+ this.btnLayerRangeBottomLayers.Size = new System.Drawing.Size(225, 22);
+ this.btnLayerRangeBottomLayers.Text = "&Bottom Layers";
+ this.btnLayerRangeBottomLayers.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnLayerRangeNormalLayers
+ //
+ this.btnLayerRangeNormalLayers.Name = "btnLayerRangeNormalLayers";
+ this.btnLayerRangeNormalLayers.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
+ | System.Windows.Forms.Keys.N)));
+ this.btnLayerRangeNormalLayers.Size = new System.Drawing.Size(225, 22);
+ this.btnLayerRangeNormalLayers.Text = "&Normal Layers";
+ this.btnLayerRangeNormalLayers.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnCancel
+ //
+ this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Image = global::UVtools.GUI.Properties.Resources.Cancel_24x24;
+ this.btnCancel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.btnCancel.Location = new System.Drawing.Point(434, 307);
+ this.btnCancel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(150, 48);
+ this.btnCancel.TabIndex = 6;
+ this.btnCancel.Text = "&Cancel";
+ this.btnCancel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ this.btnCancel.UseVisualStyleBackColor = true;
+ this.btnCancel.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnMutate
+ //
+ this.btnMutate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.btnMutate.Image = global::UVtools.GUI.Properties.Resources.Ok_24x24;
+ this.btnMutate.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.btnMutate.Location = new System.Drawing.Point(276, 307);
+ this.btnMutate.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.btnMutate.Name = "btnMutate";
+ this.btnMutate.Size = new System.Drawing.Size(150, 48);
+ this.btnMutate.TabIndex = 5;
+ this.btnMutate.Text = "&Mutate";
+ this.btnMutate.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ this.btnMutate.UseVisualStyleBackColor = true;
+ this.btnMutate.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // toolTip
+ //
+ this.toolTip.AutoPopDelay = 32767;
+ this.toolTip.InitialDelay = 500;
+ this.toolTip.IsBalloon = true;
+ this.toolTip.ReshowDelay = 100;
+ this.toolTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info;
+ this.toolTip.ToolTipTitle = "Information";
+ //
+ // cbThresholdType
+ //
+ this.cbThresholdType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cbThresholdType.FormattingEnabled = true;
+ this.cbThresholdType.Location = new System.Drawing.Point(446, 181);
+ this.cbThresholdType.Name = "cbThresholdType";
+ this.cbThresholdType.Size = new System.Drawing.Size(138, 28);
+ this.cbThresholdType.TabIndex = 13;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(13, 185);
+ this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(83, 20);
+ this.label1.TabIndex = 14;
+ this.label1.Text = "Threshold:";
+ //
+ // nmThreshold
+ //
+ this.nmThreshold.Location = new System.Drawing.Point(118, 182);
+ this.nmThreshold.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.nmThreshold.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.nmThreshold.Name = "nmThreshold";
+ this.nmThreshold.Size = new System.Drawing.Size(120, 26);
+ this.nmThreshold.TabIndex = 15;
+ this.nmThreshold.Value = new decimal(new int[] {
+ 127,
+ 0,
+ 0,
+ 0});
+ //
+ // nmMaximum
+ //
+ this.nmMaximum.Location = new System.Drawing.Point(314, 182);
+ this.nmMaximum.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.nmMaximum.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.nmMaximum.Name = "nmMaximum";
+ this.nmMaximum.Size = new System.Drawing.Size(120, 26);
+ this.nmMaximum.TabIndex = 17;
+ this.nmMaximum.Value = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(260, 185);
+ this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(46, 20);
+ this.label2.TabIndex = 16;
+ this.label2.Text = "Max.:";
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.btnPresetSetPixelsBrightness);
+ this.groupBox1.Controls.Add(this.btnPresetFreeUse);
+ this.groupBox1.Controls.Add(this.btnPresetStripAntiAliasing);
+ this.groupBox1.Location = new System.Drawing.Point(17, 222);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(567, 77);
+ this.groupBox1.TabIndex = 18;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Presets / Helpers";
+ //
+ // btnPresetSetPixelsBrightness
+ //
+ this.btnPresetSetPixelsBrightness.Location = new System.Drawing.Point(338, 25);
+ this.btnPresetSetPixelsBrightness.Name = "btnPresetSetPixelsBrightness";
+ this.btnPresetSetPixelsBrightness.Size = new System.Drawing.Size(223, 36);
+ this.btnPresetSetPixelsBrightness.TabIndex = 2;
+ this.btnPresetSetPixelsBrightness.Text = "Set pixels brightness";
+ this.btnPresetSetPixelsBrightness.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnPresetFreeUse
+ //
+ this.btnPresetFreeUse.Location = new System.Drawing.Point(6, 25);
+ this.btnPresetFreeUse.Name = "btnPresetFreeUse";
+ this.btnPresetFreeUse.Size = new System.Drawing.Size(160, 36);
+ this.btnPresetFreeUse.TabIndex = 1;
+ this.btnPresetFreeUse.Text = "Free use";
+ this.btnPresetFreeUse.UseVisualStyleBackColor = true;
+ this.btnPresetFreeUse.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnPresetStripAntiAliasing
+ //
+ this.btnPresetStripAntiAliasing.Location = new System.Drawing.Point(172, 25);
+ this.btnPresetStripAntiAliasing.Name = "btnPresetStripAntiAliasing";
+ this.btnPresetStripAntiAliasing.Size = new System.Drawing.Size(160, 36);
+ this.btnPresetStripAntiAliasing.TabIndex = 0;
+ this.btnPresetStripAntiAliasing.Text = "Strip AntiAliasing";
+ this.btnPresetStripAntiAliasing.UseVisualStyleBackColor = true;
+ this.btnPresetStripAntiAliasing.Click += new System.EventHandler(this.ItemClicked);
+ //
+ // btnLayerRangeSelect
+ //
+ this.btnLayerRangeSelect.Location = new System.Drawing.Point(446, 146);
+ this.btnLayerRangeSelect.Menu = this.cmLayerRange;
+ this.btnLayerRangeSelect.Name = "btnLayerRangeSelect";
+ this.btnLayerRangeSelect.Size = new System.Drawing.Size(138, 26);
+ this.btnLayerRangeSelect.TabIndex = 2;
+ this.btnLayerRangeSelect.Text = "Select";
+ this.btnLayerRangeSelect.UseVisualStyleBackColor = true;
+ //
+ // FrmMutationThreshold
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnCancel;
+ this.ClientSize = new System.Drawing.Size(599, 369);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.nmMaximum);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.nmThreshold);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.cbThresholdType);
+ this.Controls.Add(this.btnLayerRangeSelect);
+ this.Controls.Add(this.lbLayerRangeTo);
+ this.Controls.Add(this.nmLayerRangeEnd);
+ this.Controls.Add(this.nmLayerRangeStart);
+ this.Controls.Add(this.lbLayerRange);
+ this.Controls.Add(this.btnMutate);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.lbDescription);
+ this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.KeyPreview = true;
+ this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "FrmMutationThreshold";
+ this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Form1";
+ this.TopMost = true;
+ ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).EndInit();
+ this.cmLayerRange.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.nmThreshold)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.nmMaximum)).EndInit();
+ this.groupBox1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label lbDescription;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.Button btnMutate;
+ private System.Windows.Forms.Label lbLayerRange;
+ private System.Windows.Forms.NumericUpDown nmLayerRangeStart;
+ private System.Windows.Forms.NumericUpDown nmLayerRangeEnd;
+ private System.Windows.Forms.Label lbLayerRangeTo;
+ private Controls.SplitButton btnLayerRangeSelect;
+ private System.Windows.Forms.ContextMenuStrip cmLayerRange;
+ private System.Windows.Forms.ToolStripMenuItem btnLayerRangeAllLayers;
+ private System.Windows.Forms.ToolStripMenuItem btnLayerRangeCurrentLayer;
+ private System.Windows.Forms.ToolStripMenuItem btnLayerRangeBottomLayers;
+ private System.Windows.Forms.ToolStripMenuItem btnLayerRangeNormalLayers;
+ private System.Windows.Forms.ToolTip toolTip;
+ private System.Windows.Forms.ComboBox cbThresholdType;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.NumericUpDown nmThreshold;
+ private System.Windows.Forms.NumericUpDown nmMaximum;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button btnPresetStripAntiAliasing;
+ private System.Windows.Forms.Button btnPresetSetPixelsBrightness;
+ private System.Windows.Forms.Button btnPresetFreeUse;
+ }
+} \ No newline at end of file
diff --git a/UVtools.GUI/Forms/FrmMutationThreshold.cs b/UVtools.GUI/Forms/FrmMutationThreshold.cs
new file mode 100644
index 0000000..5049d70
--- /dev/null
+++ b/UVtools.GUI/Forms/FrmMutationThreshold.cs
@@ -0,0 +1,213 @@
+/*
+ * 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.Windows.Forms;
+using Emgu.CV.CvEnum;
+
+namespace UVtools.GUI.Forms
+{
+ public partial class FrmMutationThreshold : Form
+ {
+ #region Properties
+
+ private Mutation Mutation { get; }
+
+ public uint LayerRangeStart
+ {
+ get => (uint) nmLayerRangeStart.Value;
+ set => nmLayerRangeStart.Value = value;
+ }
+
+ public uint LayerRangeEnd
+ {
+ get => (uint)Math.Min(nmLayerRangeEnd.Value, Program.SlicerFile.LayerCount-1);
+ set => nmLayerRangeEnd.Value = value;
+ }
+
+ public byte Threshold
+ {
+ get => (byte)nmThreshold.Value;
+ set => nmThreshold.Value = value;
+ }
+
+ public byte Maximum
+ {
+ get => (byte) nmMaximum.Value;
+ set => nmMaximum.Value = value;
+ }
+
+ public ThresholdType ThresholdTypeValue
+ {
+ get => cbThresholdType.SelectedItem is ThresholdType item ? item : ThresholdType.Binary;
+ set => cbThresholdType.SelectedItem = value;
+ }
+ #endregion
+
+ #region Constructors
+ public FrmMutationThreshold(Mutation mutation)
+ {
+ InitializeComponent();
+ Mutation = mutation;
+ DialogResult = DialogResult.Cancel;
+
+ Text = $"Mutate: {mutation.MenuName}";
+ lbDescription.Text = Mutation.Description;
+
+ nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount-1;
+
+ foreach (var thresholdType in (ThresholdType[])Enum.GetValues(typeof(ThresholdType)))
+ {
+ cbThresholdType.Items.Add(thresholdType);
+ }
+
+ cbThresholdType.SelectedItem = ThresholdType.Binary;
+ }
+ #endregion
+
+ #region Overrides
+ protected override void OnKeyUp(KeyEventArgs e)
+ {
+ base.OnKeyUp(e);
+ if (e.KeyCode == Keys.Enter)
+ {
+ btnMutate.PerformClick();
+ e.Handled = true;
+ return;
+ }
+
+ if ((ModifierKeys & Keys.Shift) == Keys.Shift && (ModifierKeys & Keys.Control) == Keys.Control)
+ {
+ if (e.KeyCode == Keys.A)
+ {
+ btnLayerRangeAllLayers.PerformClick();
+ e.Handled = true;
+ return;
+ }
+
+ if (e.KeyCode == Keys.C)
+ {
+ btnLayerRangeCurrentLayer.PerformClick();
+ e.Handled = true;
+ return;
+ }
+
+ if (e.KeyCode == Keys.B)
+ {
+ btnLayerRangeBottomLayers.PerformClick();
+ e.Handled = true;
+ return;
+ }
+
+ if (e.KeyCode == Keys.N)
+ {
+ btnLayerRangeNormalLayers.PerformClick();
+ e.Handled = true;
+ return;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Events
+ private void ItemClicked(object sender, EventArgs e)
+ {
+ if (ReferenceEquals(sender, btnLayerRangeAllLayers))
+ {
+ nmLayerRangeStart.Value = 0;
+ nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount-1;
+ return;
+ }
+
+ if (ReferenceEquals(sender, btnLayerRangeCurrentLayer))
+ {
+ nmLayerRangeStart.Value = Program.FrmMain.ActualLayer;
+ nmLayerRangeEnd.Value = Program.FrmMain.ActualLayer;
+ return;
+ }
+
+ if (ReferenceEquals(sender, btnLayerRangeBottomLayers))
+ {
+ nmLayerRangeStart.Value = 0;
+ nmLayerRangeEnd.Value = Program.SlicerFile.InitialLayerCount-1;
+ return;
+ }
+
+ if (ReferenceEquals(sender, btnLayerRangeNormalLayers))
+ {
+ nmLayerRangeStart.Value = Program.SlicerFile.InitialLayerCount - 1;
+ nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount - 1;
+ return;
+ }
+
+ if (ReferenceEquals(sender, btnPresetFreeUse))
+ {
+ nmThreshold.Enabled =
+ nmMaximum.Enabled =
+ cbThresholdType.Enabled = true;
+ return;
+ }
+
+ if (ReferenceEquals(sender, btnPresetStripAntiAliasing))
+ {
+ ItemClicked(btnPresetFreeUse, e);
+ nmMaximum.Enabled = cbThresholdType.Enabled = false;
+
+ nmThreshold.Value = 127;
+ nmMaximum.Value = 255;
+ cbThresholdType.SelectedItem = ThresholdType.Binary;
+ nmThreshold.Focus();
+ return;
+ }
+
+ if (ReferenceEquals(sender, btnPresetSetPixelsBrightness))
+ {
+ ItemClicked(btnPresetFreeUse, e);
+ nmThreshold.Enabled = cbThresholdType.Enabled = false;
+
+ nmThreshold.Value = 254;
+ nmMaximum.Value = 254;
+ cbThresholdType.SelectedItem = ThresholdType.Binary;
+ nmMaximum.Focus();
+ return;
+ }
+
+
+ if (ReferenceEquals(sender, btnMutate))
+ {
+ if (!btnMutate.Enabled) return;
+ if (LayerRangeStart > LayerRangeEnd)
+ {
+ MessageBox.Show("Layer range start can't be higher than layer end.\nPlease fix and try again.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ nmLayerRangeStart.Select();
+ return;
+ }
+
+ if (MessageBox.Show($"Are you sure you want to {Mutation.Mutate}?", Text, MessageBoxButtons.YesNo,
+ MessageBoxIcon.Question) == DialogResult.Yes)
+ {
+ DialogResult = DialogResult.OK;
+ Close();
+ }
+
+ return;
+ }
+
+ if (ReferenceEquals(sender, btnCancel))
+ {
+ DialogResult = DialogResult.Cancel;
+ return;
+ }
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/UVtools.GUI/Forms/FrmMutationThreshold.resx b/UVtools.GUI/Forms/FrmMutationThreshold.resx
new file mode 100644
index 0000000..ceac7ae
--- /dev/null
+++ b/UVtools.GUI/Forms/FrmMutationThreshold.resx
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>148, 17</value>
+ </metadata>
+ <data name="lbLayerRange.ToolTip" xml:space="preserve">
+ <value>Selects the layers range within start layer and end layer where mutator will operate.
+Select same layer start as end to operate only within that layer.
+Note: "Layer Start" start can't be higher than "Layer End".</value>
+ </data>
+ <metadata name="cmLayerRange.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>17, 17</value>
+ </metadata>
+</root> \ No newline at end of file
diff --git a/UVtools.GUI/FrmMain.Designer.cs b/UVtools.GUI/FrmMain.Designer.cs
index 1c56218..0acc507 100644
--- a/UVtools.GUI/FrmMain.Designer.cs
+++ b/UVtools.GUI/FrmMain.Designer.cs
@@ -870,8 +870,7 @@
this.tsLayerImagePixelEdit.Name = "tsLayerImagePixelEdit";
this.tsLayerImagePixelEdit.Size = new System.Drawing.Size(75, 22);
this.tsLayerImagePixelEdit.Text = "Pixel &Edit";
- this.tsLayerImagePixelEdit.ToolTipText = "Edit layer image pixels (Righ click to add pixel and SHIFT + Right click to remov" +
- "e pixel)\r\nRed pixels are removed pixels\r\nGreen pixels are added pixels";
+ this.tsLayerImagePixelEdit.ToolTipText = "Edit layer image: Draw pixels, add supports and/or drain holes";
this.tsLayerImagePixelEdit.Click += new System.EventHandler(this.EventClick);
//
// toolStripSeparator18
@@ -1151,7 +1150,7 @@
//
this.tsPropertiesExportFile.Image = global::UVtools.GUI.Properties.Resources.file_image_16x16;
this.tsPropertiesExportFile.Name = "tsPropertiesExportFile";
- this.tsPropertiesExportFile.Size = new System.Drawing.Size(180, 22);
+ this.tsPropertiesExportFile.Size = new System.Drawing.Size(141, 22);
this.tsPropertiesExportFile.Text = "To &File";
this.tsPropertiesExportFile.Click += new System.EventHandler(this.EventClick);
//
@@ -1159,7 +1158,7 @@
//
this.tsPropertiesExportClipboard.Image = global::UVtools.GUI.Properties.Resources.clipboard_16x16;
this.tsPropertiesExportClipboard.Name = "tsPropertiesExportClipboard";
- this.tsPropertiesExportClipboard.Size = new System.Drawing.Size(180, 22);
+ this.tsPropertiesExportClipboard.Size = new System.Drawing.Size(141, 22);
this.tsPropertiesExportClipboard.Text = "To &Clipboard";
this.tsPropertiesExportClipboard.Click += new System.EventHandler(this.EventClick);
//
diff --git a/UVtools.GUI/FrmMain.cs b/UVtools.GUI/FrmMain.cs
index 27ddb1e..baaff52 100644
--- a/UVtools.GUI/FrmMain.cs
+++ b/UVtools.GUI/FrmMain.cs
@@ -102,19 +102,29 @@ namespace UVtools.GUI
"The Hit-or-Miss transformation is useful to find patterns in binary images. In particular, it finds those pixels whose neighbourhood matches the shape of a first structuring element B1 while not matching the shape of a second structuring element B2 at the same time.",
null
)},*/
- {LayerManager.Mutate.PyrDownUp, new Mutation(LayerManager.Mutate.PyrDownUp, null,
- "Performs downsampling step of Gaussian pyramid decomposition.\n" +
- "First it convolves image with the specified filter and then downsamples the image by rejecting even rows and columns.\n" +
- "After performs up-sampling step of Gaussian pyramid decomposition\n"
+ {LayerManager.Mutate.ThresholdPixels, new Mutation(LayerManager.Mutate.ThresholdPixels, "Threshold Pixels",
+ "Manipulates pixels values giving a threshold, maximum and a operation type.\n" +
+ "If a pixel brightness is less or equal to the threshold value, set this pixel to 0, otherwise set to defined maximum value.\n" +
+ "More info: https://docs.opencv.org/master/d7/d4d/tutorial_py_thresholding.html"
+ )},
+ {LayerManager.Mutate.PyrDownUp, new Mutation(LayerManager.Mutate.PyrDownUp, "Big Blur",
+ "Performs down/up-sampling step of Gaussian pyramid decomposition.\n" +
+ "First down-samples the image by rejecting even rows and columns, after performs up-sampling step of Gaussian pyramid decomposition.\n" +
+ "This operation will add a big blur to edges, creating a over-exaggerated anti-aliasing and as result can make edges smoother\n" +
+ "Note: Printer must support AntiAliasing on firmware to able to use this function."
)},
{LayerManager.Mutate.SmoothMedian, new Mutation(LayerManager.Mutate.SmoothMedian, "Smooth Median",
- "Each pixel becomes the median of its surrounding pixels. Also a good way to remove noise.\n" +
- "Note: Iterations must be a odd number."
+ "Each pixel becomes the median of its surrounding pixels.\n" +
+ "A good way to remove noise and can be used to reconstruct or intensify the antialiasing level.\n" +
+ "Note 1: Printer must support AntiAliasing on firmware to able to use this function.\n" +
+ "Note 2: Iterations must be a odd number."
)},
{LayerManager.Mutate.SmoothGaussian, new Mutation(LayerManager.Mutate.SmoothGaussian, "Smooth Gaussian",
"Each pixel is a sum of fractions of each pixel in its neighborhood\n" +
+ "A good way to remove noise and can be used to reconstruct or intensify the antialiasing level.\n" +
"Very fast, but does not preserve sharp edges well.\n" +
- "Note: Iterations must be a odd number."
+ "Note 1: Printer must support AntiAliasing on firmware to able to use this function.\n" +
+ "Note 2: Iterations must be a odd number."
)},
};
@@ -161,7 +171,6 @@ namespace UVtools.GUI
Settings.Default.UpdateSettings = false;
Settings.Default.Save();
}
-
Clear();
tsLayerImageLayerDifference.Checked = Settings.Default.LayerDifferenceDefault;
@@ -3075,6 +3084,8 @@ namespace UVtools.GUI
uint iterationsEnd = 0;
bool fade = false;
+ ThresholdType thresholdType = ThresholdType.Binary;
+
OperationMove operationMove = null;
double x = 0;
@@ -3137,6 +3148,17 @@ namespace UVtools.GUI
oddPattern = inputBox.OddPattern;
}
break;
+ case LayerManager.Mutate.ThresholdPixels:
+ using (FrmMutationThreshold inputBox = new FrmMutationThreshold(Mutations[mutator]))
+ {
+ if (inputBox.ShowDialog() != DialogResult.OK) return;
+ layerStart = inputBox.LayerRangeStart;
+ layerEnd = inputBox.LayerRangeEnd;
+ iterationsStart = inputBox.Threshold;
+ iterationsEnd = inputBox.Maximum;
+ thresholdType = inputBox.ThresholdTypeValue;
+ }
+ break;
default:
using (FrmMutation inputBox = new FrmMutation(Mutations[mutator]))
{
@@ -3225,6 +3247,9 @@ namespace UVtools.GUI
CvInvoke.MorphologyEx(image, image, MorphOp.HitMiss, Program.KernelFindIsolated,
new Point(-1, -1), (int) iterations, BorderType.Default, new MCvScalar());
break;*/
+ case LayerManager.Mutate.ThresholdPixels:
+ SlicerFile.LayerManager.MutateThresholdPixels(layerStart, layerEnd, (byte) iterationsStart, (byte) iterationsEnd, thresholdType, progress);
+ break;
case LayerManager.Mutate.PyrDownUp:
SlicerFile.LayerManager.MutatePyrDownUp(layerStart, layerEnd, BorderType.Default, progress);
break;
diff --git a/UVtools.GUI/FrmMain.resx b/UVtools.GUI/FrmMain.resx
index 97a17db..502c174 100644
--- a/UVtools.GUI/FrmMain.resx
+++ b/UVtools.GUI/FrmMain.resx
@@ -151,81 +151,80 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
- ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAo
- EQAAAk1TRnQBSQFMAgEBBQEAATgBBgE4AQYBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
- AwABIAMAAQEBAAEgBgABIC4AAxgBIgMwAUsDMAFMAzIBUOgAAyIBMQNWAbkDXQHiAQABAQEAAf8BAAEB
- AQAB/wEqAS0BKAH+A1MBrANNAZUDAAEB2AADIQEwA1kB7AErAS4BKQH6A1EB9wNSAfQDUwHxA0gB9gNB
- AfkBAAEBAQAB/wNPAZsDAAEB0AADHAEoA1kB6wEqAS0BKAH+A1YBtgNMAZIDSAGFA0gBhQNGAYADSAGF
- ASoBLQEoAf4BAAEBAQAB/wNOAZTQAAMmATgBKgEtASgB/gNMAZMDSwGQA00BlgNKAYsDRQF/A0MBeAND
- AXgDRwGCAz4B+ANTAbDQAANcAdQBAAEBAQAB/wNRAaADTgGYA1ABnwM6AWEDOAFdA0IBdANGAYADSAGE
- A0wBkwNYAeMDMAFMyAADNgFZA0ABcANZAdcDRwGCA0wBkwNJAYkDAQECBAADMAFLA0QBeQNIAYcDSwGQ
- A1cB6AMwAUzIAAMtAUYDOAFeA0oBjQMSARgDUAGjEAADKQE+A0sBkANNAZUDWQHsAzABTMgAAxQBHAMw
- AU0DTwGcA1EBogNTAbAQAAMrAUMDTwGbA1ABngNWAbsDFQEdyAADRAF5Az8BbgMqAUADHgErAyoBQANV
- AbEDBAEFBAADOQFgA0wBkgNOAZQDVgG2A1YBuMgAAz8BbQMuAUgDGgEkAyUBNwMhATABKwEsASsBQwMs
- AUQDSAGIA0gBhQNIAYcDSQGJA1ABmgNYAekDJwE6yAADBgEIAwoBDQNTAbADKgFAA0IBdQMUARwDNQFY
- A0QBfANOAZQDRAF8A0gBiANOAfADJwE7yAADBwEJA1UBtAMJAQwEAANBAXMDKgFBA0IBdgM8AWcDUQGn
- A1oBygNbAdYDJAE2Ax8BLdAAAwEBAgNTAawDDgETAzsBZQQAAzABTQMHAQkDBAEF5AADPwFuAwYBCAMx
- AU8DAwEEA1MBsOwAAzEBTwMBAQL/ADUAA1ABowNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGp
- A1IBqQNSAakDUgGpA1IBqQNQAaNcAAMVAR0BQgJZAfUBUQJtAfcDQwF3A1sByAJCAVkB9QJYAV8B4wNK
- AYwDCgENBAADVQG0A1kBxwMvAUkDAAEBAxsBJgMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEn
- AxwBJwMcAScDAgEDBAADUgGpMAADUgGpEAADJwE6AzABTAMwAUwDMAFMAzABTAMwAUwDMAFMAzABTAMw
- AUwDJwE6FAADBQEHA0wBkgFWAlgBwQMVAR0DPQFpAQAByAHzAf8BAAGQAeYB/wIAAdwB/wIAAd0B/wIf
- AeMB/wIAAd4B/wIAAd0B/wJYAVsBywMGAQgDAAH/AwAB/wNDAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMgFRBAADUgGpBAADUAGdA1MBqgNTAaoDUwGqA1MBqgNT
- AaoDUwGqA1ABnQwAA1IBqRAAA04B+wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A04B+xQA
- ATACMQFNAQAByQHzAf8BAAHJAfQB/wFZAmAB6wFbAl4B2QEAAcAB8QH/AgAB3wH/AgAB4AH/AgAB4AH/
- AiYB6QH/AgAB4gH/AgAB4AH/AgAB4AH/A0ABcQNRAaIDVgG2AyoBQAQAAxABFQMRARcDEQEXAxEBFwMR
- ARcDEQEXAxEBFwMRARcDEQEXAxEBFwMQARYIAANSAakEAANQAZ0DUwGqA1MBqgMfASwcAANSAakTAAH/
- AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADBwEKAVkCZwHyAQABygH0Af8BAAHK
- AfQB/wEAAcoB9AH/AQABoQHuAf8CAAHjAf8CAAHjAf8CAAHjAf8CqQHvAf8CAAHjAf8CAAHjAf8CAAHj
- Af8CVgFYAbkDCgEOAxEBFwMAAQE4AANSAakwAANSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/
- AwAB/wMAAf8DAAH/DAADFQEdAz0BaQM6AWIBXAJgAdQBAAHLAfUB/wEAAcsB9QH/AQABywH1Af8BAAGg
- AfAB/wIAAeYB/wIAAeYB/wIAAeYB/wLCAfYB/wILAegB/wIAAeYB/wIAAeYB/wJXAVkBvwNSAfQDAAH/
- Az4BbAMOARMDQgF2A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0IBdgMUARsEAANS
- AakDIgEyA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQMiATIDUgGpEwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wwAAUsCTAGQAQABywH2Af8BAAHLAfYB/wEA
- AcsB9gH/AQABywH2Af8BKQJNAfoDQwF4AyIBMgJLAV8B+wIAAekB/wIAAekB/wLNAfgB/wIaAe0B/wIA
- AekB/wIAAekB/wNQAZ4DAAH+AwAB/wNDAXcDHgErA1cBxQNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZ
- AccDWQHHA1kBxwNYAcYDJgE5BAADUgGpAzQBVQM0AVUgAAM0AVUDNAFVA1IBqRMAAf8DAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8MAANRAaABAAHMAfcB/wEAAcwB9wH/AQABzAH3Af8BAAHM
- AfcB/wNDAXcIAANKAY0CAAHsAf8CAAHsAf8CFQHvAf8CAAHsAf8CAAHsAf8BAAEGAe0B/wFSAlMBqAMz
- AVMDPAFnAxQBHDgAA1IBqQM0AVUDNAFVA0YBgANSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNFAX8DNAFV
- AzQBVQNSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DwABAQE/AkABbwE+
- AlwB+AEAAc0B9wH/AQABzQH3Af8DEgEYCAADAQECA0YBfgJSAV0B8AIAAe4B/wIAAe4B/wJAAagB/QFF
- AkYBfgMDAQQDMwFTAzwBZwMUARw4AANSAakDNAFVAzQBVQM/AW4DMgFQEAADJwE7A0QBfAM0AVUDNAFV
- A1IBqRMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8PAAEBAT8CQAFvAT4CXAH4
- AQABzgH4Af8BAAHOAfgB/wMSARgQAAMXASABAAG8AfcB/wEAAcQB9wH/AUACqAH9AUUCRgF+AwMBBAMA
- Af4DAAH/A0MBdwMfASwDVwHFA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1gBxgMm
- ATkEAANSAakDNAFVAzQBVQMFAQcDVQG1AxEBFwNSAakDKQE+BAADUAGfAxEBFwM0AVUDNAFVA1IBqRMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8MAANRAaABAAHOAfgB/wEAAc8B+QH/
- AQABzwH5Af8BAAHPAfkB/wNDAXcQAANEAXoBAAHPAfkB/wEAAc8B+QH/AQABzwH5Af8BAAHOAfgB/wFS
- AlMBqANSAfQDAAH/Az4BbAMOARMDQgF1A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3
- A0MBdwMUARsEAANSAakDNAFVAzQBVQQAAzwBaANWAb4DIwE0A1UBtQMSARkDUQGgBAADNAFVAzQBVQNS
- AakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfDAABSwJMAZABAAHQAfoB/wEA
- AdAB+gH/AQAB0AH6Af8BAAHQAfoB/wEpAk0B+gNDAXgDEgEZAxMBGgNEAXoBKAJfAfsBAAHQAfoB/wEA
- AdAB+gH/AQAB0AH6Af8BAAHQAfoB/wNKAYwDCgEOAxEBFwMAAQE4AANSAakDNAFVAzQBVQMAAQEDLQFG
- AwoBDgQAAzkBXwNcAc4DKAE8BAADNAFVAzQBVQNSAakTAAH/A4IB/wMAAf8DAAH/AwAB/wMAAf8DAAH/
- AwAB/wNcAd8DFwEgDAADFQEdAz0BaQM6AWIBXAJgAdQBAAHRAfoB/wEAAdEB+gH/AQAB0AH6Af8BAAHL
- AfMB/wEAAcsB8wH/AQAB0AH6Af8BAAHRAfoB/wEAAdEB+gH/AV0CYQHiAzoBYgM9AWkDFAEcA1EBogNW
- AbYDKgFABAADEAEVAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxABFggAA1IBqQM0
- AVUDNAFVAzMBUwNSAaYDSgGMBwABAQNHAYMIAAM0AVUDNAFVA1IBqRMAAf8DmQH/A4UB/wMAAf8DAAH/
- AwAB/wMAAf8DXAHfAxcBIBgAAwcBCgFZAmcB8gEAAdIB+wH/AQAB0gH7Af8BAAHSAfsB/wEAAdIB+wH/
- AQAB0gH7Af8BAAHSAfsB/wEAAdIB+wH/AQAB0gH7Af8BKwJfAfsDEQEXCwAB/wMAAf8DQwF3AykBPgMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AzIBUQQAA1IBqQM0AVUDNAFV
- AxEBFwNQAZ4DJAE2FAADNAFVAzQBVQNSAakQAANQAfsDAAH/AwAB/wMAAf8DAAH/AwAB/wNcAd8DFwEg
- HAABMAIxAU0BAAHSAfwB/wEAAdIB/AH/AVkCYAHrAVsCXgHZAQAB0gH8Af8BAAHSAfwB/wFbAmEB4QFd
- AmEB4gEAAdIB/AH/AQAB0gH8Af8DOAFeCAADVQG0A1kBxwMvAUkDAAEBAxsBJgMcAScDHAEnAxwBJwMc
- AScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDAgEDBAADUgGpAyIBMgNSAakDUgGpA1IBqQNSAakDUgGp
- A1IBqQNSAakDUgGpA1IBqQNSAakDIgEyA1IBqRAAAyABLgMpAT8DKQE/AykBPwMpAT8DKQE/AxEBFyAA
- AwUBBwNMAZIBVgJYAcEDFQEdAz0BaQEAAdMB/AH/AQAB0wH8Af8BRQJGAX8DEAEVA1YBswFLAkwBjwME
- AQZMAANQAaMDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUAGj
- XAADFQEdAUICWQH1AVECbQH3AyABLxgAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYA
- A/8BAAH+AR8GAAH4AQMGAAHwAQEGAAHgAQEGAAHgAQEGAAHgBwABwAFABgABwQHgBgABwQHgBgABwAFB
- BgABgAEBBgABgAEDBgABEAEHBgABhAF/BgABwQH/BgABzwH/BgAC/wGAAQEC/wH8AQECAAG/Af0B4AEH
- AcADAAGgAR0B4AEHAcABAAEQAQEBoQH9AeABBwHAAQABHwH/Ab8B/QHgAQcEAAGAAQEB4AEHBAABjwHx
- AeABBwEDAQABHwH/AYABAQHgAQcBAwEAAR8B/wGDAcEB4AEHAQMBwAIAAYABQQHgAQcBAwHAAgABiAER
- AeABBwIAAR8B/wGBAREB4AEHAgABEAEBAYEBMQHgAQ8BwAEDAgABgQHxAeABHwHAAQMCAAGAAQEB4AE/
- AcABAwL/AYABAQL/AfwBPws=
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAU
+ EQAAAk1TRnQBSQFMAgEBBQEAAUABBgFAAQYBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ AwABIAMAAQEBAAEgBgABIC4AAxgBIgMwAUsDMAFMAzIBUOgAAyIBMQNWAbkDXQHiAwAB/wMAAf8BKgEt
+ ASgB/gNTAawDTQGVAwABAdgAAyEBMANZAewBKwEuASkB+gNRAfcDUgH0A1MB8QNIAfYDQQH5AwAB/wNP
+ AZsDAAEB0AADHAEoA1kB6wEqAS0BKAH+A1YBtgNMAZIDSAGFA0gBhQNGAYADSAGFASoBLQEoAf4DAAH/
+ A04BlNAAAyYBOAEqAS0BKAH+A0wBkwNLAZADTQGWA0oBiwNFAX8DQwF4A0MBeANHAYIDPgH4A1MBsNAA
+ A1wB1AMAAf8DUQGgA04BmANQAZ8DOgFhAzgBXQNCAXQDRgGAA0gBhANMAZMDWAHjAzABTMgAAzYBWQNA
+ AXADWQHXA0cBggNMAZMDSQGJAwEBAgQAAzABSwNEAXkDSAGHA0sBkANXAegDMAFMyAADLQFGAzgBXgNK
+ AY0DEgEYA1ABoxAAAykBPgNLAZADTQGVA1kB7AMwAUzIAAMUARwDMAFNA08BnANRAaIDUwGwEAADKwFD
+ A08BmwNQAZ4DVgG7AxUBHcgAA0QBeQM/AW4DKgFAAx4BKwMqAUADVQGxAwQBBQQAAzkBYANMAZIDTgGU
+ A1YBtgNWAbjIAAM/AW0DLgFIAxoBJAMlATcDIQEwASsBLAErAUMDLAFEA0gBiANIAYUDSAGHA0kBiQNQ
+ AZoDWAHpAycBOsgAAwYBCAMKAQ0DUwGwAyoBQANCAXUDFAEcAzUBWANEAXwDTgGUA0QBfANIAYgDTgHw
+ AycBO8gAAwcBCQNVAbQDCQEMBAADQQFzAyoBQQNCAXYDPAFnA1EBpwNaAcoDWwHWAyQBNgMfAS3QAAMB
+ AQIDUwGsAw4BEwM7AWUEAAMwAU0DBwEJAwQBBeQAAz8BbgMGAQgDMQFPAwMBBANTAbDsAAMxAU8DAQEC
+ /wA1AANQAaMDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUAGj
+ XAADFQEdAUICWQH1AVECbQH3A0MBdwNbAcgCQgFZAfUCWAFfAeMDSgGMAwoBDQQAA1UBtANZAccDLwFJ
+ AwABAQMbASYDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAwIBAwQAA1IBqTAA
+ A1IBqRAAAycBOgMwAUwDMAFMAzABTAMwAUwDMAFMAzABTAMwAUwDMAFMAycBOhQAAwUBBwNMAZIBVgJY
+ AcEDFQEdAz0BaQEAAcgB8wH/AQABkAHmAf8CAAHcAf8CAAHdAf8CHgHjAf8CAAHeAf8CAAHdAf8CWAFb
+ AcsDBgEIAwAB/wMAAf8DQwF3AykBPgMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AzIBUQQAA1IBqQQAA1ABnQNTAaoDUwGqA1MBqgNTAaoDUwGqA1MBqgNQAZ0MAANSAakQAANO
+ AfsDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wNOAfsUAAEwAjEBTQEAAckB8wH/AQAByQH0
+ Af8BWQJgAesBWwJeAdkBAAHAAfEB/wIAAd8B/wIAAeAB/wIAAeAB/wIlAekB/wIAAeIB/wIAAeAB/wIA
+ AeAB/wNAAXEDUQGiA1YBtgMqAUAEAAMQARUDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMR
+ ARcDEAEWCAADUgGpBAADUAGdA1MBqgNTAaoDHwEsHAADUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/
+ AwAB/wMAAf8DAAH/AwAB/xQAAwcBCgFZAmcB8gEAAcoB9AH/AQABygH0Af8BAAHKAfQB/wEAAaEB7gH/
+ AgAB4wH/AgAB4wH/AgAB4wH/AqkB7wH/AgAB4wH/AgAB4wH/AgAB4wH/AlYBWAG5AwoBDgMRARcDAAEB
+ OAADUgGpMAADUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wwAAxUBHQM9
+ AWkDOgFiAVwCYAHUAQABywH1Af8BAAHLAfUB/wEAAcsB9QH/AQABoAHwAf8CAAHmAf8CAAHmAf8CAAHm
+ Af8CwgH2Af8CCgHoAf8CAAHmAf8CAAHmAf8CVwFZAb8DUgH0AwAB/wM+AWwDDgETA0IBdgNDAXcDQwF3
+ A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNCAXYDFAEbBAADUgGpAyIBMgNSAakDUgGpA1IBqQNS
+ AakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDIgEyA1IBqRMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AwAB/wMAAf8MAAFLAkwBkAEAAcsB9gH/AQABywH2Af8BAAHLAfYB/wEAAcsB9gH/ASkCTQH6
+ A0MBeAMiATICSwFfAfsCAAHpAf8CAAHpAf8CzQH4Af8CGQHtAf8CAAHpAf8CAAHpAf8DUAGeAwAB/gMA
+ Af8DQwF3Ax4BKwNXAcUDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWAHGAyYBOQQA
+ A1IBqQM0AVUDNAFVIAADNAFVAzQBVQNSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/DAADUQGgAQABzAH3Af8BAAHMAfcB/wEAAcwB9wH/AQABzAH3Af8DQwF3CAADSgGNAgAB7AH/
+ AgAB7AH/AhQB7wH/AgAB7AH/AgAB7AH/AQABBQHtAf8BUgJTAagDMwFTAzwBZwMUARw4AANSAakDNAFV
+ AzQBVQNGAYADUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDRQF/AzQBVQM0AVUDUgGpEwAB/wMAAf8DAAH/
+ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/w8AAQEBPwJAAW8BPgJcAfgBAAHNAfcB/wEAAc0B9wH/
+ AxIBGAgAAwEBAgNGAX4CUgFdAfACAAHuAf8CAAHuAf8CQAGoAf0BRQJGAX4DAwEEAzMBUwM8AWcDFAEc
+ OAADUgGpAzQBVQM0AVUDPwFuAzIBUBAAAycBOwNEAXwDNAFVAzQBVQNSAakTAAH/AwAB/wMAAf8DAAH/
+ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DwABAQE/AkABbwE+AlwB+AEAAc4B+AH/AQABzgH4Af8DEgEY
+ EAADFwEgAQABvAH3Af8BAAHEAfcB/wFAAqgB/QFFAkYBfgMDAQQDAAH+AwAB/wNDAXcDHwEsA1cBxQNZ
+ AccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNYAcYDJgE5BAADUgGpAzQBVQM0AVUDBQEH
+ A1UBtQMRARcDUgGpAykBPgQAA1ABnwMRARcDNAFVAzQBVQNSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AwAB/wMAAf8DAAH/DAADUQGgAQABzgH4Af8BAAHPAfkB/wEAAc8B+QH/AQABzwH5Af8DQwF3
+ EAADRAF6AQABzwH5Af8BAAHPAfkB/wEAAc8B+QH/AQABzgH4Af8BUgJTAagDUgH0AwAB/wM+AWwDDgET
+ A0IBdQNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDFAEbBAADUgGpAzQBVQM0
+ AVUEAAM8AWgDVgG+AyMBNANVAbUDEgEZA1EBoAQAAzQBVQM0AVUDUgGpEwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AwAB/wMAAf8DAAH/A1wB3wwAAUsCTAGQAQAB0AH6Af8BAAHQAfoB/wEAAdAB+gH/AQAB0AH6
+ Af8BKQJNAfoDQwF4AxIBGQMTARoDRAF6ASgCXwH7AQAB0AH6Af8BAAHQAfoB/wEAAdAB+gH/AQAB0AH6
+ Af8DSgGMAwoBDgMRARcDAAEBOAADUgGpAzQBVQM0AVUDAAEBAy0BRgMKAQ4EAAM5AV8DXAHOAygBPAQA
+ AzQBVQM0AVUDUgGpEwAB/wOCAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfAxcBIAwAAxUBHQM9
+ AWkDOgFiAVwCYAHUAQAB0QH6Af8BAAHRAfoB/wEAAdAB+gH/AQABywHzAf8BAAHLAfMB/wEAAdAB+gH/
+ AQAB0QH6Af8BAAHRAfoB/wFdAmEB4gM6AWIDPQFpAxQBHANRAaIDVgG2AyoBQAQAAxABFQMRARcDEQEX
+ AxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMQARYIAANSAakDNAFVAzQBVQMzAVMDUgGmA0oBjAcA
+ AQEDRwGDCAADNAFVAzQBVQNSAakTAAH/A5kB/wOFAf8DAAH/AwAB/wMAAf8DAAH/A1wB3wMXASAYAAMH
+ AQoBWQJnAfIBAAHSAfsB/wEAAdIB+wH/AQAB0gH7Af8BAAHSAfsB/wEAAdIB+wH/AQAB0gH7Af8BAAHS
+ AfsB/wEAAdIB+wH/ASsCXwH7AxEBFwsAAf8DAAH/A0MBdwMpAT4DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMyAVEEAANSAakDNAFVAzQBVQMRARcDUAGeAyQBNhQAAzQBVQM0
+ AVUDUgGpEAADUAH7AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfAxcBIBwAATACMQFNAQAB0gH8Af8BAAHS
+ AfwB/wFZAmAB6wFbAl4B2QEAAdIB/AH/AQAB0gH8Af8BWwJhAeEBXQJhAeIBAAHSAfwB/wEAAdIB/AH/
+ AzgBXggAA1UBtANZAccDLwFJAwABAQMbASYDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMc
+ AScDHAEnAwIBAwQAA1IBqQMiATIDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGp
+ AyIBMgNSAakQAAMgAS4DKQE/AykBPwMpAT8DKQE/AykBPwMRARcgAAMFAQcDTAGSAVYCWAHBAxUBHQM9
+ AWkBAAHTAfwB/wEAAdMB/AH/AUUCRgF/AxABFQNWAbMBSwJMAY8DBAEGTAADUAGjA1IBqQNSAakDUgGp
+ A1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1ABo1wAAxUBHQFCAlkB9QFRAm0B9wMg
+ AS8YAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/AQAB/gEfBgAB+AEDBgAB8AEB
+ BgAB4AEBBgAB4AEBBgAB4AcAAcABQAYAAcEB4AYAAcEB4AYAAcABQQYAAYABAQYAAYABAwYAARABBwYA
+ AYQBfwYAAcEB/wYAAc8B/wYAAv8BgAEBAv8B/AEBAgABvwH9AeABBwHAAwABoAEdAeABBwHAAQABEAEB
+ AaEB/QHgAQcBwAEAAR8B/wG/Af0B4AEHBAABgAEBAeABBwQAAY8B8QHgAQcBAwEAAR8B/wGAAQEB4AEH
+ AQMBAAEfAf8BgwHBAeABBwEDAcACAAGAAUEB4AEHAQMBwAIAAYgBEQHgAQcCAAEfAf8BgQERAeABBwIA
+ ARABAQGBATEB4AEPAcABAwIAAYEB8QHgAR8BwAEDAgABgAEBAeABPwHAAQMC/wGAAQEC/wH8AT8L
</value>
</data>
<metadata name="toolTipInformation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
diff --git a/UVtools.GUI/Properties/AssemblyInfo.cs b/UVtools.GUI/Properties/AssemblyInfo.cs
index 363d870..216a7c5 100644
--- a/UVtools.GUI/Properties/AssemblyInfo.cs
+++ b/UVtools.GUI/Properties/AssemblyInfo.cs
@@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.6.3.3")]
-[assembly: AssemblyFileVersion("0.6.3.3")]
+[assembly: AssemblyVersion("0.6.3.4")]
+[assembly: AssemblyFileVersion("0.6.3.4")]
diff --git a/UVtools.GUI/UVtools.GUI.csproj b/UVtools.GUI/UVtools.GUI.csproj
index 0c92564..a45810c 100644
--- a/UVtools.GUI/UVtools.GUI.csproj
+++ b/UVtools.GUI/UVtools.GUI.csproj
@@ -159,6 +159,12 @@
<Compile Include="Forms\FrmInstallPEProfiles.Designer.cs">
<DependentUpon>FrmInstallPEProfiles.cs</DependentUpon>
</Compile>
+ <Compile Include="Forms\FrmMutationThreshold.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Forms\FrmMutationThreshold.Designer.cs">
+ <DependentUpon>FrmMutationThreshold.cs</DependentUpon>
+ </Compile>
<Compile Include="Forms\FrmMutationPixelDimming.cs">
<SubType>Form</SubType>
</Compile>
@@ -259,6 +265,9 @@
<EmbeddedResource Include="Forms\FrmInstallPEProfiles.resx">
<DependentUpon>FrmInstallPEProfiles.cs</DependentUpon>
</EmbeddedResource>
+ <EmbeddedResource Include="Forms\FrmMutationThreshold.resx">
+ <DependentUpon>FrmMutationThreshold.cs</DependentUpon>
+ </EmbeddedResource>
<EmbeddedResource Include="Forms\FrmMutationPixelDimming.resx">
<DependentUpon>FrmMutationPixelDimming.cs</DependentUpon>
</EmbeddedResource>