From 788f12cc41dfd98a39f7e3d610142fe04082e0d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Mon, 27 Apr 2020 22:56:35 +0100 Subject: [PATCH] v0.3 --- CHANGELOG.md | 25 +- PrusaSL1Reader/CbddlpFile.cs | 395 ++++++++------- .../{ => Extensions}/ObjectExtensions.cs | 4 +- .../{ => Extensions}/StringExtensions.cs | 3 +- .../Extensions/ZipArchiveExtensions.cs | 54 ++ PrusaSL1Reader/FileFormat.cs | 324 ++++++++---- PrusaSL1Reader/Helpers.cs | 25 +- PrusaSL1Reader/IFileFormat.cs | 175 +++++-- PrusaSL1Reader/LayerLine.cs | 35 -- PrusaSL1Reader/PrusaSL1Reader.csproj | 7 +- PrusaSL1Reader/SL1File.cs | 364 ++++++++------ PrusaSL1Reader/UniversalLayer.cs | 44 +- PrusaSL1Reader/ZCodexFile.cs | 461 ++++++++++++++++++ PrusaSL1Viewer.sln | 2 +- PrusaSL1Viewer/FrmAbout.Designer.cs | 61 +-- PrusaSL1Viewer/FrmInputBox.Designer.cs | 40 +- PrusaSL1Viewer/FrmInputBox.cs | 31 +- PrusaSL1Viewer/FrmMain.Designer.cs | 456 ++++++++++++----- PrusaSL1Viewer/FrmMain.cs | 137 +++++- PrusaSL1Viewer/FrmMain.resx | 60 ++- PrusaSL1Viewer/Images/DataList-16x16.png | Bin 0 -> 214 bytes PrusaSL1Viewer/Images/GCode-16x16.png | Bin 0 -> 274 bytes PrusaSL1Viewer/Images/PhotoInfo-16x16.png | Bin 0 -> 265 bytes PrusaSL1Viewer/Program.cs | 46 ++ PrusaSL1Viewer/Properties/AssemblyInfo.cs | 4 +- PrusaSL1Viewer/PrusaSL1Viewer.csproj | 10 +- PrusaSL1Viewer/packages.config | 5 +- PrusaSlicer/printer/Zortrax Inkspire.ini | 37 ++ README.md | 25 +- 29 files changed, 2104 insertions(+), 726 deletions(-) rename PrusaSL1Reader/{ => Extensions}/ObjectExtensions.cs (91%) rename PrusaSL1Reader/{ => Extensions}/StringExtensions.cs (97%) create mode 100644 PrusaSL1Reader/Extensions/ZipArchiveExtensions.cs delete mode 100644 PrusaSL1Reader/LayerLine.cs create mode 100644 PrusaSL1Reader/ZCodexFile.cs create mode 100644 PrusaSL1Viewer/Images/DataList-16x16.png create mode 100644 PrusaSL1Viewer/Images/GCode-16x16.png create mode 100644 PrusaSL1Viewer/Images/PhotoInfo-16x16.png create mode 100644 PrusaSlicer/printer/Zortrax Inkspire.ini diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c0e6ffa..c2d0d035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 27/04/2020 - v0.3.0 - Beta + +* (Add) zcodex file format +* (Add) Zortrax Inkspire Printer +* (Add) Properties menu -- Shows total keys and allow save information to a file +* (Add) "GCode" viewer Tab -- Only for formats that incldue gcode into file (ie: zcodex) +* (Add) Save gcode to a text file +* (Add) Allow to vertical arrange height between thumbnails and properties +* (Improvement) Thumbnail section is now hidden if no thumbnails avaliable +* (Improvement) Thumbnail section now vertical auto scales to the image height on file load +* (Improvement) On "modify properties" window, ENTER key can now be used to accept and submit the form +* (Fixed) Current model height doesn't calculate when viewing cbddlp files +* (Change) Round values up to two decimals +* (Change) Move actual model height near total height, now it shows (actual/total mm) +* (Change) Increase font size +* (Change) Rearrange code + ## 22/04/2020 - v0.2.2 - Beta * (Add) File -> Reload @@ -27,10 +44,10 @@ ## 12/04/2020 - v0.2 - Beta -* Add cbddlp file format -* Add "convert to" function, allow convert sl1 file to another -* Add EPAX X1 printer -* Change code with abstraction of file formats +* (Add) cbddlp file format +* (Add) "convert to" function, allow convert sl1 file to another +* (Add) EPAX X1 printer +* (Change) Code with abstraction of file formats ## 06/04/2020 - V0.1 - Beta diff --git a/PrusaSL1Reader/CbddlpFile.cs b/PrusaSL1Reader/CbddlpFile.cs index 441f4e59..0546e1d3 100644 --- a/PrusaSL1Reader/CbddlpFile.cs +++ b/PrusaSL1Reader/CbddlpFile.cs @@ -11,6 +11,7 @@ using System.Diagnostics; using System.IO; using BinarySerialization; +using PrusaSL1Reader.Extensions; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -175,7 +176,6 @@ public override string ToString() #endregion #region Properties - public FileStream InputFile { get; private set; } public FileStream OutputFile { get; private set; } public Header HeaderSettings { get; protected internal set; } @@ -190,173 +190,97 @@ public override string ToString() private uint CurrentOffset { get; set; } private uint LayerDataCurrentOffset { get; set; } - #endregion - - #region Constructors - public CbddlpFile() - { - Previews = new Preview[ThumbnailsCount]; - } - #endregion - - #region Overrides - public override string FileFullPath { get; set; } + public override FileFormatType FileType => FileFormatType.Binary; public override FileExtension[] FileExtensions { get; } = { - new FileExtension("cbddlp", "Chitubox DLP Files"), - new FileExtension("photon", "Photon Files"), + new FileExtension("cbddlp", "Chitubox DLP Files"), + new FileExtension("photon", "Photon Files"), }; - public override uint ResolutionX => HeaderSettings.ResolutionX; - - public override uint ResolutionY => HeaderSettings.ResolutionY; - - - public override byte ThumbnailsCount { get; } = 2; - public override Image[] Thumbnails { get; set; } - - public override PrintParameterModifier[] PrintParameterModifiers => new[] + public override PrintParameterModifier[] PrintParameterModifiers { get; } = { PrintParameterModifier.InitialLayerCount, PrintParameterModifier.InitialExposureSeconds, PrintParameterModifier.ExposureSeconds, - PrintParameterModifier.BottomLayerOffTime, - PrintParameterModifier.LayerOffTime, - PrintParameterModifier.BottomLiftHeight, - PrintParameterModifier.BottomLiftSpeed, - PrintParameterModifier.LiftHeight, - PrintParameterModifier.LiftingSpeed, - PrintParameterModifier.RetractSpeed, + PrintParameterModifier.BottomLayerOffTime, + PrintParameterModifier.LayerOffTime, + PrintParameterModifier.BottomLiftHeight, + PrintParameterModifier.BottomLiftSpeed, + PrintParameterModifier.ZRetractHeight, + PrintParameterModifier.ZDetractSpeed, + PrintParameterModifier.ZRetractSpeed, PrintParameterModifier.BottomLightPWM, PrintParameterModifier.LightPWM, }; + public override string FileFullPath { get; set; } + + public override byte ThumbnailsCount { get; } = 2; + + public override Image[] Thumbnails { get; set; } + + public override uint ResolutionX => HeaderSettings.ResolutionX; + + public override uint ResolutionY => HeaderSettings.ResolutionY; + + public override float LayerHeight => HeaderSettings.LayerHeightMilimeter; + public override uint LayerCount => HeaderSettings.LayerCount; - public override ushort InitialLayerCount => (ushort) HeaderSettings.BottomLayersCount; + public override ushort InitialLayerCount => (ushort)HeaderSettings.BottomLayersCount; public override float InitialExposureTime => HeaderSettings.BottomExposureSeconds; + public override float LayerExposureTime => HeaderSettings.LayerExposureSeconds; + public override float ZRetractHeight => PrintParametersSettings.LiftHeight; + public override float ZRetractSpeed => PrintParametersSettings.RetractSpeed; + public override float ZDetractSpeed => PrintParametersSettings.LiftingSpeed; + public override float PrintTime => HeaderSettings.PrintTime; + public override float UsedMaterial => PrintParametersSettings.VolumeMl; public override float MaterialCost => PrintParametersSettings.CostDollars; public override string MaterialName => "Unknown"; public override string MachineName => MachineInfoSettings.MachineName; - public override float LayerHeight => HeaderSettings.LayerHeightMilimeter; - + public override object[] Configs => new[] { (object)HeaderSettings, PrintParametersSettings, MachineInfoSettings }; - public override object GetValueFromPrintParameterModifier(PrintParameterModifier modifier) - { - var baseValue = base.GetValueFromPrintParameterModifier(modifier); - if (!ReferenceEquals(baseValue, null)) return baseValue; - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLayerOffTime)) return PrintParametersSettings.BottomLightOffDelay; - if (ReferenceEquals(modifier, PrintParameterModifier.LayerOffTime)) return PrintParametersSettings.LightOffDelay; - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftHeight)) return PrintParametersSettings.BottomLiftHeight; - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftSpeed)) return PrintParametersSettings.BottomLiftSpeed; - if (ReferenceEquals(modifier, PrintParameterModifier.LiftHeight)) return PrintParametersSettings.LiftHeight; - if (ReferenceEquals(modifier, PrintParameterModifier.LiftingSpeed)) return PrintParametersSettings.LiftingSpeed; - if (ReferenceEquals(modifier, PrintParameterModifier.RetractSpeed)) return PrintParametersSettings.RetractSpeed; - - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLightPWM)) return HeaderSettings.BottomLightPWM; - if (ReferenceEquals(modifier, PrintParameterModifier.LightPWM)) return HeaderSettings.LightPWM; - - + #endregion - return null; + #region Constructors + public CbddlpFile() + { + Previews = new Preview[ThumbnailsCount]; } + #endregion - public override bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, string value) + #region Methods + public override void Clear() { - void updateLayers() - { - for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++) - { - for (uint layerIndex = 0; layerIndex < HeaderSettings.LayerCount; layerIndex++) - { - // Bottom : others - Layers[layerIndex, aaIndex].LayerExposure = layerIndex < HeaderSettings.BottomLayersCount ? HeaderSettings.BottomExposureSeconds : HeaderSettings.LayerExposureSeconds; - Layers[layerIndex, aaIndex].LayerOffTimeSeconds = layerIndex < HeaderSettings.BottomLayersCount ? PrintParametersSettings.BottomLightOffDelay : PrintParametersSettings.LightOffDelay; - } - } - } + base.Clear(); - if (ReferenceEquals(modifier, PrintParameterModifier.InitialLayerCount)) - { - HeaderSettings.BottomLayersCount = - PrintParametersSettings.BottomLayerCount = value.Convert(); - updateLayers(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.InitialExposureSeconds)) + for (byte i = 0; i < ThumbnailsCount; i++) { - HeaderSettings.BottomExposureSeconds = value.Convert(); - updateLayers(); - return true; + Previews[i] = new Preview(); } - if (ReferenceEquals(modifier, PrintParameterModifier.ExposureSeconds)) - { - HeaderSettings.LayerExposureSeconds = value.Convert(); - updateLayers(); - return true; - } + Layers = null; - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLayerOffTime)) - { - PrintParametersSettings.BottomLightOffDelay = value.Convert(); - updateLayers(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.LayerOffTime)) - { - HeaderSettings.LayerOffTime = - PrintParametersSettings.LightOffDelay = value.Convert(); - updateLayers(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftHeight)) - { - PrintParametersSettings.BottomLiftHeight = value.Convert(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftSpeed)) - { - PrintParametersSettings.BottomLiftSpeed = value.Convert(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.LiftHeight)) - { - PrintParametersSettings.LiftHeight = value.Convert(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.LiftingSpeed)) - { - PrintParametersSettings.LiftingSpeed = value.Convert(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.RetractSpeed)) + if (!ReferenceEquals(InputFile, null)) { - PrintParametersSettings.RetractSpeed = value.Convert(); - return true; + InputFile.Close(); + InputFile.Dispose(); } - if (ReferenceEquals(modifier, PrintParameterModifier.BottomLightPWM)) - { - HeaderSettings.BottomLightPWM = value.Convert(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.LightPWM)) + if (!ReferenceEquals(OutputFile, null)) { - HeaderSettings.LightPWM = value.Convert(); - return true; + OutputFile.Close(); + OutputFile.Dispose(); } - - return false; } public override void BeginEncode(string fileFullPath) @@ -471,8 +395,8 @@ public override void InsertLayerImageEncode(Image image, uint layerIndex) { Layer layer = new Layer(); List rawData = new List(); - - byte color = 0; + + byte color; byte black = 0; byte white = 1; @@ -495,7 +419,7 @@ public override void InsertLayerImageEncode(Image image, uint layerIndex) else { byte encValue = - (byte) ((prevColor << 7) | + (byte)((prevColor << 7) | nrOfColor); // push color (B/W) to highest bit and repetitions to lowest 7 bits. rawData.Add(encValue); prevColor = color; @@ -541,7 +465,7 @@ public override void EndEncode() public override void Decode(string fileFullPath) { base.Decode(fileFullPath); - + InputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read); //HeaderSettings = Helpers.ByteToType(InputFile); @@ -567,7 +491,7 @@ public override void Decode(string fileFullPath) for (byte i = 0; i < ThumbnailsCount; i++) { uint offsetAddress = i == 0 ? HeaderSettings.PreviewOneOffsetAddress : HeaderSettings.PreviewTwoOffsetAddress; - if(offsetAddress == 0) continue; + if (offsetAddress == 0) continue; InputFile.Seek(offsetAddress, SeekOrigin.Begin); Previews[i] = Helpers.Deserialize(InputFile); @@ -595,7 +519,7 @@ public override void Decode(string fileFullPath) repeat += rawImageData[++n] & 0xFF | ((rawImageData[++n] & 0x0F) << 8); } - + for (int j = 0; j < repeat; j++) { Thumbnails[i][x, y] = new Rgba32(red, green, blue, 255); @@ -616,7 +540,7 @@ public override void Decode(string fileFullPath) PrintParametersSettings = Helpers.Deserialize(InputFile); Debug.Write("Print Parameters -> "); Debug.WriteLine(PrintParametersSettings); - + MachineInfoSettings = Helpers.Deserialize(InputFile); Debug.Write("Machine Info -> "); Debug.WriteLine(MachineInfoSettings); @@ -633,7 +557,7 @@ public override void Decode(string fileFullPath) Image image = new Image((int)HeaderSettings.BedSizeX, (int)HeaderSettings.BedSizeY); - + for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++) { Debug.WriteLine($"-Image GROUP {aaIndex}-"); @@ -652,49 +576,8 @@ public override void Decode(string fileFullPath) } public override void Extract(string path, bool emptyFirst = true, bool genericConfigExtract = false, - bool genericLayersExtract = false) - { + bool genericLayersExtract = false) => base.Extract(path, emptyFirst, true, true); - } - - public override void SaveAs(string filePath = null) - { - InputFile.Dispose(); - if (!string.IsNullOrEmpty(filePath)) - { - File.Copy(FileFullPath, filePath, true); - FileFullPath = filePath; - - } - - using (InputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write)) - { - - InputFile.Seek(0, SeekOrigin.Begin); - Helpers.SerializeWriteFileStream(InputFile, HeaderSettings); - - if (HeaderSettings.Version == 2 && HeaderSettings.PrintParametersOffsetAddress > 0) - { - InputFile.Seek(HeaderSettings.PrintParametersOffsetAddress, SeekOrigin.Begin); - Helpers.SerializeWriteFileStream(InputFile, PrintParametersSettings); - Helpers.SerializeWriteFileStream(InputFile, MachineInfoSettings); - } - - uint layerOffset = HeaderSettings.LayersDefinitionOffsetAddress; - for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++) - { - for (uint layerIndex = 0; layerIndex < HeaderSettings.LayerCount; layerIndex++) - { - InputFile.Seek(layerOffset, SeekOrigin.Begin); - Helpers.SerializeWriteFileStream(InputFile, Layers[layerIndex, aaIndex]); - layerOffset += (uint) Helpers.Serializer.SizeOf(Layers[layerIndex, aaIndex]); - } - } - InputFile.Close(); - } - - Decode(FileFullPath); - } public override Image GetLayerImage(uint layerIndex) { @@ -704,7 +587,7 @@ public override Image GetLayerImage(uint layerIndex) } Image image = new Image((int)HeaderSettings.ResolutionX, (int)HeaderSettings.ResolutionY); - + for (uint aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++) { Layer layer = Layers[layerIndex, aaIndex]; @@ -720,13 +603,14 @@ public override Image GetLayerImage(uint layerIndex) uint length = (uint)(rle & 0x7F); // turn highest bit of bool color = (rle & 0x80) == 0x80; // only read 1st bit - uint x2 = (uint)Math.Min(x + length, HeaderSettings.ResolutionX); + uint x2 = Math.Min(x + length, HeaderSettings.ResolutionX); if (color) { + var span = image.GetPixelRowSpan((int)y); for (uint i = x; i < x2; i++) { - image[(int) i, (int) y] = Helpers.Gray8White; + span[(int)i] = Helpers.Gray8White; } } @@ -741,9 +625,10 @@ public override Image GetLayerImage(uint layerIndex) if (color) { + var span = image.GetPixelRowSpan((int)y); for (uint i = x; i < x2; i++) { - image[(int) i, (int) y] = new Gray8(255); + span[(int)i] = Helpers.Gray8White; } } @@ -755,44 +640,158 @@ public override Image GetLayerImage(uint layerIndex) return image; } - public override float GetHeightFromLayer(uint layerNum) + public override object GetValueFromPrintParameterModifier(PrintParameterModifier modifier) { - return HeaderSettings.LayerCount; + var baseValue = base.GetValueFromPrintParameterModifier(modifier); + if (!ReferenceEquals(baseValue, null)) return baseValue; + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLayerOffTime)) return PrintParametersSettings.BottomLightOffDelay; + if (ReferenceEquals(modifier, PrintParameterModifier.LayerOffTime)) return PrintParametersSettings.LightOffDelay; + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftHeight)) return PrintParametersSettings.BottomLiftHeight; + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftSpeed)) return PrintParametersSettings.BottomLiftSpeed; + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractHeight)) return PrintParametersSettings.LiftHeight; + if (ReferenceEquals(modifier, PrintParameterModifier.ZDetractSpeed)) return PrintParametersSettings.LiftingSpeed; + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractSpeed)) return PrintParametersSettings.RetractSpeed; + + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLightPWM)) return HeaderSettings.BottomLightPWM; + if (ReferenceEquals(modifier, PrintParameterModifier.LightPWM)) return HeaderSettings.LightPWM; + + + + return null; } - public override void Clear() + public override bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, string value) { - base.Clear(); + void UpdateLayers() + { + for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++) + { + for (uint layerIndex = 0; layerIndex < HeaderSettings.LayerCount; layerIndex++) + { + // Bottom : others + Layers[layerIndex, aaIndex].LayerExposure = layerIndex < HeaderSettings.BottomLayersCount ? HeaderSettings.BottomExposureSeconds : HeaderSettings.LayerExposureSeconds; + Layers[layerIndex, aaIndex].LayerOffTimeSeconds = layerIndex < HeaderSettings.BottomLayersCount ? PrintParametersSettings.BottomLightOffDelay : PrintParametersSettings.LightOffDelay; + } + } + } - for (byte i = 0; i < ThumbnailsCount; i++) + if (ReferenceEquals(modifier, PrintParameterModifier.InitialLayerCount)) { - Previews[i] = new Preview(); + HeaderSettings.BottomLayersCount = + PrintParametersSettings.BottomLayerCount = value.Convert(); + UpdateLayers(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.InitialExposureSeconds)) + { + HeaderSettings.BottomExposureSeconds = value.Convert(); + UpdateLayers(); + return true; } - Layers = null; + if (ReferenceEquals(modifier, PrintParameterModifier.ExposureSeconds)) + { + HeaderSettings.LayerExposureSeconds = value.Convert(); + UpdateLayers(); + return true; + } - if (!ReferenceEquals(InputFile, null)) + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLayerOffTime)) { - InputFile.Close(); - InputFile.Dispose(); + PrintParametersSettings.BottomLightOffDelay = value.Convert(); + UpdateLayers(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.LayerOffTime)) + { + HeaderSettings.LayerOffTime = + PrintParametersSettings.LightOffDelay = value.Convert(); + UpdateLayers(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftHeight)) + { + PrintParametersSettings.BottomLiftHeight = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLiftSpeed)) + { + PrintParametersSettings.BottomLiftSpeed = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractHeight)) + { + PrintParametersSettings.LiftHeight = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.ZDetractSpeed)) + { + PrintParametersSettings.LiftingSpeed = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractSpeed)) + { + PrintParametersSettings.RetractSpeed = value.Convert(); + return true; } - if (!ReferenceEquals(OutputFile, null)) + if (ReferenceEquals(modifier, PrintParameterModifier.BottomLightPWM)) { - OutputFile.Close(); - OutputFile.Dispose(); + HeaderSettings.BottomLightPWM = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.LightPWM)) + { + HeaderSettings.LightPWM = value.Convert(); + return true; } + + return false; } - public override bool Convert(Type to, string fileFullPath) + public override void SaveAs(string filePath = null) { - throw new NotImplementedException(); - } + InputFile.Dispose(); + if (!string.IsNullOrEmpty(filePath)) + { + File.Copy(FileFullPath, filePath, true); + FileFullPath = filePath; - #endregion + } - #region Methods + using (InputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write)) + { + + InputFile.Seek(0, SeekOrigin.Begin); + Helpers.SerializeWriteFileStream(InputFile, HeaderSettings); + + if (HeaderSettings.Version == 2 && HeaderSettings.PrintParametersOffsetAddress > 0) + { + InputFile.Seek(HeaderSettings.PrintParametersOffsetAddress, SeekOrigin.Begin); + Helpers.SerializeWriteFileStream(InputFile, PrintParametersSettings); + Helpers.SerializeWriteFileStream(InputFile, MachineInfoSettings); + } + uint layerOffset = HeaderSettings.LayersDefinitionOffsetAddress; + for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++) + { + for (uint layerIndex = 0; layerIndex < HeaderSettings.LayerCount; layerIndex++) + { + InputFile.Seek(layerOffset, SeekOrigin.Begin); + Helpers.SerializeWriteFileStream(InputFile, Layers[layerIndex, aaIndex]); + layerOffset += (uint)Helpers.Serializer.SizeOf(Layers[layerIndex, aaIndex]); + } + } + InputFile.Close(); + } + + Decode(FileFullPath); + } + + public override bool Convert(Type to, string fileFullPath) + { + throw new NotImplementedException(); + } #endregion } } diff --git a/PrusaSL1Reader/ObjectExtensions.cs b/PrusaSL1Reader/Extensions/ObjectExtensions.cs similarity index 91% rename from PrusaSL1Reader/ObjectExtensions.cs rename to PrusaSL1Reader/Extensions/ObjectExtensions.cs index 5f73e7b9..d7a1d1f8 100644 --- a/PrusaSL1Reader/ObjectExtensions.cs +++ b/PrusaSL1Reader/Extensions/ObjectExtensions.cs @@ -9,7 +9,7 @@ using System.IO; using System.Runtime.Serialization.Formatters.Binary; -namespace PrusaSL1Reader +namespace PrusaSL1Reader.Extensions { public static class ObjectExtensions { @@ -21,7 +21,7 @@ public static class ObjectExtensions /// Converted value into target type public static T Convert(this object input) { - return input.ToString().Convert(); + return StringExtensions.Convert(input.ToString()); } public static object DeserializeFromBytes(byte[] bytes) diff --git a/PrusaSL1Reader/StringExtensions.cs b/PrusaSL1Reader/Extensions/StringExtensions.cs similarity index 97% rename from PrusaSL1Reader/StringExtensions.cs rename to PrusaSL1Reader/Extensions/StringExtensions.cs index 1d042f50..039a6335 100644 --- a/PrusaSL1Reader/StringExtensions.cs +++ b/PrusaSL1Reader/Extensions/StringExtensions.cs @@ -5,11 +5,12 @@ * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. */ + using System; using System.ComponentModel; using System.Linq; -namespace PrusaSL1Reader +namespace PrusaSL1Reader.Extensions { public static class StringExtensions { diff --git a/PrusaSL1Reader/Extensions/ZipArchiveExtensions.cs b/PrusaSL1Reader/Extensions/ZipArchiveExtensions.cs new file mode 100644 index 00000000..9d9065ac --- /dev/null +++ b/PrusaSL1Reader/Extensions/ZipArchiveExtensions.cs @@ -0,0 +1,54 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System.IO; +using System.IO.Compression; + +namespace PrusaSL1Reader.Extensions +{ + public static class ZipArchiveExtensions + { + /// + /// Create a file into archive and write content to it + /// + /// + /// Filename to create + /// Content to write + /// Created + public static ZipArchiveEntry PutFileContent(this ZipArchive input, string filename, string content, bool deleteFirst = true) + { + if(deleteFirst) input.GetEntry(filename)?.Delete(); + + var entry = input.CreateEntry(filename); + if (ReferenceEquals(content, null)) return entry; + using (TextWriter tw = new StreamWriter(entry.Open())) + { + tw.Write(content); + tw.Close(); + } + + return entry; + } + + public static ZipArchiveEntry PutFileContent(this ZipArchive input, string filename, Stream content, bool deleteFirst = true) + { + if (deleteFirst) input.GetEntry(filename)?.Delete(); + var entry = input.CreateEntry(filename); + if (ReferenceEquals(content, null)) return entry; + using (StreamWriter tw = new StreamWriter(entry.Open())) + { + tw.Write(content); + tw.Close(); + } + + return entry; + } + + + } +} diff --git a/PrusaSL1Reader/FileFormat.cs b/PrusaSL1Reader/FileFormat.cs index dca480b1..c70fd8e6 100644 --- a/PrusaSL1Reader/FileFormat.cs +++ b/PrusaSL1Reader/FileFormat.cs @@ -6,9 +6,9 @@ * of this license document, but changing it is not allowed. */ using System; +using System.Dynamic; using System.IO; using System.Linq; -using System.Runtime.CompilerServices; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; @@ -18,37 +18,69 @@ namespace PrusaSL1Reader /// /// Slicer representation /// - public abstract class FileFormat : IFileFormat, IDisposable + public abstract class FileFormat : IFileFormat, IDisposable, IEquatable { #region Enums + /// + /// Enumeration of file format types + /// + public enum FileFormatType : byte + { + Archive, + Binary + } + #endregion + + #region Sub Classes /// /// Available Print Parameters to modify /// public class PrintParameterModifier { + + #region Instances public static PrintParameterModifier InitialLayerCount { get; } = new PrintParameterModifier("Initial Layer Count", @"Modify 'Initial Layer Count' value", null,0, ushort.MaxValue); public static PrintParameterModifier InitialExposureSeconds { get; } = new PrintParameterModifier("Initial Exposure Time", @"Modify 'Initial Exposure Time' seconds", "s", 0.1M, byte.MaxValue); public static PrintParameterModifier ExposureSeconds { get; } = new PrintParameterModifier("Exposure Time", @"Modify 'Exposure Time' seconds", "s", 0.1M, byte.MaxValue); public static PrintParameterModifier BottomLayerOffTime { get; } = new PrintParameterModifier("Bottom Layer Off Time", @"Modify 'Bottom Layer Off Time' seconds", "s"); public static PrintParameterModifier LayerOffTime { get; } = new PrintParameterModifier("Layer Off Time", @"Modify 'Layer Off Time' seconds", "s"); - public static PrintParameterModifier BottomLiftHeight { get; } = new PrintParameterModifier("Bottom Lift Height", @"Modify 'Bottom Lift Height' millimeters", "mm"); - public static PrintParameterModifier BottomLiftSpeed { get; } = new PrintParameterModifier("Bottom Lift Speed", @"Modify 'Bottom Lift Speed' mm/min", "mm/min"); - public static PrintParameterModifier LiftHeight { get; } = new PrintParameterModifier("Lift Height", @"Modify 'Lift Height' millimeters", "mm"); - public static PrintParameterModifier LiftingSpeed { get; } = new PrintParameterModifier("Lifting Speed", @"Modify 'Lifting Speed' mm/min", "mm/min", 10, 5000); - public static PrintParameterModifier RetractSpeed { get; } = new PrintParameterModifier("Retract Speed", @"Modify 'Retract Speed' mm/min", "mm/min", 10, 5000); + public static PrintParameterModifier BottomLiftHeight { get; } = new PrintParameterModifier("Bottom Lift Height", @"Modify 'Bottom Lift Height' millimeters between bottom layers", "mm"); + public static PrintParameterModifier BottomLiftSpeed { get; } = new PrintParameterModifier("Bottom Lift Speed", @"Modify 'Bottom Lift Speed' mm/min between bottom layers", "mm/min"); + public static PrintParameterModifier ZRetractHeight { get; } = new PrintParameterModifier("Z Retract Height", @"Modify 'Z Retract Height' millimeters between layers", "mm"); + public static PrintParameterModifier ZRetractSpeed { get; } = new PrintParameterModifier("Z Retract Speed", @"Modify 'Z Retract Speed' mm/min between layers", "mm/min", 10, 5000); + public static PrintParameterModifier ZDetractSpeed { get; } = new PrintParameterModifier("Z Detract Speed", @"Modify 'Z Detract Speed' mm/min between layers", "mm/min", 10, 5000); public static PrintParameterModifier BottomLightPWM { get; } = new PrintParameterModifier("Bottom Light PWM", @"Modify 'Bottom Light PWM' value", null, 50, byte.MaxValue); public static PrintParameterModifier LightPWM { get; } = new PrintParameterModifier("Light PWM", @"Modify 'Light PWM' value", null, 50, byte.MaxValue); + #endregion #region Properties + /// + /// Gets the name + /// public string Name { get; } + + /// + /// Gets the description + /// public string Description { get; } + + /// + /// Gets the value unit + /// public string ValueUnit { get; } + /// + /// Gets the minimum value + /// public decimal Minimum { get; } + + /// + /// Gets the maximum value + /// public decimal Maximum { get; } #endregion @@ -63,7 +95,12 @@ public PrintParameterModifier(string name, string description, string valueUnit } #endregion - + #region Overrides + public override string ToString() + { + return $"{nameof(Name)}: {Name}, {nameof(Description)}: {Description}, {nameof(ValueUnit)}: {ValueUnit}, {nameof(Minimum)}: {Minimum}, {nameof(Maximum)}: {Maximum}"; + } + #endregion } #endregion @@ -72,13 +109,41 @@ public PrintParameterModifier(string name, string description, string valueUnit private const string ExtractConfigFileExtension = "ini"; #endregion + #region Static Methods + /// + /// Gets the available formats to process + /// public static FileFormat[] AvaliableFormats { get; } = { - new SL1File(), - new CbddlpFile(), + new SL1File(), // Prusa SL1 + new CbddlpFile(), // cbddlp, photon + new ZCodexFile(), // zcodex }; - public static string AllFileFilters => AvaliableFormats.Aggregate(string.Empty, (current, fileFormat) => string.IsNullOrEmpty(current) ? fileFormat.GetFileFilter() : $"{current}|" + fileFormat.GetFileFilter()); + /// + /// Gets all filters for open and save file dialogs + /// + public static string AllFileFilters => + AvaliableFormats.Aggregate(string.Empty, + (current, fileFormat) => string.IsNullOrEmpty(current) + ? fileFormat.FileFilter + : $"{current}|" + fileFormat.FileFilter) + + + AvaliableFormats.Aggregate("|All slicer files|", + (current, fileFormat) => current.EndsWith("|") + ? $"{current}{fileFormat.FileFilterExtensionsOnly}" + : $"{current};{fileFormat.FileFilterExtensionsOnly}"); + + /// + /// Gets the count of available file extensions + /// + public static byte FileExtensionsCount + { + get + { + return AvaliableFormats.Aggregate(0, (current, fileFormat) => (byte) (current + fileFormat.FileExtensions.Length)); + } + } /// /// Find by an extension @@ -91,28 +156,57 @@ public static FileFormat FindByExtension(string extension, bool isFilePath = fal { return (from fileFormat in AvaliableFormats where fileFormat.IsExtensionValid(extension, isFilePath) select createNewInstance ? (FileFormat) Activator.CreateInstance(fileFormat.GetType()) : fileFormat).FirstOrDefault(); } + #endregion - /// - /// Gets the input file path loaded into this - /// - public abstract string FileFullPath { get; set; } + #region Properties + + public abstract FileFormatType FileType { get; } - /// - /// Gets the valid file extensions for this - /// public abstract FileExtension[] FileExtensions { get; } - public abstract uint ResolutionX { get; } - public abstract uint ResolutionY { get; } + public abstract PrintParameterModifier[] PrintParameterModifiers { get; } + + public string FileFilter { + get + { + var result = string.Empty; + + foreach (var fileExt in FileExtensions) + { + if (!ReferenceEquals(result, string.Empty)) + { + result += '|'; + } + result += fileExt.Filter; + } + + return result; + } + } + + public string FileFilterExtensionsOnly + { + get + { + var result = string.Empty; + + foreach (var fileExt in FileExtensions) + { + if (!ReferenceEquals(result, string.Empty)) + { + result += ';'; + } + result += $"*.{fileExt.Extension}"; + } + + return result; + } + } + + public abstract string FileFullPath { get; set; } - /// - /// Gets the thumbnails count present in this file format - /// public abstract byte ThumbnailsCount { get; } - /// - /// Gets the number of created thumbnails - /// public byte CreatedThumbnailsCount { get { @@ -129,61 +223,118 @@ public byte CreatedThumbnailsCount { } } - /// - /// Gets the thumbnails for this - /// public abstract Image[] Thumbnails { get; set; } - public abstract PrintParameterModifier[] PrintParameterModifiers { get; } + public abstract uint ResolutionX { get; } - public abstract uint LayerCount { get; } + public abstract uint ResolutionY { get; } - public abstract ushort InitialLayerCount { get; } + public abstract float LayerHeight { get; } + public float TotalHeight => (float)Math.Round(LayerCount * LayerHeight, 2); + + public abstract uint LayerCount { get; } + + public abstract ushort InitialLayerCount { get; } + public abstract float InitialExposureTime { get; } public abstract float LayerExposureTime { get; } + + public abstract float ZRetractHeight { get; } + + public abstract float ZRetractSpeed { get; } + + public abstract float ZDetractSpeed { get; } + public abstract float PrintTime { get; } + public abstract float UsedMaterial { get; } public abstract float MaterialCost { get; } public abstract string MaterialName { get; } + public abstract string MachineName { get; } - public abstract float LayerHeight { get; } - public float TotalHeight => (float)Math.Round(LayerCount * LayerHeight, 2); + public virtual string GCode { get; set; } + + public abstract object[] Configs { get; } + + public bool IsValid => !ReferenceEquals(FileFullPath, null); + #endregion + + #region Constructor protected FileFormat() { Thumbnails = new Image[ThumbnailsCount]; } + #endregion - public abstract object[] Configs { get; } + #region Overrides + public override bool Equals(object obj) + { + return Equals(obj as FileFormat); + } - public virtual object GetValueFromPrintParameterModifier(PrintParameterModifier modifier) + public bool Equals(FileFormat other) { - if (ReferenceEquals(modifier, PrintParameterModifier.InitialLayerCount)) - return InitialLayerCount; - if (ReferenceEquals(modifier, PrintParameterModifier.InitialExposureSeconds)) - return InitialExposureTime; - if (ReferenceEquals(modifier, PrintParameterModifier.ExposureSeconds)) - return LayerExposureTime; + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return FileFullPath.Equals(other.FileFullPath); + } + public override int GetHashCode() + { + return (FileFullPath != null ? FileFullPath.GetHashCode() : 0); + } - return null; + public void Dispose() + { + Clear(); } - public virtual bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, object value) + #endregion + + #region Methods + public virtual void Clear() { - return SetValueFromPrintParameterModifier(modifier, value.ToString()); + FileFullPath = null; + if (!ReferenceEquals(Thumbnails, null)) + { + for (int i = 0; i < ThumbnailsCount; i++) + { + Thumbnails[i]?.Dispose(); + } + } } - public abstract bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, string value); + public void FileValidation(string fileFullPath) + { + if (ReferenceEquals(fileFullPath, null)) throw new ArgumentNullException(nameof(FileFullPath), "fullFilePath can't be null."); + if (!File.Exists(fileFullPath)) throw new FileNotFoundException("The specified file does not exists.", fileFullPath); - public bool IsValid => !ReferenceEquals(FileFullPath, null); + if (IsExtensionValid(fileFullPath, true)) + { + return; + } + throw new FileLoadException($"The specified file is not valid.", fileFullPath); + } - public abstract void BeginEncode(string fileFullPath); + public bool IsExtensionValid(string extension, bool isFilePath = false) + { + extension = isFilePath ? Path.GetExtension(extension)?.Remove(0, 1) : extension; + return FileExtensions.Any(fileExtension => fileExtension.Extension.Equals(extension)); + } + + public virtual void BeginEncode(string fileFullPath) + { + if (File.Exists(fileFullPath)) + { + File.Delete(fileFullPath); + } + } public abstract void InsertLayerImageEncode(Image image, uint layerIndex); @@ -254,73 +405,52 @@ public virtual void Extract(string path, bool emptyFirst = true, bool genericCon } } - public void Save() - { - SaveAs(); - } - - public abstract void SaveAs(string filePath = null); - public abstract Image GetLayerImage(uint layerIndex); - public abstract float GetHeightFromLayer(uint layerNum); - - public virtual void Clear() + public virtual float GetHeightFromLayer(uint layerNum) { - FileFullPath = null; - if (!ReferenceEquals(Thumbnails, null)) - { - for (int i = 0; i < ThumbnailsCount; i++) - { - Thumbnails[i]?.Dispose(); - } - } + return (float)Math.Round(layerNum * LayerHeight, 2); } - public abstract bool Convert(Type to, string fileFullPath); - public bool Convert(FileFormat to, string fileFullPath) + public virtual object GetValueFromPrintParameterModifier(PrintParameterModifier modifier) { - return Convert(to.GetType(), fileFullPath); - } + if (ReferenceEquals(modifier, PrintParameterModifier.InitialLayerCount)) + return InitialLayerCount; + if (ReferenceEquals(modifier, PrintParameterModifier.InitialExposureSeconds)) + return InitialExposureTime; + if (ReferenceEquals(modifier, PrintParameterModifier.ExposureSeconds)) + return LayerExposureTime; - public void FileValidation(string fileFullPath) - { - if (ReferenceEquals(fileFullPath, null)) throw new ArgumentNullException(nameof(FileFullPath), "fullFilePath can't be null."); - if (!File.Exists(fileFullPath)) throw new FileNotFoundException("The specified file does not exists.", fileFullPath); + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractHeight)) + return ZRetractHeight; + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractSpeed)) + return ZRetractSpeed; + if (ReferenceEquals(modifier, PrintParameterModifier.ZDetractSpeed)) + return ZDetractSpeed; - if (IsExtensionValid(fileFullPath, true)) - { - return; - } - throw new FileLoadException($"The specified file is not valid.", fileFullPath); + return null; } - public bool IsExtensionValid(string extension, bool isFilePath = false) + public virtual bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, object value) { - extension = isFilePath ? Path.GetExtension(extension)?.Remove(0, 1) : extension; - return FileExtensions.Any(fileExtension => fileExtension.Extension.Equals(extension)); + return SetValueFromPrintParameterModifier(modifier, value.ToString()); } - public string GetFileFilter() - { - string result = string.Empty; - - foreach (var fileExt in FileExtensions) - { - if (!ReferenceEquals(result, string.Empty)) - { - result += '|'; - } - result += fileExt.Filter; - } + public abstract bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, string value); - return result; + public void Save() + { + SaveAs(); } - public void Dispose() + public abstract void SaveAs(string filePath = null); + + public abstract bool Convert(Type to, string fileFullPath); + public bool Convert(FileFormat to, string fileFullPath) { - Clear(); + return Convert(to.GetType(), fileFullPath); } + #endregion } } diff --git a/PrusaSL1Reader/Helpers.cs b/PrusaSL1Reader/Helpers.cs index b185cd49..f2f93966 100644 --- a/PrusaSL1Reader/Helpers.cs +++ b/PrusaSL1Reader/Helpers.cs @@ -6,21 +6,30 @@ * of this license document, but changing it is not allowed. */ -using System; -using System.Collections.Generic; using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization.Formatters.Binary; using BinarySerialization; +using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; namespace PrusaSL1Reader { + /// + /// A helper class with utilities + /// public static class Helpers { + public static PngEncoder PngEncoder { get; } = new PngEncoder(); + /// + /// Gets the instance + /// public static BinarySerializer Serializer { get; } = new BinarySerializer {Endianness = Endianness.Little }; + + /// + /// Gets a white color of + /// public static Gray8 Gray8White { get; } = new Gray8(255); - public static T ByteToType(BinaryReader reader) + + /*public static T ByteToType(BinaryReader reader) { byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T))); @@ -40,7 +49,7 @@ public static byte[] SerializeToBytes(T item) stream.Seek(0, SeekOrigin.Begin); return stream.ToArray(); } - } + }*/ public static MemoryStream Serialize(object value) { @@ -56,7 +65,7 @@ public static T Deserialize(BinaryReader binaryReader) public static T Deserialize(Stream stream) { - return Helpers.Serializer.Deserialize(stream); + return Serializer.Deserialize(stream); } public static uint WriteFileStream(FileStream fs, MemoryStream stream, uint offset = 0) @@ -74,7 +83,7 @@ public static uint SerializeWriteFileStream(FileStream fs, object value, uint of { using (MemoryStream stream = Helpers.Serialize(value)) { - return (uint)Helpers.WriteFileStream(fs, stream); + return WriteFileStream(fs, stream); } } } diff --git a/PrusaSL1Reader/IFileFormat.cs b/PrusaSL1Reader/IFileFormat.cs index a972b560..629d37fc 100644 --- a/PrusaSL1Reader/IFileFormat.cs +++ b/PrusaSL1Reader/IFileFormat.cs @@ -17,16 +17,53 @@ namespace PrusaSL1Reader /// public interface IFileFormat { + #region Properties + /// + /// Gets the file format type + /// + FileFormat.FileFormatType FileType { get; } + /// /// Gets the valid file extensions for this /// FileExtension[] FileExtensions { get; } + /// + /// Gets the available + /// + FileFormat.PrintParameterModifier[] PrintParameterModifiers { get; } + + /// + /// Gets the file filter for open and save dialogs + /// + string FileFilter { get; } + + /// + /// Gets all valid file extensions in "*.extension1;*.extension2" format + /// + + string FileFilterExtensionsOnly { get; } + /// /// Gets the input file path loaded into this /// string FileFullPath { get; set; } + /// + /// Gets the thumbnails count present in this file format + /// + byte ThumbnailsCount { get; } + + /// + /// Gets the number of created thumbnails + /// + byte CreatedThumbnailsCount { get; } + + /// + /// Gets the thumbnails for this + /// + Image[] Thumbnails { get; set; } + /// /// Gets the image width resolution /// @@ -38,51 +75,112 @@ public interface IFileFormat uint ResolutionY { get; } /// - /// Gets the thumbnails count present in this file format + /// Gets Layer Height in mm /// - byte ThumbnailsCount { get; } + float LayerHeight { get; } /// - /// Gets the thumbnails for this + /// Gets Total Height in mm /// - Image[] Thumbnails { get; set; } - - FileFormat.PrintParameterModifier[] PrintParameterModifiers { get; } + float TotalHeight { get; } /// - /// Number of layers present in this file + /// Gets the number of layers present in this file /// uint LayerCount { get; } + + /// + /// Gets the number of initial layer count + /// ushort InitialLayerCount { get; } + + /// + /// Gets the initial exposure time for + /// float InitialExposureTime { get; } + + /// + /// Gets the normal layer exposure time + /// float LayerExposureTime { get; } + + /// + /// Gets the height in mm to retract between layers + /// + float ZRetractHeight { get; } + + /// + /// Gets the speed in mm/min for the retracts + /// + float ZRetractSpeed { get; } + + /// + /// Gets the speed in mm/min for the detracts + /// + float ZDetractSpeed { get; } + + /// + /// Gets the estimate print time in seconds + /// float PrintTime { get; } + + /// + /// Gets the estimate used material in ml + /// float UsedMaterial { get; } + + /// + /// Gets the estimate material cost + /// float MaterialCost { get; } + + /// + /// Gets the material name + /// string MaterialName { get; } - string MachineName { get; } /// - /// Layer Height in mm + /// Gets the machine name /// - float LayerHeight { get; } + string MachineName { get; } - float TotalHeight { get; } + /// + /// Gets the GCode, returns null if not supported + /// + string GCode { get; set; } /// /// Get all configuration objects with properties and values /// object[] Configs { get; } - object GetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier); - bool SetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier, object value); - bool SetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier, string value); - /// - /// If this file is valid to read + /// Gets if this file is valid to read /// bool IsValid { get; } + #endregion + + #region Methods + /// + /// Clears all definitions and properties, it also dispose valid candidates + /// + void Clear(); + + /// + /// Validate if a file is a valid + /// + /// Full file path + void FileValidation(string fileFullPath); + + /// + /// Checks if a extension is valid under the + /// + /// Extension to check + /// True if is a full file path, otherwise false for extension only + /// True if valid, otherwise false + bool IsExtensionValid(string extension, bool isFilePath = false); + /// /// Begin encode to an output file /// @@ -117,17 +215,6 @@ public interface IFileFormat void Extract(string path, bool emptyFirst = true, bool genericConfigExtract = false, bool genericLayersExtract = false); - /// - /// Saves current configuration on input file - /// - void Save(); - - /// - /// Saves current configuration on a copy - /// - /// File path to save copy as, use null to overwrite active file (Same as ) - void SaveAs(string filePath = null); - /// /// Gets a image from layer /// @@ -143,9 +230,38 @@ void Extract(string path, bool emptyFirst = true, bool genericConfigExtract = fa float GetHeightFromLayer(uint layerNum); /// - /// Clears all definitions and properties, it also dispose valid candidates + /// Gets the value attributed to /// - void Clear(); + /// Modifier to use + /// A value + object GetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier); + + /// + /// Sets a property value attributed to + /// + /// Modifier to use + /// Value to set + /// True if set, otherwise false = not found + bool SetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier, object value); + + /// + /// Sets a property value attributed to + /// + /// Modifier to use + /// Value to set + /// True if set, otherwise false = not found + bool SetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier, string value); + + /// + /// Saves current configuration on input file + /// + void Save(); + + /// + /// Saves current configuration on a copy + /// + /// File path to save copy as, use null to overwrite active file (Same as ) + void SaveAs(string filePath = null); /// /// Converts this file type to another file type @@ -162,5 +278,6 @@ void Extract(string path, bool emptyFirst = true, bool genericConfigExtract = fa /// Output path file /// True if convert succeed, otherwise false bool Convert(FileFormat to, string fileFullPath); + #endregion } } diff --git a/PrusaSL1Reader/LayerLine.cs b/PrusaSL1Reader/LayerLine.cs deleted file mode 100644 index d701c1d6..00000000 --- a/PrusaSL1Reader/LayerLine.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace PrusaSL1Reader -{ - /// - /// Represents a line, only white pixels - /// - public class LayerLine - { - /// - /// Gets the x start position - /// - public uint X { get; } - - /// - /// Gets the x end position - /// - public uint X2 => X + Length; - - /// - /// Gets the y position - /// - public uint Y { get; } - - /// - /// Number of pixels to fill - /// - public uint Length { get; } - - public LayerLine(uint x, uint y, uint length) - { - X = x; - Y = y; - Length = length; - } - } -} diff --git a/PrusaSL1Reader/PrusaSL1Reader.csproj b/PrusaSL1Reader/PrusaSL1Reader.csproj index cb5757a2..2562899e 100644 --- a/PrusaSL1Reader/PrusaSL1Reader.csproj +++ b/PrusaSL1Reader/PrusaSL1Reader.csproj @@ -7,9 +7,9 @@ https://github.com/sn4k3/PrusaSL1Viewer https://github.com/sn4k3/PrusaSL1Viewer - 0.2.2.0 - 0.2.2.0 - 0.2.2 + 0.3.0.0 + 0.3.0.0 + 0.3.0 Open, view, edit, extract and convert DLP/SLA files generated from Slicers @@ -19,6 +19,7 @@ + diff --git a/PrusaSL1Reader/SL1File.cs b/PrusaSL1Reader/SL1File.cs index 31762c3f..1a0a8772 100644 --- a/PrusaSL1Reader/SL1File.cs +++ b/PrusaSL1Reader/SL1File.cs @@ -13,12 +13,13 @@ using System.IO.Compression; using System.Linq; using System.Reflection; +using PrusaSL1Reader.Extensions; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; namespace PrusaSL1Reader { - public class SL1File : FileFormat, IEquatable + public class SL1File : FileFormat { #region Sub Classes @@ -270,24 +271,31 @@ public override string ToString() public Statistics Statistics { get; } = new Statistics(); - #endregion - - #region Overrides - - public override string FileFullPath { get; set; } - public override uint ResolutionY => PrinterSettings.DisplayPixelsY; + public override FileFormatType FileType => FileFormatType.Archive; - public override byte ThumbnailsCount { get; } = 2; - public override Image[] Thumbnails { get; set; } + public override FileExtension[] FileExtensions { get; } = { + new FileExtension("sl1", "Prusa SL1 Files") + }; - public override PrintParameterModifier[] PrintParameterModifiers => new[] - { + public override PrintParameterModifier[] PrintParameterModifiers { get; } = { PrintParameterModifier.InitialLayerCount, PrintParameterModifier.InitialExposureSeconds, PrintParameterModifier.ExposureSeconds, }; + public override string FileFullPath { get; set; } + + public override byte ThumbnailsCount { get; } = 2; + + public override Image[] Thumbnails { get; set; } + + public override uint ResolutionX => PrinterSettings.DisplayPixelsX; + + public override uint ResolutionY => PrinterSettings.DisplayPixelsY; + + public override float LayerHeight => OutputConfigSettings.LayerHeight; + public override uint LayerCount => OutputConfigSettings.NumFast; public override ushort InitialLayerCount => OutputConfigSettings.NumFade; @@ -296,81 +304,105 @@ public override string ToString() public override float LayerExposureTime => OutputConfigSettings.ExpTime; + public override float ZRetractHeight { get; } = 0; + + public override float ZRetractSpeed { get; } = 0; + + public override float ZDetractSpeed { get; } = 0; + public override float PrintTime => OutputConfigSettings.PrintTime; public override float UsedMaterial => OutputConfigSettings.UsedMaterial; - public override float MaterialCost => OutputConfigSettings.UsedMaterial * MaterialSettings.BottleCost / MaterialSettings.BottleVolume; + public override float MaterialCost => (float) Math.Round(OutputConfigSettings.UsedMaterial * MaterialSettings.BottleCost / MaterialSettings.BottleVolume, 2); public override string MaterialName => OutputConfigSettings.MaterialName; public override string MachineName => PrinterSettings.PrinterSettingsId; - public override float LayerHeight => OutputConfigSettings.LayerHeight; public override object[] Configs => new object[] { PrinterSettings, MaterialSettings, PrintSettings, OutputConfigSettings }; - public override bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, string value) - { - if (ReferenceEquals(modifier, PrintParameterModifier.InitialLayerCount)) - { - PrintSettings.FadedLayers = - OutputConfigSettings.NumFade = value.Convert(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.InitialExposureSeconds)) - { - MaterialSettings.InitialExposureTime = - OutputConfigSettings.ExpTimeFirst = value.Convert(); - return true; - } - if (ReferenceEquals(modifier, PrintParameterModifier.ExposureSeconds)) - { - MaterialSettings.ExposureTime = - OutputConfigSettings.ExpTime = value.Convert(); - return true; - } + #endregion - return false; + #region Overrides + public override string ToString() + { + return $"{nameof(FileFullPath)}: {FileFullPath}, {nameof(MaterialSettings)}: {MaterialSettings}, {nameof(PrintSettings)}: {PrintSettings}, {nameof(OutputConfigSettings)}: {OutputConfigSettings}, {nameof(Statistics)}: {Statistics}, {nameof(LayerCount)}: {LayerCount}, {nameof(TotalHeight)}: {TotalHeight}"; } - public override FileExtension[] FileExtensions { get; } = { - new FileExtension("sl1", "Prusa SL1 Files") - }; - - public override uint ResolutionX => PrinterSettings.DisplayPixelsX; + #endregion - public override bool Equals(object obj) + #region Contructors + public SL1File() { } + public SL1File(string fileFullPath) { - return Equals(obj as SL1File); + Decode(fileFullPath); } + #endregion - public bool Equals(SL1File other) + #region Static Methods + public static string IniKeyToMemberName(string keyName) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return FileFullPath == other.FileFullPath; + string memberName = string.Empty; + string[] objs = keyName.Split('_'); + return objs.Aggregate(memberName, (current, obj) => current + obj.FirstCharToUpper()); } - public override int GetHashCode() + public static string MemberNameToIniKey(string memberName) { - return (FileFullPath != null ? FileFullPath.GetHashCode() : 0); - } + string iniKey = char.ToLowerInvariant(memberName[0]).ToString(); + for (var i = 1; i < memberName.Length; i++) + { + iniKey += char.IsUpper(memberName[i]) + ? $"_{char.ToLowerInvariant(memberName[i])}" + : memberName[i].ToString(); + } - public override string ToString() - { - return $"{nameof(FileFullPath)}: {FileFullPath}, {nameof(MaterialSettings)}: {MaterialSettings}, {nameof(PrintSettings)}: {PrintSettings}, {nameof(OutputConfigSettings)}: {OutputConfigSettings}, {nameof(Statistics)}: {Statistics}, {nameof(LayerCount)}: {LayerCount}, {nameof(TotalHeight)}: {TotalHeight}"; - } + if (iniKey.EndsWith("_")) + iniKey.Remove(iniKey.Length - 1); - #endregion + return iniKey; + } - #region Contructors - public SL1File() { } - public SL1File(string fileFullPath) + public static bool SetValue(PropertyInfo attribute, object obj, string value) { - Decode(fileFullPath); + var name = attribute.PropertyType.Name.ToLower(); + switch (name) + { + case "string": + attribute.SetValue(obj, value.Convert()); + return true; + case "boolean": + attribute.SetValue(obj, !value.Equals(0)); + return true; + case "byte": + attribute.SetValue(obj, value.Convert()); + return true; + case "uint16": + attribute.SetValue(obj, value.Convert()); + return true; + case "single": + attribute.SetValue(obj, (float)Math.Round(float.Parse(value, CultureInfo.InvariantCulture.NumberFormat), 2)); + return true; + case "double": + attribute.SetValue(obj, Math.Round(double.Parse(value, CultureInfo.InvariantCulture.NumberFormat), 2)); + return true; + case "decimal": + attribute.SetValue(obj, (decimal)Math.Round(decimal.Parse(value, CultureInfo.InvariantCulture.NumberFormat), 2)); + return true; + default: + throw new Exception($"Data type '{name}' not recognized, contact developer."); + } } #endregion #region Methods + public override void Clear() + { + base.Clear(); + InputFile?.Dispose(); + LayerEntries.Clear(); + Statistics.Clear(); + } public override void BeginEncode(string fileFullPath) { @@ -400,14 +432,7 @@ public override void Decode(string fileFullPath) Statistics.ExecutionTime.Restart(); - var parseObjects = new object[] - { - PrinterSettings, - MaterialSettings, - PrintSettings, - OutputConfigSettings, - }; - InputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read); + InputFile = ZipFile.OpenRead(FileFullPath); byte thumbnailIndex = 0; foreach (ZipArchiveEntry entity in InputFile.Entries) { @@ -426,7 +451,7 @@ public override void Decode(string fileFullPath) var fieldName = IniKeyToMemberName(keyValue[0]); bool foundMember = false; - foreach (var obj in parseObjects) + foreach (var obj in Configs) { var attribute = obj.GetType().GetProperty(fieldName); if (ReferenceEquals(attribute, null)) continue; @@ -472,8 +497,37 @@ public override void Decode(string fileFullPath) public override void Extract(string path, bool emptyFirst = true, bool genericConfigExtract = false, bool genericLayersExtract = false) { - base.Extract(path, emptyFirst, genericConfigExtract); - InputFile.ExtractToDirectory(path); + base.Extract(path, emptyFirst, genericConfigExtract, false); + InputFile?.ExtractToDirectory(path); + } + + public override Image GetLayerImage(uint layerIndex) + { + return Image.Load(LayerEntries[(int)layerIndex].Open()); + } + + public override bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, string value) + { + if (ReferenceEquals(modifier, PrintParameterModifier.InitialLayerCount)) + { + PrintSettings.FadedLayers = + OutputConfigSettings.NumFade = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.InitialExposureSeconds)) + { + MaterialSettings.InitialExposureTime = + OutputConfigSettings.ExpTimeFirst = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.ExposureSeconds)) + { + MaterialSettings.ExposureTime = + OutputConfigSettings.ExpTime = value.Convert(); + return true; + } + + return false; } public override void SaveAs(string filePath = null) @@ -483,7 +537,7 @@ public override void SaveAs(string filePath = null) { File.Copy(FileFullPath, filePath, true); FileFullPath = filePath; - + } using (InputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update)) @@ -531,24 +585,6 @@ public override void SaveAs(string filePath = null) } - public override Image GetLayerImage(uint layerIndex) - { - return Image.Load(LayerEntries[(int)layerIndex].Open()); - } - - public override float GetHeightFromLayer(uint layerNum) - { - return (float)Math.Round(MaterialSettings.InitialLayerHeight + (layerNum - 1) * OutputConfigSettings.LayerHeight, 2); - } - - public override void Clear() - { - base.Clear(); - InputFile?.Dispose(); - LayerEntries.Clear(); - Statistics.Clear(); - } - public override bool Convert(Type to, string fileFullPath) { if (!IsValid) return false; @@ -615,6 +651,98 @@ public override bool Convert(Type to, string fileFullPath) } file.EndEncode(); + + return true; + } + + if (to == typeof(ZCodexFile)) + { + TimeSpan ts = new TimeSpan(0, 0, (int)PrintTime); + ZCodexFile file = new ZCodexFile + { + ResinMetadataSettings = new ZCodexFile.ResinMetadata + { + MaterialId = 2, + Material = MaterialName, + AdditionalSupportLayerTime = 0, + BottomLayersNumber = InitialLayerCount, + BottomLayersTime = (uint)(InitialExposureTime*1000), + LayerTime = (uint)(LayerExposureTime * 1000), + DisableSettingsChanges = false, + LayerThickness = LayerHeight, + PrintTime = (uint)PrintTime, + TotalLayersCount = LayerCount, + TotalMaterialVolumeUsed = UsedMaterial, + TotalMaterialWeightUsed = UsedMaterial, + }, + UserSettings = new ZCodexFile.UserSettingsdata + { + Printer = MachineName, + BottomLayersCount = InitialLayerCount, + PrintTime = $"{ts.Hours}h {ts.Minutes}m", + LayerExposureTime = (uint)(LayerExposureTime * 1000), + BottomLayerExposureTime = (uint)(InitialExposureTime * 1000), + MaterialId = 2, + LayerThickness = $"{LayerHeight} mm", + AntiAliasing = 0, + CrossSupportEnabled = 1, + ExposureOffTime = LookupCustomValue("ExposureOffTime", 5)*1000, + HollowEnabled = PrintSettings.HollowingEnable ? (byte)1 : (byte)0, + HollowThickness = PrintSettings.HollowingMinThickness, + InfillDensity = 0, + IsAdvanced = 0, + MaterialType = MaterialName, + MaterialVolume = UsedMaterial, + MaxLayer = LayerCount-1, + ModelLiftEnabled = PrintSettings.SupportObjectElevation > 0 ? (byte)1 : (byte)0, + ModelLiftHeight = PrintSettings.SupportObjectElevation, + RaftEnabled = PrintSettings.SupportBaseHeight > 0 ? (byte)1 : (byte)0, + RaftHeight = PrintSettings.SupportBaseHeight, + RaftOffset = 0, + SupportAdditionalExposureEnabled = 0, + SupportAdditionalExposureTime = 0, + XCorrection = PrinterSettings.AbsoluteCorrection, + YCorrection = PrinterSettings.AbsoluteCorrection, + ZLiftDistance = (float)Math.Round(LookupCustomValue("ZLiftDistance", 5), 2), + ZLiftFeedRate = (float)Math.Round(LookupCustomValue("ZLiftFeedRate", 100), 2), + ZLiftRetractRate = (float)Math.Round(LookupCustomValue("ZLiftRetractRate", 100), 2), + }, + ZCodeMetadataSettings = new ZCodexFile.ZCodeMetadata + { + PrintTime = (uint)PrintTime, + PrinterName = MachineName, + Materials = new List() + { + new ZCodexFile.ZCodeMetadata.MaterialsData + { + Name = MaterialName, + ExtruderType = "MAIN", + Id = 0, + Usage = 0, + Temperature = 0 + } + }, + }, + Thumbnails = Thumbnails, + }; + + float usedMaterial = UsedMaterial / LayerCount; + for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++) + { + file.ResinMetadataSettings.Layers.Add(new ZCodexFile.ResinMetadata.LayerData + { + Layer = layerIndex, + UsedMaterialVolume = usedMaterial + }); + } + + file.BeginEncode(fileFullPath); + for (uint layerIndex = 0; layerIndex < LayerCount; layerIndex++) + { + file.InsertLayerImageEncode(GetLayerImage(layerIndex), layerIndex); + } + file.EndEncode(); + return true; } return false; @@ -622,13 +750,12 @@ public override bool Convert(Type to, string fileFullPath) public T LookupCustomValue(string name, T defaultValue, bool existsOnly = false) { + if (string.IsNullOrEmpty(PrinterSettings.PrinterNotes)) return defaultValue; string result = string.Empty; if(!existsOnly) name += '_'; int index = PrinterSettings.PrinterNotes.IndexOf(name, StringComparison.Ordinal); - - int startIndex = index + name.Length; if (index < 0 || PrinterSettings.PrinterNotes.Length < startIndex) return defaultValue; @@ -636,70 +763,17 @@ public T LookupCustomValue(string name, T defaultValue, bool existsOnly = fal for (int i = startIndex; i < PrinterSettings.PrinterNotes.Length; i++) { char c = PrinterSettings.PrinterNotes[i]; - if (!Char.IsLetterOrDigit(c) && c != '.') + if (!char.IsLetterOrDigit(c) && c != '.') { break; } - result += PrinterSettings.PrinterNotes[i]; + result += c; } - return result.Convert(); + return string.IsNullOrWhiteSpace(result) ? defaultValue : result.Convert(); } #endregion - - #region Static Methods - public static string IniKeyToMemberName(string keyName) - { - string memberName = string.Empty; - string[] objs = keyName.Split('_'); - return objs.Aggregate(memberName, (current, obj) => current + obj.FirstCharToUpper()); - } - - public static string MemberNameToIniKey(string memberName) - { - string iniKey = char.ToLowerInvariant(memberName[0]).ToString(); - for (var i = 1; i < memberName.Length; i++) - { - iniKey += char.IsUpper(memberName[i]) - ? $"_{char.ToLowerInvariant(memberName[i])}" - : memberName[i].ToString(); - } - - if (iniKey.EndsWith("_")) - iniKey.Remove(iniKey.Length-1); - - return iniKey; - } - - public static bool SetValue(PropertyInfo attribute, object obj, string value) - { - var name = attribute.PropertyType.Name.ToLower(); - switch (name) - { - case "string": - attribute.SetValue(obj, value.Convert()); - return true; - case "boolean": - attribute.SetValue(obj, !value.Equals(0)); - return true; - case "byte": - attribute.SetValue(obj, value.Convert()); - return true; - case "uint16": - attribute.SetValue(obj, value.Convert()); - return true; - case "single": - attribute.SetValue(obj, float.Parse(value, CultureInfo.InvariantCulture.NumberFormat)); - return true; - case "double": - attribute.SetValue(obj, double.Parse(value, CultureInfo.InvariantCulture.NumberFormat)); - return true; - default: - throw new Exception($"Data type '{name}' not recognized, contact developer."); - } - } - #endregion } } diff --git a/PrusaSL1Reader/UniversalLayer.cs b/PrusaSL1Reader/UniversalLayer.cs index da3a58e9..fb41ef55 100644 --- a/PrusaSL1Reader/UniversalLayer.cs +++ b/PrusaSL1Reader/UniversalLayer.cs @@ -1,12 +1,52 @@ -using System.Collections.Generic; +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ +using System.Collections.Generic; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; namespace PrusaSL1Reader { - public class UniversalLayer : List + public class UniversalLayer : List { + /// + /// Represents a line, only white pixels + /// + public class LayerLine + { + /// + /// Gets the x start position + /// + public uint X { get; } + + /// + /// Gets the x end position + /// + public uint X2 => X + Length; + + /// + /// Gets the y position + /// + public uint Y { get; } + + /// + /// Number of pixels to fill + /// + public uint Length { get; } + + public LayerLine(uint x, uint y, uint length) + { + X = x; + Y = y; + Length = length; + } + } + public List Lines { get; } = new List(); public UniversalLayer(Image image) diff --git a/PrusaSL1Reader/ZCodexFile.cs b/PrusaSL1Reader/ZCodexFile.cs new file mode 100644 index 00000000..e69a39b9 --- /dev/null +++ b/PrusaSL1Reader/ZCodexFile.cs @@ -0,0 +1,461 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using PrusaSL1Reader.Extensions; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.PixelFormats; + +namespace PrusaSL1Reader +{ + public class ZCodexFile : FileFormat + { + #region Constants + + private const string GCodeStart = "G28\nG21\nG91\nM17\n"; + private const string GCodeKeywordSlice = ""; + private const string GCodeKeywordDelayBlank = ""; + private const string GCodeKeywordDelayModel = ""; + private const string GCodeKeywordDelaySupportPart = ""; + private const string GCodeKeywordDelaySupportFull = ""; + private const string FolderImages = "ResinSlicesData"; + private const string FolderImageName = "Slice"; + #endregion + + #region Sub Classes + + public class ResinMetadata + { + public class LayerData + { + public uint Layer { get; set; } + public float UsedMaterialVolume { get; set; } + + } + + public string Guid { get; set; } = "07452AC2-7494-4576-BA60-BFEA8815F917"; + public string Material { get; set; } + public uint MaterialId { get; set; } + public float LayerThickness { get; set; } + public uint PrintTime { get; set; } + public uint LayerTime { get; set; } + public uint BottomLayersTime { get; set; } + public uint AdditionalSupportLayerTime { get; set; } + public ushort BottomLayersNumber { get; set; } + public uint BlankingLayerTime { get; set; } + public float TotalMaterialVolumeUsed { get; set; } + public float TotalMaterialWeightUsed { get; set; } + public uint TotalLayersCount { get; set; } + public bool DisableSettingsChanges { get; set; } + + public List Layers { get; set; } = new List(); + } + + public class UserSettingsdata + { + public uint MaxLayer { get; set; } + public string PrintTime { get; set; } + public float MaterialVolume { get; set; } + public byte IsAdvanced { get; set; } + public string Printer { get; set; } = "Zortrax Inkspire"; + public string MaterialType { get; set; } + public uint MaterialId { get; set; } + public string LayerThickness { get; set; } + public byte RaftEnabled { get; set; } + public float RaftHeight { get; set; } + public float RaftOffset { get; set; } + public byte ModelLiftEnabled { get; set; } + public float ModelLiftHeight { get; set; } + public byte CrossSupportEnabled { get; set; } + public uint LayerExposureTime { get; set; } + //public uint LayerThicknessesDisplayTime { get; set; } arr + public uint ExposureOffTime { get; set; } + public uint BottomLayerExposureTime { get; set; } + public uint BottomLayersCount { get; set; } + public byte SupportAdditionalExposureEnabled { get; set; } + public uint SupportAdditionalExposureTime { get; set; } + public float ZLiftDistance { get; set; } + public float ZLiftRetractRate { get; set; } + public float ZLiftFeedRate { get; set; } + public byte AntiAliasing { get; set; } + public byte XCorrection { get; set; } + public byte YCorrection { get; set; } + public byte HollowEnabled { get; set; } + public float HollowThickness { get; set; } + public byte InfillDensity { get; set; } + } + + public class ZCodeMetadata + { + public class MaterialsData + { + public string ExtruderType { get; set; } + public uint Id { get; set; } + public string Name { get; set; } + public uint Usage { get; set; } + public uint Temperature { get; set; } + } + + public string ZCodexVersion { get; set; } = "2.0.0.0"; + public string SoftwareVersion { get; set; } = "2.12.2.0"; + public string MinFirmwareVersion { get; set; } = "20013"; + public uint PrinterModelEnumId { get; set; } = 40; + public string PrinterName { get; set; } = "Inkspire"; + public List Materials { get; set; } + public byte HeatbedTemperature { get; set; } + public byte ChamberTemperature { get; set; } + public uint CommandCount { get; set; } + public uint PrintTime { get; set; } + public float NozzleDiameter { get; set; } + public string PrintBoundingBox { get; set; } + public string Pauses { get; set; } + public string MaterialUsages { get; set; } + } + + public class Layer + { + public int SupportLayerFileIndex { get; set; } = -1; + public int LayerFileIndex { get; set; } = -1; + public ZipArchiveEntry SupportLayerEntry { get; set; } + public ZipArchiveEntry LayerEntry { get; set; } + + public bool HaveSupportLayer => !ReferenceEquals(SupportLayerEntry, null); + } + + #endregion + + #region Properties + public ZipArchive InputFile { get; private set; } + public ZipArchive OutputFile { get; private set; } + + + public ResinMetadata ResinMetadataSettings { get; set; } + public UserSettingsdata UserSettings { get; set; } + public ZCodeMetadata ZCodeMetadataSettings { get; set; } + + public List LayerEntries { get; } = new List(); + public List Layers { get; } = new List(); + + public override FileFormatType FileType => FileFormatType.Archive; + + public override FileExtension[] FileExtensions { get; } = { + new FileExtension("zcodex", "ZCodex/Z-Suite Files") + }; + + public override PrintParameterModifier[] PrintParameterModifiers { get; } = { + PrintParameterModifier.InitialLayerCount, + PrintParameterModifier.InitialExposureSeconds, + PrintParameterModifier.ExposureSeconds, + + + PrintParameterModifier.ZRetractHeight, + PrintParameterModifier.ZRetractSpeed, + PrintParameterModifier.ZDetractSpeed, + }; + + public override string FileFullPath { get; set; } + + public override byte ThumbnailsCount { get; } = 1; + + public override Image[] Thumbnails { get; set; } + + public override uint ResolutionX => 1440; + + public override uint ResolutionY => 2560; + + public override float LayerHeight => ResinMetadataSettings.LayerThickness; + + public override uint LayerCount => ResinMetadataSettings.TotalLayersCount; + + public override ushort InitialLayerCount => ResinMetadataSettings.BottomLayersNumber; + + public override float InitialExposureTime => UserSettings.BottomLayerExposureTime / 1000; + + public override float LayerExposureTime => UserSettings.LayerExposureTime / 1000; + public override float ZRetractHeight => UserSettings.ZLiftDistance; + public override float ZRetractSpeed => (uint) UserSettings.ZLiftRetractRate; + public override float ZDetractSpeed => (uint) UserSettings.ZLiftFeedRate; + + public override float PrintTime => ResinMetadataSettings.PrintTime; + + public override float UsedMaterial => ResinMetadataSettings.TotalMaterialVolumeUsed; + + public override float MaterialCost => 0; + + public override string MaterialName => ResinMetadataSettings.Material; + + public override string MachineName => ZCodeMetadataSettings.PrinterName; + + public override string GCode { get; set; } + + public override object[] Configs => new[] {(object) ResinMetadataSettings, UserSettings, ZCodeMetadataSettings}; + #endregion + + #region Methods + + public override void Clear() + { + base.Clear(); + InputFile?.Dispose(); + OutputFile?.Dispose(); + Layers.Clear(); + LayerEntries.Clear(); + GCode = null; + } + + public override void BeginEncode(string fileFullPath) + { + base.BeginEncode(fileFullPath); + OutputFile = ZipFile.Open(fileFullPath, ZipArchiveMode.Create); + + OutputFile.PutFileContent("ResinMetadata", JsonConvert.SerializeObject(ResinMetadataSettings), false); + OutputFile.PutFileContent("UserSettingsData", JsonConvert.SerializeObject(UserSettings), false); + OutputFile.PutFileContent("ZCodeMetadata", JsonConvert.SerializeObject(ZCodeMetadataSettings), false); + + if (CreatedThumbnailsCount > 0) + { + using (Stream stream = OutputFile.CreateEntry("Preview.png").Open()) + { + Thumbnails[0].Save(stream, Helpers.PngEncoder); + stream.Close(); + } + } + + GCode = GCodeStart; + } + + public override void InsertLayerImageEncode(Image image, uint layerIndex) + { + GCode += $"{GCodeKeywordSlice} {layerIndex}\n" + + $"G1 Z{UserSettings.ZLiftDistance} F{UserSettings.ZLiftRetractRate}\n" + + $"G1 Z-{UserSettings.ZLiftDistance - LayerHeight} F{UserSettings.ZLiftFeedRate}\n" + + $"{GCodeKeywordDelayBlank}\n" + + "M106 S255\n" + + $"{GCodeKeywordDelayModel}\n" + + "M106 S0\n"; + + var layerimagePath = $"{FolderImages}/{FolderImageName}{layerIndex:D5}.png"; + using (Stream stream = OutputFile.CreateEntry(layerimagePath).Open()) + { + image.Save(stream, Helpers.PngEncoder); + stream.Close(); + } + } + + public override void EndEncode() + { + GCode += $"G1 Z40.0 F{UserSettings.ZLiftFeedRate}\n" + + "M18\n"; + OutputFile.PutFileContent("ResinGCodeData", GCode, false); + + OutputFile.Dispose(); + } + + public override void Decode(string fileFullPath) + { + base.Decode(fileFullPath); + + FileFullPath = fileFullPath; + InputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Read); + var entry = InputFile.GetEntry("ResinMetadata"); + if (ReferenceEquals(entry, null)) + { + Clear(); + throw new FileLoadException("ResinMetadata not found", fileFullPath); + } + using (TextReader tr = new StreamReader(entry.Open())) + { + ResinMetadataSettings = JsonConvert.DeserializeObject(tr.ReadToEnd()); + tr.Close(); + } + + entry = InputFile.GetEntry("UserSettingsData"); + if (ReferenceEquals(entry, null)) + { + Clear(); + throw new FileLoadException("UserSettingsData not found", fileFullPath); + } + using (TextReader tr = new StreamReader(entry.Open())) + { + UserSettings = JsonConvert.DeserializeObject(tr.ReadToEnd()); + tr.Close(); + } + + entry = InputFile.GetEntry("ZCodeMetadata"); + if (ReferenceEquals(entry, null)) + { + Clear(); + throw new FileLoadException("ZCodeMetadata not found", fileFullPath); + } + using (TextReader tr = new StreamReader(entry.Open())) + { + ZCodeMetadataSettings = JsonConvert.DeserializeObject(tr.ReadToEnd()); + tr.Close(); + } + + entry = InputFile.GetEntry("ResinGCodeData"); + if (ReferenceEquals(entry, null)) + { + Clear(); + throw new FileLoadException("ResinGCodeData not found", fileFullPath); + } + + GCode = string.Empty; + using (TextReader tr = new StreamReader(entry.Open())) + { + string line; + int layerIndex = 0; + int layerFileIndex = 0; + string layerimagePath = null; + while (!ReferenceEquals(line = tr.ReadLine(), null)) + { + GCode += line + Environment.NewLine; + if (line.StartsWith(GCodeKeywordSlice)) + { + layerFileIndex = int.Parse(line.Substring(GCodeKeywordSlice.Length)); + layerimagePath = $"{FolderImages}/{FolderImageName}{layerFileIndex:D5}.png"; + if (Layers.Count - 1 < layerIndex) Layers.Add(new Layer()); + continue; + } + + if (line.StartsWith(GCodeKeywordDelaySupportPart)) + { + Layers[layerIndex].SupportLayerFileIndex = layerFileIndex; + Layers[layerIndex].SupportLayerEntry = InputFile.GetEntry(layerimagePath); + continue; + } + + if (line.StartsWith(GCodeKeywordDelaySupportFull) || line.StartsWith(GCodeKeywordDelayModel)) + { + Layers[layerIndex].LayerFileIndex = layerFileIndex; + Layers[layerIndex].LayerEntry = InputFile.GetEntry(layerimagePath); + layerIndex++; + continue; + } + } + tr.Close(); + } + + foreach (ZipArchiveEntry entity in InputFile.Entries) + { + if (entity.Name.EndsWith(".png")) + { + if (entity.Name.Equals("Preview.png")) + { + using (Stream stream = entity.Open()) + { + Thumbnails[0] = Image.Load(stream); + stream.Close(); + } + + continue; + } + + LayerEntries.Add(entity); + } + } + } + + public override void Extract(string path, bool emptyFirst = true, bool genericConfigExtract = false, bool genericLayersExtract = false) + { + base.Extract(path, emptyFirst, genericConfigExtract, false); + InputFile?.ExtractToDirectory(path); + } + + public override Image GetLayerImage(uint layerIndex) + { + return Image.Load(Layers[(int)layerIndex].LayerEntry.Open()); + } + + public override bool SetValueFromPrintParameterModifier(PrintParameterModifier modifier, string value) + { + if (ReferenceEquals(modifier, PrintParameterModifier.InitialLayerCount)) + { + UserSettings.BottomLayersCount = + ResinMetadataSettings.BottomLayersNumber = value.Convert(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.InitialExposureSeconds)) + { + ResinMetadataSettings.BottomLayersTime = + UserSettings.BottomLayerExposureTime = value.Convert()*1000; + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.ExposureSeconds)) + { + ResinMetadataSettings.LayerTime = + UserSettings.LayerExposureTime = value.Convert()*1000; + return true; + } + + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractHeight)) + { + UserSettings.ZLiftDistance = value.Convert(); + UpdateGCode(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.ZRetractSpeed)) + { + UserSettings.ZLiftRetractRate = value.Convert(); + UpdateGCode(); + return true; + } + if (ReferenceEquals(modifier, PrintParameterModifier.ZDetractSpeed)) + { + UserSettings.ZLiftFeedRate = value.Convert(); + UpdateGCode(); + return true; + } + + return false; + } + + public override void SaveAs(string filePath = null) + { + InputFile.Dispose(); + if (!string.IsNullOrEmpty(filePath)) + { + File.Copy(FileFullPath, filePath, true); + FileFullPath = filePath; + + } + + using (InputFile = ZipFile.Open(FileFullPath, ZipArchiveMode.Update)) + { + InputFile.PutFileContent("ResinMetadata", JsonConvert.SerializeObject(ResinMetadataSettings)); + InputFile.PutFileContent("UserSettingsData", JsonConvert.SerializeObject(UserSettings)); + InputFile.PutFileContent("ZCodeMetadata", JsonConvert.SerializeObject(ZCodeMetadataSettings)); + InputFile.PutFileContent("ResinGCodeData", GCode); + } + + Decode(FileFullPath); + } + + public override bool Convert(Type to, string fileFullPath) + { + throw new NotImplementedException(); + } + + private void UpdateGCode() + { + GCode = Regex.Replace(GCode, @"Z[+]?([0-9]*\.[0-9]+|[0-9]+) F[+]?([0-9]*\.[0-9]+|[0-9]+)", + $"Z{UserSettings.ZLiftDistance} F{UserSettings.ZLiftRetractRate}"); + + GCode = Regex.Replace(GCode, @"Z-[-]?([0-9]*\.[0-9]+|[0-9]+) F[+]?([0-9]*\.[0-9]+|[0-9]+)", + $"Z-{UserSettings.ZLiftDistance - LayerHeight} F{UserSettings.ZLiftFeedRate}"); + + } + #endregion + } +} diff --git a/PrusaSL1Viewer.sln b/PrusaSL1Viewer.sln index f6130a6d..4253ca5e 100644 --- a/PrusaSL1Viewer.sln +++ b/PrusaSL1Viewer.sln @@ -8,7 +8,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrusaSL1Viewer", "PrusaSL1V {53B884CA-E640-4171-8AA2-03935AC076D2} = {53B884CA-E640-4171-8AA2-03935AC076D2} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrusaSL1Reader", "PrusaSL1Reader\PrusaSL1Reader.csproj", "{53B884CA-E640-4171-8AA2-03935AC076D2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PrusaSL1Reader", "PrusaSL1Reader\PrusaSL1Reader.csproj", "{53B884CA-E640-4171-8AA2-03935AC076D2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/PrusaSL1Viewer/FrmAbout.Designer.cs b/PrusaSL1Viewer/FrmAbout.Designer.cs index 96be02ed..ff9e317f 100644 --- a/PrusaSL1Viewer/FrmAbout.Designer.cs +++ b/PrusaSL1Viewer/FrmAbout.Designer.cs @@ -52,7 +52,8 @@ private void InitializeComponent() this.tableLayoutPanel.Controls.Add(this.textBoxDescription, 1, 4); this.tableLayoutPanel.Controls.Add(this.okButton, 1, 5); this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9); + this.tableLayoutPanel.Location = new System.Drawing.Point(14, 14); + this.tableLayoutPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.tableLayoutPanel.Name = "tableLayoutPanel"; this.tableLayoutPanel.RowCount = 6; this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); @@ -61,17 +62,18 @@ private void InitializeComponent() this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); - this.tableLayoutPanel.Size = new System.Drawing.Size(670, 254); + this.tableLayoutPanel.Size = new System.Drawing.Size(1004, 390); this.tableLayoutPanel.TabIndex = 0; // // logoPictureBox // this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; this.logoPictureBox.Image = global::PrusaSL1Viewer.Properties.Resources.PrusaSL1Viewer; - this.logoPictureBox.Location = new System.Drawing.Point(3, 3); + this.logoPictureBox.Location = new System.Drawing.Point(4, 5); + this.logoPictureBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.logoPictureBox.Name = "logoPictureBox"; this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 6); - this.logoPictureBox.Size = new System.Drawing.Size(215, 248); + this.logoPictureBox.Size = new System.Drawing.Size(323, 380); this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.logoPictureBox.TabIndex = 12; this.logoPictureBox.TabStop = false; @@ -79,11 +81,11 @@ private void InitializeComponent() // labelProductName // this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelProductName.Location = new System.Drawing.Point(227, 0); - this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); - this.labelProductName.MaximumSize = new System.Drawing.Size(0, 17); + this.labelProductName.Location = new System.Drawing.Point(340, 0); + this.labelProductName.Margin = new System.Windows.Forms.Padding(9, 0, 4, 0); + this.labelProductName.MaximumSize = new System.Drawing.Size(0, 26); this.labelProductName.Name = "labelProductName"; - this.labelProductName.Size = new System.Drawing.Size(440, 17); + this.labelProductName.Size = new System.Drawing.Size(660, 26); this.labelProductName.TabIndex = 19; this.labelProductName.Text = "Product Name"; this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; @@ -91,11 +93,11 @@ private void InitializeComponent() // labelVersion // this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelVersion.Location = new System.Drawing.Point(227, 25); - this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); - this.labelVersion.MaximumSize = new System.Drawing.Size(0, 17); + this.labelVersion.Location = new System.Drawing.Point(340, 39); + this.labelVersion.Margin = new System.Windows.Forms.Padding(9, 0, 4, 0); + this.labelVersion.MaximumSize = new System.Drawing.Size(0, 26); this.labelVersion.Name = "labelVersion"; - this.labelVersion.Size = new System.Drawing.Size(440, 17); + this.labelVersion.Size = new System.Drawing.Size(660, 26); this.labelVersion.TabIndex = 0; this.labelVersion.Text = "Version"; this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; @@ -103,11 +105,11 @@ private void InitializeComponent() // labelCopyright // this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelCopyright.Location = new System.Drawing.Point(227, 50); - this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); - this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 17); + this.labelCopyright.Location = new System.Drawing.Point(340, 78); + this.labelCopyright.Margin = new System.Windows.Forms.Padding(9, 0, 4, 0); + this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 26); this.labelCopyright.Name = "labelCopyright"; - this.labelCopyright.Size = new System.Drawing.Size(440, 17); + this.labelCopyright.Size = new System.Drawing.Size(660, 26); this.labelCopyright.TabIndex = 21; this.labelCopyright.Text = "Copyright"; this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; @@ -115,11 +117,11 @@ private void InitializeComponent() // labelCompanyName // this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelCompanyName.Location = new System.Drawing.Point(227, 75); - this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); - this.labelCompanyName.MaximumSize = new System.Drawing.Size(0, 17); + this.labelCompanyName.Location = new System.Drawing.Point(340, 117); + this.labelCompanyName.Margin = new System.Windows.Forms.Padding(9, 0, 4, 0); + this.labelCompanyName.MaximumSize = new System.Drawing.Size(0, 26); this.labelCompanyName.Name = "labelCompanyName"; - this.labelCompanyName.Size = new System.Drawing.Size(440, 17); + this.labelCompanyName.Size = new System.Drawing.Size(660, 26); this.labelCompanyName.TabIndex = 22; this.labelCompanyName.Text = "Company Name"; this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; @@ -127,13 +129,13 @@ private void InitializeComponent() // textBoxDescription // this.textBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill; - this.textBoxDescription.Location = new System.Drawing.Point(227, 103); - this.textBoxDescription.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3); + this.textBoxDescription.Location = new System.Drawing.Point(340, 161); + this.textBoxDescription.Margin = new System.Windows.Forms.Padding(9, 5, 4, 5); this.textBoxDescription.Multiline = true; this.textBoxDescription.Name = "textBoxDescription"; this.textBoxDescription.ReadOnly = true; this.textBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.textBoxDescription.Size = new System.Drawing.Size(440, 121); + this.textBoxDescription.Size = new System.Drawing.Size(660, 185); this.textBoxDescription.TabIndex = 23; this.textBoxDescription.TabStop = false; this.textBoxDescription.Text = "Description"; @@ -142,24 +144,27 @@ private void InitializeComponent() // this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.okButton.Location = new System.Drawing.Point(592, 230); + this.okButton.Location = new System.Drawing.Point(888, 356); + this.okButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 21); + this.okButton.Size = new System.Drawing.Size(112, 29); this.okButton.TabIndex = 24; this.okButton.Text = "&OK"; // // FrmAbout // this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(688, 272); + this.ClientSize = new System.Drawing.Size(1032, 418); this.Controls.Add(this.tableLayoutPanel); + this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "FrmAbout"; - this.Padding = new System.Windows.Forms.Padding(9); + this.Padding = new System.Windows.Forms.Padding(14, 14, 14, 14); this.ShowIcon = false; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; diff --git a/PrusaSL1Viewer/FrmInputBox.Designer.cs b/PrusaSL1Viewer/FrmInputBox.Designer.cs index 9ffef9b5..b7550474 100644 --- a/PrusaSL1Viewer/FrmInputBox.Designer.cs +++ b/PrusaSL1Viewer/FrmInputBox.Designer.cs @@ -42,7 +42,8 @@ private void InitializeComponent() // this.lbDescription.AutoSize = true; this.lbDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lbDescription.Location = new System.Drawing.Point(12, 9); + this.lbDescription.Location = new System.Drawing.Point(18, 14); + this.lbDescription.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.lbDescription.Name = "lbDescription"; this.lbDescription.Size = new System.Drawing.Size(89, 20); this.lbDescription.TabIndex = 0; @@ -51,9 +52,10 @@ private void InitializeComponent() // lbCurrentValue // this.lbCurrentValue.AutoSize = true; - this.lbCurrentValue.Location = new System.Drawing.Point(13, 47); + this.lbCurrentValue.Location = new System.Drawing.Point(20, 72); + this.lbCurrentValue.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.lbCurrentValue.Name = "lbCurrentValue"; - this.lbCurrentValue.Size = new System.Drawing.Size(74, 13); + this.lbCurrentValue.Size = new System.Drawing.Size(111, 20); this.lbCurrentValue.TabIndex = 1; this.lbCurrentValue.Text = "Current Value:"; // @@ -62,18 +64,20 @@ private void InitializeComponent() this.tbCurrentValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.tbCurrentValue.CausesValidation = false; - this.tbCurrentValue.Location = new System.Drawing.Point(93, 44); + this.tbCurrentValue.Location = new System.Drawing.Point(140, 68); + this.tbCurrentValue.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.tbCurrentValue.Name = "tbCurrentValue"; this.tbCurrentValue.ReadOnly = true; - this.tbCurrentValue.Size = new System.Drawing.Size(261, 20); + this.tbCurrentValue.Size = new System.Drawing.Size(307, 26); this.tbCurrentValue.TabIndex = 2; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(13, 72); + this.label1.Location = new System.Drawing.Point(20, 111); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(62, 13); + this.label1.Size = new System.Drawing.Size(89, 20); this.label1.TabIndex = 3; this.label1.Text = "New Value:"; // @@ -81,9 +85,10 @@ private void InitializeComponent() // this.numNewValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.numNewValue.Location = new System.Drawing.Point(93, 70); + this.numNewValue.Location = new System.Drawing.Point(140, 108); + this.numNewValue.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.numNewValue.Name = "numNewValue"; - this.numNewValue.Size = new System.Drawing.Size(261, 20); + this.numNewValue.Size = new System.Drawing.Size(309, 26); this.numNewValue.TabIndex = 4; this.numNewValue.ValueChanged += new System.EventHandler(this.ValueChanged); // @@ -93,9 +98,10 @@ private void InitializeComponent() this.btnModify.Enabled = false; this.btnModify.Image = global::PrusaSL1Viewer.Properties.Resources.Ok_24x24; this.btnModify.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnModify.Location = new System.Drawing.Point(148, 96); + this.btnModify.Location = new System.Drawing.Point(139, 148); + this.btnModify.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btnModify.Name = "btnModify"; - this.btnModify.Size = new System.Drawing.Size(100, 40); + this.btnModify.Size = new System.Drawing.Size(150, 48); this.btnModify.TabIndex = 6; this.btnModify.Text = "&Modify"; this.btnModify.TextAlign = System.Drawing.ContentAlignment.MiddleRight; @@ -108,9 +114,10 @@ private void InitializeComponent() this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Image = global::PrusaSL1Viewer.Properties.Resources.Cancel_24x24; this.btnCancel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnCancel.Location = new System.Drawing.Point(254, 96); + this.btnCancel.Location = new System.Drawing.Point(298, 148); + this.btnCancel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(100, 40); + this.btnCancel.Size = new System.Drawing.Size(150, 48); this.btnCancel.TabIndex = 5; this.btnCancel.Text = "&Cancel"; this.btnCancel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; @@ -119,10 +126,10 @@ private void InitializeComponent() // // FrmInputBox // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; - this.ClientSize = new System.Drawing.Size(366, 146); + this.ClientSize = new System.Drawing.Size(466, 211); this.Controls.Add(this.btnModify); this.Controls.Add(this.btnCancel); this.Controls.Add(this.numNewValue); @@ -130,7 +137,10 @@ private void InitializeComponent() this.Controls.Add(this.tbCurrentValue); this.Controls.Add(this.lbCurrentValue); this.Controls.Add(this.lbDescription); + this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.KeyPreview = true; + this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "FrmInputBox"; diff --git a/PrusaSL1Viewer/FrmInputBox.cs b/PrusaSL1Viewer/FrmInputBox.cs index db2bbd4c..72f659a1 100644 --- a/PrusaSL1Viewer/FrmInputBox.cs +++ b/PrusaSL1Viewer/FrmInputBox.cs @@ -1,4 +1,11 @@ -using System; +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ +using System; using System.Globalization; using System.Windows.Forms; using PrusaSL1Reader; @@ -7,6 +14,7 @@ namespace PrusaSL1Viewer { public partial class FrmInputBox : Form { + #region Properties private string _description; public string Description { @@ -30,12 +38,16 @@ public decimal CurrentValue get => _currentValue; set { _currentValue = value; tbCurrentValue.Text = value.ToString(CultureInfo.InvariantCulture)+ValueUint; } } + #endregion + #region Constructors public FrmInputBox() { InitializeComponent(); DialogResult = DialogResult.Cancel; numNewValue.Select(); + + } public FrmInputBox(FileFormat.PrintParameterModifier modifier, decimal currentValue) : this(modifier.Name, @@ -51,7 +63,22 @@ public FrmInputBox(string title, string description, decimal currentValue, strin numNewValue.Maximum = maxValue; NewValue = currentValue; } + #endregion + + #region Overrides + protected override void OnKeyUp(KeyEventArgs e) + { + base.OnKeyUp(e); + if (e.KeyCode == Keys.Enter) + { + btnModify.PerformClick(); + e.Handled = true; + } + } + + #endregion + #region Events private void ValueChanged(object sender, EventArgs e) { if (ReferenceEquals(sender, numNewValue)) @@ -66,6 +93,7 @@ private void ItemClicked(object sender, EventArgs e) { if (ReferenceEquals(sender, btnModify)) { + if (!btnModify.Enabled) return; if (MessageBox.Show($"Are you sure you want to {Description}?\nFrom {CurrentValue}{ValueUint} to {NewValue}{ValueUint}", Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { @@ -86,5 +114,6 @@ private void ItemClicked(object sender, EventArgs e) return; } } + #endregion } } diff --git a/PrusaSL1Viewer/FrmMain.Designer.cs b/PrusaSL1Viewer/FrmMain.Designer.cs index 69b71a2a..cd4fd718 100644 --- a/PrusaSL1Viewer/FrmMain.Designer.cs +++ b/PrusaSL1Viewer/FrmMain.Designer.cs @@ -28,6 +28,7 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain)); this.menu = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -50,9 +51,17 @@ private void InitializeComponent() this.menuAboutAbout = new System.Windows.Forms.ToolStripMenuItem(); this.statusBar = new System.Windows.Forms.StatusStrip(); this.sbLayers = new System.Windows.Forms.VScrollBar(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.mainTable = new System.Windows.Forms.TableLayoutPanel(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.lbLayers = new System.Windows.Forms.Label(); + this.scCenter = new System.Windows.Forms.SplitContainer(); + this.pbLayer = new System.Windows.Forms.PictureBox(); + this.tsLayer = new System.Windows.Forms.ToolStrip(); + this.tsLayerImageExport = new System.Windows.Forms.ToolStripButton(); + this.tsLayerResolution = new System.Windows.Forms.ToolStripLabel(); + this.pbLayers = new System.Windows.Forms.ProgressBar(); + this.tabControlLeft = new System.Windows.Forms.TabControl(); + this.tbpThumbnailsAndInfo = new System.Windows.Forms.TabPage(); this.scLeft = new System.Windows.Forms.SplitContainer(); this.pbThumbnail = new System.Windows.Forms.PictureBox(); this.tsThumbnails = new System.Windows.Forms.ToolStrip(); @@ -61,33 +70,45 @@ private void InitializeComponent() this.tsThumbnailsNext = new System.Windows.Forms.ToolStripButton(); this.tsThumbnailsExport = new System.Windows.Forms.ToolStripButton(); this.tsThumbnailsResolution = new System.Windows.Forms.ToolStripLabel(); + this.tbpGCode = new System.Windows.Forms.TabPage(); + this.tbGCode = new System.Windows.Forms.TextBox(); + this.tsGCode = new System.Windows.Forms.ToolStrip(); + this.tsGCodeLabelLines = new System.Windows.Forms.ToolStripLabel(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.tsGcodeLabelChars = new System.Windows.Forms.ToolStripLabel(); + this.tsGCodeButtonSave = new System.Windows.Forms.ToolStripButton(); + this.imageList16x16 = new System.Windows.Forms.ImageList(this.components); + this.tsProperties = new System.Windows.Forms.ToolStrip(); this.lvProperties = new System.Windows.Forms.ListView(); this.lvChKey = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.lvChValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.scCenter = new System.Windows.Forms.SplitContainer(); - this.pbLayer = new System.Windows.Forms.PictureBox(); - this.pbLayers = new System.Windows.Forms.ProgressBar(); - this.tsLayer = new System.Windows.Forms.ToolStrip(); - this.tsLayerImageExport = new System.Windows.Forms.ToolStripButton(); - this.tsLayerResolution = new System.Windows.Forms.ToolStripLabel(); + this.tsPropertiesLabelCount = new System.Windows.Forms.ToolStripLabel(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.tsPropertiesLabelGroups = new System.Windows.Forms.ToolStripLabel(); + this.tsPropertiesButtonSave = new System.Windows.Forms.ToolStripButton(); this.menu.SuspendLayout(); - this.tableLayoutPanel1.SuspendLayout(); + this.mainTable.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.scLeft)).BeginInit(); - this.scLeft.Panel1.SuspendLayout(); - this.scLeft.Panel2.SuspendLayout(); - this.scLeft.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pbThumbnail)).BeginInit(); - this.tsThumbnails.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.scCenter)).BeginInit(); this.scCenter.Panel1.SuspendLayout(); this.scCenter.Panel2.SuspendLayout(); this.scCenter.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbLayer)).BeginInit(); this.tsLayer.SuspendLayout(); + this.tabControlLeft.SuspendLayout(); + this.tbpThumbnailsAndInfo.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.scLeft)).BeginInit(); + this.scLeft.Panel1.SuspendLayout(); + this.scLeft.Panel2.SuspendLayout(); + this.scLeft.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbThumbnail)).BeginInit(); + this.tsThumbnails.SuspendLayout(); + this.tbpGCode.SuspendLayout(); + this.tsGCode.SuspendLayout(); + this.tsProperties.SuspendLayout(); this.SuspendLayout(); // // menu @@ -288,34 +309,33 @@ private void InitializeComponent() this.sbLayers.LargeChange = 1; this.sbLayers.Location = new System.Drawing.Point(0, 0); this.sbLayers.Name = "sbLayers"; - this.sbLayers.Size = new System.Drawing.Size(94, 642); + this.sbLayers.Size = new System.Drawing.Size(124, 670); this.sbLayers.TabIndex = 4; this.sbLayers.ValueChanged += new System.EventHandler(this.sbLayers_ValueChanged); // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.ColumnCount = 3; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 400F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100F)); - this.tableLayoutPanel1.Controls.Add(this.splitContainer1, 2, 0); - this.tableLayoutPanel1.Controls.Add(this.scLeft, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.scCenter, 1, 0); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 24); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 1; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 737F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(1631, 737); - this.tableLayoutPanel1.TabIndex = 5; + // mainTable + // + this.mainTable.ColumnCount = 3; + this.mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 400F)); + this.mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.mainTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130F)); + this.mainTable.Controls.Add(this.splitContainer1, 2, 0); + this.mainTable.Controls.Add(this.scCenter, 1, 0); + this.mainTable.Controls.Add(this.tabControlLeft, 0, 0); + this.mainTable.Dock = System.Windows.Forms.DockStyle.Fill; + this.mainTable.Location = new System.Drawing.Point(0, 24); + this.mainTable.Name = "mainTable"; + this.mainTable.RowCount = 1; + this.mainTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.mainTable.Size = new System.Drawing.Size(1631, 737); + this.mainTable.TabIndex = 5; // // splitContainer1 // this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; this.splitContainer1.IsSplitterFixed = true; - this.splitContainer1.Location = new System.Drawing.Point(1534, 3); + this.splitContainer1.Location = new System.Drawing.Point(1504, 3); this.splitContainer1.Name = "splitContainer1"; this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; // @@ -326,26 +346,124 @@ private void InitializeComponent() // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.lbLayers); - this.splitContainer1.Size = new System.Drawing.Size(94, 731); - this.splitContainer1.SplitterDistance = 642; + this.splitContainer1.Size = new System.Drawing.Size(124, 731); + this.splitContainer1.SplitterDistance = 670; this.splitContainer1.TabIndex = 0; // // lbLayers // this.lbLayers.Dock = System.Windows.Forms.DockStyle.Fill; - this.lbLayers.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lbLayers.Location = new System.Drawing.Point(0, 0); this.lbLayers.Name = "lbLayers"; - this.lbLayers.Size = new System.Drawing.Size(94, 85); + this.lbLayers.Size = new System.Drawing.Size(124, 57); this.lbLayers.TabIndex = 0; this.lbLayers.Text = "Layers"; this.lbLayers.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // + // scCenter + // + this.scCenter.Dock = System.Windows.Forms.DockStyle.Fill; + this.scCenter.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.scCenter.IsSplitterFixed = true; + this.scCenter.Location = new System.Drawing.Point(403, 3); + this.scCenter.Name = "scCenter"; + this.scCenter.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // scCenter.Panel1 + // + this.scCenter.Panel1.Controls.Add(this.pbLayer); + this.scCenter.Panel1.Controls.Add(this.tsLayer); + // + // scCenter.Panel2 + // + this.scCenter.Panel2.Controls.Add(this.pbLayers); + this.scCenter.Panel2MinSize = 18; + this.scCenter.Size = new System.Drawing.Size(1095, 731); + this.scCenter.SplitterDistance = 702; + this.scCenter.TabIndex = 4; + // + // pbLayer + // + this.pbLayer.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.pbLayer.Dock = System.Windows.Forms.DockStyle.Fill; + this.pbLayer.Location = new System.Drawing.Point(0, 25); + this.pbLayer.Name = "pbLayer"; + this.pbLayer.Size = new System.Drawing.Size(1095, 677); + this.pbLayer.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pbLayer.TabIndex = 5; + this.pbLayer.TabStop = false; + // + // tsLayer + // + this.tsLayer.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.tsLayer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsLayerImageExport, + this.tsLayerResolution}); + this.tsLayer.Location = new System.Drawing.Point(0, 0); + this.tsLayer.Name = "tsLayer"; + this.tsLayer.Size = new System.Drawing.Size(1095, 25); + this.tsLayer.TabIndex = 6; + this.tsLayer.Text = "Layer Menu"; + // + // tsLayerImageExport + // + this.tsLayerImageExport.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; + this.tsLayerImageExport.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsLayerImageExport.Enabled = false; + this.tsLayerImageExport.Image = global::PrusaSL1Viewer.Properties.Resources.Save_16x16; + this.tsLayerImageExport.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsLayerImageExport.Name = "tsLayerImageExport"; + this.tsLayerImageExport.Size = new System.Drawing.Size(23, 22); + this.tsLayerImageExport.Text = "Save Layer"; + this.tsLayerImageExport.ToolTipText = "Save layer image to file"; + this.tsLayerImageExport.Click += new System.EventHandler(this.ItemClicked); + // + // tsLayerResolution + // + this.tsLayerResolution.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; + this.tsLayerResolution.Name = "tsLayerResolution"; + this.tsLayerResolution.Size = new System.Drawing.Size(63, 22); + this.tsLayerResolution.Text = "Resolution"; + this.tsLayerResolution.ToolTipText = "Layer Resolution"; + // + // pbLayers + // + this.pbLayers.Dock = System.Windows.Forms.DockStyle.Fill; + this.pbLayers.Location = new System.Drawing.Point(0, 0); + this.pbLayers.Name = "pbLayers"; + this.pbLayers.Size = new System.Drawing.Size(1095, 25); + this.pbLayers.Step = 1; + this.pbLayers.TabIndex = 6; + // + // tabControlLeft + // + this.tabControlLeft.Controls.Add(this.tbpThumbnailsAndInfo); + this.tabControlLeft.Controls.Add(this.tbpGCode); + this.tabControlLeft.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControlLeft.ImageList = this.imageList16x16; + this.tabControlLeft.ItemSize = new System.Drawing.Size(130, 19); + this.tabControlLeft.Location = new System.Drawing.Point(3, 3); + this.tabControlLeft.Name = "tabControlLeft"; + this.tabControlLeft.SelectedIndex = 0; + this.tabControlLeft.Size = new System.Drawing.Size(394, 731); + this.tabControlLeft.TabIndex = 5; + // + // tbpThumbnailsAndInfo + // + this.tbpThumbnailsAndInfo.Controls.Add(this.scLeft); + this.tbpThumbnailsAndInfo.ImageKey = "PhotoInfo-16x16.png"; + this.tbpThumbnailsAndInfo.Location = new System.Drawing.Point(4, 23); + this.tbpThumbnailsAndInfo.Name = "tbpThumbnailsAndInfo"; + this.tbpThumbnailsAndInfo.Padding = new System.Windows.Forms.Padding(3); + this.tbpThumbnailsAndInfo.Size = new System.Drawing.Size(386, 704); + this.tbpThumbnailsAndInfo.TabIndex = 0; + this.tbpThumbnailsAndInfo.Text = "Information"; + this.tbpThumbnailsAndInfo.UseVisualStyleBackColor = true; + // // scLeft // this.scLeft.Dock = System.Windows.Forms.DockStyle.Fill; this.scLeft.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; - this.scLeft.IsSplitterFixed = true; this.scLeft.Location = new System.Drawing.Point(3, 3); this.scLeft.Name = "scLeft"; this.scLeft.Orientation = System.Windows.Forms.Orientation.Horizontal; @@ -354,14 +472,15 @@ private void InitializeComponent() // this.scLeft.Panel1.Controls.Add(this.pbThumbnail); this.scLeft.Panel1.Controls.Add(this.tsThumbnails); - this.scLeft.Panel1MinSize = 425; + this.scLeft.Panel1MinSize = 150; // // scLeft.Panel2 // this.scLeft.Panel2.Controls.Add(this.lvProperties); - this.scLeft.Size = new System.Drawing.Size(394, 731); + this.scLeft.Panel2.Controls.Add(this.tsProperties); + this.scLeft.Size = new System.Drawing.Size(380, 698); this.scLeft.SplitterDistance = 425; - this.scLeft.TabIndex = 3; + this.scLeft.TabIndex = 4; // // pbThumbnail // @@ -369,7 +488,7 @@ private void InitializeComponent() this.pbThumbnail.Dock = System.Windows.Forms.DockStyle.Fill; this.pbThumbnail.Location = new System.Drawing.Point(0, 25); this.pbThumbnail.Name = "pbThumbnail"; - this.pbThumbnail.Size = new System.Drawing.Size(394, 400); + this.pbThumbnail.Size = new System.Drawing.Size(380, 400); this.pbThumbnail.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.pbThumbnail.TabIndex = 4; this.pbThumbnail.TabStop = false; @@ -385,7 +504,7 @@ private void InitializeComponent() this.tsThumbnailsResolution}); this.tsThumbnails.Location = new System.Drawing.Point(0, 0); this.tsThumbnails.Name = "tsThumbnails"; - this.tsThumbnails.Size = new System.Drawing.Size(394, 25); + this.tsThumbnails.Size = new System.Drawing.Size(380, 25); this.tsThumbnails.TabIndex = 5; this.tsThumbnails.Text = "Thumbnail Menu"; // @@ -441,6 +560,93 @@ private void InitializeComponent() this.tsThumbnailsResolution.Text = "Resolution"; this.tsThumbnailsResolution.ToolTipText = "Thumbnail Resolution"; // + // tbpGCode + // + this.tbpGCode.Controls.Add(this.tbGCode); + this.tbpGCode.Controls.Add(this.tsGCode); + this.tbpGCode.ImageKey = "GCode-16x16.png"; + this.tbpGCode.Location = new System.Drawing.Point(4, 23); + this.tbpGCode.Name = "tbpGCode"; + this.tbpGCode.Size = new System.Drawing.Size(386, 704); + this.tbpGCode.TabIndex = 2; + this.tbpGCode.Text = "GCode"; + this.tbpGCode.UseVisualStyleBackColor = true; + // + // tbGCode + // + this.tbGCode.Dock = System.Windows.Forms.DockStyle.Fill; + this.tbGCode.Location = new System.Drawing.Point(0, 25); + this.tbGCode.Multiline = true; + this.tbGCode.Name = "tbGCode"; + this.tbGCode.ReadOnly = true; + this.tbGCode.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.tbGCode.Size = new System.Drawing.Size(386, 679); + this.tbGCode.TabIndex = 1; + // + // tsGCode + // + this.tsGCode.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.tsGCode.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsGCodeLabelLines, + this.toolStripSeparator3, + this.tsGcodeLabelChars, + this.tsGCodeButtonSave}); + this.tsGCode.Location = new System.Drawing.Point(0, 0); + this.tsGCode.Name = "tsGCode"; + this.tsGCode.Size = new System.Drawing.Size(386, 25); + this.tsGCode.TabIndex = 0; + // + // tsGCodeLabelLines + // + this.tsGCodeLabelLines.Name = "tsGCodeLabelLines"; + this.tsGCodeLabelLines.Size = new System.Drawing.Size(34, 22); + this.tsGCodeLabelLines.Text = "Lines"; + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // tsGcodeLabelChars + // + this.tsGcodeLabelChars.Name = "tsGcodeLabelChars"; + this.tsGcodeLabelChars.Size = new System.Drawing.Size(37, 22); + this.tsGcodeLabelChars.Text = "Chars"; + // + // tsGCodeButtonSave + // + this.tsGCodeButtonSave.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; + this.tsGCodeButtonSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsGCodeButtonSave.Image = global::PrusaSL1Viewer.Properties.Resources.Save_16x16; + this.tsGCodeButtonSave.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsGCodeButtonSave.Name = "tsGCodeButtonSave"; + this.tsGCodeButtonSave.Size = new System.Drawing.Size(23, 22); + this.tsGCodeButtonSave.Text = "Save GCode"; + this.tsGCodeButtonSave.ToolTipText = "Save GCode to file"; + this.tsGCodeButtonSave.Click += new System.EventHandler(this.ItemClicked); + // + // imageList16x16 + // + this.imageList16x16.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList16x16.ImageStream"))); + this.imageList16x16.TransparentColor = System.Drawing.Color.Transparent; + this.imageList16x16.Images.SetKeyName(0, "DataList-16x16.png"); + this.imageList16x16.Images.SetKeyName(1, "PhotoInfo-16x16.png"); + this.imageList16x16.Images.SetKeyName(2, "GCode-16x16.png"); + // + // tsProperties + // + this.tsProperties.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.tsProperties.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsPropertiesLabelCount, + this.toolStripSeparator4, + this.tsPropertiesLabelGroups, + this.tsPropertiesButtonSave}); + this.tsProperties.Location = new System.Drawing.Point(0, 0); + this.tsProperties.Name = "tsProperties"; + this.tsProperties.Size = new System.Drawing.Size(380, 25); + this.tsProperties.TabIndex = 0; + this.tsProperties.Text = "Properties"; + // // lvProperties // this.lvProperties.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { @@ -450,10 +656,10 @@ private void InitializeComponent() this.lvProperties.FullRowSelect = true; this.lvProperties.GridLines = true; this.lvProperties.HideSelection = false; - this.lvProperties.Location = new System.Drawing.Point(0, 0); + this.lvProperties.Location = new System.Drawing.Point(0, 25); this.lvProperties.Name = "lvProperties"; - this.lvProperties.Size = new System.Drawing.Size(394, 302); - this.lvProperties.TabIndex = 0; + this.lvProperties.Size = new System.Drawing.Size(380, 244); + this.lvProperties.TabIndex = 1; this.lvProperties.UseCompatibleStateImageBehavior = false; this.lvProperties.View = System.Windows.Forms.View.Details; // @@ -467,80 +673,35 @@ private void InitializeComponent() this.lvChValue.Text = "Value"; this.lvChValue.Width = 205; // - // scCenter - // - this.scCenter.Dock = System.Windows.Forms.DockStyle.Fill; - this.scCenter.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; - this.scCenter.IsSplitterFixed = true; - this.scCenter.Location = new System.Drawing.Point(403, 3); - this.scCenter.Name = "scCenter"; - this.scCenter.Orientation = System.Windows.Forms.Orientation.Horizontal; + // tsPropertiesLabelCount // - // scCenter.Panel1 + this.tsPropertiesLabelCount.Name = "tsPropertiesLabelCount"; + this.tsPropertiesLabelCount.Size = new System.Drawing.Size(40, 22); + this.tsPropertiesLabelCount.Text = "Count"; // - this.scCenter.Panel1.Controls.Add(this.pbLayer); - this.scCenter.Panel1.Controls.Add(this.tsLayer); - // - // scCenter.Panel2 - // - this.scCenter.Panel2.Controls.Add(this.pbLayers); - this.scCenter.Panel2MinSize = 18; - this.scCenter.Size = new System.Drawing.Size(1125, 731); - this.scCenter.SplitterDistance = 702; - this.scCenter.TabIndex = 4; - // - // pbLayer - // - this.pbLayer.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.pbLayer.Dock = System.Windows.Forms.DockStyle.Fill; - this.pbLayer.Location = new System.Drawing.Point(0, 25); - this.pbLayer.Name = "pbLayer"; - this.pbLayer.Size = new System.Drawing.Size(1125, 677); - this.pbLayer.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.pbLayer.TabIndex = 5; - this.pbLayer.TabStop = false; + // toolStripSeparator4 // - // pbLayers + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25); // - this.pbLayers.Dock = System.Windows.Forms.DockStyle.Fill; - this.pbLayers.Location = new System.Drawing.Point(0, 0); - this.pbLayers.Name = "pbLayers"; - this.pbLayers.Size = new System.Drawing.Size(1125, 25); - this.pbLayers.Step = 1; - this.pbLayers.TabIndex = 6; + // tsPropertiesLabelGroups // - // tsLayer + this.tsPropertiesLabelGroups.Name = "tsPropertiesLabelGroups"; + this.tsPropertiesLabelGroups.Size = new System.Drawing.Size(45, 22); + this.tsPropertiesLabelGroups.Text = "Groups"; // - this.tsLayer.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; - this.tsLayer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.tsLayerImageExport, - this.tsLayerResolution}); - this.tsLayer.Location = new System.Drawing.Point(0, 0); - this.tsLayer.Name = "tsLayer"; - this.tsLayer.Size = new System.Drawing.Size(1125, 25); - this.tsLayer.TabIndex = 6; - this.tsLayer.Text = "Layer Menu"; + // tsPropertiesButtonSave // - // tsLayerImageExport - // - this.tsLayerImageExport.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; - this.tsLayerImageExport.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.tsLayerImageExport.Enabled = false; - this.tsLayerImageExport.Image = global::PrusaSL1Viewer.Properties.Resources.Save_16x16; - this.tsLayerImageExport.ImageTransparentColor = System.Drawing.Color.Magenta; - this.tsLayerImageExport.Name = "tsLayerImageExport"; - this.tsLayerImageExport.Size = new System.Drawing.Size(23, 22); - this.tsLayerImageExport.Text = "Save Layer"; - this.tsLayerImageExport.ToolTipText = "Save layer image to file"; - this.tsLayerImageExport.Click += new System.EventHandler(this.ItemClicked); - // - // tsLayerResolution - // - this.tsLayerResolution.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; - this.tsLayerResolution.Name = "tsLayerResolution"; - this.tsLayerResolution.Size = new System.Drawing.Size(63, 22); - this.tsLayerResolution.Text = "Resolution"; - this.tsLayerResolution.ToolTipText = "Layer Resolution"; + this.tsPropertiesButtonSave.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; + this.tsPropertiesButtonSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsPropertiesButtonSave.Enabled = false; + this.tsPropertiesButtonSave.Image = global::PrusaSL1Viewer.Properties.Resources.Save_16x16; + this.tsPropertiesButtonSave.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsPropertiesButtonSave.Name = "tsPropertiesButtonSave"; + this.tsPropertiesButtonSave.Size = new System.Drawing.Size(23, 22); + this.tsPropertiesButtonSave.Text = "Save Thumbnail"; + this.tsPropertiesButtonSave.ToolTipText = "Save properties to a file"; + this.tsPropertiesButtonSave.Click += new System.EventHandler(this.ItemClicked); // // FrmMain // @@ -548,9 +709,10 @@ private void InitializeComponent() this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1631, 783); - this.Controls.Add(this.tableLayoutPanel1); + this.Controls.Add(this.mainTable); this.Controls.Add(this.statusBar); this.Controls.Add(this.menu); + this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MainMenuStrip = this.menu; this.MinimumSize = new System.Drawing.Size(1000, 600); @@ -558,19 +720,11 @@ private void InitializeComponent() this.Text = "PrusaSL1Viewer"; this.menu.ResumeLayout(false); this.menu.PerformLayout(); - this.tableLayoutPanel1.ResumeLayout(false); + this.mainTable.ResumeLayout(false); this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); - this.scLeft.Panel1.ResumeLayout(false); - this.scLeft.Panel1.PerformLayout(); - this.scLeft.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.scLeft)).EndInit(); - this.scLeft.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.pbThumbnail)).EndInit(); - this.tsThumbnails.ResumeLayout(false); - this.tsThumbnails.PerformLayout(); this.scCenter.Panel1.ResumeLayout(false); this.scCenter.Panel1.PerformLayout(); this.scCenter.Panel2.ResumeLayout(false); @@ -579,6 +733,23 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.pbLayer)).EndInit(); this.tsLayer.ResumeLayout(false); this.tsLayer.PerformLayout(); + this.tabControlLeft.ResumeLayout(false); + this.tbpThumbnailsAndInfo.ResumeLayout(false); + this.scLeft.Panel1.ResumeLayout(false); + this.scLeft.Panel1.PerformLayout(); + this.scLeft.Panel2.ResumeLayout(false); + this.scLeft.Panel2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.scLeft)).EndInit(); + this.scLeft.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pbThumbnail)).EndInit(); + this.tsThumbnails.ResumeLayout(false); + this.tsThumbnails.PerformLayout(); + this.tbpGCode.ResumeLayout(false); + this.tbpGCode.PerformLayout(); + this.tsGCode.ResumeLayout(false); + this.tsGCode.PerformLayout(); + this.tsProperties.ResumeLayout(false); + this.tsProperties.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -596,25 +767,15 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem menuAboutDonate; private System.Windows.Forms.ToolStripMenuItem menuAboutAbout; private System.Windows.Forms.VScrollBar sbLayers; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.TableLayoutPanel mainTable; private System.Windows.Forms.SplitContainer splitContainer1; private System.Windows.Forms.Label lbLayers; private System.Windows.Forms.ToolStripMenuItem menuEdit; - private System.Windows.Forms.PictureBox pbThumbnail; - private System.Windows.Forms.ListView lvProperties; - private System.Windows.Forms.ColumnHeader lvChKey; - private System.Windows.Forms.ColumnHeader lvChValue; - private System.Windows.Forms.SplitContainer scLeft; private System.Windows.Forms.SplitContainer scCenter; private System.Windows.Forms.PictureBox pbLayer; private System.Windows.Forms.ProgressBar pbLayers; private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem menuViewRotateImage; - private System.Windows.Forms.ToolStrip tsThumbnails; - private System.Windows.Forms.ToolStripLabel tsThumbnailsCount; - private System.Windows.Forms.ToolStripButton tsThumbnailsPrevious; - private System.Windows.Forms.ToolStripButton tsThumbnailsNext; - private System.Windows.Forms.ToolStripButton tsThumbnailsExport; private System.Windows.Forms.ToolStripMenuItem menuFileClose; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem menuFileExtract; @@ -623,10 +784,35 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem menuFileReload; private System.Windows.Forms.ToolStripMenuItem menuFileSave; private System.Windows.Forms.ToolStripMenuItem menuFileSaveAs; - private System.Windows.Forms.ToolStripLabel tsThumbnailsResolution; private System.Windows.Forms.ToolStrip tsLayer; private System.Windows.Forms.ToolStripButton tsLayerImageExport; private System.Windows.Forms.ToolStripLabel tsLayerResolution; + private System.Windows.Forms.TabControl tabControlLeft; + private System.Windows.Forms.TabPage tbpThumbnailsAndInfo; + private System.Windows.Forms.SplitContainer scLeft; + private System.Windows.Forms.PictureBox pbThumbnail; + private System.Windows.Forms.ToolStrip tsThumbnails; + private System.Windows.Forms.ToolStripButton tsThumbnailsPrevious; + private System.Windows.Forms.ToolStripLabel tsThumbnailsCount; + private System.Windows.Forms.ToolStripButton tsThumbnailsNext; + private System.Windows.Forms.ToolStripButton tsThumbnailsExport; + private System.Windows.Forms.ToolStripLabel tsThumbnailsResolution; + private System.Windows.Forms.TabPage tbpGCode; + private System.Windows.Forms.ImageList imageList16x16; + private System.Windows.Forms.TextBox tbGCode; + private System.Windows.Forms.ToolStrip tsGCode; + private System.Windows.Forms.ToolStripLabel tsGCodeLabelLines; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripLabel tsGcodeLabelChars; + private System.Windows.Forms.ToolStripButton tsGCodeButtonSave; + private System.Windows.Forms.ListView lvProperties; + private System.Windows.Forms.ColumnHeader lvChKey; + private System.Windows.Forms.ColumnHeader lvChValue; + private System.Windows.Forms.ToolStrip tsProperties; + private System.Windows.Forms.ToolStripLabel tsPropertiesLabelCount; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripLabel tsPropertiesLabelGroups; + private System.Windows.Forms.ToolStripButton tsPropertiesButtonSave; } } diff --git a/PrusaSL1Viewer/FrmMain.cs b/PrusaSL1Viewer/FrmMain.cs index c914b7ea..d1b992db 100644 --- a/PrusaSL1Viewer/FrmMain.cs +++ b/PrusaSL1Viewer/FrmMain.cs @@ -6,8 +6,8 @@ * of this license document, but changing it is not allowed. */ using System; +using System.Collections; using System.Diagnostics; -using System.Drawing.Imaging; using System.IO; using System.Reflection; using System.Windows.Forms; @@ -33,6 +33,8 @@ public static FileFormat SlicerFile public FrmMain() { InitializeComponent(); + Program.SetAllControlsFontSize(Controls, 11); + Clear(); DragEnter += (s, e) => { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy; }; @@ -97,7 +99,7 @@ private void ItemClicked(object sender, EventArgs e) { using (SaveFileDialog dialog = new SaveFileDialog()) { - dialog.Filter = SlicerFile.GetFileFilter(); + dialog.Filter = SlicerFile.FileFilter; dialog.AddExtension = true; dialog.FileName = $"{Path.GetFileNameWithoutExtension(SlicerFile.FileFullPath)}_copy"; @@ -314,9 +316,79 @@ private void ItemClicked(object sender, EventArgs e) stream.Close(); } } + return; + } + } + + /************************ + * Properties Menu * + ***********************/ + if (ReferenceEquals(sender, tsPropertiesButtonSave)) + { + using (SaveFileDialog dialog = new SaveFileDialog()) + { + dialog.Filter = "Ini Files|.*ini"; + dialog.AddExtension = true; + dialog.FileName = $"{Path.GetFileNameWithoutExtension(SlicerFile.FileFullPath)}_properties.ini"; + + if (dialog.ShowDialog() == DialogResult.OK) + { + using (TextWriter tw = new StreamWriter(dialog.OpenFile())) + { + foreach (var config in SlicerFile.Configs) + { + var type = config.GetType(); + tw.WriteLine($"[{type.Name}]"); + foreach (var property in type.GetProperties()) + { + tw.WriteLine($"{property.Name} = {property.GetValue(config)}"); + } + tw.WriteLine(); + } + tw.Close(); + } + if (MessageBox.Show( + $"Properties save was successful, do you want open the file with default editor?.\nPress 'Yes' if you want open the target file, otherwise select 'No' to continue.", + "Properties save completed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == + DialogResult.Yes) + { + Process.Start(dialog.FileName); + } + } return; + } + return; + } + + /************************ + * GCode Menu * + ***********************/ + if (ReferenceEquals(sender, tsGCodeButtonSave)) + { + using (SaveFileDialog dialog = new SaveFileDialog()) + { + dialog.Filter = "Text Files|.*txt"; + dialog.AddExtension = true; + dialog.FileName = $"{Path.GetFileNameWithoutExtension(SlicerFile.FileFullPath)}_gcode.txt"; + if (dialog.ShowDialog() == DialogResult.OK) + { + using (TextWriter tw = new StreamWriter(dialog.OpenFile())) + { + tw.Write(SlicerFile.GCode); + tw.Close(); + } + + if (MessageBox.Show( + $"GCode save was successful, do you want open the file with default editor?.\nPress 'Yes' if you want open the target file, otherwise select 'No' to continue.", + "GCode save completed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == + DialogResult.Yes) + { + Process.Start(dialog.FileName); + } + } + return; } } @@ -369,13 +441,15 @@ private void ConvertToItemOnClick(object sender, EventArgs e) //using (FileFormat instance = (FileFormat)Activator.CreateInstance(type)) //using (CbddlpFile file = new CbddlpFile()) { - dialog.Filter = fileFormat.GetFileFilter(); + dialog.Filter = fileFormat.FileFilter; } if (dialog.ShowDialog() == DialogResult.OK) { SlicerFile.Convert(fileFormat, dialog.FileName); + MessageBox.Show("Convertion is completed", "Convertion completed", MessageBoxButtons.OK, + MessageBoxIcon.Information); } } @@ -397,6 +471,7 @@ void Clear() pbThumbnail.Image = null; pbLayer.Image = null; pbThumbnail.Image = null; + tbGCode.Clear(); lbLayers.Text = "Layers"; lvProperties.BeginUpdate(); lvProperties.Items.Clear(); @@ -422,9 +497,15 @@ void Clear() { item.Enabled = false; } + foreach (ToolStripItem item in tsProperties.Items) + { + item.Enabled = false; + } tsThumbnailsResolution.Text = - tsLayerResolution.Text = string.Empty; + tsLayerResolution.Text = + tsPropertiesLabelCount.Text = + tsPropertiesLabelGroups.Text = string.Empty; menuFileReload.Enabled = @@ -436,10 +517,14 @@ void Clear() sbLayers.Enabled = pbLayers.Enabled = menuEdit.Enabled = + false; tsThumbnailsCount.Text = "0/0"; tsThumbnailsCount.Tag = null; + + tabControlLeft.TabPages.Remove(tbpGCode); + tabControlLeft.SelectedIndex = 0; } void ProcessFile() @@ -498,6 +583,7 @@ void ProcessFile(string fileName) menuFileConvert.DropDownItems.Add(menuItem); } + scLeft.Panel1Collapsed = SlicerFile.CreatedThumbnailsCount == 0; if (SlicerFile.CreatedThumbnailsCount > 0) { tsThumbnailsCount.Tag = 0; @@ -509,11 +595,20 @@ void ProcessFile(string fileName) { tsThumbnails.Items[i].Enabled = true; } + + tsThumbnailsNext.Enabled = SlicerFile.CreatedThumbnailsCount > 1; + scLeft.SplitterDistance = pbThumbnail.Image.Height + 5; } foreach (ToolStripItem item in tsLayer.Items) { item.Enabled = true; } + foreach (ToolStripItem item in tsProperties.Items) + { + item.Enabled = true; + } + tsPropertiesLabelCount.Text = $"Properties: {lvProperties.Items.Count}"; + tsPropertiesLabelGroups.Text = $"Groups: {lvProperties.Groups.Count}"; menuFileReload.Enabled = menuFileClose.Enabled = @@ -524,6 +619,11 @@ void ProcessFile(string fileName) menuEdit.Enabled = true; + if (!string.IsNullOrEmpty(SlicerFile.GCode)) + { + tabControlLeft.TabPages.Add(tbpGCode); + } + //ShowLayer(0); sbLayers.SmallChange = 1; @@ -531,6 +631,8 @@ void ProcessFile(string fileName) sbLayers.Maximum = (int)SlicerFile.LayerCount-1; sbLayers.Value = sbLayers.Maximum; + tabControlLeft.SelectedIndex = 0; + RefreshInfo(); @@ -566,12 +668,35 @@ void RefreshInfo() { ListViewItem item = new ListViewItem(propertyInfo.Name, group); object obj = new object(); - item.SubItems.Add(propertyInfo.GetValue(config)?.ToString()); + var value = propertyInfo.GetValue(config); + if (!ReferenceEquals(value, null)) + { + if (value is IList list) + { + item.SubItems.Add(list.Count.ToString()); + } + else + { + item.SubItems.Add(value.ToString()); + } + + } + lvProperties.Items.Add(item); } } lvProperties.EndUpdate(); + tsPropertiesLabelCount.Text = $"Properties: {lvProperties.Items.Count}"; + tsPropertiesLabelGroups.Text = $"Groups: {lvProperties.Groups.Count}"; + + if (!string.IsNullOrEmpty(SlicerFile.GCode)) + { + tbGCode.Text = SlicerFile.GCode; + tsGCodeLabelLines.Text = $"Lines: {tbGCode.Lines.Length}"; + tsGcodeLabelChars.Text = $"Chars: {tbGCode.Text.Length}"; + } + statusBar.Items.Clear(); AddStatusBarItem(nameof(SlicerFile.LayerHeight), SlicerFile.LayerHeight, "mm"); AddStatusBarItem(nameof(SlicerFile.InitialLayerCount), SlicerFile.InitialLayerCount); @@ -614,7 +739,7 @@ void ShowLayer(uint layerNum) byte percent = (byte)((layerNum + 1) * 100 / SlicerFile.LayerCount); - lbLayers.Text = $"{SlicerFile.TotalHeight}mm\n{layerNum + 1} / {SlicerFile.LayerCount}\n{SlicerFile.GetHeightFromLayer((uint)layerNum + 1)}mm\n{percent}%"; + lbLayers.Text = $"{SlicerFile.GetHeightFromLayer((uint)layerNum + 1)} / {SlicerFile.TotalHeight}mm\n{layerNum + 1} / {SlicerFile.LayerCount}\n{percent}%"; pbLayers.Value = percent; } catch (Exception e) diff --git a/PrusaSL1Viewer/FrmMain.resx b/PrusaSL1Viewer/FrmMain.resx index d68375e0..7af10c65 100644 --- a/PrusaSL1Viewer/FrmMain.resx +++ b/PrusaSL1Viewer/FrmMain.resx @@ -123,12 +123,66 @@ 132, 17 - - 233, 17 - 357, 17 + + 447, 17 + + + 805, 17 + + + 707, 17 + + + 571, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADg + CAAAAk1TRnQBSQFMAgEBAwEAARABAAEQAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABEAMAAQEBAAEgBgABEFYAA0QBowNCAakDQgGpA0IBqQNCAakDQgGpA0IBqQNCAakDQgGpA0IBqQNC + AakDQgGpA0IBqQNEAaOEAANAAbQDOAHHAy4BSQMAAQEDGwEmAxwBJwMcAScDHAEnAxwBJwMcAScDHAEn + AxwBJwMcAScDHAEnAxwBJwMCAQMEAANCAakwAANCAakQAAMmAToDMAFMAzABTAMwAUwDMAFMAzABTAMw + AUwDMAFMAzABTAMmATpPAAH/AwAB/wNAAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA + Af8DAAH/AwAB/wMAAf8DMgFRBAADQgGpBAADRAGdA0MBqgNDAaoDQwGqA0MBqgNDAaoDQwGqA0QBnQwA + A0IBqRAAA04B+wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A04B+0wAA0MBogM/AbYDKgFA + BAADEAEVAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxABFggAA0IBqQQAA0QBnQND + AaoDQwGqAx8BLBwAA0IBqRAAA00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/0wA + AwoBDgMRARcDAAEBOAADQgGpMAADQgGpEAADTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/wNN + Af8DTQH/TAADEAH0AwAB/wM9AWwDDgETAz8BdgNAAXcDQAF3A0ABdwNAAXcDQAF3A0ABdwNAAXcDQAF3 + A0ABdwM/AXYDFAEbBAADQgGpAyIBMgNCAakDQgGpA0IBqQNCAakDQgGpA0IBqQNCAakDQgGpA0IBqQNC + AakDIgEyA0IBqRAAA00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/08AAf4DAAH/ + A0ABdwMeASsDOgHFAzgBxwM4AccDOAHHAzgBxwM4AccDOAHHAzgBxwM4AccDOAHHAzoBxgMmATkEAANC + AakDNAFVAzQBVSAAAzQBVQM0AVUDQgGpEAADTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/wNN + Af8DTQH/TAADMwFTAzsBZwMUARw4AANCAakDNAFVAzQBVQNCAYADQgGpA0IBqQNCAakDQgGpA0IBqQNC + AakDQQF/AzQBVQM0AVUDQgGpEAADTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/ + TAADMwFTAzsBZwMUARw4AANCAakDNAFVAzQBVQM9AW4DMgFQEAADJwE7A0ABfAM0AVUDNAFVA0IBqRAA + A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A00B/08AAf4DAAH/A0ABdwMfASwDOgHF + AzgBxwM4AccDOAHHAzgBxwM4AccDOAHHAzgBxwM4AccDOAHHAzoBxgMmATkEAANCAakDNAFVAzQBVQMF + AQcDQQG1AxEBFwNCAakDKQE+BAADRAGfAxEBFwM0AVUDNAFVA0IBqRAAA00B/wNNAf8DTQH/A00B/wNN + Af8DTQH/A00B/wNNAf8DTQH/A00B/0wAAxAB9AMAAf8DPQFsAw4BEwM/AXUDQAF3A0ABdwNAAXcDQAF3 + A0ABdwNAAXcDQAF3A0ABdwNAAXcDQAF3AxQBGwQAA0IBqQM0AVUDNAFVBAADOwFoAz4BvgMjATQDQQG1 + AxIBGQNEAaAEAAM0AVUDNAFVA0IBqRAAA00B/wNNAf8DTQH/A00B/wNNAf8DTQH/A1EB/wNWAf8DVgH/ + A1oB30wAAwoBDgMRARcDAAEBOAADQgGpAzQBVQM0AVUDAAEBAy0BRgMKAQ4EAAM4AV8DNQHOAygBPAQA + AzQBVQM0AVUDQgGpEAADTQH/A4IB/wNsAf8DVgH/A00B/wNNAf8DYAH/A2cB/wNjAd8DFwEgTAADQwGi + Az8BtgMqAUAEAAMQARUDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEQEXAxEBFwMRARcDEAEWCAADQgGp + AzQBVQM0AVUDMwFTA0QBpgNCAYwHAAEBA0MBgwgAAzQBVQM0AVUDQgGpEAADTQH/A5kB/wOFAf8DeQH/ + A00B/wNNAf8DYAH/A2MB3wMXASBTAAH/AwAB/wNAAXcDKQE+AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ + AwAB/wMAAf8DAAH/AwAB/wMAAf8DMgFRBAADQgGpAzQBVQM0AVUDEQEXA0MBngMkATYUAAM0AVUDNAFV + A0IBqRAAA1AB+wNYAf8DWAH/A1gB/wNNAf8DTQH/A2AB3wMXASBUAANAAbQDOAHHAy4BSQMAAQEDGwEm + AxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMcAScDHAEnAxwBJwMCAQMEAANCAakDIgEyA0IBqQNC + AakDQgGpA0IBqQNCAakDQgGpA0IBqQNCAakDQgGpA0IBqQMiATIDQgGpEAADIAEuAykBPwMpAT8DKQE/ + AykBPwMpAT8DEQEXnAADRAGjA0IBqQNCAakDQgGpA0IBqQNCAakDQgGpA0IBqQNCAakDQgGpA0IBqQNC + AakDQgGpA0QBo4QAAUIBTQE+BwABPgMAASgDAAFAAwABEAMAAQEBAAEBBQABgBcAA/8BAAL/AYABAQL/ + BAABvwH9AeABBwQAAaABHQHgAQcCAAEQAQEBoQH9AeABBwIAAR8B/wG/Af0B4AEHBAABgAEBAeABBwQA + AY8B8QHgAQcCAAEfAf8BgAEBAeABBwIAAR8B/wGDAcEB4AEHBAABgAFBAeABBwQAAYgBEQHgAQcCAAEf + Af8BgQERAeABBwIAARABAQGBATEB4AEPBAABgQHxAeABHwQAAYABAQHgAT8CAAL/AYABAQL/AgAL + + diff --git a/PrusaSL1Viewer/Images/DataList-16x16.png b/PrusaSL1Viewer/Images/DataList-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..b0e24de3ef502ea4bb8f3e3769dde06611169df2 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`b3I)gLn>}1rz{XKVEQPgAjbAc zP2nEnkyQbONe5&n9Qq&N$0{Jt{-{~SLV+XYfRch3<0CxJA8oDMfDUEw MboFyt=akR{0P2iJU;qFB literal 0 HcmV?d00001 diff --git a/PrusaSL1Viewer/Images/GCode-16x16.png b/PrusaSL1Viewer/Images/GCode-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..c33c4a35a9ebb5abc295ae163ad527f45e160bff GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F5M?jcysy3fAQ1FPS zi(`nz>9>YqzRnuis*w5IkAsq%KF3;kEC!3<`aZ)w&iH zM@~Dd)i5)4TB^aZ15w?pR<&JG^u5g8VBRrDc}1r!+JibvSd(LFxzV zk&Qh8=e!i&u{3w0PK2n(!d zex#x>kL5`4!iPrk9oh{y`X(?=a`?m1VZMNMo~eK}(??$?whZQtYJD$uvmIqQ%piY2 zl1)T?Nr957vBGOd^8`JC&rU}jI-hf?vMp#n?=Z*b1jDAi4rOI*3>k|Z1?_4REP#Gv N@O1TaS?83{1OW34T}1!@ literal 0 HcmV?d00001 diff --git a/PrusaSL1Viewer/Program.cs b/PrusaSL1Viewer/Program.cs index 0bfbe424..6e1bc5d1 100644 --- a/PrusaSL1Viewer/Program.cs +++ b/PrusaSL1Viewer/Program.cs @@ -6,6 +6,7 @@ * of this license document, but changing it is not allowed. */ using System; +using System.Drawing; using System.Globalization; using System.Threading; using System.Windows.Forms; @@ -15,6 +16,50 @@ namespace PrusaSL1Viewer { static class Program { + /// + /// Changes fonts of controls contained in font collection recursively.
+ /// Usage:
+ /// SetAllControlsFont(this.Controls, 20); // This makes fonts 20% bigger.
+ /// SetAllControlsFont(this.Controls, -4, false); // This makes fonts smaller by 4.
+ ///
+ /// Control collection containing controls + /// Amount to change: posive value makes it bigger, + /// negative value smaller + /// True - grow / shrink in percent, + /// False - grow / shrink absolute + /// 0 = Absolute | 1 = Partial | 2 = Percent + public static void SetAllControlsFontSize( + Control.ControlCollection ctrls, + int amount = 0, byte amountType = 0) + { + if (amount == 0) return; + foreach (Control ctrl in ctrls) + { + // recursive + SetAllControlsFontSize(ctrl.Controls, amount, amountType); + + var oldSize = ctrl.Font.Size; + float newSize; + switch (amountType) + { + case 1: + newSize = oldSize + amount; + break; + case 2: + newSize = oldSize + oldSize * (amount / 100); + break; + default: + newSize = amount; + break; + } + + if (newSize < 8) newSize = 8; // don't allow less than 8 + var fontFamilyName = ctrl.Font.FontFamily.Name; + var fontStyle = ctrl.Font.Style; + ctrl.Font = new Font(fontFamilyName, newSize, fontStyle); + }; + } + public static FileFormat SlicerFile { get; set; } public static FrmMain FrmMain { get; private set; } public static FrmAbout FrmAbout { get; private set; } @@ -31,6 +76,7 @@ static void Main() FrmMain = new FrmMain(); FrmAbout = new FrmAbout(); + Application.Run(FrmMain); } } diff --git a/PrusaSL1Viewer/Properties/AssemblyInfo.cs b/PrusaSL1Viewer/Properties/AssemblyInfo.cs index eec0d428..18b03b48 100644 --- a/PrusaSL1Viewer/Properties/AssemblyInfo.cs +++ b/PrusaSL1Viewer/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.2.2.0")] -[assembly: AssemblyFileVersion("0.2.2.0")] +[assembly: AssemblyVersion("0.3.0.0")] +[assembly: AssemblyFileVersion("0.3.0.0")] diff --git a/PrusaSL1Viewer/PrusaSL1Viewer.csproj b/PrusaSL1Viewer/PrusaSL1Viewer.csproj index d6f3aa7a..a4c97fd4 100644 --- a/PrusaSL1Viewer/PrusaSL1Viewer.csproj +++ b/PrusaSL1Viewer/PrusaSL1Viewer.csproj @@ -1,6 +1,6 @@  - + Debug @@ -60,6 +60,9 @@ ..\packages\BinarySerializer.8.5.1\lib\net46\BinarySerializer.dll + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + ..\packages\SixLabors.Core.1.0.0-beta0008\lib\netstandard2.0\SixLabors.Core.dll @@ -113,7 +116,7 @@ True - ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0-preview.2.20160.6\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0-preview.3.20214.6\lib\net45\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll @@ -121,6 +124,7 @@ True + @@ -250,6 +254,6 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/PrusaSL1Viewer/packages.config b/PrusaSL1Viewer/packages.config index ba4b62b6..36aadb15 100644 --- a/PrusaSL1Viewer/packages.config +++ b/PrusaSL1Viewer/packages.config @@ -1,7 +1,8 @@  - + + @@ -16,7 +17,7 @@ - + diff --git a/PrusaSlicer/printer/Zortrax Inkspire.ini b/PrusaSlicer/printer/Zortrax Inkspire.ini new file mode 100644 index 00000000..bd672c33 --- /dev/null +++ b/PrusaSlicer/printer/Zortrax Inkspire.ini @@ -0,0 +1,37 @@ +# generated by PrusaSlicer 2.2.0+win64 on 2020-04-25 at 21:34:59 UTC +absolute_correction = 0 +area_fill = 50 +bed_custom_model = +bed_custom_texture = +bed_shape = 0x0,115x0,115x65,0x65 +default_sla_material_profile = Prusa Orange Tough 0.05 +default_sla_print_profile = 0.05 Normal +display_height = 74 +display_mirror_x = 1 +display_mirror_y = 0 +display_orientation = portrait +display_pixels_x = 2560 +display_pixels_y = 1440 +display_width = 132 +elefant_foot_compensation = 0.2 +elefant_foot_min_width = 0.2 +fast_tilt_time = 5 +gamma_correction = 1 +inherits = Original Prusa SL1 +max_exposure_time = 120 +max_initial_exposure_time = 300 +max_print_height = 175 +min_exposure_time = 1 +min_initial_exposure_time = 1 +print_host = +printer_model = SL1 +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_SL1\nPRINTER_VENDOR_EPAX\nPRINTER_MODEL_X1\n\nSTART_CUSTOM_VALUES\nExposureOffTime_5\nZLiftDistance_5\nZLiftFeedRate_100\nZLiftRetractRate_100\nEND_CUSTOM_VALUES +printer_settings_id = +printer_technology = SLA +printer_variant = default +printer_vendor = +printhost_apikey = +printhost_cafile = +relative_correction = 1,1 +slow_tilt_time = 8 +thumbnails = 400x400,800x480 diff --git a/README.md b/README.md index fe6f6384..fcd8ccca 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,25 @@ But also, i need victims for test subject. Proceed at your own risk! * SL1 (Prusa SL1) * CBDDLP (Chitubox DLP) * Photon - -## Configure printer under PrusaSlicer - -1. Import Epax X1 printer (PrusaSlicer -> printers) -1. Duplicate and tune the values if required -1. Look up under "Printer -> Notes" and configure parameters from target slicer +* ZCodex + +## Install and configure printer under PrusaSlicer + +1. Download and install PrusaSlicer from: https://www.prusa3d.com/prusaslicer/ +1. Start and configure PrusaSlicer (Wizard) + * Choose SL1 printer +1. Close PrusaSlicer +1. On different operating systems open: + * Windows: "%AppData%\PrusaSlicer" + * macOS: "/Users/[Username]/Library/Application Support/PrusaSlicer" + * Linux: + * Stable build: "~/.PrusaSlicer/" + * Alpha build: "~/.PrusaSlicer-alpha/" +1. Copy GitHub PrusaSlicer subfolder ("printer") to the folder above +1. Open PrusaSlicer and check if profiles are there +1. To clean up interface remove printers that you will not use (OPTIONAL) +1. Duplicate or create your printer and tune the values if required +1. Look up under "Printer -> Notes" and configure parameters to the target slicer 1. Change only the value after the "_" (underscore) ## Custom "Printer Notes" keywords