Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Conceição <Tiago_caza@hotmail.com>2020-06-18 22:24:51 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2020-06-18 22:24:51 +0300
commit7fe804a9ac5d0ddc759ae32c0419020d9ae7a226 (patch)
tree644ed625e21ebce759be9b85554907ef6f75c2da
parent379c5140f60de41ac4d282e926010905a1670a85 (diff)
v0.5.1.3v0.5.1.3
* (Add) Button save layer image to Clipboard * (Change) Go to issue now zoom at bouding area instead of first pixels * (Change) Layer navigation panel width increased in 20 pixels, in some cases it was overlaping the slider * (Change) Actual layer information now have a depth border * (Change) Increased main GUI size to X: 1800 and Y: 850 pixels * (Change) If the GUI window is bigger than current screen resolution, it will start maximized istead * (Fix) cbddlp: AntiAlias is number of _greys_, not number of significant bits (ezrec/uv3dp#75) * (Fix) Outline not working as before, due a forget to remove test code
-rw-r--r--CHANGELOG.md14
-rw-r--r--UVtools.GUI/FrmMain.Designer.cs110
-rw-r--r--UVtools.GUI/FrmMain.cs464
-rw-r--r--UVtools.GUI/FrmMain.resx125
-rw-r--r--UVtools.GUI/Images/clipboard-16x16.pngbin0 -> 207 bytes
-rw-r--r--UVtools.GUI/Images/file-image-16x16.pngbin0 -> 234 bytes
-rw-r--r--UVtools.GUI/Properties/AssemblyInfo.cs4
-rw-r--r--UVtools.GUI/Properties/Resources.Designer.cs20
-rw-r--r--UVtools.GUI/Properties/Resources.resx28
-rw-r--r--UVtools.GUI/UVtools.GUI.csproj2
-rw-r--r--UVtools.Parser/ChituboxFile.cs30
-rw-r--r--UVtools.Parser/LayerManager.cs47
-rw-r--r--UVtools.Parser/UVtools.Parser.csproj6
13 files changed, 601 insertions, 249 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd7659c..e79b91b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
# Changelog
+## 18/06/2020 - v0.5.1.3
+
+* (Add) Button save layer image to Clipboard
+* (Change) Go to issue now zoom at bouding area instead of first pixels
+* (Change) Layer navigation panel width increased in 20 pixels, in some cases it was overlaping the slider
+* (Change) Actual layer information now have a depth border
+* (Change) Increased main GUI size to X: 1800 and Y: 850 pixels
+* (Change) If the GUI window is bigger than current screen resolution, it will start maximized istead
+* (Fix) cbddlp: AntiAlias is number of _greys_, not number of significant bits (ezrec/uv3dp#75)
+* (Fix) Outline not working as before, due a forget to remove test code
+
+
## 17/06/2020 - v0.5.1.2
* (Add) Able to install only the desired profiles and not the whole lot (Suggested by: Ingo Strohmenger)
@@ -12,7 +24,7 @@
## 16/06/2020 - v0.5.1.1
* (Add) photon, cbddlp, ctb and phz can be converted to Zip
-* (Fix) CTB: When AntiAliasing is on it saves a bad file
+* (Fix) ctb: When AntiAliasing is on it saves a bad file
## 16/06/2020 - v0.5.1
diff --git a/UVtools.GUI/FrmMain.Designer.cs b/UVtools.GUI/FrmMain.Designer.cs
index a726ab1..17f2258 100644
--- a/UVtools.GUI/FrmMain.Designer.cs
+++ b/UVtools.GUI/FrmMain.Designer.cs
@@ -59,7 +59,9 @@
this.scCenter = new System.Windows.Forms.SplitContainer();
this.pbLayer = new Cyotek.Windows.Forms.ImageBox();
this.tsLayer = new System.Windows.Forms.ToolStrip();
- this.tsLayerImageExport = new System.Windows.Forms.ToolStripButton();
+ this.tsLayerImageExport = new System.Windows.Forms.ToolStripSplitButton();
+ this.tsLayerImageExportFile = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsLayerImageExportClipboard = new System.Windows.Forms.ToolStripMenuItem();
this.tsLayerResolution = new System.Windows.Forms.ToolStripLabel();
this.tsLayerImageRotate = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
@@ -170,7 +172,7 @@
this.helpToolStripMenuItem});
this.menu.Location = new System.Drawing.Point(0, 0);
this.menu.Name = "menu";
- this.menu.Size = new System.Drawing.Size(1684, 24);
+ this.menu.Size = new System.Drawing.Size(1784, 24);
this.menu.TabIndex = 0;
this.menu.Text = "menuStrip1";
//
@@ -384,9 +386,9 @@
//
// statusBar
//
- this.statusBar.Location = new System.Drawing.Point(0, 764);
+ this.statusBar.Location = new System.Drawing.Point(0, 789);
this.statusBar.Name = "statusBar";
- this.statusBar.Size = new System.Drawing.Size(1684, 22);
+ this.statusBar.Size = new System.Drawing.Size(1784, 22);
this.statusBar.TabIndex = 1;
this.statusBar.Text = "statusStrip1";
//
@@ -395,7 +397,7 @@
this.mainTable.ColumnCount = 3;
this.mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 400F));
this.mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
- this.mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130F));
+ this.mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 150F));
this.mainTable.Controls.Add(this.scCenter, 1, 0);
this.mainTable.Controls.Add(this.tabControlLeft, 0, 0);
this.mainTable.Controls.Add(this.tlRight, 2, 0);
@@ -404,7 +406,7 @@
this.mainTable.Name = "mainTable";
this.mainTable.RowCount = 1;
this.mainTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
- this.mainTable.Size = new System.Drawing.Size(1684, 740);
+ this.mainTable.Size = new System.Drawing.Size(1784, 765);
this.mainTable.TabIndex = 5;
//
// scCenter
@@ -425,8 +427,8 @@
//
this.scCenter.Panel2.Controls.Add(this.pbLayers);
this.scCenter.Panel2MinSize = 18;
- this.scCenter.Size = new System.Drawing.Size(1148, 734);
- this.scCenter.SplitterDistance = 705;
+ this.scCenter.Size = new System.Drawing.Size(1228, 759);
+ this.scCenter.SplitterDistance = 730;
this.scCenter.TabIndex = 4;
//
// pbLayer
@@ -437,7 +439,7 @@
this.pbLayer.Name = "pbLayer";
this.pbLayer.PanMode = Cyotek.Windows.Forms.ImageBoxPanMode.Left;
this.pbLayer.ShowPixelGrid = true;
- this.pbLayer.Size = new System.Drawing.Size(1148, 680);
+ this.pbLayer.Size = new System.Drawing.Size(1228, 705);
this.pbLayer.TabIndex = 7;
this.pbLayer.Zoomed += new System.EventHandler<Cyotek.Windows.Forms.ImageBoxZoomEventArgs>(this.pbLayer_Zoomed);
this.pbLayer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pbLayer_MouseMove);
@@ -466,7 +468,7 @@
this.tsLayerImageMouseLocation});
this.tsLayer.Location = new System.Drawing.Point(0, 0);
this.tsLayer.Name = "tsLayer";
- this.tsLayer.Size = new System.Drawing.Size(1148, 25);
+ this.tsLayer.Size = new System.Drawing.Size(1228, 25);
this.tsLayer.TabIndex = 6;
this.tsLayer.Text = "Layer Menu";
//
@@ -474,14 +476,32 @@
//
this.tsLayerImageExport.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.tsLayerImageExport.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
- this.tsLayerImageExport.Enabled = false;
+ this.tsLayerImageExport.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tsLayerImageExportFile,
+ this.tsLayerImageExportClipboard});
this.tsLayerImageExport.Image = global::UVtools.GUI.Properties.Resources.Save_16x16;
this.tsLayerImageExport.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsLayerImageExport.Name = "tsLayerImageExport";
- this.tsLayerImageExport.Size = new System.Drawing.Size(23, 22);
- this.tsLayerImageExport.Text = "Save Layer";
- this.tsLayerImageExport.ToolTipText = "Save layer image to file";
- this.tsLayerImageExport.Click += new System.EventHandler(this.EventClick);
+ this.tsLayerImageExport.Size = new System.Drawing.Size(32, 22);
+ this.tsLayerImageExport.Text = "Save to";
+ this.tsLayerImageExport.ToolTipText = "Save layer image to a file or clipboard";
+ this.tsLayerImageExport.ButtonClick += new System.EventHandler(this.EventClick);
+ //
+ // tsLayerImageExportFile
+ //
+ this.tsLayerImageExportFile.Image = global::UVtools.GUI.Properties.Resources.file_image_16x16;
+ this.tsLayerImageExportFile.Name = "tsLayerImageExportFile";
+ this.tsLayerImageExportFile.Size = new System.Drawing.Size(141, 22);
+ this.tsLayerImageExportFile.Text = "To &File";
+ this.tsLayerImageExportFile.Click += new System.EventHandler(this.EventClick);
+ //
+ // tsLayerImageExportClipboard
+ //
+ this.tsLayerImageExportClipboard.Image = global::UVtools.GUI.Properties.Resources.clipboard_16x16;
+ this.tsLayerImageExportClipboard.Name = "tsLayerImageExportClipboard";
+ this.tsLayerImageExportClipboard.Size = new System.Drawing.Size(141, 22);
+ this.tsLayerImageExportClipboard.Text = "To &Clipboard";
+ this.tsLayerImageExportClipboard.Click += new System.EventHandler(this.EventClick);
//
// tsLayerResolution
//
@@ -618,7 +638,7 @@
this.pbLayers.Dock = System.Windows.Forms.DockStyle.Fill;
this.pbLayers.Location = new System.Drawing.Point(0, 0);
this.pbLayers.Name = "pbLayers";
- this.pbLayers.Size = new System.Drawing.Size(1148, 25);
+ this.pbLayers.Size = new System.Drawing.Size(1228, 25);
this.pbLayers.Step = 1;
this.pbLayers.TabIndex = 6;
//
@@ -633,7 +653,7 @@
this.tabControlLeft.Location = new System.Drawing.Point(3, 3);
this.tabControlLeft.Name = "tabControlLeft";
this.tabControlLeft.SelectedIndex = 0;
- this.tabControlLeft.Size = new System.Drawing.Size(394, 734);
+ this.tabControlLeft.Size = new System.Drawing.Size(394, 759);
this.tabControlLeft.TabIndex = 5;
this.tabControlLeft.SelectedIndexChanged += new System.EventHandler(this.EventSelectedIndexChanged);
//
@@ -644,7 +664,7 @@
this.tbpThumbnailsAndInfo.Location = new System.Drawing.Point(4, 23);
this.tbpThumbnailsAndInfo.Name = "tbpThumbnailsAndInfo";
this.tbpThumbnailsAndInfo.Padding = new System.Windows.Forms.Padding(3);
- this.tbpThumbnailsAndInfo.Size = new System.Drawing.Size(386, 707);
+ this.tbpThumbnailsAndInfo.Size = new System.Drawing.Size(386, 732);
this.tbpThumbnailsAndInfo.TabIndex = 0;
this.tbpThumbnailsAndInfo.Text = "Information";
this.tbpThumbnailsAndInfo.UseVisualStyleBackColor = true;
@@ -667,7 +687,7 @@
//
this.scLeft.Panel2.Controls.Add(this.lvProperties);
this.scLeft.Panel2.Controls.Add(this.tsProperties);
- this.scLeft.Size = new System.Drawing.Size(380, 701);
+ this.scLeft.Size = new System.Drawing.Size(380, 726);
this.scLeft.SplitterDistance = 425;
this.scLeft.TabIndex = 4;
//
@@ -761,7 +781,7 @@
this.lvProperties.HideSelection = false;
this.lvProperties.Location = new System.Drawing.Point(0, 25);
this.lvProperties.Name = "lvProperties";
- this.lvProperties.Size = new System.Drawing.Size(380, 247);
+ this.lvProperties.Size = new System.Drawing.Size(380, 272);
this.lvProperties.TabIndex = 1;
this.lvProperties.UseCompatibleStateImageBehavior = false;
this.lvProperties.View = System.Windows.Forms.View.Details;
@@ -828,7 +848,7 @@
this.tabPageGCode.ImageKey = "GCode-16x16.png";
this.tabPageGCode.Location = new System.Drawing.Point(4, 23);
this.tabPageGCode.Name = "tabPageGCode";
- this.tabPageGCode.Size = new System.Drawing.Size(386, 707);
+ this.tabPageGCode.Size = new System.Drawing.Size(386, 732);
this.tabPageGCode.TabIndex = 2;
this.tabPageGCode.Text = "GCode";
this.tabPageGCode.UseVisualStyleBackColor = true;
@@ -841,7 +861,7 @@
this.tbGCode.Name = "tbGCode";
this.tbGCode.ReadOnly = true;
this.tbGCode.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.tbGCode.Size = new System.Drawing.Size(386, 682);
+ this.tbGCode.Size = new System.Drawing.Size(386, 707);
this.tbGCode.TabIndex = 1;
//
// tsGCode
@@ -894,7 +914,7 @@
this.tabPageIssues.Location = new System.Drawing.Point(4, 23);
this.tabPageIssues.Name = "tabPageIssues";
this.tabPageIssues.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageIssues.Size = new System.Drawing.Size(386, 707);
+ this.tabPageIssues.Size = new System.Drawing.Size(386, 732);
this.tabPageIssues.TabIndex = 3;
this.tabPageIssues.Text = "Issues";
this.tabPageIssues.UseVisualStyleBackColor = true;
@@ -914,7 +934,7 @@
this.lvIssues.HideSelection = false;
this.lvIssues.Location = new System.Drawing.Point(3, 28);
this.lvIssues.Name = "lvIssues";
- this.lvIssues.Size = new System.Drawing.Size(380, 676);
+ this.lvIssues.Size = new System.Drawing.Size(380, 701);
this.lvIssues.TabIndex = 8;
this.lvIssues.UseCompatibleStateImageBehavior = false;
this.lvIssues.View = System.Windows.Forms.View.Details;
@@ -1062,7 +1082,7 @@
this.tlRight.Controls.Add(this.lbInitialLayer, 0, 5);
this.tlRight.Controls.Add(this.panel2, 0, 4);
this.tlRight.Dock = System.Windows.Forms.DockStyle.Fill;
- this.tlRight.Location = new System.Drawing.Point(1557, 3);
+ this.tlRight.Location = new System.Drawing.Point(1637, 3);
this.tlRight.Name = "tlRight";
this.tlRight.RowCount = 6;
this.tlRight.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F));
@@ -1071,16 +1091,17 @@
this.tlRight.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F));
this.tlRight.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F));
this.tlRight.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F));
- this.tlRight.Size = new System.Drawing.Size(124, 734);
+ this.tlRight.Size = new System.Drawing.Size(144, 759);
this.tlRight.TabIndex = 6;
//
// btnPreviousLayer
//
+ this.btnPreviousLayer.Dock = System.Windows.Forms.DockStyle.Fill;
this.btnPreviousLayer.Enabled = false;
this.btnPreviousLayer.Image = global::UVtools.GUI.Properties.Resources.arrow_down_16x16;
- this.btnPreviousLayer.Location = new System.Drawing.Point(3, 623);
+ this.btnPreviousLayer.Location = new System.Drawing.Point(3, 648);
this.btnPreviousLayer.Name = "btnPreviousLayer";
- this.btnPreviousLayer.Size = new System.Drawing.Size(118, 26);
+ this.btnPreviousLayer.Size = new System.Drawing.Size(138, 26);
this.btnPreviousLayer.TabIndex = 14;
this.btnPreviousLayer.Tag = "0";
this.btnPreviousLayer.Text = "-";
@@ -1096,7 +1117,7 @@
this.btnNextLayer.Image = global::UVtools.GUI.Properties.Resources.arrow_up_16x16;
this.btnNextLayer.Location = new System.Drawing.Point(3, 53);
this.btnNextLayer.Name = "btnNextLayer";
- this.btnNextLayer.Size = new System.Drawing.Size(118, 26);
+ this.btnNextLayer.Size = new System.Drawing.Size(138, 26);
this.btnNextLayer.TabIndex = 8;
this.btnNextLayer.Tag = "1";
this.btnNextLayer.Text = "+";
@@ -1110,7 +1131,7 @@
this.lbMaxLayer.Dock = System.Windows.Forms.DockStyle.Fill;
this.lbMaxLayer.Location = new System.Drawing.Point(3, 0);
this.lbMaxLayer.Name = "lbMaxLayer";
- this.lbMaxLayer.Size = new System.Drawing.Size(118, 50);
+ this.lbMaxLayer.Size = new System.Drawing.Size(138, 50);
this.lbMaxLayer.TabIndex = 12;
this.lbMaxLayer.Text = "Layers";
this.lbMaxLayer.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
@@ -1122,25 +1143,26 @@
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(3, 85);
this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(118, 532);
+ this.panel1.Size = new System.Drawing.Size(138, 557);
this.panel1.TabIndex = 13;
//
// lbLayerActual
//
this.lbLayerActual.AutoSize = true;
- this.lbLayerActual.Location = new System.Drawing.Point(3, 551);
+ this.lbLayerActual.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+ this.lbLayerActual.Location = new System.Drawing.Point(3, 248);
this.lbLayerActual.Name = "lbLayerActual";
- this.lbLayerActual.Size = new System.Drawing.Size(13, 13);
+ this.lbLayerActual.Size = new System.Drawing.Size(15, 15);
this.lbLayerActual.TabIndex = 9;
this.lbLayerActual.Text = "?";
//
// tbLayer
//
this.tbLayer.Dock = System.Windows.Forms.DockStyle.Right;
- this.tbLayer.Location = new System.Drawing.Point(73, 0);
+ this.tbLayer.Location = new System.Drawing.Point(93, 0);
this.tbLayer.Name = "tbLayer";
this.tbLayer.Orientation = System.Windows.Forms.Orientation.Vertical;
- this.tbLayer.Size = new System.Drawing.Size(45, 532);
+ this.tbLayer.Size = new System.Drawing.Size(45, 557);
this.tbLayer.TabIndex = 8;
this.tbLayer.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
this.tbLayer.ValueChanged += new System.EventHandler(this.ValueChanged);
@@ -1148,9 +1170,9 @@
// lbInitialLayer
//
this.lbInitialLayer.Dock = System.Windows.Forms.DockStyle.Fill;
- this.lbInitialLayer.Location = new System.Drawing.Point(3, 684);
+ this.lbInitialLayer.Location = new System.Drawing.Point(3, 709);
this.lbInitialLayer.Name = "lbInitialLayer";
- this.lbInitialLayer.Size = new System.Drawing.Size(118, 50);
+ this.lbInitialLayer.Size = new System.Drawing.Size(138, 50);
this.lbInitialLayer.TabIndex = 11;
this.lbInitialLayer.Text = "Layers";
this.lbInitialLayer.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
@@ -1161,9 +1183,9 @@
this.panel2.Controls.Add(this.btnLastLayer);
this.panel2.Controls.Add(this.btnFirstLayer);
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.panel2.Location = new System.Drawing.Point(3, 655);
+ this.panel2.Location = new System.Drawing.Point(3, 680);
this.panel2.Name = "panel2";
- this.panel2.Size = new System.Drawing.Size(118, 26);
+ this.panel2.Size = new System.Drawing.Size(138, 26);
this.panel2.TabIndex = 15;
//
// btnFindLayer
@@ -1173,7 +1195,7 @@
this.btnFindLayer.Image = global::UVtools.GUI.Properties.Resources.search_16x16;
this.btnFindLayer.Location = new System.Drawing.Point(37, 0);
this.btnFindLayer.Name = "btnFindLayer";
- this.btnFindLayer.Size = new System.Drawing.Size(44, 26);
+ this.btnFindLayer.Size = new System.Drawing.Size(64, 26);
this.btnFindLayer.TabIndex = 17;
this.btnFindLayer.Text = "-";
this.toolTipInformation.SetToolTip(this.btnFindLayer, "Go to a layer index [CTRL+F]");
@@ -1185,7 +1207,7 @@
this.btnLastLayer.Dock = System.Windows.Forms.DockStyle.Right;
this.btnLastLayer.Enabled = false;
this.btnLastLayer.Image = global::UVtools.GUI.Properties.Resources.arrow_top_16x16;
- this.btnLastLayer.Location = new System.Drawing.Point(81, 0);
+ this.btnLastLayer.Location = new System.Drawing.Point(101, 0);
this.btnLastLayer.Name = "btnLastLayer";
this.btnLastLayer.Size = new System.Drawing.Size(37, 26);
this.btnLastLayer.TabIndex = 16;
@@ -1225,7 +1247,7 @@
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1684, 786);
+ this.ClientSize = new System.Drawing.Size(1784, 811);
this.Controls.Add(this.mainTable);
this.Controls.Add(this.statusBar);
this.Controls.Add(this.menu);
@@ -1302,7 +1324,6 @@
private System.Windows.Forms.ToolStripMenuItem menuFileSave;
private System.Windows.Forms.ToolStripMenuItem menuFileSaveAs;
private System.Windows.Forms.ToolStrip tsLayer;
- private System.Windows.Forms.ToolStripButton tsLayerImageExport;
private System.Windows.Forms.ToolStripLabel tsLayerResolution;
private System.Windows.Forms.TabControl tabControlLeft;
private System.Windows.Forms.TabPage tbpThumbnailsAndInfo;
@@ -1382,6 +1403,9 @@
private System.Windows.Forms.ToolTip toolTipInformation;
private System.Windows.Forms.ColumnHeader lvIssuesType;
private System.Windows.Forms.Timer layerScrollTimer;
+ private System.Windows.Forms.ToolStripSplitButton tsLayerImageExport;
+ private System.Windows.Forms.ToolStripMenuItem tsLayerImageExportFile;
+ private System.Windows.Forms.ToolStripMenuItem tsLayerImageExportClipboard;
}
}
diff --git a/UVtools.GUI/FrmMain.cs b/UVtools.GUI/FrmMain.cs
index 0f742ad..7905296 100644
--- a/UVtools.GUI/FrmMain.cs
+++ b/UVtools.GUI/FrmMain.cs
@@ -12,8 +12,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
-using System.Linq;
-using System.Numerics;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@@ -137,6 +135,13 @@ namespace UVtools.GUI
Clear();
+ if (Width >= Screen.FromControl(this).WorkingArea.Width ||
+ Height >= Screen.FromControl(this).WorkingArea.Height)
+ {
+ WindowState = FormWindowState.Maximized;
+ }
+
+
DragEnter += (s, e) => { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy; };
DragDrop += (s, e) => { ProcessFile((string[])e.Data.GetData(DataFormats.FileDrop)); };
@@ -663,7 +668,6 @@ namespace UVtools.GUI
}
}
-
using (FrmInstallPEProfiles form = new FrmInstallPEProfiles())
{
form.ShowDialog();
@@ -939,6 +943,11 @@ namespace UVtools.GUI
if (ReferenceEquals(sender, tsLayerImageExport))
{
+ tsLayerImageExport.ShowDropDown();
+ return;
+ }
+ if (ReferenceEquals(sender, tsLayerImageExportFile))
+ {
using (SaveFileDialog dialog = new SaveFileDialog())
{
if (ReferenceEquals(pbLayer, null))
@@ -960,10 +969,21 @@ namespace UVtools.GUI
stream.Close();
}
}
+ }
+ return;
+ }
- return;
-
+ if (ReferenceEquals(sender, tsLayerImageExportClipboard))
+ {
+ if (ReferenceEquals(pbLayer, null))
+ {
+ return; // This should never happen!
}
+
+ Image image = (Image)pbLayer.Image.Tag;
+ Clipboard.SetImage(image.ToBitmap());
+
+ return;
}
if (ReferenceEquals(sender, btnFirstLayer))
@@ -1149,18 +1169,29 @@ namespace UVtools.GUI
}
else if (issue.X >= 0 && issue.Y >= 0)
{
- int x = issue.X;
- int y = issue.Y;
+ if (issue.BoundingRectangle.IsEmpty || issue.Size == 1)
+ {
+ int x = issue.X;
+ int y = issue.Y;
+
+ if (tsLayerImageRotate.Checked)
+ {
+ x = ActualLayerImage.Height - 1 - issue.Y;
+ y = issue.X;
+ }
- if (tsLayerImageRotate.Checked)
+ pbLayer.ZoomToRegion(x, y, 5, 5);
+ //pbLayer.ZoomOut(true);
+ }
+ else
{
- x = ActualLayerImage.Height - 1 - issue.Y;
- y = issue.X;
+ pbLayer.ZoomToRegion(
+ tsLayerImageRotate.Checked ? ActualLayerImage.Height - 1 - issue.BoundingRectangle.Bottom : issue.BoundingRectangle.X,
+ tsLayerImageRotate.Checked ? issue.BoundingRectangle.X : issue.BoundingRectangle.Y,
+ tsLayerImageRotate.Checked ? issue.BoundingRectangle.Height : issue.BoundingRectangle.Width,
+ tsLayerImageRotate.Checked ? issue.BoundingRectangle.Width : issue.BoundingRectangle.Height
+ );
}
-
- //pbLayer.Zoom = 1200;
- pbLayer.ZoomToRegion(x, y, 5, 5);
- pbLayer.ZoomOut(true);
}
tsIssueCount.Tag = lvIssues.SelectedIndices[0];
@@ -1595,54 +1626,27 @@ namespace UVtools.GUI
if (tsLayerImageLayerOutline.Checked)
{
- Image<Gray, byte> grayscale = ActualLayerImage.ToEmguImage();
- //ThresholdBinary(new Gray(127), new Gray(255) )
- ListViewItem item = new ListViewItem();
- //grayscale = grayscale.Canny(80, 40, 3, true);
- //var grayscaleInv = grayscale.ThresholdBinaryInv(new Gray(200), new Gray(255));
+ Image<Gray, byte> greyscale = ActualLayerImage.ToEmguImage();
+#if DEBUG
+ grayscale = grayscale.ThresholdBinary(new Gray(254), new Gray(255));
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
Mat external = new Mat();
-
+
CvInvoke.FindContours(grayscale, contours, external, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
var arr = external.GetData();
-
-
- //
- // hierarchy[i][0]: the index of the next contour of the same level
- // hierarchy[i][1]: the index of the previous contour of the same level
- // hierarchy[i][2]: the index of the first child
- // hierarchy[i][3]: the index of the parent
- //
for (int i = 0; i < contours.Size; i++)
{
if ((int)arr.GetValue(0, i, 2) != -1 || (int)arr.GetValue(0, i, 3) == -1) continue;
var r = CvInvoke.BoundingRectangle(contours[i]);
-
- //CvInvoke.Rectangle(grayscale, r, new MCvScalar(125), 5);
- grayscale.FillConvexPoly(contours[i].ToArray(), new Gray(125), LineType.FourConnected);
- }
-
-
- //var grayscaleinv = grayscale.ThresholdBinaryInv(new Gray(200), new Gray(255));
-
- //grayscale =grayscaleinv;
- /*grayscale = grayscale.Dilate(1).Erode(1);
-
- Gray gray = new Gray(255);
- Mat external = new Mat();
- VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
- CvInvoke.FindContours(grayscale, contours, external, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
-
- for (int i = 0; i < contours.Size; i++)
- {
- grayscale.FillConvexPoly(contours[i].ToArray(), gray, LineType.FourConnected);
+ CvInvoke.Rectangle(grayscale, r, new MCvScalar(125), 10);
}
- */
-
- imageRgba = grayscale.ToImageSharpL8().CloneAs<Rgba32>();
- grayscale.Dispose();
+#else
+ greyscale = greyscale.Canny(80, 40, 3, true);
+#endif
+ imageRgba = greyscale.ToImageSharpL8().CloneAs<Rgba32>();
+ greyscale.Dispose();
}
else if (tsLayerImageLayerDifference.Checked)
{
@@ -1650,7 +1654,7 @@ namespace UVtools.GUI
{
var previousImage = SlicerFile[layerNum-1].Image;
var nextImage = SlicerFile[layerNum+1].Image;
- var newImage = new Image<Rgba32>(previousImage.Width, previousImage.Height);
+ //var newImage = new Image<Rgba32>(previousImage.Width, previousImage.Height);
/*Parallel.For(0, ActualLayerImage.Height, y => {
var newImageSpan = newImage.GetPixelRowSpan(y);
@@ -1722,23 +1726,56 @@ namespace UVtools.GUI
!ReferenceEquals(Issues, null) &&
Issues.TryGetValue(ActualLayer, out var issues))
{
+ imageRgba.TryGetSinglePixelSpan(out var span);
+ byte alpha;
foreach (var issue in issues)
{
if (ReferenceEquals(issue, null)) continue; // Removed issue
if(!issue.HaveValidPoint) continue;
+
+ if (issue.Type == LayerIssue.IssueType.ResinTrap)
+ {
+ using (var dummyImage = new Image<Gray, byte>(ActualLayerImage.Width,
+ ActualLayerImage.Height))
+ {
+ dummyImage.FillConvexPoly(issue.Pixels, new Gray(255));
+ dummyImage.DrawPolyline(issue.Pixels, true, new Gray(125), 2);
+ byte[,,] data = dummyImage.Data;
+ for (int y = issue.BoundingRectangle.Y; y < issue.BoundingRectangle.Bottom; y++)
+ {
+ for (int x = issue.BoundingRectangle.X; x < issue.BoundingRectangle.Right; x++)
+ {
+ if (data[y, x, 0] == 0) continue;
+ if(data[y, x, 0] == 255)
+ span[y * ActualLayerImage.Width + x] = new Rgba32(255, 180, 0);
+ else
+ span[y * ActualLayerImage.Width + x] = new Rgba32(255, 0, 0);
+ }
+ }
+ }
+
+ continue;
+ }
+
foreach (var pixel in issue)
{
- var alpha = ActualLayerImage[pixel.X, pixel.Y].PackedValue;
- if (alpha == 0) continue;
- // alpha, Color.Yellow
- alpha = Math.Max((byte) 80, alpha);
switch (issue.Type)
{
+ /*case LayerIssue.IssueType.ResinTrap:
+ break;*/
case LayerIssue.IssueType.Island:
- imageRgba[pixel.X, pixel.Y] = new Rgba32(alpha, alpha, 0);
+ alpha = ActualLayerImage[pixel.X, pixel.Y].PackedValue;
+ if (alpha == 0) continue;
+ // alpha, Color.Yellow
+ alpha = Math.Max((byte)80, alpha);
+ span[pixel.Y * ActualLayerImage.Width + pixel.X] = new Rgba32(alpha, alpha, 0);
break;
default:
- imageRgba[pixel.X, pixel.Y] = new Rgba32(alpha, 0, 0);
+ alpha = ActualLayerImage[pixel.X, pixel.Y].PackedValue;
+ if (alpha == 0) continue;
+ // alpha, Color.Yellow
+ alpha = Math.Max((byte)80, alpha);
+ span[pixel.Y * ActualLayerImage.Width + pixel.X] = new Rgba32(alpha, 0, 0);
break;
}
@@ -1967,7 +2004,7 @@ namespace UVtools.GUI
return;
}
}
- #endregion
+#endregion
@@ -2264,63 +2301,266 @@ namespace UVtools.GUI
}
}
- /*var layerHollowAreas = new ConcurrentDictionary<uint, List<LayerHollowArea>>();
+ return true;
+ var layerHollowAreas = new ConcurrentDictionary<uint, List<LayerHollowArea>>();
+
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
Parallel.ForEach(SlicerFile,
//new ParallelOptions{MaxDegreeOfParallelism = 1},
layer =>
{
- var image = layer.Image;
- Image<Gray, byte> grayscale = image.ToEmguImage().ThresholdBinary(new Gray(254), new Gray(255));
-
- var listHollowArea = new List<LayerHollowArea>();
-
- VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
- Mat hierarchy = new Mat();
-
- CvInvoke.FindContours(grayscale, contours, hierarchy, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
-
- var arr = hierarchy.GetData();
- //
- //hierarchy[i][0]: the index of the next contour of the same level
- //hierarchy[i][1]: the index of the previous contour of the same level
- //hierarchy[i][2]: the index of the first child
- //hierarchy[i][3]: the index of the parent
- //
- Stopwatch sw = new Stopwatch();
- sw.Start();
- for (int i = 0; i < contours.Size; i++)
+ using (var image = layer.Image)
{
- if ((int) arr.GetValue(0, i, 2) != -1 || (int) arr.GetValue(0, i, 3) == -1) continue;
+ using (Image<Gray, byte> grayscale = image.ToEmguImage().ThresholdBinary(new Gray(254), new Gray(255)))
+ {
+ var listHollowArea = new List<LayerHollowArea>();
- grayscale.Dispose();
- grayscale = new Image<Gray, byte>(image.Width, image.Height);
- //grayscale = grayscale.CopyBlank();
- grayscale.FillConvexPoly(contours[i].ToArray(), new Gray(125));
- List<Point> points = new List<Point>();
+ VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
+ Mat hierarchy = new Mat();
- var rect = CvInvoke.BoundingRectangle(contours[i]);
- byte[,,] data = grayscale.Data;
- for (int y = rect.Y; y < rect.Bottom; y++)
- {
- for (int x = rect.X; x < rect.Right; x++)
+ CvInvoke.FindContours(grayscale, contours, hierarchy, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
+
+ var arr = hierarchy.GetData();
+ //
+ //hierarchy[i][0]: the index of the next contour of the same level
+ //hierarchy[i][1]: the index of the previous contour of the same level
+ //hierarchy[i][2]: the index of the first child
+ //hierarchy[i][3]: the index of the parent
+ //
+
+ for (int i = 0; i < contours.Size; i++)
{
+ if ((int) arr.GetValue(0, i, 2) != -1 || (int) arr.GetValue(0, i, 3) == -1)
+ continue;
- if (data[y, x, 0] != 125) continue;
- points.Add(new Point(x, y)); // Gather pixels
+ listHollowArea.Add(new LayerHollowArea(contours[i].ToArray(), CvInvoke.BoundingRectangle(contours[i]), layer.Index == 0 || layer.Index == SlicerFile.LayerCount-1 ? LayerHollowArea.AreaType.Drain : LayerHollowArea.AreaType.Unknown));
+
+ if (listHollowArea.Count > 0)
+ layerHollowAreas.TryAdd(layer.Index, listHollowArea);
}
}
+ }
+ });
+
+ List<LayerHollowArea> linkedAreas = new List<LayerHollowArea>();
+ LayerHollowArea lastCheckedArea;
+
+ for (uint layerIndex = 1; layerIndex < SlicerFile.LayerCount-1; layerIndex++) // Ignore first and last layers, always drains
+ {
+ if(!layerHollowAreas.TryGetValue(layerIndex, out var areas)) continue; // No hollow areas in this layer, ignore
+
+ byte areaCount = 0;
+ foreach (var area in areas)
+ {
+ if (area.Type != LayerHollowArea.AreaType.Unknown) continue; // processed, ignore
+ area.Type = LayerHollowArea.AreaType.Trap;
+
+ areaCount++;
+
+ linkedAreas.Clear();
+
+ for (sbyte dir = 1; dir >= -1 && area.Type != LayerHollowArea.AreaType.Drain; dir -= 2)
+ {
+ Queue<LayerHollowArea> queue = new Queue<LayerHollowArea>();
+ queue.Enqueue(area);
+ int nextLayerIndex = (int) layerIndex;
+ while (queue.Count > 0 && area.Type != LayerHollowArea.AreaType.Drain)
+ {
+ lastCheckedArea = queue.Dequeue();
+ nextLayerIndex += dir;
+ Debug.WriteLine($"Area Count: {areaCount} | Layer: {layerIndex} | Next Layer: {nextLayerIndex} | Dir: {dir}");
+ if (nextLayerIndex < 0 && nextLayerIndex >= SlicerFile.LayerCount) break; // Exhaust layers
+ bool haveNextAreas = layerHollowAreas.TryGetValue((uint)nextLayerIndex, out var nextAreas);
+
+ using (var image = SlicerFile[nextLayerIndex].Image)
+ {
+ using (var emguImage = new Image<Gray, byte>(ActualLayerImage.Width, ActualLayerImage.Height))
+ {
+ image.TryGetSinglePixelSpan(out var span);
+ emguImage.FillConvexPoly(lastCheckedArea.Contour, new Gray(255));
+
+ bool exitPixelLoop = false;
+
+ byte[,,] data = emguImage.Data;
+ for (int y = lastCheckedArea.BoundingRectangle.Y;
+ y <= lastCheckedArea.BoundingRectangle.Bottom && area.Type != LayerHollowArea.AreaType.Drain && !exitPixelLoop;
+ y++)
+ {
+ for (int x = lastCheckedArea.BoundingRectangle.X;
+ x <= lastCheckedArea.BoundingRectangle.Right && area.Type != LayerHollowArea.AreaType.Drain && !exitPixelLoop;
+ x++)
+ {
+
+ if (data[y, x, 0] != 255) continue;
+
+ if (span[y * image.Width + x] == Helpers.L8Black) // Found a black pixel: Drain or trap
+ {
+ if (haveNextAreas)
+ {
+ foreach (var nextArea in nextAreas)
+ {
+ if (!area.BoundingRectangle.IntersectsWith(nextArea.BoundingRectangle)) // If not intersect futher ispection is useless
+ {
+ continue;
+ }
+ if (CvInvoke.PointPolygonTest(new VectorOfPoint(nextArea.Contour),
+ new PointF(x, y), false) >= 0)
+ {
+ if (nextArea.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
+ {
+ area.Type = LayerHollowArea.AreaType.Drain;
+ }
+ else
+ {
+ queue.Enqueue(nextArea);
+ }
+
+ linkedAreas.Add(nextArea);
+
+ exitPixelLoop = true;
+ break;
+ }
+ }
+ }
+ else // Black pixel without next areas = Drain
+ {
+ area.Type = LayerHollowArea.AreaType.Drain;
+ exitPixelLoop = true;
+ break;
+ }
+ } // black check
+ } // X loop
+ } // Y loop
+ } // Dispose emgu image
+ } // Dispose image
+ } // Areas loop
+ } // Dir layer loop
+
+ foreach (var linkedArea in linkedAreas) // Update linked areas
+ {
+ linkedArea.Type = area.Type;
+ }
+
+ /*for (sbyte dir = 1; dir >= -1; dir-=2)
+ {
+ Debug.WriteLine($"dir: {dir}");
+ for (int nextLayerIndex = (int) (layerIndex + dir); nextLayerIndex >= 0 && nextLayerIndex < SlicerFile.LayerCount; nextLayerIndex+= dir) // Search on next layer
+ {
+ Debug.WriteLine($"Next Layer: {nextLayerIndex}");
+ bool nextHaveAreas = layerHollowAreas.TryGetValue((uint) nextLayerIndex, out var nextList);
+ // if (!layerHollowAreas.TryGetValue((uint) i, out var nextList)) // No areas found on next layer, check for tops
+ // {
+ area.Type = LayerHollowArea.AreaType.Trap;
+ using (var image = SlicerFile[nextLayerIndex].Image)
+ {
+ using (var emguImage = new Image<Gray, byte>(ActualLayerImage.Width, ActualLayerImage.Height))
+ {
+ image.TryGetSinglePixelSpan(out var span);
+ emguImage.FillConvexPoly(lastCheckedArea.Contour, new Gray(255));
+
+ byte[,,] data = emguImage.Data;
+ for (int y = lastCheckedArea.BoundingRectangle.Y;
+ y < lastCheckedArea.BoundingRectangle.Bottom && area.Type != LayerHollowArea.AreaType.Drain;
+ y++)
+ {
+ for (int x = lastCheckedArea.BoundingRectangle.X;
+ x < lastCheckedArea.BoundingRectangle.Right && area.Type != LayerHollowArea.AreaType.Drain;
+ x++)
+ {
+
+ if (data[y, x, 0] != 255) continue;
+
+ var pixelIndex = y * image.Width + x;
+ if (span[pixelIndex] == Helpers.L8Black) // Found a black pixel: Drain
+ {
+ if (nextHaveAreas)
+ {
+ foreach (var nextArea in nextList)
+ {
+ if (CvInvoke.PointPolygonTest(new VectorOfPoint(nextArea.Contour),
+ new PointF(x, y), false) > 0)
+ {
+ linkedAreas.Add(nextArea);
+ if (nextArea.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
+ {
+ area.Type = nextArea.Type;
+ }
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ area.Type = LayerHollowArea.AreaType.Drain;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
- listHollowArea.Add(new LayerHollowArea(points.ToArray()));
+ if (area.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
+ {
+ break;
+ }
+ //}
+
+ /*foreach (var nextArea in nextList)
+ {
+ if (area.BoundingRectangle.IntersectsWith(nextArea.BoundingRectangle))
+ {
+ lastCheckedArea = nextArea;
+ linkedAreas.Add(nextArea);
+ if (nextArea.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
+ {
+ area.Type = nextArea.Type;
+ break;
+ }
+ }
+ }*/
+ /*}
+
+ if(area.Type == LayerHollowArea.AreaType.Drain) // Found a drain, stop query
+ break;
}
- sw.Stop();
- Debug.WriteLine(sw.ElapsedMilliseconds);
+ foreach (var linkedArea in linkedAreas) // Update linked areas
+ {
+ linkedArea.Type = area.Type;
+ }*/
+ }
+ }
- if (listHollowArea.Count > 0)
- layerHollowAreas.TryAdd(layer.Index, listHollowArea);
- });*/
+ Issues = new Dictionary<uint, List<LayerIssue>>();
+ for (uint layerIndex = 0; layerIndex < SlicerFile.LayerCount; layerIndex++)
+ {
+ if (!layerHollowAreas.TryGetValue(layerIndex, out var list)) continue;
+ if (list.Count > 0)
+ {
+ var issuesHollow = new List<LayerIssue>();
+
+ foreach (var area in list)
+ {
+ if (area.Type == LayerHollowArea.AreaType.Trap)
+ {
+ issuesHollow.Add(new LayerIssue(SlicerFile[layerIndex], LayerIssue.IssueType.ResinTrap, area.Contour, area.BoundingRectangle));
+ }
+ }
+
+ if (issues.Count > 0)
+ {
+ Issues.Add(layerIndex, issuesHollow);
+ }
+ }
+ }
+
+ sw.Stop();
+ Debug.WriteLine($"RectSearch: {sw.ElapsedMilliseconds}ms");
result = true;
}
@@ -2347,19 +2587,23 @@ namespace UVtools.GUI
try
{
- foreach (var kv in Issues)
+ if (!ReferenceEquals(Issues, null))
{
- foreach (var issue in kv.Value)
+ foreach (var kv in Issues)
{
- TotalIssues++;
- count++;
- ListViewItem item = new ListViewItem(lvIssues.Groups[(int)issue.Type]) {Text = issue.Type.ToString() };
- item.SubItems.Add(count.ToString());
- item.SubItems.Add(kv.Key.ToString());
- item.SubItems.Add($"{issue.X}, {issue.Y}");
- item.SubItems.Add(issue.Size.ToString());
- item.Tag = issue;
- lvIssues.Items.Add(item);
+ foreach (var issue in kv.Value)
+ {
+ TotalIssues++;
+ count++;
+ ListViewItem item = new ListViewItem(lvIssues.Groups[(int) issue.Type])
+ {Text = issue.Type.ToString()};
+ item.SubItems.Add(count.ToString());
+ item.SubItems.Add(kv.Key.ToString());
+ item.SubItems.Add($"{issue.X}, {issue.Y}");
+ item.SubItems.Add(issue.Size.ToString());
+ item.Tag = issue;
+ lvIssues.Items.Add(item);
+ }
}
}
}
diff --git a/UVtools.GUI/FrmMain.resx b/UVtools.GUI/FrmMain.resx
index 0d12783..fb7b729 100644
--- a/UVtools.GUI/FrmMain.resx
+++ b/UVtools.GUI/FrmMain.resx
@@ -126,12 +126,6 @@
<metadata name="tsLayer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>201, 17</value>
</metadata>
- <metadata name="tsThumbnails.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>291, 17</value>
- </metadata>
- <metadata name="tsProperties.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- <value>649, 17</value>
- </metadata>
<metadata name="tsGCode.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>551, 17</value>
</metadata>
@@ -145,70 +139,85 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
- ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABA
- DgAAAk1TRnQBSQFMAgEBBAEAAegBAwHoAQMBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA4
+ DgAAAk1TRnQBSQFMAgEBBAEAASABBAEgAQQBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AZgADUAGjA1IBqQNS
- AakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1ABo1wAAxUBHQE9AYUBlwH1
- ATkBjwGkAfcDQwF3A1sByAJCAY0B9QJYAWYB4wNKAYwDCgENBAADVQG0A1kBxwMvAUkDAAEBAxsBJgMc
+ AakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1ABo1wAAxUBHQFCAXABgAH1
+ AUABhQGMAfcDQwF3A1sByAJCAXsB9QJYAV8B4wNKAYwDCgENBAADVQG0A1kBxwMvAUkDAAEBAxsBJgMc
AScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDAgEDBAADUgGpMAADUgGpEAADJwE6
AzABTAMwAUwDMAFMAzABTAMwAUwDMAFMAzABTAMwAUwDJwE6FAADBQEHA0wBkgFWAlgBwQMVAR0DPQFp
- ARAByAHzAf8BHgGQAeYB/wI0AdwB/wI0Ad0B/wJpAeMB/wI/Ad4B/wI0Ad0B/wJYAVsBywMGAQgDAAH/
+ AQkByAHzAf8BFwGQAeYB/wItAdwB/wItAd0B/wJiAeMB/wI4Ad4B/wItAd0B/wJYAVsBywMGAQgDAAH/
AwAB/wNDAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMgFR
BAADUgGpBAADUAGdA1MBqgNTAaoDUwGqA1MBqgNTAaoDUwGqA1ABnQwAA1IBqRAAA04B+wMAAf8DAAH/
- AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A04B+xQAATACMQFNAREByQHzAf8BEQHJAfQB/wFVAXQBewHr
- AVoBXwFgAdkBFAHAAfEB/wE1AT0B3wH/AjcB4AH/AjcB4AH/AnAB6QH/AkIB4gH/AjcB4AH/AjcB4AH/
- A0ABcQNRAaIDVgG2AyoBQAQAAxABFQMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMQ
- ARYIAANSAakEAANQAZ0DUwGqA1MBqgMfASwcAANSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/
- AwAB/wMAAf8DAAH/FAADBwEKAUgBhAGQAfIBEwHKAfQB/wETAcoB9AH/ARMBygH0Af8BHwGhAe4B/wI6
- AeMB/wI6AeMB/wI6AeMB/wKpAe8B/wJBAeMB/wI6AeMB/wI6AeMB/wJWAVgBuQMKAQ4DEQEXAwABATgA
- A1IBqTAAA1IBqRMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8MAAMVAR0DPQFp
- AzoBYgFcAmAB1AEUAcsB9QH/ARQBywH1Af8BFAHLAfUB/wEiAaAB8AH/Aj0B5gH/Aj0B5gH/Aj0B5gH/
- AsIB9gH/AlUB6AH/Aj0B5gH/Aj0B5gH/AlcBWQG/A1IB9AMAAf8DPgFsAw4BEwNCAXYDQwF3A0MBdwND
- AXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQgF2AxQBGwQAA1IBqQMiATIDUgGpA1IBqQNSAakDUgGp
- A1IBqQNSAakDUgGpA1IBqQNSAakDUgGpAyIBMgNSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/
- AwAB/wMAAf8DAAH/DAABSwJMAZABFQHLAfYB/wEVAcsB9gH/ARUBywH2Af8BFQHLAfYB/wEpAaIBvAH6
- A0MBeAMiATICSwG+AfsCQAHpAf8CQAHpAf8CzQH4Af8CZAHtAf8CQAHpAf8CQAHpAf8DUAGeAwAB/gMA
- Af8DQwF3Ax4BKwNXAcUDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWAHGAyYBOQQA
- A1IBqQM0AVUDNAFVIAADNAFVAzQBVQNSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
- Af8DAAH/DAADUQGgARcBzAH3Af8BFwHMAfcB/wEXAcwB9wH/ARcBzAH3Af8DQwF3CAADSgGNAkMB7AH/
- AkMB7AH/Al8B7wH/AkcB7AH/AkMB7AH/AT8BUAHtAf8BUgJTAagDMwFTAzwBZwMUARw4AANSAakDNAFV
- AzQBVQNGAYADUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDRQF/AzQBVQM0AVUDUgGpEwAB/wMAAf8DAAH/
- AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/w8AAQEBPwJAAW8BPAGbAbEB+AEYAc0B9wH/ARgBzQH3
- Af8DEgEYCAADAQECA0YBfgJSAYYB8AJGAe4B/wFGAUcB7gH/AUABXQHRAf0BRQJGAX4DAwEEAzMBUwM8
- AWcDFAEcOAADUgGpAzQBVQM0AVUDPwFuAzIBUBAAAycBOwNEAXwDNAFVAzQBVQNSAakTAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DwABAQE/AkABbwE9AZsBsQH4ARkBzgH4Af8BGQHO
- AfgB/wMSARgQAAMXAiABvAH3Af8BHQHEAfcB/wEvAbkB1wH9AUUCRgF+AwMBBAMAAf4DAAH/A0MBdwMf
+ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A04B+xQAATACMQFNAQoByQHzAf8BCgHJAfQB/wFZAWcBaQHr
+ AVsCXgHZAQ0BwAHxAf8BLgE2Ad8B/wIwAeAB/wIwAeAB/wJpAekB/wI7AeIB/wIwAeAB/wIwAeAB/wNA
+ AXEDUQGiA1YBtgMqAUAEAAMQARUDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEAEW
+ CAADUgGpBAADUAGdA1MBqgNTAaoDHwEsHAADUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AwAB/xQAAwcBCgFPAXIBeQHyAQwBygH0Af8BDAHKAfQB/wEMAcoB9AH/ARgBoQHuAf8CMwHj
+ Af8CMwHjAf8CMwHjAf8CqQHvAf8COgHjAf8CMwHjAf8CMwHjAf8CVgFYAbkDCgEOAxEBFwMAAQE4AANS
+ AakwAANSAakTAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADFQEdAz0BaQM6
+ AWIBXAJgAdQBDQHLAfUB/wENAcsB9QH/AQ0BywH1Af8BGwGgAfAB/wI2AeYB/wI2AeYB/wI2AeYB/wLC
+ AfYB/wJOAegB/wI2AeYB/wI2AeYB/wJXAVkBvwNSAfQDAAH/Az4BbAMOARMDQgF2A0MBdwNDAXcDQwF3
+ A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0IBdgMUARsEAANSAakDIgEyA1IBqQNSAakDUgGpA1IBqQNS
+ AakDUgGpA1IBqQNSAakDUgGpA1IBqQMiATIDUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AwAB/wwAAUsCTAGQAQ4BywH2Af8BDgHLAfYB/wEOAcsB9gH/AQ4BywH2Af8BKQGSAaQB+gND
+ AXgDIgEyAksBogH7AjkB6QH/AjkB6QH/As0B+AH/Al0B7QH/AjkB6QH/AjkB6QH/A1ABngMAAf4DAAH/
+ A0MBdwMeASsDVwHFA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1gBxgMmATkEAANS
+ AakDNAFVAzQBVSAAAzQBVQM0AVUDUgGpEwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/
+ AwAB/wwAA1EBoAEQAcwB9wH/ARABzAH3Af8BEAHMAfcB/wEQAcwB9wH/A0MBdwgAA0oBjQI8AewB/wI8
+ AewB/wJYAe8B/wJAAewB/wI8AewB/wE4AUkB7QH/AVICUwGoAzMBUwM8AWcDFAEcOAADUgGpAzQBVQM0
+ AVUDRgGAA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA0UBfwM0AVUDNAFVA1IBqRMAAf8DAAH/AwAB/wMA
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8PAAEBAT8CQAFvAT4BiwGYAfgBEQHNAfcB/wERAc0B9wH/
+ AxIBGAgAAwEBAgNGAX4CUgFsAfACPwHuAf8BPwFAAe4B/wFAAVIBvgH9AUUCRgF+AwMBBAMzAVMDPAFn
+ AxQBHDgAA1IBqQM0AVUDNAFVAz8BbgMyAVAQAAMnATsDRAF8AzQBVQM0AVUDUgGpEwAB/wMAAf8DAAH/
+ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/w8AAQEBPwJAAW8BPgGLAZgB+AESAc4B+AH/ARIBzgH4
+ Af8DEgEYEAADFwEgARkBvAH3Af8BFgHEAfcB/wE2AbIBwgH9AUUCRgF+AwMBBAMAAf4DAAH/A0MBdwMf
ASwDVwHFA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1kBxwNZAccDWQHHA1gBxgMmATkEAANSAakDNAFV
AzQBVQMFAQcDVQG1AxEBFwNSAakDKQE+BAADUAGfAxEBFwM0AVUDNAFVA1IBqRMAAf8DAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8MAANRAaABGwHOAfgB/wEbAc8B+QH/ARsBzwH5Af8BGwHP
- AfkB/wNDAXcQAANEAXoBGwHPAfkB/wEbAc8B+QH/ARsBzwH5Af8BGwHOAfgB/wFSAlMBqANSAfQDAAH/
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8MAANRAaABFAHOAfgB/wEUAc8B+QH/ARQBzwH5Af8BFAHP
+ AfkB/wNDAXcQAANEAXoBFAHPAfkB/wEUAc8B+QH/ARQBzwH5Af8BFAHOAfgB/wFSAlMBqANSAfQDAAH/
Az4BbAMOARMDQgF1A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwNDAXcDQwF3A0MBdwMUARsEAANS
AakDNAFVAzQBVQQAAzwBaANWAb4DIwE0A1UBtQMSARkDUQGgBAADNAFVAzQBVQNSAakTAAH/AwAB/wMA
- Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfDAABSwJMAZABHAHQAfoB/wEcAdAB+gH/ARwB0AH6
- Af8BHAHQAfoB/wEpAaIBuwH6A0MBeAMSARkDEwEaA0QBegEoAaMBxQH7ARwB0AH6Af8BHAHQAfoB/wEc
- AdAB+gH/ARwB0AH6Af8DSgGMAwoBDgMRARcDAAEBOAADUgGpAzQBVQM0AVUDAAEBAy0BRgMKAQ4EAAM5
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfDAABSwJMAZABFQHQAfoB/wEVAdAB+gH/ARUB0AH6
+ Af8BFQHQAfoB/wEpAZIBpAH6A0MBeAMSARkDEwEaA0QBegEoAZUBqwH7ARUB0AH6Af8BFQHQAfoB/wEV
+ AdAB+gH/ARUB0AH6Af8DSgGMAwoBDgMRARcDAAEBOAADUgGpAzQBVQM0AVUDAAEBAy0BRgMKAQ4EAAM5
AV8DXAHOAygBPAQAAzQBVQM0AVUDUgGpEwAB/wOCAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHf
- AxcBIAwAAxUBHQM9AWkDOgFiAVwCYAHUAR0B0QH6Af8BHQHRAfoB/wEdAdAB+gH/AR0BywHzAf8BHQHL
- AfMB/wEdAdAB+gH/AR0B0QH6Af8BHQHRAfoB/wFaAWUBagHiAzoBYgM9AWkDFAEcA1EBogNWAbYDKgFA
- BAADEAEVAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxABFggAA1IBqQM0AVUDNAFV
- AzMBUwNSAaYDSgGMBwABAQNHAYMIAAM0AVUDNAFVA1IBqRMAAf8DmQH/A4UB/wMAAf8DAAH/AwAB/wMA
- Af8DXAHfAxcBIBgAAwcBCgFKAYUBkAHyAR8B0gH7Af8BHwHSAfsB/wEfAdIB+wH/AR8B0gH7Af8BHwHS
- AfsB/wEfAdIB+wH/AR8B0gH7Af8BHwHSAfsB/wErAacBxQH7AxEBFwsAAf8DAAH/A0MBdwMpAT4DAAH/
- AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMyAVEEAANSAakDNAFVAzQBVQMR
- ARcDUAGeAyQBNhQAAzQBVQM0AVUDUgGpEAADUAH7AwAB/wMAAf8DAAH/AwAB/wMAAf8DXAHfAxcBIBwA
- ATACMQFNASAB0gH8Af8BIAHSAfwB/wFXAXcBfQHrAVoBXwFgAdkBIAHSAfwB/wEgAdIB/AH/AVsBZwFp
- AeEBWgFmAWoB4gEgAdIB/AH/ASAB0gH8Af8DOAFeCAADVQG0A1kBxwMvAUkDAAEBAxsBJgMcAScDHAEn
- AxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDAgEDBAADUgGpAyIBMgNSAakDUgGpA1IBqQNS
- AakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDIgEyA1IBqRAAAyABLgMpAT8DKQE/AykBPwMpAT8DKQE/
- AxEBFyAAAwUBBwNMAZIBVgJYAcEDFQEdAz0BaQEhAdMB/AH/ASEB0wH8Af8BRQJGAX8DEAEVA1YBswFL
- AkwBjwMEAQZMAANQAaMDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNS
- AakDUAGjXAADFQEdAUIBjQGfAfUBPgGeAa8B9wMgAS8YAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEB
- AQABAQYAAQEWAAP/gQAC/wGAAQEC/wH8AQECAAG/Af0B4AEHAcADAAGgAR0B4AEHAcABAAEQAQEBoQH9
- AeABBwHAAQABHwH/Ab8B/QHgAQcEAAGAAQEB4AEHBAABjwHxAeABBwEDAQABHwH/AYABAQHgAQcBAwEA
- AR8B/wGDAcEB4AEHAQMBwAIAAYABQQHgAQcBAwHAAgABiAERAeABBwIAAR8B/wGBAREB4AEHAgABEAEB
- AYEBMQHgAQ8BwAEDAgABgQHxAeABHwHAAQMCAAGAAQEB4AE/AcABAwL/AYABAQL/AfwBPws=
+ AxcBIAwAAxUBHQM9AWkDOgFiAVwCYAHUARYB0QH6Af8BFgHRAfoB/wEWAdAB+gH/ARYBywHzAf8BFgHL
+ AfMB/wEWAdAB+gH/ARYB0QH6Af8BFgHRAfoB/wFdAmEB4gM6AWIDPQFpAxQBHANRAaIDVgG2AyoBQAQA
+ AxABFQMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMQARYIAANSAakDNAFVAzQBVQMz
+ AVMDUgGmA0oBjAcAAQEDRwGDCAADNAFVAzQBVQNSAakTAAH/A5kB/wOFAf8DAAH/AwAB/wMAAf8DAAH/
+ A1wB3wMXASAYAAMHAQoBUwFyAXkB8gEYAdIB+wH/ARgB0gH7Af8BGAHSAfsB/wEYAdIB+wH/ARgB0gH7
+ Af8BGAHSAfsB/wEYAdIB+wH/ARgB0gH7Af8BKwGWAasB+wMRARcLAAH/AwAB/wNDAXcDKQE+AwAB/wMA
+ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMgFRBAADUgGpAzQBVQM0AVUDEQEX
+ A1ABngMkATYUAAM0AVUDNAFVA1IBqRAAA1AB+wMAAf8DAAH/AwAB/wMAAf8DAAH/A1wB3wMXASAcAAEw
+ AjEBTQEZAdIB/AH/ARkB0gH8Af8BWQFoAWoB6wFbAl4B2QEZAdIB/AH/ARkB0gH8Af8BWwJhAeEBXQJh
+ AeIBGQHSAfwB/wEZAdIB/AH/AzgBXggAA1UBtANZAccDLwFJAwABAQMbASYDHAEnAxwBJwMcAScDHAEn
+ AxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAwIBAwQAA1IBqQMiATIDUgGpA1IBqQNSAakDUgGpA1IBqQNS
+ AakDUgGpA1IBqQNSAakDUgGpAyIBMgNSAakQAAMgAS4DKQE/AykBPwMpAT8DKQE/AykBPwMRARcgAAMF
+ AQcDTAGSAVYCWAHBAxUBHQM9AWkBGgHTAfwB/wEaAdMB/AH/AUUCRgF/AxABFQNWAbMBSwJMAY8DBAEG
+ TAADUAGjA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1IBqQNSAakDUgGpA1ABo1wA
+ AxUBHQFCAXsBhAH1AUoBiQGWAfcDIAEvGAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEB
+ FgAD/4EAAv8BgAEBAv8B/AEBAgABvwH9AeABBwHAAwABoAEdAeABBwHAAQABEAEBAaEB/QHgAQcBwAEA
+ AR8B/wG/Af0B4AEHBAABgAEBAeABBwQAAY8B8QHgAQcBAwEAAR8B/wGAAQEB4AEHAQMBAAEfAf8BgwHB
+ AeABBwEDAcACAAGAAUEB4AEHAQMBwAIAAYgBEQHgAQcCAAEfAf8BgQERAeABBwIAARABAQGBATEB4AEP
+ AcABAwIAAYEB8QHgAR8BwAEDAgABgAEBAeABPwHAAQMC/wGAAQEC/wH8AT8L
</value>
</data>
+ <metadata name="tsThumbnails.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>291, 17</value>
+ </metadata>
+ <metadata name="tsProperties.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>649, 17</value>
+ </metadata>
+ <metadata name="tsGCode.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>551, 17</value>
+ </metadata>
+ <metadata name="tsIssues.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>765, 17</value>
+ </metadata>
+ <metadata name="toolTipInformation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>863, 17</value>
+ </metadata>
<metadata name="toolTipInformation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>863, 17</value>
</metadata>
diff --git a/UVtools.GUI/Images/clipboard-16x16.png b/UVtools.GUI/Images/clipboard-16x16.png
new file mode 100644
index 0000000..42f9370
--- /dev/null
+++ b/UVtools.GUI/Images/clipboard-16x16.png
Binary files differ
diff --git a/UVtools.GUI/Images/file-image-16x16.png b/UVtools.GUI/Images/file-image-16x16.png
new file mode 100644
index 0000000..7e10379
--- /dev/null
+++ b/UVtools.GUI/Images/file-image-16x16.png
Binary files differ
diff --git a/UVtools.GUI/Properties/AssemblyInfo.cs b/UVtools.GUI/Properties/AssemblyInfo.cs
index 674c0cc..04bc2a1 100644
--- a/UVtools.GUI/Properties/AssemblyInfo.cs
+++ b/UVtools.GUI/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.5.1.2")]
-[assembly: AssemblyFileVersion("0.5.1.2")]
+[assembly: AssemblyVersion("0.5.1.3")]
+[assembly: AssemblyFileVersion("0.5.1.3")]
diff --git a/UVtools.GUI/Properties/Resources.Designer.cs b/UVtools.GUI/Properties/Resources.Designer.cs
index 0bf6de3..d20e24b 100644
--- a/UVtools.GUI/Properties/Resources.Designer.cs
+++ b/UVtools.GUI/Properties/Resources.Designer.cs
@@ -193,6 +193,16 @@ namespace UVtools.GUI.Properties {
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
+ internal static System.Drawing.Bitmap clipboard_16x16 {
+ get {
+ object obj = ResourceManager.GetObject("clipboard-16x16", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ /// </summary>
internal static System.Drawing.Bitmap CNCMachine_16x16 {
get {
object obj = ResourceManager.GetObject("CNCMachine-16x16", resourceCulture);
@@ -293,6 +303,16 @@ namespace UVtools.GUI.Properties {
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
+ internal static System.Drawing.Bitmap file_image_16x16 {
+ get {
+ object obj = ResourceManager.GetObject("file-image-16x16", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ /// </summary>
internal static System.Drawing.Bitmap File_Refresh_16x16 {
get {
object obj = ResourceManager.GetObject("File-Refresh-16x16", resourceCulture);
diff --git a/UVtools.GUI/Properties/Resources.resx b/UVtools.GUI/Properties/Resources.resx
index 0fb1e7a..a53bad9 100644
--- a/UVtools.GUI/Properties/Resources.resx
+++ b/UVtools.GUI/Properties/Resources.resx
@@ -157,6 +157,9 @@
<data name="arrow-up-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\arrow-up-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
+ <data name="file-image-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Images\file-image-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </data>
<data name="warning-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\warning-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
@@ -175,15 +178,15 @@
<data name="arrow-up" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\arrow-up.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
+ <data name="SaveAs-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Images\SaveAs-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </data>
<data name="Ok-24x24" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\Ok-24x24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Button-Info-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\Button-Info-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
- <data name="arrow-down-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
- <value>..\Images\arrow-down-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
- </data>
<data name="Next-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\Next-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
@@ -208,11 +211,14 @@
<data name="eye-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\eye-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
+ <data name="mutation_tophat" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Images\gui\mutation_tophat.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </data>
<data name="Geometry-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\Geometry-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
- <data name="mutation_tophat" type="System.Resources.ResXFileRef, System.Windows.Forms">
- <value>..\Images\gui\mutation_tophat.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ <data name="CNCMachine-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Images\CNCMachine-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="plus" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\plus.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
@@ -238,14 +244,14 @@
<data name="arrow-end-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\arrow-end-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
- <data name="SaveAs-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
- <value>..\Images\SaveAs-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ <data name="checkbox-unmarked-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Images\checkbox-unmarked-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="delete-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\delete-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
- <data name="CNCMachine-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
- <value>..\Images\CNCMachine-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ <data name="arrow-down-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Images\arrow-down-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="pointer-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\pointer-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
@@ -268,7 +274,7 @@
<data name="island-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\island-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
- <data name="checkbox-unmarked-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
- <value>..\Images\checkbox-unmarked-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ <data name="clipboard-16x16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Images\clipboard-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> \ No newline at end of file
diff --git a/UVtools.GUI/UVtools.GUI.csproj b/UVtools.GUI/UVtools.GUI.csproj
index 13f8a4f..79782a2 100644
--- a/UVtools.GUI/UVtools.GUI.csproj
+++ b/UVtools.GUI/UVtools.GUI.csproj
@@ -273,6 +273,8 @@
<ItemGroup>
<None Include="Images\checkbox-marked-16x16.png" />
<None Include="Images\checkbox-unmarked-16x16.png" />
+ <None Include="Images\file-image-16x16.png" />
+ <None Include="Images\clipboard-16x16.png" />
<Content Include="UVtools.ico" />
<None Include="UVtools.png" />
<None Include="Images\Exit-16x16.png" />
diff --git a/UVtools.Parser/ChituboxFile.cs b/UVtools.Parser/ChituboxFile.cs
index 6c88700..5c3c1f3 100644
--- a/UVtools.Parser/ChituboxFile.cs
+++ b/UVtools.Parser/ChituboxFile.cs
@@ -533,8 +533,6 @@ namespace UVtools.Parser
{
var layer = parent.LayersDefinitions[bit, layerIndex];
- byte bitValue = (byte)(byte.MaxValue / ((1 << parent.AntiAliasing) - 1) * (1 << bit));
-
int n = 0;
for (int index = 0; index < layer.DataSize; index++)
{
@@ -547,7 +545,7 @@ namespace UVtools.Parser
{
for (int i = 0; i < reps; i++)
{
- span[n + i].PackedValue |= bitValue;
+ span[n + i].PackedValue++;
}
}
@@ -565,6 +563,20 @@ namespace UVtools.Parser
}
}
+ for (int i = 0; i < span.Length; i++)
+ {
+ int newC = span[i].PackedValue * (256 / parent.AntiAliasing);
+
+ if (newC > 0)
+ {
+ newC--;
+ }
+
+ span[i].PackedValue = (byte) newC;
+
+
+ }
+
return image;
}
@@ -655,6 +667,14 @@ namespace UVtools.Parser
bool obit = false;
int rep = 0;
+ //ngrey:= uint16(r | g | b)
+ // thresholds:
+ // aa 1: 127
+ // aa 2: 255 127
+ // aa 4: 255 191 127 63
+ // aa 8: 255 223 191 159 127 95 63 31
+ byte threshold = (byte)(256 / Parent.AntiAliasing * bit - 1);
+
void AddRep()
{
if (rep <= 0) return;
@@ -675,9 +695,7 @@ namespace UVtools.Parser
Span<L8> pixelRowSpan = image.GetPixelRowSpan(y);
for (int x = 0; x < image.Width; x++)
{
- //ngrey:= uint16(r | g | b)
-
- var nbit = (pixelRowSpan[x].PackedValue & (1 << (8 - Parent.AntiAliasing + bit))) != 0;
+ var nbit = pixelRowSpan[x].PackedValue >= threshold;
if (nbit == obit)
{
diff --git a/UVtools.Parser/LayerManager.cs b/UVtools.Parser/LayerManager.cs
index 11b55b8..0403e49 100644
--- a/UVtools.Parser/LayerManager.cs
+++ b/UVtools.Parser/LayerManager.cs
@@ -16,6 +16,7 @@ using UVtools.Parser.Extensions;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using Point = System.Drawing.Point;
+using Rectangle = System.Drawing.Rectangle;
namespace UVtools.Parser
{
@@ -47,6 +48,11 @@ namespace UVtools.Parser
public Point[] Pixels { get; }
/// <summary>
+ /// Gets the bounding rectangle of the pixel area
+ /// </summary>
+ public Rectangle BoundingRectangle { get; }
+
+ /// <summary>
/// Gets the X coordinate for the first point, -1 if doesn't exists
/// </summary>
public int X => HaveValidPoint ? Pixels[0].X : -1;
@@ -71,11 +77,12 @@ namespace UVtools.Parser
/// </summary>
public bool HaveValidPoint => !ReferenceEquals(Pixels, null) && Pixels.Length > 0;
- public LayerIssue(Layer layer, IssueType type, Point[] pixels = null)
+ public LayerIssue(Layer layer, IssueType type, Point[] pixels = null, Rectangle boundingRectangle = new Rectangle())
{
Layer = layer;
Type = type;
Pixels = pixels;
+ BoundingRectangle = boundingRectangle;
}
public Point this[uint index] => Pixels[index];
@@ -112,30 +119,32 @@ namespace UVtools.Parser
/// <summary>
/// Gets area pixels
/// </summary>
- public Point[] Pixels { get; set; }
+ public Point[] Contour { get; }
+
+ public System.Drawing.Rectangle BoundingRectangle { get; }
public AreaType Type { get; set; } = AreaType.Unknown;
#region Indexers
public Point this[uint index]
{
- get => index < Pixels.Length ? Pixels[index] : Point.Empty;
- set => Pixels[index] = value;
+ get => index < Contour.Length ? Contour[index] : Point.Empty;
+ set => Contour[index] = value;
}
public Point this[int index]
{
- get => index < Pixels.Length ? Pixels[index] : Point.Empty;
- set => Pixels[index] = value;
+ get => index < Contour.Length ? Contour[index] : Point.Empty;
+ set => Contour[index] = value;
}
public Point this[uint x, uint y]
{
get
{
- for (uint i = 0; i < Pixels.Length; i++)
+ for (uint i = 0; i < Contour.Length; i++)
{
- if (Pixels[i].X == x && Pixels[i].Y == y) return Pixels[i];
+ if (Contour[i].X == x && Contour[i].Y == y) return Contour[i];
}
return Point.Empty;
}
@@ -147,11 +156,9 @@ namespace UVtools.Parser
#endregion
-
-
public IEnumerator<Point> GetEnumerator()
{
- return ((IEnumerable<Point>)Pixels).GetEnumerator();
+ return ((IEnumerable<Point>)Contour).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
@@ -163,9 +170,11 @@ namespace UVtools.Parser
{
}
- public LayerHollowArea(Point[] pixels)
+ public LayerHollowArea(Point[] contour, System.Drawing.Rectangle boundingRectangle, AreaType type = AreaType.Unknown)
{
- Pixels = pixels;
+ Contour = contour;
+ BoundingRectangle = boundingRectangle;
+ Type = type;
}
}
#endregion
@@ -439,7 +448,10 @@ namespace UVtools.Parser
pixels.Add(new Point(x, y));
islandSupportingPixels = previousBytes[pixelIndex] >= minPixelForSupportIsland ? 1u : 0;
-
+ int minX = x;
+ int maxX = x;
+ int minY = y;
+ int maxY = y;
int x2;
int y2;
@@ -472,6 +484,11 @@ namespace UVtools.Parser
pixels.Add(point);
queue.Enqueue(point);
+ minX = Math.Min(minX, tempx2);
+ maxX = Math.Max(maxX, tempx2);
+ minY = Math.Min(minY, tempy2);
+ maxY = Math.Max(maxY, tempy2);
+
islandSupportingPixels += previousBytes[pixelIndex] >= minPixelForSupportIsland ? 1u : 0;
}
}
@@ -482,7 +499,7 @@ namespace UVtools.Parser
continue; // Not a island, bounding is strong
if (islandSupportingPixels > 0 && pixels.Count < requiredPixelsToSupportIsland &&
islandSupportingPixels >= Math.Max(1, pixels.Count / 2)) continue; // Not a island
- result.Add(new LayerIssue(this, LayerIssue.IssueType.Island, pixels.ToArray()));
+ result.Add(new LayerIssue(this, LayerIssue.IssueType.Island, pixels.ToArray(), new Rectangle(minX, minY, maxX-minX, maxY-minY)));
}
}
}
diff --git a/UVtools.Parser/UVtools.Parser.csproj b/UVtools.Parser/UVtools.Parser.csproj
index 8741111..752f6d5 100644
--- a/UVtools.Parser/UVtools.Parser.csproj
+++ b/UVtools.Parser/UVtools.Parser.csproj
@@ -7,9 +7,9 @@
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<PackageIcon></PackageIcon>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
- <AssemblyVersion>0.5.1.2</AssemblyVersion>
- <FileVersion>0.5.1.2</FileVersion>
- <Version>0.5.1.2</Version>
+ <AssemblyVersion>0.5.1.3</AssemblyVersion>
+ <FileVersion>0.5.1.3</FileVersion>
+ <Version>0.5.1.3</Version>
<Description>MSLA/DLP, file analysis, repair, conversion and manipulation</Description>
<PackageId>UVtoolsParser</PackageId>
<PackageLicenseFile>LICENSE</PackageLicenseFile>