diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs
index ead41c9..6ff4e23 100644
--- a/UVtools.Core/FileFormats/ChituboxFile.cs
+++ b/UVtools.Core/FileFormats/ChituboxFile.cs
@@ -867,15 +867,15 @@ namespace UVtools.Core.FileFormats
{
}
- public LayerDataEx(LayerData layerData)
+ public LayerDataEx(LayerData layerData, uint layerIndex)
{
LayerData = layerData;
if (!ReferenceEquals(layerData.Parent, null))
{
- LiftHeight = layerData.Parent.LiftHeight;
- LiftSpeed = layerData.Parent.LiftSpeed;
- RetractSpeed = layerData.Parent.RetractSpeed;
- LightPWM = layerData.Parent.HeaderSettings.LightPWM;
+ LiftHeight = layerData.Parent.GetInitialLayerValueOrNormal(layerIndex, layerData.Parent.PrintParametersSettings.BottomLiftHeight, layerData.Parent.PrintParametersSettings.LiftHeight);
+ LiftSpeed = layerData.Parent.GetInitialLayerValueOrNormal(layerIndex, layerData.Parent.PrintParametersSettings.BottomLiftSpeed, layerData.Parent.PrintParametersSettings.LiftSpeed);
+ RetractSpeed = layerData.Parent.PrintParametersSettings.RetractSpeed;
+ LightPWM = layerData.Parent.GetInitialLayerValueOrNormal(layerIndex, layerData.Parent.HeaderSettings.BottomLightPWM, layerData.Parent.HeaderSettings.LightPWM);
}
if (layerData.DataSize > 0)
@@ -1096,7 +1096,8 @@ namespace UVtools.Core.FileFormats
if(SlicerInfoSettings.MysteriousId == 0)
SlicerInfoSettings.MysteriousId = 0x12345678;
- SlicerInfoSettings.Unknown1 = HeaderSettings.Version == 3 ? 0u : 0x200;
+ if(SlicerInfoSettings.Unknown1 == 0)
+ SlicerInfoSettings.Unknown1 = HeaderSettings.Version == 3 ? 0u : 0x200;
if (HeaderSettings.EncryptionKey == 0)
{
@@ -1166,7 +1167,7 @@ namespace UVtools.Core.FileFormats
HeaderSettings.LayersDefinitionOffsetAddress = currentOffset;
uint layerDataCurrentOffset = currentOffset + (uint)Helpers.Serializer.SizeOf(new LayerData()) * HeaderSettings.LayerCount * HeaderSettings.AntiAliasLevel;
-
+
progress.ItemCount *= 2 * HeaderSettings.AntiAliasLevel;
for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++)
@@ -1208,11 +1209,18 @@ namespace UVtools.Core.FileFormats
}
}
- if (ReferenceEquals(layerDataHash, null))
+ if (layerDataHash is null)
{
layerData.DataAddress = layerDataCurrentOffset;
outputFile.Seek(layerDataCurrentOffset, SeekOrigin.Begin);
+
+ if (HeaderSettings.Version >= 3)
+ {
+ var layerDataEx = new LayerDataEx(layerData, layerIndex);
+ layerData.DataAddress = layerDataCurrentOffset += Helpers.SerializeWriteFileStream(outputFile, layerDataEx);
+ }
+
layerDataCurrentOffset += outputFile.WriteBytes(layerData.EncodedRle);
}
diff --git a/UVtools.Core/Operations/Operation.cs b/UVtools.Core/Operations/Operation.cs
index 8b20d86..4824a10 100644
--- a/UVtools.Core/Operations/Operation.cs
+++ b/UVtools.Core/Operations/Operation.cs
@@ -5,6 +5,9 @@
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
+
+using UVtools.Core.Obects;
+
namespace UVtools.Core.Operations
{
public class Operation
@@ -16,8 +19,30 @@ namespace UVtools.Core.Operations
///
public string Id => GetType().Name.Remove(0, ClassNameLength);
+ ///
+ /// Gets the title of this operation
+ ///
+ public virtual string Title => Id;
+
+ ///
+ /// Gets a descriptive text of this operation
+ ///
+ public virtual string Description => Id;
+
+ ///
+ /// Gets the Ok button text
+ ///
+ public virtual string ButtonOkText => Title;
+
+ ///
+ /// Gets the confirmation text for the operation
+ ///
public virtual string ConfirmationText => $"Are you sure you want to {Id}";
- public virtual string Validate() => null;
+ ///
+ /// Validates the operation
+ ///
+ /// null or empty if validates, or else, return a string with error message
+ public virtual StringTag Validate(params object[] parameters) => null;
}
}
diff --git a/UVtools.Core/Operations/OperationChangeResolution.cs b/UVtools.Core/Operations/OperationChangeResolution.cs
index e022b68..c2580ba 100644
--- a/UVtools.Core/Operations/OperationChangeResolution.cs
+++ b/UVtools.Core/Operations/OperationChangeResolution.cs
@@ -1,10 +1,12 @@
using System.Drawing;
using System.Text;
+using UVtools.Core.Obects;
namespace UVtools.Core.Operations
{
public sealed class OperationChangeResolution : Operation
{
+ #region Subclasses
public class Resolution
{
public uint ResolutionX { get; }
@@ -28,7 +30,41 @@ namespace UVtools.Core.Operations
return str;
}
}
+ #endregion
+ #region Overrides
+
+ public override string Title => "Change Resolution";
+ public override string Description =>
+ "Crops or resizes all layer images to fit an alternate print area\n" +
+ "Useful to make files printable on a different printer than they were originally sliced for without the need to re-slice.\n" +
+ "NOTE: Please ensure that the actual object will fit within the new print resolution. The operation will be aborted if it will result in any of the actual model being clipped.";
+
+ public override string ConfirmationText =>
+ "Are you sure you want change file resolution?\n" +
+ $"From: {OldResolutionX} x {OldResolutionY}\n" +
+ $"To: {NewResolutionX} x {NewResolutionY}";
+
+ public override StringTag Validate(params object[] parameters)
+ {
+ var sb = new StringBuilder();
+ if (OldResolutionX == NewResolutionX && OldResolutionY == NewResolutionY)
+ {
+ sb.AppendLine($"The new resolution must be different from current resolution ({OldResolutionX} x {OldResolutionY}).");
+ }
+
+ if (NewResolutionX < VolumeBonds.Width || NewResolutionY < VolumeBonds.Height)
+ {
+ sb.AppendLine($"The new resolution ({NewResolutionX} x {NewResolutionY}) is not enough to accommodate the object volume ({VolumeBonds.Width} x {VolumeBonds.Height}), continuing operation would cut the object");
+ sb.AppendLine("To fix this, try to rotate the object and/or resize to fit on this new resolution.");
+ }
+
+ return new StringTag(sb.ToString());
+ }
+
+ #endregion
+
+ #region Properties
public uint OldResolutionX { get; }
public uint OldResolutionY { get; }
@@ -36,17 +72,16 @@ namespace UVtools.Core.Operations
public uint NewResolutionY { get; set; }
public Rectangle VolumeBonds { get; }
- public override string ConfirmationText => "Are you sure you want change file resolution?\n" +
- $"From: {OldResolutionX} x {OldResolutionY}\n" +
- $"To: {NewResolutionX} x {NewResolutionY}";
+ #endregion
+ #region Constructor
public OperationChangeResolution(uint oldResolutionX, uint oldResolutionY, Rectangle volumeBonds)
{
OldResolutionX = oldResolutionX;
OldResolutionY = oldResolutionY;
VolumeBonds = volumeBonds;
}
-
+ #endregion
public static Resolution[] GetResolutions()
{
@@ -68,21 +103,6 @@ namespace UVtools.Core.Operations
};
}
- public override string Validate()
- {
- var sb = new StringBuilder();
- if (OldResolutionX == NewResolutionX && OldResolutionY == NewResolutionY)
- {
- sb.AppendLine($"The new resolution must be different from current resolution ({OldResolutionX} x {OldResolutionY}).");
- }
-
- if (NewResolutionX < VolumeBonds.Width || NewResolutionY < VolumeBonds.Height)
- {
- sb.AppendLine($"The new resolution ({NewResolutionX} x {NewResolutionY}) is not enough to accommodate the object volume ({VolumeBonds.Width} x {VolumeBonds.Height}), continuing operation would cut the object");
- sb.AppendLine("To fix this, try to rotate the object and/or resize to fit on this new resolution.");
- }
-
- return sb.ToString();
- }
+
}
}
diff --git a/UVtools.Core/Operations/OperationLayerImport.cs b/UVtools.Core/Operations/OperationLayerImport.cs
index a60407a..9547dcf 100644
--- a/UVtools.Core/Operations/OperationLayerImport.cs
+++ b/UVtools.Core/Operations/OperationLayerImport.cs
@@ -4,14 +4,18 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
+using System.Text;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
+using Emgu.CV.Ocl;
+using UVtools.Core.Obects;
namespace UVtools.Core.Operations
{
public sealed class OperationLayerImport : Operation
{
+ public Size FileResolution { get; }
public uint InsertAfterLayerIndex { get; set; }
public bool ReplaceStartLayer { get; set; }
public bool ReplaceSubsequentLayers { get; set; }
@@ -21,27 +25,55 @@ namespace UVtools.Core.Operations
public int Count => Files.Count;
+ public override string Title => "Import Layer(s)";
+
+ public override string Description =>
+ "Import layer(s) from local file(s) into the model at a selected height.\n" +
+ "NOTE: Images must respect file resolution and in greyscale color.";
+
public override string ConfirmationText => $"import {Count} layer(s)?";
+ public OperationLayerImport(Size fileResolution)
+ {
+ FileResolution = fileResolution;
+ }
+
public void Sort()
{
Files.Sort((file1, file2) => string.Compare(Path.GetFileNameWithoutExtension(file1), Path.GetFileNameWithoutExtension(file2), StringComparison.Ordinal));
}
- public ConcurrentBag Validate(Size resolution)
+ public override StringTag Validate(params object[] parameters)
{
var result = new ConcurrentBag();
Parallel.ForEach(Files, file =>
{
using (Mat mat = CvInvoke.Imread(file, ImreadModes.AnyColor))
{
- if (mat.Size != resolution)
+ if (mat.Size != FileResolution)
{
result.Add(file);
}
}
});
- return result;
+
+ if (result.IsEmpty) return null;
+ var message = new StringBuilder();
+ message.AppendLine($"The following {result.Count} files mismatched the slice resolution of {FileResolution.Width} x {FileResolution.Height}:");
+ message.AppendLine();
+ uint count = 0;
+ foreach (var file in result)
+ {
+ count++;
+ if (count == 20)
+ {
+ message.AppendLine("... To many to show ...");
+ break;
+ }
+ message.AppendLine(Path.GetFileNameWithoutExtension(file));
+ }
+
+ return new StringTag(message.ToString(), result);
}
public uint CalculateTotalLayers(uint totalLayers)
diff --git a/UVtools.GUI/Controls/CtrlToolWindowContent.cs b/UVtools.GUI/Controls/CtrlToolWindowContent.cs
index 470c846..0c3a213 100644
--- a/UVtools.GUI/Controls/CtrlToolWindowContent.cs
+++ b/UVtools.GUI/Controls/CtrlToolWindowContent.cs
@@ -10,6 +10,8 @@ using System.Drawing.Design;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using UVtools.Core.Extensions;
+using UVtools.Core.Obects;
+using UVtools.Core.Operations;
using UVtools.GUI.Annotations;
using UVtools.GUI.Forms;
@@ -71,9 +73,10 @@ namespace UVtools.GUI.Controls
}
#endregion
-
#region Properties
+ [ReadOnly(true)] [Browsable(false)] public Operation BaseOperation { get; private set; }
+
[ReadOnly(true)] [Browsable(false)] public FrmToolWindow ParentToolWindow => ParentForm as FrmToolWindow;
[Editor("System.ComponentModel.Design.MultilineStringEditor", typeof(UITypeEditor))]
@@ -108,7 +111,18 @@ namespace UVtools.GUI.Controls
[ReadOnly(true)]
[Browsable(false)]
- public virtual string ConfirmationText => $"{Text}?";
+ public virtual string ConfirmationText
+ {
+ get
+ {
+ if (BaseOperation is null || string.IsNullOrEmpty(BaseOperation.ConfirmationText))
+ {
+ return $"{Text}?";
+ }
+
+ return BaseOperation.ConfirmationText;
+ }
+ }
#endregion
@@ -121,8 +135,35 @@ namespace UVtools.GUI.Controls
#region Methods
- public virtual bool ValidateForm() => true;
+ public void SetOperation(Operation operation)
+ {
+ BaseOperation = operation;
+ if(!string.IsNullOrEmpty(operation.Title)) Text = operation.Title;
+ if (!string.IsNullOrEmpty(operation.Description)) Description = operation.Description;
+ if (!string.IsNullOrEmpty(operation.ButtonOkText)) ButtonOkText = operation.ButtonOkText;
+ }
+ ///
+ /// Updates operation object with items retrieved from form fields
+ ///
+ public virtual void UpdateOperation(){}
+
+ ///
+ /// Validates if is safe to continue with operation
+ ///
+ ///
+ public virtual bool ValidateForm()
+ {
+ if (BaseOperation is null) return true;
+ UpdateOperation();
+ return ValidateFormFromString(BaseOperation.Validate());
+ }
+
+ ///
+ /// Validates if is safe to continue with operation, if not shows a message box with the error
+ ///
+ ///
+ ///
public bool ValidateFormFromString(string text)
{
if (string.IsNullOrEmpty(text)) return true;
@@ -130,6 +171,19 @@ namespace UVtools.GUI.Controls
return false;
}
+ ///
+ /// Validates if is safe to continue with operation, if not shows a message box with the error
+ ///
+ ///
+ ///
+ public bool ValidateFormFromString(StringTag text)
+ {
+ if (text is null) return true;
+ if (string.IsNullOrEmpty(text.ToString())) return true;
+ MessageBoxError(text.ToString());
+ return false;
+ }
+
public DialogResult MessageBoxError(string message, MessageBoxButtons buttons = MessageBoxButtons.OK) => GUIExtensions.MessageErrorBox($"{Text} Error", message, buttons);
public DialogResult MessageQuestionBox(string message, string title = null, MessageBoxButtons buttons = MessageBoxButtons.YesNo) => GUIExtensions.MessageQuestionBox($"{title ?? Text}", message, buttons);
diff --git a/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.Designer.cs b/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.Designer.cs
index 3ddaa2a..656e578 100644
--- a/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.Designer.cs
+++ b/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.Designer.cs
@@ -28,7 +28,6 @@
///
private void InitializeComponent()
{
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CtrlToolChangeResolution));
this.lbObjectVolume = new System.Windows.Forms.Label();
this.nmNewY = new System.Windows.Forms.NumericUpDown();
this.label3 = new System.Windows.Forms.Label();
@@ -149,7 +148,6 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
- this.ButtonOkText = "Change Resolution";
this.Controls.Add(this.lbObjectVolume);
this.Controls.Add(this.nmNewY);
this.Controls.Add(this.label3);
@@ -158,7 +156,7 @@
this.Controls.Add(this.cbPreset);
this.Controls.Add(this.label2);
this.Controls.Add(this.lbCurrent);
- this.Description = resources.GetString("$this.Description");
+ this.Description = "";
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LayerRangeVisible = false;
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
diff --git a/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.cs b/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.cs
index 898d11e..3398aa8 100644
--- a/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.cs
+++ b/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.cs
@@ -18,13 +18,11 @@ namespace UVtools.GUI.Controls.Tools
public uint NewResolutionX => (uint) nmNewX.Value;
public uint NewResolutionY => (uint) nmNewY.Value;
- public override string ConfirmationText => Operation.ConfirmationText;
-
public CtrlToolChangeResolution(uint oldResolutionX, uint oldResolutionY, Rectangle volumeBonds)
{
InitializeComponent();
- Text = "Change Resolution";
Operation = new OperationChangeResolution(oldResolutionX, oldResolutionY, volumeBonds);
+ SetOperation(Operation);
lbCurrent.Text = $"Current resolution (X/Y): {oldResolutionX} x {oldResolutionY}";
lbObjectVolume.Text = $"Object volume (X/Y): {volumeBonds.Width} x {volumeBonds.Height}";
@@ -58,11 +56,10 @@ namespace UVtools.GUI.Controls.Tools
}
}
- public override bool ValidateForm()
+ public override void UpdateOperation()
{
Operation.NewResolutionX = NewResolutionX;
Operation.NewResolutionY = NewResolutionY;
- return ValidateFormFromString(Operation.Validate());
}
}
}
diff --git a/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.resx b/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.resx
index fdaf0d0..8766f29 100644
--- a/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.resx
+++ b/UVtools.GUI/Controls/Tools/CtrlToolChangeResolution.resx
@@ -120,10 +120,4 @@
17, 17
-
- Changes images resolution (X/Y).
-Usefull to make files printable under a different printer resolution without have to reslice.
-Note 1: Before run this tool, ensure object rotatation and volume fits new resolution.
-Note 2: Object will auto-center on new resolution.
-
\ No newline at end of file
diff --git a/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.Designer.cs b/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.Designer.cs
index 9b53b62..e831616 100644
--- a/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.Designer.cs
+++ b/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.Designer.cs
@@ -281,7 +281,6 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
- this.ButtonOkText = "Import";
this.Controls.Add(this.cbDiscardRemainingLayers);
this.Controls.Add(this.cbReplaceSubsequentLayers);
this.Controls.Add(this.lbResult);
@@ -292,8 +291,6 @@
this.Controls.Add(this.nmInsertAfterLayer);
this.Controls.Add(this.label1);
this.Controls.Add(this.splitContainer);
- this.Description = "Import layer(s) from local file(s) into the model at a selected height.\r\nNOTE: Im" +
- "ages must respect file resolution and in greyscale color.";
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LayerRangeVisible = false;
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
diff --git a/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.cs b/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.cs
index d72a757..b1d8512 100644
--- a/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.cs
+++ b/UVtools.GUI/Controls/Tools/CtrlToolLayerImport.cs
@@ -7,6 +7,7 @@
*/
using System;
+using System.Collections.Concurrent;
using System.Diagnostics;
using System.Drawing;
using System.IO;
@@ -19,12 +20,13 @@ namespace UVtools.GUI.Controls.Tools
{
public partial class CtrlToolLayerImport : CtrlToolWindowContent
{
- public OperationLayerImport Operation { get; } = new OperationLayerImport();
+ public OperationLayerImport Operation { get; }
public CtrlToolLayerImport(uint currentLayer = 0)
{
InitializeComponent();
- Text = "Import Layer(s)";
+ Operation = new OperationLayerImport(Program.FrmMain.ActualLayerImage.Size);
+ SetOperation(Operation);
nmInsertAfterLayer.Maximum = Program.SlicerFile.LayerCount-1;
@@ -32,9 +34,7 @@ namespace UVtools.GUI.Controls.Tools
nmInsertAfterLayer_ValueChanged(nmInsertAfterLayer, EventArgs.Empty);
}
- public override string ConfirmationText => Operation.ConfirmationText;
-
- public void UpdateOperation()
+ public override void UpdateOperation()
{
Operation.InsertAfterLayerIndex = (uint)nmInsertAfterLayer.Value;
Operation.ReplaceStartLayer = cbReplaceStartLayer.Checked;
@@ -46,29 +46,14 @@ namespace UVtools.GUI.Controls.Tools
public override bool ValidateForm()
{
UpdateOperation();
- var result = Operation.Validate(Program.FrmMain.ActualLayerImage.Size);
- if (result.Count == 0) return true;
+ var message = Operation.Validate();
+ if (message is null) return true;
- var message = new StringBuilder();
- message.AppendLine($"The following {result.Count} files mismatched the slice resolution of {Program.FrmMain.ActualLayerImage.Size.Width}x{Program.FrmMain.ActualLayerImage.Size.Height}:");
- message.AppendLine();
- uint count = 0;
- foreach (var file in result)
- {
- count++;
- if (count == 20)
- {
- message.AppendLine("... To many to show ...");
- break;
- }
- message.AppendLine(Path.GetFileNameWithoutExtension(file));
-
- }
- message.AppendLine();
- message.AppendLine("Do you want to remove all invalid files from list?");
+ message.Content += "\nDo you want to remove all invalid files from list?";
if (MessageBoxError(message.ToString(), MessageBoxButtons.YesNo) == DialogResult.Yes)
{
+ ConcurrentBag result = (ConcurrentBag)message.Tag;
foreach (var file in result)
{
Operation.Files.Remove(file);