diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2020-08-08 05:10:16 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2020-08-08 05:10:16 +0300 |
commit | 292db4090fad93a5cecbeb63de1e56dd2b95b164 (patch) | |
tree | ecb4ca44430760caaf877d38aa302fedf0285fb1 /UVtools.GUI | |
parent | f53dc038818c487120de1915b563b1f1f6ec0818 (diff) |
v0.6.5.0v0.6.5.0
* (Add) Mutators: Custom kernels, auto kernels and anchor where applicable
* (Add) Mutator - Blur: Box Blur
* (Add) Mutator - Blur: Filter2D
* (Improvement) Mutator: Group all blurs into one window
* (Fix) Mutators: Sample images was gone
* (Fix) Mutator - Solidify: Remove the disabled input box
* (Fix) Mutator - Pixel Dimming: Disable word wrap on pattern text box
Diffstat (limited to 'UVtools.GUI')
-rw-r--r-- | UVtools.GUI/Controls/CtrlKernel.Designer.cs | 307 | ||||
-rw-r--r-- | UVtools.GUI/Controls/CtrlKernel.cs | 133 | ||||
-rw-r--r-- | UVtools.GUI/Controls/CtrlKernel.resx | 120 | ||||
-rw-r--r-- | UVtools.GUI/Forms/FrmMutation.Designer.cs | 48 | ||||
-rw-r--r-- | UVtools.GUI/Forms/FrmMutation.cs | 36 | ||||
-rw-r--r-- | UVtools.GUI/Forms/FrmMutationBlur.Designer.cs | 367 | ||||
-rw-r--r-- | UVtools.GUI/Forms/FrmMutationBlur.cs | 248 | ||||
-rw-r--r-- | UVtools.GUI/Forms/FrmMutationBlur.resx | 136 | ||||
-rw-r--r-- | UVtools.GUI/Forms/FrmMutationPixelDimming.Designer.cs | 146 | ||||
-rw-r--r-- | UVtools.GUI/Forms/FrmToolEmpty.cs | 15 | ||||
-rw-r--r-- | UVtools.GUI/FrmMain.cs | 93 | ||||
-rw-r--r-- | UVtools.GUI/Mutation.cs | 1 | ||||
-rw-r--r-- | UVtools.GUI/Properties/AssemblyInfo.cs | 4 | ||||
-rw-r--r-- | UVtools.GUI/UVtools.GUI.csproj | 18 |
14 files changed, 1535 insertions, 137 deletions
diff --git a/UVtools.GUI/Controls/CtrlKernel.Designer.cs b/UVtools.GUI/Controls/CtrlKernel.Designer.cs new file mode 100644 index 0000000..eb7e35b --- /dev/null +++ b/UVtools.GUI/Controls/CtrlKernel.Designer.cs @@ -0,0 +1,307 @@ +namespace UVtools.GUI.Controls +{ + partial class CtrlKernel + { + /// <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 Component 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.tbKernel = new System.Windows.Forms.TextBox(); + this.cbShape = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.nmSizeX = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.nmSizeY = new System.Windows.Forms.NumericUpDown(); + this.btnGen = new System.Windows.Forms.Button(); + this.btnReset = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label4 = new System.Windows.Forms.Label(); + this.nmAnchorY = new System.Windows.Forms.NumericUpDown(); + this.nmAnchorX = new System.Windows.Forms.NumericUpDown(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.nmSizeX)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmSizeY)).BeginInit(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nmAnchorY)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmAnchorX)).BeginInit(); + this.SuspendLayout(); + // + // tbKernel + // + this.tbKernel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbKernel.Location = new System.Drawing.Point(6, 25); + this.tbKernel.Multiline = true; + this.tbKernel.Name = "tbKernel"; + this.tbKernel.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.tbKernel.Size = new System.Drawing.Size(210, 178); + this.tbKernel.TabIndex = 1; + this.tbKernel.WordWrap = false; + // + // cbShape + // + this.cbShape.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.cbShape.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbShape.FormattingEnabled = true; + this.cbShape.Location = new System.Drawing.Point(308, 24); + this.cbShape.Name = "cbShape"; + this.cbShape.Size = new System.Drawing.Size(133, 28); + this.cbShape.TabIndex = 2; + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(248, 28); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(60, 20); + this.label1.TabIndex = 0; + this.label1.Text = "Shape:"; + // + // nmSizeX + // + this.nmSizeX.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.nmSizeX.Location = new System.Drawing.Point(308, 58); + this.nmSizeX.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.nmSizeX.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.nmSizeX.Name = "nmSizeX"; + this.nmSizeX.Size = new System.Drawing.Size(50, 26); + this.nmSizeX.TabIndex = 3; + this.nmSizeX.Value = new decimal(new int[] { + 3, + 0, + 0, + 0}); + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(258, 61); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(44, 20); + this.label2.TabIndex = 4; + this.label2.Text = "Size:"; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(366, 61); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(16, 20); + this.label3.TabIndex = 5; + this.label3.Text = "x"; + // + // nmSizeY + // + this.nmSizeY.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.nmSizeY.Location = new System.Drawing.Point(392, 58); + this.nmSizeY.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.nmSizeY.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.nmSizeY.Name = "nmSizeY"; + this.nmSizeY.Size = new System.Drawing.Size(50, 26); + this.nmSizeY.TabIndex = 6; + this.nmSizeY.Value = new decimal(new int[] { + 3, + 0, + 0, + 0}); + // + // btnGen + // + this.btnGen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnGen.Location = new System.Drawing.Point(226, 147); + this.btnGen.Name = "btnGen"; + this.btnGen.Size = new System.Drawing.Size(131, 56); + this.btnGen.TabIndex = 7; + this.btnGen.Text = "Generate"; + this.btnGen.UseVisualStyleBackColor = true; + this.btnGen.Click += new System.EventHandler(this.EventClick); + // + // btnReset + // + this.btnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnReset.Location = new System.Drawing.Point(367, 147); + this.btnReset.Name = "btnReset"; + this.btnReset.Size = new System.Drawing.Size(74, 56); + this.btnReset.TabIndex = 8; + this.btnReset.Text = "Reset"; + this.btnReset.UseVisualStyleBackColor = true; + this.btnReset.Click += new System.EventHandler(this.EventClick); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.nmAnchorY); + this.groupBox1.Controls.Add(this.nmAnchorX); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.btnReset); + this.groupBox1.Controls.Add(this.btnGen); + this.groupBox1.Controls.Add(this.tbKernel); + this.groupBox1.Controls.Add(this.nmSizeY); + this.groupBox1.Controls.Add(this.cbShape); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.nmSizeX); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(448, 215); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Kernel"; + // + // label4 + // + this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(223, 93); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(79, 20); + this.label4.TabIndex = 9; + this.label4.Text = "Anchor X:"; + // + // nmAnchorY + // + this.nmAnchorY.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.nmAnchorY.Location = new System.Drawing.Point(392, 90); + this.nmAnchorY.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.nmAnchorY.Minimum = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + this.nmAnchorY.Name = "nmAnchorY"; + this.nmAnchorY.Size = new System.Drawing.Size(50, 26); + this.nmAnchorY.TabIndex = 11; + this.nmAnchorY.Value = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + // + // nmAnchorX + // + this.nmAnchorX.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.nmAnchorX.Location = new System.Drawing.Point(308, 90); + this.nmAnchorX.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.nmAnchorX.Minimum = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + this.nmAnchorX.Name = "nmAnchorX"; + this.nmAnchorX.Size = new System.Drawing.Size(50, 26); + this.nmAnchorX.TabIndex = 10; + this.nmAnchorX.Value = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + // + // label5 + // + this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(363, 93); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(24, 20); + this.label5.TabIndex = 12; + this.label5.Text = "Y:"; + // + // label6 + // + this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(222, 123); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(218, 20); + this.label6.TabIndex = 13; + this.label6.Text = "Note: Anchor auto center = -1"; + // + // CtrlKernel + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.Controls.Add(this.groupBox1); + this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Name = "CtrlKernel"; + this.Size = new System.Drawing.Size(448, 215); + ((System.ComponentModel.ISupportInitialize)(this.nmSizeX)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmSizeY)).EndInit(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nmAnchorY)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmAnchorX)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.ComboBox cbShape; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown nmSizeX; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.NumericUpDown nmSizeY; + private System.Windows.Forms.Button btnGen; + private System.Windows.Forms.Button btnReset; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.NumericUpDown nmAnchorY; + private System.Windows.Forms.NumericUpDown nmAnchorX; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label6; + public System.Windows.Forms.TextBox tbKernel; + } +} diff --git a/UVtools.GUI/Controls/CtrlKernel.cs b/UVtools.GUI/Controls/CtrlKernel.cs new file mode 100644 index 0000000..7653f5b --- /dev/null +++ b/UVtools.GUI/Controls/CtrlKernel.cs @@ -0,0 +1,133 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using Emgu.CV; +using Emgu.CV.CvEnum; +using UVtools.Core.Extensions; + +namespace UVtools.GUI.Controls +{ + public partial class CtrlKernel : UserControl + { + public ElementShape AutoShape => (ElementShape)cbShape.SelectedItem; + public Size AutoKernelSize => new Size((int) nmSizeX.Value, (int) nmSizeY.Value); + public Point KernelAnchor => new Point((int) nmAnchorX.Value, (int) nmAnchorY.Value); + public CtrlKernel() + { + InitializeComponent(); + if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return; + + foreach (var element in (ElementShape[])Enum.GetValues( + typeof(ElementShape))) + { + if (element == ElementShape.Custom) continue; + cbShape.Items.Add(element); + } + + cbShape.SelectedItem = ElementShape.Rectangle; + Reset(); + } + + private void EventClick(object sender, EventArgs e) + { + if (ReferenceEquals(sender, btnGen)) + { + if (nmSizeX.Value <= nmAnchorX.Value || nmSizeY.Value <= nmAnchorY.Value) + { + MessageBox.Show("Anchor position X/Y can't be higher or equal than size X/Y\nPlease fix the values.", + "Invalid anchor position", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + using (var kernel = CvInvoke.GetStructuringElement(AutoShape, AutoKernelSize, KernelAnchor)) + { + string text = string.Empty; + for (int y = 0; y < kernel.Height; y++) + { + var span = kernel.GetPixelRowSpan<byte>(y); + var line = string.Empty; + for (int x = 0; x < span.Length; x++) + { + line += $" {span[x]}"; + } + + line = line.Remove(0, 1); + text += line; + if (y < kernel.Height - 1) + { + text += Environment.NewLine; + } + } + + tbKernel.Text = text; + } + return; + } + + if (ReferenceEquals(sender, btnReset)) + { + Reset(); + } + } + + public void Reset() + { + nmSizeX.Value = 3; + nmSizeY.Value = 3; + nmAnchorX.Value = -1; + nmAnchorY.Value = -1; + cbShape.SelectedItem = ElementShape.Rectangle; + btnGen.PerformClick(); + } + + public Matrix<byte> GetMatrix() + { + if (string.IsNullOrEmpty(tbKernel.Text)) + { + MessageBox.Show("Kernel can't be empty.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + return null; + } + Matrix<byte> matrix = null; + for (var row = 0; row < tbKernel.Lines.Length; row++) + { + var bytes = tbKernel.Lines[row].Trim().Split(' '); + if (row == 0) + { + matrix = new Matrix<byte>(tbKernel.Lines.Length, bytes.Length); + } + else + { + if (matrix.Cols != bytes.Length) + { + MessageBox.Show($"Row {row + 1} have invalid number of columns, the matrix must have equal columns count per line, per defined on line 1", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + matrix.Dispose(); + return null; + } + } + + for (int col = 0; col < bytes.Length; col++) + { + if (byte.TryParse(bytes[col], out var value)) + { + matrix[row, col] = value; + } + else + { + MessageBox.Show($"{bytes[col]} is a invalid number, use values from 0 to 255", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + matrix.Dispose(); + return null; + } + } + } + if (matrix.Cols <= nmAnchorX.Value || matrix.Rows <= nmAnchorY.Value) + { + MessageBox.Show("Anchor position X/Y can't be higher or equal than kernel columns/rows\nPlease fix the values.", + "Invalid anchor position", MessageBoxButtons.OK, MessageBoxIcon.Error); + matrix.Dispose(); + return null; + } + return matrix; + } + } +} diff --git a/UVtools.GUI/Controls/CtrlKernel.resx b/UVtools.GUI/Controls/CtrlKernel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UVtools.GUI/Controls/CtrlKernel.resx @@ -0,0 +1,120 @@ +<?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> +</root>
\ No newline at end of file diff --git a/UVtools.GUI/Forms/FrmMutation.Designer.cs b/UVtools.GUI/Forms/FrmMutation.Designer.cs index 8d32fc0..15f3f04 100644 --- a/UVtools.GUI/Forms/FrmMutation.Designer.cs +++ b/UVtools.GUI/Forms/FrmMutation.Designer.cs @@ -48,11 +48,12 @@ namespace UVtools.GUI.Forms this.nmIterationsEnd = new System.Windows.Forms.NumericUpDown(); this.cbIterationsFade = new System.Windows.Forms.CheckBox(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); - this.btnLayerRangeSelect = new UVtools.GUI.Controls.SplitButton(); this.btnCancel = new System.Windows.Forms.Button(); this.btnPreview = new System.Windows.Forms.Button(); this.pbInfo = new System.Windows.Forms.PictureBox(); this.btnMutate = new System.Windows.Forms.Button(); + this.ctrlKernel = new UVtools.GUI.Controls.CtrlKernel(); + this.btnLayerRangeSelect = new UVtools.GUI.Controls.SplitButton(); ((System.ComponentModel.ISupportInitialize)(this.numIterationsStart)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).BeginInit(); @@ -69,7 +70,7 @@ namespace UVtools.GUI.Forms 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(584, 128); + this.lbDescription.Size = new System.Drawing.Size(584, 323); this.lbDescription.TabIndex = 0; this.lbDescription.Text = "Description"; // @@ -245,23 +246,13 @@ namespace UVtools.GUI.Forms this.toolTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info; this.toolTip.ToolTipTitle = "Information"; // - // btnLayerRangeSelect - // - this.btnLayerRangeSelect.Location = new System.Drawing.Point(484, 147); - this.btnLayerRangeSelect.Menu = this.cmLayerRange; - this.btnLayerRangeSelect.Name = "btnLayerRangeSelect"; - this.btnLayerRangeSelect.Size = new System.Drawing.Size(114, 26); - this.btnLayerRangeSelect.TabIndex = 2; - this.btnLayerRangeSelect.Text = "Select"; - this.btnLayerRangeSelect.UseVisualStyleBackColor = true; - // // 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(447, 230); + this.btnCancel.Location = new System.Drawing.Point(447, 451); 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); @@ -277,7 +268,7 @@ namespace UVtools.GUI.Forms this.btnPreview.Enabled = false; this.btnPreview.Image = global::UVtools.GUI.Properties.Resources.eye_24x24; this.btnPreview.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnPreview.Location = new System.Drawing.Point(131, 230); + this.btnPreview.Location = new System.Drawing.Point(131, 451); this.btnPreview.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btnPreview.Name = "btnPreview"; this.btnPreview.Size = new System.Drawing.Size(150, 48); @@ -289,11 +280,10 @@ namespace UVtools.GUI.Forms // // pbInfo // - this.pbInfo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Right))); + this.pbInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.pbInfo.Location = new System.Drawing.Point(604, 14); this.pbInfo.Name = "pbInfo"; - this.pbInfo.Size = new System.Drawing.Size(311, 264); + this.pbInfo.Size = new System.Drawing.Size(311, 323); this.pbInfo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.pbInfo.TabIndex = 7; this.pbInfo.TabStop = false; @@ -304,7 +294,7 @@ namespace UVtools.GUI.Forms 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(289, 230); + this.btnMutate.Location = new System.Drawing.Point(289, 451); 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); @@ -314,12 +304,31 @@ namespace UVtools.GUI.Forms this.btnMutate.UseVisualStyleBackColor = true; this.btnMutate.Click += new System.EventHandler(this.ItemClicked); // + // ctrlKernel + // + this.ctrlKernel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ctrlKernel.Location = new System.Drawing.Point(12, 221); + this.ctrlKernel.Name = "ctrlKernel"; + this.ctrlKernel.Size = new System.Drawing.Size(585, 217); + this.ctrlKernel.TabIndex = 16; + // + // btnLayerRangeSelect + // + this.btnLayerRangeSelect.Location = new System.Drawing.Point(484, 147); + this.btnLayerRangeSelect.Menu = this.cmLayerRange; + this.btnLayerRangeSelect.Name = "btnLayerRangeSelect"; + this.btnLayerRangeSelect.Size = new System.Drawing.Size(114, 26); + this.btnLayerRangeSelect.TabIndex = 2; + this.btnLayerRangeSelect.Text = "Select"; + this.btnLayerRangeSelect.UseVisualStyleBackColor = true; + // // FrmMutation // 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(927, 292); + this.ClientSize = new System.Drawing.Size(927, 513); + this.Controls.Add(this.ctrlKernel); this.Controls.Add(this.cbIterationsFade); this.Controls.Add(this.nmIterationsEnd); this.Controls.Add(this.lbIterationsStop); @@ -380,5 +389,6 @@ namespace UVtools.GUI.Forms private System.Windows.Forms.NumericUpDown nmIterationsEnd; private System.Windows.Forms.CheckBox cbIterationsFade; private System.Windows.Forms.ToolTip toolTip; + public CtrlKernel ctrlKernel; } }
\ No newline at end of file diff --git a/UVtools.GUI/Forms/FrmMutation.cs b/UVtools.GUI/Forms/FrmMutation.cs index 24035e4..16b2a49 100644 --- a/UVtools.GUI/Forms/FrmMutation.cs +++ b/UVtools.GUI/Forms/FrmMutation.cs @@ -7,7 +7,9 @@ */ using System; +using System.Drawing; using System.Windows.Forms; +using Emgu.CV; using UVtools.Core; namespace UVtools.GUI.Forms @@ -47,6 +49,9 @@ namespace UVtools.GUI.Forms get => cbIterationsFade.Checked; set => cbIterationsFade.Checked = value; } + + public Matrix<byte> KernelMatrix { get; private set; } + public Point KernelAnchor => ctrlKernel.KernelAnchor; #endregion #region Constructors @@ -62,9 +67,7 @@ namespace UVtools.GUI.Forms Mutation = mutation; DialogResult = DialogResult.Cancel; - if (defaultIterations == 0 || - mutation.Mutate == LayerManager.Mutate.PyrDownUp || - mutation.Mutate == LayerManager.Mutate.Solidify) + if (defaultIterations == 0) { lbIterationsStart.Enabled = numIterationsStart.Enabled = @@ -79,15 +82,6 @@ namespace UVtools.GUI.Forms numIterationsStart.Select(); } - if (Mutation.Mutate == LayerManager.Mutate.SmoothGaussian || - Mutation.Mutate == LayerManager.Mutate.SmoothMedian) - { - lbIterationsStop.Enabled = - nmIterationsEnd.Enabled = - cbIterationsFade.Enabled = - false; - } - Text = $"Mutate: {mutation.MenuName}"; lbDescription.Text = Mutation.Description; @@ -112,6 +106,7 @@ namespace UVtools.GUI.Forms base.OnKeyUp(e); if (e.KeyCode == Keys.Enter) { + if (ctrlKernel.tbKernel.ContainsFocus) return; btnMutate.PerformClick(); e.Handled = true; return; @@ -192,20 +187,9 @@ namespace UVtools.GUI.Forms return; } - if (Mutation.Mutate == LayerManager.Mutate.SmoothGaussian || - Mutation.Mutate == LayerManager.Mutate.SmoothMedian) - { - if (IterationsFade) - { - MessageBox.Show("Smooth doesn't support fading.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - if (Iterations % 2 != 1) - { - MessageBox.Show("Iterations must be a odd number.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - } + KernelMatrix = ctrlKernel.GetMatrix(); + if (ReferenceEquals(KernelMatrix, null)) return; + var operationName = string.IsNullOrEmpty(Mutation.MenuName) ? Mutation.Mutate.ToString() : Mutation.MenuName; if (MessageBox.Show($"Are you sure you want to {operationName}?", Text, MessageBoxButtons.YesNo, diff --git a/UVtools.GUI/Forms/FrmMutationBlur.Designer.cs b/UVtools.GUI/Forms/FrmMutationBlur.Designer.cs new file mode 100644 index 0000000..9ccf143 --- /dev/null +++ b/UVtools.GUI/Forms/FrmMutationBlur.Designer.cs @@ -0,0 +1,367 @@ +using UVtools.GUI.Controls; + +namespace UVtools.GUI.Forms +{ + partial class FrmMutationBlur + { + /// <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(FrmMutationBlur)); + this.lbDescription = new System.Windows.Forms.Label(); + this.lbIterationsStart = new System.Windows.Forms.Label(); + this.nmSize = new System.Windows.Forms.NumericUpDown(); + 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.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnPreview = new System.Windows.Forms.Button(); + this.pbInfo = new System.Windows.Forms.PictureBox(); + this.btnMutate = new System.Windows.Forms.Button(); + this.cbAlgorithm = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.ctrlKernel = new UVtools.GUI.Controls.CtrlKernel(); + this.btnLayerRangeSelect = new UVtools.GUI.Controls.SplitButton(); + ((System.ComponentModel.ISupportInitialize)(this.nmSize)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).BeginInit(); + this.cmLayerRange.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbInfo)).BeginInit(); + this.SuspendLayout(); + // + // lbDescription + // + 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(584, 128); + this.lbDescription.TabIndex = 0; + this.lbDescription.Text = "Description"; + // + // lbIterationsStart + // + this.lbIterationsStart.AutoSize = true; + this.lbIterationsStart.Location = new System.Drawing.Point(66, 220); + this.lbIterationsStart.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.lbIterationsStart.Name = "lbIterationsStart"; + this.lbIterationsStart.Size = new System.Drawing.Size(44, 20); + this.lbIterationsStart.TabIndex = 3; + this.lbIterationsStart.Text = "Size:"; + this.toolTip.SetToolTip(this.lbIterationsStart, resources.GetString("lbIterationsStart.ToolTip")); + // + // nmSize + // + this.nmSize.Location = new System.Drawing.Point(118, 217); + this.nmSize.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.nmSize.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.nmSize.Name = "nmSize"; + this.nmSize.Size = new System.Drawing.Size(149, 26); + this.nmSize.TabIndex = 3; + this.nmSize.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // 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(149, 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(149, 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); + // + // 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"; + // + // 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(447, 476); + 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); + // + // btnPreview + // + this.btnPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnPreview.Enabled = false; + this.btnPreview.Image = global::UVtools.GUI.Properties.Resources.eye_24x24; + this.btnPreview.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnPreview.Location = new System.Drawing.Point(131, 476); + this.btnPreview.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(150, 48); + this.btnPreview.TabIndex = 4; + this.btnPreview.Text = "&Preview"; + this.btnPreview.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Visible = false; + // + // pbInfo + // + this.pbInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.pbInfo.Location = new System.Drawing.Point(604, 14); + this.pbInfo.Name = "pbInfo"; + this.pbInfo.Size = new System.Drawing.Size(311, 323); + this.pbInfo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pbInfo.TabIndex = 7; + this.pbInfo.TabStop = false; + this.pbInfo.Visible = false; + // + // 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(289, 476); + 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); + // + // cbAlgorithm + // + this.cbAlgorithm.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbAlgorithm.DropDownWidth = 600; + this.cbAlgorithm.FormattingEnabled = true; + this.cbAlgorithm.Location = new System.Drawing.Point(118, 181); + this.cbAlgorithm.Name = "cbAlgorithm"; + this.cbAlgorithm.Size = new System.Drawing.Size(479, 28); + this.cbAlgorithm.TabIndex = 17; + this.cbAlgorithm.SelectedIndexChanged += new System.EventHandler(this.EventSelectedIndexChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(30, 185); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(80, 20); + this.label1.TabIndex = 18; + this.label1.Text = "Algorithm:"; + // + // ctrlKernel + // + this.ctrlKernel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ctrlKernel.Location = new System.Drawing.Point(12, 251); + this.ctrlKernel.Name = "ctrlKernel"; + this.ctrlKernel.Size = new System.Drawing.Size(586, 217); + this.ctrlKernel.TabIndex = 16; + // + // btnLayerRangeSelect + // + this.btnLayerRangeSelect.Location = new System.Drawing.Point(470, 147); + this.btnLayerRangeSelect.Menu = this.cmLayerRange; + this.btnLayerRangeSelect.Name = "btnLayerRangeSelect"; + this.btnLayerRangeSelect.Size = new System.Drawing.Size(128, 26); + this.btnLayerRangeSelect.TabIndex = 2; + this.btnLayerRangeSelect.Text = "Select"; + this.btnLayerRangeSelect.UseVisualStyleBackColor = true; + // + // FrmMutationBlur + // + 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(927, 538); + this.Controls.Add(this.label1); + this.Controls.Add(this.cbAlgorithm); + this.Controls.Add(this.ctrlKernel); + 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.btnPreview); + this.Controls.Add(this.pbInfo); + this.Controls.Add(this.btnMutate); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.nmSize); + this.Controls.Add(this.lbIterationsStart); + 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 = "FrmMutationBlur"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Form1"; + this.TopMost = true; + ((System.ComponentModel.ISupportInitialize)(this.nmSize)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).EndInit(); + this.cmLayerRange.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pbInfo)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lbDescription; + private System.Windows.Forms.Label lbIterationsStart; + private System.Windows.Forms.NumericUpDown nmSize; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnMutate; + private System.Windows.Forms.PictureBox pbInfo; + private System.Windows.Forms.Button btnPreview; + 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; + public CtrlKernel ctrlKernel; + private System.Windows.Forms.ComboBox cbAlgorithm; + private System.Windows.Forms.Label label1; + } +}
\ No newline at end of file diff --git a/UVtools.GUI/Forms/FrmMutationBlur.cs b/UVtools.GUI/Forms/FrmMutationBlur.cs new file mode 100644 index 0000000..0f58441 --- /dev/null +++ b/UVtools.GUI/Forms/FrmMutationBlur.cs @@ -0,0 +1,248 @@ +/* + * 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.Drawing; +using System.Windows.Forms; +using Emgu.CV; +using UVtools.Core; + +namespace UVtools.GUI.Forms +{ + public partial class FrmMutationBlur : Form + { + public enum BlurAlgorithm + { + Blur, + Pyramid, + MedianBlur, + GaussianBlur, + Filter2D + } + public struct BlurAlgorithmDescription + { + public BlurAlgorithm BlurAlgorithm; + public string Description; + + public BlurAlgorithmDescription(BlurAlgorithm blurAlgorithm, string description) + { + BlurAlgorithm = blurAlgorithm; + Description = description; + } + + public override string ToString() + { + return Description; + } + } + #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 BlurAlgorithm BlurAlgorithmType => ((BlurAlgorithmDescription) cbAlgorithm.SelectedItem).BlurAlgorithm; + + public uint KSize + { + get => (uint) nmSize.Value; + set => nmSize.Value = value; + } + + public Matrix<byte> KernelMatrix { get; private set; } + public Point KernelAnchor => ctrlKernel.KernelAnchor; + #endregion + + #region Constructors + + public FrmMutationBlur() + { + InitializeComponent(); + nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount - 1; + cbAlgorithm.Items.AddRange(new object[] + { + new BlurAlgorithmDescription(BlurAlgorithm.Blur, "Blur: Normalized box filter"), + new BlurAlgorithmDescription(BlurAlgorithm.Pyramid, "Pyramid: Down/up-sampling step of Gaussian pyramid decomposition"), + new BlurAlgorithmDescription(BlurAlgorithm.MedianBlur, "Median Blur: Each pixel becomes the median of its surrounding pixels"), + new BlurAlgorithmDescription(BlurAlgorithm.GaussianBlur, "Gaussian Blur: Each pixel is a sum of fractions of each pixel in its neighborhood"), + new BlurAlgorithmDescription(BlurAlgorithm.Filter2D, "Filter 2D: Applies an arbitrary linear filter to an image"), + }); + cbAlgorithm.SelectedIndex = 0; + } + + public FrmMutationBlur(Mutation mutation) : this() + { + + Mutation = mutation; + + Text = $"Mutate: {mutation.MenuName}"; + lbDescription.Text = Mutation.Description; + + if (ReferenceEquals(mutation.Image, null)) + { + Width = pbInfo.Location.X+25; + } + else + { + pbInfo.Image = mutation.Image; + pbInfo.Visible = true; + } + } + #endregion + + #region Overrides + protected override void OnKeyUp(KeyEventArgs e) + { + base.OnKeyUp(e); + if (e.KeyCode == Keys.Enter) + { + if (ctrlKernel.tbKernel.ContainsFocus) return; + 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, 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 (BlurAlgorithmType == BlurAlgorithm.GaussianBlur || + BlurAlgorithmType == BlurAlgorithm.MedianBlur) + { + if (KSize % 2 != 1) + { + MessageBox.Show("Size must be a odd number", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + } + + if (BlurAlgorithmType == BlurAlgorithm.Filter2D) + { + KernelMatrix = ctrlKernel.GetMatrix(); + if (ReferenceEquals(KernelMatrix, null)) return; + } + + + 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; + if (KSize <= 0) // Should never happen! + { + DialogResult = DialogResult.Cancel; + } + Close(); + } + + return; + } + + if (ReferenceEquals(sender, btnCancel)) + { + DialogResult = DialogResult.Cancel; + return; + } + } + + private void EventSelectedIndexChanged(object sender, EventArgs e) + { + if (ReferenceEquals(sender, cbAlgorithm)) + { + ctrlKernel.Enabled = BlurAlgorithmType == BlurAlgorithm.Filter2D; + nmSize.Enabled = BlurAlgorithmType != BlurAlgorithm.Pyramid && BlurAlgorithmType != BlurAlgorithm.Filter2D; + return; + } + } + + #endregion + + + } +} diff --git a/UVtools.GUI/Forms/FrmMutationBlur.resx b/UVtools.GUI/Forms/FrmMutationBlur.resx new file mode 100644 index 0000000..40776f4 --- /dev/null +++ b/UVtools.GUI/Forms/FrmMutationBlur.resx @@ -0,0 +1,136 @@ +<?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="lbIterationsStart.ToolTip" xml:space="preserve"> + <value>Selects the number of iterations/passes to perform on each layer using this mutator. +Enable the "Fade in/out" to fade the iteration over layers, you can use a start iteration higher than end to perform a inverse fade. +WARNING: Using high iteration values can destroy your model depending on the mutator being used, please use low values or with caution!</value> + </data> + <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/Forms/FrmMutationPixelDimming.Designer.cs b/UVtools.GUI/Forms/FrmMutationPixelDimming.Designer.cs index 55114be..4e06213 100644 --- a/UVtools.GUI/Forms/FrmMutationPixelDimming.Designer.cs +++ b/UVtools.GUI/Forms/FrmMutationPixelDimming.Designer.cs @@ -45,11 +45,11 @@ namespace UVtools.GUI.Forms this.btnLayerRangeNormalLayers = new System.Windows.Forms.ToolStripMenuItem(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.label1 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); - this.label6 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label(); this.btnCancel = new System.Windows.Forms.Button(); this.btnMutate = new System.Windows.Forms.Button(); @@ -68,6 +68,10 @@ namespace UVtools.GUI.Forms this.btnDimPatternChessBoard = new System.Windows.Forms.Button(); this.tbOddPattern = new System.Windows.Forms.TextBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.label13 = new System.Windows.Forms.Label(); + this.label11 = new System.Windows.Forms.Label(); + this.nmInfillSpacing = new System.Windows.Forms.NumericUpDown(); + this.label12 = new System.Windows.Forms.Label(); this.label8 = new System.Windows.Forms.Label(); this.btnInfillPatternWaves = new System.Windows.Forms.Button(); this.btnInfillPatternSquareGrid = new System.Windows.Forms.Button(); @@ -75,10 +79,6 @@ namespace UVtools.GUI.Forms this.nmInfillThickness = new System.Windows.Forms.NumericUpDown(); this.label9 = new System.Windows.Forms.Label(); this.label10 = new System.Windows.Forms.Label(); - this.label11 = new System.Windows.Forms.Label(); - this.nmInfillSpacing = new System.Windows.Forms.NumericUpDown(); - this.label12 = new System.Windows.Forms.Label(); - this.label13 = new System.Windows.Forms.Label(); this.btnLayerRangeSelect = new UVtools.GUI.Controls.SplitButton(); ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).BeginInit(); @@ -87,8 +87,8 @@ namespace UVtools.GUI.Forms ((System.ComponentModel.ISupportInitialize)(this.nmPixelDimBrightness)).BeginInit(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.nmInfillThickness)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nmInfillSpacing)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmInfillThickness)).BeginInit(); this.SuspendLayout(); // // lbDescription @@ -225,6 +225,17 @@ namespace UVtools.GUI.Forms this.label1.Text = "px"; this.toolTip.SetToolTip(this.label1, resources.GetString("label1.ToolTip")); // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(19, 478); + this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(548, 20); + this.label6.TabIndex = 25; + this.label6.Text = "(Leave this field empty to use only the even layer pattern for the layers range)"; + this.toolTip.SetToolTip(this.label6, resources.GetString("label6.ToolTip")); + // // label2 // this.label2.AutoSize = true; @@ -265,17 +276,6 @@ namespace UVtools.GUI.Forms this.label5.TabIndex = 24; this.label5.Text = "Odd Layer\r\nPattern:\r\n0 = Black\r\n255 = White\r\n(Optional)"; // - // label6 - // - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(19, 478); - this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(548, 20); - this.label6.TabIndex = 25; - this.label6.Text = "(Leave this field empty to use only the even layer pattern for the layers range)"; - this.toolTip.SetToolTip(this.label6, resources.GetString("label6.ToolTip")); - // // label7 // this.label7.AutoSize = true; @@ -344,6 +344,7 @@ namespace UVtools.GUI.Forms this.tbEvenPattern.Size = new System.Drawing.Size(469, 124); this.tbEvenPattern.TabIndex = 17; this.tbEvenPattern.Text = "127 255 255 255\r\n255 255 127 255"; + this.tbEvenPattern.WordWrap = false; // // nmPixelDimBrightness // @@ -485,6 +486,7 @@ namespace UVtools.GUI.Forms this.tbOddPattern.Size = new System.Drawing.Size(469, 124); this.tbOddPattern.TabIndex = 23; this.tbOddPattern.Text = "255 255 127 255\r\n127 255 255 255"; + this.tbOddPattern.WordWrap = false; // // groupBox2 // @@ -506,6 +508,60 @@ namespace UVtools.GUI.Forms this.groupBox2.TabStop = false; this.groupBox2.Text = "Infill generator"; // + // label13 + // + this.label13.Location = new System.Drawing.Point(7, 22); + this.label13.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(561, 46); + this.label13.TabIndex = 34; + this.label13.Text = "The infill function can create a ton of resin traps, use only this tool if you kn" + + "ow what are you doing or for specific parts. You always need to ensure the drain" + + "s."; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(543, 76); + this.label11.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(25, 20); + this.label11.TabIndex = 33; + this.label11.Text = "px"; + // + // nmInfillSpacing + // + this.nmInfillSpacing.Location = new System.Drawing.Point(422, 73); + this.nmInfillSpacing.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.nmInfillSpacing.Maximum = new decimal(new int[] { + 10000, + 0, + 0, + 0}); + this.nmInfillSpacing.Minimum = new decimal(new int[] { + 5, + 0, + 0, + 0}); + this.nmInfillSpacing.Name = "nmInfillSpacing"; + this.nmInfillSpacing.Size = new System.Drawing.Size(113, 26); + this.nmInfillSpacing.TabIndex = 31; + this.nmInfillSpacing.Value = new decimal(new int[] { + 20, + 0, + 0, + 0}); + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(343, 76); + this.label12.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(71, 20); + this.label12.TabIndex = 32; + this.label12.Text = "Spacing:"; + // // label8 // this.label8.AutoSize = true; @@ -589,60 +645,6 @@ namespace UVtools.GUI.Forms this.label10.TabIndex = 21; this.label10.Text = "Thickness:"; // - // label11 - // - this.label11.AutoSize = true; - this.label11.Location = new System.Drawing.Point(543, 76); - this.label11.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label11.Name = "label11"; - this.label11.Size = new System.Drawing.Size(25, 20); - this.label11.TabIndex = 33; - this.label11.Text = "px"; - // - // nmInfillSpacing - // - this.nmInfillSpacing.Location = new System.Drawing.Point(422, 73); - this.nmInfillSpacing.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); - this.nmInfillSpacing.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.nmInfillSpacing.Minimum = new decimal(new int[] { - 5, - 0, - 0, - 0}); - this.nmInfillSpacing.Name = "nmInfillSpacing"; - this.nmInfillSpacing.Size = new System.Drawing.Size(113, 26); - this.nmInfillSpacing.TabIndex = 31; - this.nmInfillSpacing.Value = new decimal(new int[] { - 20, - 0, - 0, - 0}); - // - // label12 - // - this.label12.AutoSize = true; - this.label12.Location = new System.Drawing.Point(343, 76); - this.label12.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label12.Name = "label12"; - this.label12.Size = new System.Drawing.Size(71, 20); - this.label12.TabIndex = 32; - this.label12.Text = "Spacing:"; - // - // label13 - // - this.label13.Location = new System.Drawing.Point(7, 22); - this.label13.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label13.Name = "label13"; - this.label13.Size = new System.Drawing.Size(561, 46); - this.label13.TabIndex = 34; - this.label13.Text = "The infill function can create a ton of resin traps, use only this tool if you kn" + - "ow what are you doing or for specific parts. You always need to ensure the drain" + - "s."; - // // btnLayerRangeSelect // this.btnLayerRangeSelect.Location = new System.Drawing.Point(446, 146); @@ -697,8 +699,8 @@ namespace UVtools.GUI.Forms this.groupBox1.PerformLayout(); this.groupBox2.ResumeLayout(false); this.groupBox2.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.nmInfillThickness)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.nmInfillSpacing)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmInfillThickness)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); diff --git a/UVtools.GUI/Forms/FrmToolEmpty.cs b/UVtools.GUI/Forms/FrmToolEmpty.cs index 29d89cc..9c91473 100644 --- a/UVtools.GUI/Forms/FrmToolEmpty.cs +++ b/UVtools.GUI/Forms/FrmToolEmpty.cs @@ -33,11 +33,22 @@ namespace UVtools.GUI.Forms #endregion #region Constructors - public FrmToolEmpty(uint layerIndex, string text, string description, string btnOkText) + public FrmToolEmpty() { InitializeComponent(); - DialogResult = DialogResult.Cancel; + } + + public FrmToolEmpty(Mutation mutation) : this() + { + btnOk.Text = "Mutate"; + Text = $"Mutate: {mutation.MenuName}"; + lbDescription.Text = mutation.Description; + nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount - 1; + } + + public FrmToolEmpty(uint layerIndex, string text, string description, string btnOkText) : this() + { nmLayerRangeStart.Value = layerIndex; nmLayerRangeEnd.Value = layerIndex; diff --git a/UVtools.GUI/FrmMain.cs b/UVtools.GUI/FrmMain.cs index fb2aa3b..8f0d0aa 100644 --- a/UVtools.GUI/FrmMain.cs +++ b/UVtools.GUI/FrmMain.cs @@ -109,7 +109,12 @@ namespace UVtools.GUI "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", Resources.blur_16x16, + {LayerManager.Mutate.Blur, new Mutation(LayerManager.Mutate.Blur, "Blur", Resources.blur_16x16, + "Blur and averaging images with various low pass filters\n" + + "Note: Printer must support AntiAliasing on firmware to able to use this function\n" + + "More information: https://docs.opencv.org/master/d4/d13/tutorial_py_filtering.html " + )}, + /*{LayerManager.Mutate.PyrDownUp, new Mutation(LayerManager.Mutate.PyrDownUp, "Big Blur", Resources.blur_16x16, "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" + @@ -127,7 +132,7 @@ namespace UVtools.GUI "Very fast, but does not preserve sharp edges well.\n" + "Note 1: Printer must support AntiAliasing on firmware to able to use this function.\n" + "Note 2: Iterations must be a odd number." - )}, + )},*/ }; @@ -3103,6 +3108,9 @@ namespace UVtools.GUI uint iterationsEnd = 0; bool fade = false; + Matrix<byte> kernel = null; + Point kernelAnchor = Point.Empty; + ThresholdType thresholdType = ThresholdType.Binary; OperationMove operationMove = null; @@ -3113,6 +3121,8 @@ namespace UVtools.GUI Matrix<byte> evenPattern = null; Matrix<byte> oddPattern = null; + FrmMutationBlur.BlurAlgorithm blurAlgorithm = FrmMutationBlur.BlurAlgorithm.Blur; + switch (mutator) { case LayerManager.Mutate.Move: @@ -3156,6 +3166,14 @@ namespace UVtools.GUI x = (double) inputBox.Value; } break; + case LayerManager.Mutate.Solidify: + using (FrmToolEmpty inputBox = new FrmToolEmpty(Mutations[mutator])) + { + if (inputBox.ShowDialog() != DialogResult.OK) return; + layerStart = inputBox.LayerRangeStart; + layerEnd = inputBox.LayerRangeEnd; + } + break; case LayerManager.Mutate.PixelDimming: using (FrmMutationPixelDimming inputBox = new FrmMutationPixelDimming(Mutations[mutator])) { @@ -3178,6 +3196,25 @@ namespace UVtools.GUI thresholdType = inputBox.ThresholdTypeValue; } break; + case LayerManager.Mutate.Blur: + using (FrmMutationBlur inputBox = new FrmMutationBlur(Mutations[mutator])) + { + if (inputBox.ShowDialog() != DialogResult.OK) return; + iterationsStart = inputBox.KSize; + if (iterationsStart == 0) return; + layerStart = inputBox.LayerRangeStart; + layerEnd = inputBox.LayerRangeEnd; + + blurAlgorithm = inputBox.BlurAlgorithmType; + + if (blurAlgorithm == FrmMutationBlur.BlurAlgorithm.Filter2D) + { + kernel = inputBox.KernelMatrix; + kernelAnchor = inputBox.KernelAnchor; + } + } + + break; default: using (FrmMutation inputBox = new FrmMutation(Mutations[mutator])) { @@ -3187,6 +3224,9 @@ namespace UVtools.GUI layerStart = inputBox.LayerRangeStart; layerEnd = inputBox.LayerRangeEnd; iterationsEnd = inputBox.IterationsEnd; + + kernel = inputBox.KernelMatrix; + kernelAnchor = inputBox.KernelAnchor; } break; @@ -3234,19 +3274,19 @@ namespace UVtools.GUI SlicerFile.LayerManager.MutatePixelDimming(layerStart, layerEnd, evenPattern, oddPattern, (ushort) iterationsStart, progress); break; case LayerManager.Mutate.Erode: - SlicerFile.LayerManager.MutateErode(layerStart, layerEnd, (int) iterationsStart, (int) iterationsEnd, fade, progress); + SlicerFile.LayerManager.MutateErode(layerStart, layerEnd, (int) iterationsStart, (int) iterationsEnd, fade, progress, kernel, kernelAnchor); break; case LayerManager.Mutate.Dilate: - SlicerFile.LayerManager.MutateDilate(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress); + SlicerFile.LayerManager.MutateDilate(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress, kernel, kernelAnchor); break; case LayerManager.Mutate.Opening: - SlicerFile.LayerManager.MutateOpen(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress); + SlicerFile.LayerManager.MutateOpen(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress, kernel, kernelAnchor); break; case LayerManager.Mutate.Closing: - SlicerFile.LayerManager.MutateClose(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress); + SlicerFile.LayerManager.MutateClose(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress, kernel, kernelAnchor); break; case LayerManager.Mutate.Gradient: - SlicerFile.LayerManager.MutateGradient(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress); + SlicerFile.LayerManager.MutateGradient(layerStart, layerEnd, (int)iterationsStart, (int)iterationsEnd, fade, progress, kernel, kernelAnchor); break; /*case Mutation.Mutates.TopHat: kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(9, 9), @@ -3267,21 +3307,42 @@ namespace UVtools.GUI 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; - case LayerManager.Mutate.SmoothMedian: - SlicerFile.LayerManager.MutateMedianBlur(layerStart, layerEnd, (int)iterationsStart, progress); - break; - case LayerManager.Mutate.SmoothGaussian: - SlicerFile.LayerManager.MutateGaussianBlur(layerStart, layerEnd, new Size((int) iterationsStart, (int) iterationsStart), 0,0, BorderType.Default, progress); + case LayerManager.Mutate.Blur: + switch (blurAlgorithm) + { + case FrmMutationBlur.BlurAlgorithm.Blur: + SlicerFile.LayerManager.MutateBlur(layerStart, layerEnd, new Size((int)iterationsStart, (int)iterationsStart), kernelAnchor, BorderType.Reflect101, progress); + break; + case FrmMutationBlur.BlurAlgorithm.Pyramid: + SlicerFile.LayerManager.MutatePyrDownUp(layerStart, layerEnd, BorderType.Default, progress); + break; + case FrmMutationBlur.BlurAlgorithm.MedianBlur: + SlicerFile.LayerManager.MutateMedianBlur(layerStart, layerEnd, (int) iterationsStart, progress); + break; + case FrmMutationBlur.BlurAlgorithm.GaussianBlur: + SlicerFile.LayerManager.MutateGaussianBlur(layerStart, layerEnd, new Size((int)iterationsStart, (int)iterationsStart), 0, 0, BorderType.Reflect101, progress); + break; + case FrmMutationBlur.BlurAlgorithm.Filter2D: + SlicerFile.LayerManager.MutateFilter2D(layerStart, layerEnd, kernel, kernelAnchor, BorderType.Reflect101, progress); + break; + default: + throw new ArgumentOutOfRangeException(); + } break; + /*case LayerManager.Mutate.PyrDownUp: + SlicerFile.LayerManager.MutatePyrDownUp(layerStart, layerEnd, BorderType.Default, progress); + break; + case LayerManager.Mutate.SmoothMedian: + SlicerFile.LayerManager.MutateMedianBlur(layerStart, layerEnd, (int)iterationsStart, progress); + break; + case LayerManager.Mutate.SmoothGaussian: + SlicerFile.LayerManager.MutateGaussianBlur(layerStart, layerEnd, new Size((int) iterationsStart, (int) iterationsStart), 0,0, BorderType.Default, progress); + break;*/ } } catch (OperationCanceledException) { - } catch (Exception ex) { diff --git a/UVtools.GUI/Mutation.cs b/UVtools.GUI/Mutation.cs index 323faf3..b56fb91 100644 --- a/UVtools.GUI/Mutation.cs +++ b/UVtools.GUI/Mutation.cs @@ -31,6 +31,7 @@ namespace UVtools.GUI MenuName = menuName ?? mutate.ToString(); Description = description; MenuImage = menuImage ?? Properties.Resources.filter_filled_16x16; + Image = image; } #endregion diff --git a/UVtools.GUI/Properties/AssemblyInfo.cs b/UVtools.GUI/Properties/AssemblyInfo.cs index 8100aa2..ebfa840 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.4.3")] -[assembly: AssemblyFileVersion("0.6.4.3")] +[assembly: AssemblyVersion("0.6.5.0")] +[assembly: AssemblyFileVersion("0.6.5.0")] diff --git a/UVtools.GUI/UVtools.GUI.csproj b/UVtools.GUI/UVtools.GUI.csproj index d93fd0a..229ff2c 100644 --- a/UVtools.GUI/UVtools.GUI.csproj +++ b/UVtools.GUI/UVtools.GUI.csproj @@ -145,6 +145,12 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <Compile Include="Controls\CtrlKernel.cs"> + <SubType>UserControl</SubType> + </Compile> + <Compile Include="Controls\CtrlKernel.Designer.cs"> + <DependentUpon>CtrlKernel.cs</DependentUpon> + </Compile> <Compile Include="Controls\Log.cs" /> <Compile Include="Controls\SlicerPropertyItem.cs" /> <Compile Include="Controls\SplitButton.cs"> @@ -156,6 +162,12 @@ <Compile Include="Forms\FrmInstallPEProfiles.Designer.cs"> <DependentUpon>FrmInstallPEProfiles.cs</DependentUpon> </Compile> + <Compile Include="Forms\FrmMutationBlur.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="Forms\FrmMutationBlur.Designer.cs"> + <DependentUpon>FrmMutationBlur.cs</DependentUpon> + </Compile> <Compile Include="Forms\FrmMutationThreshold.cs"> <SubType>Form</SubType> </Compile> @@ -262,12 +274,18 @@ <Compile Include="Mutation.cs" /> <Compile Include="Program.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <EmbeddedResource Include="Controls\CtrlKernel.resx"> + <DependentUpon>CtrlKernel.cs</DependentUpon> + </EmbeddedResource> <EmbeddedResource Include="Forms\FrmAbout.resx"> <DependentUpon>FrmAbout.cs</DependentUpon> </EmbeddedResource> <EmbeddedResource Include="Forms\FrmInstallPEProfiles.resx"> <DependentUpon>FrmInstallPEProfiles.cs</DependentUpon> </EmbeddedResource> + <EmbeddedResource Include="Forms\FrmMutationBlur.resx"> + <DependentUpon>FrmMutationBlur.cs</DependentUpon> + </EmbeddedResource> <EmbeddedResource Include="Forms\FrmMutationThreshold.resx"> <DependentUpon>FrmMutationThreshold.cs</DependentUpon> </EmbeddedResource> |