diff --git a/Scripts/010 Editor/ctb.bt b/Scripts/010 Editor/ctb.bt index c54041a..1377d2d 100644 --- a/Scripts/010 Editor/ctb.bt +++ b/Scripts/010 Editor/ctb.bt @@ -85,7 +85,7 @@ struct SLICER_INFO { uint MachineNameAddress ; uint MachineNameSize ; - uint EncryptionMode ; // 0/8 for cbddlp files, 0xF (15) for ctb files, 0x2000000F (536870927) for v3 ctb and 1073741839 for v4 ctb files to allow per layer parameters + uint PerLayerSettings ; // 0/8 for cbddlp files, 0xF (15) for ctb files, 0x2000000F (536870927) for v3 ctb and 1073741839 for v4 ctb files to allow per layer parameters uint MysteriousId ; // v3 = 305419896 | v4 lightoff? = 27093086 | v4 rest? = 27093090 uint AntiAliasLevel ; uint SoftwareVersion ; // ctb v3 = 17171200 | ctb v4 pro = 16777216 @@ -164,7 +164,7 @@ struct LAYER_DATA { uint DataAddress ; uint DataSize ; uint Unknown1 ; - uint Unknown2 ; + uint TableSize ; uint Unknown3 ; uint Unknown4 ; }; diff --git a/UVtools.Core/FileFormats/CTBEncryptedFile.cs b/UVtools.Core/FileFormats/CTBEncryptedFile.cs index a1697f2..d144d85 100644 --- a/UVtools.Core/FileFormats/CTBEncryptedFile.cs +++ b/UVtools.Core/FileFormats/CTBEncryptedFile.cs @@ -25,6 +25,9 @@ namespace UVtools.Core.FileFormats public const ushort RLE16EncodingLimit = 0xFFF; public const ushort RLEEncryptedMinimumLength = 512; + public const uint PERLAYER_SETTINGS_DISALLOW = 0xF; // 15 (This disallow per layer settings) + public const uint PERLAYER_SETTINGS_ALLOW = 0x5000000F; // 1342177295 (This allow per layer settings) + private const string CTB_DISCLAIMER = "Layout and record format for the ctb and cbddlp file types are the copyrighted programs or codes of CBD Technology (China) Inc..The Customer or User shall not in any manner reproduce, distribute, modify, decompile, disassemble, decrypt, extract, reverse engineer, lease, assign, or sublicense the said programs or codes."; private const ushort CTB_DISCLAIMER_SIZE = 320; @@ -41,9 +44,11 @@ namespace UVtools.Core.FileFormats public class FileHeader { + public const byte TABLE_SIZE = 48; + [FieldOrder(0)] public uint Magic { get; set; } = MAGIC_CBT_ENCRYPTED; - [FieldOrder(1)] public uint SettingsSize { get; set; } - [FieldOrder(2)] public uint SettingsOffset { get; set; } + [FieldOrder(1)] public uint SettingsSize { get; set; } = SlicerSettings.TABLE_SIZE; + [FieldOrder(2)] public uint SettingsOffset { get; set; } = TABLE_SIZE; [FieldOrder(3)] public uint Unknown1 { get; set; } // set to 0 [FieldOrder(4)] public uint Unknown2 { get; set; } = 4; // set to 4 [FieldOrder(5)] public uint SignatureSize { get; set; } @@ -63,6 +68,8 @@ namespace UVtools.Core.FileFormats public class SlicerSettings { + public const ushort TABLE_SIZE = 288; + private string _machineName; /// @@ -110,7 +117,7 @@ namespace UVtools.Core.FileFormats [FieldOrder(39)] public float RestTimeAfterLift { get; set; } [FieldOrder(40)] public uint MachineNameOffset { get; set; } [FieldOrder(41)] public uint MachineNameSize { get; set; } - [FieldOrder(42)] public uint Unknown12 { get; set; } = 15; + [FieldOrder(42)] public uint PerLayerSettings { get; set; } = PERLAYER_SETTINGS_DISALLOW; [FieldOrder(43)] public uint Unknown13 { get; set; } [FieldOrder(44)] public uint Unknown14 { get; set; } = 8; [FieldOrder(45)] public float RestTimeAfterRetract { get; set; } @@ -154,7 +161,7 @@ namespace UVtools.Core.FileFormats public override string ToString() { - return $"{nameof(Unknown15)}: {Unknown15}, {nameof(ChecksumValue)}: {ChecksumValue}, {nameof(LayerPointersOffset)}: {LayerPointersOffset}, {nameof(DisplayWidth)}: {DisplayWidth}, {nameof(DisplayHeight)}: {DisplayHeight}, {nameof(MachineZ)}: {MachineZ}, {nameof(Unknown1)}: {Unknown1}, {nameof(Unknown2)}: {Unknown2}, {nameof(TotalHeightMillimeter)}: {TotalHeightMillimeter}, {nameof(LayerHeight)}: {LayerHeight}, {nameof(ExposureTime)}: {ExposureTime}, {nameof(BottomExposureTime)}: {BottomExposureTime}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(BottomLayerCount)}: {BottomLayerCount}, {nameof(ResolutionX)}: {ResolutionX}, {nameof(ResolutionY)}: {ResolutionY}, {nameof(LayerCount)}: {LayerCount}, {nameof(LargePreviewOffset)}: {LargePreviewOffset}, {nameof(SmallPreviewOffset)}: {SmallPreviewOffset}, {nameof(PrintTime)}: {PrintTime}, {nameof(ProjectorType)}: {ProjectorType}, {nameof(BottomLiftHeight)}: {BottomLiftHeight}, {nameof(BottomLiftSpeed)}: {BottomLiftSpeed}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(MaterialMilliliters)}: {MaterialMilliliters}, {nameof(MaterialGrams)}: {MaterialGrams}, {nameof(MaterialCost)}: {MaterialCost}, {nameof(BottomLightOffDelay)}: {BottomLightOffDelay}, {nameof(Unknown9)}: {Unknown9}, {nameof(LightPWM)}: {LightPWM}, {nameof(BottomLightPWM)}: {BottomLightPWM}, {nameof(LayerXorKey)}: {LayerXorKey}, {nameof(BottomLiftHeight2)}: {BottomLiftHeight2}, {nameof(BottomLiftSpeed2)}: {BottomLiftSpeed2}, {nameof(LiftHeight2)}: {LiftHeight2}, {nameof(LiftSpeed2)}: {LiftSpeed2}, {nameof(RetractHeight2)}: {RetractHeight2}, {nameof(RetractSpeed2)}: {RetractSpeed2}, {nameof(RestTimeAfterLift)}: {RestTimeAfterLift}, {nameof(MachineNameOffset)}: {MachineNameOffset}, {nameof(MachineNameSize)}: {MachineNameSize}, {nameof(Unknown12)}: {Unknown12}, {nameof(Unknown13)}: {Unknown13}, {nameof(Unknown14)}: {Unknown14}, {nameof(RestTimeAfterRetract)}: {RestTimeAfterRetract}, {nameof(RestTimeAfterLift2)}: {RestTimeAfterLift2}, {nameof(BottomRetractSpeed)}: {BottomRetractSpeed}, {nameof(BottomRetractSpeed2)}: {BottomRetractSpeed2}, {nameof(Four1)}: {Four1}, {nameof(Padding1)}: {Padding1}, {nameof(Four2)}: {Four2}, {nameof(Padding2)}: {Padding2}, {nameof(RestTimeAfterRetract2)}: {RestTimeAfterRetract2}, {nameof(RestTimeAfterLift3)}: {RestTimeAfterLift3}, {nameof(RestTimeBeforeLift)}: {RestTimeBeforeLift}, {nameof(BottomRetractHeight2)}: {BottomRetractHeight2}, {nameof(Unknown23)}: {Unknown23}, {nameof(Unknown24)}: {Unknown24}, {nameof(Unknown25)}: {Unknown25}, {nameof(LastLayerIndex)}: {LastLayerIndex}, {nameof(Padding3)}: {Padding3}, {nameof(Padding4)}: {Padding4}, {nameof(Padding5)}: {Padding5}, {nameof(Padding6)}: {Padding6}, {nameof(DisclaimerOffset)}: {DisclaimerOffset}, {nameof(DisclaimerSize)}: {DisclaimerSize}, {nameof(Padding7)}: {Padding7}, {nameof(Padding8)}: {Padding8}, {nameof(Padding9)}: {Padding9}, {nameof(Padding10)}: {Padding10}, {nameof(MachineName)}: {MachineName}"; + return $"{nameof(Unknown15)}: {Unknown15}, {nameof(ChecksumValue)}: {ChecksumValue}, {nameof(LayerPointersOffset)}: {LayerPointersOffset}, {nameof(DisplayWidth)}: {DisplayWidth}, {nameof(DisplayHeight)}: {DisplayHeight}, {nameof(MachineZ)}: {MachineZ}, {nameof(Unknown1)}: {Unknown1}, {nameof(Unknown2)}: {Unknown2}, {nameof(TotalHeightMillimeter)}: {TotalHeightMillimeter}, {nameof(LayerHeight)}: {LayerHeight}, {nameof(ExposureTime)}: {ExposureTime}, {nameof(BottomExposureTime)}: {BottomExposureTime}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(BottomLayerCount)}: {BottomLayerCount}, {nameof(ResolutionX)}: {ResolutionX}, {nameof(ResolutionY)}: {ResolutionY}, {nameof(LayerCount)}: {LayerCount}, {nameof(LargePreviewOffset)}: {LargePreviewOffset}, {nameof(SmallPreviewOffset)}: {SmallPreviewOffset}, {nameof(PrintTime)}: {PrintTime}, {nameof(ProjectorType)}: {ProjectorType}, {nameof(BottomLiftHeight)}: {BottomLiftHeight}, {nameof(BottomLiftSpeed)}: {BottomLiftSpeed}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(MaterialMilliliters)}: {MaterialMilliliters}, {nameof(MaterialGrams)}: {MaterialGrams}, {nameof(MaterialCost)}: {MaterialCost}, {nameof(BottomLightOffDelay)}: {BottomLightOffDelay}, {nameof(Unknown9)}: {Unknown9}, {nameof(LightPWM)}: {LightPWM}, {nameof(BottomLightPWM)}: {BottomLightPWM}, {nameof(LayerXorKey)}: {LayerXorKey}, {nameof(BottomLiftHeight2)}: {BottomLiftHeight2}, {nameof(BottomLiftSpeed2)}: {BottomLiftSpeed2}, {nameof(LiftHeight2)}: {LiftHeight2}, {nameof(LiftSpeed2)}: {LiftSpeed2}, {nameof(RetractHeight2)}: {RetractHeight2}, {nameof(RetractSpeed2)}: {RetractSpeed2}, {nameof(RestTimeAfterLift)}: {RestTimeAfterLift}, {nameof(MachineNameOffset)}: {MachineNameOffset}, {nameof(MachineNameSize)}: {MachineNameSize}, {nameof(PerLayerSettings)}: {PerLayerSettings}, {nameof(Unknown13)}: {Unknown13}, {nameof(Unknown14)}: {Unknown14}, {nameof(RestTimeAfterRetract)}: {RestTimeAfterRetract}, {nameof(RestTimeAfterLift2)}: {RestTimeAfterLift2}, {nameof(BottomRetractSpeed)}: {BottomRetractSpeed}, {nameof(BottomRetractSpeed2)}: {BottomRetractSpeed2}, {nameof(Four1)}: {Four1}, {nameof(Padding1)}: {Padding1}, {nameof(Four2)}: {Four2}, {nameof(Padding2)}: {Padding2}, {nameof(RestTimeAfterRetract2)}: {RestTimeAfterRetract2}, {nameof(RestTimeAfterLift3)}: {RestTimeAfterLift3}, {nameof(RestTimeBeforeLift)}: {RestTimeBeforeLift}, {nameof(BottomRetractHeight2)}: {BottomRetractHeight2}, {nameof(Unknown23)}: {Unknown23}, {nameof(Unknown24)}: {Unknown24}, {nameof(Unknown25)}: {Unknown25}, {nameof(LastLayerIndex)}: {LastLayerIndex}, {nameof(Padding3)}: {Padding3}, {nameof(Padding4)}: {Padding4}, {nameof(Padding5)}: {Padding5}, {nameof(Padding6)}: {Padding6}, {nameof(DisclaimerOffset)}: {DisclaimerOffset}, {nameof(DisclaimerSize)}: {DisclaimerSize}, {nameof(Padding7)}: {Padding7}, {nameof(Padding8)}: {Padding8}, {nameof(Padding9)}: {Padding9}, {nameof(Padding10)}: {Padding10}, {nameof(MachineName)}: {MachineName}"; } } @@ -162,7 +169,7 @@ namespace UVtools.Core.FileFormats { [FieldOrder(0)] public uint LayerOffset { get; set; } [FieldOrder(1)] public uint Padding1 { get; set; } // 0 - [FieldOrder(2)] public uint LayerTableSize { get; set; } = LayerDef.TableSize; // always 0x58 + [FieldOrder(2)] public uint LayerTableSize { get; set; } = LayerDef.TABLE_SIZE; // always 0x58 [FieldOrder(3)] public uint Padding2 { get; set; } // 0 public override string ToString() @@ -182,9 +189,9 @@ namespace UVtools.Core.FileFormats public class LayerDef { - public const byte TableSize = 88; + public const byte TABLE_SIZE = 88; - [FieldOrder(0)] public uint LayerHeaderSize { get; set; } = TableSize; + [FieldOrder(0)] public uint TableSize { get; set; } = TABLE_SIZE; [FieldOrder(1)] public float PositionZ { get; set; } [FieldOrder(2)] public float ExposureTime { get; set; } [FieldOrder(3)] public float LightOffDelay { get; set; } @@ -222,7 +229,6 @@ namespace UVtools.Core.FileFormats public void SetFrom(Layer layer) { - PositionZ = layer.PositionZ; ExposureTime = layer.ExposureTime; LightOffDelay = layer.LightOffDelay; @@ -421,7 +427,7 @@ namespace UVtools.Core.FileFormats public override string ToString() { - return $"{nameof(LayerHeaderSize)}: {LayerHeaderSize}, {nameof(PositionZ)}: {PositionZ}, {nameof(ExposureTime)}: {ExposureTime}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(LayerDefOffset)}: {LayerDefOffset}, {nameof(Unknown2)}: {Unknown2}, {nameof(DataLength)}: {DataLength}, {nameof(Unknown3)}: {Unknown3}, {nameof(EncryptedDataOffset)}: {EncryptedDataOffset}, {nameof(EncryptedDataLength)}: {EncryptedDataLength}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(LiftHeight2)}: {LiftHeight2}, {nameof(LiftSpeed2)}: {LiftSpeed2}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(RetractHeight2)}: {RetractHeight2}, {nameof(RetractSpeed2)}: {RetractSpeed2}, {nameof(RestTimeBeforeLift)}: {RestTimeBeforeLift}, {nameof(RestTimeAfterLift)}: {RestTimeAfterLift}, {nameof(RestTimeAfterRetract)}: {RestTimeAfterRetract}, {nameof(LightPWM)}: {LightPWM}, {nameof(Unknown6)}: {Unknown6}, {nameof(RLEData)}: {RLEData?.Length}"; + return $"{nameof(TableSize)}: {TableSize}, {nameof(PositionZ)}: {PositionZ}, {nameof(ExposureTime)}: {ExposureTime}, {nameof(LightOffDelay)}: {LightOffDelay}, {nameof(LayerDefOffset)}: {LayerDefOffset}, {nameof(Unknown2)}: {Unknown2}, {nameof(DataLength)}: {DataLength}, {nameof(Unknown3)}: {Unknown3}, {nameof(EncryptedDataOffset)}: {EncryptedDataOffset}, {nameof(EncryptedDataLength)}: {EncryptedDataLength}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(LiftHeight2)}: {LiftHeight2}, {nameof(LiftSpeed2)}: {LiftSpeed2}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(RetractHeight2)}: {RetractHeight2}, {nameof(RetractSpeed2)}: {RetractSpeed2}, {nameof(RestTimeBeforeLift)}: {RestTimeBeforeLift}, {nameof(RestTimeAfterLift)}: {RestTimeAfterLift}, {nameof(RestTimeAfterRetract)}: {RestTimeAfterRetract}, {nameof(LightPWM)}: {LightPWM}, {nameof(Unknown6)}: {Unknown6}, {nameof(RLEData)}: {RLEData?.Length}"; } } @@ -1046,6 +1052,13 @@ namespace UVtools.Core.FileFormats return false; } + private void SanitizeProperties() + { + Settings.PerLayerSettings = LayerManager.AllLayersHaveGlobalParameters + ? PERLAYER_SETTINGS_DISALLOW + : PERLAYER_SETTINGS_ALLOW; + } + protected override void DecodeInternally(string fileFullPath, OperationProgress progress) { @@ -1224,14 +1237,10 @@ namespace UVtools.Core.FileFormats /* Create the file header and fill out what we can. SignatureOffset will have to be populated later * this will be the last thing written to file */ - Header.Magic = MAGIC_CBT_ENCRYPTED; Header.SettingsSize = (uint)Helpers.Serializer.SizeOf(Settings); Header.SettingsOffset = (uint)Helpers.Serializer.SizeOf(Header); - Header.Unknown2 = 4; - Header.Unknown4 = 1; - Header.Unknown5 = 1; - Header.Unknown5 = 42; + SanitizeProperties(); if (Settings.LayerXorKey == 0) { @@ -1313,7 +1322,7 @@ namespace UVtools.Core.FileFormats var layerDef = LayersDefinition[layerIndex]; LayersPointer[layerIndex] = new LayerPointer((uint)outputFile.Position); - layerDef.LayerDefOffset = LayersPointer[layerIndex].LayerOffset + LayerDef.TableSize; + layerDef.LayerDefOffset = LayersPointer[layerIndex].LayerOffset + LayerDef.TABLE_SIZE; Helpers.SerializeWriteFileStream(outputFile, layerDef); outputFile.WriteBytes(layerDef.RLEData); progress++; @@ -1365,6 +1374,8 @@ namespace UVtools.Core.FileFormats FileFullPath = filePath; } + SanitizeProperties(); + using var outputFile = new FileStream(FileFullPath, FileMode.Open, FileAccess.Write); outputFile.Seek(Header.SettingsOffset, SeekOrigin.Begin); diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs index 711c871..1762b3a 100644 --- a/UVtools.Core/FileFormats/ChituboxFile.cs +++ b/UVtools.Core/FileFormats/ChituboxFile.cs @@ -39,10 +39,11 @@ namespace UVtools.Core.FileFormats public const byte RLE8EncodingLimit = 0x7d; // 125; public const ushort RLE16EncodingLimit = 0xFFF; - public const uint ENCRYPTYION_MODE_CBDDLP = 0x8; // 0 or 8 - public const uint ENCRYPTYION_MODE_CTBv2 = 0xF; // 15 for ctb v2 files - public const uint ENCRYPTYION_MODE_CTBv3 = 536870927; // 536870927 for ctb v3 files (This allow per layer settings, while 15 don't) - public const uint ENCRYPTYION_MODE_CTBv4 = 1073741839; // 1073741839 for ctb v4 files (This allow per layer settings, while 15 don't) + public const uint PERLAYER_SETTINGS_CBDDLP = 0x8; // 0 or 8 (This disallow per layer settings) + public const uint PERLAYER_SETTINGS_DISALLOW = 0xF; // 15 (This disallow per layer settings) + public const uint PERLAYER_SETTINGS_CTBv2 = 0xF; // 15 for ctb v2 files and others (This disallow per layer settings) + public const uint PERLAYER_SETTINGS_CTBv3 = 0x2000000F; // 536870927 for ctb v3 files (This allow per layer settings, while 15 don't) + public const uint PERLAYER_SETTINGS_CTBv4 = 0x4000000F; // 1073741839 for ctb v4 files (This allow per layer settings, while 15 don't) private const string CTBv4_DISCLAIMER = "Layout and record format for the ctb and cbddlp file types are the copyrighted programs or codes of CBD Technology (China) Inc..The Customer or User shall not in any manner reproduce, distribute, modify, decompile, disassemble, decrypt, extract, reverse engineer, lease, assign, or sublicense the said programs or codes."; private const ushort CTBv4_DISCLAIMER_SIZE = 320; @@ -304,7 +305,7 @@ namespace UVtools.Core.FileFormats /// Gets the parameter used to control encryption. /// Not totally understood. 0/8 for cbddlp files, 0xF (15) for ctb files, 0x2000000F (536870927) for v3 ctb and 1073741839 for v4 ctb files to allow per layer parameters /// - [FieldOrder(9)] public uint EncryptionMode { get; set; } = ENCRYPTYION_MODE_CTBv3; + [FieldOrder(9)] public uint PerLayerSettings { get; set; } = PERLAYER_SETTINGS_CTBv3; /// /// Gets a number that increments with time or number of models sliced, or both. Zeroing it in output seems to have no effect. Possibly a user tracking bug. @@ -349,7 +350,7 @@ namespace UVtools.Core.FileFormats public override string ToString() { - return $"{nameof(BottomLiftHeight2)}: {BottomLiftHeight2}, {nameof(BottomLiftSpeed2)}: {BottomLiftSpeed2}, {nameof(LiftHeight2)}: {LiftHeight2}, {nameof(LiftSpeed2)}: {LiftSpeed2}, {nameof(RetractHeight2)}: {RetractHeight2}, {nameof(RetractSpeed2)}: {RetractSpeed2}, {nameof(RestTimeAfterLift)}: {RestTimeAfterLift}, {nameof(MachineNameAddress)}: {MachineNameAddress}, {nameof(MachineNameSize)}: {MachineNameSize}, {nameof(EncryptionMode)}: {EncryptionMode}, {nameof(MysteriousId)}: {MysteriousId}, {nameof(AntiAliasLevel)}: {AntiAliasLevel}, {nameof(SoftwareVersion)}: {SoftwareVersion}, {nameof(RestTimeAfterRetract)}: {RestTimeAfterRetract}, {nameof(RestTimeAfterLift2)}: {RestTimeAfterLift2}, {nameof(TransitionLayerCount)}: {TransitionLayerCount}, {nameof(PrintParametersV4Address)}: {PrintParametersV4Address}, {nameof(Padding2)}: {Padding2}, {nameof(Padding3)}: {Padding3}, {nameof(MachineName)}: {MachineName}"; + return $"{nameof(BottomLiftHeight2)}: {BottomLiftHeight2}, {nameof(BottomLiftSpeed2)}: {BottomLiftSpeed2}, {nameof(LiftHeight2)}: {LiftHeight2}, {nameof(LiftSpeed2)}: {LiftSpeed2}, {nameof(RetractHeight2)}: {RetractHeight2}, {nameof(RetractSpeed2)}: {RetractSpeed2}, {nameof(RestTimeAfterLift)}: {RestTimeAfterLift}, {nameof(MachineNameAddress)}: {MachineNameAddress}, {nameof(MachineNameSize)}: {MachineNameSize}, {nameof(PerLayerSettings)}: {PerLayerSettings}, {nameof(MysteriousId)}: {MysteriousId}, {nameof(AntiAliasLevel)}: {AntiAliasLevel}, {nameof(SoftwareVersion)}: {SoftwareVersion}, {nameof(RestTimeAfterRetract)}: {RestTimeAfterRetract}, {nameof(RestTimeAfterLift2)}: {RestTimeAfterLift2}, {nameof(TransitionLayerCount)}: {TransitionLayerCount}, {nameof(PrintParametersV4Address)}: {PrintParametersV4Address}, {nameof(Padding2)}: {Padding2}, {nameof(Padding3)}: {Padding3}, {nameof(MachineName)}: {MachineName}"; } } @@ -581,15 +582,17 @@ namespace UVtools.Core.FileFormats #region Layer public class LayerDef { + public const byte TABLE_SIZE = 36; + /// /// Gets the build platform Z position for this layer, measured in millimeters. /// - [FieldOrder(0)] public float PositionZ { get; set; } + [FieldOrder(0)] public float PositionZ { get; set; } /// /// Gets the exposure time for this layer, in seconds. /// - [FieldOrder(1)] public float ExposureTime { get; set; } + [FieldOrder(1)] public float ExposureTime { get; set; } /// /// Gets how long to keep the light off after exposing this layer, in seconds. @@ -599,34 +602,29 @@ namespace UVtools.Core.FileFormats /// /// Gets the layer image offset to encoded layer data, and its length in bytes. /// - [FieldOrder(3)] public uint DataAddress { get; set; } + [FieldOrder(3)] public uint DataAddress { get; set; } /// /// Gets the layer image length in bytes. /// - [FieldOrder(4)] public uint DataSize { get; set; } - [FieldOrder(5)] public uint Unknown1 { get; set; } - [FieldOrder(6)] public uint Unknown2 { get; set; }// = 84; // Spoted on Mars 2 Pro - [FieldOrder(7)] public uint Unknown3 { get; set; } - [FieldOrder(8)] public uint Unknown4 { get; set; } + [FieldOrder(4)] public uint DataSize { get; set; } + [FieldOrder(5)] public uint Unknown1 { get; set; } + [FieldOrder(6)] public uint TableSize { get; set; } = TABLE_SIZE; + [FieldOrder(7)] public uint Unknown3 { get; set; } + [FieldOrder(8)] public uint Unknown4 { get; set; } [Ignore] public byte[] EncodedRle { get; set; } [Ignore] public ChituboxFile Parent { get; set; } - public LayerDef() - { - } + public LayerDef() { } public LayerDef(ChituboxFile parent, Layer layer) { Parent = parent; SetFrom(layer); - if (parent.HeaderSettings.Version >= 3 && Unknown2 == 0) - { - Unknown2 = 84; - } + TableSize = parent.HeaderSettings.Version <= 2 ? TABLE_SIZE : LayerDefEx.TABLE_SIZE; } public void SetFrom(Layer layer) @@ -952,12 +950,13 @@ namespace UVtools.Core.FileFormats public override string ToString() { - return $"{nameof(PositionZ)}: {PositionZ}, {nameof(ExposureTime)}: {ExposureTime}, {nameof(LightOffSeconds)}: {LightOffSeconds}, {nameof(DataAddress)}: {DataAddress}, {nameof(DataSize)}: {DataSize}, {nameof(Unknown1)}: {Unknown1}, {nameof(Unknown2)}: {Unknown2}, {nameof(Unknown3)}: {Unknown3}, {nameof(Unknown4)}: {Unknown4}"; + return $"{nameof(PositionZ)}: {PositionZ}, {nameof(ExposureTime)}: {ExposureTime}, {nameof(LightOffSeconds)}: {LightOffSeconds}, {nameof(DataAddress)}: {DataAddress}, {nameof(DataSize)}: {DataSize}, {nameof(Unknown1)}: {Unknown1}, {nameof(TableSize)}: {TableSize}, {nameof(Unknown3)}: {Unknown3}, {nameof(Unknown4)}: {Unknown4}"; } } public class LayerDefEx { + public const byte TABLE_SIZE = 48; /// /// Gets a copy of layer data definition /// @@ -1738,7 +1737,7 @@ namespace UVtools.Core.FileFormats if (HeaderSettings.Version <= 2) { - SlicerInfoSettings.EncryptionMode = ENCRYPTYION_MODE_CTBv2; + SlicerInfoSettings.PerLayerSettings = PERLAYER_SETTINGS_CTBv2; PrintParametersSettings.Padding4 = 0x1234; // 4660 if (SlicerInfoSettings.MysteriousId == 0) @@ -1746,14 +1745,14 @@ namespace UVtools.Core.FileFormats } else if (HeaderSettings.Version == 3) { - SlicerInfoSettings.EncryptionMode = ENCRYPTYION_MODE_CTBv3; + SlicerInfoSettings.PerLayerSettings = LayerManager.AllLayersHaveGlobalParameters ? PERLAYER_SETTINGS_DISALLOW : PERLAYER_SETTINGS_CTBv3; if (SlicerInfoSettings.MysteriousId == 0) SlicerInfoSettings.MysteriousId = 305419896; } else if (HeaderSettings.Version >= 4) { - SlicerInfoSettings.EncryptionMode = ENCRYPTYION_MODE_CTBv4; + SlicerInfoSettings.PerLayerSettings = LayerManager.AllLayersHaveGlobalParameters ? PERLAYER_SETTINGS_DISALLOW : PERLAYER_SETTINGS_CTBv4; if (SlicerInfoSettings.MysteriousId == 0) SlicerInfoSettings.MysteriousId = 27087820; @@ -1806,7 +1805,7 @@ namespace UVtools.Core.FileFormats { //HeaderSettings.Version = 2; HeaderSettings.EncryptionKey = 0; // Force disable encryption - SlicerInfoSettings.EncryptionMode = ENCRYPTYION_MODE_CBDDLP; + SlicerInfoSettings.PerLayerSettings = PERLAYER_SETTINGS_CBDDLP; } //uint currentOffset = (uint)Helpers.Serializer.SizeOf(HeaderSettings); diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs index bbd1bf1..d88f226 100644 --- a/UVtools.Core/Layer/Layer.cs +++ b/UVtools.Core/Layer/Layer.cs @@ -133,9 +133,18 @@ namespace UVtools.Core public uint Index { get => _index; - set => RaiseAndSetIfChanged(ref _index, value); + set + { + if(!RaiseAndSetIfChanged(ref _index, value)) return; + RaisePropertyChanged(nameof(Number)); + } } + /// + /// Gets the layer number, 1 started + /// + public uint Number => _index + 1; + /// /// Gets or sets the layer position on Z in mm /// @@ -492,38 +501,42 @@ namespace UVtools.Core if (IsBottomLayer) { if ( - LightOffDelay != SlicerFile.BottomLightOffDelay || - WaitTimeBeforeCure != SlicerFile.BottomWaitTimeBeforeCure || - ExposureTime != SlicerFile.BottomExposureTime || - WaitTimeBeforeCure != SlicerFile.BottomWaitTimeBeforeCure || - LiftHeight != SlicerFile.BottomLiftHeight || - LiftSpeed != SlicerFile.BottomLiftSpeed || - LiftHeight2 != SlicerFile.BottomLiftHeight2 || - LiftSpeed2 != SlicerFile.BottomLiftSpeed2 || - WaitTimeAfterLift != SlicerFile.BottomWaitTimeAfterLift || - RetractSpeed != SlicerFile.BottomRetractSpeed || - RetractHeight2 != SlicerFile.BottomRetractHeight2 || - RetractSpeed2 != SlicerFile.BottomRetractSpeed2 || - LightPWM != SlicerFile.BottomLightPWM - ) return false; + _positionZ != RoundHeight(SlicerFile.LayerHeight * Number) || + _lightOffDelay != SlicerFile.BottomLightOffDelay || + _waitTimeBeforeCure != SlicerFile.BottomWaitTimeBeforeCure || + _exposureTime != SlicerFile.BottomExposureTime || + _waitTimeAfterCure != SlicerFile.BottomWaitTimeAfterCure || + _liftHeight != SlicerFile.BottomLiftHeight || + _liftSpeed != SlicerFile.BottomLiftSpeed || + _liftHeight2 != SlicerFile.BottomLiftHeight2 || + _liftSpeed2 != SlicerFile.BottomLiftSpeed2 || + _waitTimeAfterLift != SlicerFile.BottomWaitTimeAfterLift || + _retractSpeed != SlicerFile.BottomRetractSpeed || + _retractHeight2 != SlicerFile.BottomRetractHeight2 || + _retractSpeed2 != SlicerFile.BottomRetractSpeed2 || + _lightPwm != SlicerFile.BottomLightPWM + ) + return false; } else { if ( - LightOffDelay != SlicerFile.LightOffDelay || - WaitTimeBeforeCure != SlicerFile.WaitTimeBeforeCure || - ExposureTime != SlicerFile.ExposureTime || - WaitTimeAfterCure != SlicerFile.WaitTimeAfterCure || - LiftHeight != SlicerFile.LiftHeight || - LiftSpeed != SlicerFile.LiftSpeed || - LiftHeight2 != SlicerFile.LiftHeight2 || - LiftSpeed2 != SlicerFile.LiftSpeed2 || - WaitTimeAfterLift != SlicerFile.WaitTimeAfterLift || - RetractSpeed != SlicerFile.RetractSpeed || - RetractHeight2 != SlicerFile.RetractHeight2 || - RetractSpeed2 != SlicerFile.RetractSpeed2 || - LightPWM != SlicerFile.LightPWM - ) return false; + _positionZ != RoundHeight(SlicerFile.LayerHeight * Number) || + _lightOffDelay != SlicerFile.LightOffDelay || + _waitTimeBeforeCure != SlicerFile.WaitTimeBeforeCure || + _exposureTime != SlicerFile.ExposureTime || + _waitTimeAfterCure != SlicerFile.WaitTimeAfterCure || + _liftHeight != SlicerFile.LiftHeight || + _liftSpeed != SlicerFile.LiftSpeed || + _liftHeight2 != SlicerFile.LiftHeight2 || + _liftSpeed2 != SlicerFile.LiftSpeed2 || + _waitTimeAfterLift != SlicerFile.WaitTimeAfterLift || + _retractSpeed != SlicerFile.RetractSpeed || + _retractHeight2 != SlicerFile.RetractHeight2 || + _retractSpeed2 != SlicerFile.RetractSpeed2 || + _lightPwm != SlicerFile.LightPWM + ) + return false; } return true;