From 15d9b3e7a5d8783493339bfe8f5c73ad74528b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Mon, 1 Jun 2020 04:31:18 +0100 Subject: [PATCH] v0.4.1 * (Add) Opening, Closing and Gradient Mutators * (Add) Choose layer range when appling a mutator #1 * (Add) Choose iterations range/fading when appling a mutator (Thanks to Renos Makrosellis) * (Add) Global and unhandled exceptions are now logged to be easier to report a bug * (Change) Current layer and layer count text was reduced by 1 to match indexes on mutators * (Improvement) Better mutator dialogs and explanation * (Improvement) Compressed GUI images size * (Fix) SlicerHeader was with wrong data size and affecting .photon, .cbddlp and .cbt (Thanks to Renos Makrosellis) --- CHANGELOG.md | 12 + PrusaSL1Reader/ChituboxFile.cs | 6 +- PrusaSL1Reader/PHZFile.cs | 10 + PrusaSL1Reader/PrusaSL1Reader.csproj | 6 +- PrusaSL1Viewer/Controls/SplitButton.cs | 99 +++++ PrusaSL1Viewer/FrmMain.cs | 166 ++++++-- PrusaSL1Viewer/FrmMain.resx | 49 +-- PrusaSL1Viewer/FrmMutation.Designer.cs | 380 ++++++++++++++++++ PrusaSL1Viewer/FrmMutation.cs | 211 ++++++++++ .../{ImageBox.resx => FrmMutation.resx} | 16 + PrusaSL1Viewer/ImageBox.Designer.cs | 46 --- PrusaSL1Viewer/ImageBox.cs | 65 --- PrusaSL1Viewer/Images/Back-16x16.png | Bin 186 -> 138 bytes PrusaSL1Viewer/Images/Button-Info-16x16.png | Bin 791 -> 666 bytes PrusaSL1Viewer/Images/CNCMachine-16x16.png | Bin 375 -> 261 bytes PrusaSL1Viewer/Images/Cancel-24x24.png | Bin 995 -> 513 bytes PrusaSL1Viewer/Images/Cancel-32x32.png | Bin 1339 -> 588 bytes PrusaSL1Viewer/Images/Convert-16x16.png | Bin 788 -> 629 bytes PrusaSL1Viewer/Images/DataList-16x16.png | Bin 214 -> 179 bytes PrusaSL1Viewer/Images/Donate-16x16.png | Bin 769 -> 536 bytes PrusaSL1Viewer/Images/Error-128x128.png | Bin 1953 -> 889 bytes PrusaSL1Viewer/Images/Exit-16x16.png | Bin 230 -> 174 bytes .../Images/Extract-object-16x16.png | Bin 554 -> 490 bytes PrusaSL1Viewer/Images/File-Close-16x16.png | Bin 355 -> 247 bytes PrusaSL1Viewer/Images/File-Refresh-16x16.png | Bin 276 -> 196 bytes PrusaSL1Viewer/Images/GCode-16x16.png | Bin 274 -> 151 bytes PrusaSL1Viewer/Images/Geometry-16x16.png | Bin 360 -> 259 bytes .../Images/Global-Network-icon-16x16.png | Bin 963 -> 876 bytes PrusaSL1Viewer/Images/Next-16x16.png | Bin 198 -> 140 bytes PrusaSL1Viewer/Images/Ok-24x24.png | Bin 548 -> 350 bytes PrusaSL1Viewer/Images/Open-16x16.png | Bin 326 -> 248 bytes PrusaSL1Viewer/Images/PhotoInfo-16x16.png | Bin 265 -> 196 bytes PrusaSL1Viewer/Images/Rotate-16x16.png | Bin 384 -> 259 bytes PrusaSL1Viewer/Images/Save-16x16.png | Bin 425 -> 247 bytes PrusaSL1Viewer/Images/SaveAs-16x16.png | Bin 340 -> 244 bytes PrusaSL1Viewer/Images/Wrench-16x16.png | Bin 347 -> 237 bytes PrusaSL1Viewer/Images/eye-16x16.png | Bin 0 -> 402 bytes PrusaSL1Viewer/Images/eye-24x24.png | Bin 0 -> 731 bytes PrusaSL1Viewer/Images/filter-filled-16x16.png | Bin 0 -> 253 bytes .../Images/gui/mutation_blackhat.png | Bin 0 -> 2165 bytes .../Images/gui/mutation_closing.png | Bin 0 -> 1427 bytes .../Images/gui/mutation_dilation.png | Bin 0 -> 1083 bytes .../Images/gui/mutation_erosion.png | Bin 0 -> 1055 bytes .../Images/gui/mutation_gradient.png | Bin 0 -> 1280 bytes .../Images/gui/mutation_opening.png | Bin 0 -> 1265 bytes PrusaSL1Viewer/Images/gui/mutation_tophat.png | Bin 0 -> 948 bytes PrusaSL1Viewer/Images/layers-16x16.png | Bin 459 -> 358 bytes PrusaSL1Viewer/Images/pixel-16x16.png | Bin 591 -> 454 bytes PrusaSL1Viewer/Images/search-16x16.png | Bin 50607 -> 344 bytes .../Libraries/ApplicationManagement.dll | Bin 0 -> 28672 bytes PrusaSL1Viewer/Mutation.cs | 51 +++ PrusaSL1Viewer/Program.cs | 22 + PrusaSL1Viewer/Properties/AssemblyInfo.cs | 4 +- .../Properties/Resources.Designer.cs | 100 +++++ PrusaSL1Viewer/Properties/Resources.resx | 114 ++++-- PrusaSL1Viewer/PrusaSL1Viewer.csproj | 37 +- README.md | 7 +- 57 files changed, 1163 insertions(+), 238 deletions(-) create mode 100644 PrusaSL1Viewer/Controls/SplitButton.cs create mode 100644 PrusaSL1Viewer/FrmMutation.Designer.cs create mode 100644 PrusaSL1Viewer/FrmMutation.cs rename PrusaSL1Viewer/{ImageBox.resx => FrmMutation.resx} (83%) delete mode 100644 PrusaSL1Viewer/ImageBox.Designer.cs delete mode 100644 PrusaSL1Viewer/ImageBox.cs create mode 100644 PrusaSL1Viewer/Images/eye-16x16.png create mode 100644 PrusaSL1Viewer/Images/eye-24x24.png create mode 100644 PrusaSL1Viewer/Images/filter-filled-16x16.png create mode 100644 PrusaSL1Viewer/Images/gui/mutation_blackhat.png create mode 100644 PrusaSL1Viewer/Images/gui/mutation_closing.png create mode 100644 PrusaSL1Viewer/Images/gui/mutation_dilation.png create mode 100644 PrusaSL1Viewer/Images/gui/mutation_erosion.png create mode 100644 PrusaSL1Viewer/Images/gui/mutation_gradient.png create mode 100644 PrusaSL1Viewer/Images/gui/mutation_opening.png create mode 100644 PrusaSL1Viewer/Images/gui/mutation_tophat.png create mode 100644 PrusaSL1Viewer/Libraries/ApplicationManagement.dll create mode 100644 PrusaSL1Viewer/Mutation.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ef90a2..58c02104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 01/06/2020 - v0.4.1 - Beta + +* (Add) Opening, Closing and Gradient Mutators +* (Add) Choose layer range when appling a mutator #1 +* (Add) Choose iterations range/fading when appling a mutator (Thanks to Renos Makrosellis) +* (Add) Global and unhandled exceptions are now logged to be easier to report a bug +* (Change) Current layer and layer count text was reduced by 1 to match indexes on mutators +* (Improvement) Better mutator dialogs and explanation +* (Improvement) Compressed GUI images size +* (Fix) SlicerHeader was with wrong data size and affecting .photon, .cbddlp and .cbt (Thanks to Renos Makrosellis) + + ## 27/05/2020 - v0.4 - Beta * (Add) CWS file format diff --git a/PrusaSL1Reader/ChituboxFile.cs b/PrusaSL1Reader/ChituboxFile.cs index f671fe34..e4be6931 100644 --- a/PrusaSL1Reader/ChituboxFile.cs +++ b/PrusaSL1Reader/ChituboxFile.cs @@ -703,11 +703,9 @@ void rleRGB15() currentOffset += Helpers.SerializeWriteFileStream(outputFile, PrintParametersSettings); HeaderSettings.SlicerOffset = currentOffset; - HeaderSettings.SlicerSize = (uint) Helpers.Serializer.SizeOf(SlicerInfoSettings); + HeaderSettings.SlicerSize = (uint) Helpers.Serializer.SizeOf(SlicerInfoSettings) - SlicerInfoSettings.MachineNameSize; - SlicerInfoSettings.MachineNameAddress = - (uint) (currentOffset + Helpers.Serializer.SizeOf(SlicerInfoSettings) - - SlicerInfoSettings.MachineNameSize); + SlicerInfoSettings.MachineNameAddress = currentOffset + HeaderSettings.SlicerSize; currentOffset += Helpers.SerializeWriteFileStream(outputFile, SlicerInfoSettings); diff --git a/PrusaSL1Reader/PHZFile.cs b/PrusaSL1Reader/PHZFile.cs index 5d7371e1..c2f2ced7 100644 --- a/PrusaSL1Reader/PHZFile.cs +++ b/PrusaSL1Reader/PHZFile.cs @@ -715,6 +715,10 @@ void AddRep() for (int x = 0; x < image.Width; x++) { var grey7 = (byte)((pixelRowSpan[x].PackedValue >> 1) & 0x7f); + if (grey7 > 0x7c) + { + grey7 = 0x7c; + } if (color == byte.MaxValue) { @@ -882,6 +886,12 @@ private Image DecodePhzImage(uint layerIndex) //lastColor = (byte) (code << 1); // // Convert from 7bpp to 8bpp (extending the last bit) lastColor = (byte) (((code & 0x7f) << 1) | (code & 1)); + if (lastColor >= 0xfc) { + // Make 'white' actually white + lastColor = 0xff; + + } + if (index < limit) { span[index].PackedValue = lastColor; diff --git a/PrusaSL1Reader/PrusaSL1Reader.csproj b/PrusaSL1Reader/PrusaSL1Reader.csproj index 92d9c60c..2682295e 100644 --- a/PrusaSL1Reader/PrusaSL1Reader.csproj +++ b/PrusaSL1Reader/PrusaSL1Reader.csproj @@ -7,9 +7,9 @@ https://github.com/sn4k3/PrusaSL1Viewer https://github.com/sn4k3/PrusaSL1Viewer - 0.4.0.0 - 0.4.4.0 - 0.4 + 0.4.1.0 + 0.4.1.0 + 0.4.1 Open, view, edit, extract and convert DLP/SLA files generated from Slicers diff --git a/PrusaSL1Viewer/Controls/SplitButton.cs b/PrusaSL1Viewer/Controls/SplitButton.cs new file mode 100644 index 00000000..57140e43 --- /dev/null +++ b/PrusaSL1Viewer/Controls/SplitButton.cs @@ -0,0 +1,99 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ +// https://stackoverflow.com/questions/10803184/windows-forms-button-with-drop-down-menu +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace PrusaSL1Viewer.Controls +{ + public class SplitButton : Button + { + [DefaultValue(null), Browsable(true), + DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public ContextMenuStrip Menu { get; set; } + + [DefaultValue(20), Browsable(true), + DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public int SplitWidth { get; set; } = 20; + + [DefaultValue(false), Browsable(true), + DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool OpenMenuOnlyOnArrow { get; set; } = false; + + public SplitButton() + { + } + + protected override void OnMouseClick(MouseEventArgs e) + { + if (Menu != null && e.Button == MouseButtons.Left) + { + if (OpenMenuOnlyOnArrow) + { + var splitRect = new Rectangle(this.Width - this.SplitWidth, 0, this.SplitWidth, this.Height); + if (!splitRect.Contains(e.Location)) + { + base.OnMouseDown(e); + return; + } + } + Menu.Show(this, 0, this.Height); // Shows menu under button + //Menu.Show(this, mevent.Location); // Shows menu at click location + } + else + { + base.OnMouseDown(e); + } + } + + /*protected override void OnMouseDown(MouseEventArgs mevent) + { + var splitRect = new Rectangle(this.Width - this.SplitWidth, 0, this.SplitWidth, this.Height); + + // Figure out if the button click was on the button itself or the menu split + if (Menu != null && + mevent.Button == MouseButtons.Left && + splitRect.Contains(mevent.Location)) + { + Menu.Show(this, 0, this.Height); // Shows menu under button + //Menu.Show(this, mevent.Location); // Shows menu at click location + } + else + { + base.OnMouseDown(mevent); + } + }*/ + + protected override void OnPaint(PaintEventArgs pevent) + { + base.OnPaint(pevent); + + if (this.Menu != null && this.SplitWidth > 0) + { + // Draw the arrow glyph on the right side of the button + int arrowX = ClientRectangle.Width - 14; + int arrowY = ClientRectangle.Height / 2 - 1; + + var arrowBrush = Enabled ? SystemBrushes.ControlText : SystemBrushes.ButtonShadow; + var arrows = new[] { new Point(arrowX, arrowY), new Point(arrowX + 7, arrowY), new Point(arrowX + 3, arrowY + 4) }; + pevent.Graphics.FillPolygon(arrowBrush, arrows); + + // Draw a dashed separator on the left of the arrow + int lineX = ClientRectangle.Width - this.SplitWidth; + int lineYFrom = arrowY - 4; + int lineYTo = arrowY + 8; + using (var separatorPen = new Pen(Brushes.DarkGray) { DashStyle = DashStyle.Dot }) + { + pevent.Graphics.DrawLine(separatorPen, lineX, lineYFrom, lineX, lineYTo); + } + } + } + } +} diff --git a/PrusaSL1Viewer/FrmMain.cs b/PrusaSL1Viewer/FrmMain.cs index d5a965ff..a4126af1 100644 --- a/PrusaSL1Viewer/FrmMain.cs +++ b/PrusaSL1Viewer/FrmMain.cs @@ -14,6 +14,8 @@ using System.Reflection; using System.Threading.Tasks; using System.Windows.Forms; +using Emgu.CV; +using Emgu.CV.CvEnum; using Emgu.CV.Structure; using PrusaSL1Reader; using SixLabors.ImageSharp; @@ -22,37 +24,66 @@ using SixLabors.ImageSharp.Processing; using Color = System.Drawing.Color; using Point = System.Drawing.Point; +using Size = System.Drawing.Size; namespace PrusaSL1Viewer { public partial class FrmMain : Form { #region Enums - public enum eMutate - { - Erode, - Dilate, - PyrDownUp, - SmoothMedian, - SmoothGaussian - } #endregion #region Properties - public static readonly Dictionary MutateDescriptions = new Dictionary - { - {eMutate.Erode, "Erodes image using a 3x3 rectangular structuring element.\n" + - "Erosion are applied several (iterations) times"}, - {eMutate.Dilate, "Dilates image using a 3x3 rectangular structuring element.\n" + - "Dilation are applied several (iterations) times"}, - {eMutate.PyrDownUp, "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" + - "First it upsamples image by injecting even zero rows and columns and then convolves result with the specified filter multiplied by 4 for interpolation"}, - {eMutate.SmoothMedian, "Finding median of size neighborhood"}, - {eMutate.SmoothGaussian, "Perform Gaussian Smoothing"} - }; + public static readonly Dictionary Mutations = + new Dictionary + { + {Mutation.Mutates.Erode, new Mutation(Mutation.Mutates.Erode, + "The basic idea of erosion is just like soil erosion only, it erodes away the boundaries of foreground object (Always try to keep foreground in white). " + + "So what happends is that, all the pixels near boundary will be discarded depending upon the size of kernel. So the thickness or size of the foreground object decreases or simply white region decreases in the image. It is useful for removing small white noises, detach two connected objects, etc.", + Properties.Resources.mutation_erosion + )}, + {Mutation.Mutates.Dilate, new Mutation(Mutation.Mutates.Dilate, + "It is just opposite of erosion. Here, a pixel element is '1' if atleast one pixel under the kernel is '1'. So it increases the white region in the image or size of foreground object increases. Normally, in cases like noise removal, erosion is followed by dilation. Because, erosion removes white noises, but it also shrinks our object. So we dilate it. Since noise is gone, they won't come back, but our object area increases. It is also useful in joining broken parts of an object.", + Properties.Resources.mutation_dilation + )}, + {Mutation.Mutates.Opening, new Mutation(Mutation.Mutates.Opening, + "Opening is just another name of erosion followed by dilation. It is useful in removing noise.", + Properties.Resources.mutation_opening + )}, + {Mutation.Mutates.Closing, new Mutation(Mutation.Mutates.Closing, + "Closing is reverse of Opening, Dilation followed by Erosion. It is useful in closing small holes inside the foreground objects, or small black points on the object.", + Properties.Resources.mutation_closing + )}, + {Mutation.Mutates.Gradient, new Mutation(Mutation.Mutates.Gradient, + "It's the difference between dilation and erosion of an image.", + Properties.Resources.mutation_gradient + )}, + /*{Mutation.Mutates.TopHat, new Mutation(Mutation.Mutates.TopHat, + "It's the difference between input image and Opening of the image.", + Properties.Resources.mutation_tophat + )}, + {Mutation.Mutates.BlackHat, new Mutation(Mutation.Mutates.BlackHat, + "It's the difference between the closing of the input image and input image.", + Properties.Resources.mutation_blackhat + )},*/ + /*{Mutation.Mutates.HitMiss, new Mutation(Mutation.Mutates.HitMiss, + "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 + )},*/ + {Mutation.Mutates.PyrDownUp, new Mutation(Mutation.Mutates.PyrDownUp, + "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" + )}, + {Mutation.Mutates.SmoothMedian, new Mutation(Mutation.Mutates.SmoothMedian, + "Finding median of size neighborhood" + )}, + {Mutation.Mutates.SmoothGaussian, new Mutation(Mutation.Mutates.SmoothGaussian, + "Perform Gaussian Smoothing" + )}, + }; + public FrmLoading FrmLoading { get; } public static FileFormat SlicerFile @@ -79,11 +110,12 @@ public FrmMain() DragEnter += (s, e) => { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy; }; DragDrop += (s, e) => { ProcessFile((string[])e.Data.GetData(DataFormats.FileDrop)); }; - foreach (eMutate mutate in (eMutate[])Enum.GetValues(typeof(eMutate))) + foreach (Mutation.Mutates mutate in (Mutation.Mutates[])Enum.GetValues(typeof(Mutation.Mutates))) { + if(!Mutations.ContainsKey(mutate)) continue; var item = new ToolStripMenuItem(mutate.ToString()) { - ToolTipText = MutateDescriptions[mutate], Tag = mutate, AutoToolTip = true + ToolTipText = Mutations[mutate].Description, Tag = mutate, AutoToolTip = true, Image = Properties.Resources.filter_filled_16x16 }; item.Click += ItemClicked; menuMutate.DropDownItems.Add(item); @@ -374,9 +406,9 @@ private void ItemClicked(object sender, EventArgs e) } - if (item.Tag.GetType() == typeof(eMutate)) + if (item.Tag.GetType() == typeof(Mutation.Mutates)) { - eMutate mutate = (eMutate)item.Tag; + Mutation.Mutates mutate = (Mutation.Mutates)item.Tag; MutateLayers(mutate); return; } @@ -1128,7 +1160,7 @@ void ShowLayer(uint layerNum) watch.Stop(); tsLayerPreviewTime.Text = $"{watch.ElapsedMilliseconds}ms"; - lbLayers.Text = $"{SlicerFile.GetHeightFromLayer((uint)layerNum + 1)} / {SlicerFile.TotalHeight}mm\n{layerNum + 1} / {SlicerFile.LayerCount}\n{percent}%"; + lbLayers.Text = $"{SlicerFile.GetHeightFromLayer((uint)layerNum + 1)} / {SlicerFile.TotalHeight}mm\n{layerNum} / {SlicerFile.LayerCount-1}\n{percent}%"; pbLayers.Value = percent; } catch (Exception e) @@ -1229,14 +1261,29 @@ private void pbLayer_MouseMove(object sender, MouseEventArgs e) DrawPixel(true, e.Location, Color.Green, Helpers.L8White); } - public void MutateLayers(eMutate type) + public void MutateLayers(Mutation.Mutates type) { - decimal value = 0; - using (FrmInputBox inputBox = new FrmInputBox($"Mutate - {type}", MutateDescriptions[type], 0)) + uint layerStart; + uint layerEnd; + uint iterationsStart; + uint iterationsEnd; + bool fade; + float iterationSteps = 0; + uint maxIteration = 0; + using (FrmMutation inputBox = new FrmMutation(Mutations[type])) { if (inputBox.ShowDialog() != DialogResult.OK) return; - value = inputBox.NewValue; - if (value == 0) return; + iterationsStart = inputBox.Iterations; + if (iterationsStart == 0) return; + layerStart = inputBox.LayerRangeStart; + layerEnd = inputBox.LayerRangeEnd; + iterationsEnd = inputBox.IterationsEnd; + fade = layerStart != layerEnd && iterationsStart != iterationsEnd && inputBox.IterationsFade; + if (fade) + { + iterationSteps = Math.Abs((float)iterationsStart - iterationsEnd) / (layerEnd - layerStart); + maxIteration = Math.Max(iterationsStart, iterationsEnd); + } } DisableGUI(); @@ -1247,26 +1294,63 @@ public void MutateLayers(eMutate type) bool result = false; try { - Parallel.ForEach(SlicerFile, (layer) => + Parallel.For(layerStart, layerEnd+1, i => { + var iterations = iterationsStart; + if (fade) + { + // calculate iterations based on range + iterations = iterationsStart < iterationsEnd ? + (uint) ((i + 1 - layerStart) * iterationSteps) : + (uint) (iterationsStart - (i - layerStart) * iterationSteps); + + // constrain + iterations = Math.Min(Math.Max(1, iterations), maxIteration); + //Debug.WriteLine($"A Layer: {i} = {iterations}"); + } + LayerManager.Layer layer = SlicerFile[i]; var image = layer.Image; var imageEgmu = image.ToEmguImage(); switch (type) { - case eMutate.Erode: - imageEgmu = imageEgmu.Erode((int) value); + case Mutation.Mutates.Erode: + imageEgmu = imageEgmu.Erode((int) iterations); + break; + case Mutation.Mutates.Dilate: + imageEgmu = imageEgmu.Dilate((int) iterations); + break; + case Mutation.Mutates.Opening: + imageEgmu = imageEgmu.Erode((int)iterations); + imageEgmu = imageEgmu.Dilate((int)iterations); + break; + case Mutation.Mutates.Closing: + imageEgmu = imageEgmu.Dilate((int)iterations); + imageEgmu = imageEgmu.Erode((int)iterations); + break; + case Mutation.Mutates.Gradient: + imageEgmu = imageEgmu.MorphologyEx(MorphOp.Gradient, Program.KernelStar3x3, new Point(-1, -1), (int) iterations, + BorderType.Default, new MCvScalar()); + break; + case Mutation.Mutates.TopHat: + imageEgmu = imageEgmu.MorphologyEx(MorphOp.Tophat, CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(9, 9), new Point(-1, -1)), new Point(-1, -1), (int)iterations, + BorderType.Default, new MCvScalar()); + break; + case Mutation.Mutates.BlackHat: + imageEgmu = imageEgmu.MorphologyEx(MorphOp.Blackhat, CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(9, 9), new Point(-1, -1)), new Point(-1, -1), (int)iterations, + BorderType.Default, new MCvScalar()); break; - case eMutate.Dilate: - imageEgmu = imageEgmu.Dilate((int) value); + case Mutation.Mutates.HitMiss: + imageEgmu = imageEgmu.MorphologyEx(MorphOp.HitMiss, Program.KernelFindIsolated, new Point(-1, -1), (int)iterations, + BorderType.Default, new MCvScalar()); break; - case eMutate.PyrDownUp: + case Mutation.Mutates.PyrDownUp: imageEgmu = imageEgmu.PyrDown().PyrUp(); break; - case eMutate.SmoothMedian: - imageEgmu = imageEgmu.SmoothMedian((int) value); + case Mutation.Mutates.SmoothMedian: + imageEgmu = imageEgmu.SmoothMedian((int) iterations); break; - case eMutate.SmoothGaussian: - imageEgmu = imageEgmu.SmoothGaussian((int)value); + case Mutation.Mutates.SmoothGaussian: + imageEgmu = imageEgmu.SmoothGaussian((int)iterations); break; } layer.Image = imageEgmu.ToImageSharpL8(); diff --git a/PrusaSL1Viewer/FrmMain.resx b/PrusaSL1Viewer/FrmMain.resx index ece3314a..4d21ad4b 100644 --- a/PrusaSL1Viewer/FrmMain.resx +++ b/PrusaSL1Viewer/FrmMain.resx @@ -126,12 +126,6 @@ 201, 17 - - 291, 17 - - - 649, 17 - 551, 17 @@ -143,37 +137,37 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADg - CAAAAk1TRnQBSQFMAgEBAwEAASABAQEgAQEBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + CAAAAk1TRnQBSQFMAgEBAwEAATABAQEwAQEBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA AwABEAMAAQEBAAEgBgABEFYAA1ABowNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNS AakDUgGpA1IBqQNQAaOEAANVAbQDWQHHAy8BSQMAAQEDGwEmAxwBJwMcAScDHAEnAxwBJwMcAScDHAEn AxwBJwMcAScDHAEnAxwBJwMCAQMEAANSAakwAANSAakQAAMnAToDMAFMAzABTAMwAUwDMAFMAzABTAMw AUwDMAFMAzABTAMnATpPAAH/AwAB/wNDAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DMgFRBAADUgGpBAADUAGdA1MBqgNTAaoDUwGqA1MBqgNTAaoDUwGqA1ABnQwA - A1IBqRAAA04B+wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/A04B+0wAA1EBogNWAbYDKgFA + A1IBqRAAA04B+wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/A04B+0wAA1EBogNWAbYDKgFA BAADEAEVAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxABFggAA1IBqQQAA1ABnQNT - AaoDUwGqAx8BLBwAA1IBqRAAAysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/0wA - AwoBDgMRARcDAAEBOAADUgGpMAADUgGpEAADKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/wMr - Af8DKwH/TAADUgH0AwAB/wM+AWwDDgETA0IBdgNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3 + AaoDUwGqAx8BLBwAA1IBqRAAAykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/0wA + AwoBDgMRARcDAAEBOAADUgGpMAADUgGpEAADKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/wMp + Af8DKQH/TAADUgH0AwAB/wM+AWwDDgETA0IBdgNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3 A0MBdwNCAXYDFAEbBAADUgGpAyIBMgNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNS - AakDIgEyA1IBqRAAAysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/08AAf4DAAH/ + AakDIgEyA1IBqRAAAykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/08AAf4DAAH/ A0MBdwMeASsDVwHFA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1gBxgMmATkEAANS - AakDNAFVAzQBVSAAAzQBVQM0AVUDUgGpEAADKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/wMr - Af8DKwH/TAADMwFTAzwBZwMUARw4AANSAakDNAFVAzQBVQNGAYADUgGpA1IBqQNSAakDUgGpA1IBqQNS - AakDRQF/AzQBVQM0AVUDUgGpEAADKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/ + AakDNAFVAzQBVSAAAzQBVQM0AVUDUgGpEAADKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/wMp + Af8DKQH/TAADMwFTAzwBZwMUARw4AANSAakDNAFVAzQBVQNGAYADUgGpA1IBqQNSAakDUgGpA1IBqQNS + AakDRQF/AzQBVQM0AVUDUgGpEAADKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/ TAADMwFTAzwBZwMUARw4AANSAakDNAFVAzQBVQM/AW4DMgFQEAADJwE7A0QBfAM0AVUDNAFVA1IBqRAA - AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/wMrAf8DKwH/AysB/08AAf4DAAH/A0MBdwMfASwDVwHF + AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/wMpAf8DKQH/AykB/08AAf4DAAH/A0MBdwMfASwDVwHF A1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1gBxgMmATkEAANSAakDNAFVAzQBVQMF - AQcDVQG1AxEBFwNSAakDKQE+BAADUAGfAxEBFwM0AVUDNAFVA1IBqRAAAysB/wMrAf8DKwH/AysB/wMr - Af8DKwH/AysB/wMrAf8DKwH/AysB/0wAA1IB9AMAAf8DPgFsAw4BEwNCAXUDQwF3A0MBdwNDAXcDQwF3 + AQcDVQG1AxEBFwNSAakDKQE+BAADUAGfAxEBFwM0AVUDNAFVA1IBqRAAAykB/wMpAf8DKQH/AykB/wMp + Af8DKQH/AykB/wMpAf8DKQH/AykB/0wAA1IB9AMAAf8DPgFsAw4BEwNCAXUDQwF3A0MBdwNDAXcDQwF3 A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3AxQBGwQAA1IBqQM0AVUDNAFVBAADPAFoA1YBvgMjATQDVQG1 - AxIBGQNRAaAEAAM0AVUDNAFVA1IBqRAAAysB/wMrAf8DKwH/AysB/wMrAf8DKwH/Ay8B/wM0Af8DNAH/ + AxIBGQNRAaAEAAM0AVUDNAFVA1IBqRAAAykB/wMpAf8DKQH/AykB/wMpAf8DKQH/Ay0B/wMyAf8DMgH/ A1wB30wAAwoBDgMRARcDAAEBOAADUgGpAzQBVQM0AVUDAAEBAy0BRgMKAQ4EAAM5AV8DXAHOAygBPAQA - AzQBVQM0AVUDUgGpEAADKwH/A4IB/wNKAf8DNAH/AysB/wMrAf8DPgH/A0UB/wNcAd8DFwEgTAADUQGi + AzQBVQM0AVUDUgGpEAADKQH/A4IB/wNIAf8DMgH/AykB/wMpAf8DPAH/A0MB/wNcAd8DFwEgTAADUQGi A1YBtgMqAUAEAAMQARUDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEAEWCAADUgGp - AzQBVQM0AVUDMwFTA1IBpgNKAYwHAAEBA0cBgwgAAzQBVQM0AVUDUgGpEAADKwH/A5kB/wOFAf8DVwH/ - AysB/wMrAf8DPgH/A1wB3wMXASBTAAH/AwAB/wNDAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ + AzQBVQM0AVUDMwFTA1IBpgNKAYwHAAEBA0cBgwgAAzQBVQM0AVUDUgGpEAADKQH/A5kB/wOFAf8DVQH/ + AykB/wMpAf8DPAH/A1wB3wMXASBTAAH/AwAB/wNDAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ AwAB/wMAAf8DAAH/AwAB/wMAAf8DMgFRBAADUgGpAzQBVQM0AVUDEQEXA1ABngMkATYUAAM0AVUDNAFV - A1IBqRAAA1AB+wM2Af8DNgH/AzYB/wMrAf8DKwH/A1wB3wMXASBUAANVAbQDWQHHAy8BSQMAAQEDGwEm + A1IBqRAAA1AB+wM0Af8DNAH/AzQB/wMpAf8DKQH/A1wB3wMXASBUAANVAbQDWQHHAy8BSQMAAQEDGwEm AxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMCAQMEAANSAakDIgEyA1IBqQNS AakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQMiATIDUgGpEAADIAEuAykBPwMpAT8DKQE/ AykBPwMpAT8DEQEXnAADUAGjA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNS @@ -183,6 +177,15 @@ Af8BgQERAeABBwIAARABAQGBATEB4AEPBAABgQHxAeABHwQAAYABAQHgAT8CAAL/AYABAQL/AgAL + + 291, 17 + + + 649, 17 + + + 551, 17 + diff --git a/PrusaSL1Viewer/FrmMutation.Designer.cs b/PrusaSL1Viewer/FrmMutation.Designer.cs new file mode 100644 index 00000000..80776ecd --- /dev/null +++ b/PrusaSL1Viewer/FrmMutation.Designer.cs @@ -0,0 +1,380 @@ +namespace PrusaSL1Viewer +{ + partial class FrmMutation + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMutation)); + this.lbDescription = new System.Windows.Forms.Label(); + this.lbIterationsStart = new System.Windows.Forms.Label(); + this.numIterationsStart = 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.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.lbIterationsStop = new System.Windows.Forms.Label(); + 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 PrusaSL1Viewer.Controls.SplitButton(); + ((System.ComponentModel.ISupportInitialize)(this.numIterationsStart)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).BeginInit(); + this.cmLayerRange.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbInfo)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmIterationsEnd)).BeginInit(); + this.SuspendLayout(); + // + // lbDescription + // + this.lbDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + 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(13, 190); + this.lbIterationsStart.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.lbIterationsStart.Name = "lbIterationsStart"; + this.lbIterationsStart.Size = new System.Drawing.Size(80, 20); + this.lbIterationsStart.TabIndex = 3; + this.lbIterationsStart.Text = "Iterations:"; + this.toolTip.SetToolTip(this.lbIterationsStart, resources.GetString("lbIterationsStart.ToolTip")); + // + // numIterationsStart + // + this.numIterationsStart.Location = new System.Drawing.Point(132, 187); + this.numIterationsStart.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.numIterationsStart.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numIterationsStart.Name = "numIterationsStart"; + this.numIterationsStart.Size = new System.Drawing.Size(149, 26); + this.numIterationsStart.TabIndex = 3; + this.numIterationsStart.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(132, 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(328, 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(289, 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::PrusaSL1Viewer.Properties.Resources.Cancel_24x24; + this.btnCancel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnCancel.Location = new System.Drawing.Point(447, 230); + 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::PrusaSL1Viewer.Properties.Resources.eye_24x24; + this.btnPreview.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnPreview.Location = new System.Drawing.Point(131, 230); + 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; + // + // 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.Location = new System.Drawing.Point(604, 14); + this.pbInfo.Name = "pbInfo"; + this.pbInfo.Size = new System.Drawing.Size(311, 264); + 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::PrusaSL1Viewer.Properties.Resources.Ok_24x24; + this.btnMutate.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnMutate.Location = new System.Drawing.Point(289, 230); + 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); + // + // lbIterationsStop + // + this.lbIterationsStop.AutoSize = true; + this.lbIterationsStop.Enabled = false; + this.lbIterationsStop.Location = new System.Drawing.Point(289, 190); + this.lbIterationsStop.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.lbIterationsStop.Name = "lbIterationsStop"; + this.lbIterationsStop.Size = new System.Drawing.Size(31, 20); + this.lbIterationsStop.TabIndex = 13; + this.lbIterationsStop.Text = "To:"; + // + // nmIterationsEnd + // + this.nmIterationsEnd.Enabled = false; + this.nmIterationsEnd.Location = new System.Drawing.Point(328, 187); + this.nmIterationsEnd.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.nmIterationsEnd.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.nmIterationsEnd.Name = "nmIterationsEnd"; + this.nmIterationsEnd.Size = new System.Drawing.Size(149, 26); + this.nmIterationsEnd.TabIndex = 14; + this.nmIterationsEnd.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // cbIterationsFade + // + this.cbIterationsFade.AutoSize = true; + this.cbIterationsFade.Location = new System.Drawing.Point(484, 188); + this.cbIterationsFade.Name = "cbIterationsFade"; + this.cbIterationsFade.Size = new System.Drawing.Size(108, 24); + this.cbIterationsFade.TabIndex = 15; + this.cbIterationsFade.Text = "Fade in/out"; + this.cbIterationsFade.UseVisualStyleBackColor = true; + this.cbIterationsFade.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // 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"; + // + // 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.Controls.Add(this.cbIterationsFade); + this.Controls.Add(this.nmIterationsEnd); + this.Controls.Add(this.lbIterationsStop); + 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.numIterationsStart); + 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 = "FrmMutation"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.Text = "Form1"; + this.TopMost = true; + ((System.ComponentModel.ISupportInitialize)(this.numIterationsStart)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeStart)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmLayerRangeEnd)).EndInit(); + this.cmLayerRange.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pbInfo)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nmIterationsEnd)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lbDescription; + private System.Windows.Forms.Label lbIterationsStart; + private System.Windows.Forms.NumericUpDown numIterationsStart; + 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.Label lbIterationsStop; + private System.Windows.Forms.NumericUpDown nmIterationsEnd; + private System.Windows.Forms.CheckBox cbIterationsFade; + private System.Windows.Forms.ToolTip toolTip; + } +} \ No newline at end of file diff --git a/PrusaSL1Viewer/FrmMutation.cs b/PrusaSL1Viewer/FrmMutation.cs new file mode 100644 index 00000000..bbadb3b1 --- /dev/null +++ b/PrusaSL1Viewer/FrmMutation.cs @@ -0,0 +1,211 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * 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; + +namespace PrusaSL1Viewer +{ + public partial class FrmMutation : 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 uint Iterations + { + get => (uint) numIterationsStart.Value; + set => numIterationsStart.Value = value; + } + + public uint IterationsEnd + { + get => (uint)nmIterationsEnd.Value; + set => nmIterationsEnd.Value = value; + } + + public bool IterationsFade + { + get => cbIterationsFade.Checked; + set => cbIterationsFade.Checked = value; + } + #endregion + + #region Constructors + public FrmMutation(Mutation mutation, uint defaultIterations = 1) + { + InitializeComponent(); + Mutation = mutation; + DialogResult = DialogResult.Cancel; + + if (defaultIterations == 0 || mutation.Mutate == Mutation.Mutates.PyrDownUp) + { + lbIterationsStart.Enabled = + numIterationsStart.Enabled = + lbIterationsStop.Enabled = + nmIterationsEnd.Enabled = + cbIterationsFade.Enabled = + false; + } + else + { + Iterations = defaultIterations; + numIterationsStart.Select(); + } + + Text = $"Mutate: {mutation.Mutate}"; + lbDescription.Text = Mutation.Description; + + if (ReferenceEquals(mutation.Image, null)) + { + Width = pbInfo.Location.X+25; + } + else + { + pbInfo.Image = mutation.Image; + pbInfo.Visible = true; + } + + nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount-1; + + } + #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, 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; + if (Iterations <= 0) // Should never happen! + { + DialogResult = DialogResult.Cancel; + } + Close(); + } + + return; + } + + if (ReferenceEquals(sender, btnCancel)) + { + DialogResult = DialogResult.Cancel; + return; + } + } + + private void CheckedChanged(object sender, EventArgs e) + { + if (ReferenceEquals(sender, cbIterationsFade)) + { + lbIterationsStop.Enabled = + nmIterationsEnd.Enabled = + cbIterationsFade.Checked; + + return; + } + } + #endregion + + + } +} diff --git a/PrusaSL1Viewer/ImageBox.resx b/PrusaSL1Viewer/FrmMutation.resx similarity index 83% rename from PrusaSL1Viewer/ImageBox.resx rename to PrusaSL1Viewer/FrmMutation.resx index 1af7de15..40776f48 100644 --- a/PrusaSL1Viewer/ImageBox.resx +++ b/PrusaSL1Viewer/FrmMutation.resx @@ -117,4 +117,20 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 148, 17 + + + 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! + + + 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". + + + 17, 17 + \ No newline at end of file diff --git a/PrusaSL1Viewer/ImageBox.Designer.cs b/PrusaSL1Viewer/ImageBox.Designer.cs deleted file mode 100644 index 9e71e8e4..00000000 --- a/PrusaSL1Viewer/ImageBox.Designer.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace PrusaSL1Viewer -{ - partial class ImageBox - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.SuspendLayout(); - // - // ImageBox - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.Black; - this.Name = "ImageBox"; - this.Size = new System.Drawing.Size(393, 251); - this.ResumeLayout(false); - - } - - #endregion - } -} diff --git a/PrusaSL1Viewer/ImageBox.cs b/PrusaSL1Viewer/ImageBox.cs deleted file mode 100644 index 985669b5..00000000 --- a/PrusaSL1Viewer/ImageBox.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; - -namespace PrusaSL1Viewer -{ - public partial class ImageBox : UserControl - { - private static SolidBrush Brush { get; } = new SolidBrush(System.Drawing.Color.White); - public Image Image { get; private set; } - - public ImageBox() - { - SetStyle(ControlStyles.UserPaint, true); - SetStyle(ControlStyles.AllPaintingInWmPaint, true); - SetStyle(ControlStyles.OptimizedDoubleBuffer, true); - SetStyle(ControlStyles.ResizeRedraw, true); - - UpdateStyles(); - InitializeComponent(); - - } - - protected override void OnLoad(EventArgs e) - { - base.OnLoad(e); - } - - protected override void OnPaint(PaintEventArgs e) - { - base.OnPaint(e); - if (ReferenceEquals(Image, null)) return; - - var newImage = Image.Clone(); - - newImage.Mutate(x => x.Resize(Width, Height)); - - for (int y = 0; y < newImage.Height; y++) - { - var span = newImage.GetPixelRowSpan(y); - for (int x = 0; x < newImage.Width; x++) - { - if (span[x].PackedValue > 125) - e.Graphics.FillRectangle(Brush, x, y, 1, 1); - } - } - } - - public void SetImage(Image image) - { - Image = image; - - } - } -} diff --git a/PrusaSL1Viewer/Images/Back-16x16.png b/PrusaSL1Viewer/Images/Back-16x16.png index 1968f0d01b25faa36b2a3a41c2fe66ff5f44cdf6..c28c6216a9b191202258ac7ecec22ae5d1b1d909 100644 GIT binary patch delta 120 zcmV-;0Ehp&0g3^T8F2&v006c6H|hWY08vRqK~#7FV;~JMG8E&Np2_f^ko14N(qJeK zhwNz581N&5JE}A$+zV0A2<2kJ;}8XHgcL9_EWm9ATnSD`B9vhFCZ-ZJfT@H5zmjqW aQUL(F1zJJQkduS}0000=) delta 169 zcmV;a09OBs0lEQ@8Gi-<001BJ|6u?C0D(zFK~#9!V`QKZFcOd}0^(kB3;>DG0OB+P zmSB}c)=bEi7?S9kK|lhFz7IhB6Wsu8nsI?oKpY0dI~mE)3C z0I?;^fHokmq{ILwAf5-r@#K1eR6{TV5uYJMMBkC_y*n zG%O3R!?x@;Y)fy!Johqmthn{Dr;tRR#)7Nw!ZqO-93%EaTXz_! zmgDuVQ?yK4c7JfyT}on<+HfBa-hUy;%j1D%H{lq*57s_gk*0N=9iIVhHN94w{#Ziv<9Yji;&?+JeQwx4%yO;&Qr$bqXgT) z9qgg7MqSp4#p}d9uZFfpA0bU^JHSbhLtG*NO`H#9(vp{^#tTZFP6O?Lo&ZC?X%ib~Pwt!?YxVAT9D%6j^G!-qzhcdpVbx=1jS} z)(^vc%>U0f^UwDUg8yR=7&9BWyzM1m$<6_U06bGu`0MZ>1b-Ip()_E$Vw8Y0k;&Yl z-F>8H&5kmpGZ}&7wE%>G5{ZK34?^_AAd!b2^pL>Z30l99NMPY?1p~&~^9827T+s3w zAc{f<1|lmA108Zi1Yu?tLVY(UuxFx#?(;GNlwxzI*SD3M3N`^?1&~GqNXtXz#tg>Z z_hlZGpa8NjKz|8k2>+Y`e{ahR67cL(32ID^W@koa72S*h@jM`ogRN!*xax`+K~484 ze4G;iiy}m)J%DLT!pIvCUf!xj$YgV^Yra>lN!HV=aIvORcn8V%i&Dz#aoT}K zghh$H_(~XcS{OZB#&A)4KLkZNmLs$_GDRQr-D8YWDvsjRiUy=!DKXOYJbb!P$?%re z=irM-@gzMcO4|s%? z9MW3WyML@rx2qX}6fa6m(!oSa9mDoZ-LM=MV>wLyATRmB|MXf9lQHX9tCL@Ar#k!N z1j#!1eEkr^o6mK@awtxq1cD$=k3+DZ%BcECYtC_JHMH%;BBsfZ+9c?y8z*nnvkm#D z??XgVVlv`TkSfsb#{ORwD^|AZHf$S6bDXggg?IzC9iSG@%}8R&Z;RnS{-AG!BOwS5 zb&kv4$4QYPf4E10TNzTzw_(F;@>~PS_#VW`A`4=002ovPDHLkV1iC_bSD4+ diff --git a/PrusaSL1Viewer/Images/CNCMachine-16x16.png b/PrusaSL1Viewer/Images/CNCMachine-16x16.png index dbafe4d95eb37d3afdeb5432138e37458a9a62a2..e2a5e4b377be126befa3deefddb022960e8f8a13 100644 GIT binary patch delta 244 zcmVb?(t_;@hpKv!Ss#i0?> zM&0^!V%@4Exu!IGati>q{g{$;uZc$ua4Ot^Nw4Ohuz^fhTW#CBPz+W_Sc0&E%#D_o zXCWV~iwb16kl6v3!W)>az=Pv@aIP~1Hifektm&Jn0G3UsVBCk@A%GOn@}%%BOYTc( u0P{-m=Uo94djEjZBJ2xM_v5+-^nL--4}!`UVw&*)0000CkGn5hZ(J^Q@u8=@F(CJr&z5vz|Of>Kf?`} zz!5eO4+jYR0;uiU!fI7TjS@*#WaO+Qi)uxW7%PU>mVwnJ&)2w@t^aE^S z8a3YkD}hNrpaIWlsUW~s8u0_>bsCjc!Vj>2<9HPTZ{MvSQ`Vd6_%Z+h002ovPDHLk FV1mD|qKyCm diff --git a/PrusaSL1Viewer/Images/Cancel-24x24.png b/PrusaSL1Viewer/Images/Cancel-24x24.png index b5a69201c380e1474e36ba258a1c7c6d9a083121..74e45594c5af144310f841b43b70e6c43ce83273 100644 GIT binary patch delta 498 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 diff --git a/PrusaSL1Viewer/Images/DataList-16x16.png b/PrusaSL1Viewer/Images/DataList-16x16.png index b0e24de3ef502ea4bb8f3e3769dde06611169df2..a4e784cdcbdcdde39c457c91decc170e5f3175a8 100644 GIT binary patch delta 162 zcmV;T0A2sq0kZ*+8Gi%-006c6H|hWY0D4J8K~#9!g^{%tLO~D!=N>uk5aSKtq=Y<* zKvVAep#~luz%@jS+xMMG*B6-smMMxFb^ONQ_Ruim7U&H29GL()3O@4yaSA9RxNu`j zh8+gK6}WQ4(BXvjd8P|<7F3Bq2>7;Whqd?*sqv4fsfcTehZ_=4Ek8@*4)m2!3{^vb QFaQ7m07*qoM6N<$f|?IQ;s5{u delta 197 zcmV;$06PD(0oDPK8Gi-<001BJ|6u?C0G&xhK~#9!V`QKZFaq%wAQlGVCLrDc#Hvtn zV!$1c!v9cC1rQ$x;)5hOAP8i@A|Mt4;w~UQ0K}p|%tVA{kj1Y+2JitfCy0aO8j`}` z3lMVyaV`)q2jV0mT>t`0KnDDS8UzZ1tw21J1TPeWGzLS%06wJo2{~S%*Z^cNfYQV) zQoVp4h{+7ZB_xmmOQ{l#6elE#lQPAbi6Q_1-tsJA_=bhH00000NkvXXu0mjf!B0j^ diff --git a/PrusaSL1Viewer/Images/Donate-16x16.png b/PrusaSL1Viewer/Images/Donate-16x16.png index 20d8f08fdf2766f367a3bcda28f4c8d04cb27613..8d9d6f1d8e78fdf6e5c66fd0e5e46054dec91f7e 100644 GIT binary patch delta 522 zcmV+l0`>iY2ABkp8Gi!+001a04^sdD0OU|iR7C&)08@F&ReaA25F12erA=_VL0_H= z5gk-|%t2qDA1zBnW2RMo&qHFP3J)1TU7Q~-O&%;tRC>!*e9u;V&mb>PReaD@ea}{X z&rNZ>KwX>* zYmL=|pWB0<+w7&k=B2l+LWx|gP`1!tKf#B+>ol@sJrEGk=K>2;EJW)dYIWI zzHjmX001F$Qh!cU0NMEon!%R|*_SYy{hA4vFfiHu`7r(Y`N5Z({hGo3muGkBUH||9 z!bwCyRCwAw%mac1K@Y4QcT3pXkYkyXd;mWe++P3xFvQ{i3%YzX1 z?sVGOLL7L8K3!+L-Mq=ocI>#!BI9SgTeQDv?fr}{F8z$9oc_N|<;j-I)$26N{og%C0pQKaI*cb?o6R`i4w0I4`^ zHVt*JEeCUFCslIaNFKmgi#B!}7PPg+kz0(lu_#9%wttZuyET_gXY)!rfeb(_qBuSr z1>n!cm+XxOn0x2~aP;FI>aW_29^UF#UToqvG{SK*O1$w|+ zxOHcZ(cvgHx5Wps;OpmGP+GUjjtU-fJ&;*n~8@t0`wX#rDOLu3d zQUjwCv51l#2EWa(lTLNf71%Q5X3JoV<>W~GH3LtZrMt6J>fd|6ln#D&etLiJ@rxbm zr*a95v6P=}0Fe2p8!5%E0IaPnPA|{@R1yH;SZ!Y@KR$Ca9PNESE4wdl7iY##d+QZ{ zXKgsv7dkO^XZ56qtfiu^1{!%;`|@`aUq^yQ$DQ#0000jV{(t@W_w z%kR(kU+4~R{V@L(#+nd)Ht<~XSNw}2|;Bxi_zpQ+cZ`0-Kkwd0!>Y z?JQKXfBSTC`G1e^x+Z!2P-}gmH$nK`k~h1gKb$Oh`~Q7CtEBm+*BV@T9wmQ8?gUyL zlP|Ble!64#v45NoCMWD*`n~=zC%^By<}USBo6R40?yP6o?QZyR<&z%MoQ%K9H%z-& zXLsd_sy+E9_(tp~>y)MSEcMo|h7BTfI<*u$-^w543;YuB;hW$axuc9)&eN3w_Nmrs zx_EBrco1>_li_Uljd^RnB;B36cKi4JTV28*b6h)X`pDOP;ikR5y~}DN)S_C`BpeIP zkLYy?Z@qjrtvQIbk})iB&iD8OIbp2Ao7osDHrt)KyW!P2rpOPQ1Ixu)b+&icUtAD! zW1sPjlJuE*m0>m$a(@{p`k!mKnIY2k&Umt;rkc%@mm5u8CkJYLNKQ78Y~`w78>H*D za3=Rb^P?#uO3nofRC+2_1u0rwn9Dos*n0|adf37Kug@5_{$dJ1XF&mb? za$l&s>t=1JdqAmw(YKkdm*zGd*?j)otWWhiXPPgB2&(w}nYXa_(GpvBt^}VN7ER^( zlBpu;1y}YPYX3I)*Tyo(Ro+prT|qTe@WFfaX3-TKo0_tu6Bb7-*x$goWs!Vq$1kA+ zr(IYgjs8zKXMIdAAy2_gF<4Vb&_uK&@WhmmMf}EFg=!_-y*}>~ZJea;rr6Z-Vqd4@ z0;75LLXIcj`A!pFB;mS$%8#esQ(6jM*#0^kxF#TyUv0&!E{5L+o6KJ;t@xL)us?~Z z-+tZm-J9F)i8r{pT=>GI@@cWa)q83hzIV8u1uvKu>fisrU}b$jciD*}%n9t>Ewaa6 z*mWqEd9+Ji+_=lU)aKFxwKvN7uB8HRCg+(Y&Nb1!r=J#lC~w|<<{Y0l(hpwVXVg2& ze#4_oZu+O|_Kl~nH%J#QoS5I1W3o@$NO9u&V`^gilua-G$Vzi$`@T%9Bz)EH7285D n^sZUEEBa!&(B0EOp#LPkq<6uTIj5ZufwGaOtDnm{r-UW|{|bRK delta 1950 zcmV;P2Vwa62B8m-8Gi-<006^2Vaosj2WUw|K~#9!?Va(J+%yozzpDVK0H*?u3NRG_ z6|hvmQ2|Q@gbHvfAXI=-0igm+1%wK~b6$r%pS_mlk!D8H?>+sKmv<}MpXK>9Gxi-S zMRO-Tfr>0u0EJTpP&icpg;S~kJ{v|m`!_d?H_{VJO-TayV1F17!#EA2S@}QxFuGy9 z9L7J=6HY-X0{CPYud#mN=k&w)au|O|Pdqjy2;ggscXbG-VZ4$)fSBYifFl=w;)IMv zkh1`2*?-IQx9*YY;~-Z7P{7v@<3pyu_YPzHkX>Mys{nq+xO8*U4dWZ>1LGz~0g%Uc zk^Xjz%=QX$6o0_)7@yfOpqS!Q=>y~>Hvw=&{ac)nkt@ha0NjD!8d(K|ISJrLj9a}a zpsnKXqz{;bTm~WWKLvi$wr>lvg%l8)$P-u+fF|3wMF%6c(24*g_xnR>VIWUnMF1LY z-xdxAY=5Bz0i-DNip2@a%g3|}AjW=whjAZa?$>F5fqeXl@we3H3A77<)Ao^rpbNYe zos-+>!1u_Z`Kz^sngzgF=G9?;RLXM{4=Gf=_zne8qEGc+n~V zPTSWY{O;q7L0TxZg<1u`)!ozK_=XJEqd;X>k$*-3aF%&-9X%hhFl1mos zBc^%%%{Zq9ifo}a0dRKrIPmSnaqdK_>MGJC0PgM{2b}^S8Yr=angqaok{$F4fOBq# z&?0~s*}fip)j3=-z%?xt*g`D=h*jprb$tIum|G78W0C?$(cR;4Jlf_;O5H-Nt4LA+ zDayP!b^~L+b!@^x$QDWoAZ2$C#TQ4Ou`wLL5+Yqi5(1#WkCy%>(eJegcLFJ!PN;i#2&yQECB5boV%f2UsZ_z?=>V zZDC3QNOt#x9%l*%utbYQd4iMzkUE(}gRo^al>?ZQtb8n$0HnKnTI|20B;G!H%?Sy* zic$zb!`r;h*dJX>H>4)X6QmG;hL<{Y*dJJFm^b}?R9hHZ0Mg6ogu{L(pyho84Syoq z!q@_kuu)vcs--18YFANA0Z2bX=QP-NC&efO3#COQTNqOS+TP~X!v7>v;QCH_!dLW& zR6Z6<02*H6Jm(DmfJ)oyMMUW;iXi|Ewr`0&4H?q=7E462g)sz>^4mRoaPW5m8Z6)v z>|I6N0?=anme{kss>!{~X~1X;xqk(q#X225Ud_khz*s)UDFDqcah_=4clT(rfJ?BI zk8uh>o9$bog`X9a$^!b*gUJ?h2|#PmG{@)8(fBcnCC*^T6L1JXtLGrhqTb?vM{s``By8&|TZqmxEmqoZx8-eFb1?zkg0>%eCcT*E>((D*(&3 zuSIxCwdI)S3=doABLK~1UR!W9RakaC4K`Lj9|2g~@4rUd2P0DBu#qR&5`g6;P~!(9 zBxrHt5x6A)3uRtwIOu&{d`f!UC?C5e0FB)}dvK@%m{{#9S`&a}+kZFVPz5ltY75r{ zptZYa4?XxADlI<>ClYY=%3z+lld@KpT`f_(o2R$E-)PTe6u{alih3=lc z99ac&y89=d^hV4Dki)ZX4qd<&`^%*$5O%Pe{amBRRcv%E0L$6FEl32UeBXo+ZGY2B znA^plIN_2lycR%?cYpsiWQ88EohGFlfg)zh7I=#umsMaAfaNXUkb{4HIo|0#KyZNrC86MNkRZuo79!hOQNbQa=2Qd`h88r^9$XpVdQbHHMH7=y}mz zMqL$bKzF;l42tVk3t{%YAcEXN-7nA$`Frp3x71$`uPCDmpm3@H3a1L7aH;?brwX8O kssIY73ZQVR02d19KL>$;Ehvhri~s-t07*qoM6N<$g4Lpf4FCWD diff --git a/PrusaSL1Viewer/Images/Exit-16x16.png b/PrusaSL1Viewer/Images/Exit-16x16.png index a111b846242d5486b6e3087cc53fcc3b50dc5205..863566c50a43bf5844ea246dfbcc918a54b7a865 100644 GIT binary patch delta 157 zcmV;O0Al~<0j>d%8Gi%-006c6H|hWY0Ch=3K~#7FV*rD8hMx@o(cn*@C=|#r{9{OE zut$TbKv5Zp0(GEzaRziC4ir_#rGN>)0tJSL40=Gi4pRYw|B=BB#ziOyX1K?29|)g- zeesJS1zkZonn(XJv@$RfR6xKAk{pQu@^Ehw4k*GwO*pa$Miw^!(g|Exog{{z00000 LNkvXXu0mjf4hA^z delta 213 zcmV;`04o2k0p}00dXaW z!w40W0pdqMoDRgd2pFIS#4~|d4v3$?3{VH+8$c`p#4iaLAP&SYfLH^FZ<1mF6A=F+ z*8l||J_y9VKzs>^>wtJADF(pgKLK$l5buIX;4&Z>h`W*GSx$ji8p{3+#92T*2cH4u zK-_^RApbK!qP>P@22kt;iUScH$OG{qN}>@2C`w4k0ILBMXC?*)GP5%P8F)$)@}$we P00000NkvXXu0mjflQ2t_ diff --git a/PrusaSL1Viewer/Images/Extract-object-16x16.png b/PrusaSL1Viewer/Images/Extract-object-16x16.png index 1283fc3be4792d8b962cbf245fc09bfec4c294bb..9bdb1d24b8956c31e86c82acf6a74232e3e6f39e 100644 GIT binary patch delta 464 zcmV;>0Wbcl1nL8jB!96=ZQHhOt!+#3+O}=mwryLr zHMaibiym8>-<|$L$Xb!~vyQ005Fw0iy&d62k19396+abcb06bix zz&gUV<$1+DuLJVCcasdoj`0k|P7o#7JPY16KZ95854ceH~|Kk z@UiL*Ja4m{bs*nyYDj#Q)Tmub2DgG7&5hGabepWSzBLY*}h{Ng-|np=62cl zN5)TKe14|=d|&iBnC z(9@5AUpHi`b$@_XxDniLxJYxS?h06XIZ&_95oRfJE&XZo?Z7KoFAuZ=OyEQ2dm7ac zT?jPDqFqasYh}N{?sbHA!rul+{M#gvgujj8@gc>EaHf9K<}$wMrzG_5+1((V$=@(M zh+DK2O`{nJR2e+7J4Kk~s`VD<;Z~JWBVmSHbvzTdt4TEQnKi;_Gw#Bwm6cT@jfJJT zO2X{Uz893hFZq#?KPu`Ye^xYzg7-88e=CZ6dGtH$IBx(JWQ9Q|;v2UB0000MGaf2=w4aHI*@2M8->g3wJ_x)7;#UlBL>}Kcp|I`P%>{Sc821<6e+M*25TEAP zVh)~P9w*oijD^R~fMSwZ z>}B}J^p|0m#eZUkvzoiXB8>l-863}qGgw~s`DWK6%MBLWop<{g6C*Q*0dM)AGhEQz z&+tg{I+!o{T8Y8>^(3(W4=qHE`KmN&j+%JO3FZRZ~NsnsSTU5 zPk{|MQugE&BLgGBgoFleT6alnfDPDR_~0GTT0v5D{|DwN$9@H7umPJgF7D@K;dUU! zfZzXqp7WZfZ45TRLn}ls!K`Q!2MebfFa+?20nqAS|9;(DeSTKK>hp8K*%<&7uCn0! Ts;Gbf015yANkvXXu0mjf#)}A^ diff --git a/PrusaSL1Viewer/Images/File-Close-16x16.png b/PrusaSL1Viewer/Images/File-Close-16x16.png index 91440923bea9c0e875a8e0ba029beb773fb69dd9..ef36711b8c1ef14aa00cc1a68c75a5a1ad5d3287 100644 GIT binary patch delta 230 zcmVeUwg5)nj|>9i*q(v_)j gy&M#ouq-B-Q!>a<GVsHqHVsID+ zhA~u_hzj<>n&8T2H5o*!!(g!(mc(K*7%YOK(LW#)94rVb7O~hw=DrW_b1+|=yvzqa zaL3*AySw+EHxiK)_A!A-e%1vFc$E&N4Oe(a1z&B~=CFmVIlvyS;_NWiSPDILU-HS7I4 z>T8iLM#W#yB8E@Y-GU7(o luWNBTcG-dwxYa*^`xex?OYUV8p)3FZ002ovPDHLkV1kNInzaA` diff --git a/PrusaSL1Viewer/Images/File-Refresh-16x16.png b/PrusaSL1Viewer/Images/File-Refresh-16x16.png index 8407ab3451d42ea61635af8a948eedeea3335bb6..39d6920d60123ff26b325154d40172c4d2a84927 100644 GIT binary patch delta 179 zcmV;k08Ias0>lB38Gi%-006c6H|hWY0E;50))a%PJ5^$^q?Aak z$6yJl9cZ+nf{O^S>{x{eEV%M$Fal%FOgbb22iojv!SM3|04!Ea{RhUKsY9!K^}vi$ h^8N+pUC9&%;0ao_DuWCf4tM|n002ovPDHLkV1iq)O%VV9 delta 259 zcmV+e0sQ{N0h9ue8Gi-<001BJ|6u?C0NY7KK~#9!)ziTW0YMzc@mWV#c>-@BJb()~ zBAkeXxX4LT@&uyf#z8sA6F7PRa&(kEI&zQ$zSEA{R=6q=6VtFS&-3MDxJ54t$W1uuq+IT5s<_m}_x002ov JPDHLkV1hbFZ0rC4 diff --git a/PrusaSL1Viewer/Images/GCode-16x16.png b/PrusaSL1Viewer/Images/GCode-16x16.png index c33c4a35a9ebb5abc295ae163ad527f45e160bff..127cecc7a871267105f4fd646416f3dcbcdb4d04 100644 GIT binary patch delta 133 zcmV;00DAwD0+#`h8GZx+006c6H|hWY0A5K%K~#7FV;~af=^5C=pqe-q1p&XK{)3=D z5GLI>Q@~K*|9|HH*8kNI1^+VgABqm)vf=k4Z2*4ler*V+Y;Q0)qmO8Gi%-006c6H|hWY0Ln>3K~#9!b)rz(6g>-edDHecSx_{ z5wBF-CE=2BC*v+1OL#*PiA>|8K0SZn-kA}mS1+;EXm+kf47pk{p;N9X0!H1yv{dr~ z!hAIA9%vIU$)=Bjytd*AAWMa}((HK+@Ytd^0N&{k=d&!^9&5u5^AZ4X)0FRi`yt1S z8#i%NgDHdZd~(y3TX-p7ojbuNo=8$}!nh-|Mif}`INFo9tf{i@%)!$26u@x(d`P7W$`Rjcmm z<|4F%F5(9WwjxCwMQ|us9E4KDMJI6)-IStON=3w}c5~B7a1nGWhz053$N%67L`l;0 z;71_bJ$duqooxk=13lAz6YPM+8FV0teQdW9uz+D~pnx~r;eRAdz&KJ^#1AfTh!yPM zHYi{aIZUIWcX@?$B8w$Fcm;Ih2y>{p-p?b7bM&bf6L@t8m}Z?~70>^w>c_Hr@qr<% z=~wHvLW)V>R;H q3VD>BVJ_3Bp1W3ym&qATuk$Zh8b}k~jU==H0000YN zyKPHJDy{O^zj<~?;y+S);mZ|XL^(lH`Bep5V}5AAfHlNVvD+B6HVVh#tQOr=Qz{jv!o^*&rYRp3x8Q7=eIm{r3E1U`D`bH zuWVN~vFkxq7US%~%6I|?Sn_4Q@B9Qa^$EE_pXWZDVr-!H?WmmE=T{IJAhE+?Hx-p| z#I~D?P!dguSOEkB1Z9(;JIygQ^*CNPS?_DYkzaCFPmYhp6WQ+fUX#`wb;ssFaem7_ z+iwuH8wxpObAJJSOD+LbCY2syX6iFk)uVUnYX)Y1AS^cV;)kEn*Sv>ky1{ZeQM3QW zIeFo&35T#X6)&KYL1NUNhg2JCa3zawA<3L_f=V$5)t|z*oo)0Fc1WJR$`-iZ9?Rp+ zm`gV41(T7C$<7IlO1Fo&W?*DqrFHN==B-7Htj_l5AAiFuA2c&PGYXQlhww~uRZgrO z$#$vE4dIwJ_qFsfm}=$AftTo+`kqKYr*UmPcfbB2nyTVt8euLUPgYhbuDL)wF^fNI z@WiLRXz>toI6z=y1HEaD%ED=MIn3KXzKt$TF*LRs#}p`jA>nvF!nN$d$<#bu1FteU zl=|HVW`B6UeThqVKbXNWxaZAhFbtFN;Q-m$D3ZN^&|~BluNf3B{#(u87m*%YP0TS_ zqd;XyFwr|o-8qlq%nR1U*JIfZ^I03u%z^}owbiUyAAds$=NI2T*5{w4%BGk%h8P(h z!^g+~sG`rYoOp(S97CzkX~qeTp&KCyF$Ka41MD zuTBJ0%g2obS-vXbX}WSp?3d>&4==X>{zvBv-)ODyJaLj`dAs_sQrBdFAtdQdAvyP4 fy+>K|Kkt7AQOtUisI8N}00000NkvXXu0mjftSO^F delta 941 zcmV;e15*6#2EzxCB!7xYL_t(|+Fg@vY*S?v$N%@<_O`d}+EUuB-PY1|w2XGcZNNYm z_Q91wG7}Usj1l%hLvX~P68vI9oP1eg3=BzzfExV3muZ4A5)o!13rGwkyll6Uv8-+_ zZP)kpb-leW-pxSJ^W;gM=Q-#6a{hVFA@D!jc>L#9QKxv9P=8Q;^3^W!0;Dn@l5)lC z^1e8G`JKRv@x-%(Z(y9}-I`Iog*v>^RwX;F70@a-mN*8tW@1Rj(#S0GVl|UJr{SI+ zW4|Bfort1jm14)3D>jZGY4=!M;21TXuRB?=E_ZljX94HF~b%47o3`HqPiD$~CL zSp~R<#>eWMihrR!oAt2TnjvaU(5V%u5%VCI)97w=;>PsXm`neLxkwmy?{;DSN&VT# zwG&4P=UeAn)K)Xw-{U4b+_l)(VnJ|OfLci*lMNx2xC5n9#9ZPY=2H)$B{$%w$vX&6 z?-DBl<0G60E}XL1%^$7vG@{vQMvun~LZt*pEJL5V4}XeYgHnZng|1>DH6{CB!^amt z!Nl(isFb@;%N2aZw!akj3Wi?PJ51QzWX7P!gs18I$d$>mb(-f-Ip${RbY$ZlY4nfl)Q#;I>cEcj6cd zxeyit&3`Corl76wD-aF+Bl&^1Z|bt?_YtgUK^runv}(NRQ6dn2gtpowRFoDBX~LNw zzQgR}I%Hxrq+%2%ufIT8cb;Tlef@@a{_i%VtNwoh42?Fs5nt|Y#o1pjU@~wGgRcx? z1W|w}2(tbuY;V_N^vDQ$ z4;@7`riaGjglEgkV&^uCZ?%zJ2QH1}65%0~vjERQ6h%lR1(_pn5gjcJ$mU8iTnUwB zJ%4mIJ36{*&z;)sIkE~E7-s3&bolCG@PWS&VS#Ez)+hr=Ql1A5+S@kZueb!W!v~jV zEnMpj6E%6he|W!-dp=CV<1GCsRve8+vWIh#AX!J}pw%$YueG5!g`pV{$W1FfP+9^yFBFDtOCXeMgqIRt{ZP7?e#U+nTuzZm}y^f_*;>h|p& P00000NkvXXu0mjfBsdsK~#7FV;~)rGce&-@SkA;ekK30DPd<2 zhr|DvO57Pf0)^lZQ^{VC06rzhfgJ3xjgW#y{8r3lV1zpow=||V5z^QJA!!DvG#*e4 clqLlL03EVgK^))n3IG5A07*qoM6N<$g62Fdo&W#< delta 181 zcmV;m080Oi0mcE48Gi-<001BJ|6u?C0F6mRK~#9!V`QKZFcP7r9EiJt_#e3j{0HKN zK%9il5Mm8rz-0)s0qj65fW?3pNNfy4U=}hQJKi3&c)DXvQ!EX25YE zwjjX(5NHSDDoPA!0^)jdy)X-iGl2L%Ie`e*j2ws{Kuk2EXf8%K02la=OEW13VAV{l j0mVSvhfOoF2H*t%-u)&K@0P)400000NkvXXu0mjfUKd1` diff --git a/PrusaSL1Viewer/Images/Ok-24x24.png b/PrusaSL1Viewer/Images/Ok-24x24.png index 1063d218433c8bb13e89aa6ed324460752b86a09..e4cc79d91282bf9182c4810b0df7120e9b78611c 100644 GIT binary patch delta 334 zcmV-U0kQt11l|IW8Gi%-002sU^>Y9K0VPR9K~#9!ozx{5)L<9~@L%0Nwt372p7qVv73f0H9qs5M%xMy-%ReB??`ee~)3{q6kZ ziBc{&R<8OaKCfDt92;+w-Q;0Fd22JW{#E?93Lm}gz2reKaerVrP$o-}hb!JBdIg!M zzfri1r5mYY8O3jccw|4exs@mdwU58_a2T8$&}*7sDqIBX5xt=mE8MjkJKY)4JK90a zZ>*j9!8!;oOtR|6A)N&$d~hBdnt5)h2l_WHz;WBL*TY%eYKoDKTNVH=1-TWo#wC>_ zK{1}npq#k9X-DaRCqW~tG<*|F@4fPI=HaUR|HeBl(5K&=Z*9UAjXgvw3b`r(fu}0D g!4bnur;B0cGnSc*GCpbdu>b%707*qoM6N<$g5HRp3jhEB delta 534 zcmV+x0_pwU0;B|x8Gi-<007{3J@^0s0qaRbK~#9!wU$jNL{SvS&s!Q4`B(@GNfAq1 zkqu?R%q)nl4aJ7+G_z(QUkeKxiG`1{z=E1)YoidWQA`%ZLis3*@jtzD>w3L=-+NO| z{hHgG^X~b$_nh+_vP%i*1HGUf)X4J}a1GAEDflvN;256Az<&&w29=^$(0=vzU%@h1 z1fO9Hbb?*bMA0M%hQWo+KtI@%)ac&YBG7d>f+RTcGr*o_WOFLgKtaxc#8aM! za4m3cJcDv@!+#rkbmDAa6--#XHbs!s9NPfnKKkpt$Vd*O7}x=$@*h|Fu|YrUNNBAQ z3_Ov0L*76IxhIRFol-) z7#RWEmQB@~FG0QDD$h-heYnRTgef9F$PZR@K+1MGFnV67#!N9=E#>(*T&wn2bL(iQ)s&(V~rRyjL z@bK|rRg4AvKDcii_tPg2f1?<{$1lL}=l3sS47j;$(R2-zFtD(3KEcV!$?)&*UxK>- z{{6dQ<lIz+vZi3CHhjuN38z3$r yt*B>cKJC}fA0lB38Gi%-006c6H|hWY0ET8Gi-<001BJ|6u?C0MJQ9K~#9!V`PAU#X!u)KpOZ3#IcM}&PpKe z1mbccHN(_~BO9;=%02|d?La&Oh)-eB915jFa2fCqh=YOn84#BMF-T1l5Z4lG0El)4 z;uApp35er?I3I}ffcOY82CN3+3?L2z;xZs^1mYB^w-SgkU~v-=uLI&FAf5!oQ=#E9 zABZb}*p83^l0f_jh&P}Go;46V0`W~k251AZCXVR42E_!!03W~^1{5cxa3VD`AnQRl yU@j2zLd8Id=L#hTpo7mqoJ`07vb{idb_M`wqd^fqePB2M00003K~#9!eat0T7*GI((KBD4yQjJJF!we$ z95N1-g!B)ml5psBEa6^hxIWzF{P|wssRlD4BCf$Yif?!I!8hK7``>lm5UTeDUu$_(?Ht)Ox$*6E5RYhZFSFxQ2@v`D%Bxy1m%Kk0EjRn sc3`8V_3p9lBm~bk2u60K63?B;C~gR5feUR3P*mxJXS&j zvzWxO_S?0v4__F?whJi018Tk5_A%hylULl-kZ#;aKraq-z=tkV0`IVZcQ3@PR%%ib zkU*0bz2GO}I~3_8)u;(fel3GE`tuEtSCc)Hb^(%hfwPza>zKo^1XSV;S7?hFAe(Fk z<8B4#=tLv#BWa53P=-snZ~-mo!3K(rw_QW66(=Y`c{sqeRZQy#l73e27aDuOb})oB zWB0?qfC*!Nk*q>?TC=f-s|tg-MF)0WL9XA}VC>PB*=DhfCye0KAN&gxazIHft#0!G O0000 z0>Z+=^32T4Y&<+XVSIdi6~BJ{YPoagPA8Ctt6|jF*FVb0$Y}NN-@k1@1H6$9(AL&o z!^+Ak{^iS;9Y8}`Kw?16jX*;hV1_Un7#REo(oEP4(9+UsW`AK}5&8D*+Y^`p=!Sp{ z_zx9-_x0=7mOp>~z}*LQ83Pj&6C*b_cM6cLk8C*15M%>L20%k9C^7&DzEElaN*FwP z^X5$|&{;q6X#mCwyQrw>Y#>t(#Q<0=2nh+v@$>WhV$=NT)2GdE-@bjMtE;;em_EF) z8UQq1TR=b{0e_nTA3uIv@aom8t9T6n#ybNW8yi;V|Ni|OjPV*ED=X^-Ov0zg$ zA}0+1U2}|4OiWB!Qc`je&=8oZ#DIT5%_m;Gco7ExJQJzV%Vk{J;s5{u07*qoM6N<$ Ef?RaCNB{r; diff --git a/PrusaSL1Viewer/Images/SaveAs-16x16.png b/PrusaSL1Viewer/Images/SaveAs-16x16.png index 33cf0078342cabd61fa6bccaa653742616807497..e22cce717d9e25e5b39983746f887ac29b9f3255 100644 GIT binary patch delta 227 zcmV<90383+0`vip8Gi%-006c6H|hWY0J}*rlo+fB`{pAO*wj0zXWjl2LK~o4o^0$&4}OBI12z`wrl@d=YaZkY-bh>Ki3^ dqeQb;908_(fZjwpBMSfk002ovPDHLkV1o4CWC;KO delta 324 zcmV-K0lWV60n`GJ8Gi-<001BJ|6u?C0UJp~K~#9!rPHxX0$~_{@lV<$2#TZ@t*t?* zQD|zDv_HVbHKn1z=FnAKoC<1asXY+Hs3nr1t>5E0xUjDHIxCGb0T;u@L`fft1I z__YRPGV=!d^9GDPu!)*O-~<7j;SPIlfwn$Ww~_Px`sx^%d91((Hqf&j-^Ldzwso)G z>Z%o}>HXU$g?)5T!qwQZclpvufi1-FgA9&vK1)F68N2#^fP@+SGyi_tX#y*Fz>a=? z#VM+?K25-i$UR2u<4qs-J<8T*YE1~p_>jahqA1{40g-AlQ{9!FvaSU@v)0wjc<4 z0ROE%7dr?1z8jDEOYDtJL2znLk8Qy^u`;!eg{b;P+MHX`6jiO9%LSn0uDPVvwjelC z3-Cf$bXD!G9ECmsywxA2w)4~%lhL?Sik@iPEyZ(107kV+uzYtt>%ByOtT-{?yF{17 W6jwq#O`9bE0000Xtx;1DgXZ4pFEEe$~_h=CL}iXcP~4!wbB2&W1nhz5ziN1qE1a=hn0 z@ByEDe17NNb8p0RR}K|qF^dcVUK|~J%8d$fiU7+MS$^`s+!*{OhP9CQpCcvC>MqPWrDt=tUe!x7guz-7% d@fl{=)IW?;F}7CR^lbnD002ovPDHLkV1gIbm1Y0{ diff --git a/PrusaSL1Viewer/Images/eye-16x16.png b/PrusaSL1Viewer/Images/eye-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..4f3c7e2dcce9a67b4c8c9be8b1d9d7e22bf53bd4 GIT binary patch literal 402 zcmV;D0d4+?P)E#x7PILGy*5Cv`Wb#WnmjzGX8 zHLO%|0UFjK(+e24u<{@MTqYMnxPV!eJX4iY6P2c~qRxMaK&9kVC7%U%onxZ~M#qoj z6-KM_DsfaONgK!SyH9C?QORBACf@tW*ZITB4|`_hO3Z@LEEh%MMGEGSgNTQoa`qyHRuMtLL$QZa(1PGWuRVEEksd4* zyx3MRO%Sq?kP?!Vgphr$N&H?&VhAagpy;6whJR-MdGpPi`QD@E{_>*E0semgjYcEm z@pubtHrqi_loB%6?RJk_tyZ8~t?s5$soYEeHk-|Zq{~omA}OPXg)c?Eqs) z%}^-x=}Z7-vw0pBzr^MngJdn}ETT>UXu)I+^v|_gZ7CX!exC{;7K8o}z6V`Fy@N0#K<`Jh@!Hg#@=z(FtU| zUazm=B(HM0+`V)<-5_yJr}HB|-mw#q6YU`O7TWoQMx#A~n*sNG?DGMrMyi%brP6Ku zxQZXCMx(J94u|)QM&mW1P`K*%`#r;icDwx zUM-PGw&8Zb{MH8`)kFN{a@iY?$43BMF84XqHsp{H3nHAx6tL+25CA7vi$o&Q5hvs; zrBHx$_-oeWxUcUEb7~pO2v)B_CakoW-)3J2JP(+S)owyluBiP$S_a9 zgmuh<4EY1O2fw+ClS5`A`MYd3>&s*^wGmBGEv3`xhBUnZup}1rz9jKFg?;xNJ~@T z{loewwa1}JzQcaP3Q0B=iG@9^4l@3Wp0zs6VK8QR@+Z_m#%0N~QU@8fPi)GQ6r=_6 z*^s{zFErRG zoJ($4610hjfiWOz2G@~UPox-vAD>|GjFDhq*vp`##Pp*03D7?bp00i_>zopr0JL{l AcK`qY literal 0 HcmV?d00001 diff --git a/PrusaSL1Viewer/Images/gui/mutation_blackhat.png b/PrusaSL1Viewer/Images/gui/mutation_blackhat.png new file mode 100644 index 0000000000000000000000000000000000000000..80f1cd088ed44c0621b92ba1ad36264ac53b1116 GIT binary patch literal 2165 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 literal 0 HcmV?d00001 diff --git a/PrusaSL1Viewer/Images/gui/mutation_dilation.png b/PrusaSL1Viewer/Images/gui/mutation_dilation.png new file mode 100644 index 0000000000000000000000000000000000000000..92e1952403488721da471407937c578754b2022c GIT binary patch literal 1083 zcmV-B1jPG^P)0Dyo1FfafhAOQdW0PyetaBu)XKmZUB0N~&NU|;~SumHfo0HB}%(9i%j_Ye30 z00YBGL_t(|0qonss^c&aMA5qc|I@P>ctG=l7*bczquR!}ICO#)Th7aWnU|NB7yf3i z%@+dLKEHD(P_1J*kQvp7?eja=0Sk2x_<#>6UUwhx0aMO@2F!9`maj!~0T?A(*Ck(~ zbxq&GZ1*LLecNXTzEEw$7piUC1F{vU*0CJO1)y2S1>n19F96s0T;O}?vS5H}9gBhQ zZsCHf?tARHZh$^;yAR!m>qGak-G|~!y^RY%1mN?b_%iD(ABr#4HaH*^b-m zD_qH!d>44ivw%4R7JLdYkp`IL0x*$)pO35oBLR#1M?UKeU`8BZ@ln=1kq_Ln1Ly;8 z2QX*6a1kh$xs}_2cYOzkE(P)v?Hl@ywsW5k{QAYj*_w3j^MEv#JI4q1SC2G+%68I! z^C1jy)b$1k7l3F3WCq&4Sylsb0Z7S*;fv|ZMIXM8LmsIDM^$Zr-0;!!amFJ>;H+u^ zOT6jp@x}=cbdVl!HkAg*ht&ScgXE*i%kl3$1t6b8>vcL%d^62XW54lDAD`M?o!{!) zfHgY5^}Y^-R-5PR5OscQ77s7UR$fL#Ubi$Ormxm{-&gHSIzWMT(3zBc-1p7@4ZaU^ z13GN-c)>^?dUa(}(eLyyD9ZUs}G|83B0a!|<7JWFQPMr@lY!+>MHZFc1Xb zsT(JMR{Q=>dt7Yk(tFpykfkqmqL z?ItiJGs{?$EVy|t`JS>_5;8E8%z%-M?VN4g1BB$ul`Sy=z(iIz&u88<3qZl=fjsX4 zYH#yQcfo?SthnrJ`W@(9jN=QG5-=+y&HY##;k#w9q~a z01O*Iu__ec7^wrH`+S=ia4l5V>eKCqvI__ah@=8rbf0hZc5U?2+79D@l1N@40ipZ+ zVmsX$)Y8UkB;UqT4R#-A5eVJqAD5C9v`m(Na=)K^@r!N1B3o+qGyZZriitk=xa7#@ z$8E-6X;Vhs_pV!K>%Mo*|K_#)o$knyBS(%L`2bnfD}J)ipU(gQ002ovPDHLkV1fzl B`_upc literal 0 HcmV?d00001 diff --git a/PrusaSL1Viewer/Images/gui/mutation_erosion.png b/PrusaSL1Viewer/Images/gui/mutation_erosion.png new file mode 100644 index 0000000000000000000000000000000000000000..8f2422c7f3d73b59dc9ab552f7d37de7d87f93be GIT binary patch literal 1055 zcmV+)1mOFLP)0Dyo1FfafhAOQdW0PyetaBu)XKmZUB0N~&NU|;~SumHfo0HB}%(9i%j_Ye30 z00XBT&Nf7eJK#f1I50+viG&X+Lw2p>^mH|r|k}1F7SY%%dx)mfqmtjNL=6@ z>p~CwTYadn0|GDrnQsbT4E$u_Xy2go4S>uy=zN3Tr}9-mOa%1di-4F2xcCMj^9>4~ ziGVN((0jfB$l@!2U{+w}8-R>Auvy0hz^8>F<81^2yC-M(&Zj%P#tztn1Ry-x#YW%L zJG)~+*zVf^T#I_(&OrfdQ~U|tdd|G`HNz3FM;<4&;_32yBm0c z$Nz?cgTI1+V?Ut)rBAql^gvV_$Od5P^R-Xvi-7bSsPlQvmjM0NH|TtW-Y4S?fWY_t z27+mT3oihMK5zME3ZTVT05OGc;Wa*(0=V!JAPD|Pu+e9pVwX>M!x9;9umV^!`++;h zuRPlzIE%5@XCUAWNOYgT%C`VHNjC$m{VLm9nl$%1RJ!SP5ZZcPP&+fdPI>pQ=S8(W zk80updY)|Fk@{vf1Fefg8q-(u-~gT21>2{PVGKACT@ z(>JNF2TlaU{7XK)uekdHusr$G-rcCU3IkC9K6T>BuiE#2+FN6b5n-+|lrE41>^c=3 zzgS2Fw1W)AKfuUP+ft+d+&7XOfq~=(v!waz1vE}X{JU^sig6BpPf&rl4D=*DAS7)* zX0987$_^iyW8GRMG8W@JanD=Q{F896eYvo`B`nEuRXEmYmyxnh%zokmGWnYM{PE z(}A-i=^BCh$A+XUH*W(USA8WAGigmTP+^xRPg2@}XP*WfE%|JlCKO)-P!XQj-U<+o zWUd>8im(1FTL0*$4#eCJRD6K_OyHSj^53wQ!x>mB#1-IZbztk8Di)Fh-i_kcJ$-hB zCLk^W;cft-_Bv1W@}B6^HXYgl!I6AI2kJt#<(Oepu9sX_M(L$5)gXKAF9K2FEAEq= zgso2Ezxf2Hf0m1FKU2{Jv}`=Jv}`= Z{{TErA5U(g3^D)!002ovPDHLkV1m`e?8g8A literal 0 HcmV?d00001 diff --git a/PrusaSL1Viewer/Images/gui/mutation_gradient.png b/PrusaSL1Viewer/Images/gui/mutation_gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..7b60d709015b778817d2e097031b839b4b71e99e GIT binary patch literal 1280 zcmV+b1^@bqP)Zq0Vz2jqHS)h8VUQUSJn zPT~MiwKl2N+4KpEDyelH@=3KW^WB)+ebU9g+vg7Y!fG3RVYQ8OK#FBLGNwhJbQ93K z4xKA{zC#xw)tCL|O9>h9GT&W5_cej^fz?0GXaczs=)NY9KCpVerwQaduu*o|2YdHj z3-pSy}&nK2IvJdu?!gS1%L~8I{WsRxh@8L z=T%l{>~`K1R@(s1e{xUT^o48yB`FMC-_W!JD6i=QrB|RTAq0G1%NzhU?l?FI?3GDs zR^ARQ`+fpD1K$T~1<1eDR_Ly_HD4dNp^jA`yMgOIa$Ah^b{=;cn=LcoylNY8mA4JJ z?xQe)7%(=0n6Ch&Hi5%$;W3}{qFapnDnR!63>f#R;afk&7_aaKnlCqjv%8Ea(0H*e zh7&$=KBi5kjR7%V0BB9d3-}T|Y375#^cgVD6ApBq`y$6s2>JxTsK`b=G=aD;Fo8gr zry&4Bz6Wqz5$OcCZRGh1^(gB@%(MTq-BcH9eb3Go2L=vIr*!ZCFBoWT>bmE_V>}g3 zgS2>Swm@qEx3c6Cy#?FKhLNf+&{lW~l{aW!H8{g4(#{dz@HiML9;*Vthh_wdj_G(P zlRU4D`@B2mOKF zKB_)~zCZ2U2ePCv3%6;IsJ{veja&H8_tfkz3pj-G& zSsREzvK3f0wy(Vx?LYL>24c7gw0%H4$^ey?>U{=))c`t$@BqhX0DVFjJ}e|xoQ29! zeSUwCZvo)~BD4U}eB5lE(91cYpO495T#*CG9WEgJK0UJ?-V>;$zHSuSK4Vr5a=o6M zK=^%naVbbf%`6k#XMeV80Ax9EgeIs*CPlVWS@iDT-uYj$ONU z?b@|#*ROi~cpNhY0N*;`2R>%90se$u?-QTXoBh#@$@gq~?;zylld@^1jA0~D_OYG~B z*!e&RxIH&mXRR6#5_n-mJpcP$5Kulon>_vfZr6uR`up8FYsII9`b@eodOz>2QELvM zzN$AEzzd^qKz&t5AfWE~=PCRFv)+Z#FP}b7Z%!m&-s505kDcb5Vj)4>`Q^(HXp zA@7+X@}C#-?u&uIxdLXr3q$bi0j-|07;w!WFzs>h&v)iMGf3`S$>X4KXWnxkQVd|; z+YK^1V1I89VBXsS^;Q$Sfb{$h00_)bgZG6e1Nr&g{B5b;Is4-R=G7=NwL&x0?7?+o z-V;7o00Qlu0gryJfIxR(z^hRLXwA2RhZQ{?#LC|BE*_eBI!L%K9{#^)>ZCOEb!NQ_ zW5RRBGkAthN=LlBr-M{$;(>8pJP>U$kAuV_+)*-SanzPIwoF-}84cn}7eTd*Oy~pp$pM(9rws6@4Xf zc=>$LR}!~pD8flzjmmk3fb2?l5Bhhz$IG;X{cP_HTN{LdFdXPtFTRP1)vcRb|NoDi zdXuxdj9ix$#(aU+L&(Du8ghcwB(I`MzQ$OpWJMO|J>IVdP>+59Sj+)7u_DX(Sx-cb z;drvEc@B*vdt-!?WE#&f|iK-$(@MoUBLZ)Yd36g)i z1L9Utj*3huM+Bn-I=!HZ=Xf2A@iRv+m};3a1iOjp^@0kXoe6Syzu+m&OA0=j4se$1 z%uQdx6Bq{o6%kDHHiFNlcEE+}%r;!f(+j2z)4gy?@P!u!*O_g&lBfTP>i>$F7JMD6 zE+JTo=avn8R`wVZxA9$jeTrP<+Ni8$J&->|`ApY75H5I%98Lq=u$j7{5qrBb!c*Vw%BS(%L bIdbF!s>5x7+L3}{00000NkvXXu0mjfi$`CT literal 0 HcmV?d00001 diff --git a/PrusaSL1Viewer/Images/gui/mutation_tophat.png b/PrusaSL1Viewer/Images/gui/mutation_tophat.png new file mode 100644 index 0000000000000000000000000000000000000000..60c1c84f32f1d4c8851315af9f254de34c479e4f GIT binary patch literal 948 zcmV;l155mgP)0Dyo1FfafhAOQdW0PyetaBu)XKmZUB0N~&NU|;~SumHfo0HB}%(9i%j_Ye30 z00TTpL_t(|0qoo1O2bePMBzQ}|Iz|#76VML(2VT3^RFfFaZK^5wUs~1cDvnfw*yG^ zxK@#a(S;jGcpzjKg0~R)cmp?Z1Irv(8@Pc3&Ou|~{-ic=x-Tly?d|XLyWK8e0Hk{m z>NQBZ$4qYn@q#^*M|dE?f%~RQzz7dy17{C&AnAYaCH)4Hegik~(LM~`pY~z!();lD zLGiUL&j5P7_4+}mSLt4ZAs#oc!BDTk1dqF?!D$}R9=DYMle`8ed)!B9(Bv674G!>t zGml{&J;hbUc~t@o^ctMxmCyt@z>}c9a+Fu6T-8jkB&NXu-d(JE1~hp44>B7V;Oz~J z^7a*~FZFvikk1YC>bD+4Jr(&Os)7^k;Esf+xTdV6w+#@1s3)QEd>2g6Pz{&c2N1|G&1lR=lL3 zPFhO=50H2XcsxsjD{;$q*4J6*-hg1;rM|!J>q+)NM{)^^WVp01Bs0rcNEX~Wm%LGS zg*YwDBr{+nV>@S?)j+{l*@$VL2C}+!esE(HggZVT$cGxJ`-ZJx!lHGTQMpkSq4(_s za(FjT`9Z`~Fw80GTVOD=X>K>O@Rkt!fw7kYb>Fm}y+pFU2Kpo2cNkbBIckBjFOm;5 zQuC;R2V187z;SjaJy7t4W^jjk;L6!PABd5RK@Jpr{^Cj6uLOGEL0})rryMBw^uR;o zhXY4}NF(G7vaj7MnpWBLyMqGvNyFdy2U*FBm&CSit&CMq) W6(c3kSaS#f0000*%6_1X{bH<@w!KM124grO0pPOsz0elf>5d$21UB*kQUBT|orH?04UW)Ox( zkea@Tv|~P1%ng^ z8+*Hsa@GS+t3*dY!T)FmVbl2kp_kR8PF>|JX%2RHdcb860gVWN%OHXp@fy^oqmYXKHiH<6(TL9=#*GuWD;!K%>Ve`M zB!=IQL+Ac9g1umG&MlK$V6w_y`idnR(;vLLe*I%%IP^^C_;^_rhZuWF z_w)ufK?w(t!oR=1GawrT0>~Pf**GBvet3D{#m-p`U@tgGiplue`>#5s;bnPOLWcp_ zAP_*-sQlszgMayr?Z>wq+8DO)*~=%4Yb^gYAVE;7my9gQISbz0xFq&2U8v7 zG{RT{BW$~13f9PW0bbIp`~UL~MJp(%iArdSW->Gv^RW<{@Q9E)|A$P(Ff@WK+mn$* ztf=(+U=`Nj94`D5pctxi%k8lRyE6LEuNy??|&vQu`4G=;3j5aH5LZK!9vn+D~~x}LLQ>s|L@@%eqaYSU_1JvC&pj~ z=1BM*LjMg=Exi_v?^ul$Sck=!jtOEGK4$u-CX|#x;|adw99Chjm?7Km_<=PAGOM(q zR+1O=86WT#ukaq9@B^Fup+Lb*10xoO31AREqb~7VXd}vo${f X-E*2*`5`_S00000NkvXXu0mjfb}q;T delta 567 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 wES2$@sB7{lO&+6_l4tVqY8YN<;^ + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ +using System.Drawing; + + +namespace PrusaSL1Viewer +{ + public class Mutation + { + #region Enum + public enum Mutates : byte + { + Erode, + Dilate, + Opening, + Closing, + Gradient, + TopHat, + BlackHat, + HitMiss, + PyrDownUp, + SmoothMedian, + SmoothGaussian + } + #endregion + + #region Properties + public Mutates Mutate { get; } + + public string Description { get; } + + public Image Image { get; } + #endregion + + #region Constructor + + public Mutation(Mutates mutate, string description, Image image = null) + { + Mutate = mutate; + Description = description; + Image = image; + } + + #endregion + } +} diff --git a/PrusaSL1Viewer/Program.cs b/PrusaSL1Viewer/Program.cs index d8cf1b52..a26cecc8 100644 --- a/PrusaSL1Viewer/Program.cs +++ b/PrusaSL1Viewer/Program.cs @@ -11,6 +11,8 @@ using System.Globalization; using System.Threading; using System.Windows.Forms; +using ApplicationManagement; +using Emgu.CV; using PrusaSL1Reader; namespace PrusaSL1Viewer @@ -61,9 +63,26 @@ public static void SetAllControlsFontSize( }; } + public static Matrix KernelStar3x3 { get; } = new Matrix(new byte[,] + { + { 0, 1, 0 }, + { 1, 0, 1 }, + { 0, 1, 0 } + }); + + public static Matrix KernelFindIsolated { get; } = new Matrix(new sbyte[,] + { + { 0, 1, 0 }, + { 1, -1, 1 }, + { 0, 1, 0 } + }); + public static FileFormat SlicerFile { get; set; } public static FrmMain FrmMain { get; private set; } public static FrmAbout FrmAbout { get; private set; } + + public static ExceptionHandler ExceptionHandler { get; private set; } + public static string[] Args { get; private set; } /// /// The main entry point for the application. @@ -77,6 +96,9 @@ static void Main(string[] args) Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + ExceptionHandler = new ExceptionHandler {MessageBoxButtons = MessageBoxButtons.OK}; + ExceptionHandler.StartHandlingExceptions(); + FrmMain = new FrmMain(); FrmAbout = new FrmAbout(); diff --git a/PrusaSL1Viewer/Properties/AssemblyInfo.cs b/PrusaSL1Viewer/Properties/AssemblyInfo.cs index 75ba680c..e0322166 100644 --- a/PrusaSL1Viewer/Properties/AssemblyInfo.cs +++ b/PrusaSL1Viewer/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // 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.4.0.0")] -[assembly: AssemblyFileVersion("0.4.0.0")] +[assembly: AssemblyVersion("0.4.1.0")] +[assembly: AssemblyFileVersion("0.4.1.0")] diff --git a/PrusaSL1Viewer/Properties/Resources.Designer.cs b/PrusaSL1Viewer/Properties/Resources.Designer.cs index ec18b715..5c64235a 100644 --- a/PrusaSL1Viewer/Properties/Resources.Designer.cs +++ b/PrusaSL1Viewer/Properties/Resources.Designer.cs @@ -160,6 +160,26 @@ internal static System.Drawing.Bitmap Extract_object_16x16 { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap eye_16x16 { + get { + object obj = ResourceManager.GetObject("eye-16x16", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap eye_24x24 { + get { + object obj = ResourceManager.GetObject("eye-24x24", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -180,6 +200,16 @@ internal static System.Drawing.Bitmap File_Refresh_16x16 { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap filter_filled_16x16 { + get { + object obj = ResourceManager.GetObject("filter-filled-16x16", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -210,6 +240,76 @@ internal static System.Drawing.Bitmap layers_16x16 { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap mutation_blackhat { + get { + object obj = ResourceManager.GetObject("mutation_blackhat", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap mutation_closing { + get { + object obj = ResourceManager.GetObject("mutation_closing", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap mutation_dilation { + get { + object obj = ResourceManager.GetObject("mutation_dilation", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap mutation_erosion { + get { + object obj = ResourceManager.GetObject("mutation_erosion", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap mutation_gradient { + get { + object obj = ResourceManager.GetObject("mutation_gradient", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap mutation_opening { + get { + object obj = ResourceManager.GetObject("mutation_opening", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap mutation_tophat { + get { + object obj = ResourceManager.GetObject("mutation_tophat", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/PrusaSL1Viewer/Properties/Resources.resx b/PrusaSL1Viewer/Properties/Resources.resx index 869850b6..f8c143c5 100644 --- a/PrusaSL1Viewer/Properties/Resources.resx +++ b/PrusaSL1Viewer/Properties/Resources.resx @@ -118,79 +118,109 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Images\Donate-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Images\File-Refresh-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Images\Ok-24x24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Error-128x128.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Images\layers-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Rotate-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\gui\mutation_closing.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Global-Network-icon-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Back-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\search-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Extract-object-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Cancel-24x24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\File-Refresh-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\SaveAs-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Exit-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Back-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Global-Network-icon-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\Next-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\gui\mutation_erosion.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Images\Save-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Exit-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Wrench-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Convert-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\PrusaSL1Viewer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Open-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Ok-24x24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Images\Button-Info-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Geometry-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\filter-filled-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\Cancel-32x32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\Open-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Images\File-Close-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Extract-object-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\search-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Geometry-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\eye-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\Rotate-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\gui\mutation_tophat.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\CNCMachine-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\Convert-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\gui\mutation_dilation.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\gui\mutation_gradient.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Images\pixel-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\PrusaSL1Viewer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\SaveAs-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Next-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\gui\mutation_opening.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Error-128x128.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\gui\mutation_blackhat.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Wrench-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Cancel-24x24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\Cancel-32x32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\Donate-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\CNCMachine-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\eye-24x24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/PrusaSL1Viewer/PrusaSL1Viewer.csproj b/PrusaSL1Viewer/PrusaSL1Viewer.csproj index 56579646..7582f99c 100644 --- a/PrusaSL1Viewer/PrusaSL1Viewer.csproj +++ b/PrusaSL1Viewer/PrusaSL1Viewer.csproj @@ -57,6 +57,9 @@ PrusaSL1Viewer.ico + + Libraries\ApplicationManagement.dll + ..\packages\BinarySerializer.8.5.1\lib\net46\BinarySerializer.dll @@ -104,6 +107,7 @@ True True + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll @@ -142,6 +146,15 @@ + + Component + + + Form + + + FrmMutation.cs + Form @@ -166,19 +179,17 @@ FrmMain.cs - - UserControl - - - ImageBox.cs - + FrmAbout.cs + + FrmMutation.cs + FrmInputBox.cs @@ -188,9 +199,6 @@ FrmMain.cs - - ImageBox.cs - ResXFileCodeGenerator Resources.Designer.cs @@ -260,6 +268,16 @@ + + + + + + + + + + @@ -275,6 +293,7 @@ false + xcopy /y $(ProjectDir)..\LICENSE $(ProjectDir)$(OutDir) diff --git a/README.md b/README.md index 909d7100..45d5d12d 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ But also, i need victims for test subject. Proceed at your own risk! * View and extract thumbnails * View all used settings * Edit print properties and save file +* Mutate and filter layers * Export file to a folder * Convert SL1 format to another format * Portable (No installation needed) @@ -58,7 +59,7 @@ But also, i need victims for test subject. Proceed at your own risk! * Choose SL1 printer 1. Close PrusaSlicer 1. Open PrusaSL1Viewer -1. Under Menu click -> About -> Install printers into PrusaSlicer + * Under Menu click -> About -> Install printers 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 or create your printer and tune the values if required @@ -80,9 +81,11 @@ After some tests without failure you can increase your confidence and ignore thi 1. Windows 7 or greater 2. .NET Framework 4.8 installed (Comes pre-installed on Windows 10 with last updates) +3. 2 GB RAM or higher ### Mac and Linux +(Not tested nor compiled) 1. Latest Mono ## How to use @@ -100,8 +103,6 @@ Are you a developer? This project include a .NET Core library (PrusaSL1Reader) t ## TODO -* Speed up layer preview -* Put convert operation under a task (No GUI freeze) * More file formats * Clean up (always)