- **File Formats:**
   - (Add) SL1S: Prusa SL1S Speed
   - (Add) CTB v4 support (318570758)
   - (Improvement) PHOTON, CBDDLP, CTB v2, PHZ: Disallow per layer settings, beside the format support, printers never use it
   - (Improvement) Longer Orange format with new found keys
   - (Improvement) CXDLP: Fix the resolution from CL-60 and trigger an error when a invalid resolution was set and unable to detect the printer model
- **Prusa Slicer:**
   - (Add) UVtools Prusa SL1S SPEED
   - (Add) Longer Orange 120
   - (Fix) Creality HALOT-ONE CL-60: Flip resolution & display and remove mirror
   - (Fix) Creality HALOT-SKY CL-89: Remove mirror
   - (Improvement) Longer Orange printers with better default settings
- (Add) Button on `Help - Sponsor`: Open github sponsor webpage
This commit is contained in:
Tiago Conceição
2021-07-03 01:16:17 +01:00
parent 2329074efb
commit ac51b7c4e0
33 changed files with 1008 additions and 206 deletions
+16
View File
@@ -1,5 +1,21 @@
# Changelog
## 03/06/2021 - v2.14.0
- **File Formats:**
- (Add) SL1S: Prusa SL1S Speed
- (Add) CTB v4 support (318570758)
- (Improvement) PHOTON, CBDDLP, CTB v2, PHZ: Disallow per layer settings, beside the format support, printers never use it
- (Improvement) Longer Orange format with new found keys
- (Improvement) CXDLP: Fix the resolution from CL-60 and trigger an error when a invalid resolution was set and unable to detect the printer model
- **Prusa Slicer:**
- (Add) UVtools Prusa SL1S SPEED
- (Add) Longer Orange 120
- (Fix) Creality HALOT-ONE CL-60: Flip resolution & display and remove mirror
- (Fix) Creality HALOT-SKY CL-89: Remove mirror
- (Improvement) Longer Orange printers with better default settings
- (Add) Button on `Help - Sponsor`: Open github sponsor webpage
## 25/06/2021 - v2.13.4
- (Fix) ZCode: lcd.gcode was blank / not generating when converting from any file format
@@ -1,18 +1,18 @@
# generated by PrusaSlicer 2.3.1+win64 on 2021-06-08 at 21:10:32 UTC
# generated by PrusaSlicer 2.3.1+win64 on 2021-07-02 at 17:30:53 UTC
absolute_correction = 0
area_fill = 50
bed_custom_model =
bed_custom_texture =
bed_shape = 0x0,130x0,130x82,0x82
bed_shape = 0x0,81x0,81x128,0x128
default_sla_material_profile = Prusa Orange Tough 0.05
default_sla_print_profile = 0.05 Normal
display_height = 82
display_mirror_x = 1
display_height = 128
display_mirror_x = 0
display_mirror_y = 0
display_orientation = landscape
display_pixels_x = 2560
display_pixels_y = 1620
display_width = 130
display_pixels_x = 1620
display_pixels_y = 2560
display_width = 81
elefant_foot_compensation = 0.2
elefant_foot_min_width = 0.2
fast_tilt_time = 5
@@ -1,4 +1,4 @@
# generated by PrusaSlicer 2.3.0+win64 on 2021-04-14 at 04:53:05 UTC
# generated by PrusaSlicer 2.3.1+win64 on 2021-07-02 at 17:32:15 UTC
absolute_correction = 0
area_fill = 50
bed_custom_model =
@@ -7,7 +7,7 @@ bed_shape = 0x0,192x0,192x120,0x120
default_sla_material_profile = Prusa Orange Tough 0.05
default_sla_print_profile = 0.05 Normal
display_height = 120
display_mirror_x = 1
display_mirror_x = 0
display_mirror_y = 0
display_orientation = landscape
display_pixels_x = 3840
+2 -2
View File
@@ -1,4 +1,4 @@
# generated by PrusaSlicer 2.3.0+win64 on 2021-01-13 at 02:36:09 UTC
# generated by PrusaSlicer 2.3.1+win64 on 2021-06-26 at 12:15:10 UTC
absolute_correction = 0
area_fill = 50
bed_custom_model =
@@ -26,7 +26,7 @@ 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_LONGER\nPRINTER_MODEL_ORANGE10\nFILEFORMAT_LGS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_4\nLiftHeight_2\nBottomLiftSpeed_90\nLiftSpeed_150\nEND_CUSTOM_VALUES
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_LONGER\nPRINTER_MODEL_ORANGE10\nFILEFORMAT_LGS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_4\nLiftHeight_4\nBottomLiftSpeed_90\nLiftSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
+38
View File
@@ -0,0 +1,38 @@
# generated by PrusaSlicer 2.3.1+win64 on 2021-06-26 at 11:55:17 UTC
absolute_correction = 0
area_fill = 50
bed_custom_model =
bed_custom_texture =
bed_shape = 0x0,68.04x0,68.04x120.96,0x120.96
default_sla_material_profile = Prusa Orange Tough 0.05
default_sla_print_profile = 0.05 Normal
display_height = 120.96
display_mirror_x = 1
display_mirror_y = 0
display_orientation = landscape
display_pixels_x = 1440
display_pixels_y = 2560
display_width = 68.04
elefant_foot_compensation = 0.2
elefant_foot_min_width = 0.2
fast_tilt_time = 5
gamma_correction = 1
host_type = octoprint
inherits = Original Prusa SL1
max_exposure_time = 120
max_initial_exposure_time = 300
max_print_height = 150
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_LONGER\nPRINTER_MODEL_ORANGE120\nFILEFORMAT_LGS120\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_4\nLiftHeight_4\nBottomLiftSpeed_90\nLiftSpeed_150\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
+2 -2
View File
@@ -1,4 +1,4 @@
# generated by PrusaSlicer 2.3.0+win64 on 2021-01-13 at 03:51:46 UTC
# generated by PrusaSlicer 2.3.1+win64 on 2021-06-26 at 11:58:44 UTC
absolute_correction = 0
area_fill = 50
bed_custom_model =
@@ -26,7 +26,7 @@ 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_LONGER\nPRINTER_MODEL_ORANGE30\nFILEFORMAT_LGS30\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_2\nLiftHeight_2\nBottomLiftSpeed_48\nLiftSpeed_150\nEND_CUSTOM_VALUES
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_LONGER\nPRINTER_MODEL_ORANGE30\nFILEFORMAT_LGS30\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_4\nLiftHeight_4\nBottomLiftSpeed_90\nLiftSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
@@ -1,4 +1,4 @@
# generated by PrusaSlicer 2.3.0+win64 on 2021-01-13 at 02:35:56 UTC
# generated by PrusaSlicer 2.3.1+win64 on 2021-06-28 at 08:59:40 UTC
absolute_correction = 0
area_fill = 50
bed_custom_model =
@@ -21,12 +21,12 @@ host_type = octoprint
inherits = Original Prusa SL1
max_exposure_time = 120
max_initial_exposure_time = 300
max_print_height = 170
max_print_height = 190
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_LONGER\nPRINTER_MODEL_ORANGE30\nFILEFORMAT_LGS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_2\nLiftHeight_2\nBottomLiftSpeed_90\nLiftSpeed_150\nEND_CUSTOM_VALUES
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_LONGER\nPRINTER_MODEL_ORANGE4K\nFILEFORMAT_LGS4K\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_4\nLiftHeight_4\nBottomLiftSpeed_90\nLiftSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
@@ -0,0 +1,38 @@
# generated by PrusaSlicer 2.3.1+win64 on 2021-07-02 at 10:34:03 UTC
absolute_correction = 0
area_fill = 45
bed_custom_model =
bed_custom_texture =
bed_shape = 0.5x0.5,127.5x0.5,127.5x80.5,0.5x80.5
default_sla_material_profile = Prusa Orange Tough @0.05 SL1S
default_sla_print_profile = 0.05 Normal @SL1S
display_height = 81
display_mirror_x = 1
display_mirror_y = 0
display_orientation = landscape
display_pixels_x = 1620
display_pixels_y = 2560
display_width = 128
elefant_foot_compensation = 0.2
elefant_foot_min_width = 0.2
fast_tilt_time = 2.5
gamma_correction = 1
host_type = octoprint
inherits = Original Prusa SL1S SPEED
max_exposure_time = 120
max_initial_exposure_time = 300
max_print_height = 150
min_exposure_time = 1
min_initial_exposure_time = 1
print_host =
printer_model = SL1S
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_SL1S\n
printer_settings_id =
printer_technology = SLA
printer_variant = default
printer_vendor =
printhost_apikey =
printhost_cafile =
relative_correction = 1,1
slow_tilt_time = 5
thumbnails = 400x400,800x480
+9 -4
View File
@@ -55,6 +55,7 @@ But also, i need victims for test subject. Proceed at your own risk!
# Known File Formats
* SL1 (PrusaSlicer)
* SL1S (PrusaSlicer)
* Zip (Chitubox)
* Photon (Chitubox)
* Photons (Chitubox)
@@ -78,6 +79,8 @@ But also, i need victims for test subject. Proceed at your own risk!
* CXDLP (Creality Box)
* LGS (Longer Orange 10)
* LGS30 (Longer Orange 30)
* LGS120 (Longer Orange 120)
* LGS4K (Longer Orange 4K & mono)
* VDA.ZIP (Voxeldance Additive)
* VDT (Voxeldance Tango)
* UVJ (Zip file format for manual manipulation)
@@ -139,8 +142,8 @@ But also, i need victims for test subject. Proceed at your own risk!
* LD-002R
* LD-002H
* LD-006
* HALOT-ONE CL-60
* HALOT-SKY CL-89
* HALOT-SKY CL-60
* **Voxelab**
* Polaris 5.5
* Proxima 6
@@ -148,7 +151,8 @@ But also, i need victims for test subject. Proceed at your own risk!
* **Longer**
* Orange 10
* Orange 30
* Orange4K
* Orange 120
* Orange 4K
* **Uniz IBEE**
* **Zortrax Inkspire**
@@ -437,7 +441,7 @@ The fastest way to compile the project is by run the `build/CompileWindows.bat`,
# TODO
* More file formats
* Clean up (always)
* Clean up & performance (always)
* See features request under Github
# Support my work / Donate
@@ -445,4 +449,5 @@ The fastest way to compile the project is by run the `build/CompileWindows.bat`,
All my work here is given for free (OpenSource), it took some hours to build, test and polish the program.
If you're happy to contribute for a better program and for my work i will appreciate the tip.
PP: https://paypal.me/SkillTournament
Sponsor: https://github.com/sponsors/sn4k3
PayPal: https://paypal.me/SkillTournament
+61 -59
View File
@@ -8,65 +8,67 @@ SET PRINT_DIR=sla_print
SET PRINTER_DIR=printer
SET files[0]=UVtools Prusa SL1.ini
SET files[1]=EPAX E6 Mono.ini
SET files[2]=EPAX E10 Mono.ini
SET files[3]=EPAX X1.ini
SET files[4]=EPAX X10.ini
SET files[5]=EPAX X10 4K Mono.ini
SET files[6]=EPAX X133 4K Mono.ini
SET files[7]=EPAX X156 4K Color.ini
SET files[8]=EPAX X1K 2K Mono.ini
SET files[9]=Zortrax Inkspire.ini
SET files[10]=Nova3D Elfin.ini
SET files[11]=Nova3D Bene4 Mono.ini
SET files[12]=AnyCubic Photon.ini
SET files[13]=AnyCubic Photon S.ini
SET files[14]=AnyCubic Photon Zero.ini
SET files[15]=AnyCubic Photon X.ini
SET files[16]=AnyCubic Photon Mono.ini
SET files[17]=AnyCubic Photon Mono SE.ini
SET files[18]=AnyCubic Photon Mono X.ini
SET files[19]=Elegoo Mars.ini
SET files[20]=Elegoo Mars 2 Pro.ini
SET files[21]=Elegoo Mars C.ini
SET files[22]=Elegoo Saturn.ini
SET files[23]=Peopoly Phenom.ini
SET files[24]=Peopoly Phenom L.ini
SET files[25]=Peopoly Phenom Noir.ini
SET files[26]=Peopoly Phenom XXL.ini
SET files[27]=QIDI Shadow5.5.ini
SET files[28]=QIDI Shadow6.0 Pro.ini
SET files[29]=QIDI S-Box.ini
SET files[30]=QIDI I-Box Mono.ini
SET files[31]=Phrozen Shuffle.ini
SET files[32]=Phrozen Shuffle Lite.ini
SET files[33]=Phrozen Shuffle XL.ini
SET files[34]=Phrozen Shuffle XL Lite.ini
SET files[35]=Phrozen Shuffle 16.ini
SET files[36]=Phrozen Shuffle 4K.ini
SET files[37]=Phrozen Sonic.ini
SET files[38]=Phrozen Sonic 4K.ini
SET files[39]=Phrozen Sonic Mighty 4K.ini
SET files[40]=Phrozen Sonic Mini.ini
SET files[41]=Phrozen Sonic Mini 4K.ini
SET files[42]=Phrozen Transform.ini
SET files[43]=Kelant S400.ini
SET files[44]=Wanhao D7.ini
SET files[45]=Wanhao D8.ini
SET files[46]=Wanhao CGR Mini Mono.ini
SET files[47]=Wanhao CGR Mono.ini
SET files[48]=Creality LD-002R.ini
SET files[49]=Creality LD-002H.ini
SET files[50]=Creality LD-006.ini
SET files[51]=Creality HALOT-ONE CL-60.ini
SET files[52]=Creality HALOT-SKY CL-89.ini
SET files[53]=Voxelab Polaris 5.5.ini
SET files[54]=Voxelab Proxima 6.ini
SET files[55]=Voxelab Ceres 8.9.ini
SET files[56]=Longer Orange 10.ini
SET files[57]=Longer Orange 30.ini
SET files[58]=Longer Orange4K.ini
SET files[59]=Uniz IBEE.ini
SET files[1]=UVtools Prusa SL1S Speed.ini
SET files[2]=EPAX E6 Mono.ini
SET files[3]=EPAX E10 Mono.ini
SET files[4]=EPAX X1.ini
SET files[5]=EPAX X10.ini
SET files[6]=EPAX X10 4K Mono.ini
SET files[7]=EPAX X133 4K Mono.ini
SET files[8]=EPAX X156 4K Color.ini
SET files[9]=EPAX X1K 2K Mono.ini
SET files[10]=Zortrax Inkspire.ini
SET files[11]=Nova3D Elfin.ini
SET files[12]=Nova3D Bene4 Mono.ini
SET files[13]=AnyCubic Photon.ini
SET files[14]=AnyCubic Photon S.ini
SET files[15]=AnyCubic Photon Zero.ini
SET files[16]=AnyCubic Photon X.ini
SET files[17]=AnyCubic Photon Mono.ini
SET files[18]=AnyCubic Photon Mono SE.ini
SET files[19]=AnyCubic Photon Mono X.ini
SET files[20]=Elegoo Mars.ini
SET files[21]=Elegoo Mars 2 Pro.ini
SET files[22]=Elegoo Mars C.ini
SET files[23]=Elegoo Saturn.ini
SET files[24]=Peopoly Phenom.ini
SET files[25]=Peopoly Phenom L.ini
SET files[26]=Peopoly Phenom Noir.ini
SET files[27]=Peopoly Phenom XXL.ini
SET files[28]=QIDI Shadow5.5.ini
SET files[29]=QIDI Shadow6.0 Pro.ini
SET files[30]=QIDI S-Box.ini
SET files[31]=QIDI I-Box Mono.ini
SET files[32]=Phrozen Shuffle.ini
SET files[33]=Phrozen Shuffle Lite.ini
SET files[34]=Phrozen Shuffle XL.ini
SET files[35]=Phrozen Shuffle XL Lite.ini
SET files[36]=Phrozen Shuffle 16.ini
SET files[37]=Phrozen Shuffle 4K.ini
SET files[38]=Phrozen Sonic.ini
SET files[39]=Phrozen Sonic 4K.ini
SET files[40]=Phrozen Sonic Mighty 4K.ini
SET files[41]=Phrozen Sonic Mini.ini
SET files[42]=Phrozen Sonic Mini 4K.ini
SET files[43]=Phrozen Transform.ini
SET files[44]=Kelant S400.ini
SET files[45]=Wanhao D7.ini
SET files[46]=Wanhao D8.ini
SET files[47]=Wanhao CGR Mini Mono.ini
SET files[48]=Wanhao CGR Mono.ini
SET files[49]=Creality LD-002R.ini
SET files[50]=Creality LD-002H.ini
SET files[51]=Creality LD-006.ini
SET files[52]=Creality HALOT-ONE CL-60.ini
SET files[53]=Creality HALOT-SKY CL-89.ini
SET files[54]=Voxelab Polaris 5.5.ini
SET files[55]=Voxelab Proxima 6.ini
SET files[56]=Voxelab Ceres 8.9.ini
SET files[57]=Longer Orange 10.ini
SET files[58]=Longer Orange 30.ini
SET files[59]=Longer Orange 120.ini
SET files[60]=Longer Orange 4K.ini
SET files[61]=Uniz IBEE.ini
echo PrusaSlicer Printers Instalation
echo This will replace printers, all changes will be discarded
+212
View File
@@ -0,0 +1,212 @@
//------------------------------------------------
//--- 010 Editor v8.0.1 Binary Template
//
// File: ctb, cbddlp, photon
// Authors: Tiago Conceição
//------------------------------------------------
LittleEndian();
struct HEADER {
uint Magic <fgcolor=cBlack, bgcolor=cRed>;
uint Version <fgcolor=cBlack, bgcolor=cRed>;
float BedSizeX <fgcolor=cBlack, bgcolor=cRed>;
float BedSizeY <fgcolor=cBlack, bgcolor=cRed>;
float BedSizeZ <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown1 <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown2 <fgcolor=cBlack, bgcolor=cRed>;
float TotalHeightMilimeter <fgcolor=cBlack, bgcolor=cRed>;
float LayerHeightMilimeter <fgcolor=cBlack, bgcolor=cRed>;
float LayerExposureSeconds <fgcolor=cBlack, bgcolor=cRed>;
float BottomExposureSeconds <fgcolor=cBlack, bgcolor=cRed>;
float LightOffDelay <fgcolor=cBlack, bgcolor=cRed>;
uint BottomLayersCount <fgcolor=cBlack, bgcolor=cRed>;
uint ResolutionX <fgcolor=cBlack, bgcolor=cRed>;
uint ResolutionY <fgcolor=cBlack, bgcolor=cRed>;
uint PreviewLargeOffsetAddress <fgcolor=cBlack, bgcolor=cRed>;
uint LayersDefinitionOffsetAddress <fgcolor=cBlack, bgcolor=cRed>;
uint LayerCount <fgcolor=cBlack, bgcolor=cRed>;
uint PreviewSmallOffsetAddress <fgcolor=cBlack, bgcolor=cRed>;
uint PrintTime <fgcolor=cBlack, bgcolor=cRed>;
uint ProjectorType <fgcolor=cBlack, bgcolor=cRed>;
uint PrintParametersOffsetAddress <fgcolor=cBlack, bgcolor=cRed>;
uint PrintParametersSize <fgcolor=cBlack, bgcolor=cRed>;
uint AntiAliasLevel <fgcolor=cBlack, bgcolor=cRed>;
ushort LightPWM <fgcolor=cBlack, bgcolor=cRed>;
ushort BottomLightPWM <fgcolor=cBlack, bgcolor=cRed>;
uint EncryptionKey <fgcolor=cBlack, bgcolor=cRed>;
uint SlicerOffset <fgcolor=cBlack, bgcolor=cRed>;
uint SlicerSize <fgcolor=cBlack, bgcolor=cRed>;
} header;
struct PREVIEW {
uint ResolutionX <fgcolor=cBlack, bgcolor=cRed>;
uint ResolutionY <fgcolor=cBlack, bgcolor=cRed>;
uint ImageOffset <fgcolor=cBlack, bgcolor=cRed>;
uint ImageLength <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown1 <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown2 <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown3 <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown4 <fgcolor=cBlack, bgcolor=cRed>;
byte Data[ImageLength] <fgcolor=cBlack, bgcolor=cRed>;
};
struct PRINT_PARAMETERS {
float BottomLiftHeight <fgcolor=cBlack, bgcolor=cRed>;
float BottomLiftSpeed <fgcolor=cBlack, bgcolor=cRed>;
float LiftHeight <fgcolor=cBlack, bgcolor=cRed>;
float LiftSpeed <fgcolor=cBlack, bgcolor=cRed>;
float RetractSpeed <fgcolor=cBlack, bgcolor=cRed>;
float VolumeMl <fgcolor=cBlack, bgcolor=cRed>;
float WeightG <fgcolor=cBlack, bgcolor=cRed>;
float CostDollars <fgcolor=cBlack, bgcolor=cRed>;
float BottomLightOffDelay <fgcolor=cBlack, bgcolor=cRed>;
float LightOffDelay <fgcolor=cBlack, bgcolor=cRed>;
uint BottomLayerCount <fgcolor=cBlack, bgcolor=cRed>;
uint Padding1 <fgcolor=cBlack, bgcolor=cRed>;
uint Padding2 <fgcolor=cBlack, bgcolor=cRed>;
uint Padding3 <fgcolor=cBlack, bgcolor=cRed>;
uint Padding4 <fgcolor=cBlack, bgcolor=cRed>;
};
struct SLICER_INFO {
float BottomLiftDistance2 <fgcolor=cBlack, bgcolor=cRed>;
float BottomLiftSpeed2 <fgcolor=cBlack, bgcolor=cRed>;
float LiftHeight2 <fgcolor=cBlack, bgcolor=cRed>;
float LiftSpeed2 <fgcolor=cBlack, bgcolor=cRed>;
float RetractHeight2 <fgcolor=cBlack, bgcolor=cRed>;
float RetractSpeed2 <fgcolor=cBlack, bgcolor=cRed>;
float RestTimeAfterLift <fgcolor=cBlack, bgcolor=cRed>;
uint MachineNameAddress <fgcolor=cBlack, bgcolor=cRed>;
uint MachineNameSize <fgcolor=cBlack, bgcolor=cRed>;
uint EncryptionMode <fgcolor=cBlack, bgcolor=cRed>; // 0/8 for cbddlp files, 0xF (15) for ctb files, 0x2000000F (536870927) for v3 ctb files allow per layer parameters
uint MysteriousId <fgcolor=cBlack, bgcolor=cRed>; // v3 = 305419896 | v4 = 27087675
uint AntiAliasLevel <fgcolor=cBlack, bgcolor=cRed>;
uint SoftwareVersion <fgcolor=cBlack, bgcolor=cRed>; // ctb v3 = 17171200 | ctb v4 = 16777216
float RestTimeAfterRetract <fgcolor=cBlack, bgcolor=cRed>;
float RestTimeAfterLift2 <fgcolor=cBlack, bgcolor=cRed>;
uint TransitionLayerCount <fgcolor=cBlack, bgcolor=cRed>;
uint Padding1 <fgcolor=cBlack, bgcolor=cRed>;
uint Padding2 <fgcolor=cBlack, bgcolor=cRed>;
uint Padding3 <fgcolor=cBlack, bgcolor=cRed>;
if(MachineNameAddress > 0 && MachineNameSize > 0)
{
char MachineName[MachineNameSize] <fgcolor=cBlack, bgcolor=cRed>;
}
};
if(header.PreviewLargeOffsetAddress > 0)
{
FSeek(header.PreviewLargeOffsetAddress);
PREVIEW previewLarge <fgcolor=cBlack, bgcolor=cYellow>;
}
if(header.PreviewSmallOffsetAddress > 0)
{
FSeek(header.PreviewSmallOffsetAddress);
PREVIEW previewSmall <fgcolor=cBlack, bgcolor=cYellow>;
}
if(header.PrintParametersOffsetAddress > 0){
FSeek(header.PrintParametersOffsetAddress);
PRINT_PARAMETERS parameters <fgcolor=cBlack, bgcolor=cYellow>;
}
if(header.SlicerOffset > 0){
FSeek(header.SlicerOffset);
SLICER_INFO SlicerInfo <fgcolor=cBlack, bgcolor=cYellow>;
}
if(header.Version >= 4)
{
struct PRINT_PARAMETERS_V4
{
char Disclaimer[320] <fgcolor=cBlack, bgcolor=cYellow>;
float BottomRetractSpeed <fgcolor=cWhite, bgcolor=cBlue>;
float BottomRetractSpeed2 <fgcolor=cWhite, bgcolor=cBlue>;
uint Padding1 <fgcolor=cWhite, bgcolor=cBlue>;
float Four1 <fgcolor=cWhite, bgcolor=cBlue>; // 4?
uint Padding2 <fgcolor=cWhite, bgcolor=cBlue>;
float Four2 <fgcolor=cWhite, bgcolor=cBlue>; // 4?
float RestTimeAfterRetract <fgcolor=cWhite, bgcolor=cBlue>;
float RestTimeAfterLift <fgcolor=cWhite, bgcolor=cBlue>;
float RestTimeBeforeLift <fgcolor=cWhite, bgcolor=cBlue>;
float BottomRetractHeight2 <fgcolor=cWhite, bgcolor=cBlue>;
float Unknown1 <fgcolor=cWhite, bgcolor=cBlue>; // 2955.996 or uint:1161347054 but changes
uint Unknown2 <fgcolor=cWhite, bgcolor=cBlue>; // 73470 but changes
uint Unknown3 <fgcolor=cWhite, bgcolor=cBlue>; // 5?
uint Unknown4 <fgcolor=cWhite, bgcolor=cBlue>; // 139 but changes
uint Padding3 <fgcolor=cWhite, bgcolor=cBlue>;
uint Padding4 <fgcolor=cWhite, bgcolor=cBlue>;
uint Padding5 <fgcolor=cWhite, bgcolor=cBlue>;
uint Padding6 <fgcolor=cWhite, bgcolor=cBlue>;
uint Unknown5 <fgcolor=cWhite, bgcolor=cBlue>; // 23047 but changes
uint Unknown6 <fgcolor=cWhite, bgcolor=cBlue>; // 320 but changes
byte Reserved[420] <fgcolor=cWhite, bgcolor=cBlue>;
} printParametersV4;
}
typedef struct() {
float LayerPositionZ <fgcolor=cBlack, bgcolor=cRed>;
float LayerExposure <fgcolor=cBlack, bgcolor=cRed>;
float LightOffSeconds <fgcolor=cBlack, bgcolor=cRed>;
uint DataAddress <fgcolor=cBlack, bgcolor=cRed>;
uint DataSize <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown1 <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown2 <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown3 <fgcolor=cBlack, bgcolor=cRed>;
uint Unknown4 <fgcolor=cBlack, bgcolor=cRed>;
} LAYER_DATA;
typedef struct() {
LAYER_DATA LayerData <fgcolor=cBlack, bgcolor=cRed>;
uint TotalSize <fgcolor=cBlack, bgcolor=cRed>;
float LiftHeight <fgcolor=cBlack, bgcolor=cRed>;
float LiftSpeed <fgcolor=cBlack, bgcolor=cRed>;
float LiftHeight2 <fgcolor=cBlack, bgcolor=cRed>;
float LiftSpeed2 <fgcolor=cBlack, bgcolor=cRed>;
float RetractSpeed <fgcolor=cBlack, bgcolor=cRed>;
float RetractHeight2 <fgcolor=cBlack, bgcolor=cRed>;
float RetractSpeed2 <fgcolor=cBlack, bgcolor=cRed>;
float RestTimeBeforeLift <fgcolor=cBlack, bgcolor=cRed>;
float RestTimeAfterLift <fgcolor=cBlack, bgcolor=cRed>;
float RestTimeAfterRetract <fgcolor=cBlack, bgcolor=cRed>;
float LightPWM <fgcolor=cBlack, bgcolor=cRed>;
} LAYER_DATAEX;
typedef struct(int size) {
byte layerDataBlock[size] <fgcolor=cBlack, bgcolor=cGreen>;
} LAYER_RLE;
FSeek(header.LayersDefinitionOffsetAddress);
struct LAYERS {
local int aa;
local int i;
local uint currentPos;
for( aa = 0; aa < header.AntiAliasLevel; aa++)
{
for( i = 0; i < header.LayerCount; i++ ){
LAYER_DATA layerData <fgcolor=cBlack, bgcolor=cYellow>;
currentPos = FTell();
if(header.Version >= 3)
{
FSeek(layerData.DataAddress - 84);
LAYER_DATAEX layerDataEx;
}
FSeek(layerData.DataAddress);
LAYER_RLE layerRLE(layerData.DataSize);
FSeek(currentPos);
}
}
} layers;
+1 -1
View File
@@ -17,7 +17,7 @@ typedef struct(int size) {
} rgbPreviewImageRawData;
struct HEADER {
char name[8] <fgcolor=cBlack, bgcolor=cWhite>;
char Name[8] <fgcolor=cBlack, bgcolor=cWhite>;
uint32 Uint_08 <fgcolor=cBlack, bgcolor=cRed>;
uint32 Uint_0C <fgcolor=cBlack, bgcolor=cRed>;
uint32 PrinterModel <fgcolor=cBlack, bgcolor=cRed>;
-1
View File
@@ -7,7 +7,6 @@
*/
using System;
using System.IO;
using System.Reflection;
namespace UVtools.Core
+240
View File
@@ -0,0 +1,240 @@
/*
* GNU AFFERO GENERAL PUBLIC LICENSE
* Version 3, 19 November 2007
* Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using UVtools.Core.Extensions;
namespace UVtools.Core.EmguCV
{
/// <summary>
/// A contour cache for OpenCV
/// </summary>
public class Contour : IReadOnlyCollection<Point>, IDisposable
{
#region Members
private VectorOfPoint _points;
private Rectangle? _bounds;
private RotatedRect? _boundsBestFit;
private CircleF? _minEnclosingCircle;
private bool? _isConvex;
private double _area = double.NaN;
private double _perimeter = double.NaN;
private Moments _moments;
private Point? _centroid;
#endregion
#region Properties
public int XMin => Bounds.X;
public int YMin => Bounds.Y;
public int XMax => Bounds.Right;
public int YMax => Bounds.Bottom;
public Rectangle Bounds => _bounds ??= CvInvoke.BoundingRectangle(_points);
public RotatedRect BoundsBestFit => _boundsBestFit ??= CvInvoke.MinAreaRect(_points);
public CircleF MinEnclosingCircle => _minEnclosingCircle ??= CvInvoke.MinEnclosingCircle(_points);
public bool IsConvex => _isConvex ??= CvInvoke.IsContourConvex(_points);
/// <summary>
/// Gets the area of the contour
/// </summary>
public double Area
{
get
{
if (double.IsNaN(_area))
{
_area = CvInvoke.ContourArea(_points);
}
return _area;
}
}
/// <summary>
/// Gets the perimeter of the contours
/// </summary>
public double Perimeter
{
get
{
if (double.IsNaN(_perimeter))
{
_perimeter = CvInvoke.ArcLength(_points, true);
}
return _perimeter;
}
}
public Moments Moments => _moments ??= CvInvoke.Moments(_points);
/// <summary>
/// Gets the centroid of the contour
/// </summary>
public Point Centroid => _centroid ??= Moments.M00 == 0 ? Point.Empty :
new Point(
(int)Math.Round(_moments.M10 / _moments.M00),
(int)Math.Round(_moments.M01 / _moments.M00));
/// <summary>
/// Gets or sets the contour <see cref="Point"/>
/// </summary>
public VectorOfPoint Points
{
get => _points;
set
{
Dispose();
_points = value ?? throw new ArgumentNullException(nameof(Points));
}
}
/// <summary>
/// Gets if this contour have any point
/// </summary>
public bool IsEmpty => _points.Size == 0;
#endregion
#region Constructor
public Contour(VectorOfPoint points) : this(points.ToArray())
{ }
public Contour(Point[] points)
{
Points = new VectorOfPoint(points);
}
#endregion
#region Methods
/// <summary>
/// Checks if a given <see cref="Point"/> is inside the contour rectangle bounds
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public bool IsInsideBounds(Point point) => Bounds.Contains(point);
/// <summary>
/// Gets if a given <see cref="Point"/> is inside the contour
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public bool IsInside(Point point)
{
if (!IsInsideBounds(point)) return false;
return CvInvoke.PointPolygonTest(_points, point, false) >= 0;
}
public double MeasureDist(Point point)
{
if (!IsInsideBounds(point)) return -1;
return CvInvoke.PointPolygonTest(_points, point, true);
}
public IOutputArray ContourApproximation(double epsilon = 0.1)
{
var mat = new Mat();
CvInvoke.ApproxPolyDP(_points, mat, epsilon*Perimeter, true);
return mat;
}
/*
/// <summary>
/// Calculate the X/Y min/max boundary
/// </summary>
private void CalculateMinMax()
{
Bounds = Rectangle.Empty;
if (_contourPoints.Length == 0)
{
_xMin = -1;
_yMin = -1;
_xMax = -1;
_yMax = -1;
return;
}
_xMin = int.MaxValue;
_yMin = int.MaxValue;
_xMax = int.MinValue;
_yMax = int.MinValue;
for (int i = 0; i < _contourPoints.Length; i++)
{
_xMin = Math.Min(_xMin, _contourPoints[i].X);
_yMin = Math.Min(_yMin, _contourPoints[i].Y);
_xMax = Math.Max(_xMax, _contourPoints[i].X);
_yMax = Math.Max(_yMax, _contourPoints[i].Y);
}
Bounds = new Rectangle(_xMin, _yMin, _xMax - _xMin, _yMax - _yMin);
}
*/
public void FitCircle(Mat src, MCvScalar color, int thickness = 1, LineType lineType = LineType.EightConnected, int shift = 0)
{
CvInvoke.Circle(src,
MinEnclosingCircle.Center.ToPoint(),
(int) Math.Round(MinEnclosingCircle.Radius),
color,
thickness,
lineType,
shift);
}
/*public void FitEllipse(Mat src, MCvScalar color, int thickness = 1, LineType lineType = LineType.EightConnected, int shift = 0)
{
var ellipse = CvInvoke.FitEllipse(_points);
CvInvoke.Ellipse(src, ellipse.Center.ToPoint(), ellipse.Size.ToSize(), ellipse.Angle, 0, 0);
}*/
#endregion
#region Implementations
public IEnumerator<Point> GetEnumerator()
{
return (IEnumerator<Point>) _points.ToArray().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count => _points.Size;
public Point this[int index] => _points[index];
public Point this[uint index] => _points[(int) index];
public Point this[long index] => _points[(int) index];
public Point this[ulong index] => _points[(int) index];
public void Dispose()
{
_points?.Dispose();
_moments?.Dispose();
}
#endregion
}
}
@@ -24,6 +24,26 @@ namespace UVtools.Core.Extensions
return buffer;
}
public static uint ReadUShortLittleEndian(this FileStream fs, int offset = 0)
{
return BitExtensions.ToUShortLittleEndian(fs.ReadBytes(2, offset));
}
public static uint ReadUShortBigEndian(this FileStream fs, int offset = 0)
{
return BitExtensions.ToUShortBigEndian(fs.ReadBytes(2, offset));
}
public static uint ReadUIntLittleEndian(this FileStream fs, int offset = 0)
{
return BitExtensions.ToUIntLittleEndian(fs.ReadBytes(4, offset));
}
public static uint ReadUIntBigEndian(this FileStream fs, int offset = 0)
{
return BitExtensions.ToUIntBigEndian(fs.ReadBytes(4, offset));
}
public static uint WriteStream(this FileStream fs, MemoryStream stream, int offset = 0)
{
return fs.WriteBytes(stream.ToArray(), offset);
+1 -1
View File
@@ -532,7 +532,7 @@ namespace UVtools.Core.FileFormats
Printer = PrinterType.Elfin;
for (int i = 0; i < FileExtensions.Length; i++)
{
if (!fileFullPath.EndsWith(FileExtensions[i].Extension) && !fileFullPath.EndsWith($"{FileExtensions[i].Extension}{TemporaryFileAppend}")) continue;
if (!FileEndsWith(FileExtensions[i].Extension)) continue;
Printer = (PrinterType) i+1;
}
}
+5 -1
View File
@@ -560,7 +560,7 @@ namespace UVtools.Core.FileFormats
{
using var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write);
if (ResolutionX == 2560 && ResolutionY == 1620)
if (ResolutionX == 1620 && ResolutionY == 2560)
{
MachineName = "CL-60";
}
@@ -568,6 +568,10 @@ namespace UVtools.Core.FileFormats
{
MachineName = "CL-89";
}
else if (!MachineName.StartsWith("CL-"))
{
throw new Exception("Unable to detect printer model from resolution, check if resolution is well defined on slicer for your printer model.");
}
var pageBreak = PageBreak.Bytes;
+177 -47
View File
@@ -14,6 +14,7 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BinarySerialization;
using Emgu.CV;
@@ -29,6 +30,7 @@ namespace UVtools.Core.FileFormats
#region Constants
private const uint MAGIC_CBDDLP = 0x12FD0019; // 318570521
private const uint MAGIC_CBT = 0x12FD0086; // 318570630
private const uint MAGIC_CBTv4 = 0x12FD0106; // 318570758
private const ushort REPEATRGB15MASK = 0x20;
private const byte RLE8EncodingLimit = 0x7d; // 125;
@@ -36,7 +38,11 @@ namespace UVtools.Core.FileFormats
private const uint ENCRYPTYION_MODE_CBDDLP = 0x8; // 0 or 8
private const uint ENCRYPTYION_MODE_CTBv2 = 0xF; // 15 for ctb v2 files
private const uint ENCRYPTYION_MODE_CTBv3 = 0x2000000F; // 536870927 for ctb v3 files (This allow per layer settings, while 0xF don't)
private const uint ENCRYPTYION_MODE_CTBv3 = 536870927; // 536870927 for ctb v3 files (This allow per layer settings, while 15 don't)
private const uint ENCRYPTYION_MODE_CTBv4 = 1073741839; // 1073741839 for ctb v3 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;
#endregion
#region Sub Classes
@@ -270,13 +276,13 @@ namespace UVtools.Core.FileFormats
public class SlicerInfo
{
private string _machineName;
[FieldOrder(0)] public uint Padding1 { get; set; }
[FieldOrder(1)] public uint Padding2 { get; set; }
[FieldOrder(2)] public uint Padding3 { get; set; }
[FieldOrder(3)] public uint Padding4 { get; set; }
[FieldOrder(4)] public uint Padding5 { get; set; }
[FieldOrder(5)] public uint Padding6 { get; set; }
[FieldOrder(6)] public uint Padding7 { get; set; }
[FieldOrder(0)] public float BottomLiftDistance2 { get; set; }
[FieldOrder(1)] public float BottomLiftSpeed2 { get; set; }
[FieldOrder(2)] public float LiftHeight2 { get; set; }
[FieldOrder(3)] public float LiftSpeed2 { get; set; }
[FieldOrder(4)] public float RetractHeight2 { get; set; }
[FieldOrder(5)] public float RetractSpeed2 { get; set; }
[FieldOrder(6)] public float RestTimeAfterLift { get; set; }
/// <summary>
/// Gets the machine name offset to a string naming the machine type, and its length in bytes.
@@ -290,14 +296,14 @@ namespace UVtools.Core.FileFormats
/// <summary>
/// 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 files allow per layer parameters
/// 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
/// </summary>
[FieldOrder(9)] public uint EncryptionMode { get; set; } = ENCRYPTYION_MODE_CTBv3;
/// <summary>
/// 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.
/// </summary>
[FieldOrder(10)] public uint MysteriousId { get; set; }
[FieldOrder(10)] public uint MysteriousId { get; set; } = 305419896; // v3 = 305419896 | v4 = 27087675
/// <summary>
/// Gets the user-selected antialiasing level. For cbddlp files this will match the level_set_count. For ctb files, this number is essentially arbitrary.
@@ -309,13 +315,13 @@ namespace UVtools.Core.FileFormats
/// (No provision is made to name the software being used, so this assumes that only one software package can generate the files.
/// Probably best to hardcode it at 0x01060300.)
/// </summary>
[FieldOrder(12)] public uint SoftwareVersion { get; set; } = 0x01060300;
[FieldOrder(13)] public uint Unknown1 { get; set; }
[FieldOrder(14)] public uint Padding8 { get; set; }
[FieldOrder(12)] public uint SoftwareVersion { get; set; } = 0x01060300; // ctb v3 = 17171200 | ctb v4 = 16777216
[FieldOrder(13)] public float RestTimeAfterRetract { get; set; }
[FieldOrder(14)] public float RestTimeAfterLift2 { get; set; }
[FieldOrder(15)] public uint TransitionLayerCount { get; set; } // CTB not all printers
[FieldOrder(16)] public uint Padding10 { get; set; }
[FieldOrder(17)] public uint Padding11 { get; set; }
[FieldOrder(18)] public uint Padding12 { get; set; }
[FieldOrder(16)] public uint Padding1 { get; set; }
[FieldOrder(17)] public uint Padding2 { get; set; }
[FieldOrder(18)] public uint Padding3 { get; set; }
/// <summary>
/// Gets the machine name. string is not nul-terminated.
@@ -337,12 +343,90 @@ namespace UVtools.Core.FileFormats
public override string ToString()
{
return $"{nameof(Padding1)}: {Padding1}, {nameof(Padding2)}: {Padding2}, {nameof(Padding3)}: {Padding3}, {nameof(Padding4)}: {Padding4}, {nameof(Padding5)}: {Padding5}, {nameof(Padding6)}: {Padding6}, {nameof(Padding7)}: {Padding7}, {nameof(MachineNameAddress)}: {MachineNameAddress}, {nameof(MachineNameSize)}: {MachineNameSize}, {nameof(EncryptionMode)}: {EncryptionMode}, {nameof(MysteriousId)}: {MysteriousId}, {nameof(AntiAliasLevel)}: {AntiAliasLevel}, {nameof(SoftwareVersion)}: {SoftwareVersion}, {nameof(Unknown1)}: {Unknown1}, {nameof(Padding8)}: {Padding8}, {nameof(TransitionLayerCount)}: {TransitionLayerCount}, {nameof(Padding10)}: {Padding10}, {nameof(Padding11)}: {Padding11}, {nameof(Padding12)}: {Padding12}, {nameof(MachineName)}: {MachineName}";
return $"{nameof(BottomLiftDistance2)}: {BottomLiftDistance2}, {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(Padding1)}: {Padding1}, {nameof(Padding2)}: {Padding2}, {nameof(Padding3)}: {Padding3}, {nameof(MachineName)}: {MachineName}";
}
}
#endregion
#region PrintParametersV4
public sealed class PrintParametersV4
{
[FieldOrder(1)]
[FieldLength(CTBv4_DISCLAIMER_SIZE)]
public string Disclaimer { get; set; } = CTBv4_DISCLAIMER; // 320 bytes
[FieldOrder(2)]
public float BottomRetractSpeed { get; set; }
[FieldOrder(3)]
public float BottomRetractSpeed2 { get; set; }
[FieldOrder(4)]
public uint Padding1 { get; set; }
[FieldOrder(5)]
public float Four1 { get; set; } = 4; // 4?
[FieldOrder(6)]
public uint Padding2 { get; set; }
[FieldOrder(7)]
public float Four2 { get; set; } = 4; // ?
[FieldOrder(8)]
public float RestTimeAfterRetract { get; set; }
[FieldOrder(9)]
public float RestTimeAfterLift { get; set; }
[FieldOrder(10)]
public float RestTimeBeforeLift { get; set; }
[FieldOrder(11)]
public float BottomRetractHeight2 { get; set; }
[FieldOrder(12)]
public float Unknown1 { get; set; } // 2955.996 or uint:1161347054 but changes
[FieldOrder(13)]
public uint Unknown2 { get; set; } // 73470 but changes
[FieldOrder(14)]
public uint Unknown3 { get; set; } = 5; // 5?
[FieldOrder(15)]
public uint Unknown4 { get; set; } // 139 but changes
[FieldOrder(16)]
public uint Padding3 { get; set; }
[FieldOrder(17)]
public uint Padding4 { get; set; }
[FieldOrder(18)]
public uint Padding5 { get; set; }
[FieldOrder(19)]
public uint Padding6 { get; set; }
[FieldOrder(20)]
public uint Unknown5 { get; set; } // 23047 but changes
[FieldOrder(21)]
public uint Unknown6 { get; set; } // 320 but changes
[FieldOrder(22)]
[FieldCount(420)]
private byte[] Reserved { get; set; } = new byte[420]; // 420 bytes
public override string ToString()
{
return $"{nameof(Disclaimer)}: {Disclaimer}, {nameof(BottomRetractSpeed)}: {BottomRetractSpeed}, {nameof(BottomRetractSpeed2)}: {BottomRetractSpeed2}, {nameof(Padding1)}: {Padding1}, {nameof(Four1)}: {Four1}, {nameof(Padding2)}: {Padding2}, {nameof(Four2)}: {Four2}, {nameof(RestTimeAfterRetract)}: {RestTimeAfterRetract}, {nameof(RestTimeAfterLift)}: {RestTimeAfterLift}, {nameof(RestTimeBeforeLift)}: {RestTimeBeforeLift}, {nameof(BottomRetractHeight2)}: {BottomRetractHeight2}, {nameof(Unknown1)}: {Unknown1}, {nameof(Unknown2)}: {Unknown2}, {nameof(Unknown3)}: {Unknown3}, {nameof(Unknown4)}: {Unknown4}, {nameof(Padding3)}: {Padding3}, {nameof(Padding4)}: {Padding4}, {nameof(Padding5)}: {Padding5}, {nameof(Padding6)}: {Padding6}, {nameof(Unknown5)}: {Unknown5}, {nameof(Unknown6)}: {Unknown6}, {nameof(Reserved)}: {Reserved}";
}
}
#endregion
#region Preview
/// <summary>
/// The files contain two preview images.
@@ -524,8 +608,6 @@ namespace UVtools.Core.FileFormats
[Ignore] public byte[] EncodedRle { get; set; }
[Ignore] public ChituboxFile Parent { get; set; }
[Ignore] public uint Version { get; set; } = 2;
public LayerData()
{
}
@@ -814,7 +896,6 @@ namespace UVtools.Core.FileFormats
rawData.Add((byte)(stride >> 8));
rawData.Add((byte)stride);
}
}
@@ -864,7 +945,7 @@ namespace UVtools.Core.FileFormats
/// <summary>
/// Gets a copy of layer data defenition
/// </summary>
[FieldOrder(0)] public LayerData LayerData { get; set; } = new LayerData();
[FieldOrder(0)] public LayerData LayerData { get; set; } = new();
/// <summary>
/// Gets the total size of ctbImageInfo and Image data
@@ -872,14 +953,14 @@ namespace UVtools.Core.FileFormats
[FieldOrder(1)] public uint TotalSize { get; set; }
[FieldOrder(2)] public float LiftHeight { get; set; }
[FieldOrder(3)] public float LiftSpeed { get; set; }
[FieldOrder(4)] public uint Unknown6 { get; set; }
[FieldOrder(5)] public uint Unknown7 { get; set; }
[FieldOrder(4)] public float LiftHeight2 { get; set; }
[FieldOrder(5)] public float LiftSpeed2 { get; set; }
[FieldOrder(6)] public float RetractSpeed { get; set; }
[FieldOrder(7)] public uint Unknown8 { get; set; }
[FieldOrder(8)] public uint Unknown9 { get; set; }
[FieldOrder(9)] public uint Unknown10 { get; set; }
[FieldOrder(10)] public uint Unknown11 { get; set; }
[FieldOrder(11)] public uint Unknown12 { get; set; } = 28672; // 28672 v3?
[FieldOrder(7)] public float RetractHeight2 { get; set; }
[FieldOrder(8)] public float RetractSpeed2 { get; set; }
[FieldOrder(9)] public float RestTimeBeforeLift { get; set; }
[FieldOrder(10)] public float RestTimeAfterLift { get; set; }
[FieldOrder(11)] public float RestTimeAfterRetract { get; set; } // 28672 v3?
[FieldOrder(12)] public float LightPWM { get; set; }
public LayerDataEx()
@@ -905,7 +986,7 @@ namespace UVtools.Core.FileFormats
public override string ToString()
{
return $"{nameof(LayerData)}: {LayerData}, {nameof(TotalSize)}: {TotalSize}, {nameof(LiftHeight)}: {LiftHeight}, {nameof(LiftSpeed)}: {LiftSpeed}, {nameof(Unknown6)}: {Unknown6}, {nameof(Unknown7)}: {Unknown7}, {nameof(RetractSpeed)}: {RetractSpeed}, {nameof(Unknown8)}: {Unknown8}, {nameof(Unknown9)}: {Unknown9}, {nameof(Unknown10)}: {Unknown10}, {nameof(Unknown11)}: {Unknown11}, {nameof(Unknown12)}: {Unknown12}, {nameof(LightPWM)}: {LightPWM}";
return $"{nameof(LayerData)}: {LayerData}, {nameof(TotalSize)}: {TotalSize}, {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}";
}
}
@@ -965,10 +1046,11 @@ namespace UVtools.Core.FileFormats
#region Properties
public Header HeaderSettings { get; protected internal set; } = new Header();
public PrintParameters PrintParametersSettings { get; protected internal set; } = new PrintParameters();
public Header HeaderSettings { get; protected internal set; } = new();
public PrintParameters PrintParametersSettings { get; protected internal set; } = new();
public SlicerInfo SlicerInfoSettings { get; protected internal set; } = new SlicerInfo();
public SlicerInfo SlicerInfoSettings { get; protected internal set; } = new();
public PrintParametersV4 PrintParametersV4Settings { get; protected internal set; } = new();
public Preview[] Previews { get; protected internal set; }
@@ -1005,6 +1087,7 @@ namespace UVtools.Core.FileFormats
public override PrintParameterModifier[] PrintParameterPerLayerModifiers {
get
{
if (!IsCbtFile) return null; // Only ctb files
if (HeaderSettings.Version >= 3)
{
return new[]
@@ -1018,14 +1101,15 @@ namespace UVtools.Core.FileFormats
};
}
if (HeaderSettings.Version <= 2)
/* Disable for v2 beside the fields on format they are not used
if (HeaderSettings.Version <= 2)
{
return new[]
{
PrintParameterModifier.ExposureSeconds,
PrintParameterModifier.LightOffDelay,
};
}
}*/
return null;
}
@@ -1192,7 +1276,7 @@ namespace UVtools.Core.FileFormats
public override float RetractSpeed
{
get => PrintParametersSettings.RetractSpeed;
set => base.RetractSpeed = PrintParametersSettings.RetractSpeed = (float)Math.Round(value, 2);
set => base.RetractSpeed = PrintParametersV4Settings.BottomRetractSpeed = PrintParametersSettings.RetractSpeed = (float)Math.Round(value, 2);
}
public override byte BottomLightPWM
@@ -1249,10 +1333,22 @@ namespace UVtools.Core.FileFormats
}
}
public override object[] Configs => new[] { (object)HeaderSettings, PrintParametersSettings, SlicerInfoSettings };
public override object[] Configs
{
get
{
if (HeaderSettings.Version <= 1)
return new object[] { HeaderSettings };
if (HeaderSettings.Version <= 3)
return new object[] {HeaderSettings, PrintParametersSettings, SlicerInfoSettings};
return new object[] { HeaderSettings, PrintParametersSettings, SlicerInfoSettings, PrintParametersV4Settings };
}
}
public bool IsCbddlpFile => HeaderSettings.Magic == MAGIC_CBDDLP;
public bool IsCbtFile => HeaderSettings.Magic == MAGIC_CBT;
public bool IsCbtFile => HeaderSettings.Magic is MAGIC_CBT or MAGIC_CBTv4;
public bool CanHash => !IsCbtFile && HeaderSettings.Version <= 2;
#endregion
@@ -1281,7 +1377,7 @@ namespace UVtools.Core.FileFormats
{
LayersHash.Clear();
HeaderSettings.Magic = fileFullPath.EndsWith(".ctb") || fileFullPath.EndsWith($".ctb{TemporaryFileAppend}") ? MAGIC_CBT : MAGIC_CBDDLP;
HeaderSettings.Magic = FileEndsWith(".ctb") ? MAGIC_CBT : MAGIC_CBDDLP;
HeaderSettings.PrintParametersSize = (uint)Helpers.Serializer.SizeOf(PrintParametersSettings);
if (IsCbtFile)
@@ -1295,23 +1391,33 @@ namespace UVtools.Core.FileFormats
if (HeaderSettings.Version <= 2)
{
if (SlicerInfoSettings.Unknown1 == 0)
SlicerInfoSettings.Unknown1 = 0x200; // 512 for v2 | 0 for v3
//if (SlicerInfoSettings.RestTimeAfterRetract == 0)
//SlicerInfoSettings.RestTimeAfterRetract = 0x200; // 512 for v2 | 0 for v3
SlicerInfoSettings.EncryptionMode = ENCRYPTYION_MODE_CTBv2;
PrintParametersSettings.Padding4 = 0x1234; // 4660
if (SlicerInfoSettings.MysteriousId == 0)
SlicerInfoSettings.MysteriousId = 305419896;
}
else
else if(HeaderSettings.Version == 3)
{
SlicerInfoSettings.EncryptionMode = ENCRYPTYION_MODE_CTBv3;
if (SlicerInfoSettings.MysteriousId == 0)
SlicerInfoSettings.MysteriousId = 305419896;
}
else
{
SlicerInfoSettings.EncryptionMode = ENCRYPTYION_MODE_CTBv4;
if (SlicerInfoSettings.MysteriousId == 0)
SlicerInfoSettings.MysteriousId = 27087820;
}
if(SlicerInfoSettings.MysteriousId == 0)
SlicerInfoSettings.MysteriousId = 0x12345678;
if (HeaderSettings.EncryptionKey == 0)
{
Random rnd = new();
var rnd = new Random();
HeaderSettings.EncryptionKey = (uint)rnd.Next(byte.MaxValue, int.MaxValue);
}
}
@@ -1374,6 +1480,11 @@ namespace UVtools.Core.FileFormats
currentOffset += Helpers.SerializeWriteFileStream(outputFile, SlicerInfoSettings);
if (HeaderSettings.Version >= 4)
{
currentOffset += Helpers.SerializeWriteFileStream(outputFile, PrintParametersV4Settings);
}
}
HeaderSettings.LayersDefinitionOffsetAddress = currentOffset;
@@ -1449,6 +1560,7 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine(Previews[1]);
Debug.WriteLine(PrintParametersSettings);
Debug.WriteLine(SlicerInfoSettings);
Debug.WriteLine(PrintParametersV4Settings);
Debug.WriteLine("-End-");
}
@@ -1459,9 +1571,14 @@ namespace UVtools.Core.FileFormats
//HeaderSettings = Helpers.ByteToType<CbddlpFile.Header>(InputFile);
//HeaderSettings = Helpers.Serializer.Deserialize<Header>(InputFile.ReadBytes(Helpers.Serializer.SizeOf(typeof(Header))));
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Magic != MAGIC_CBDDLP && HeaderSettings.Magic != MAGIC_CBT)
/*if (HeaderSettings.Magic == MAGIC_CBTv4)
{
throw new FileLoadException("Not a valid CBDDLP nor CTB nor Photon file!", fileFullPath);
throw new FileLoadException("CTB v4 not supported!", fileFullPath);
}*/
if (HeaderSettings.Magic is not MAGIC_CBDDLP and not MAGIC_CBT and not MAGIC_CBTv4)
{
throw new FileLoadException($"Not a valid PHOTON nor CBDDLP nor CTB file! Magic Value: {HeaderSettings.Magic}", fileFullPath);
}
if (HeaderSettings.Version == 1 || HeaderSettings.AntiAliasLevel == 0)
@@ -1521,6 +1638,13 @@ namespace UVtools.Core.FileFormats
Debug.WriteLine($"{nameof(MachineName)}: {MachineName}");*/
//}
if (HeaderSettings.Version >= 4)
{
PrintParametersV4Settings = Helpers.Deserialize<PrintParametersV4>(inputFile);
Debug.Write("Print Parameters V4 -> ");
Debug.WriteLine(PrintParametersV4Settings);
}
LayerDefinitions = new LayerData[HeaderSettings.AntiAliasLevel, HeaderSettings.LayerCount];
var LayerDefinitionsEx = HeaderSettings.Version >= 3 ? new LayerDataEx[HeaderSettings.LayerCount] : null;
@@ -1652,6 +1776,12 @@ namespace UVtools.Core.FileFormats
Helpers.SerializeWriteFileStream(outputFile, new LayerDataEx(LayerDefinitions[0, layerIndex], layerIndex));
}
}
if (HeaderSettings.Version >= 4)
{
outputFile.Seek(SlicerInfoSettings.MachineNameAddress + SlicerInfoSettings.MachineNameSize, SeekOrigin.Begin);
Helpers.SerializeWriteFileStream(outputFile, PrintParametersV4Settings);
}
}
#endregion
+25 -11
View File
@@ -367,12 +367,12 @@ namespace UVtools.Core.FileFormats
public abstract FileExtension[] FileExtensions { get; }
/// <summary>
/// Gets the available <see cref="FileFormat.PrintParameterModifier"/>
/// Gets the available <see cref="PrintParameterModifier"/>
/// </summary>
public virtual PrintParameterModifier[] PrintParameterModifiers => null;
/// <summary>
/// Gets the available <see cref="FileFormat.PrintParameterModifier"/> per layer
/// Gets the available <see cref="PrintParameterModifier"/> per layer
/// </summary>
public virtual PrintParameterModifier[] PrintParameterPerLayerModifiers => null;
@@ -385,12 +385,12 @@ namespace UVtools.Core.FileFormats
PrintParameterModifiers is not null && PrintParameterModifiers.Contains(modifier);
/// <summary>
/// Checks if a <see cref="PrintParameterModifier"/> exists on print parameters
/// Checks if a <see cref="PrintParameterModifier"/> exists on layer parameters
/// </summary>
/// <param name="modifier"></param>
/// <returns>True if exists, otherwise false</returns>
public bool HavePrintParameterPerLayerModifier(PrintParameterModifier modifier) =>
PrintParameterPerLayerModifiers is not null && PrintParameterPerLayerModifiers.Contains(modifier);
public bool HaveLayerParameterModifier(PrintParameterModifier modifier) =>
SupportPerLayerSettings && PrintParameterPerLayerModifiers.Contains(modifier);
/// <summary>
/// Gets the file filter for open and save dialogs
@@ -917,7 +917,7 @@ namespace UVtools.Core.FileFormats
public bool CanUseAnyLiftHeight => CanUseBottomLiftHeight || CanUseLiftHeight;
public bool CanUseBottomLiftSpeed => HavePrintParameterModifier(PrintParameterModifier.BottomLiftSpeed);
public bool CanUseLiftSpeed => HavePrintParameterModifier(PrintParameterModifier.LiftHeight);
public bool CanUseLiftSpeed => HavePrintParameterModifier(PrintParameterModifier.LiftSpeed);
public bool CanUseAnyLiftSpeed => CanUseBottomLiftSpeed || CanUseLiftSpeed;
public bool CanUseRetractSpeed => HavePrintParameterModifier(PrintParameterModifier.RetractSpeed);
@@ -930,6 +930,13 @@ namespace UVtools.Core.FileFormats
public bool CanUseLightPWM => HavePrintParameterModifier(PrintParameterModifier.LightPWM);
public bool CanUseAnyLightPWM => CanUseBottomLightPWM || CanUseLightPWM;
public bool CanUseLayerExposureTime => HaveLayerParameterModifier(PrintParameterModifier.ExposureSeconds);
public bool CanUseLayerLiftHeight => HaveLayerParameterModifier(PrintParameterModifier.LiftHeight);
public bool CanUseLayerLiftSpeed => HaveLayerParameterModifier(PrintParameterModifier.LiftSpeed);
public bool CanUseLayerRetractSpeed => HaveLayerParameterModifier(PrintParameterModifier.RetractSpeed);
public bool CanUseLayerLightOffDelay => HaveLayerParameterModifier(PrintParameterModifier.LightOffDelay);
public bool CanUseLayerLightPWM => HaveLayerParameterModifier(PrintParameterModifier.LightPWM);
public string ExposureRepresentation
{
get
@@ -1368,6 +1375,13 @@ namespace UVtools.Core.FileFormats
return result;
}
public bool FileEndsWith(string extension)
{
if (extension[0] != '.') extension = $".{extension}";
return FileFullPath.EndsWith(extension, StringComparison.OrdinalIgnoreCase) ||
FileFullPath.EndsWith($"{extension}{TemporaryFileAppend}", StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Gets a thumbnail by it height or lower
/// </summary>
@@ -1617,15 +1631,15 @@ namespace UVtools.Core.FileFormats
tw.WriteLine($"{nameof(layer.PositionZ)}: {layer.PositionZ}");
tw.WriteLine($"{nameof(layer.ExposureTime)}: {layer.ExposureTime}");
if (HavePrintParameterPerLayerModifier(PrintParameterModifier.LightOffDelay))
if (HaveLayerParameterModifier(PrintParameterModifier.LightOffDelay))
tw.WriteLine($"{nameof(layer.LightOffDelay)}: {layer.LightOffDelay}");
if (HavePrintParameterPerLayerModifier(PrintParameterModifier.LiftHeight))
if (HaveLayerParameterModifier(PrintParameterModifier.LiftHeight))
tw.WriteLine($"{nameof(layer.LiftHeight)}: {layer.LiftHeight}");
if (HavePrintParameterPerLayerModifier(PrintParameterModifier.LiftSpeed))
if (HaveLayerParameterModifier(PrintParameterModifier.LiftSpeed))
tw.WriteLine($"{nameof(layer.LiftSpeed)}: {layer.LiftSpeed}");
if (HavePrintParameterPerLayerModifier(PrintParameterModifier.RetractSpeed))
if (HaveLayerParameterModifier(PrintParameterModifier.RetractSpeed))
tw.WriteLine($"{nameof(layer.RetractSpeed)}: {layer.RetractSpeed}");
if (HavePrintParameterPerLayerModifier(PrintParameterModifier.LightPWM))
if (HaveLayerParameterModifier(PrintParameterModifier.LightPWM))
tw.WriteLine($"{nameof(layer.LightPWM)}: {layer.LightPWM}");
var materialMillilitersPercent = layer.MaterialMillilitersPercent;
+111 -44
View File
@@ -6,6 +6,7 @@
* of this license document, but changing it is not allowed.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
@@ -28,17 +29,16 @@ namespace UVtools.Core.FileFormats
public class Header
{
public const string NameValue = "Longer3D";
//[FieldOrder(0)] public uint Offset1 { get; set; }
/// <summary>
/// Gets the model name
/// </summary>
[FieldOrder(0)] [FieldLength(8)] public string Name { get; set; } = NameValue; // 0x00:
[FieldOrder(1)] public uint Uint_08 { get; set; } = 4278190081; // 0x08: 0xff000001 ?
[FieldOrder(1)] public uint Uint_08 { get; set; } = 1; // 0x08: 0xff000001 ?
[FieldOrder(2)] public uint Uint_0c { get; set; } = 1; // 0x0c: 1 ?
[FieldOrder(3)] public uint Uint_10 { get; set; } = 30; // 0x10: 30 ?
[FieldOrder(3)] public uint PrinterModel { get; set; } = 30; // 10, 30, 120, 4000 (4k), 4500 (4k mono)
[FieldOrder(4)] public uint Uint_14 { get; set; } = 0; // 0x14: 0 ?
[FieldOrder(5)] public uint Uint_18 { get; set; } = 34; // 0x18: 34 ?
[FieldOrder(5)] public uint MagicKey { get; set; } = 34; // 0x18: 34
[FieldOrder(6)] public float PixelPerMmX { get; set; } = 15.404f;
[FieldOrder(7)] public float PixelPerMmY { get; set; } = 4.866f;
[FieldOrder(8)] public float ResolutionX { get; set; }
@@ -69,7 +69,7 @@ namespace UVtools.Core.FileFormats
[FieldOrder(33)] public float Float_88 { get; set; } = 6; // 0x88: 6?
[FieldOrder(34)] public float Float_8c { get; set; } = 150; // 0x8c: 150 ?
[FieldOrder(35)] public float Float_90 { get; set; } = 1001; // 0x90: 1001 ?
[FieldOrder(36)] public float Float_94 { get; set; } = 140;// 0x94: 140 for lgs10, 170 for lgs30, 190 for lgs4k
[FieldOrder(36)] public float MachineZ { get; set; } = 140;// 0x94: 140 for lgs10, 170 for lgs30, 150 for lgs120, 190 for lgs4k
[FieldOrder(37)] public uint Uint_98 { get; set; } // 0x98: 0 ?
[FieldOrder(38)] public uint Uint_9c { get; set; } // 0x9c: 0 ?
[FieldOrder(39)] public uint Uint_a0 { get; set; } // 0xa0: 0 ?
@@ -81,6 +81,45 @@ namespace UVtools.Core.FileFormats
#endregion
#region LGS120PngPreview
public class LGS120PngPreview
{
public const ushort ResolutionX = 1200;
public const ushort ResolutionY = 1600;
[FieldOrder(0)] public uint DataSize { get; set; }
[FieldOrder(1)]
[FieldLength(nameof(DataSize))]
public byte[] EncodedRle { get; set; }
public void Encode(Mat mat)
{
if (mat.Width != ResolutionX || mat.Height != ResolutionY)
{
using var resizeMat = new Mat();
CvInvoke.Resize(mat, resizeMat, new Size(ResolutionX, ResolutionY));
EncodedRle = resizeMat.GetPngByes();
}
else
{
EncodedRle = mat.GetPngByes();
}
}
public Mat Decode(bool consumeRle = true)
{
var mat = new Mat();
CvInvoke.Imdecode(EncodedRle, ImreadModes.AnyColor, mat);
if (consumeRle)
EncodedRle = null;
return mat;
}
}
#endregion
#region LayerData
public class LayerData
@@ -200,12 +239,14 @@ namespace UVtools.Core.FileFormats
#region Properties
public Header HeaderSettings { get; protected internal set; } = new Header();
public Header HeaderSettings { get; protected internal set; } = new();
public override FileFormatType FileType => FileFormatType.Binary;
public override FileExtension[] FileExtensions { get; } = {
new ("lgs", "Longer Orange 10"),
new ("lgs30", "Longer Orange 30"),
//new ("lgs120", "Longer Orange 120"),
//new ("lgs4k", "Longer Orange 4k"),
};
public override PrintParameterModifier[] PrintParameterModifiers { get; } =
@@ -276,6 +317,12 @@ namespace UVtools.Core.FileFormats
set { }
}
public override float MachineZ
{
get => HeaderSettings.MachineZ > 0 ? HeaderSettings.MachineZ : base.MachineZ;
set => base.MachineZ = HeaderSettings.MachineZ = (float)Math.Round(value, 2);
}
public override bool MirrorDisplay
{
get => true;
@@ -389,6 +436,7 @@ namespace UVtools.Core.FileFormats
public override string MaterialName => "Unknown";
public override string MachineName => null;*/
public override object[] Configs => new object[] { HeaderSettings };
#endregion
@@ -450,18 +498,34 @@ namespace UVtools.Core.FileFormats
protected override void EncodeInternally(string fileFullPath, OperationProgress progress)
{
if (ResolutionY >= 2560) // Longer Orange 30
if (FileEndsWith(".lgs")) // Longer Orange 10
{
HeaderSettings.Float_94 = 170;
MachineZ = 140;
HeaderSettings.PrinterModel = 10;
}
else if (FileEndsWith(".lgs30")) // Longer Orange 30
{
MachineZ = 170;
HeaderSettings.PrinterModel = 30;
}
else if (FileEndsWith(".lgs120")) // Longer Orange 120
{
MachineZ = 150;
HeaderSettings.PrinterModel = 120;
}
else if (FileEndsWith(".lgs4k")) // Longer Orange 4K & Mono
{
MachineZ = 190;
if(HeaderSettings.PrinterModel is not 4000 and not 4500) HeaderSettings.PrinterModel = 4500;
}
//uint currentOffset = (uint)Helpers.Serializer.SizeOf(HeaderSettings);
using (var outputFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write))
{
outputFile.WriteSerialize(HeaderSettings);
outputFile.WriteBytes(PreviewEncode(Thumbnails[0]));
LayerData[] layerData = new LayerData[LayerCount];
var layerData = new LayerData[LayerCount];
Parallel.For(0, LayerCount, layerIndex =>
{
@@ -493,47 +557,51 @@ namespace UVtools.Core.FileFormats
protected override void DecodeInternally(string fileFullPath, OperationProgress progress)
{
using (var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read))
using var inputFile = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Name != Header.NameValue)
{
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
if (HeaderSettings.Name != Header.NameValue)
{
throw new FileLoadException("Not a valid LGS file!", fileFullPath);
}
throw new FileLoadException("Not a valid LGS file!", fileFullPath);
}
// Fix inconsistencies found of different version of plugin and slicers
if (ResolutionX > ResolutionY)
{
var oldX = ResolutionX;
ResolutionX = ResolutionY;
ResolutionY = oldX;
}
// Fix inconsistencies found of different version of plugin and slicers
if (ResolutionX > ResolutionY)
{
var oldX = ResolutionX;
ResolutionX = ResolutionY;
ResolutionY = oldX;
}
int previewSize = (int) (HeaderSettings.PreviewSizeX * HeaderSettings.PreviewSizeY * 2);
byte[] previewData = new byte[previewSize];
int previewSize = (int) (HeaderSettings.PreviewSizeX * HeaderSettings.PreviewSizeY * 2);
byte[] previewData = new byte[previewSize];
uint currentOffset = (uint) Helpers.Serializer.SizeOf(HeaderSettings);
currentOffset += inputFile.ReadBytes(previewData);
Thumbnails[0] = PreviewDecode(previewData);
uint currentOffset = (uint) Helpers.Serializer.SizeOf(HeaderSettings);
currentOffset += inputFile.ReadBytes(previewData);
Thumbnails[0] = PreviewDecode(previewData);
if (FileEndsWith(".lgs120"))
{
var pngPreview = Helpers.Deserialize<LGS120PngPreview>(inputFile);
}
LayerData[] layerData = new LayerData[HeaderSettings.LayerCount];
progress.Reset(OperationProgress.StatusGatherLayers, HeaderSettings.LayerCount);
LayerData[] layerData = new LayerData[HeaderSettings.LayerCount];
progress.Reset(OperationProgress.StatusGatherLayers, HeaderSettings.LayerCount);
for (int layerIndex = 0; layerIndex < HeaderSettings.LayerCount; layerIndex++)
{
progress.Token.ThrowIfCancellationRequested();
layerData[layerIndex] = Helpers.Deserialize<LayerData>(inputFile);
layerData[layerIndex].Parent = this;
}
for (int layerIndex = 0; layerIndex < HeaderSettings.LayerCount; layerIndex++)
{
progress.Token.ThrowIfCancellationRequested();
layerData[layerIndex] = Helpers.Deserialize<LayerData>(inputFile);
layerData[layerIndex].Parent = this;
}
LayerManager.Init(HeaderSettings.LayerCount);
progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
LayerManager.Init(HeaderSettings.LayerCount);
progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount);
Parallel.For(0, LayerCount,
//new ParallelOptions{MaxDegreeOfParallelism = 1},
layerIndex =>
Parallel.For(0, LayerCount,
//new ParallelOptions{MaxDegreeOfParallelism = 1},
layerIndex =>
{
if (progress.Token.IsCancellationRequested) return;
@@ -543,8 +611,7 @@ namespace UVtools.Core.FileFormats
progress.LockAndIncrement();
});
LayerManager.RebuildLayersProperties();
}
LayerManager.RebuildLayersProperties();
}
public override void SaveAs(string filePath = null, OperationProgress progress = null)
+2 -2
View File
@@ -710,10 +710,10 @@ namespace UVtools.Core.FileFormats
PrintParameterModifier.LightPWM,
};
public override PrintParameterModifier[] PrintParameterPerLayerModifiers { get; } = {
/*public override PrintParameterModifier[] PrintParameterPerLayerModifiers { get; } = {
PrintParameterModifier.ExposureSeconds,
PrintParameterModifier.LightOffDelay,
};
};*/
public override Size[] ThumbnailsOriginalSize { get; } =
{
@@ -1187,7 +1187,7 @@ namespace UVtools.Core.FileFormats
public override object[] Configs => new object[] { FileMarkSettings, HeaderSettings, PreviewSettings, LayersDefinition };
public LayerRleFormat LayerFormat =>
FileFullPath.EndsWith(".pws") || FileFullPath.EndsWith($".pws{TemporaryFileAppend}")
FileEndsWith(".pws")
? LayerRleFormat.PWS
: LayerRleFormat.PW0;
@@ -1195,32 +1195,32 @@ namespace UVtools.Core.FileFormats
{
get
{
if (FileFullPath.EndsWith(".pws") || FileFullPath.EndsWith($".pws{TemporaryFileAppend}"))
if (FileEndsWith(".pws"))
{
return AnyCubicMachine.AnyCubicPhotonS;
}
if (FileFullPath.EndsWith(".pw0") || FileFullPath.EndsWith($".pw0{TemporaryFileAppend}"))
if (FileEndsWith(".pw0"))
{
return AnyCubicMachine.AnyCubicPhotonZero;
}
if (FileFullPath.EndsWith(".pwx") || FileFullPath.EndsWith($".pwx{TemporaryFileAppend}"))
if (FileEndsWith(".pwx"))
{
return AnyCubicMachine.AnyCubicPhotonX;
}
if (FileFullPath.EndsWith(".pwmo") || FileFullPath.EndsWith($".pwmo{TemporaryFileAppend}"))
if (FileEndsWith(".pwmo"))
{
return AnyCubicMachine.AnyCubicPhotonMono;
}
if (FileFullPath.EndsWith(".pwms") || FileFullPath.EndsWith($".pwms{TemporaryFileAppend}"))
if (FileEndsWith(".pwms"))
{
return AnyCubicMachine.AnyCubicPhotonMonoSE;
}
if (FileFullPath.EndsWith(".pwmx") || FileFullPath.EndsWith($".pwmx{TemporaryFileAppend}"))
if (FileEndsWith(".pwmx"))
{
return AnyCubicMachine.AnyCubicPhotonMonoX;
}
+3 -1
View File
@@ -264,6 +264,7 @@ namespace UVtools.Core.FileFormats
var now = DateTime.Now;
return $"{now.Year}-{now.Month:D2}-{now.Day:D2} at {now.Hour:D2}:{now.Minute:D2}:{now.Second:D2} {now.Kind}";
}
set{}
}
public float LayerHeight { get; set; }
public string MaterialName { get; set; } = About.Software;
@@ -303,7 +304,8 @@ namespace UVtools.Core.FileFormats
public override FileFormatType FileType => FileFormatType.Archive;
public override FileExtension[] FileExtensions { get; } = {
new("sl1", "PrusaSlicer SL1")
new("sl1", "PrusaSlicer SL1"),
new("sl1s", "PrusaSlicer SL1S Speed")
};
public override PrintParameterModifier[] PrintParameterModifiers { get; } = {
PrintParameterModifier.BottomLayerCount,
@@ -980,7 +980,7 @@ namespace UVtools.Core.Operations
if (_multipleBrightnessGenExposureTime == 0)
_multipleBrightnessGenExposureTime = (decimal)SlicerFile.ExposureTime;
if (!SlicerFile.HavePrintParameterPerLayerModifier(FileFormat.PrintParameterModifier.ExposureSeconds))
if (!SlicerFile.HaveLayerParameterModifier(FileFormat.PrintParameterModifier.ExposureSeconds))
{
_multipleLayerHeight = false;
_multipleExposures = false;
+1 -1
View File
@@ -10,7 +10,7 @@
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
<Version>2.13.4</Version>
<Version>2.14.0</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
+8 -2
View File
@@ -960,11 +960,14 @@
<Component Id="owc7B488E0A9D9B2656D06620E0CEEFDA13" Guid="7c2fe9e4-adb9-72d1-c0f4-ee7311cabadf">
<File Id="owf7B488E0A9D9B2656D06620E0CEEFDA13" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\Longer Orange 10.ini" KeyPath="yes" />
</Component>
<Component Id="owc81404C7F01EDBA07B087B424DAA40376" Guid="aaee9d27-478d-5d85-c09b-e2b2c8f61633">
<File Id="owf81404C7F01EDBA07B087B424DAA40376" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\Longer Orange 120.ini" KeyPath="yes" />
</Component>
<Component Id="owc227006E17D85BD8103B64C6480AF8A6F" Guid="33dff0a8-a2a6-7ad5-51b1-a91bc258b227">
<File Id="owf227006E17D85BD8103B64C6480AF8A6F" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\Longer Orange 30.ini" KeyPath="yes" />
</Component>
<Component Id="owcCF42E79995933F0457692A2F239FCBB5" Guid="fa18ff15-0e8a-1624-2359-2a9fc30791f0">
<File Id="owfCF42E79995933F0457692A2F239FCBB5" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\Longer Orange4K.ini" KeyPath="yes" />
<Component Id="owc6FE42BDB3CE927703AA1E9971366D810" Guid="b3fd97c9-d3b8-b5db-942f-f7ab9d2195e5">
<File Id="owf6FE42BDB3CE927703AA1E9971366D810" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\Longer Orange 4K.ini" KeyPath="yes" />
</Component>
<Component Id="owc60E90B40E8992C21339B84C28DFE9891" Guid="e8e24d92-2cb1-0bec-3963-817532a4c171">
<File Id="owf60E90B40E8992C21339B84C28DFE9891" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\Nova3D Bene4 Mono.ini" KeyPath="yes" />
@@ -1038,6 +1041,9 @@
<Component Id="owcD0FD9259BE924EB58AE9F7A85AE0A9E8" Guid="360b089c-8765-92db-0c8f-367d80202d8f">
<File Id="owfD0FD9259BE924EB58AE9F7A85AE0A9E8" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\UVtools Prusa SL1.ini" KeyPath="yes" />
</Component>
<Component Id="owc92527EBFC9C5B568C8D66A882C08D0B5" Guid="dcca948b-ff91-af94-7363-d77b50dde1a5">
<File Id="owf92527EBFC9C5B568C8D66A882C08D0B5" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\UVtools Prusa SL1S SPEED.ini" KeyPath="yes" />
</Component>
<Component Id="owc2D767EDC65A9490BE5587F5807220F67" Guid="1b34ea21-cadd-c887-3f4e-8655903ef11a">
<File Id="owf2D767EDC65A9490BE5587F5807220F67" Source="$(var.SourceDir)\Assets\PrusaSlicer\printer\Voxelab Ceres 8.9.ini" KeyPath="yes" />
</Component>
Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

@@ -811,7 +811,8 @@
Content="Enable - For advanced users only!"
IsChecked="{Binding Operation.MultipleExposures}"/>
<StackPanel Orientation="Horizontal" Spacing="20">
<StackPanel Orientation="Horizontal" Spacing="20"
IsVisible="{Binding SlicerFile.CanUseLayerLiftHeight}">
<CheckBox
ToolTip.Tip="The lift height will be set to 0 for sequential layers that share same z position, saving moves and time.
@@ -31,7 +31,7 @@ namespace UVtools.WPF.Controls.Calibrators
set => RaiseAndSetIfChanged(ref _previewImage, value);
}
public bool CanSupportPerLayerSettings => SlicerFile.HavePrintParameterPerLayerModifier(FileFormat.PrintParameterModifier.ExposureSeconds);
public bool CanSupportPerLayerSettings => SlicerFile.HaveLayerParameterModifier(FileFormat.PrintParameterModifier.ExposureSeconds);
public CalibrateExposureFinderControl()
{
@@ -44,7 +44,7 @@ namespace UVtools.WPF.Controls.Tools
return;
}
if (!SlicerFile.HavePrintParameterPerLayerModifier(FileFormat.PrintParameterModifier.ExposureSeconds))
if (!SlicerFile.HaveLayerParameterModifier(FileFormat.PrintParameterModifier.ExposureSeconds))
{
App.MainWindow.MessageBoxWaring($"Your printer seems to not support this tool, still you are allowed to run it for analyze, packing layers or simulation.\n" +
$"Do not print this file after run this tool on a not compatible printer, it will result in malformed model and height violation.\n" +
@@ -14,8 +14,8 @@ namespace UVtools.WPF.Controls.Tools
{
InitializeComponent();
BaseOperation = new OperationDynamicLifts(SlicerFile);
if (!SlicerFile.HavePrintParameterPerLayerModifier(FileFormat.PrintParameterModifier.LiftHeight) ||
!SlicerFile.HavePrintParameterPerLayerModifier(FileFormat.PrintParameterModifier.LiftSpeed))
if (!SlicerFile.HaveLayerParameterModifier(FileFormat.PrintParameterModifier.LiftHeight) ||
!SlicerFile.HaveLayerParameterModifier(FileFormat.PrintParameterModifier.LiftSpeed))
{
App.MainWindow.MessageBoxInfo("Your printer/format does not support this tool.", "Dynamic lifts - Printer not supported");
CanRun = false;
+9 -1
View File
@@ -191,13 +191,21 @@
<MenuItem
Header="_Donate"
InputGesture="Ctrl + Shift + F1" HotKey="Ctrl + Shift + F1"
Command="{Binding OpenDonateWebsite}">
<MenuItem.Icon>
<Image Source="\Assets\Icons\donate-16x16.png"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem
Header="_Sponsor"
Command="{Binding OpenWebsite}"
CommandParameter="https://github.com/sponsors/sn4k3">
<MenuItem.Icon>
<Image Source="\Assets\Icons\heart-16x16.png"/>
</MenuItem.Icon>
</MenuItem>
<Separator/>
<MenuItem
+1 -1
View File
@@ -12,7 +12,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<Version>2.13.4</Version>
<Version>2.14.0</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">