diff --git a/CHANGELOG.md b/CHANGELOG.md index fd7659ca..e79b91b1 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 a726ab13..17f2258d 100644 --- a/UVtools.GUI/FrmMain.Designer.cs +++ b/UVtools.GUI/FrmMain.Designer.cs @@ -59,7 +59,9 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() // // 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() // 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 @@ private void InitializeComponent() 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(this.pbLayer_Zoomed); this.pbLayer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pbLayer_MouseMove); @@ -466,7 +468,7 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() // 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() // 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() // 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 @@ private void InitializeComponent() 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 void InitializeComponent() 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 void InitializeComponent() 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 0f742ad0..7905296f 100644 --- a/UVtools.GUI/FrmMain.cs +++ b/UVtools.GUI/FrmMain.cs @@ -12,8 +12,6 @@ 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 @@ public FrmMain() 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 @@ private void EventClick(object sender, EventArgs e) } } - using (FrmInstallPEProfiles form = new FrmInstallPEProfiles()) { form.ShowDialog(); @@ -938,6 +942,11 @@ private void EventClick(object sender, EventArgs e) } if (ReferenceEquals(sender, tsLayerImageExport)) + { + tsLayerImageExport.ShowDropDown(); + return; + } + if (ReferenceEquals(sender, tsLayerImageExportFile)) { using (SaveFileDialog dialog = new SaveFileDialog()) { @@ -960,10 +969,21 @@ private void EventClick(object sender, EventArgs e) 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 @@ private void EventItemActivate(object sender, EventArgs e) } 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 @@ void ShowLayer(uint layerNum) if (tsLayerImageLayerOutline.Checked) { - Image 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 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(); - grayscale.Dispose(); +#else + greyscale = greyscale.Canny(80, 40, 3, true); +#endif + imageRgba = greyscale.ToImageSharpL8().CloneAs(); + greyscale.Dispose(); } else if (tsLayerImageLayerDifference.Checked) { @@ -1650,7 +1654,7 @@ void ShowLayer(uint layerNum) { var previousImage = SlicerFile[layerNum-1].Image; var nextImage = SlicerFile[layerNum+1].Image; - var newImage = new Image(previousImage.Width, previousImage.Height); + //var newImage = new Image(previousImage.Width, previousImage.Height); /*Parallel.For(0, ActualLayerImage.Height, y => { var newImageSpan = newImage.GetPixelRowSpan(y); @@ -1722,23 +1726,56 @@ void ShowLayer(uint layerNum) !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(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 @@ private void EventKeyUp(object sender, KeyEventArgs e) return; } } - #endregion +#endregion @@ -2264,63 +2301,266 @@ private void ComputeIssues() } } - /*var layerHollowAreas = new ConcurrentDictionary>(); + return true; + var layerHollowAreas = new ConcurrentDictionary>(); + + Stopwatch sw = new Stopwatch(); + sw.Start(); Parallel.ForEach(SlicerFile, //new ParallelOptions{MaxDegreeOfParallelism = 1}, layer => { - var image = layer.Image; - Image grayscale = image.ToEmguImage().ThresholdBinary(new Gray(254), new Gray(255)); - - var listHollowArea = new List(); - - 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 grayscale = image.ToEmguImage().ThresholdBinary(new Gray(254), new Gray(255))) + { + var listHollowArea = new List(); - grayscale.Dispose(); - grayscale = new Image(image.Width, image.Height); - //grayscale = grayscale.CopyBlank(); - grayscale.FillConvexPoly(contours[i].ToArray(), new Gray(125)); - List points = new List(); + 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 linkedAreas = new List(); + 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 queue = new Queue(); + 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(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(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>(); + for (uint layerIndex = 0; layerIndex < SlicerFile.LayerCount; layerIndex++) + { + if (!layerHollowAreas.TryGetValue(layerIndex, out var list)) continue; + if (list.Count > 0) + { + var issuesHollow = new List(); + + 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 @@ private void ComputeIssues() 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 0d127831..fb7b7292 100644 --- a/UVtools.GUI/FrmMain.resx +++ b/UVtools.GUI/FrmMain.resx @@ -126,12 +126,6 @@ 201, 17 - - 291, 17 - - - 649, 17 - 551, 17 @@ -145,70 +139,85 @@ 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 + + 291, 17 + + + 649, 17 + + + 551, 17 + + + 765, 17 + + + 863, 17 + 863, 17 diff --git a/UVtools.GUI/Images/clipboard-16x16.png b/UVtools.GUI/Images/clipboard-16x16.png new file mode 100644 index 00000000..42f93706 Binary files /dev/null and b/UVtools.GUI/Images/clipboard-16x16.png differ diff --git a/UVtools.GUI/Images/file-image-16x16.png b/UVtools.GUI/Images/file-image-16x16.png new file mode 100644 index 00000000..7e10379a Binary files /dev/null and b/UVtools.GUI/Images/file-image-16x16.png differ diff --git a/UVtools.GUI/Properties/AssemblyInfo.cs b/UVtools.GUI/Properties/AssemblyInfo.cs index 674c0cc5..04bc2a16 100644 --- a/UVtools.GUI/Properties/AssemblyInfo.cs +++ b/UVtools.GUI/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.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 0bf6de31..d20e24b9 100644 --- a/UVtools.GUI/Properties/Resources.Designer.cs +++ b/UVtools.GUI/Properties/Resources.Designer.cs @@ -190,6 +190,16 @@ internal static System.Drawing.Bitmap checkbox_unmarked_16x16 { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clipboard_16x16 { + get { + object obj = ResourceManager.GetObject("clipboard-16x16", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -290,6 +300,16 @@ internal static System.Drawing.Bitmap File_Close_16x16 { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap file_image_16x16 { + get { + object obj = ResourceManager.GetObject("file-image-16x16", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/UVtools.GUI/Properties/Resources.resx b/UVtools.GUI/Properties/Resources.resx index 0fb1e7ad..a53bad99 100644 --- a/UVtools.GUI/Properties/Resources.resx +++ b/UVtools.GUI/Properties/Resources.resx @@ -157,6 +157,9 @@ ..\Images\arrow-up-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\file-image-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Images\warning-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -175,15 +178,15 @@ ..\Images\arrow-up.ico;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\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\arrow-down-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 @@ -208,11 +211,14 @@ ..\Images\eye-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\Geometry-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\plus.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -238,14 +244,14 @@ ..\Images\arrow-end-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\checkbox-unmarked-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Images\delete-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\arrow-down-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Images\pointer-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -268,7 +274,7 @@ ..\Images\island-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Images\checkbox-unmarked-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\clipboard-16x16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/UVtools.GUI/UVtools.GUI.csproj b/UVtools.GUI/UVtools.GUI.csproj index 13f8a4fc..79782a22 100644 --- a/UVtools.GUI/UVtools.GUI.csproj +++ b/UVtools.GUI/UVtools.GUI.csproj @@ -273,6 +273,8 @@ + + diff --git a/UVtools.Parser/ChituboxFile.cs b/UVtools.Parser/ChituboxFile.cs index 6c88700c..5c3c1f35 100644 --- a/UVtools.Parser/ChituboxFile.cs +++ b/UVtools.Parser/ChituboxFile.cs @@ -533,8 +533,6 @@ public static Image DecodeCbddlpImage(ChituboxFile parent, uint layerIndex) { 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 @@ public static Image DecodeCbddlpImage(ChituboxFile parent, uint layerIndex) { for (int i = 0; i < reps; i++) { - span[n + i].PackedValue |= bitValue; + span[n + i].PackedValue++; } } @@ -565,6 +563,20 @@ public static Image DecodeCbddlpImage(ChituboxFile parent, uint layerIndex) } } + 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 @@ public byte[] EncodeCbddlpImage(Image image, byte bit) 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 @@ void AddRep() Span 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 11b55b8a..0403e495 100644 --- a/UVtools.Parser/LayerManager.cs +++ b/UVtools.Parser/LayerManager.cs @@ -16,6 +16,7 @@ using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using Point = System.Drawing.Point; +using Rectangle = System.Drawing.Rectangle; namespace UVtools.Parser { @@ -46,6 +47,11 @@ public enum IssueType : byte /// public Point[] Pixels { get; } + /// + /// Gets the bounding rectangle of the pixel area + /// + public Rectangle BoundingRectangle { get; } + /// /// Gets the X coordinate for the first point, -1 if doesn't exists /// @@ -71,11 +77,12 @@ public enum IssueType : byte /// 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 @@ public enum AreaType : byte /// /// Gets area pixels /// - 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 @@ public Point this[int index] #endregion - - public IEnumerator GetEnumerator() { - return ((IEnumerable)Pixels).GetEnumerator(); + return ((IEnumerable)Contour).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() @@ -163,9 +170,11 @@ public LayerHollowArea() { } - 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 @@ public List GetIssues(uint requiredPixelsToSupportIsland = 5) 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 @@ public List GetIssues(uint requiredPixelsToSupportIsland = 5) 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 @@ public List GetIssues(uint requiredPixelsToSupportIsland = 5) 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 87411114..752f6d53 100644 --- a/UVtools.Parser/UVtools.Parser.csproj +++ b/UVtools.Parser/UVtools.Parser.csproj @@ -7,9 +7,9 @@ https://github.com/sn4k3/UVtools https://github.com/sn4k3/UVtools - 0.5.1.2 - 0.5.1.2 - 0.5.1.2 + 0.5.1.3 + 0.5.1.3 + 0.5.1.3 MSLA/DLP, file analysis, repair, conversion and manipulation UVtoolsParser LICENSE