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>2021-11-18 06:29:08 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-11-18 06:29:08 +0300
commitc968eaedf961a6809d571b02528bf823b34e625b (patch)
treef7c7e3891dec8a075e0e7e37be1ebb5f50373842
parent0e099ae50b5c64102f57e369da1f27e4b3bc95ad (diff)
v2.25.0v2.25.0
- **File formats:** - (Add) Allow to partial open the files for read and/or change properties, the layer images won't be read nor cached (Fast) - (Add) More abstraction on partial save - **Scripting:** - (Add) ScriptOpenFolderDialogInput - Selects a folder path - (Add) ScriptOpenFileDialogInput - Selectes a file to open - (Add) ScriptSaveFileDialogInput - Selects a file to save - (Add) [UNSAVED] tag to the title bar when there are unsaved changes on the current session - (Improvement) Better handling of empty images on the UI
-rw-r--r--CHANGELOG.md12
-rw-r--r--UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs2
-rw-r--r--UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj2
-rw-r--r--UVtools.Core/FileFormats/CTBEncryptedFile.cs99
-rw-r--r--UVtools.Core/FileFormats/CWSFile.cs117
-rw-r--r--UVtools.Core/FileFormats/CXDLPFile.cs145
-rw-r--r--UVtools.Core/FileFormats/CXDLPv1File.cs113
-rw-r--r--UVtools.Core/FileFormats/ChituboxFile.cs90
-rw-r--r--UVtools.Core/FileFormats/ChituboxZipFile.cs61
-rw-r--r--UVtools.Core/FileFormats/FDGFile.cs61
-rw-r--r--UVtools.Core/FileFormats/FileFormat.cs98
-rw-r--r--UVtools.Core/FileFormats/FlashForgeSVGXFile.cs51
-rw-r--r--UVtools.Core/FileFormats/GR1File.cs96
-rw-r--r--UVtools.Core/FileFormats/ImageFile.cs12
-rw-r--r--UVtools.Core/FileFormats/LGSFile.cs60
-rw-r--r--UVtools.Core/FileFormats/MDLPFile.cs96
-rw-r--r--UVtools.Core/FileFormats/OSLAFile.cs71
-rw-r--r--UVtools.Core/FileFormats/PHZFile.cs55
-rw-r--r--UVtools.Core/FileFormats/PhotonSFile.cs48
-rw-r--r--UVtools.Core/FileFormats/PhotonWorkshopFile.cs66
-rw-r--r--UVtools.Core/FileFormats/SL1File.cs50
-rw-r--r--UVtools.Core/FileFormats/UVJFile.cs42
-rw-r--r--UVtools.Core/FileFormats/VDAFile.cs41
-rw-r--r--UVtools.Core/FileFormats/VDTFile.cs91
-rw-r--r--UVtools.Core/FileFormats/ZCodeFile.cs43
-rw-r--r--UVtools.Core/FileFormats/ZCodexFile.cs173
-rw-r--r--UVtools.Core/Layers/Layer.cs11
-rw-r--r--UVtools.Core/Layers/LayerManager.cs16
-rw-r--r--UVtools.Core/Managers/ClipboardManager.cs6
-rw-r--r--UVtools.Core/Managers/IssueManager.cs2
-rw-r--r--UVtools.Core/Operations/Operation.cs9
-rw-r--r--UVtools.Core/Operations/OperationCalculator.cs3
-rw-r--r--UVtools.Core/Operations/OperationDynamicLifts.cs2
-rw-r--r--UVtools.Core/Operations/OperationEditParameters.cs4
-rw-r--r--UVtools.Core/Operations/OperationFadeExposureTime.cs1
-rw-r--r--UVtools.Core/Operations/OperationIPrintedThisFile.cs2
-rw-r--r--UVtools.Core/Operations/OperationRaiseOnPrintFinish.cs3
-rw-r--r--UVtools.Core/Operations/OperationScripting.cs2
-rw-r--r--UVtools.Core/Scripting/ScriptFileDialogInput.cs41
-rw-r--r--UVtools.Core/Scripting/ScriptOpenFileDialogInput.cs23
-rw-r--r--UVtools.Core/Scripting/ScriptOpenFolderDialogInput.cs18
-rw-r--r--UVtools.Core/Scripting/ScriptSaveFileDialogInput.cs18
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.ScriptSample/ScriptCloneSettings.cs427
-rw-r--r--UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs644
-rw-r--r--UVtools.WPF/LayerCache.cs1
-rw-r--r--UVtools.WPF/MainWindow.Issues.cs8
-rw-r--r--UVtools.WPF/MainWindow.LayerPreview.cs9
-rw-r--r--UVtools.WPF/MainWindow.axaml7
-rw-r--r--UVtools.WPF/MainWindow.axaml.cs105
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj2
51 files changed, 1852 insertions, 1309 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86f9dec..f682326 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
# Changelog
+## 18/11/2021 - v2.25.0
+
+- **File formats:**
+ - (Add) Allow to partial open the files for read and/or change properties, the layer images won't be read nor cached (Fast)
+ - (Add) More abstraction on partial save
+- **Scripting:**
+ - (Add) ScriptOpenFolderDialogInput - Selects a folder path
+ - (Add) ScriptOpenFileDialogInput - Selectes a file to open
+ - (Add) ScriptSaveFileDialogInput - Selects a file to save
+- (Add) [UNSAVED] tag to the title bar when there are unsaved changes on the current session
+- (Improvement) Better handling of empty images on the UI
+
## 14/11/2021 - v2.24.4
- **File - Send to - Device**
diff --git a/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs b/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs
index 7791193..6ff899d 100644
--- a/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs
+++ b/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs
@@ -2117,7 +2117,7 @@ namespace UVtools.AvaloniaControls
/// <returns></returns>
public Rect GetImageViewPort()
{
- if (ViewPortSize.Width == 0 && ViewPortSize.Height == 0) return Rect.Empty;
+ if (!IsImageLoaded || (ViewPortSize.Width == 0 && ViewPortSize.Height == 0)) return Rect.Empty;
double xOffset = 0;
double yOffset = 0;
diff --git a/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj b/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj
index e7ba28e..977d10a 100644
--- a/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj
+++ b/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj
@@ -13,7 +13,7 @@
<PackageTags>Advanced image box</PackageTags>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<Description>AvaloniaUI Controls</Description>
- <Version>1.0.0</Version>
+ <Version>1.0.1</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
diff --git a/UVtools.Core/FileFormats/CTBEncryptedFile.cs b/UVtools.Core/FileFormats/CTBEncryptedFile.cs
index 680a445..efa7fab 100644
--- a/UVtools.Core/FileFormats/CTBEncryptedFile.cs
+++ b/UVtools.Core/FileFormats/CTBEncryptedFile.cs
@@ -1097,15 +1097,15 @@ namespace UVtools.Core.FileFormats
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
Header = Helpers.Deserialize<FileHeader>(inputFile);
Debug.WriteLine($"Header: {Header}");
if (Header.Magic is not MAGIC_CBT_ENCRYPTED)
{
- throw new FileLoadException($"Not a valid CTB encrypted file! Magic Value: {Header.Magic}", fileFullPath);
+ throw new FileLoadException($"Not a valid CTB encrypted file! Magic Value: {Header.Magic}", FileFullPath);
}
inputFile.Seek(Header.SettingsOffset, SeekOrigin.Begin);
@@ -1127,7 +1127,7 @@ namespace UVtools.Core.FileFormats
var hash = inputFile.ReadBytes(HASH_LENGTH);
if (!hash.SequenceEqual(encryptedHash))
{
- throw new FileLoadException("The file checksum does not match, malformed file.", fileFullPath);
+ throw new FileLoadException("The file checksum does not match, malformed file.", FileFullPath);
}
progress.Reset(OperationProgress.StatusDecodePreviews, ThumbnailsCount);
@@ -1174,7 +1174,7 @@ namespace UVtools.Core.FileFormats
}
progress.Reset(OperationProgress.StatusDecodeLayers, Settings.LayerCount);
- LayerManager.Init(Settings.LayerCount);
+ LayerManager.Init(Settings.LayerCount, DecodeType == FileDecodeType.Partial);
LayersDefinition = new LayerDef[LayerCount];
var buggyLayers = new ConcurrentBag<uint>();
@@ -1187,43 +1187,48 @@ namespace UVtools.Core.FileFormats
inputFile.Seek(LayersPointer[layerIndex].LayerOffset, SeekOrigin.Begin);
LayersDefinition[layerIndex] = Helpers.Deserialize<LayerDef>(inputFile);
LayersDefinition[layerIndex].Parent = this;
- LayersDefinition[layerIndex].RLEData = inputFile.ReadBytes(LayersDefinition[layerIndex].DataLength);
+ if (DecodeType == FileDecodeType.Full) LayersDefinition[layerIndex].RLEData = inputFile.ReadBytes(LayersDefinition[layerIndex].DataLength);
Debug.WriteLine($"layer[{layerIndex}]: {LayersDefinition[layerIndex]}");
}
-
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ if (DecodeType == FileDecodeType.Full)
{
- if (progress.Token.IsCancellationRequested) return;
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ {
+ if (progress.Token.IsCancellationRequested) return;
- var layerDef = LayersDefinition[layerIndex];
+ var layerDef = LayersDefinition[layerIndex];
- if (layerDef.EncryptedDataLength > 0)
- {
- /* Decrypt RLE data here */
- var byteBuffer = new byte[layerDef.EncryptedDataLength];
- Array.Copy(layerDef.RLEData, (int)layerDef.EncryptedDataOffset, byteBuffer, 0, (int)layerDef.EncryptedDataLength);
+ if (layerDef.EncryptedDataLength > 0)
+ {
+ /* Decrypt RLE data here */
- byteBuffer = CryptExtensions.AesCryptBytes(byteBuffer, Bigfoot, CipherMode.CBC, PaddingMode.None, false, CookieMonster);
- Array.Copy(byteBuffer, 0, layerDef.RLEData, layerDef.EncryptedDataOffset, layerDef.EncryptedDataLength);
- }
+ var byteBuffer = new byte[layerDef.EncryptedDataLength];
+ Array.Copy(layerDef.RLEData, (int)layerDef.EncryptedDataOffset, byteBuffer, 0,
+ (int)layerDef.EncryptedDataLength);
- bool isBugged = false;
- /* bug fix for Chitubox when a small layer RLE data is encrypted */
- if (layerDef.EncryptedDataLength > 0 && layerDef.RLEData.Length < RLEEncryptedMinimumLength && layerDef.RLEData.Length % 16 != 0)
- {
- buggyLayers.Add((uint)layerIndex);
- isBugged = true;
- layerDef.RLEData = null; /* clean up RLE data */
- }
+ byteBuffer = CryptExtensions.AesCryptBytes(byteBuffer, Bigfoot, CipherMode.CBC,
+ PaddingMode.None, false, CookieMonster);
+ Array.Copy(byteBuffer, 0, layerDef.RLEData, layerDef.EncryptedDataOffset,
+ layerDef.EncryptedDataLength);
+ }
- var layer = new Layer((uint)layerIndex, isBugged ? null : layerDef.DecodeImage((uint)layerIndex), this);
- layerDef.CopyTo(layer);
- this[layerIndex] = layer;
-
- progress.LockAndIncrement();
- });
+ bool isBugged = false;
+ /* bug fix for Chitubox when a small layer RLE data is encrypted */
+ if (layerDef.EncryptedDataLength > 0 && layerDef.RLEData.Length < RLEEncryptedMinimumLength &&
+ layerDef.RLEData.Length % 16 != 0)
+ {
+ buggyLayers.Add((uint)layerIndex);
+ isBugged = true;
+ layerDef.RLEData = null; /* clean up RLE data */
+ }
+
+ this[layerIndex] = new Layer((uint)layerIndex, isBugged ? null : layerDef.DecodeImage((uint)layerIndex), this);
+
+ progress.LockAndIncrement();
+ });
+ }
}
if (buggyLayers.Count == LayerCount)
@@ -1231,7 +1236,12 @@ namespace UVtools.Core.FileFormats
throw new FileLoadException("Unable to load this file due to Chitubox bug affecting every layer." +
"Please increase the portion of the plate in use and reslice the file.");
}
-
+
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
+ {
+ LayersDefinition[layerIndex].CopyTo(this[layerIndex]);
+ }
+
if (!buggyLayers.IsEmpty)
{
var sortedLayerIndexes = buggyLayers.ToArray();
@@ -1267,13 +1277,13 @@ namespace UVtools.Core.FileFormats
//inputFile.ReadBytes(HashLength);
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
#if !DEBUG
throw new NotSupportedException(Preamble);
#endif
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
//uint currentOffset = 0;
/* Create the file header and fill out what we can. SignatureOffset will have to be populated later
@@ -1401,25 +1411,8 @@ namespace UVtools.Core.FileFormats
Helpers.SerializeWriteFileStream(outputFile, Header);
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
SanitizeProperties();
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
diff --git a/UVtools.Core/FileFormats/CWSFile.cs b/UVtools.Core/FileFormats/CWSFile.cs
index 97b9f8f..d7f1c6b 100644
--- a/UVtools.Core/FileFormats/CWSFile.cs
+++ b/UVtools.Core/FileFormats/CWSFile.cs
@@ -575,7 +575,7 @@ namespace UVtools.Core.FileFormats
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
//var filename = fileFullPath.EndsWith(TemporaryFileAppend) ? Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileFullPath)) : Path.GetFileNameWithoutExtension(fileFullPath);
@@ -610,7 +610,7 @@ namespace UVtools.Core.FileFormats
throw new InvalidOperationException($"Filename for this format should not end with a digit: {filename}");
}
- using ZipArchive outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create);
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create);
if (Printer == PrinterType.Wanhao)
{
var manifest = new CWSManifest
@@ -703,9 +703,9 @@ namespace UVtools.Core.FileFormats
outputFile.PutFileContent($"{filename}.gcode", GCodeStr, ZipArchiveMode.Create);
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Read);
+ using var inputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read);
var entry = inputFile.GetEntry("manifest.xml");
if (entry is not null) // Wanhao
{
@@ -722,7 +722,7 @@ namespace UVtools.Core.FileFormats
catch (Exception e)
{
Clear();
- throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", fileFullPath);
+ throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", FileFullPath);
}
@@ -741,7 +741,7 @@ namespace UVtools.Core.FileFormats
catch (Exception e)
{
Clear();
- throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", fileFullPath);
+ throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", FileFullPath);
}
}
}
@@ -751,7 +751,7 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException("slice.conf not found", fileFullPath);
+ throw new FileLoadException("slice.conf not found", FileFullPath);
}
using TextReader tr = new StreamReader(entry.Open());
@@ -780,8 +780,7 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException("Unable to find .gcode file",
- fileFullPath);
+ throw new FileLoadException("Unable to find .gcode file", FileFullPath);
}
using (TextReader tr = new StreamReader(entry.Open()))
@@ -821,32 +820,36 @@ namespace UVtools.Core.FileFormats
tr.Close();
}
- LayerManager.Init(OutputSettings.LayersNum);
+ LayerManager.Init(OutputSettings.LayersNum, DecodeType == FileDecodeType.Partial);
progress.ItemCount = OutputSettings.LayersNum;
if(LayerCount > 0)
{
- var inputFilename = Path.GetFileNameWithoutExtension(fileFullPath);
- foreach (var pngEntry in inputFile.Entries)
+ if (DecodeType == FileDecodeType.Full)
{
- if (!pngEntry.Name.EndsWith(".png")) continue;
- var filename = Path.GetFileNameWithoutExtension(pngEntry.Name).Replace(inputFilename, string.Empty, StringComparison.Ordinal);
-
- var layerIndexStr = string.Empty;
- var layerStr = filename;
- for (int i = layerStr.Length - 1; i >= 0; i--)
+ var inputFilename = Path.GetFileNameWithoutExtension(FileFullPath);
+ foreach (var pngEntry in inputFile.Entries)
{
- if (layerStr[i] < '0' || layerStr[i] > '9') break;
- layerIndexStr = $"{layerStr[i]}{layerIndexStr}";
- }
+ if (!pngEntry.Name.EndsWith(".png")) continue;
+ var filename = Path.GetFileNameWithoutExtension(pngEntry.Name)
+ .Replace(inputFilename, string.Empty, StringComparison.Ordinal);
- if (string.IsNullOrEmpty(layerIndexStr)) continue;
- if (!uint.TryParse(layerIndexStr, out var layerIndex)) continue;
- using var stream = pngEntry.Open();
- this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
- }
+ var layerIndexStr = string.Empty;
+ var layerStr = filename;
+ for (int i = layerStr.Length - 1; i >= 0; i--)
+ {
+ if (layerStr[i] < '0' || layerStr[i] > '9') break;
+ layerIndexStr = $"{layerStr[i]}{layerIndexStr}";
+ }
+ if (string.IsNullOrEmpty(layerIndexStr)) continue;
+ if (!uint.TryParse(layerIndexStr, out var layerIndex)) continue;
+ using var stream = pngEntry.Open();
+ this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
+ }
+ }
+
GCode.ParseLayersFromGCode(this);
var firstLayer = FirstLayer;
@@ -993,61 +996,43 @@ namespace UVtools.Core.FileFormats
RaisePropertyChanged(nameof(GCodeStr));
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update);
+ var arch = Environment.Is64BitOperatingSystem ? "64-bits" : "32-bits";
+ var entry = outputFile.GetPutFile("slice.conf");
+ var stream = entry.Open();
+ stream.SetLength(0);
- if (!string.IsNullOrEmpty(filePath))
+ using (TextWriter tw = new StreamWriter(stream))
{
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
- using (var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update))
- {
- string arch = Environment.Is64BitOperatingSystem ? "64-bits" : "32-bits";
- var entry = outputFile.GetPutFile("slice.conf");
- var stream = entry.Open();
- stream.SetLength(0);
+ tw.WriteLine($"# {About.Website} {About.Software} {Assembly.GetExecutingAssembly().GetName().Version} {arch} {DateTime.UtcNow}");
+ tw.WriteLine("# conf version 1.0");
+ tw.WriteLine("");
- using (TextWriter tw = new StreamWriter(stream))
+ foreach (var propertyInfo in SliceSettings.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
-
- tw.WriteLine($"# {About.Website} {About.Software} {Assembly.GetExecutingAssembly().GetName().Version} {arch} {DateTime.UtcNow}");
- tw.WriteLine("# conf version 1.0");
- tw.WriteLine("");
-
- foreach (var propertyInfo in SliceSettings.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
- {
- var displayNameAttribute = propertyInfo.GetCustomAttributes(false).OfType<DisplayNameAttribute>().FirstOrDefault();
- if (displayNameAttribute is null) continue;
- tw.WriteLine($"{displayNameAttribute.DisplayName.PadRight(24)}= {propertyInfo.GetValue(SliceSettings)}");
- }
+ var displayNameAttribute = propertyInfo.GetCustomAttributes(false).OfType<DisplayNameAttribute>().FirstOrDefault();
+ if (displayNameAttribute is null) continue;
+ tw.WriteLine($"{displayNameAttribute.DisplayName.PadRight(24)}= {propertyInfo.GetValue(SliceSettings)}");
}
+ }
- var entriesToRemove = outputFile.Entries.Where(zipEntry => zipEntry.Name.EndsWith(".gcode")).ToArray();
- foreach (var zipEntry in entriesToRemove)
- {
- zipEntry.Delete();
- }
+ var entriesToRemove = outputFile.Entries.Where(zipEntry => zipEntry.Name.EndsWith(".gcode")).ToArray();
+ foreach (var zipEntry in entriesToRemove)
+ {
+ zipEntry.Delete();
+ }
- outputFile.PutFileContent($"{About.Software}.gcode", GCodeStr, ZipArchiveMode.Update);
+ outputFile.PutFileContent($"{About.Software}.gcode", GCodeStr, ZipArchiveMode.Update);
- /*foreach (var layer in this)
+ /*foreach (var layer in this)
{
if (!layer.IsModified) continue;
outputFile.PutFileContent(layer.Filename, layer.CompressedBytes, ZipArchiveMode.Update);
layer.IsModified = false;
}*/
- }
//Decode(FileFullPath, progress);
}
diff --git a/UVtools.Core/FileFormats/CXDLPFile.cs b/UVtools.Core/FileFormats/CXDLPFile.cs
index 705567f..ff39673 100644
--- a/UVtools.Core/FileFormats/CXDLPFile.cs
+++ b/UVtools.Core/FileFormats/CXDLPFile.cs
@@ -17,7 +17,6 @@ using System.Text;
using System.Threading.Tasks;
using BinarySerialization;
using Emgu.CV;
-using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using MoreLinq;
using UVtools.Core.Extensions;
@@ -571,9 +570,9 @@ namespace UVtools.Core.FileFormats
SlicerInfoSettings.WaitTimeBeforeCure = (ushort)Math.Max(1, WaitTimeBeforeCure);
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.ReadWrite);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.ReadWrite);
if (ResolutionX == 1620 && ResolutionY == 2560)
{
@@ -790,9 +789,9 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
inputFile.Seek(0, SeekOrigin.Begin);
@@ -812,10 +811,10 @@ namespace UVtools.Core.FileFormats
if (expectedCheckSum != checkSum)
{
throw new FileLoadException($"Checksum fails, expecting: {expectedCheckSum} but got: {checkSum}.\n" +
- $"Try to reslice the file.", fileFullPath);
+ $"Try to reslice the file.", FileFullPath);
}
- byte[][] previews = new byte[ThumbnailsOriginalSize.Length][];
+ var previews = new byte[ThumbnailsOriginalSize.Length][];
for (int i = 0; i < ThumbnailsOriginalSize.Length; i++)
{
previews[i] = new byte[ThumbnailsOriginalSize[i].Area() * 2];
@@ -833,116 +832,80 @@ namespace UVtools.Core.FileFormats
SlicerInfoSettings = Helpers.Deserialize<SlicerInfo>(inputFile);
Debug.WriteLine(SlicerInfoSettings);
- LayerManager.Init(HeaderSettings.LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
inputFile.Seek(LayerCount * 4 + 2, SeekOrigin.Current); // Skip pre layers
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
- /*var preLayers = new PreLayer[LayerCount];
- for (int layerIndex = 0; layerIndex < LayerCount; layerIndex++)
- {
- progress.Token.ThrowIfCancellationRequested();
- preLayers[layerIndex] = Helpers.Deserialize<PreLayer>(inputFile);
- progress++;
- }*/
-
- //inputFile.Seek(2, SeekOrigin.Current);
- var linesBytes = new byte[LayerCount][];
- foreach (var batch in BatchLayersIndexes())
+ if (DecodeType == FileDecodeType.Full)
{
- progress.Token.ThrowIfCancellationRequested();
+ progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
- foreach (var layerIndex in batch)
+ var linesBytes = new byte[LayerCount][];
+ foreach (var batch in BatchLayersIndexes())
{
- inputFile.Seek(4, SeekOrigin.Current);
- var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
-
- linesBytes[layerIndex] = new byte[lineCount * 6];
- inputFile.ReadBytes(linesBytes[layerIndex]);
- inputFile.Seek(2, SeekOrigin.Current);
-
progress.Token.ThrowIfCancellationRequested();
- }
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
- {
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = EmguExtensions.InitMat(Resolution))
+ foreach (var layerIndex in batch)
{
+ inputFile.Seek(4, SeekOrigin.Current);
+ var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
+
+ linesBytes[layerIndex] = new byte[lineCount * 6];
+ inputFile.ReadBytes(linesBytes[layerIndex]);
+ inputFile.Seek(2, SeekOrigin.Current);
+
+ progress.Token.ThrowIfCancellationRequested();
+ }
- for (int i = 0; i < linesBytes[layerIndex].Length; i++)
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ {
+ if (progress.Token.IsCancellationRequested) return;
+ using (var mat = EmguExtensions.InitMat(Resolution))
{
- LayerLine line = new()
+
+ for (int i = 0; i < linesBytes[layerIndex].Length; i++)
{
- Coordinates =
+ LayerLine line = new()
{
- [0] = linesBytes[layerIndex][i++],
- [1] = linesBytes[layerIndex][i++],
- [2] = linesBytes[layerIndex][i++],
- [3] = linesBytes[layerIndex][i++],
- [4] = linesBytes[layerIndex][i++]
- },
- Gray = linesBytes[layerIndex][i]
- };
-
- CvInvoke.Line(mat, new Point(line.StartX, line.StartY), new Point(line.StartX, line.EndY),
- new MCvScalar(line.Gray));
- }
+ Coordinates =
+ {
+ [0] = linesBytes[layerIndex][i++],
+ [1] = linesBytes[layerIndex][i++],
+ [2] = linesBytes[layerIndex][i++],
+ [3] = linesBytes[layerIndex][i++],
+ [4] = linesBytes[layerIndex][i++]
+ },
+ Gray = linesBytes[layerIndex][i]
+ };
+
+ CvInvoke.Line(mat, new Point(line.StartX, line.StartY),
+ new Point(line.StartX, line.EndY),
+ new MCvScalar(line.Gray));
+ }
- linesBytes[layerIndex] = null;
+ linesBytes[layerIndex] = null;
- this[layerIndex] = new Layer((uint)layerIndex, mat, this);
- }
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+ }
- progress.LockAndIncrement();
- });
+ progress.LockAndIncrement();
+ });
+ }
}
-
- progress.Token.ThrowIfCancellationRequested();
-
- /*var layerDefs = new LayerDef[LayerCount];
- for (int layerIndex = 0; layerIndex < LayerCount; layerIndex++)
+ else // Partial read
{
- progress.Token.ThrowIfCancellationRequested();
- layerDefs[layerIndex] = Helpers.Deserialize<LayerDef>(inputFile);
- progress++;
+ inputFile.Seek(-Helpers.Serializer.SizeOf(FooterSettings), SeekOrigin.End);
}
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
- Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex =>
- {
- if (progress.Token.IsCancellationRequested) return;
- using var mat = EmguExtensions.InitMat(Resolution);
- foreach (var line in layerDefs[layerIndex].Lines)
- {
- CvInvoke.Line(mat, new Point(line.StartX, line.StartY), new Point(line.StartX, line.EndY), new MCvScalar(line.Gray));
- }
+ progress.Token.ThrowIfCancellationRequested();
+
- this[layerIndex] = new Layer((uint)layerIndex, mat, this);
- progress.LockAndIncrement();
- });*/
FooterSettings = Helpers.Deserialize<Footer>(inputFile);
FooterSettings.Validate();
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
var offset = Helpers.Serializer.SizeOf(HeaderSettings);
foreach (var size in ThumbnailsOriginalSize)
{
diff --git a/UVtools.Core/FileFormats/CXDLPv1File.cs b/UVtools.Core/FileFormats/CXDLPv1File.cs
index 24e79d2..f3cc5ef 100644
--- a/UVtools.Core/FileFormats/CXDLPv1File.cs
+++ b/UVtools.Core/FileFormats/CXDLPv1File.cs
@@ -499,9 +499,9 @@ namespace UVtools.Core.FileFormats
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
if (ResolutionX == 2560 && ResolutionY == 1620)
{
@@ -628,9 +628,9 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
HeaderSettings.Validate();
@@ -654,62 +654,67 @@ namespace UVtools.Core.FileFormats
SlicerInfoSettings = Helpers.Deserialize<SlicerInfo>(inputFile);
Debug.WriteLine(SlicerInfoSettings);
- LayerManager.Init(HeaderSettings.LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
inputFile.Seek(LayerCount * 4 + 2, SeekOrigin.Current); // Skip pre layers
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
-
- var range = Enumerable.Range(0, (int)LayerCount);
-
- var linesBytes = new byte[LayerCount][];
- foreach (var batch in BatchLayersIndexes())
+ if (DecodeType == FileDecodeType.Full)
{
- progress.Token.ThrowIfCancellationRequested();
-
- foreach (var layerIndex in batch)
+ progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
+ var linesBytes = new byte[LayerCount][];
+ foreach (var batch in BatchLayersIndexes())
{
- inputFile.Seek(4, SeekOrigin.Current);
- var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
+ progress.Token.ThrowIfCancellationRequested();
+
+ foreach (var layerIndex in batch)
+ {
+ inputFile.Seek(4, SeekOrigin.Current);
+ var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
- linesBytes[layerIndex] = new byte[lineCount * 6];
- inputFile.ReadBytes(linesBytes[layerIndex]);
- inputFile.Seek(2, SeekOrigin.Current);
+ linesBytes[layerIndex] = new byte[lineCount * 6];
+ inputFile.ReadBytes(linesBytes[layerIndex]);
+ inputFile.Seek(2, SeekOrigin.Current);
- progress.Token.ThrowIfCancellationRequested();
- }
+ progress.Token.ThrowIfCancellationRequested();
+ }
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
- {
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = EmguExtensions.InitMat(Resolution))
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
- for (int i = 0; i < linesBytes[layerIndex].Length; i++)
+ if (progress.Token.IsCancellationRequested) return;
+ using (var mat = EmguExtensions.InitMat(Resolution))
{
- LayerLine line = new()
+ for (int i = 0; i < linesBytes[layerIndex].Length; i++)
{
- Coordinates =
+ LayerLine line = new()
{
- [0] = linesBytes[layerIndex][i++],
- [1] = linesBytes[layerIndex][i++],
- [2] = linesBytes[layerIndex][i++],
- [3] = linesBytes[layerIndex][i++],
- [4] = linesBytes[layerIndex][i++]
- },
- Gray = linesBytes[layerIndex][i]
- };
-
- CvInvoke.Line(mat, new Point(line.StartX, line.StartY), new Point(line.StartX, line.EndY),
- new MCvScalar(line.Gray));
- }
+ Coordinates =
+ {
+ [0] = linesBytes[layerIndex][i++],
+ [1] = linesBytes[layerIndex][i++],
+ [2] = linesBytes[layerIndex][i++],
+ [3] = linesBytes[layerIndex][i++],
+ [4] = linesBytes[layerIndex][i++]
+ },
+ Gray = linesBytes[layerIndex][i]
+ };
+
+ CvInvoke.Line(mat, new Point(line.StartX, line.StartY),
+ new Point(line.StartX, line.EndY),
+ new MCvScalar(line.Gray));
+ }
- linesBytes[layerIndex] = null;
+ linesBytes[layerIndex] = null;
- this[layerIndex] = new Layer((uint)layerIndex, mat, this);
- }
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+ }
- progress.LockAndIncrement();
- });
+ progress.LockAndIncrement();
+ });
+ }
+ }
+ else // Partial read
+ {
+ inputFile.Seek(-Helpers.Serializer.SizeOf(FooterSettings), SeekOrigin.End);
}
progress.Token.ThrowIfCancellationRequested();
@@ -718,24 +723,8 @@ namespace UVtools.Core.FileFormats
FooterSettings.Validate();
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
var offset = Helpers.Serializer.SizeOf(HeaderSettings);
foreach (var size in ThumbnailsOriginalSize)
{
diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs
index 3882ee5..98461fa 100644
--- a/UVtools.Core/FileFormats/ChituboxFile.cs
+++ b/UVtools.Core/FileFormats/ChituboxFile.cs
@@ -1775,7 +1775,7 @@ namespace UVtools.Core.FileFormats
return true;
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
SanitizeMagicVersion();
SanitizeProperties();
@@ -1799,7 +1799,7 @@ namespace UVtools.Core.FileFormats
//uint currentOffset = (uint)Helpers.Serializer.SizeOf(HeaderSettings);
LayerDefinitions = new LayerDef[HeaderSettings.AntiAliasLevel, HeaderSettings.LayerCount];
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
outputFile.Seek(Helpers.Serializer.SizeOf(HeaderSettings), SeekOrigin.Begin);
Mat[] thumbnails = {GetThumbnail(true), GetThumbnail(false)};
@@ -1956,16 +1956,16 @@ namespace UVtools.Core.FileFormats
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
//HeaderSettings = Helpers.ByteToType<CbddlpFile.Header>(InputFile);
//HeaderSettings = Helpers.Serializer.Deserialize<Header>(InputFile.ReadBytes(Helpers.Serializer.SizeOf(typeof(Header))));
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Magic is not MAGIC_CBDDLP and not MAGIC_CTB and not MAGIC_CTBv4)
{
- throw new FileLoadException($"Not a valid PHOTON nor CBDDLP nor CTB file! Magic Value: {HeaderSettings.Magic}", fileFullPath);
+ throw new FileLoadException($"Not a valid PHOTON nor CBDDLP nor CTB file! Magic Value: {HeaderSettings.Magic}", FileFullPath);
}
if (HeaderSettings.Version == 1 || HeaderSettings.AntiAliasLevel == 0)
@@ -1973,8 +1973,6 @@ namespace UVtools.Core.FileFormats
HeaderSettings.AntiAliasLevel = 1;
}
- FileFullPath = fileFullPath;
-
progress.Reset(OperationProgress.StatusDecodePreviews, ThumbnailsCount);
Debug.Write("Header -> ");
@@ -2031,7 +2029,7 @@ namespace UVtools.Core.FileFormats
{
throw new FileLoadException(
$"Malformed file, PrintParametersV4Address is missing",
- fileFullPath);
+ FileFullPath);
}
inputFile.Seek(SlicerInfoSettings.PrintParametersV4Address, SeekOrigin.Begin);
@@ -2044,7 +2042,7 @@ namespace UVtools.Core.FileFormats
throw new FileLoadException(
$"Malformed file, PrintParametersV4 found invalid validation values, expected (4, 4) " +
$"but got ({PrintParametersV4Settings.Four1}, {PrintParametersV4Settings.Four2})",
- fileFullPath);
+ FileFullPath);
}
}
@@ -2053,8 +2051,7 @@ namespace UVtools.Core.FileFormats
uint layerOffset = HeaderSettings.LayersDefinitionOffsetAddress;
- progress.Reset(OperationProgress.StatusGatherLayers,
- HeaderSettings.AntiAliasLevel * HeaderSettings.LayerCount);
+ progress.Reset(OperationProgress.StatusGatherLayers, HeaderSettings.AntiAliasLevel * HeaderSettings.LayerCount);
for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++)
{
@@ -2089,65 +2086,52 @@ namespace UVtools.Core.FileFormats
}
}
- LayerManager.Init(HeaderSettings.LayerCount);
-
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
- foreach (var batch in BatchLayersIndexes())
+ if (DecodeType == FileDecodeType.Full)
{
- foreach (var layerIndex in batch)
- {
- for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++)
- {
- progress.Token.ThrowIfCancellationRequested();
+ progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
- inputFile.Seek(LayerDefinitions[aaIndex, layerIndex].DataAddress, SeekOrigin.Begin);
- LayerDefinitions[aaIndex, layerIndex].EncodedRle = inputFile.ReadBytes(LayerDefinitions[aaIndex, layerIndex].DataSize);
- }
- }
-
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ foreach (var batch in BatchLayersIndexes())
{
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = LayerDefinitions[0, layerIndex].Decode((uint)layerIndex))
+ foreach (var layerIndex in batch)
{
- var layer = new Layer((uint)layerIndex, mat, this);
- if (layerDefinitionsEx is not null) // CTBv4
- {
- layerDefinitionsEx[layerIndex].CopyTo(layer);
- }
- else // others
+ for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++)
{
- LayerDefinitions[0, layerIndex].CopyTo(layer);
- }
+ progress.Token.ThrowIfCancellationRequested();
- this[layerIndex] = layer;
+ inputFile.Seek(LayerDefinitions[aaIndex, layerIndex].DataAddress, SeekOrigin.Begin);
+ LayerDefinitions[aaIndex, layerIndex].EncodedRle = inputFile.ReadBytes(LayerDefinitions[aaIndex, layerIndex].DataSize);
+ }
}
- progress.LockAndIncrement();
- });
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ {
+ if (progress.Token.IsCancellationRequested) return;
+ using var mat = LayerDefinitions[0, layerIndex].Decode((uint)layerIndex);
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+
+ progress.LockAndIncrement();
+ });
+ }
}
- }
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
- {
- if (RequireFullEncode)
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
{
- if (!string.IsNullOrEmpty(filePath))
+ if (layerDefinitionsEx is not null) // CTBv4
+ {
+ layerDefinitionsEx[layerIndex].CopyTo(this[layerIndex]);
+ }
+ else // others
{
- FileFullPath = filePath;
+ LayerDefinitions[0, layerIndex].CopyTo(this[layerIndex]);
}
- Encode(FileFullPath, progress);
- return;
}
+ }
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
+ protected override void PartialSaveInternally(OperationProgress progress)
+ {
SanitizeProperties();
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(0, SeekOrigin.Begin);
diff --git a/UVtools.Core/FileFormats/ChituboxZipFile.cs b/UVtools.Core/FileFormats/ChituboxZipFile.cs
index ead0b3e..7cd44d2 100644
--- a/UVtools.Core/FileFormats/ChituboxZipFile.cs
+++ b/UVtools.Core/FileFormats/ChituboxZipFile.cs
@@ -401,9 +401,9 @@ namespace UVtools.Core.FileFormats
return false;
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using (ZipArchive outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create))
+ using (ZipArchive outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create))
{
if (Thumbnails.Length > 0 && Thumbnails[0] is not null)
{
@@ -416,14 +416,10 @@ namespace UVtools.Core.FileFormats
if (Thumbnails.Length > 1 && Thumbnails[1] is not null)
{
- using (Stream stream = outputFile.CreateEntry("preview_cropping.png").Open())
- {
- using (var vec = new VectorOfByte())
- {
- stream.WriteBytes(Thumbnails[1].GetPngByes());
- stream.Close();
- }
- }
+ using Stream stream = outputFile.CreateEntry("preview_cropping.png").Open();
+ using var vec = new VectorOfByte();
+ stream.WriteBytes(Thumbnails[1].GetPngByes());
+ stream.Close();
}
if (!IsPHZZip)
@@ -443,7 +439,7 @@ namespace UVtools.Core.FileFormats
}
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
using (var inputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read))
{
@@ -497,24 +493,27 @@ namespace UVtools.Core.FileFormats
}
}
- LayerManager.Init(HeaderSettings.LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
progress.ItemCount = LayerCount;
- for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
+ if (DecodeType == FileDecodeType.Full)
{
- if (progress.Token.IsCancellationRequested) break;
- entry = inputFile.GetEntry($"{layerIndex+1}.png");
- if (entry is null)
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
{
- Clear();
- throw new FileLoadException($"Layer {layerIndex+1} not found", fileFullPath);
- }
+ if (progress.Token.IsCancellationRequested) break;
+ entry = inputFile.GetEntry($"{layerIndex + 1}.png");
+ if (entry is null)
+ {
+ Clear();
+ throw new FileLoadException($"Layer {layerIndex + 1} not found", FileFullPath);
+ }
- using var stream = entry.Open();
- this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
+ using var stream = entry.Open();
+ this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
- progress++;
+ progress++;
+ }
}
if (IsPHZZip) // PHZ file
@@ -561,24 +560,8 @@ namespace UVtools.Core.FileFormats
RaisePropertyChanged(nameof(GCodeStr));
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update);
var entriesToRemove = outputFile.Entries.Where(zipEntry => zipEntry.Name.EndsWith(".gcode")).ToArray();
foreach (var zipEntry in entriesToRemove)
diff --git a/UVtools.Core/FileFormats/FDGFile.cs b/UVtools.Core/FileFormats/FDGFile.cs
index ec1e414..442bc8e 100644
--- a/UVtools.Core/FileFormats/FDGFile.cs
+++ b/UVtools.Core/FileFormats/FDGFile.cs
@@ -904,7 +904,7 @@ namespace UVtools.Core.FileFormats
LayersDefinitions = null;
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
/*if (HeaderSettings.EncryptionKey == 0)
{
@@ -912,7 +912,7 @@ namespace UVtools.Core.FileFormats
HeaderSettings.EncryptionKey = (uint)rnd.Next(short.MaxValue, int.MaxValue);
}*/
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
outputFile.Seek(Helpers.Serializer.SizeOf(HeaderSettings), SeekOrigin.Begin);
for (byte i = 0; i < ThumbnailsCount; i++)
@@ -1021,22 +1021,19 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
//HeaderSettings = Helpers.ByteToType<CbddlpFile.Header>(InputFile);
//HeaderSettings = Helpers.Serializer.Deserialize<Header>(InputFile.ReadBytes(Helpers.Serializer.SizeOf(typeof(Header))));
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Magic != MAGIC)
{
- throw new FileLoadException("Not a valid FDG file!", fileFullPath);
+ throw new FileLoadException("Not a valid FDG file!", FileFullPath);
}
HeaderSettings.AntiAliasLevel = 1;
- FileFullPath = fileFullPath;
-
-
progress.Reset(OperationProgress.StatusDecodePreviews, ThumbnailsCount);
Debug.Write("Header -> ");
Debug.WriteLine(HeaderSettings);
@@ -1070,7 +1067,7 @@ namespace UVtools.Core.FileFormats
HeaderSettings.MachineName = Encoding.ASCII.GetString(buffer);
}
- LayerManager.Init(HeaderSettings.LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
LayersDefinitions = new LayerDef[HeaderSettings.LayerCount];
progress.Reset(OperationProgress.StatusDecodeLayers, HeaderSettings.LayerCount);
@@ -1087,45 +1084,37 @@ namespace UVtools.Core.FileFormats
Debug.Write($"LAYER {layerIndex} -> ");
Debug.WriteLine(layerDef);
- inputFile.SeekDoWorkAndRewind(layerDef.DataAddress, () =>
+ if (DecodeType == FileDecodeType.Full)
{
- layerDef.EncodedRle = inputFile.ReadBytes(layerDef.DataSize);
- });
+ inputFile.SeekDoWorkAndRewind(layerDef.DataAddress,
+ () => { layerDef.EncodedRle = inputFile.ReadBytes(layerDef.DataSize); });
+ }
}
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ if (DecodeType == FileDecodeType.Full)
{
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex))
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
- var layer = new Layer((uint)layerIndex, mat, this);
- LayersDefinitions[layerIndex].CopyTo(layer);
- this[layerIndex] = layer;
- }
-
- progress.LockAndIncrement();
- });
- }
- }
+ if (progress.Token.IsCancellationRequested) return;
+ if (DecodeType == FileDecodeType.Full)
+ {
+ using var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex);
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+ }
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
- {
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
+ progress.LockAndIncrement();
+ });
}
- Encode(FileFullPath, progress);
- return;
}
- if (!string.IsNullOrEmpty(filePath))
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
{
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
+ LayersDefinitions[layerIndex].CopyTo(this[layerIndex]);
}
+ }
+ protected override void PartialSaveInternally(OperationProgress progress)
+ {
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(0, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, HeaderSettings);
diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs
index 5ded9f6..cfe695d 100644
--- a/UVtools.Core/FileFormats/FileFormat.cs
+++ b/UVtools.Core/FileFormats/FileFormat.cs
@@ -121,6 +121,19 @@ namespace UVtools.Core.FileFormats
Small = 0,
Large
}
+
+ public enum FileDecodeType : byte
+ {
+ /// <summary>
+ /// Decodes all the file information and caches layer images
+ /// </summary>
+ Full,
+
+ /// <summary>
+ /// Decodes only the information in the file and thumbnails, no layer image is read nor cached, fast
+ /// </summary>
+ Partial,
+ }
#endregion
#region Sub Classes
@@ -441,6 +454,17 @@ namespace UVtools.Core.FileFormats
return PathExtensions.GetFileNameStripExtensions(filepath, AllFileExtensionsString.OrderByDescending(s => s.Length).ToList(), out strippedExtension);
}
+ public static FileFormat Open(string fileFullPath, FileDecodeType decodeType, OperationProgress progress = null)
+ {
+ var slicerFile = FindByExtensionOrFilePath(fileFullPath, true);
+ if (slicerFile is null) return null;
+ slicerFile.Decode(fileFullPath, decodeType, progress);
+ return slicerFile;
+ }
+
+ public static FileFormat Open(string fileFullPath, OperationProgress progress = null) =>
+ Open(fileFullPath, FileDecodeType.Full, progress);
+
public static byte[] EncodeImage(string dataType, Mat mat)
{
@@ -762,6 +786,8 @@ namespace UVtools.Core.FileFormats
/// </summary>
public abstract FileExtension[] FileExtensions { get; }
+ public FileDecodeType DecodeType { get; private set; } = FileDecodeType.Full;
+
/// <summary>
/// Gets the available <see cref="PrintParameterModifier"/>
/// </summary>
@@ -847,6 +873,7 @@ namespace UVtools.Core.FileFormats
/// </summary>
public string FileFullPath { get; set; }
+ public string FileDirectoryPath => Path.GetDirectoryName(FileFullPath);
public string Filename => Path.GetFileName(FileFullPath);
public string FileExtension => Path.GetExtension(FileFullPath);
public string FilenameNoExt => GetFileNameStripExtensions(FileFullPath);
@@ -2520,9 +2547,8 @@ namespace UVtools.Core.FileFormats
/// <summary>
/// Encode to an output file
/// </summary>
- /// <param name="fileFullPath">Output file</param>
/// <param name="progress"></param>
- protected abstract void EncodeInternally(string fileFullPath, OperationProgress progress);
+ protected abstract void EncodeInternally(OperationProgress progress);
/// <summary>
/// Encode to an output file
@@ -2531,6 +2557,11 @@ namespace UVtools.Core.FileFormats
/// <param name="progress"></param>
public void Encode(string fileFullPath, OperationProgress progress = null)
{
+ if (DecodeType == FileDecodeType.Partial)
+ {
+ throw new InvalidOperationException("File was partial decoded, a full encode is not possible.");
+ }
+
progress ??= new OperationProgress();
progress.Reset(OperationProgress.StatusEncodeLayers, LayerCount);
@@ -2543,12 +2574,9 @@ namespace UVtools.Core.FileFormats
LayerManager.Sanitize();
- FileFullPath = fileFullPath;
+ if (File.Exists(fileFullPath)) File.Delete(fileFullPath);
- if (File.Exists(fileFullPath))
- {
- File.Delete(fileFullPath);
- }
+ FileFullPath = fileFullPath;
for (var i = 0; i < Thumbnails.Length; i++)
{
@@ -2557,7 +2585,7 @@ namespace UVtools.Core.FileFormats
CvInvoke.Resize(Thumbnails[i], Thumbnails[i], new Size(ThumbnailsOriginalSize[i].Width, ThumbnailsOriginalSize[i].Height));
}
- EncodeInternally(fileFullPath, progress);
+ EncodeInternally(progress);
LayerManager.SetAllIsModified(false);
RequireFullEncode = false;
@@ -2566,24 +2594,32 @@ namespace UVtools.Core.FileFormats
/// <summary>
/// Decode a slicer file
/// </summary>
+ /// <param name="progress"></param>
+ protected abstract void DecodeInternally(OperationProgress progress);
+
+ /// <summary>
+ /// Decode a slicer file
+ /// </summary>
/// <param name="fileFullPath"></param>
/// <param name="progress"></param>
- protected abstract void DecodeInternally(string fileFullPath, OperationProgress progress);
+ public void Decode(string fileFullPath, OperationProgress progress = null) => Decode(fileFullPath, FileDecodeType.Full, progress);
/// <summary>
/// Decode a slicer file
/// </summary>
/// <param name="fileFullPath"></param>
+ /// <param name="fileDecodeType"></param>
/// <param name="progress"></param>
- public void Decode(string fileFullPath, OperationProgress progress = null)
+ public void Decode(string fileFullPath, FileDecodeType fileDecodeType, OperationProgress progress = null)
{
Clear();
FileValidation(fileFullPath);
FileFullPath = fileFullPath;
+ DecodeType = fileDecodeType;
progress ??= new OperationProgress();
progress.Reset(OperationProgress.StatusGatherLayers, LayerCount);
- DecodeInternally(fileFullPath, progress);
+ DecodeInternally(progress);
progress.Token.ThrowIfCancellationRequested();
@@ -2745,20 +2781,15 @@ namespace UVtools.Core.FileFormats
}
}
- if (LayerCount > 0)
+ if (LayerCount > 0 && DecodeType == FileDecodeType.Full)
{
Parallel.ForEach(this, CoreSettings.ParallelOptions, layer =>
{
if (progress.Token.IsCancellationRequested) return;
var byteArr = layer.CompressedBytes;
- using var stream = File.Create(Path.Combine(path, layer.Filename),
- byteArr.Length);
+ if (byteArr is null) return;
+ using var stream = new FileStream(Path.Combine(path, layer.Filename), FileMode.Create, FileAccess.Write);
stream.Write(byteArr, 0, byteArr.Length);
- stream.Close();
-
- //using var mat = layer.LayerMat;
- //mat.Save(Path.Combine(path, $"{layer.Filename}.jpg"));
-
progress.LockAndIncrement();
});
}
@@ -3343,7 +3374,34 @@ namespace UVtools.Core.FileFormats
/// </summary>
/// <param name="filePath">File path to save copy as, use null to overwrite active file (Same as <see cref="Save"/>)</param>
/// <param name="progress"></param>
- public abstract void SaveAs(string filePath = null, OperationProgress progress = null);
+ public void SaveAs(string filePath = null, OperationProgress progress = null)
+ {
+ if (RequireFullEncode)
+ {
+ if (!string.IsNullOrEmpty(filePath))
+ {
+ FileFullPath = filePath;
+ }
+ Encode(FileFullPath, progress);
+ return;
+ }
+
+ if (!string.IsNullOrEmpty(filePath))
+ {
+ File.Copy(FileFullPath, filePath, true);
+ FileFullPath = filePath;
+
+ }
+
+ PartialSaveInternally(progress);
+ }
+
+ /// <summary>
+ /// Partial save of the file, this is the file information only.
+ /// When this function is called it's already ready to save to file
+ /// </summary>
+ /// <param name="progress"></param>
+ protected abstract void PartialSaveInternally(OperationProgress progress);
/// <summary>
/// Triggers when a conversion is valid and before start converting values
diff --git a/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs b/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs
index 3e3190c..0583caf 100644
--- a/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs
+++ b/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs
@@ -446,17 +446,17 @@ namespace UVtools.Core.FileFormats
#endregion
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
if (SVGDocument.PrintParameters.ResolutionX == 0 || SVGDocument.PrintParameters.ResolutionY == 0 ||
SVGDocument.PrintParameters.DisplayWidth == 0 || SVGDocument.PrintParameters.DisplayHeight == 0)
{
throw new FileLoadException("This file does not contain a resolution and/or display size information needed to generate the layer images.\n" +
"Note that FlashDLPrint slicer is unable to output files with the required information to load in here.\n" +
- "Please use other compatible slicer capable of output the correct information to load the file in here.", fileFullPath);
+ "Please use other compatible slicer capable of output the correct information to load the file in here.", FileFullPath);
}
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
outputFile.Seek(Helpers.Serializer.SizeOf(HeaderSettings), SeekOrigin.Begin);
HeaderSettings.Preview1Address = 0;
@@ -594,13 +594,13 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Identifier != Header.IdentifierText)
{
- throw new FileLoadException("Not a valid Flashforge SVGX file!", fileFullPath);
+ throw new FileLoadException("Not a valid Flashforge SVGX file!", FileFullPath);
}
progress.Reset(OperationProgress.StatusDecodePreviews, ThumbnailsCount);
@@ -644,15 +644,16 @@ namespace UVtools.Core.FileFormats
{
throw new FileLoadException("This file does not contain a resolution and/or display size information needed to generate the layer images.\n" +
"Note that FlashDLPrint slicer is unable to output files with the required information to load in here.\n" +
- "Please use other compatible slicer capable of output the correct information to load the file in here.", fileFullPath);
+ "Please use other compatible slicer capable of output the correct information to load the file in here.", FileFullPath);
}
var halfDisplay = Display.Half();
var ppmm = Ppmm;
- LayerManager.Init(SVGDocument.PrintParameters.LayerCount);
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
+ LayerManager.Init(SVGDocument.PrintParameters.LayerCount, DecodeType == FileDecodeType.Partial);
+ if (DecodeType != FileDecodeType.Full) return;
+ progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex =>
{
if (progress.Token.IsCancellationRequested) return;
@@ -661,14 +662,15 @@ namespace UVtools.Core.FileFormats
var group = SVGDocument.Groups.FirstOrDefault(g => g.Id == $"layer-{layerIndex}");
- if (group is not null)
+ if (@group is not null)
{
var pointsOfPoints = new List<Point[]>();
var points = new List<Point>();
- foreach (var path in group.Paths)
+ foreach (var path in @group.Paths)
{
if (progress.Token.IsCancellationRequested) break;
- var spaceSplit = path.Value.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
+ var spaceSplit = path.Value.Split(' ',
+ StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < spaceSplit.Length; i++)
{
@@ -679,8 +681,10 @@ namespace UVtools.Core.FileFormats
pointsOfPoints.Add(points.ToArray());
points.Clear();
}
+
continue;
}
+
if (spaceSplit[i] == "Z")
{
if (points.Count > 0)
@@ -688,9 +692,12 @@ namespace UVtools.Core.FileFormats
pointsOfPoints.Add(points.ToArray());
points.Clear();
}
+
continue;
}
- if (spaceSplit[i].Length == 1 && !char.IsDigit(spaceSplit[i][0])) continue; // Ignore any other not processed 1 char that's not a digit (L)
+
+ if (spaceSplit[i].Length == 1 && !char.IsDigit(spaceSplit[i][0]))
+ continue; // Ignore any other not processed 1 char that's not a digit (L)
if (i + 1 >= spaceSplit.Length) break; // No more to see
@@ -730,24 +737,8 @@ namespace UVtools.Core.FileFormats
});
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(HeaderSettings.SVGDocumentAddress, SeekOrigin.Begin);
outputFile.SetLength(outputFile.Position);
diff --git a/UVtools.Core/FileFormats/GR1File.cs b/UVtools.Core/FileFormats/GR1File.cs
index 808b588..c55167e 100644
--- a/UVtools.Core/FileFormats/GR1File.cs
+++ b/UVtools.Core/FileFormats/GR1File.cs
@@ -354,9 +354,9 @@ namespace UVtools.Core.FileFormats
#endregion
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
var pageBreak = PageBreak.Bytes;
Helpers.SerializeWriteFileStream(outputFile, HeaderSettings);
@@ -465,13 +465,13 @@ namespace UVtools.Core.FileFormats
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.HeaderValue != Header.HEADER_VALUE)
{
- throw new FileLoadException("Not a valid Makerbase file!", fileFullPath);
+ throw new FileLoadException("Not a valid Makerbase file!", FileFullPath);
}
byte[][] previews = new byte[ThumbnailsOriginalSize.Length][];
@@ -491,77 +491,65 @@ namespace UVtools.Core.FileFormats
SlicerInfoSettings = Helpers.Deserialize<SlicerInfo>(inputFile);
- LayerManager.Init(SlicerInfoSettings.LayerCount);
+ LayerManager.Init(SlicerInfoSettings.LayerCount, DecodeType == FileDecodeType.Partial);
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
-
- var range = Enumerable.Range(0, (int)LayerCount);
-
- var linesBytes = new byte[LayerCount][];
- foreach (var batch in BatchLayersIndexes())
+ if (DecodeType == FileDecodeType.Full)
{
- progress.Token.ThrowIfCancellationRequested();
-
- foreach (var layerIndex in batch)
+ progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
+ var linesBytes = new byte[LayerCount][];
+ foreach (var batch in BatchLayersIndexes())
{
- var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
+ progress.Token.ThrowIfCancellationRequested();
- linesBytes[layerIndex] = new byte[lineCount * 6];
- inputFile.ReadBytes(linesBytes[layerIndex]);
- inputFile.Seek(2, SeekOrigin.Current);
+ foreach (var layerIndex in batch)
+ {
+ var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
- progress.Token.ThrowIfCancellationRequested();
- }
+ linesBytes[layerIndex] = new byte[lineCount * 6];
+ inputFile.ReadBytes(linesBytes[layerIndex]);
+ inputFile.Seek(2, SeekOrigin.Current);
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
- {
- if (progress.Token.IsCancellationRequested) return;
- using var mat = EmguExtensions.InitMat(Resolution);
+ progress.Token.ThrowIfCancellationRequested();
+ }
- for (int i = 0; i < linesBytes[layerIndex].Length; i++)
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
- var startY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
- var endY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
- var startX = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i]);
+ if (progress.Token.IsCancellationRequested) return;
+ using var mat = EmguExtensions.InitMat(Resolution);
- CvInvoke.Line(mat, new Point(startX, startY), new Point(startX, endY), EmguExtensions.WhiteColor);
- }
+ for (int i = 0; i < linesBytes[layerIndex].Length; i++)
+ {
+ var startY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
+ var endY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
+ var startX = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i]);
- linesBytes[layerIndex] = null;
+ CvInvoke.Line(mat, new Point(startX, startY), new Point(startX, endY),
+ EmguExtensions.WhiteColor);
+ }
- this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+ linesBytes[layerIndex] = null;
- progress.LockAndIncrement();
- });
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+
+ progress.LockAndIncrement();
+ });
+ }
+ }
+ else // Partial read
+ {
+ inputFile.Seek(-Helpers.Serializer.SizeOf(HeaderSettings), SeekOrigin.End);
}
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.HeaderValue != Header.HEADER_VALUE)
{
- throw new FileLoadException("Not a valid Makerbase file!", fileFullPath);
+ throw new FileLoadException("Not a valid Makerbase file!", FileFullPath);
}
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(SlicerInfoAddress, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, SlicerInfoSettings);
diff --git a/UVtools.Core/FileFormats/ImageFile.cs b/UVtools.Core/FileFormats/ImageFile.cs
index 6057155..f80b8f1 100644
--- a/UVtools.Core/FileFormats/ImageFile.cs
+++ b/UVtools.Core/FileFormats/ImageFile.cs
@@ -77,14 +77,14 @@ namespace UVtools.Core.FileFormats
private Mat ImageMat { get; set; }
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- throw new NotSupportedException();
+ this[0].LayerMat.Save(FileFullPath);
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- ImageMat = CvInvoke.Imread(fileFullPath, ImreadModes.Grayscale);
+ ImageMat = CvInvoke.Imread(FileFullPath, ImreadModes.Grayscale);
const byte startDivisor = 2;
for (int i = 0; i < ThumbnailsCount; i++)
{
@@ -102,9 +102,9 @@ namespace UVtools.Core.FileFormats
this[0] = new Layer(0, ImageMat, LayerManager);
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- this[0].LayerMat.Save(filePath ?? FileFullPath);
+ this[0].LayerMat.Save(FileFullPath);
}
public override FileFormat Convert(Type to, string fileFullPath, OperationProgress progress = null)
diff --git a/UVtools.Core/FileFormats/LGSFile.cs b/UVtools.Core/FileFormats/LGSFile.cs
index 5ce2820..492c438 100644
--- a/UVtools.Core/FileFormats/LGSFile.cs
+++ b/UVtools.Core/FileFormats/LGSFile.cs
@@ -487,7 +487,7 @@ namespace UVtools.Core.FileFormats
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
if (FileEndsWith(".lgs")) // Longer Orange 10
{
@@ -511,7 +511,7 @@ namespace UVtools.Core.FileFormats
}
//uint currentOffset = (uint)Helpers.Serializer.SizeOf(HeaderSettings);
- using (var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write))
+ using (var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write))
{
outputFile.WriteSerialize(HeaderSettings);
outputFile.WriteBytes(EncodeImage(DATATYPE_RGB565_BE, Thumbnails[0]));
@@ -566,13 +566,13 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Name != Header.NameValue)
{
- throw new FileLoadException("Not a valid LGS file!", fileFullPath);
+ throw new FileLoadException("Not a valid LGS file!", FileFullPath);
}
//if (HeaderSettings.PrinterModel is 10 or 30 or 120)
@@ -594,54 +594,38 @@ namespace UVtools.Core.FileFormats
}
- LayerManager.Init(HeaderSettings.LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
var layerData = new LayerDef[LayerCount];
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
- foreach (var batch in BatchLayersIndexes())
+ if (DecodeType == FileDecodeType.Full)
{
- foreach (var layerIndex in batch)
+ progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
+ foreach (var batch in BatchLayersIndexes())
{
- progress.Token.ThrowIfCancellationRequested();
+ foreach (var layerIndex in batch)
+ {
+ progress.Token.ThrowIfCancellationRequested();
- layerData[layerIndex] = Helpers.Deserialize<LayerDef>(inputFile);
- layerData[layerIndex].Parent = this;
- }
+ layerData[layerIndex] = Helpers.Deserialize<LayerDef>(inputFile);
+ layerData[layerIndex].Parent = this;
+ }
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
- {
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = layerData[layerIndex].Decode())
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
+ if (progress.Token.IsCancellationRequested) return;
+ using var mat = layerData[layerIndex].Decode();
this[layerIndex] = new Layer((uint)layerIndex, mat, this);
- }
- progress.LockAndIncrement();
- });
+ progress.LockAndIncrement();
+ });
+ }
}
LayerManager.RebuildLayersProperties();
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(0, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, HeaderSettings);
diff --git a/UVtools.Core/FileFormats/MDLPFile.cs b/UVtools.Core/FileFormats/MDLPFile.cs
index 10d14e7..7736634 100644
--- a/UVtools.Core/FileFormats/MDLPFile.cs
+++ b/UVtools.Core/FileFormats/MDLPFile.cs
@@ -315,9 +315,9 @@ namespace UVtools.Core.FileFormats
#endregion
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
var pageBreak = PageBreak.Bytes;
Helpers.SerializeWriteFileStream(outputFile, HeaderSettings);
@@ -425,9 +425,9 @@ namespace UVtools.Core.FileFormats
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
//HeaderSettings = Helpers.ByteToType<CbddlpFile.Header>(InputFile);
//HeaderSettings = Helpers.Serializer.Deserialize<Header>(InputFile.ReadBytes(Helpers.Serializer.SizeOf(typeof(Header))));
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
@@ -450,76 +450,62 @@ namespace UVtools.Core.FileFormats
SlicerInfoSettings = Helpers.Deserialize<SlicerInfo>(inputFile);
- LayerManager.Init(SlicerInfoSettings.LayerCount);
+ LayerManager.Init(SlicerInfoSettings.LayerCount, DecodeType == FileDecodeType.Partial);
-
- progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
-
- var range = Enumerable.Range(0, (int)LayerCount);
-
- var linesBytes = new byte[LayerCount][];
- foreach (var batch in BatchLayersIndexes())
+ if (DecodeType == FileDecodeType.Full)
{
- progress.Token.ThrowIfCancellationRequested();
-
- foreach (var layerIndex in batch)
+ progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
+ var linesBytes = new byte[LayerCount][];
+ foreach (var batch in BatchLayersIndexes())
{
- var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
-
- linesBytes[layerIndex] = new byte[lineCount * 6];
- inputFile.ReadBytes(linesBytes[layerIndex]);
- inputFile.Seek(2, SeekOrigin.Current);
-
progress.Token.ThrowIfCancellationRequested();
- }
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
- {
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = EmguExtensions.InitMat(Resolution))
+ foreach (var layerIndex in batch)
{
+ var lineCount = BitExtensions.ToUIntBigEndian(inputFile.ReadBytes(4));
+
+ linesBytes[layerIndex] = new byte[lineCount * 6];
+ inputFile.ReadBytes(linesBytes[layerIndex]);
+ inputFile.Seek(2, SeekOrigin.Current);
- for (int i = 0; i < linesBytes[layerIndex].Length; i++)
+ progress.Token.ThrowIfCancellationRequested();
+ }
+
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ {
+ if (progress.Token.IsCancellationRequested) return;
+ using (var mat = EmguExtensions.InitMat(Resolution))
{
- var startY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
- var endY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
- var startX = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i]);
- CvInvoke.Line(mat, new Point(startX, startY), new Point(startX, endY), EmguExtensions.WhiteColor);
- }
+ for (int i = 0; i < linesBytes[layerIndex].Length; i++)
+ {
+ var startY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
+ var endY = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i++]);
+ var startX = BitExtensions.ToUShortBigEndian(linesBytes[layerIndex][i++], linesBytes[layerIndex][i]);
- linesBytes[layerIndex] = null;
+ CvInvoke.Line(mat, new Point(startX, startY), new Point(startX, endY), EmguExtensions.WhiteColor);
+ }
- this[layerIndex] = new Layer((uint)layerIndex, mat, this);
- }
+ linesBytes[layerIndex] = null;
- progress.LockAndIncrement();
- });
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+ }
+
+ progress.LockAndIncrement();
+ });
+ }
+ }
+ else // Partial read
+ {
+ inputFile.Seek(-Helpers.Serializer.SizeOf(HeaderSettings), SeekOrigin.End);
}
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
HeaderSettings.Validate();
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(SlicerInfoAddress, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, SlicerInfoSettings);
diff --git a/UVtools.Core/FileFormats/OSLAFile.cs b/UVtools.Core/FileFormats/OSLAFile.cs
index c80f680..8d487ab 100644
--- a/UVtools.Core/FileFormats/OSLAFile.cs
+++ b/UVtools.Core/FileFormats/OSLAFile.cs
@@ -465,9 +465,9 @@ namespace UVtools.Core.FileFormats
Previews = null;
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
FileSettings.Update();
var fileDefSize = Helpers.SerializeWriteFileStream(outputFile, FileSettings);
HeaderSettings.TableSize = (uint)Helpers.Serializer.SizeOf(HeaderSettings);
@@ -598,9 +598,9 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
FileSettings = Helpers.Deserialize<FileDef>(inputFile);
Debug.Write("File -> ");
Debug.WriteLine(FileSettings);
@@ -646,7 +646,7 @@ namespace UVtools.Core.FileFormats
inputFile.Seek(HeaderSettings.LayerDefinitionsAddress, SeekOrigin.Begin);
- LayerManager.Init(HeaderSettings.LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
var layerDef = new LayerDef[LayerCount];
@@ -672,34 +672,37 @@ namespace UVtools.Core.FileFormats
}
-
- progress.Reset(OperationProgress.StatusDecodeLayers, HeaderSettings.LayerCount);
- foreach (var batch in BatchLayersIndexes())
+ if (DecodeType == FileDecodeType.Full)
{
- var layerBytes = new byte[LayerCount][];
-
- foreach (var layerIndex in batch)
+ progress.Reset(OperationProgress.StatusDecodeLayers, HeaderSettings.LayerCount);
+ foreach (var batch in BatchLayersIndexes())
{
- progress.Token.ThrowIfCancellationRequested();
+ var layerBytes = new byte[LayerCount][];
- inputFile.Seek(layerDataAddresses[layerIndex], SeekOrigin.Begin);
- layerBytes[layerIndex] = inputFile.ReadBytes(inputFile.ReadUIntLittleEndian());
- }
+ foreach (var layerIndex in batch)
+ {
+ progress.Token.ThrowIfCancellationRequested();
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
- {
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = DecodeImage(HeaderSettings.LayerDataType, layerBytes[layerIndex], Resolution))
+ inputFile.Seek(layerDataAddresses[layerIndex], SeekOrigin.Begin);
+ layerBytes[layerIndex] = inputFile.ReadBytes(inputFile.ReadUIntLittleEndian());
+ }
+
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
+ if (progress.Token.IsCancellationRequested) return;
+ using var mat = DecodeImage(HeaderSettings.LayerDataType, layerBytes[layerIndex], Resolution);
layerBytes[layerIndex] = null; // Clean
- var layer = new Layer((uint)layerIndex, mat, this);
- layerDef[layerIndex].CopyTo(layer);
- this[layerIndex] = layer;
- }
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
- progress.LockAndIncrement();
- });
+ progress.LockAndIncrement();
+ });
+ }
+ }
+
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
+ {
+ layerDef[layerIndex].CopyTo(this[layerIndex]);
}
progress.Reset(OperationProgress.StatusDecodeGcode);
@@ -711,24 +714,8 @@ namespace UVtools.Core.FileFormats
UpdateGlobalPropertiesFromLayers();
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(0, SeekOrigin.Begin);
FileSettings.Update();
diff --git a/UVtools.Core/FileFormats/PHZFile.cs b/UVtools.Core/FileFormats/PHZFile.cs
index b69bf5f..8fc1c4b 100644
--- a/UVtools.Core/FileFormats/PHZFile.cs
+++ b/UVtools.Core/FileFormats/PHZFile.cs
@@ -927,7 +927,7 @@ namespace UVtools.Core.FileFormats
LayersDefinitions = null;
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
/*if (HeaderSettings.EncryptionKey == 0)
{
@@ -936,7 +936,7 @@ namespace UVtools.Core.FileFormats
}*/
LayersDefinitions = new LayerDef[HeaderSettings.LayerCount];
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
outputFile.Seek(Helpers.Serializer.SizeOf(HeaderSettings), SeekOrigin.Begin);
for (byte i = 0; i < ThumbnailsCount; i++)
@@ -1046,15 +1046,15 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
//HeaderSettings = Helpers.ByteToType<CbddlpFile.Header>(InputFile);
//HeaderSettings = Helpers.Serializer.Deserialize<Header>(InputFile.ReadBytes(Helpers.Serializer.SizeOf(typeof(Header))));
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Magic != MAGIC_PHZ)
{
- throw new FileLoadException("Not a valid PHZ file!", fileFullPath);
+ throw new FileLoadException("Not a valid PHZ file!", FileFullPath);
}
HeaderSettings.AntiAliasLevel = 1;
@@ -1093,7 +1093,7 @@ namespace UVtools.Core.FileFormats
}
- LayerManager.Init(HeaderSettings.LayerCount);
+ LayerManager.Init(HeaderSettings.LayerCount, DecodeType == FileDecodeType.Partial);
LayersDefinitions = new LayerDef[HeaderSettings.LayerCount];
progress.Reset(OperationProgress.StatusDecodeLayers, HeaderSettings.LayerCount);
@@ -1110,45 +1110,34 @@ namespace UVtools.Core.FileFormats
Debug.Write($"LAYER {layerIndex} -> ");
Debug.WriteLine(layerDef);
- inputFile.SeekDoWorkAndRewind(layerDef.DataAddress, () =>
+ if (DecodeType == FileDecodeType.Full)
{
- layerDef.EncodedRle = inputFile.ReadBytes(layerDef.DataSize);
- });
+ inputFile.SeekDoWorkAndRewind(layerDef.DataAddress,
+ () => { layerDef.EncodedRle = inputFile.ReadBytes(layerDef.DataSize); });
+ }
}
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ if (DecodeType == FileDecodeType.Full)
{
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex))
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
- var layer = new Layer((uint)layerIndex, mat, this);
- LayersDefinitions[layerIndex].CopyTo(layer);
- this[layerIndex] = layer;
- }
-
- progress.LockAndIncrement();
- });
- }
- }
+ if (progress.Token.IsCancellationRequested) return;
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
- {
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
+ using var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex);
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this);
+ progress.LockAndIncrement();
+ });
}
- Encode(FileFullPath, progress);
- return;
}
- if (!string.IsNullOrEmpty(filePath))
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
{
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
+ LayersDefinitions[layerIndex].CopyTo(this[layerIndex]);
}
+ }
+ protected override void PartialSaveInternally(OperationProgress progress)
+ {
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(0, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, HeaderSettings);
diff --git a/UVtools.Core/FileFormats/PhotonSFile.cs b/UVtools.Core/FileFormats/PhotonSFile.cs
index 87c4368..d054234 100644
--- a/UVtools.Core/FileFormats/PhotonSFile.cs
+++ b/UVtools.Core/FileFormats/PhotonSFile.cs
@@ -434,10 +434,10 @@ namespace UVtools.Core.FileFormats
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
//throw new NotSupportedException("PhotonS is read-only format, please use pws instead!");
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
outputFile.WriteSerialize(HeaderSettings);
outputFile.WriteBytes(EncodeImage(DATATYPE_BGR565, Thumbnails[0]));
outputFile.WriteSerialize(LayerSettings);
@@ -474,13 +474,13 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine("-End-");
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Tag1 != Header.TAG1 || HeaderSettings.Tag2 != Header.TAG2)
{
- throw new FileLoadException("Not a valid PHOTONS file! TAGs doesn't match", fileFullPath);
+ throw new FileLoadException("Not a valid PHOTONS file! TAGs doesn't match", FileFullPath);
}
int previewSize = (int) (HeaderSettings.PreviewResolutionX * HeaderSettings.PreviewResolutionY * 2);
@@ -495,7 +495,7 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine(LayerSettings);
- LayerManager.Init(LayerSettings.LayerCount);
+ LayerManager.Init(LayerSettings.LayerCount, DecodeType == FileDecodeType.Partial);
var layersDefinitions = new LayerDef[LayerSettings.LayerCount];
progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
@@ -508,7 +508,8 @@ namespace UVtools.Core.FileFormats
var layerDef = Helpers.Deserialize<LayerDef>(inputFile);
layersDefinitions[layerIndex] = layerDef;
- layerDef.EncodedRle = inputFile.ReadBytes(layerDef.RleDataSize);
+ if (DecodeType == FileDecodeType.Full) layerDef.EncodedRle = inputFile.ReadBytes(layerDef.RleDataSize);
+ else inputFile.Seek(layerDef.RleDataSize, SeekOrigin.Current);
Debug.Write($"LAYER {layerIndex} -> ");
Debug.WriteLine(layerDef);
@@ -521,40 +522,23 @@ namespace UVtools.Core.FileFormats
}
}
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ if (DecodeType == FileDecodeType.Full)
{
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = layersDefinitions[layerIndex].Decode())
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
+ if (progress.Token.IsCancellationRequested) return;
+ using var mat = layersDefinitions[layerIndex].Decode();
this[layerIndex] = new Layer((uint)layerIndex, mat, this);
- }
-
- progress.LockAndIncrement();
- });
+ progress.LockAndIncrement();
+ });
+ }
}
LayerManager.RebuildLayersProperties();
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
outputFile.Seek(0, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, HeaderSettings);
diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
index 33176aa..246d6b2 100644
--- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
+++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
@@ -1256,7 +1256,7 @@ namespace UVtools.Core.FileFormats
LayersDefinition = null;
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
HeaderSettings.PixelSizeUm = PixelSizeMicronsMax;
@@ -1277,7 +1277,7 @@ namespace UVtools.Core.FileFormats
FileMarkSettings.HeaderAddress = (uint) Helpers.Serializer.SizeOf(FileMarkSettings);
- using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
+ using var outputFile = new FileStream(FileFullPath, FileMode.Create, FileAccess.Write);
outputFile.Seek((int)FileMarkSettings.HeaderAddress, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, HeaderSettings);
@@ -1348,9 +1348,9 @@ namespace UVtools.Core.FileFormats
Helpers.SerializeWriteFileStream(outputFile, FileMarkSettings);
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
+ using var inputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Read);
FileMarkSettings = Helpers.Deserialize<FileMark>(inputFile);
Debug.Write("FileMark -> ");
@@ -1359,17 +1359,14 @@ namespace UVtools.Core.FileFormats
if (!FileMarkSettings.Mark.Equals(FileMark.SectionMarkFile))
{
throw new FileLoadException(
- $"Invalid Filemark {FileMarkSettings.Mark}, expected {FileMark.SectionMarkFile}", fileFullPath);
+ $"Invalid Filemark {FileMarkSettings.Mark}, expected {FileMark.SectionMarkFile}", FileFullPath);
}
if (FileMarkSettings.Version is not VERSION_1 and not VERSION_515)
{
- throw new FileLoadException($"Invalid Version {FileMarkSettings.Version}, expected {VERSION_1} or {VERSION_515}",
- fileFullPath);
+ throw new FileLoadException($"Invalid Version {FileMarkSettings.Version}, expected {VERSION_1} or {VERSION_515}", FileFullPath);
}
- FileFullPath = fileFullPath;
-
inputFile.Seek(FileMarkSettings.HeaderAddress, SeekOrigin.Begin);
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
@@ -1402,7 +1399,7 @@ namespace UVtools.Core.FileFormats
Debug.Write("LayersDefinition -> ");
Debug.WriteLine(LayersDefinition);
- LayerManager.Init(LayersDefinition.LayerCount);
+ LayerManager.Init(LayersDefinition.LayerCount, DecodeType == FileDecodeType.Partial);
LayersDefinition.Layers = new LayerDef[LayerCount];
LayersDefinition.Validate();
@@ -1418,52 +1415,43 @@ namespace UVtools.Core.FileFormats
LayersDefinition[layerIndex].Parent = this;
Debug.WriteLine($"Layer {layerIndex}: {LayersDefinition[layerIndex]}");
-
- inputFile.SeekDoWorkAndRewind(LayersDefinition[layerIndex].DataAddress, () =>
+ if (DecodeType == FileDecodeType.Full)
{
- LayersDefinition[layerIndex].EncodedRle = inputFile.ReadBytes(LayersDefinition[layerIndex].DataLength);
- });
+ inputFile.SeekDoWorkAndRewind(LayersDefinition[layerIndex].DataAddress,
+ () =>
+ {
+ LayersDefinition[layerIndex].EncodedRle = inputFile.ReadBytes(LayersDefinition[layerIndex].DataLength);
+ });
+ }
}
- Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
+ if (DecodeType == FileDecodeType.Full)
{
- if (progress.Token.IsCancellationRequested) return;
- using (var mat = LayersDefinition[layerIndex].Decode())
+ Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex =>
{
- var layer = new Layer((uint)layerIndex, mat, this)
+ if (progress.Token.IsCancellationRequested) return;
+
+ using var mat = LayersDefinition[layerIndex].Decode();
+ this[layerIndex] = new Layer((uint)layerIndex, mat, this)
{
PositionZ = LayersDefinition.Layers
.Where((_, i) => i <= layerIndex)
.Sum(def => def.LayerHeight),
};
- LayersDefinition[layerIndex].CopyTo(layer);
- this[layerIndex] = layer;
- }
-
- progress.LockAndIncrement();
- });
- }
- }
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
- {
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
+ progress.LockAndIncrement();
+ });
}
- Encode(FileFullPath, progress);
- return;
}
-
- if (!string.IsNullOrEmpty(filePath))
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
{
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
+ LayersDefinition[layerIndex].CopyTo(this[layerIndex]);
}
+ }
+ protected override void PartialSaveInternally(OperationProgress progress)
+ {
HeaderSettings.PerLayerOverride = LayerManager.AllLayersAreUsingGlobalParameters ? 0 : 1u;
using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write);
diff --git a/UVtools.Core/FileFormats/SL1File.cs b/UVtools.Core/FileFormats/SL1File.cs
index feac9dd..34fc91c 100644
--- a/UVtools.Core/FileFormats/SL1File.cs
+++ b/UVtools.Core/FileFormats/SL1File.cs
@@ -533,13 +533,13 @@ namespace UVtools.Core.FileFormats
Statistics.Clear();
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- var filename = fileFullPath;
+ var filename = FileFullPath;
if (filename.EndsWith(TemporaryFileAppend)) filename = Path.GetFileNameWithoutExtension(filename); // tmp
filename = Path.GetFileNameWithoutExtension(filename); // sl1
OutputConfigSettings.JobDir = filename;
- using ZipArchive outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create);
+ using ZipArchive outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create);
var entry = outputFile.CreateEntry("config.ini");
using (TextWriter tw = new StreamWriter(entry.Open()))
{
@@ -596,7 +596,7 @@ namespace UVtools.Core.FileFormats
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
PrinterSettings = new Printer();
MaterialSettings = new Material();
@@ -605,7 +605,7 @@ namespace UVtools.Core.FileFormats
Statistics.ExecutionTime.Restart();
- using (var inputFile = ZipFile.OpenRead(fileFullPath))
+ using (var inputFile = ZipFile.OpenRead(FileFullPath))
{
List<string> iniFiles = new();
foreach (ZipArchiveEntry entity in inputFile.Entries)
@@ -689,7 +689,7 @@ namespace UVtools.Core.FileFormats
LightPWM = LookupCustomValue(Keyword_LightPWM, DefaultBottomLightPWM);
});
- LayerManager.Init(OutputConfigSettings.NumSlow + OutputConfigSettings.NumFast);
+ LayerManager.Init(OutputConfigSettings.NumSlow + OutputConfigSettings.NumFast, DecodeType == FileDecodeType.Partial);
progress.ItemCount = LayerCount;
@@ -698,7 +698,7 @@ namespace UVtools.Core.FileFormats
if (!entity.Name.EndsWith(".png")) continue;
if (entity.Name.StartsWith("thumbnail"))
{
- using Stream stream = entity.Open();
+ using var stream = entity.Open();
Mat image = new();
CvInvoke.Imdecode(stream.ToArray(), ImreadModes.AnyColor, image);
byte thumbnailIndex =
@@ -707,17 +707,21 @@ namespace UVtools.Core.FileFormats
? FileThumbnailSize.Small
: FileThumbnailSize.Large);
Thumbnails[thumbnailIndex] = image;
- stream.Close();
//thumbnailIndex++;
continue;
}
-
- // - .png - 5 numbers
- string layerStr = entity.Name.Substring(entity.Name.Length - 4 - 5, 5);
- uint iLayer = uint.Parse(layerStr);
- this[iLayer] = new Layer(iLayer, entity.Open(), LayerManager);
+
+ if (DecodeType == FileDecodeType.Full)
+ {
+ // - .png - 5 numbers
+ string layerStr = entity.Name.Substring(entity.Name.Length - 4 - 5, 5);
+ uint iLayer = uint.Parse(layerStr);
+ using var stream = entity.Open();
+ this[iLayer] = new Layer(iLayer, stream, LayerManager);
+ }
+
progress.ProcessedItems++;
}
}
@@ -729,26 +733,8 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine(Statistics);
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
-
- }
-
using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update);
//InputFile.CreateEntry("Modified");
using (TextWriter tw = new StreamWriter(outputFile.PutFileContent("config.ini", string.Empty, ZipArchiveMode.Update).Open()))
diff --git a/UVtools.Core/FileFormats/UVJFile.cs b/UVtools.Core/FileFormats/UVJFile.cs
index 913fc8c..9fabb76 100644
--- a/UVtools.Core/FileFormats/UVJFile.cs
+++ b/UVtools.Core/FileFormats/UVJFile.cs
@@ -467,7 +467,7 @@ namespace UVtools.Core.FileFormats
JsonSettings.Layers = new List<LayerDef>();
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
// Redo layer data
if (JsonSettings.Layers is null)
@@ -484,7 +484,7 @@ namespace UVtools.Core.FileFormats
JsonSettings.Layers.Add(new LayerDef(this[layerIndex]));
}
- using var outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create);
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create);
outputFile.PutFileContent(FileConfigName, JsonConvert.SerializeObject(JsonSettings, Formatting.Indented), ZipArchiveMode.Create);
if (CreatedThumbnailsCount > 0)
@@ -514,20 +514,20 @@ namespace UVtools.Core.FileFormats
}
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using (var inputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Read))
+ using (var inputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read))
{
var entry = inputFile.GetEntry(FileConfigName);
if (entry is null)
{
Clear();
- throw new FileLoadException($"{FileConfigName} not found", fileFullPath);
+ throw new FileLoadException($"{FileConfigName} not found", FileFullPath);
}
JsonSettings = Helpers.JsonDeserializeObject<Settings>(entry.Open());
- LayerManager.Init(JsonSettings.Properties.Size.Layers);
+ LayerManager.Init(JsonSettings.Properties.Size.Layers, DecodeType == FileDecodeType.Partial);
entry = inputFile.GetEntry(FilePreviewTinyName);
if (entry is not null)
@@ -554,15 +554,16 @@ namespace UVtools.Core.FileFormats
entry = inputFile.GetEntry($"{FolderImageName}/{layerIndex:D8}.png");
if (entry is null) continue;
- using var stream = entry.Open();
- var layer = new Layer(layerIndex, stream, LayerManager);
+ if (DecodeType == FileDecodeType.Full)
+ {
+ using var stream = entry.Open();
+ this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
+ }
if (JsonSettings.Layers?.Count > layerIndex)
{
- JsonSettings.Layers[(int)layerIndex].CopyTo(layer);
+ JsonSettings.Layers[(int)layerIndex].CopyTo(this[layerIndex]);
}
-
- this[layerIndex] = layer;
}
progress.ProcessedItems++;
@@ -571,25 +572,8 @@ namespace UVtools.Core.FileFormats
LayerManager.GetBoundingRectangle(progress);
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
-
- }
-
if (JsonSettings.Layers is null)
{
JsonSettings.Layers = new List<LayerDef>();
diff --git a/UVtools.Core/FileFormats/VDAFile.cs b/UVtools.Core/FileFormats/VDAFile.cs
index f8353ed..8f83d41 100644
--- a/UVtools.Core/FileFormats/VDAFile.cs
+++ b/UVtools.Core/FileFormats/VDAFile.cs
@@ -302,10 +302,10 @@ namespace UVtools.Core.FileFormats
return false;
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using var outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create);
- var manifestFilename = Path.GetFileName(fileFullPath).
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create);
+ var manifestFilename = Filename.
Replace($".{FileExtensions[0].Extension}{TemporaryFileAppend}", ".xml").
Replace($".{FileExtensions[0].Extension}", ".xml");
@@ -328,7 +328,7 @@ namespace UVtools.Core.FileFormats
serializer.Serialize(stream, ManifestFile, ns);
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
using (var inputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read))
{
@@ -336,7 +336,7 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException($".xml manifest not found", fileFullPath);
+ throw new FileLoadException($".xml manifest not found", FileFullPath);
}
try
@@ -348,11 +348,11 @@ namespace UVtools.Core.FileFormats
catch (Exception e)
{
Clear();
- throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", fileFullPath);
+ throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", FileFullPath);
}
- LayerManager.Init(ManifestFile.Slices.LayerCount);
+ LayerManager.Init(ManifestFile.Slices.LayerCount, DecodeType == FileDecodeType.Partial);
progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
@@ -364,11 +364,14 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException($"Layer {filename} not found", fileFullPath);
+ throw new FileLoadException($"Layer {filename} not found", FileFullPath);
}
- using var stream = entry.Open();
- this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
+ if (DecodeType == FileDecodeType.Full)
+ {
+ using var stream = entry.Open();
+ this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
+ }
progress++;
}
@@ -377,24 +380,8 @@ namespace UVtools.Core.FileFormats
LayerManager.GetBoundingRectangle(progress);
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update);
bool deleted;
diff --git a/UVtools.Core/FileFormats/VDTFile.cs b/UVtools.Core/FileFormats/VDTFile.cs
index 7d725e3..db5fe12 100644
--- a/UVtools.Core/FileFormats/VDTFile.cs
+++ b/UVtools.Core/FileFormats/VDTFile.cs
@@ -149,6 +149,42 @@ namespace UVtools.Core.FileFormats
[JsonProperty("retract_distance2")] public float RetractHeight2 { get; set; } = DefaultRetractHeight2;
[JsonProperty("retract_speed2")] public float RetractSpeed2 { get; set; } = DefaultRetractSpeed2;
[JsonProperty("light_pwm")] public byte LightPWM { get; set; } = DefaultLightPWM;
+
+ public void SetFrom(Layer layer)
+ {
+ PositionZ = layer.PositionZ;
+ LightOffDelay = layer.LightOffDelay;
+ WaitTimeBeforeCure = layer.WaitTimeBeforeCure;
+ ExposureTime = layer.ExposureTime;
+ WaitTimeAfterCure = layer.WaitTimeAfterCure;
+ LiftHeight = layer.LiftHeight;
+ LiftSpeed = layer.LiftSpeed;
+ LiftHeight2 = layer.LiftHeight2;
+ LiftSpeed2 = layer.LiftSpeed2;
+ WaitTimeAfterLift = layer.WaitTimeAfterLift;
+ RetractSpeed = layer.RetractSpeed;
+ RetractHeight2 = layer.RetractHeight2;
+ RetractSpeed2 = layer.RetractSpeed2;
+ LightPWM = layer.LightPWM;
+ }
+
+ public void CopyTo(Layer layer)
+ {
+ layer.PositionZ = PositionZ;
+ layer.LightOffDelay = LightOffDelay;
+ layer.WaitTimeBeforeCure = WaitTimeBeforeCure;
+ layer.ExposureTime = ExposureTime;
+ layer.WaitTimeAfterCure = WaitTimeAfterCure;
+ layer.LiftHeight = LiftHeight;
+ layer.LiftSpeed = LiftSpeed;
+ layer.LiftHeight2 = LiftHeight2;
+ layer.LiftSpeed2 = LiftSpeed2;
+ layer.WaitTimeAfterLift = WaitTimeAfterLift;
+ layer.RetractSpeed = RetractSpeed;
+ layer.RetractHeight2 = RetractHeight2;
+ layer.RetractSpeed2 = RetractSpeed2;
+ layer.LightPWM = LightPWM;
+ }
}
#endregion
@@ -566,12 +602,12 @@ namespace UVtools.Core.FileFormats
}
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
// Redo layer data
RebuildVDTLayers();
- using var outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create);
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create);
outputFile.PutFileContent(FileManifestName, JsonConvert.SerializeObject(ManifestFile, Formatting.Indented), ZipArchiveMode.Create);
if (CreatedThumbnailsCount > 0)
@@ -598,20 +634,20 @@ namespace UVtools.Core.FileFormats
}
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using (var inputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Read))
+ using (var inputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read))
{
var entry = inputFile.GetEntry(FileManifestName);
if (entry is null)
{
Clear();
- throw new FileLoadException($"{FileManifestName} not found", fileFullPath);
+ throw new FileLoadException($"{FileManifestName} not found", FileFullPath);
}
ManifestFile = Helpers.JsonDeserializeObject<VDTManifest>(entry.Open());
- LayerManager.Init((uint) ManifestFile.Layers.Length);
+ LayerManager.Init((uint) ManifestFile.Layers.Length, DecodeType == FileDecodeType.Partial);
for (int i = 0; i < FilePreviewNames.Length; i++)
{
@@ -631,24 +667,14 @@ namespace UVtools.Core.FileFormats
var manifestLayer = ManifestFile.Layers[layerIndex];
entry = inputFile.GetEntry($"{layerIndex}.png");
if (entry is null) continue;
- using var stream = entry.Open();
- this[layerIndex] = new Layer(layerIndex, stream, LayerManager)
+
+ if (DecodeType == FileDecodeType.Full)
{
- PositionZ = manifestLayer.PositionZ,
- LightOffDelay = manifestLayer.LightOffDelay,
- WaitTimeBeforeCure = manifestLayer.WaitTimeBeforeCure,
- ExposureTime = manifestLayer.ExposureTime,
- WaitTimeAfterCure = manifestLayer.WaitTimeAfterCure,
- LiftHeight = manifestLayer.LiftHeight,
- LiftSpeed = manifestLayer.LiftSpeed,
- LiftHeight2 = manifestLayer.LiftHeight2,
- LiftSpeed2 = manifestLayer.LiftSpeed2,
- WaitTimeAfterLift = manifestLayer.WaitTimeAfterLift,
- RetractSpeed = manifestLayer.RetractSpeed,
- RetractHeight2 = manifestLayer.RetractHeight2,
- RetractSpeed2 = manifestLayer.RetractSpeed2,
- LightPWM = manifestLayer.LightPWM,
- };
+ using var stream = entry.Open();
+ this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
+ }
+
+ manifestLayer.CopyTo(this[layerIndex]);
}
progress.ProcessedItems++;
@@ -657,25 +683,8 @@ namespace UVtools.Core.FileFormats
LayerManager.GetBoundingRectangle(progress);
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
-
- }
-
RebuildVDTLayers();
using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update);
outputFile.PutFileContent(FileManifestName, JsonConvert.SerializeObject(ManifestFile, Formatting.Indented), ZipArchiveMode.Update);
diff --git a/UVtools.Core/FileFormats/ZCodeFile.cs b/UVtools.Core/FileFormats/ZCodeFile.cs
index cb4710a..37728c9 100644
--- a/UVtools.Core/FileFormats/ZCodeFile.cs
+++ b/UVtools.Core/FileFormats/ZCodeFile.cs
@@ -467,9 +467,9 @@ namespace UVtools.Core.FileFormats
#region Methods
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
- using ZipArchive outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create);
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create);
if (Thumbnails.Length > 0 && Thumbnails[0] is not null)
{
using var thumbnailsStream = outputFile.CreateEntry(PreviewFilename).Open();
@@ -497,14 +497,14 @@ namespace UVtools.Core.FileFormats
outputFile.PutFileContent(GCodeFilename, EncryptGCode(progress), ZipArchiveMode.Create);
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
using var inputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read);
var entry = inputFile.GetEntry(ManifestFilename);
if (entry is null)
{
Clear();
- throw new FileLoadException($"{ManifestFilename} not found", fileFullPath);
+ throw new FileLoadException($"{ManifestFilename} not found", FileFullPath);
}
try
@@ -516,14 +516,14 @@ namespace UVtools.Core.FileFormats
catch (Exception e)
{
Clear();
- throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", fileFullPath);
+ throw new FileLoadException($"Unable to deserialize '{entry.Name}'\n{e}", FileFullPath);
}
entry = inputFile.GetEntry(GCodeFilename);
if (entry is null)
{
Clear();
- throw new FileLoadException($"{GCodeFilename} not found", fileFullPath);
+ throw new FileLoadException($"{GCodeFilename} not found", FileFullPath);
}
var encryptEngine = new RsaEngine();
@@ -551,7 +551,7 @@ namespace UVtools.Core.FileFormats
tr.Close();
}
- LayerManager.Init(ManifestFile.Job.LayerCount);
+ LayerManager.Init(ManifestFile.Job.LayerCount, DecodeType == FileDecodeType.Partial);
progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
//var gcode = GCode.ToString();
@@ -564,12 +564,15 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException($"Layer {layerIndex+1} not found", fileFullPath);
+ throw new FileLoadException($"Layer {layerIndex+1} not found", FileFullPath);
}
- using var stream = entry.Open();
- this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
-
+ if (DecodeType == FileDecodeType.Full)
+ {
+ using var stream = entry.Open();
+ this[layerIndex] = new Layer(layerIndex, stream, LayerManager);
+ }
+
progress++;
}
@@ -585,24 +588,8 @@ namespace UVtools.Core.FileFormats
LayerManager.GetBoundingRectangle(progress);
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
- }
-
using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update);
var entriesToRemove = outputFile.Entries.Where(zipEntry => zipEntry.Name.EndsWith(".gcode") || zipEntry.Name.EndsWith(".xml")).ToArray();
diff --git a/UVtools.Core/FileFormats/ZCodexFile.cs b/UVtools.Core/FileFormats/ZCodexFile.cs
index 34f3839..e8d7eaf 100644
--- a/UVtools.Core/FileFormats/ZCodexFile.cs
+++ b/UVtools.Core/FileFormats/ZCodexFile.cs
@@ -374,7 +374,7 @@ namespace UVtools.Core.FileFormats
LayersSettings.Clear();
}
- protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void EncodeInternally(OperationProgress progress)
{
float usedMaterial = MaterialMilliliters / LayerCount;
ResinMetadataSettings.Layers.Clear();
@@ -387,87 +387,83 @@ namespace UVtools.Core.FileFormats
});
}
- using (ZipArchive outputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create))
- {
- outputFile.PutFileContent("ResinMetadata", JsonConvert.SerializeObject(ResinMetadataSettings, Formatting.Indented), ZipArchiveMode.Create);
- outputFile.PutFileContent("UserSettingsData", JsonConvert.SerializeObject(UserSettings, Formatting.Indented), ZipArchiveMode.Create);
- outputFile.PutFileContent("ZCodeMetadata", JsonConvert.SerializeObject(ZCodeMetadataSettings, Formatting.Indented), ZipArchiveMode.Create);
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Create);
+ outputFile.PutFileContent("ResinMetadata", JsonConvert.SerializeObject(ResinMetadataSettings, Formatting.Indented), ZipArchiveMode.Create);
+ outputFile.PutFileContent("UserSettingsData", JsonConvert.SerializeObject(UserSettings, Formatting.Indented), ZipArchiveMode.Create);
+ outputFile.PutFileContent("ZCodeMetadata", JsonConvert.SerializeObject(ZCodeMetadataSettings, Formatting.Indented), ZipArchiveMode.Create);
- if (CreatedThumbnailsCount > 0)
- {
- using (var stream = outputFile.CreateEntry("Preview.png").Open())
- {
- stream.WriteBytes(Thumbnails[0].GetPngByes());
- stream.Close();
- }
- }
+ if (CreatedThumbnailsCount > 0)
+ {
+ using var stream = outputFile.CreateEntry("Preview.png").Open();
+ stream.WriteBytes(Thumbnails[0].GetPngByes());
+ stream.Close();
+ }
- GCode.Clear();
+ GCode.Clear();
- float lastZPosition = 0;
- for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
- {
- progress.Token.ThrowIfCancellationRequested();
+ float lastZPosition = 0;
+ for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++)
+ {
+ progress.Token.ThrowIfCancellationRequested();
- Layer layer = this[layerIndex];
- GCode.AppendLine($"{GCodeKeywordSlice} {layerIndex}");
+ var layer = this[layerIndex];
+ GCode.AppendLine($"{GCodeKeywordSlice} {layerIndex}");
- if (lastZPosition != layer.PositionZ)
+ if (lastZPosition != layer.PositionZ)
+ {
+ if (layer.LiftHeight > 0)
{
- if (layer.LiftHeight > 0)
- {
- GCode.AppendLine($"G1 Z{layer.LiftHeight} F{layer.LiftSpeed}");
- GCode.AppendLine($"G1 Z-{Layer.RoundHeight(layer.LiftHeight - layer.PositionZ + lastZPosition)} F{layer.RetractSpeed}");
- }
- else
- {
- GCode.AppendLine($"G1 Z{Layer.RoundHeight(layer.PositionZ- lastZPosition)} F{layer.LiftSpeed}");
- }
+ GCode.AppendLine($"G1 Z{layer.LiftHeight} F{layer.LiftSpeed}");
+ GCode.AppendLine($"G1 Z-{Layer.RoundHeight(layer.LiftHeight - layer.PositionZ + lastZPosition)} F{layer.RetractSpeed}");
}
- /*else
+ else
+ {
+ GCode.AppendLine($"G1 Z{Layer.RoundHeight(layer.PositionZ- lastZPosition)} F{layer.LiftSpeed}");
+ }
+ }
+ /*else
{
//GCode.AppendLine($";G1 Z{LiftHeight} F{LiftSpeed}; Already here");
//GCode.AppendLine($";G1 Z-{LiftHeight - layer.PositionZ + lastZPosition} F{RetractSpeed}; Already here");
}*/
- //GCode.AppendLine($"G1 Z{LiftHeight} F{LiftSpeed}");
- //GCode.AppendLine($"G1 Z-{LiftHeight - LayerHeight} F{RetractSpeed}");
- GCode.AppendLine(GCodeKeywordDelayBlank);
- GCode.AppendLine("M106 S255");
- GCode.AppendLine(GCodeKeywordDelayModel);
- GCode.AppendLine("M106 S0");
-
-
- var layerimagePath = $"{FolderImages}/{FolderImageName}{layerIndex:D5}.png";
- using (Stream stream = outputFile.CreateEntry(layerimagePath).Open())
- {
- //image.Save(stream, Helpers.PngEncoder);
- var byteArr = this[layerIndex].CompressedBytes;
- stream.Write(byteArr, 0, byteArr.Length);
- stream.Close();
- }
+ //GCode.AppendLine($"G1 Z{LiftHeight} F{LiftSpeed}");
+ //GCode.AppendLine($"G1 Z-{LiftHeight - LayerHeight} F{RetractSpeed}");
+ GCode.AppendLine(GCodeKeywordDelayBlank);
+ GCode.AppendLine("M106 S255");
+ GCode.AppendLine(GCodeKeywordDelayModel);
+ GCode.AppendLine("M106 S0");
- lastZPosition = layer.PositionZ;
- progress++;
+ var layerimagePath = $"{FolderImages}/{FolderImageName}{layerIndex:D5}.png";
+ using (var stream = outputFile.CreateEntry(layerimagePath).Open())
+ {
+ //image.Save(stream, Helpers.PngEncoder);
+ var byteArr = this[layerIndex].CompressedBytes;
+ stream.Write(byteArr, 0, byteArr.Length);
+ stream.Close();
}
- GCode.AppendLine($"G1 Z40.0 F{UserSettings.ZLiftFeedRate}");
- GCode.AppendLine("M18");
+ lastZPosition = layer.PositionZ;
- outputFile.PutFileContent("ResinGCodeData", GCode.ToString(), ZipArchiveMode.Create);
+ progress++;
}
+
+ GCode.AppendLine($"G1 Z40.0 F{UserSettings.ZLiftFeedRate}");
+ GCode.AppendLine("M18");
+
+ outputFile.PutFileContent("ResinGCodeData", GCode.ToString(), ZipArchiveMode.Create);
}
- protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
+ protected override void DecodeInternally(OperationProgress progress)
{
- using (var inputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Read))
+ using (var inputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read))
{
var entry = inputFile.GetEntry("ResinMetadata");
if (entry is null)
{
Clear();
- throw new FileLoadException("ResinMetadata not found", fileFullPath);
+ throw new FileLoadException("ResinMetadata not found", FileFullPath);
}
ResinMetadataSettings = Helpers.JsonDeserializeObject<ResinMetadata>(entry.Open());
@@ -476,7 +472,7 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException("UserSettingsData not found", fileFullPath);
+ throw new FileLoadException("UserSettingsData not found", FileFullPath);
}
UserSettings = Helpers.JsonDeserializeObject<UserSettingsdata>(entry.Open());
@@ -485,7 +481,7 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException("ZCodeMetadata not found", fileFullPath);
+ throw new FileLoadException("ZCodeMetadata not found", FileFullPath);
}
ZCodeMetadataSettings = Helpers.JsonDeserializeObject<ZCodeMetadata>(entry.Open());
@@ -494,10 +490,10 @@ namespace UVtools.Core.FileFormats
if (entry is null)
{
Clear();
- throw new FileLoadException("ResinGCodeData not found", fileFullPath);
+ throw new FileLoadException("ResinGCodeData not found", FileFullPath);
}
- LayerManager.Init(ResinMetadataSettings.TotalLayersCount);
+ LayerManager.Init(ResinMetadataSettings.TotalLayersCount, DecodeType == FileDecodeType.Partial);
GCode.Clear();
using (TextReader tr = new StreamReader(entry.Open()))
{
@@ -577,14 +573,18 @@ M106 S0
LayersSettings[layerIndex].LayerFileIndex = layerFileIndex;
LayersSettings[layerIndex].LayerEntry = inputFile.GetEntry(layerimagePath);
- this[layerIndex] = new Layer((uint) layerIndex, LayersSettings[layerIndex].LayerEntry.Open(), LayerManager)
+
+ if (DecodeType == FileDecodeType.Full)
{
- PositionZ = currentHeight,
- LiftHeight = liftHeight,
- LiftSpeed = liftSpeed,
- RetractSpeed = retractSpeed,
- LightPWM = pwm
- };
+ using var stream = LayersSettings[layerIndex].LayerEntry.Open();
+ this[layerIndex] = new Layer((uint)layerIndex, stream, LayerManager);
+ }
+
+ this[layerIndex].PositionZ = currentHeight;
+ this[layerIndex].LiftHeight = liftHeight;
+ this[layerIndex].LiftSpeed = liftSpeed;
+ this[layerIndex].RetractSpeed = retractSpeed;
+ this[layerIndex].LightPWM = pwm;
layerIndex++;
progress++;
@@ -595,9 +595,9 @@ M106 S0
}
entry = inputFile.GetEntry("Preview.png");
- if (!ReferenceEquals(entry, null))
+ if (entry is not null)
{
- using Stream stream = entry.Open();
+ using var stream = entry.Open();
CvInvoke.Imdecode(stream.ToArray(), ImreadModes.AnyColor, Thumbnails[0]);
stream.Close();
}
@@ -622,36 +622,15 @@ M106 S0
RaisePropertyChanged(nameof(GCodeStr));
}
- public override void SaveAs(string filePath = null, OperationProgress progress = null)
+ protected override void PartialSaveInternally(OperationProgress progress)
{
- if (RequireFullEncode)
- {
- if (!string.IsNullOrEmpty(filePath))
- {
- FileFullPath = filePath;
- }
- Encode(FileFullPath, progress);
- return;
- }
-
- if (!string.IsNullOrEmpty(filePath))
- {
- File.Copy(FileFullPath, filePath, true);
- FileFullPath = filePath;
-
- }
-
- using (var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update))
- {
- outputFile.PutFileContent("ResinMetadata", JsonConvert.SerializeObject(ResinMetadataSettings, Formatting.Indented), ZipArchiveMode.Update);
- outputFile.PutFileContent("UserSettingsData", JsonConvert.SerializeObject(UserSettings, Formatting.Indented), ZipArchiveMode.Update);
- outputFile.PutFileContent("ZCodeMetadata", JsonConvert.SerializeObject(ZCodeMetadataSettings, Formatting.Indented), ZipArchiveMode.Update);
- outputFile.PutFileContent("ResinGCodeData", GCodeStr, ZipArchiveMode.Update);
- }
-
- //Decode(FileFullPath, progress);
+ using var outputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update);
+ outputFile.PutFileContent("ResinMetadata", JsonConvert.SerializeObject(ResinMetadataSettings, Formatting.Indented), ZipArchiveMode.Update);
+ outputFile.PutFileContent("UserSettingsData", JsonConvert.SerializeObject(UserSettings, Formatting.Indented), ZipArchiveMode.Update);
+ outputFile.PutFileContent("ZCodeMetadata", JsonConvert.SerializeObject(ZCodeMetadataSettings, Formatting.Indented), ZipArchiveMode.Update);
+ outputFile.PutFileContent("ResinGCodeData", GCodeStr, ZipArchiveMode.Update);
}
- #endregion
+ #endregion
}
}
diff --git a/UVtools.Core/Layers/Layer.cs b/UVtools.Core/Layers/Layer.cs
index 7f425c3..055d888 100644
--- a/UVtools.Core/Layers/Layer.cs
+++ b/UVtools.Core/Layers/Layer.cs
@@ -479,6 +479,7 @@ namespace UVtools.Core.Layers
{
get
{
+ if (!HaveImage) return null;
Mat mat = new();
CvInvoke.Imdecode(_compressedBytes, ImreadModes.Grayscale, mat);
return mat;
@@ -604,6 +605,8 @@ namespace UVtools.Core.Layers
_lightPWM = SlicerFile.GetBottomOrNormalValue(this, SlicerFile.BottomLightPWM, SlicerFile.LightPWM);
}
+ public Layer(uint index, FileFormat slicerFile) : this(index, slicerFile.LayerManager) {}
+
public Layer(uint index, byte[] compressedBytes, LayerManager parentLayerManager) : this(index, parentLayerManager)
{
CompressedBytes = compressedBytes;
@@ -625,8 +628,8 @@ namespace UVtools.Core.Layers
public Layer(uint index, Mat layerMat, FileFormat slicerFile) : this(index, layerMat, slicerFile.LayerManager) { }
- public Layer(uint index, Stream stream, LayerManager parentLayerManager) : this(index, stream.ToArray(), parentLayerManager) { }
- public Layer(uint index, Stream stream, FileFormat slicerFile) : this(index, stream.ToArray(), slicerFile.LayerManager) { }
+ public Layer(uint index, Stream stream, LayerManager parentLayerManager) : this(index, stream?.ToArray(), parentLayerManager) { }
+ public Layer(uint index, Stream stream, FileFormat slicerFile) : this(index, stream?.ToArray(), slicerFile.LayerManager) { }
#endregion
#region Equatables
@@ -671,7 +674,7 @@ namespace UVtools.Core.Layers
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
if (_index != other._index) return false;
- if (_compressedBytes.Length != other._compressedBytes.Length) return false;
+ if (_compressedBytes?.Length != other._compressedBytes?.Length) return false;
return _compressedBytes.AsSpan().SequenceEqual(other._compressedBytes.AsSpan());
//return Equals(_compressedBytes, other._compressedBytes);
}
@@ -1112,7 +1115,7 @@ namespace UVtools.Core.Layers
//layer.CompressedBytes = _compressedBytes.ToArray();
//Debug.WriteLine(ReferenceEquals(_compressedBytes, layer.CompressedBytes));
//return layer;
- return new (_index, CompressedBytes.ToArray(), ParentLayerManager)
+ return new (_index, CompressedBytes?.ToArray(), ParentLayerManager)
{
_positionZ = _positionZ,
_lightOffDelay = _lightOffDelay,
diff --git a/UVtools.Core/Layers/LayerManager.cs b/UVtools.Core/Layers/LayerManager.cs
index 4e551ff..2b1a1bc 100644
--- a/UVtools.Core/Layers/LayerManager.cs
+++ b/UVtools.Core/Layers/LayerManager.cs
@@ -176,9 +176,14 @@ namespace UVtools.Core
}
}
- public void Init(uint layerCount)
+ public void Init(uint layerCount, bool initializeLayers = false)
{
_layers = new Layer[layerCount];
+ if (!initializeLayers) return;
+ for (uint layerIndex = 0; layerIndex < layerCount; layerIndex++)
+ {
+ this[layerIndex] = new Layer(layerIndex, this);
+ }
}
public void Init(Layer[] layers)
@@ -672,9 +677,10 @@ namespace UVtools.Core
public Rectangle GetBoundingRectangle(OperationProgress progress = null)
{
- if (!_boundingRectangle.IsEmpty || LayerCount == 0 || this[0] is null) return _boundingRectangle;
+ var firstLayer = FirstLayer;
+ if (!_boundingRectangle.IsEmpty || LayerCount == 0 || firstLayer is null || !firstLayer.HaveImage) return _boundingRectangle;
progress ??= new OperationProgress(OperationProgress.StatusOptimizingBounds, LayerCount - 1);
- _boundingRectangle = this[0].BoundingRectangle;
+ _boundingRectangle = firstLayer.BoundingRectangle;
if (_boundingRectangle.IsEmpty) // Safe checking
{
progress.Reset(OperationProgress.StatusOptimizingBounds, LayerCount-1);
@@ -687,9 +693,9 @@ namespace UVtools.Core
if (progress is null) return;
progress.LockAndIncrement();
});
- _boundingRectangle = this[0].BoundingRectangle;
+ _boundingRectangle = firstLayer.BoundingRectangle;
- if (progress is not null && progress.Token.IsCancellationRequested)
+ if (progress.Token.IsCancellationRequested)
{
_boundingRectangle = Rectangle.Empty;
progress.Token.ThrowIfCancellationRequested();
diff --git a/UVtools.Core/Managers/ClipboardManager.cs b/UVtools.Core/Managers/ClipboardManager.cs
index 07a363f..7c5de4b 100644
--- a/UVtools.Core/Managers/ClipboardManager.cs
+++ b/UVtools.Core/Managers/ClipboardManager.cs
@@ -275,11 +275,11 @@ namespace UVtools.Core.Managers
/// <param name="slicerFile"></param>
public void Init(FileFormat slicerFile)
{
+ Clear();
+ SlicerFile = slicerFile;
+ if (slicerFile is null || slicerFile.DecodeType == FileFormat.FileDecodeType.Partial) return;
SuppressRestoreWork(() =>
{
- Clear();
- SlicerFile = slicerFile;
- if (slicerFile is null) return;
var clip = new ClipboardItem(SlicerFile, "Original layers", true);
clip.AddRange(SlicerFile.LayerManager.CloneLayers());
Add(clip);
diff --git a/UVtools.Core/Managers/IssueManager.cs b/UVtools.Core/Managers/IssueManager.cs
index da771a0..48079d2 100644
--- a/UVtools.Core/Managers/IssueManager.cs
+++ b/UVtools.Core/Managers/IssueManager.cs
@@ -124,6 +124,8 @@ namespace UVtools.Core.Managers
bool emptyLayersConfig = true,
OperationProgress progress = null)
{
+ if (SlicerFile.DecodeType == FileFormat.FileDecodeType.Partial) return null;
+
islandConfig ??= new IslandDetectionConfiguration();
overhangConfig ??= new OverhangDetectionConfiguration();
resinTrapConfig ??= new ResinTrapDetectionConfiguration();
diff --git a/UVtools.Core/Operations/Operation.cs b/UVtools.Core/Operations/Operation.cs
index f635df7..8bc2db6 100644
--- a/UVtools.Core/Operations/Operation.cs
+++ b/UVtools.Core/Operations/Operation.cs
@@ -7,15 +7,12 @@
*/
using System;
-using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Emgu.CV;
-using Emgu.CV.Cuda;
-using Emgu.CV.Util;
using UVtools.Core.Extensions;
using UVtools.Core.FileFormats;
using UVtools.Core.Layers;
@@ -121,6 +118,11 @@ namespace UVtools.Core.Operations
public virtual bool PassActualLayerIndex => false;
/// <summary>
+ /// Gets if this operation can run in a file open as partial mode
+ /// </summary>
+ public virtual bool CanRunInPartialMode => false;
+
+ /// <summary>
/// Gets if this operation can make use of ROI
/// </summary>
public virtual bool CanROI => true;
@@ -502,6 +504,7 @@ namespace UVtools.Core.Operations
public bool Execute(OperationProgress progress = null)
{
if (_slicerFile is null) throw new InvalidOperationException($"{Title} can't execute due the lacking of a file parent.");
+ if (_slicerFile.DecodeType == FileFormat.FileDecodeType.Partial && !CanRunInPartialMode) throw new InvalidOperationException($"The file was open in partial mode and the tool \"{Title}\" is unable to run in this mode.\nPlease reload the file in full mode in order to use this tool.");
if (!IsValidated)
{
var msg = Validate();
diff --git a/UVtools.Core/Operations/OperationCalculator.cs b/UVtools.Core/Operations/OperationCalculator.cs
index 9f50071..779272e 100644
--- a/UVtools.Core/Operations/OperationCalculator.cs
+++ b/UVtools.Core/Operations/OperationCalculator.cs
@@ -18,6 +18,9 @@ namespace UVtools.Core.Operations
public class OperationCalculator : Operation
{
#region Overrides
+
+ public override bool CanRunInPartialMode => true;
+
public override string Title => "Calculator";
public override string Description => null;
diff --git a/UVtools.Core/Operations/OperationDynamicLifts.cs b/UVtools.Core/Operations/OperationDynamicLifts.cs
index d772222..53d4f6d 100644
--- a/UVtools.Core/Operations/OperationDynamicLifts.cs
+++ b/UVtools.Core/Operations/OperationDynamicLifts.cs
@@ -65,6 +65,8 @@ namespace UVtools.Core.Operations
#region Overrides
+ public override bool CanRunInPartialMode => true;
+
public override Enumerations.LayerRangeSelection StartLayerRangeSelection => Enumerations.LayerRangeSelection.Normal;
public override string Title => "Dynamic lifts";
diff --git a/UVtools.Core/Operations/OperationEditParameters.cs b/UVtools.Core/Operations/OperationEditParameters.cs
index de8d37f..7e6e8f3 100644
--- a/UVtools.Core/Operations/OperationEditParameters.cs
+++ b/UVtools.Core/Operations/OperationEditParameters.cs
@@ -9,10 +9,8 @@
using System;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
using System.Xml.Serialization;
using UVtools.Core.FileFormats;
-using UVtools.Core.Objects;
namespace UVtools.Core.Operations
{
@@ -29,6 +27,8 @@ namespace UVtools.Core.Operations
#endregion
#region Overrides
+
+ public override bool CanRunInPartialMode => true;
public override Enumerations.LayerRangeSelection StartLayerRangeSelection => Enumerations.LayerRangeSelection.None;
public override bool CanROI => false;
diff --git a/UVtools.Core/Operations/OperationFadeExposureTime.cs b/UVtools.Core/Operations/OperationFadeExposureTime.cs
index 6a9ffd9..328ea66 100644
--- a/UVtools.Core/Operations/OperationFadeExposureTime.cs
+++ b/UVtools.Core/Operations/OperationFadeExposureTime.cs
@@ -25,6 +25,7 @@ namespace UVtools.Core.Operations
#endregion
#region Overrides
+ public override bool CanRunInPartialMode => true;
public override Enumerations.LayerRangeSelection StartLayerRangeSelection => Enumerations.LayerRangeSelection.Normal;
public override bool LayerIndexEndEnabled => false;
public override string Title => "Fade exposure time";
diff --git a/UVtools.Core/Operations/OperationIPrintedThisFile.cs b/UVtools.Core/Operations/OperationIPrintedThisFile.cs
index 36aec90..c36faeb 100644
--- a/UVtools.Core/Operations/OperationIPrintedThisFile.cs
+++ b/UVtools.Core/Operations/OperationIPrintedThisFile.cs
@@ -27,6 +27,8 @@ namespace UVtools.Core.Operations
#region Overrides
+ public override bool CanRunInPartialMode => true;
+
public override Enumerations.LayerRangeSelection StartLayerRangeSelection => Enumerations.LayerRangeSelection.None;
public override bool CanROI => false;
diff --git a/UVtools.Core/Operations/OperationRaiseOnPrintFinish.cs b/UVtools.Core/Operations/OperationRaiseOnPrintFinish.cs
index 7b378ad..387b43c 100644
--- a/UVtools.Core/Operations/OperationRaiseOnPrintFinish.cs
+++ b/UVtools.Core/Operations/OperationRaiseOnPrintFinish.cs
@@ -29,6 +29,9 @@ namespace UVtools.Core.Operations
#endregion
#region Overrides
+
+ public override bool CanRunInPartialMode => true;
+
public override Enumerations.LayerRangeSelection StartLayerRangeSelection => Enumerations.LayerRangeSelection.None;
public override string Title => "Raise platform on print finish";
diff --git a/UVtools.Core/Operations/OperationScripting.cs b/UVtools.Core/Operations/OperationScripting.cs
index a54326c..4ca04a1 100644
--- a/UVtools.Core/Operations/OperationScripting.cs
+++ b/UVtools.Core/Operations/OperationScripting.cs
@@ -30,6 +30,8 @@ namespace UVtools.Core.Operations
#region Overrides
+ public override bool CanRunInPartialMode => true;
+
public override bool CanHaveProfiles => false;
public override string Title => "Scripting";
diff --git a/UVtools.Core/Scripting/ScriptFileDialogInput.cs b/UVtools.Core/Scripting/ScriptFileDialogInput.cs
new file mode 100644
index 0000000..a8b4aef
--- /dev/null
+++ b/UVtools.Core/Scripting/ScriptFileDialogInput.cs
@@ -0,0 +1,41 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+using System.Collections.Generic;
+
+namespace UVtools.Core.Scripting
+{
+ public abstract class ScriptFileDialogInput : ScriptBaseInput<string>
+ {
+ public class ScriptFileDialogFilter
+ {
+ public string Name { get; set; }
+ public List<string> Extensions { get; set; } = new();
+ }
+
+ /// <summary>
+ /// Gets or sets the title for the dialog
+ /// </summary>
+ public string Title { get; set; }
+
+ /// <summary>
+ /// Gets or sets the default directory to open the dialog in
+ /// </summary>
+ public string Directory { get; set; }
+
+ /// <summary>
+ /// Gets or sets the initial filename to be on the dialog
+ /// </summary>
+ public string InitialFilename { get; set; }
+
+ /// <summary>
+ /// Gets or sets the file filters on the dropdown list
+ /// </summary>
+ public List<ScriptFileDialogFilter> Filters { get; set; }
+ }
+}
diff --git a/UVtools.Core/Scripting/ScriptOpenFileDialogInput.cs b/UVtools.Core/Scripting/ScriptOpenFileDialogInput.cs
new file mode 100644
index 0000000..209b0c5
--- /dev/null
+++ b/UVtools.Core/Scripting/ScriptOpenFileDialogInput.cs
@@ -0,0 +1,23 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+namespace UVtools.Core.Scripting
+{
+ public class ScriptOpenFileDialogInput : ScriptFileDialogInput
+ {
+ /// <summary>
+ /// Gets or sets if allow multiple file selection
+ /// </summary>
+ public bool AllowMultiple { get; set; }
+
+ /// <summary>
+ /// Gets or sets the selected files
+ /// </summary>
+ public string[] Files {get; set; }
+ }
+}
diff --git a/UVtools.Core/Scripting/ScriptOpenFolderDialogInput.cs b/UVtools.Core/Scripting/ScriptOpenFolderDialogInput.cs
new file mode 100644
index 0000000..5baa2f1
--- /dev/null
+++ b/UVtools.Core/Scripting/ScriptOpenFolderDialogInput.cs
@@ -0,0 +1,18 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+namespace UVtools.Core.Scripting
+{
+ public class ScriptOpenFolderDialogInput : ScriptBaseInput<string>
+ {
+ /// <summary>
+ /// Gets the title for the dialog
+ /// </summary>
+ public string Title { get; set; }
+ }
+}
diff --git a/UVtools.Core/Scripting/ScriptSaveFileDialogInput.cs b/UVtools.Core/Scripting/ScriptSaveFileDialogInput.cs
new file mode 100644
index 0000000..e2d64c8
--- /dev/null
+++ b/UVtools.Core/Scripting/ScriptSaveFileDialogInput.cs
@@ -0,0 +1,18 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+namespace UVtools.Core.Scripting
+{
+ public class ScriptSaveFileDialogInput : ScriptFileDialogInput
+ {
+ /// <summary>
+ /// Gets or sets the default extension for the dialog
+ /// </summary>
+ public string DefaultExtension { get; set; }
+ }
+}
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index dc66e2b..3d59718 100644
--- a/UVtools.Core/UVtools.Core.csproj
+++ b/UVtools.Core/UVtools.Core.csproj
@@ -10,7 +10,7 @@
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
- <Version>2.24.4</Version>
+ <Version>2.25.0</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.ScriptSample/ScriptCloneSettings.cs b/UVtools.ScriptSample/ScriptCloneSettings.cs
new file mode 100644
index 0000000..70a7704
--- /dev/null
+++ b/UVtools.ScriptSample/ScriptCloneSettings.cs
@@ -0,0 +1,427 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+using System;
+using UVtools.Core.Scripting;
+using System.IO;
+using System.Collections.Generic;
+using UVtools.Core.FileFormats;
+using System.Threading.Tasks;
+using UVtools.Core;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.Linq;
+
+namespace UVtools.ScriptSample
+{
+ /// <summary>
+ /// Performs a black inset around objects
+ /// </summary>
+ public class ScriptCloneSettings : ScriptGlobals
+ {
+ ScriptCheckBoxInput Recursive = new()
+ {
+ Label = "Recursive",
+ ToolTip = "If unchecked, only files in the same folder are modified; if checked, files in all sub-folders are modified too",
+ Value = true
+ };
+
+ ScriptCheckBoxInput Report = new()
+ {
+ Label = "Generate report file",
+ ToolTip = "Optionally generate a report file in the same directory as the open file",
+ Value = true
+ };
+
+ ScriptCheckBoxInput OpenReport = new()
+ {
+ Label = "Open report file",
+ ToolTip = "Optionally open the result file when completed",
+ Value = true
+ };
+
+ ScriptOpenFolderDialogInput FolderPath = new()
+ {
+ Label = "Folder path",
+ ToolTip = "The folder path to process",
+ };
+
+ private enum ResultStatus
+ {
+ Exception,
+ UnknownFileType,
+ DifferentMachineTypes,
+ Success,
+ Unchanged,
+ }
+
+ /// <summary>
+ /// Set configurations here, this function trigger just after load a script
+ /// </summary>
+ public void ScriptInit()
+ {
+ Script.Name = "Clone Settings";
+ Script.Description = "Copies the print settings from the current file to all files in the same directory and, optionally, recursively below it";
+ Script.Author = "Gina Venolia";
+ Script.Version = new Version(0, 2);
+ Script.UserInputs.Add(Recursive);
+ Script.UserInputs.Add(Report);
+ Script.UserInputs.Add(OpenReport);
+ Script.UserInputs.Add(FolderPath);
+ FolderPath.Value = SlicerFile.FileDirectoryPath;
+ }
+
+ /// <summary>
+ /// Validate user inputs here, this function trigger when user click on execute
+ /// </summary>
+ /// <returns>A error message, empty or null if validation passes.</returns>
+ public string ScriptValidate()
+ {
+ return null;
+ }
+
+ /// <summary>
+ /// Execute the script, this function trigger when when user click on execute and validation passes
+ /// </summary>
+ /// <returns>True if executes successfully to the end, otherwise false.</returns>
+ public bool ScriptExecute()
+ {
+ Progress.CanCancel = true;
+
+ // Gather the list of directories to operate on
+ Progress.Reset("Processing files...");
+
+ var directoryPaths = new List<string>();
+ directoryPaths.Add(Path.GetDirectoryName(SlicerFile.FileFullPath));
+
+ if (Recursive.Value)
+ {
+ for (var i = 0; i < directoryPaths.Count; i++)
+ {
+ directoryPaths.AddRange(Directory.EnumerateDirectories(directoryPaths[i]));
+ }
+ }
+
+ // Gather the list of files to operate on
+ var filePaths = new List<string>();
+ foreach (var directoryPath in directoryPaths)
+ {
+ filePaths.AddRange(Directory.EnumerateFiles(directoryPath));
+ }
+
+ // Except for the file we started with
+ var normalizedFilePath = Path.GetFullPath(SlicerFile.FileFullPath);
+ filePaths.RemoveAll(x => Path.GetFullPath(x) == normalizedFilePath);
+
+ // Process the files
+ Progress.Reset("Processing files...", (uint)filePaths.Count, 0);
+
+ var results = new List<Tuple<ResultStatus, string, List<string>>>();
+ foreach (var filePath in filePaths)
+ {
+ if (Progress.Token.IsCancellationRequested) return false;
+
+ Tuple<ResultStatus, string, List<string>> result;
+ try
+ {
+ result = ProcessFile(filePath);
+ }
+ catch (Exception ex)
+ {
+ var deets = new List<string>();
+ deets.Add(ex.GetType().Name);
+ deets.Add(ex.Message);
+ result = new Tuple<ResultStatus, string, List<string>>(ResultStatus.Exception, filePath, deets);
+ }
+
+ results.Add(result);
+
+ Progress++;
+ }
+
+ // Generate the report
+ if (Report.Value)
+ {
+ var reportDirectory = Path.GetDirectoryName(SlicerFile.FileFullPath);
+ var reportFilePath = Path.Combine(reportDirectory, "CloneSettingsReport.txt");
+ using (var writer = new StreamWriter(reportFilePath))
+ {
+ writer.WriteLine(Script.Name + " " + Script.Version.ToString() + " by " + Script.Author);
+ writer.WriteLine("Source file: " + SlicerFile.FileFullPath);
+ writer.WriteLine(DateTime.Now.ToLongDateString() + ", " + DateTime.Now.ToLongTimeString());
+ writer.WriteLine("Recursive: " + Recursive.Value.ToString());
+ writer.WriteLine("Directories: " + directoryPaths.Count);
+ writer.WriteLine("Files: " + filePaths.Count);
+ writer.WriteLine();
+
+ foreach (var statusGroup in results.GroupBy(x => x.Item1))
+ {
+ writer.WriteLine(statusGroup.Key.ToString());
+ foreach (var result in statusGroup.OrderBy(x => x.Item2))
+ {
+ writer.WriteLine("\t" + result.Item2);
+ if (result.Item3 is not null)
+ {
+ foreach (var detail in result.Item3)
+ {
+ writer.WriteLine("\t\t" + detail);
+ }
+ }
+ }
+ }
+ }
+
+ if (OpenReport.Value)
+ {
+ var startInfo = new ProcessStartInfo(reportFilePath)
+ {
+ UseShellExecute = true
+ };
+ Process.Start(startInfo);
+ }
+ }
+
+ // return true if not cancelled by user
+ return true;
+ }
+
+ private Tuple<ResultStatus, string, List<string>> ProcessFile(string filePath)
+ {
+ // Determine the type of file
+ var file = FileFormat.FindByExtensionOrFilePath(filePath, true);
+ if (file is null)
+ {
+ return new Tuple<ResultStatus, string, List<string>>(ResultStatus.UnknownFileType, filePath, null);
+ }
+
+ // Load the file
+ file.Decode(filePath);
+ if (string.Compare(file.MachineName, SlicerFile.MachineName, true) != 0)
+ {
+ var deets = new List<string>();
+ deets.Add("Source machine type: " + SlicerFile.MachineName);
+ deets.Add("Destination machine type: " + file.MachineName);
+ return new Tuple<ResultStatus, string, List<string>>(ResultStatus.DifferentMachineTypes, filePath, deets);
+ }
+
+ // TODO: Validate that some parameters are the same in both files?
+
+ // Change the parameters
+ var changed = false;
+ var details = new List<string>();
+
+ if (file.CanUseBottomLayerCount && file.BottomLayerCount != SlicerFile.BottomLayerCount)
+ {
+ details.Add($"Bottom Layer Count: {file.BottomLayerCount} to {SlicerFile.BottomLayerCount}");
+ file.BottomLayerCount = SlicerFile.BottomLayerCount;
+ changed = true;
+ }
+
+ if (file.CanUseBottomLightOffDelay && file.BottomLightOffDelay != SlicerFile.BottomLightOffDelay)
+ {
+ details.Add($"Bottom Light Off Delay: {file.BottomLightOffDelay} to {SlicerFile.BottomLightOffDelay}");
+ file.BottomLightOffDelay = SlicerFile.BottomLightOffDelay;
+ changed = true;
+ }
+
+ if (file.CanUseLightOffDelay && file.LightOffDelay != SlicerFile.LightOffDelay)
+ {
+ details.Add($"Light Off Delay: {file.LightOffDelay} to {SlicerFile.LightOffDelay}");
+ file.LightOffDelay = SlicerFile.LightOffDelay;
+ changed = true;
+ }
+
+ if (file.CanUseBottomWaitTimeBeforeCure && file.BottomWaitTimeBeforeCure != SlicerFile.BottomWaitTimeBeforeCure)
+ {
+ details.Add($"Bottom Wait Time Before Cure: {file.BottomWaitTimeBeforeCure} to {SlicerFile.BottomWaitTimeBeforeCure}");
+ file.BottomWaitTimeBeforeCure = SlicerFile.BottomWaitTimeBeforeCure;
+ changed = true;
+ }
+
+ if (file.CanUseWaitTimeBeforeCure && file.WaitTimeBeforeCure != SlicerFile.WaitTimeBeforeCure)
+ {
+ details.Add($"Wait Time Before Cure: {file.WaitTimeBeforeCure} to {SlicerFile.WaitTimeBeforeCure}");
+ file.WaitTimeBeforeCure = SlicerFile.WaitTimeBeforeCure;
+ changed = true;
+ }
+
+ if (file.CanUseBottomExposureTime && file.BottomExposureTime != SlicerFile.BottomExposureTime)
+ {
+ details.Add($"Bottom Exposure Time: {file.BottomExposureTime} to {SlicerFile.BottomExposureTime}");
+ file.BottomExposureTime = SlicerFile.BottomExposureTime;
+ changed = true;
+ }
+
+ if (file.CanUseExposureTime && file.ExposureTime != SlicerFile.ExposureTime)
+ {
+ details.Add($"Exposure Time: {file.ExposureTime} to {SlicerFile.ExposureTime}");
+ file.ExposureTime = SlicerFile.ExposureTime;
+ changed = true;
+ }
+
+ if (file.CanUseBottomWaitTimeAfterCure && file.BottomWaitTimeAfterCure != SlicerFile.BottomWaitTimeAfterCure)
+ {
+ details.Add($"Bottom Wait Time After Cure: {file.BottomWaitTimeAfterCure} to {SlicerFile.BottomWaitTimeAfterCure}");
+ file.BottomWaitTimeAfterCure = SlicerFile.BottomWaitTimeAfterCure;
+ changed = true;
+ }
+
+ if (file.CanUseWaitTimeAfterCure && file.WaitTimeAfterCure != SlicerFile.WaitTimeAfterCure)
+ {
+ details.Add($"Wait Time After Cure: {file.WaitTimeAfterCure} to {SlicerFile.WaitTimeAfterCure}");
+ file.WaitTimeAfterCure = SlicerFile.WaitTimeAfterCure;
+ changed = true;
+ }
+
+ if (file.CanUseBottomLiftHeight && file.BottomLiftHeight != SlicerFile.BottomLiftHeight)
+ {
+ details.Add($"Bottom Lift Height: {file.BottomLiftHeight} to {SlicerFile.BottomLiftHeight}");
+ file.BottomLiftHeight = SlicerFile.BottomLiftHeight;
+ changed = true;
+ }
+
+ if (file.CanUseBottomLiftSpeed && file.BottomLiftSpeed != SlicerFile.BottomLiftSpeed)
+ {
+ details.Add($"Bottom Lift Speed: {file.BottomLiftSpeed} to {SlicerFile.BottomLiftSpeed}");
+ file.BottomLiftSpeed = SlicerFile.BottomLiftSpeed;
+ changed = true;
+ }
+
+ if (file.CanUseLiftHeight && file.LiftHeight != SlicerFile.LiftHeight)
+ {
+ details.Add($"Lift Height: {file.LiftHeight} to {SlicerFile.LiftHeight}");
+ file.LiftHeight = SlicerFile.LiftHeight;
+ changed = true;
+ }
+
+ if (file.CanUseLiftSpeed && file.LiftSpeed != SlicerFile.LiftSpeed)
+ {
+ details.Add($"Lift Speed: {file.LiftSpeed} to {SlicerFile.LiftSpeed}");
+ file.LiftSpeed = SlicerFile.LiftSpeed;
+ changed = true;
+ }
+
+ if (file.CanUseBottomLiftHeight2 && file.BottomLiftHeight2 != SlicerFile.BottomLiftHeight2)
+ {
+ details.Add($"Bottom Lift Height 2: {file.BottomLiftHeight2} to {SlicerFile.BottomLiftHeight2}");
+ file.BottomLiftHeight2 = SlicerFile.BottomLiftHeight2;
+ changed = true;
+ }
+
+ if (file.CanUseBottomLiftSpeed2 && file.BottomLiftSpeed2 != SlicerFile.BottomLiftSpeed2)
+ {
+ details.Add($"Bottom Lift Speed2: {file.BottomLiftSpeed2} to {SlicerFile.BottomLiftSpeed2}");
+ file.BottomLiftSpeed2 = SlicerFile.BottomLiftSpeed2;
+ changed = true;
+ }
+
+ if (file.CanUseLiftHeight2 && file.LiftHeight2 != SlicerFile.LiftHeight2)
+ {
+ details.Add($"Lift Height 2: {file.LiftHeight2} to {SlicerFile.LiftHeight2}");
+ file.LiftHeight2 = SlicerFile.LiftHeight2;
+ changed = true;
+ }
+
+ if (file.CanUseLiftSpeed2 && file.LiftSpeed2 != SlicerFile.LiftSpeed2)
+ {
+ details.Add($"Lift Speed 2: {file.LiftSpeed2} to {SlicerFile.LiftSpeed2}");
+ file.LiftSpeed2 = SlicerFile.LiftSpeed2;
+ changed = true;
+ }
+
+ if (file.CanUseBottomWaitTimeAfterLift && file.BottomWaitTimeAfterLift != SlicerFile.BottomWaitTimeAfterLift)
+ {
+ details.Add($"Bottom Wait Time After Lift: {file.BottomWaitTimeAfterLift} to {SlicerFile.BottomWaitTimeAfterLift}");
+ file.BottomWaitTimeAfterLift = SlicerFile.BottomWaitTimeAfterLift;
+ changed = true;
+ }
+
+ if (file.CanUseWaitTimeAfterLift && file.WaitTimeAfterLift != SlicerFile.WaitTimeAfterLift)
+ {
+ details.Add($"Wait Time After Lift: {file.WaitTimeAfterLift} to {SlicerFile.WaitTimeAfterLift}");
+ file.WaitTimeAfterLift = SlicerFile.WaitTimeAfterLift;
+ changed = true;
+ }
+
+ if (file.CanUseBottomRetractSpeed && file.BottomRetractSpeed != SlicerFile.BottomRetractSpeed)
+ {
+ details.Add($"Bottom Retract Speed: {file.BottomRetractSpeed} to {SlicerFile.BottomRetractSpeed}");
+ file.BottomRetractSpeed = SlicerFile.BottomRetractSpeed;
+ changed = true;
+ }
+
+ if (file.CanUseRetractSpeed && file.RetractSpeed != SlicerFile.RetractSpeed)
+ {
+ details.Add($"Retract Speed: {file.RetractSpeed} to {SlicerFile.RetractSpeed}");
+ file.RetractSpeed = SlicerFile.RetractSpeed;
+ changed = true;
+ }
+
+ if (file.CanUseBottomRetractHeight2 && file.BottomRetractHeight2 != SlicerFile.BottomRetractHeight2)
+ {
+ details.Add($"Bottom Retract Height 2: {file.BottomRetractHeight2} to {SlicerFile.BottomRetractHeight2}");
+ file.BottomRetractHeight2 = SlicerFile.BottomRetractHeight2;
+ changed = true;
+ }
+
+ if (file.CanUseBottomRetractSpeed2 && file.BottomRetractSpeed2 != SlicerFile.BottomRetractSpeed2)
+ {
+ details.Add($"Bottom Retract Speed2: {file.BottomRetractSpeed2} to {SlicerFile.BottomRetractSpeed2}");
+ file.BottomRetractSpeed2 = SlicerFile.BottomRetractSpeed2;
+ changed = true;
+ }
+
+ if (file.CanUseRetractHeight2 && file.RetractHeight2 != SlicerFile.RetractHeight2)
+ {
+ details.Add($"Retract Height 2: {file.RetractHeight2} to {SlicerFile.RetractHeight2}");
+ file.RetractHeight2 = SlicerFile.RetractHeight2;
+ changed = true;
+ }
+
+ if (file.CanUseRetractSpeed2 && file.RetractSpeed2 != SlicerFile.RetractSpeed2)
+ {
+ details.Add($"Retract Speed 2: {file.RetractSpeed2} to {SlicerFile.RetractSpeed2}");
+ file.RetractSpeed2 = SlicerFile.RetractSpeed2;
+ changed = true;
+ }
+
+ if (file.CanUseBottomLightPWM && file.BottomLightPWM != SlicerFile.BottomLightPWM)
+ {
+ details.Add($"Bottom Light PWM: {file.BottomLightPWM} to {SlicerFile.BottomLightPWM}");
+ file.BottomLightPWM = SlicerFile.BottomLightPWM;
+ changed = true;
+ }
+
+ if (file.CanUseLightPWM && file.LightPWM != SlicerFile.LightPWM)
+ {
+ details.Add($"Light PWM: {file.LightPWM} to {SlicerFile.LightPWM}");
+ file.LightPWM = SlicerFile.LightPWM;
+ changed = true;
+ }
+
+ // if (file.CanUseXXX && file.XXX != SlicerFile.XXX)
+ // {
+ // details.Add($"XXX: {file.XXX} to {SlicerFile.XXX}");
+ // file.XXX = SlicerFile.XXX;
+ // changed = true;
+ // }
+
+ // Bail out if not changed
+ if (!changed)
+ {
+ return new Tuple<ResultStatus, string, List<string>>(ResultStatus.Unchanged, filePath, null);
+ }
+
+ // Save the changed file
+ file.Save();
+
+ return new Tuple<ResultStatus, string, List<string>>(ResultStatus.Success, filePath, details);
+ }
+
+ }
+}
diff --git a/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs
index a786ac5..720d020 100644
--- a/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs
+++ b/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using Avalonia;
using Avalonia.Controls;
@@ -39,7 +40,7 @@ namespace UVtools.WPF.Controls.Tools
{
case ToolWindow.Callbacks.Init:
case ToolWindow.Callbacks.Loaded:
- ParentWindow.ButtonOkEnabled = Operation.CanExecute;
+ if(ParentWindow is not null) ParentWindow.ButtonOkEnabled = Operation.CanExecute;
ReloadGUI();
Operation.PropertyChanged += (sender, e) =>
{
@@ -183,309 +184,309 @@ namespace UVtools.WPF.Controls.Tools
switch (variable)
{
case ScriptNumericalInput<sbyte> numSBYTE:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numSBYTE.Minimum,
- Maximum = numSBYTE.Maximum,
- Value = numSBYTE.Value,
- Increment = numSBYTE.Increment,
- MinWidth = 150
- };
+ Minimum = numSBYTE.Minimum,
+ Maximum = numSBYTE.Maximum,
+ Value = numSBYTE.Value,
+ Increment = numSBYTE.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numSBYTE.Value = (sbyte)value;
- control.Value = numSBYTE.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numSBYTE.Value = (sbyte)value;
+ control.Value = numSBYTE.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<byte> numBYTE:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numBYTE.Minimum,
- Maximum = numBYTE.Maximum,
- Value = numBYTE.Value,
- Increment = numBYTE.Increment,
- MinWidth = 150
- };
+ Minimum = numBYTE.Minimum,
+ Maximum = numBYTE.Maximum,
+ Value = numBYTE.Value,
+ Increment = numBYTE.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numBYTE.Value = (byte)value;
- control.Value = numBYTE.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numBYTE.Value = (byte)value;
+ control.Value = numBYTE.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<short> numSHORT:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numSHORT.Minimum,
- Maximum = numSHORT.Maximum,
- Value = numSHORT.Value,
- Increment = numSHORT.Increment,
- MinWidth = 150
- };
+ Minimum = numSHORT.Minimum,
+ Maximum = numSHORT.Maximum,
+ Value = numSHORT.Value,
+ Increment = numSHORT.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numSHORT.Value = (short)value;
- control.Value = numSHORT.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numSHORT.Value = (short)value;
+ control.Value = numSHORT.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<ushort> numUSHORT:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numUSHORT.Minimum,
- Maximum = numUSHORT.Maximum,
- Value = numUSHORT.Value,
- Increment = numUSHORT.Increment,
- MinWidth = 150
- };
+ Minimum = numUSHORT.Minimum,
+ Maximum = numUSHORT.Maximum,
+ Value = numUSHORT.Value,
+ Increment = numUSHORT.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numUSHORT.Value = (ushort)value;
- control.Value = numUSHORT.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numUSHORT.Value = (ushort)value;
+ control.Value = numUSHORT.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<int> numINT:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numINT.Minimum,
- Maximum = numINT.Maximum,
- Value = numINT.Value,
- Increment = numINT.Increment,
- MinWidth = 150
- };
+ Minimum = numINT.Minimum,
+ Maximum = numINT.Maximum,
+ Value = numINT.Value,
+ Increment = numINT.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numINT.Value = (int)value;
- control.Value = numINT.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numINT.Value = (int)value;
+ control.Value = numINT.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<uint> numUINT:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numUINT.Minimum,
- Maximum = numUINT.Maximum,
- Value = numUINT.Value,
- Increment = numUINT.Increment,
- MinWidth = 150
- };
+ Minimum = numUINT.Minimum,
+ Maximum = numUINT.Maximum,
+ Value = numUINT.Value,
+ Increment = numUINT.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numUINT.Value = (uint)value;
- control.Value = numUINT.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numUINT.Value = (uint)value;
+ control.Value = numUINT.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<long> numLONG:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numLONG.Minimum,
- Maximum = numLONG.Maximum,
- Value = numLONG.Value,
- Increment = numLONG.Increment,
- MinWidth = 150
- };
+ Minimum = numLONG.Minimum,
+ Maximum = numLONG.Maximum,
+ Value = numLONG.Value,
+ Increment = numLONG.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numLONG.Value = (long)value;
- control.Value = numLONG.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numLONG.Value = (long)value;
+ control.Value = numLONG.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<ulong> numULONG:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numULONG.Minimum,
- Maximum = numULONG.Maximum,
- Value = numULONG.Value,
- Increment = numULONG.Increment,
- MinWidth = 150
- };
+ Minimum = numULONG.Minimum,
+ Maximum = numULONG.Maximum,
+ Value = numULONG.Value,
+ Increment = numULONG.Increment,
+ MinWidth = 150
+ };
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numULONG.Value = (ulong)value;
- control.Value = numULONG.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numULONG.Value = (ulong)value;
+ control.Value = numULONG.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<float> numFLOAT:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numFLOAT.Minimum,
- Maximum = numFLOAT.Maximum,
- Value = numFLOAT.Value,
- Increment = numFLOAT.Increment,
- MinWidth = 150
- };
+ Minimum = numFLOAT.Minimum,
+ Maximum = numFLOAT.Maximum,
+ Value = numFLOAT.Value,
+ Increment = numFLOAT.Increment,
+ MinWidth = 150
+ };
- if (numFLOAT.DecimalPlates > 0)
- {
- control.FormatString = $"F{numFLOAT.DecimalPlates}";
- }
+ if (numFLOAT.DecimalPlates > 0)
+ {
+ control.FormatString = $"F{numFLOAT.DecimalPlates}";
+ }
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numFLOAT.Value = (float) Math.Round(value, numFLOAT.DecimalPlates);
- control.Value = numFLOAT.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numFLOAT.Value = (float) Math.Round(value, numFLOAT.DecimalPlates);
+ control.Value = numFLOAT.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<double> numDOUBLE:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = numDOUBLE.Minimum,
- Maximum = numDOUBLE.Maximum,
- Value = numDOUBLE.Value,
- Increment = numDOUBLE.Increment,
- MinWidth = 150
- };
+ Minimum = numDOUBLE.Minimum,
+ Maximum = numDOUBLE.Maximum,
+ Value = numDOUBLE.Value,
+ Increment = numDOUBLE.Increment,
+ MinWidth = 150
+ };
- if (numDOUBLE.DecimalPlates > 0)
- {
- control.FormatString = $"F{numDOUBLE.DecimalPlates}";
- }
+ if (numDOUBLE.DecimalPlates > 0)
+ {
+ control.FormatString = $"F{numDOUBLE.DecimalPlates}";
+ }
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numDOUBLE.Value = Math.Round(value, numDOUBLE.DecimalPlates);
- control.Value = numDOUBLE.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numDOUBLE.Value = Math.Round(value, numDOUBLE.DecimalPlates);
+ control.Value = numDOUBLE.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptNumericalInput<decimal> numDECIMAL:
+ {
+ NumericUpDown control = new()
{
- NumericUpDown control = new()
- {
- Minimum = (double)numDECIMAL.Minimum,
- Maximum = (double)numDECIMAL.Maximum,
- Value = (double)numDECIMAL.Value,
- Increment = (double)numDECIMAL.Increment,
- MinWidth = 150
- };
+ Minimum = (double)numDECIMAL.Minimum,
+ Maximum = (double)numDECIMAL.Maximum,
+ Value = (double)numDECIMAL.Value,
+ Increment = (double)numDECIMAL.Increment,
+ MinWidth = 150
+ };
- if (numDECIMAL.DecimalPlates > 0)
- {
- control.FormatString = $"F{numDECIMAL.DecimalPlates}";
- }
+ if (numDECIMAL.DecimalPlates > 0)
+ {
+ control.FormatString = $"F{numDECIMAL.DecimalPlates}";
+ }
- var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
- valueProperty.Subscribe(value =>
- {
- numDECIMAL.Value = (decimal)Math.Round(value, numDECIMAL.DecimalPlates);
- control.Value = (double)numDECIMAL.Value;
- });
+ var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
+ valueProperty.Subscribe(value =>
+ {
+ numDECIMAL.Value = (decimal)Math.Round(value, numDECIMAL.DecimalPlates);
+ control.Value = (double)numDECIMAL.Value;
+ });
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
- }
+ continue;
+ }
case ScriptCheckBoxInput inputCheckBox:
+ {
+ var control = new CheckBox
{
- CheckBox control = new()
- {
- Content = variable.Label,
- IsChecked = inputCheckBox.Value
- };
-
- var valueProperty = control.GetObservable(CheckBox.IsCheckedProperty);
- valueProperty.Subscribe(value =>
- {
- if (value != null) inputCheckBox.Value = value.Value;
- });
+ Content = variable.Label,
+ IsChecked = inputCheckBox.Value
+ };
- _scriptVariablesGrid.Children.Add(control);
- Grid.SetRow(control, i * 2);
- Grid.SetColumn(control, 2);
+ var valueProperty = control.GetObservable(CheckBox.IsCheckedProperty);
+ valueProperty.Subscribe(value =>
+ {
+ if (value != null) inputCheckBox.Value = value.Value;
+ });
- if (!string.IsNullOrWhiteSpace(variable.ToolTip))
- {
- ToolTip.SetTip(control, variable.ToolTip);
- }
+ _scriptVariablesGrid.Children.Add(control);
+ Grid.SetRow(control, i * 2);
+ Grid.SetColumn(control, 2);
- continue;
+ if (!string.IsNullOrWhiteSpace(variable.ToolTip))
+ {
+ ToolTip.SetTip(control, variable.ToolTip);
}
+
+ continue;
+ }
case ScriptTextBoxInput inputTextBox:
{
TextBox control = new()
@@ -506,10 +507,169 @@ namespace UVtools.WPF.Controls.Tools
continue;
}
+ case ScriptOpenFolderDialogInput inputOpenFolder:
+ {
+ var panel = new StackPanel
+ {
+ Orientation = Orientation.Horizontal,
+ Spacing = 5
+ };
+
+ var control = new TextBox
+ {
+ IsReadOnly = true,
+ Text = inputOpenFolder.Value,
+ };
+
+ var button = new Button
+ {
+ Content = "Select",
+ };
+
+ button.Click += async (sender, args) =>
+ {
+ var dialog = new OpenFolderDialog
+ {
+ Directory = inputOpenFolder.Value,
+ Title = inputOpenFolder.Title
+ };
+ var result = await dialog.ShowAsync(ParentWindow);
+ if (!string.IsNullOrWhiteSpace(result))
+ {
+ inputOpenFolder.Value = result;
+ control.Text = result;
+ }
+ };
+
+ panel.Children.Add(control);
+ panel.Children.Add(button);
+
+ _scriptVariablesGrid.Children.Add(panel);
+ Grid.SetRow(panel, i * 2);
+ Grid.SetColumn(panel, 2);
+
+ continue;
+ }
+ case ScriptSaveFileDialogInput inputSaveFile:
+ {
+ var panel = new StackPanel
+ {
+ Orientation = Orientation.Horizontal,
+ Spacing = 5
+ };
+
+ var control = new TextBox
+ {
+ IsReadOnly = true,
+ Text = inputSaveFile.Value,
+ };
+
+ var button = new Button
+ {
+ Content = "Select",
+ };
+
+ button.Click += async (sender, args) =>
+ {
+ var dialog = new SaveFileDialog
+ {
+ Directory = inputSaveFile.Value,
+ Title = inputSaveFile.Title,
+ DefaultExtension = inputSaveFile.DefaultExtension,
+ InitialFileName = inputSaveFile.InitialFilename
+ };
+
+ if (inputSaveFile.Filters is not null)
+ {
+ foreach (var filter in inputSaveFile.Filters)
+ {
+ dialog.Filters.Add(new FileDialogFilter
+ {
+ Extensions = filter.Extensions,
+ Name = filter.Name
+ });
+ }
+ }
+
+ var result = await dialog.ShowAsync(ParentWindow);
+ if (!string.IsNullOrWhiteSpace(result))
+ {
+ inputSaveFile.Value = result;
+ control.Text = result;
+ }
+ };
+
+ panel.Children.Add(control);
+ panel.Children.Add(button);
+
+ _scriptVariablesGrid.Children.Add(panel);
+ Grid.SetRow(panel, i * 2);
+ Grid.SetColumn(panel, 2);
+
+ continue;
+ }
+ case ScriptOpenFileDialogInput inputOpenFile:
+ {
+ var panel = new StackPanel
+ {
+ Orientation = Orientation.Horizontal,
+ Spacing = 5
+ };
+
+ var control = new TextBox
+ {
+ IsReadOnly = true,
+ Text = inputOpenFile.Value,
+ AcceptsReturn = true,
+ };
+
+ var button = new Button
+ {
+ Content = "Select",
+ };
+
+ button.Click += async (sender, args) =>
+ {
+ var dialog = new OpenFileDialog
+ {
+ Directory = inputOpenFile.Value,
+ Title = inputOpenFile.Title,
+ AllowMultiple = inputOpenFile.AllowMultiple,
+ InitialFileName = inputOpenFile.InitialFilename
+ };
+
+ if (inputOpenFile.Filters is not null)
+ {
+ foreach (var filter in inputOpenFile.Filters)
+ {
+ dialog.Filters.Add(new FileDialogFilter
+ {
+ Extensions = filter.Extensions,
+ Name = filter.Name
+ });
+ }
+ }
+
+ var result = await dialog.ShowAsync(ParentWindow);
+ if (result is null || result.Length == 0) return;
+ inputOpenFile.Value = result[0];
+ inputOpenFile.Files = result;
+ control.Text = string.Join('\n', result);
+ };
+
+ panel.Children.Add(control);
+ panel.Children.Add(button);
+
+ _scriptVariablesGrid.Children.Add(panel);
+ Grid.SetRow(panel, i * 2);
+ Grid.SetColumn(panel, 2);
+
+ continue;
+ }
}
}
- ParentWindow.FitToSize();
+ ParentWindow?.FitToSize();
}
}
}
diff --git a/UVtools.WPF/LayerCache.cs b/UVtools.WPF/LayerCache.cs
index 4c5f1b8..b8c84bc 100644
--- a/UVtools.WPF/LayerCache.cs
+++ b/UVtools.WPF/LayerCache.cs
@@ -36,6 +36,7 @@ namespace UVtools.WPF
Clear();
_layer = value;
Image = _layer.LayerMat;
+ if (Image is null) return;
ImageBgr = new Mat();
CvInvoke.CvtColor(Image, ImageBgr, ColorConversion.Gray2Bgr);
diff --git a/UVtools.WPF/MainWindow.Issues.cs b/UVtools.WPF/MainWindow.Issues.cs
index 6cc6122..88bce1f 100644
--- a/UVtools.WPF/MainWindow.Issues.cs
+++ b/UVtools.WPF/MainWindow.Issues.cs
@@ -24,6 +24,7 @@ using MoreLinq;
using UVtools.Core;
using UVtools.Core.EmguCV;
using UVtools.Core.Extensions;
+using UVtools.Core.FileFormats;
using UVtools.Core.Layers;
using UVtools.Core.Operations;
using UVtools.WPF.Extensions;
@@ -467,6 +468,13 @@ namespace UVtools.WPF
public async Task OnClickDetectIssues()
{
if (!IsFileLoaded) return;
+ if (SlicerFile.DecodeType == FileFormat.FileDecodeType.Partial)
+ {
+ await this.MessageBoxError("The file was open in partial mode and the detect issues is unable to run in this mode.\n" +
+ "Please reload the file in full mode in order to use detect issues.", "Unable to run in partial mode");
+ return;
+
+ }
await ComputeIssues(
GetIslandDetectionConfiguration(),
GetOverhangDetectionConfiguration(),
diff --git a/UVtools.WPF/MainWindow.LayerPreview.cs b/UVtools.WPF/MainWindow.LayerPreview.cs
index a6844f8..e369695 100644
--- a/UVtools.WPF/MainWindow.LayerPreview.cs
+++ b/UVtools.WPF/MainWindow.LayerPreview.cs
@@ -799,7 +799,11 @@ namespace UVtools.WPF
var watch = Stopwatch.StartNew();
LayerCache.Layer = SlicerFile[_actualLayer];
-
+ if (LayerCache.Image is null)
+ {
+ RefreshCurrentLayerData();
+ return;
+ }
try
{
//var imageSpan = LayerCache.Image.GetPixelSpan<byte>();
@@ -1304,9 +1308,6 @@ namespace UVtools.WPF
CvInvoke.Rotate(LayerCache.ImageBgr, LayerCache.ImageBgr, _showLayerImageRotateCcwDirection ? RotateFlags.Rotate90CounterClockwise : RotateFlags.Rotate90Clockwise);
}
-
-
-
LayerImageBox.Image = LayerCache.Bitmap = LayerCache.ImageBgr.ToBitmap();
RefreshCurrentLayerData();
diff --git a/UVtools.WPF/MainWindow.axaml b/UVtools.WPF/MainWindow.axaml
index e825817..f76687c 100644
--- a/UVtools.WPF/MainWindow.axaml
+++ b/UVtools.WPF/MainWindow.axaml
@@ -43,6 +43,13 @@
<Image Source="\Assets\Icons\file-import-16x16.png"/>
</MenuItem.Icon>
</MenuItem>
+ <MenuItem Name="MainMenu.File.OpenInPartialMode" Header="Open in partial mode" Command="{Binding MenuFileOpenInPartialModeClicked}"
+ ToolTip.Tip="Open a file only to see and/or edit properties.
+&#x0a;Layer images won't be loaded and most tools won't run in this mode.">
+ <MenuItem.Icon>
+ <Image Source="\Assets\Icons\file-import-16x16.png"/>
+ </MenuItem.Icon>
+ </MenuItem>
<MenuItem
Name="MainMenu.File.Reload"
Header="_Reload"
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index 131f48e..1364e12 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -584,8 +584,7 @@ namespace UVtools.WPF
menuTool.Click += async (sender, args) => await ShowRunOperation(operation.GetType());
}
}
-
-
+
/*LayerSlider.PropertyChanged += (sender, args) =>
{
Debug.WriteLine(args.Property.Name);
@@ -1146,6 +1145,7 @@ namespace UVtools.WPF
public void MenuFileOpenClicked() => OpenFile();
public void MenuFileOpenNewWindowClicked() => OpenFile(true);
+ public void MenuFileOpenInPartialModeClicked() => OpenFile(false, FileFormat.FileDecodeType.Partial);
public void MenuFileOpenCurrentFileFolderClicked()
{
@@ -1196,7 +1196,7 @@ namespace UVtools.WPF
await SaveFile(file);
}
- public async void OpenFile(bool newWindow = false)
+ public async void OpenFile(bool newWindow = false, FileFormat.FileDecodeType fileDecodeType = FileFormat.FileDecodeType.Full)
{
var filters = Helpers.ToAvaloniaFileFilter(FileFormat.AllFileFiltersAvalonia);
var orderedFilters = new List<FileDialogFilter> {filters[Settings.General.DefaultOpenFileExtensionIndex]};
@@ -1213,7 +1213,7 @@ namespace UVtools.WPF
Directory = Settings.General.DefaultDirectoryOpenFile
};
var files = await dialog.ShowAsync(this);
- ProcessFiles(files, newWindow);
+ ProcessFiles(files, newWindow, fileDecodeType);
}
public async void OnMenuFileCloseFile()
@@ -1386,19 +1386,36 @@ namespace UVtools.WPF
private void UpdateTitle()
{
- Title = SlicerFile is null
- ? $"{About.Software} Version: {App.VersionStr}"
- : $"{About.Software} File: {Path.GetFileName(SlicerFile.FileFullPath)} ({Math.Round(LastStopWatch.ElapsedMilliseconds / 1000m, 2)}s) Version: {App.VersionStr}"
- ;
+ var title = $"{About.Software} ";
+
+ if (IsFileLoaded)
+ {
+ title += $"File: {Path.GetFileName(SlicerFile.FileFullPath)} ({Math.Round(LastStopWatch.ElapsedMilliseconds / 1000m, 2)}s) ";
+ }
- Title += $" RAM: {SizeExtensions.SizeSuffix(Environment.WorkingSet)}";
+ title += $"Version: {App.VersionStr} RAM: {SizeExtensions.SizeSuffix(Environment.WorkingSet)}";
+
+ if (IsFileLoaded)
+ {
+ if (CanSave)
+ {
+ title += " [UNSAVED]";
+ }
+
+ if (SlicerFile.DecodeType == FileFormat.FileDecodeType.Partial)
+ {
+ title += " [PARTIAL MODE]";
+ }
+ }
#if DEBUG
- Title += " [DEBUG]";
+ title += " [DEBUG]";
#endif
+
+ Title = title;
}
- public async void ProcessFiles(string[] files, bool openNewWindow = false)
+ public async void ProcessFiles(string[] files, bool openNewWindow = false, FileFormat.FileDecodeType fileDecodeType = FileFormat.FileDecodeType.Full)
{
if (files is null || files.Length == 0) return;
@@ -1436,7 +1453,7 @@ namespace UVtools.WPF
if (i == 0 && !openNewWindow && (_globalModifiers & KeyModifiers.Shift) == 0)
{
- ProcessFile(files[i]);
+ ProcessFile(files[i], fileDecodeType);
continue;
}
@@ -1450,10 +1467,11 @@ namespace UVtools.WPF
void ReloadFile(uint actualLayer)
{
if (App.SlicerFile is null) return;
- ProcessFile(SlicerFile.FileFullPath, _actualLayer);
+ ProcessFile(SlicerFile.FileFullPath, SlicerFile.DecodeType, _actualLayer);
}
- async void ProcessFile(string fileName, uint actualLayer = 0)
+ void ProcessFile(string fileName, uint actualLayer = 0) => ProcessFile(fileName, FileFormat.FileDecodeType.Full, actualLayer);
+ async void ProcessFile(string fileName, FileFormat.FileDecodeType fileDecodeType, uint actualLayer = 0)
{
if (!File.Exists(fileName)) return;
CloseFile();
@@ -1468,7 +1486,7 @@ namespace UVtools.WPF
{
try
{
- SlicerFile.Decode(fileName, Progress);
+ SlicerFile.Decode(fileName, fileDecodeType, Progress);
return true;
}
catch (OperationCanceledException)
@@ -1507,7 +1525,7 @@ namespace UVtools.WPF
return;
}
- if (Settings.Automations.AutoConvertFiles)
+ if (Settings.Automations.AutoConvertFiles && SlicerFile.DecodeType == FileFormat.FileDecodeType.Full)
{
string convertFileExtension = SlicerFile switch
{
@@ -1626,7 +1644,7 @@ namespace UVtools.WPF
Clipboard.Init(SlicerFile);
- if (SlicerFile is not ImageFile)
+ if (SlicerFile is not ImageFile && SlicerFile.DecodeType == FileFormat.FileDecodeType.Full)
{
List<MenuItem> menuItems = new();
foreach (var fileFormat in FileFormat.AvailableFormats)
@@ -1664,7 +1682,7 @@ namespace UVtools.WPF
MenuFileConvertItems = menuItems.ToArray();
}
- using var mat = SlicerFile[0].LayerMat;
+ using var mat = SlicerFile.FirstLayer?.LayerMat;
VisibleThumbnailIndex = 1;
@@ -1672,7 +1690,6 @@ namespace UVtools.WPF
UpdateTitle();
-
if (mat is not null)
{
if (Settings.LayerPreview.AutoRotateLayerBestView)
@@ -1726,7 +1743,7 @@ namespace UVtools.WPF
"Incorrect image ratio detected");
}
- if (mat.Size != SlicerFile.Resolution)
+ if (mat is not null && mat.Size != SlicerFile.Resolution)
{
var result = await this.MessageBoxWaring($"Layer image resolution of {mat.Size} mismatch with printer resolution of {SlicerFile.Resolution}.\n" +
"1) Printing this file can lead to problems or malformed model, please verify your slicer printer settings;\n" +
@@ -1747,29 +1764,32 @@ namespace UVtools.WPF
UpdateLayerTrackerHighlightIssues();
};
- if (Settings.Issues.ComputeIssuesOnLoad)
+ if (SlicerFile.DecodeType == FileFormat.FileDecodeType.Full)
{
- _firstTimeOnIssues = false;
- await OnClickDetectIssues();
- if (SlicerFile.IssueManager.Count > 0)
+ if (Settings.Issues.ComputeIssuesOnLoad)
{
- SelectedTabItem = TabIssues;
- if(Settings.Issues.AutoRepairIssuesOnLoad)
- await RunOperation(ToolRepairLayersControl.GetOperationRepairLayers());
+ _firstTimeOnIssues = false;
+ await OnClickDetectIssues();
+ if (SlicerFile.IssueManager.Count > 0)
+ {
+ SelectedTabItem = TabIssues;
+ if (Settings.Issues.AutoRepairIssuesOnLoad)
+ await RunOperation(ToolRepairLayersControl.GetOperationRepairLayers());
+ }
}
- }
- else
- {
- await ComputeIssues(
- GetIslandDetectionConfiguration(false),
- GetOverhangDetectionConfiguration(false),
- GetResinTrapDetectionConfiguration(false),
- GetTouchingBoundsDetectionConfiguration(false),
- GetPrintHeightDetectionConfiguration(true),
- true);
- if (SlicerFile.IssueManager.Count > 0)
+ else
{
- SelectedTabItem = TabIssues;
+ await ComputeIssues(
+ GetIslandDetectionConfiguration(false),
+ GetOverhangDetectionConfiguration(false),
+ GetResinTrapDetectionConfiguration(false),
+ GetTouchingBoundsDetectionConfiguration(false),
+ GetPrintHeightDetectionConfiguration(true),
+ true);
+ if (SlicerFile.IssueManager.Count > 0)
+ {
+ SelectedTabItem = TabIssues;
+ }
}
}
@@ -2066,6 +2086,13 @@ namespace UVtools.WPF
return null;
}
+ if (SlicerFile.DecodeType == FileFormat.FileDecodeType.Partial && !control.BaseOperation.CanRunInPartialMode)
+ {
+ await this.MessageBoxError($"The file was open in partial mode and the tool \"{control.BaseOperation.Title}\" is unable to run in this mode.\n" +
+ "Please reload the file in full mode in order to use this tool.", "Unable to run in partial mode");
+ return null;
+ }
+
if (removeContent)
{
control.IsVisible = false;
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index 38e0b02..f231c37 100644
--- a/UVtools.WPF/UVtools.WPF.csproj
+++ b/UVtools.WPF/UVtools.WPF.csproj
@@ -12,7 +12,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
- <Version>2.24.4</Version>
+ <Version>2.25.0</Version>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>