Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Conceição <Tiago_caza@hotmail.com>2021-05-04 07:07:04 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-05-04 07:07:04 +0300
commitb5575b3ef167d1c31c871b5ca9a70acfc9ddfa1c (patch)
tree730c27550db32bfbd41236034782188543800e25
parent6d6be66ced23339f8d30f4aed2d32b83d14384af (diff)
v2.9.3v2.9.3
- (Upgrade) AvaloniaUI from 0.10.2 to 0.10.3 - (Change) PrusaSlicer printers: Set 'Light-Off Delay' and 'Bottom Light-Off Delay' to 0 as default to allow UVtools auto-compute the right value once open the file in - **Exposure time finder:** - Optimize layers by merge same position/exposure layers - Add a fence option to the zebra bars - Add a option to pattern the loaded model and generate multiple exposures on that - Allow to generate tests without the holes feature - Prevent from using more chamfers than the base height - Removed two of the largest holes - Hide not so often used 'Multiple brightness' and 'Multiple layer height' by default - Disable Anti-Aliasing by default - Change 'Part margin' from 1.5mm to 2.0mm - Change 'Multiple exposures - Bottom exposure step' default to 0 - Fix a error when generating tests with multiple exposures - Fix some typos - **XYZ accuracy test:** - Change 'Wall thickess' default from 2.5mm to 3.0mm - (Improvement) Allow compute print time without a lift sequence
-rw-r--r--CHANGELOG.md27
-rw-r--r--PrusaSlicer/printer/AnyCubic Photon Mono SE.ini2
-rw-r--r--PrusaSlicer/printer/AnyCubic Photon Mono X.ini2
-rw-r--r--PrusaSlicer/printer/AnyCubic Photon Mono.ini2
-rw-r--r--PrusaSlicer/printer/AnyCubic Photon S.ini2
-rw-r--r--PrusaSlicer/printer/AnyCubic Photon X.ini2
-rw-r--r--PrusaSlicer/printer/AnyCubic Photon Zero.ini2
-rw-r--r--PrusaSlicer/printer/AnyCubic Photon.ini2
-rw-r--r--PrusaSlicer/printer/Creality LD-002R.ini2
-rw-r--r--PrusaSlicer/printer/Longer Orange 10.ini2
-rw-r--r--PrusaSlicer/printer/Longer Orange 30.ini2
-rw-r--r--PrusaSlicer/printer/Longer Orange4K.ini2
-rw-r--r--PrusaSlicer/printer/Peopoly Phenom XXL.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Shuffle 16.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Shuffle 4K.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Shuffle Lite.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Shuffle XL.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Shuffle.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Sonic Mighty 4K.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Sonic.ini2
-rw-r--r--PrusaSlicer/printer/Phrozen Transform.ini2
-rw-r--r--PrusaSlicer/printer/Uniz IBEE.ini2
-rw-r--r--PrusaSlicer/printer/Zortrax Inkspire.ini2
-rw-r--r--UVtools.Core/Extensions/EmguExtensions.cs5
-rw-r--r--UVtools.Core/FileFormats/FileFormat.cs31
-rw-r--r--UVtools.Core/Layer/Layer.cs2
-rw-r--r--UVtools.Core/Layer/LayerManager.cs2
-rw-r--r--UVtools.Core/Objects/ExposureItem.cs5
-rw-r--r--UVtools.Core/Operations/OperationCalculator.cs2
-rw-r--r--UVtools.Core/Operations/OperationCalibrateExposureFinder.cs625
-rw-r--r--UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs4
-rw-r--r--UVtools.Core/Operations/OperationProgress.cs6
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.ScriptSample/README.md2
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml164
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml2
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml2
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj12
38 files changed, 691 insertions, 246 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d77e43..83ac813 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,33 @@
# Changelog
+## 04/05/2021 - v2.9.3
+
+- (Upgrade) AvaloniaUI from 0.10.2 to 0.10.3
+- (Change) PrusaSlicer printers: Set 'Light-Off Delay' and 'Bottom Light-Off Delay' to 0 as default to allow UVtools auto-compute the right value once open the file in
+- **Exposure time finder:**
+ - Optimize layers by merge same position/exposure layers
+ - Add a fence option to the zebra bars
+ - Add a option to pattern the loaded model and generate multiple exposures on that
+ - Allow to generate tests without the holes feature
+ - Prevent from using more chamfers than the base height
+ - Removed two of the largest holes
+ - Hide not so often used 'Multiple brightness' and 'Multiple layer height' by default
+ - Disable Anti-Aliasing by default
+ - Change 'Part margin' from 1.5mm to 2.0mm
+ - Change 'Multiple exposures - Bottom exposure step' default to 0
+ - Fix a error when generating tests with multiple exposures
+ - Fix some typos
+- **XYZ accuracy test:**
+ - Change 'Wall thickess' default from 2.5mm to 3.0mm
+- (Improvement) Allow compute print time without a lift sequence
+
## 30/04/2021 - v2.9.2
- (Upgrade) AvaloniaUI from 0.10 to 0.10.2
- (Remove) Unused assemblies
-- **Issues**
- - Improve the performance when loading big lists of issues into the DataGrid
- - Auto refresh issues on the vertical highlight tracker once cath a modification on the Issues list
+- **Issues:**
+ - Improve the performance when loading big lists of issues into the DataGrid
+ - Auto refresh issues on the vertical highlight tracker once cath a modification on the Issues list
- **Layer preview - Difference:**
- Layer difference will now only check the pixels inside the union of previous, current and next layer bounding rectangle, increasing the performance and speed
- Previous and next layer pixels if both exists was not showing with the configured color and using the next layer color instead
diff --git a/PrusaSlicer/printer/AnyCubic Photon Mono SE.ini b/PrusaSlicer/printer/AnyCubic Photon Mono SE.ini
index 5f7594b..3318815 100644
--- a/PrusaSlicer/printer/AnyCubic Photon Mono SE.ini
+++ b/PrusaSlicer/printer/AnyCubic Photon Mono SE.ini
@@ -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_ANYCUBIC\nPRINTER_MODEL_PHOTON_MONO_SE\nFILEFORMAT_PWMS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0.5\nBottomLightOffDelay_2\nBottomLiftHeight_6\nLiftHeight_6\nBottomLiftSpeed_150\nLiftSpeed_150\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_ANYCUBIC\nPRINTER_MODEL_PHOTON_MONO_SE\nFILEFORMAT_PWMS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_6\nLiftHeight_6\nBottomLiftSpeed_150\nLiftSpeed_150\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/AnyCubic Photon Mono X.ini b/PrusaSlicer/printer/AnyCubic Photon Mono X.ini
index 0a9a498..7c1c19c 100644
--- a/PrusaSlicer/printer/AnyCubic Photon Mono X.ini
+++ b/PrusaSlicer/printer/AnyCubic Photon Mono X.ini
@@ -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_ANYCUBIC\nPRINTER_MODEL_PHOTON_MONO_X\nFILEFORMAT_PWMX\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0.5\nBottomLightOffDelay_2\nBottomLiftHeight_8\nLiftHeight_8\nBottomLiftSpeed_120\nLiftSpeed_120\nRetractSpeed_120\nBottomLightPWM_255\nLightPWM_255\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_ANYCUBIC\nPRINTER_MODEL_PHOTON_MONO_X\nFILEFORMAT_PWMX\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_8\nLiftHeight_8\nBottomLiftSpeed_120\nLiftSpeed_120\nRetractSpeed_120\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/AnyCubic Photon Mono.ini b/PrusaSlicer/printer/AnyCubic Photon Mono.ini
index a6a56b7..9df8b45 100644
--- a/PrusaSlicer/printer/AnyCubic Photon Mono.ini
+++ b/PrusaSlicer/printer/AnyCubic Photon Mono.ini
@@ -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_ANYCUBIC\nPRINTER_MODEL_PHOTON_MONO\nFILEFORMAT_PWMO\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0.5\nBottomLightOffDelay_2\nBottomLiftHeight_6\nLiftHeight_6\nBottomLiftSpeed_150\nLiftSpeed_150\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_ANYCUBIC\nPRINTER_MODEL_PHOTON_MONO\nFILEFORMAT_PWMO\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_6\nLiftHeight_6\nBottomLiftSpeed_150\nLiftSpeed_150\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/AnyCubic Photon S.ini b/PrusaSlicer/printer/AnyCubic Photon S.ini
index 6af11a5..e5fdb20 100644
--- a/PrusaSlicer/printer/AnyCubic Photon S.ini
+++ b/PrusaSlicer/printer/AnyCubic Photon S.ini
@@ -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_ANYCUBIC\nPRINTER_MODEL_PHOTON_S\nFILEFORMAT_PWS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_1\nLiftHeight_6\nLiftSpeed_60\nRetractSpeed_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_ANYCUBIC\nPRINTER_MODEL_PHOTON_S\nFILEFORMAT_PWS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nLiftHeight_6\nLiftSpeed_60\nRetractSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/AnyCubic Photon X.ini b/PrusaSlicer/printer/AnyCubic Photon X.ini
index e7954b6..963f5ee 100644
--- a/PrusaSlicer/printer/AnyCubic Photon X.ini
+++ b/PrusaSlicer/printer/AnyCubic Photon X.ini
@@ -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_ANYCUBIC\nPRINTER_MODEL_PHOTON_X\nFILEFORMAT_PWX\n\nSTART_CUSTOM_VALUES\nLightOffDelay_1\nBottomLightOffDelay_2\nBottomLiftHeight_8\nLiftHeight_8\nBottomLiftSpeed_150\nLiftSpeed_150\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_ANYCUBIC\nPRINTER_MODEL_PHOTON_X\nFILEFORMAT_PWX\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_8\nLiftHeight_8\nBottomLiftSpeed_150\nLiftSpeed_150\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/AnyCubic Photon Zero.ini b/PrusaSlicer/printer/AnyCubic Photon Zero.ini
index 7b64510..dde504d 100644
--- a/PrusaSlicer/printer/AnyCubic Photon Zero.ini
+++ b/PrusaSlicer/printer/AnyCubic Photon Zero.ini
@@ -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_ANYCUBIC\nPRINTER_MODEL_PHOTON_ZERO\nFILEFORMAT_PW0\n\nSTART_CUSTOM_VALUES\nLightOffDelay_1\nLiftHeight_6\nLiftingSpeed_60\nRetractSpeed_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_ANYCUBIC\nPRINTER_MODEL_PHOTON_ZERO\nFILEFORMAT_PW0\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nLiftHeight_6\nLiftingSpeed_60\nRetractSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/AnyCubic Photon.ini b/PrusaSlicer/printer/AnyCubic Photon.ini
index e71b8d3..3a09109 100644
--- a/PrusaSlicer/printer/AnyCubic Photon.ini
+++ b/PrusaSlicer/printer/AnyCubic Photon.ini
@@ -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_ANYCUBIC\nPRINTER_MODEL_PHOTON\nFILEFORMAT_PHOTON\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_2\nBottomLiftHeight_5\nLiftHeight_5\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_ANYCUBIC\nPRINTER_MODEL_PHOTON\nFILEFORMAT_PHOTON\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_5\nLiftHeight_5\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Creality LD-002R.ini b/PrusaSlicer/printer/Creality LD-002R.ini
index 3605fff..d5ea06d 100644
--- a/PrusaSlicer/printer/Creality LD-002R.ini
+++ b/PrusaSlicer/printer/Creality LD-002R.ini
@@ -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_CREALITY\nPRINTER_MODEL_LD_002R\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_2\nBottomLiftHeight_5\nLiftHeight_5\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_CREALITY\nPRINTER_MODEL_LD_002R\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_5\nLiftHeight_5\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Longer Orange 10.ini b/PrusaSlicer/printer/Longer Orange 10.ini
index cedf3f5..9c20964 100644
--- a/PrusaSlicer/printer/Longer Orange 10.ini
+++ b/PrusaSlicer/printer/Longer Orange 10.ini
@@ -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_1\nBottomLightOffDelay_1\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_2\nBottomLiftSpeed_90\nLiftSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Longer Orange 30.ini b/PrusaSlicer/printer/Longer Orange 30.ini
index b5ee165..7a32e4b 100644
--- a/PrusaSlicer/printer/Longer Orange 30.ini
+++ b/PrusaSlicer/printer/Longer Orange 30.ini
@@ -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_1\nBottomLightOffDelay_1\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_2\nLiftHeight_2\nBottomLiftSpeed_48\nLiftSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Longer Orange4K.ini b/PrusaSlicer/printer/Longer Orange4K.ini
index 440ae51..b02931f 100644
--- a/PrusaSlicer/printer/Longer Orange4K.ini
+++ b/PrusaSlicer/printer/Longer Orange4K.ini
@@ -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_LGS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_1\nBottomLightOffDelay_1\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_ORANGE30\nFILEFORMAT_LGS\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_2\nLiftHeight_2\nBottomLiftSpeed_90\nLiftSpeed_150\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Peopoly Phenom XXL.ini b/PrusaSlicer/printer/Peopoly Phenom XXL.ini
index 50a551f..db192e5 100644
--- a/PrusaSlicer/printer/Peopoly Phenom XXL.ini
+++ b/PrusaSlicer/printer/Peopoly Phenom XXL.ini
@@ -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_PEOPOLY\nPRINTER_MODEL_PHENOM_XXL\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_2\nBottomLightOffDelay_8\nBottomLiftHeight_15\nLiftHeight_14\nBottomLiftSpeed_32\nLiftSpeed_35\nRetractSpeed_100\nBottomLightPWM_255\nLightPWM_255\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_PEOPOLY\nPRINTER_MODEL_PHENOM_XXL\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_15\nLiftHeight_14\nBottomLiftSpeed_32\nLiftSpeed_35\nRetractSpeed_100\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Shuffle 16.ini b/PrusaSlicer/printer/Phrozen Shuffle 16.ini
index cc546b5..7417f45 100644
--- a/PrusaSlicer/printer/Phrozen Shuffle 16.ini
+++ b/PrusaSlicer/printer/Phrozen Shuffle 16.ini
@@ -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_PHROZEN\nPRINTER_MODEL_SHUFFLE_16\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_15\nBottomLightOffDelay_15\nBottomLiftHeight_10\nLiftHeight_8\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_SHUFFLE_16\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_10\nLiftHeight_8\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Shuffle 4K.ini b/PrusaSlicer/printer/Phrozen Shuffle 4K.ini
index bef8e0d..91e9e50 100644
--- a/PrusaSlicer/printer/Phrozen Shuffle 4K.ini
+++ b/PrusaSlicer/printer/Phrozen Shuffle 4K.ini
@@ -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_PHROZEN\nPRINTER_MODEL_SHUFFLE_4K\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_10\nBottomLightOffDelay_10\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_SHUFFLE_4K\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Shuffle Lite.ini b/PrusaSlicer/printer/Phrozen Shuffle Lite.ini
index 8915387..abb2cf2 100644
--- a/PrusaSlicer/printer/Phrozen Shuffle Lite.ini
+++ b/PrusaSlicer/printer/Phrozen Shuffle Lite.ini
@@ -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_PHROZEN\nPRINTER_MODEL_SHUFFLE_LITE\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_7\nBottomLightOffDelay_7\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_200\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_SHUFFLE_LITE\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_200\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Shuffle XL.ini b/PrusaSlicer/printer/Phrozen Shuffle XL.ini
index 8e3bf95..651461d 100644
--- a/PrusaSlicer/printer/Phrozen Shuffle XL.ini
+++ b/PrusaSlicer/printer/Phrozen Shuffle XL.ini
@@ -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_PHROZEN\nPRINTER_MODEL_SHUFFLE_XL\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_7\nBottomLightOffDelay_7\nBottomLiftHeight_8\nLiftHeight_6\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_SHUFFLE_XL\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_8\nLiftHeight_6\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Shuffle.ini b/PrusaSlicer/printer/Phrozen Shuffle.ini
index faa1ecb..43e99b7 100644
--- a/PrusaSlicer/printer/Phrozen Shuffle.ini
+++ b/PrusaSlicer/printer/Phrozen Shuffle.ini
@@ -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_PHROZEN\nPRINTER_MODEL_SHUFFLE\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_7\nBottomLightOffDelay_7\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_200\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_SHUFFLE\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_200\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Sonic Mighty 4K.ini b/PrusaSlicer/printer/Phrozen Sonic Mighty 4K.ini
index dd9fd15..9fc0045 100644
--- a/PrusaSlicer/printer/Phrozen Sonic Mighty 4K.ini
+++ b/PrusaSlicer/printer/Phrozen Sonic Mighty 4K.ini
@@ -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_PHROZEN\nPRINTER_MODEL_SONIC_MIGHTY_4K\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_11\nBottomLightOffDelay_11\nBottomLiftHeight_8\nLiftHeight_6\nBottomLiftSpeed_60\nLiftSpeed_60\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_SONIC_MIGHTY_4K\nFILEFORMAT_CTB\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_8\nLiftHeight_6\nBottomLiftSpeed_60\nLiftSpeed_60\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Sonic.ini b/PrusaSlicer/printer/Phrozen Sonic.ini
index 8fe4087..cbfd4e4 100644
--- a/PrusaSlicer/printer/Phrozen Sonic.ini
+++ b/PrusaSlicer/printer/Phrozen Sonic.ini
@@ -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_PHROZEN\nPRINTER_MODEL_SONIC\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_6\nBottomLightOffDelay_6\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_200\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_SONIC\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_6\nLiftHeight_5\nBottomLiftSpeed_100\nLiftSpeed_100\nRetractSpeed_200\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Phrozen Transform.ini b/PrusaSlicer/printer/Phrozen Transform.ini
index 0674451..5d1dfea 100644
--- a/PrusaSlicer/printer/Phrozen Transform.ini
+++ b/PrusaSlicer/printer/Phrozen Transform.ini
@@ -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_PHROZEN\nPRINTER_MODEL_TRANSFORM\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_10\nBottomLightOffDelay_10\nBottomLiftHeight_10\nLiftHeight_8\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\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_PHROZEN\nPRINTER_MODEL_TRANSFORM\nFILEFORMAT_ZIP\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_10\nLiftHeight_8\nBottomLiftSpeed_65\nLiftSpeed_65\nRetractSpeed_150\nBottomLightPWM_255\nLightPWM_255\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Uniz IBEE.ini b/PrusaSlicer/printer/Uniz IBEE.ini
index d760053..2a7d1ca 100644
--- a/PrusaSlicer/printer/Uniz IBEE.ini
+++ b/PrusaSlicer/printer/Uniz IBEE.ini
@@ -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_UNIZ\nPRINTER_MODEL_IBEE\nFILEFORMAT_ZCODE\n\nSTART_CUSTOM_VALUES\nLightOffDelay_2\nBottomLightOffDelay_4\nBottomLiftHeight_15\nLiftHeight_7\nBottomLiftSpeed_20\nLiftSpeed_80\nRetractSpeed_80\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_UNIZ\nPRINTER_MODEL_IBEE\nFILEFORMAT_ZCODE\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nBottomLightOffDelay_0\nBottomLiftHeight_15\nLiftHeight_7\nBottomLiftSpeed_20\nLiftSpeed_80\nRetractSpeed_80\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/PrusaSlicer/printer/Zortrax Inkspire.ini b/PrusaSlicer/printer/Zortrax Inkspire.ini
index 4b574ec..f35d066 100644
--- a/PrusaSlicer/printer/Zortrax Inkspire.ini
+++ b/PrusaSlicer/printer/Zortrax Inkspire.ini
@@ -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_ZORTRAX\nPRINTER_MODEL_INKSPIRE\nFILEFORMAT_ZCODEX\n\nSTART_CUSTOM_VALUES\nLightOffDelay_5\nLiftHeight_5\nLiftSpeed_100\nRetractSpeed_100\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_ZORTRAX\nPRINTER_MODEL_INKSPIRE\nFILEFORMAT_ZCODEX\n\nSTART_CUSTOM_VALUES\nLightOffDelay_0\nLiftHeight_5\nLiftSpeed_100\nRetractSpeed_100\nEND_CUSTOM_VALUES
printer_settings_id =
printer_technology = SLA
printer_variant = default
diff --git a/UVtools.Core/Extensions/EmguExtensions.cs b/UVtools.Core/Extensions/EmguExtensions.cs
index 9ea852a..2806e43 100644
--- a/UVtools.Core/Extensions/EmguExtensions.cs
+++ b/UVtools.Core/Extensions/EmguExtensions.cs
@@ -220,6 +220,11 @@ namespace UVtools.Core.Extensions
return new byte[mat.GetLength()];
}
+ public static Mat New(this Mat mat)
+ {
+ return new(mat.Rows, mat.Cols, mat.Depth, mat.NumberOfChannels);
+ }
+
/// <summary>
/// Clone this <see cref="Mat"/> blanked (All zeros)
/// </summary>
diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs
index 9b05d2e..ff2f5c3 100644
--- a/UVtools.Core/FileFormats/FileFormat.cs
+++ b/UVtools.Core/FileFormats/FileFormat.cs
@@ -915,11 +915,11 @@ namespace UVtools.Core.FileFormats
}
var lightOffDelay = OperationCalculator.LightOffDelayC.CalculateSeconds(layer.LiftHeight, layer.LiftSpeed, layer.RetractSpeed);
- time += layer.ExposureTime;
- if (lightOffDelay >= layer.LightOffDelay)
+ time += layer.ExposureTime + lightOffDelay;
+ /*if (lightOffDelay >= layer.LightOffDelay)
time += lightOffDelay;
else
- time += layer.LightOffDelay;
+ time += layer.LightOffDelay;*/
}
}
@@ -1043,18 +1043,19 @@ namespace UVtools.Core.FileFormats
{
if (SuppressRebuildProperties) return;
if (
- e.PropertyName == nameof(BottomLayerCount) ||
- e.PropertyName == nameof(BottomExposureTime) ||
- e.PropertyName == nameof(ExposureTime) ||
- e.PropertyName == nameof(BottomLightOffDelay) ||
- e.PropertyName == nameof(LightOffDelay) ||
- e.PropertyName == nameof(BottomLiftHeight) ||
- e.PropertyName == nameof(LiftHeight) ||
- e.PropertyName == nameof(BottomLiftSpeed) ||
- e.PropertyName == nameof(LiftSpeed) ||
- e.PropertyName == nameof(RetractSpeed) ||
- e.PropertyName == nameof(BottomLightPWM) ||
- e.PropertyName == nameof(LightPWM)
+ e.PropertyName
+ is nameof(BottomLayerCount)
+ or nameof(BottomExposureTime)
+ or nameof(ExposureTime)
+ or nameof(BottomLightOffDelay)
+ or nameof(LightOffDelay)
+ or nameof(BottomLiftHeight)
+ or nameof(LiftHeight)
+ or nameof(BottomLiftSpeed)
+ or nameof(LiftSpeed)
+ or nameof(RetractSpeed)
+ or nameof(BottomLightPWM)
+ or nameof(LightPWM)
)
{
LayerManager?.RebuildLayersProperties(false, e.PropertyName);
diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs
index a5dc4e9..84df8fb 100644
--- a/UVtools.Core/Layer/Layer.cs
+++ b/UVtools.Core/Layer/Layer.cs
@@ -312,6 +312,8 @@ namespace UVtools.Core
}
}
+ public Mat LayerMatBoundingRectangle => new(LayerMat, BoundingRectangle);
+
/// <summary>
/// Gets a new Brg image instance
/// </summary>
diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs
index 84ab961..2abd13e 100644
--- a/UVtools.Core/Layer/LayerManager.cs
+++ b/UVtools.Core/Layer/LayerManager.cs
@@ -14,7 +14,6 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
-using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
@@ -523,6 +522,7 @@ namespace UVtools.Core
if(zeroLightOffDelay) layer.LightOffDelay = 0;
}
SlicerFile?.RebuildGCode();
+ SlicerFile.PrintTime = SlicerFile.PrintTimeComputed;
}
public Rectangle GetBoundingRectangle(OperationProgress progress = null)
diff --git a/UVtools.Core/Objects/ExposureItem.cs b/UVtools.Core/Objects/ExposureItem.cs
index 8e889f5..6ab12ab 100644
--- a/UVtools.Core/Objects/ExposureItem.cs
+++ b/UVtools.Core/Objects/ExposureItem.cs
@@ -97,5 +97,10 @@ namespace UVtools.Core.Objects
if (exposureComparison != 0) return exposureComparison;
return _brightness.CompareTo(other._brightness);
}
+
+ public ExposureItem Clone()
+ {
+ return MemberwiseClone() as ExposureItem;
+ }
}
}
diff --git a/UVtools.Core/Operations/OperationCalculator.cs b/UVtools.Core/Operations/OperationCalculator.cs
index d4c0384..e683af4 100644
--- a/UVtools.Core/Operations/OperationCalculator.cs
+++ b/UVtools.Core/Operations/OperationCalculator.cs
@@ -287,7 +287,7 @@ namespace UVtools.Core.Operations
}
catch (Exception)
{
- return 0;
+ return extraWaitTime;
}
}
diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
index e039b8a..8c886a6 100644
--- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
+++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
@@ -7,11 +7,13 @@
*/
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Linq;
using System.Text;
+using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
@@ -48,17 +50,19 @@ namespace UVtools.Core.Operations
private byte _chamferLayers = 0;
private byte _erodeBottomIterations = 0;
private decimal _partMargin = 0;
- private bool _enableAntiAliasing = true;
+ private bool _enableAntiAliasing = false;
private bool _mirrorOutput;
private decimal _baseHeight = 1;
private decimal _featuresHeight = 1;
- private decimal _featuresMargin = 1.5m;
+ private decimal _featuresMargin = 2m;
private Measures _unitOfMeasure = Measures.Pixels;
- private string _holeDiametersPx = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13";
- private string _holeDiametersMm = "0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.4";
+ private string _holeDiametersPx = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11";
+ private string _holeDiametersMm = "0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2";
private decimal _barSpacing = 1.5m;
private decimal _barLength = 4;
private sbyte _barVerticalSplitter = 0;
+ private byte _barFenceThickness = 12;
+ private byte _barFenceOffset;
private string _barThicknessesPx = "4, 6, 8, 10, 12, 14, 16, 18, 20";
private string _barThicknessesMm = "0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2";
private FontFace _textFont = TextMarkingFontFace;
@@ -81,7 +85,7 @@ namespace UVtools.Core.Operations
private bool _multipleExposures;
private ExposureGenTypes _exposureGenType = ExposureGenTypes.Linear;
private bool _exposureGenIgnoreBaseExposure;
- private decimal _exposureGenBottomStep = 0.5m;
+ private decimal _exposureGenBottomStep = 0;
private decimal _exposureGenNormalStep = 0.2m;
private byte _exposureGenTests = 4;
private decimal _exposureGenManualLayerHeight;
@@ -89,6 +93,8 @@ namespace UVtools.Core.Operations
private decimal _exposureGenManualNormal;
private RangeObservableCollection<ExposureItem> _exposureTable = new();
private CalibrateExposureFinderShapes _holeShape = CalibrateExposureFinderShapes.Square;
+ private bool _patternModel;
+ private bool _patternModelGlueBottomLayers = true;
#endregion
@@ -128,9 +134,14 @@ namespace UVtools.Core.Operations
sb.AppendLine("Display height must be a positive value.");
}
- if (Holes.Length <= 0)
+ if (!_patternModel && Bars.Length <= 0 && Holes.Length <= 0 && string.IsNullOrWhiteSpace(Text))
{
- sb.AppendLine("No objects to output.");
+ sb.AppendLine("No objects to output, enable at least 1 feature.");
+ }
+
+ if (_chamferLayers * _layerHeight > _baseHeight)
+ {
+ sb.AppendLine("The chamfer can't be higher than the base height, lower the chamfer layer count.");
}
if (_multipleExposures)
@@ -150,7 +161,7 @@ namespace UVtools.Core.Operations
}
}
if(!found)
- sb.AppendLine($"[ME]: {Layer.ShowHeight(layerHeight)}mm layer height have no exposure(s).");
+ sb.AppendLine($"[ME]: The {Layer.ShowHeight(layerHeight)}mm layer height have no set exposure(s).");
}
}
@@ -158,7 +169,20 @@ namespace UVtools.Core.Operations
{
if (MultipleBrightnessValuesArray.Length == 0)
{
- sb.AppendLine($"[MB]: Multiple brightness tests are enabled but no valid values are set, use from 1 to 255.");
+ sb.AppendLine($"Multiple brightness tests are enabled but no valid values are set, use from 1 to 255.");
+ }
+ }
+
+ if (_patternModel)
+ {
+ if (!CanPatternModel)
+ {
+ sb.AppendLine($"Unable to pattern the loaded model within the available space.");
+ }
+
+ if (!_multipleBrightness && !_multipleExposures)
+ {
+ sb.AppendLine($"Pattern the loaded model requires either multiple brightness or multiple exposures to use with.");
}
}
@@ -361,7 +385,7 @@ namespace UVtools.Core.Operations
if (string.IsNullOrWhiteSpace(mmStr)) continue;
if (!decimal.TryParse(mmStr, out var mm)) continue;
var mmPx = (int)Math.Floor(mm * Ppmm);
- if (mmPx <= 0 || mmPx > 500) continue;
+ if (mmPx is <= 0 or > 500) continue;
if(holes.Contains(mmPx)) continue;
holes.Add((int)Math.Floor(mm * Ppmm));
}
@@ -373,7 +397,7 @@ namespace UVtools.Core.Operations
{
if (string.IsNullOrWhiteSpace(pxStr)) continue;
if (!int.TryParse(pxStr, out var px)) continue;
- if (px <= 0 || px > 500) continue;
+ if (px is <= 0 or > 500) continue;
if (holes.Contains(px)) continue;
holes.Add(px);
}
@@ -385,6 +409,7 @@ namespace UVtools.Core.Operations
public int GetHolesLength(int[] holes)
{
+ if (holes.Length == 0) return 0;
return (int) (holes.Sum() + (holes.Length-1) * _featuresMargin * Yppmm);
}
@@ -406,6 +431,18 @@ namespace UVtools.Core.Operations
set => RaiseAndSetIfChanged(ref _barVerticalSplitter, value);
}
+ public byte BarFenceThickness
+ {
+ get => _barFenceThickness;
+ set => RaiseAndSetIfChanged(ref _barFenceThickness, value);
+ }
+
+ public byte BarFenceOffset
+ {
+ get => _barFenceOffset;
+ set => RaiseAndSetIfChanged(ref _barFenceOffset, value);
+ }
+
public string BarThicknessesPx
{
get => _barThicknessesPx;
@@ -447,7 +484,7 @@ namespace UVtools.Core.Operations
{
if (string.IsNullOrWhiteSpace(pxStr)) continue;
if (!int.TryParse(pxStr, out var px)) continue;
- if (px <= 0 || px > 500) continue;
+ if (px is <= 0 or > 500) continue;
if (bars.Contains(px)) continue;
bars.Add(px);
}
@@ -457,9 +494,15 @@ namespace UVtools.Core.Operations
}
}
- public int GetBarsWidth(int[] bars)
+ public int GetBarsLength(int[] bars)
{
- return (int)(bars.Sum() + (bars.Length + 1) * _barSpacing * Yppmm);
+ if (bars.Length == 0) return 0;
+ int len = (int) (bars.Sum() + (bars.Length + 1) * _barSpacing * Yppmm);
+ if (_barFenceThickness > 0)
+ {
+ len += _barFenceThickness * 2 + _barFenceOffset * 2;
+ }
+ return len;
}
public static Array TextFonts => Enum.GetValues(typeof(FontFace));
@@ -685,6 +728,30 @@ namespace UVtools.Core.Operations
set => RaiseAndSetIfChanged(ref _exposureTable, value);
}
+ public bool PatternModel
+ {
+ get => _patternModel;
+ set
+ {
+ if(!RaiseAndSetIfChanged(ref _patternModel, value)) return;
+ if (_patternModel)
+ {
+ LayerHeight = (decimal) SlicerFile.LayerHeight;
+ MultipleLayerHeight = false;
+ }
+ }
+ }
+
+ public bool PatternModelGlueBottomLayers
+ {
+ get => _patternModelGlueBottomLayers;
+ set => RaiseAndSetIfChanged(ref _patternModelGlueBottomLayers, value);
+ }
+
+
+ public bool CanPatternModel => SlicerFile.BoundingRectangle.Width * 2 + _leftRightMargin * 2 + _partMargin * Xppmm < SlicerFile.ResolutionX ||
+ SlicerFile.BoundingRectangle.Height * 2 + _topBottomMargin * 2 + _partMargin * Yppmm < SlicerFile.ResolutionY;
+
#endregion
#region Constructor
@@ -764,7 +831,7 @@ namespace UVtools.Core.Operations
private bool Equals(OperationCalibrateExposureFinder other)
{
- return _layerHeight == other._layerHeight && _bottomLayers == other._bottomLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _topBottomMargin == other._topBottomMargin && _leftRightMargin == other._leftRightMargin && _chamferLayers == other._chamferLayers && _erodeBottomIterations == other._erodeBottomIterations && _partMargin == other._partMargin && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput && _baseHeight == other._baseHeight && _featuresHeight == other._featuresHeight && _featuresMargin == other._featuresMargin && _unitOfMeasure == other._unitOfMeasure && _holeDiametersPx == other._holeDiametersPx && _holeDiametersMm == other._holeDiametersMm && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleBrightness == other._multipleBrightness && _multipleBrightnessExcludeFrom == other._multipleBrightnessExcludeFrom && _multipleBrightnessValues == other._multipleBrightnessValues && _dontLiftSamePositionedLayers == other._dontLiftSamePositionedLayers && _zeroLightOffSamePositionedLayers == other._zeroLightOffSamePositionedLayers && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && Equals(_exposureTable, other._exposureTable) && _holeShape == other._holeShape;
+ return _displayWidth == other._displayWidth && _displayHeight == other._displayHeight && _layerHeight == other._layerHeight && _bottomLayers == other._bottomLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _topBottomMargin == other._topBottomMargin && _leftRightMargin == other._leftRightMargin && _chamferLayers == other._chamferLayers && _erodeBottomIterations == other._erodeBottomIterations && _partMargin == other._partMargin && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput && _baseHeight == other._baseHeight && _featuresHeight == other._featuresHeight && _featuresMargin == other._featuresMargin && _unitOfMeasure == other._unitOfMeasure && _holeDiametersPx == other._holeDiametersPx && _holeDiametersMm == other._holeDiametersMm && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barFenceThickness == other._barFenceThickness && _barFenceOffset == other._barFenceOffset && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleBrightness == other._multipleBrightness && _multipleBrightnessExcludeFrom == other._multipleBrightnessExcludeFrom && _multipleBrightnessValues == other._multipleBrightnessValues && _multipleBrightnessGenExposureTime == other._multipleBrightnessGenExposureTime && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _dontLiftSamePositionedLayers == other._dontLiftSamePositionedLayers && _zeroLightOffSamePositionedLayers == other._zeroLightOffSamePositionedLayers && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && _exposureGenManualLayerHeight == other._exposureGenManualLayerHeight && _exposureGenManualBottom == other._exposureGenManualBottom && _exposureGenManualNormal == other._exposureGenManualNormal && Equals(_exposureTable, other._exposureTable) && _holeShape == other._holeShape && _patternModel == other._patternModel && _patternModelGlueBottomLayers == other._patternModelGlueBottomLayers;
}
public override bool Equals(object obj)
@@ -775,6 +842,8 @@ namespace UVtools.Core.Operations
public override int GetHashCode()
{
var hashCode = new HashCode();
+ hashCode.Add(_displayWidth);
+ hashCode.Add(_displayHeight);
hashCode.Add(_layerHeight);
hashCode.Add(_bottomLayers);
hashCode.Add(_bottomExposure);
@@ -795,6 +864,8 @@ namespace UVtools.Core.Operations
hashCode.Add(_barSpacing);
hashCode.Add(_barLength);
hashCode.Add(_barVerticalSplitter);
+ hashCode.Add(_barFenceThickness);
+ hashCode.Add(_barFenceOffset);
hashCode.Add(_barThicknessesPx);
hashCode.Add(_barThicknessesMm);
hashCode.Add((int) _textFont);
@@ -804,6 +875,7 @@ namespace UVtools.Core.Operations
hashCode.Add(_multipleBrightness);
hashCode.Add((int) _multipleBrightnessExcludeFrom);
hashCode.Add(_multipleBrightnessValues);
+ hashCode.Add(_multipleBrightnessGenExposureTime);
hashCode.Add(_multipleLayerHeight);
hashCode.Add(_multipleLayerHeightMaximum);
hashCode.Add(_multipleLayerHeightStep);
@@ -815,8 +887,13 @@ namespace UVtools.Core.Operations
hashCode.Add(_exposureGenBottomStep);
hashCode.Add(_exposureGenNormalStep);
hashCode.Add(_exposureGenTests);
+ hashCode.Add(_exposureGenManualLayerHeight);
+ hashCode.Add(_exposureGenManualBottom);
+ hashCode.Add(_exposureGenManualNormal);
hashCode.Add(_exposureTable);
hashCode.Add((int) _holeShape);
+ hashCode.Add(_patternModel);
+ hashCode.Add(_patternModelGlueBottomLayers);
return hashCode.ToHashCode();
}
@@ -831,9 +908,14 @@ namespace UVtools.Core.Operations
public void SanitizeExposureTable()
{
- List<ExposureItem> list = _exposureTable.ToList().Distinct().ToList();
+ _exposureTable.ReplaceCollection(GetSanitizedExposureTable());
+ }
+
+ public List<ExposureItem> GetSanitizedExposureTable()
+ {
+ var list = _exposureTable.ToList().Distinct().ToList();
list.Sort();
- _exposureTable.ReplaceCollection(list);
+ return list;
}
public void GenerateExposure()
@@ -875,17 +957,16 @@ namespace UVtools.Core.Operations
public Mat[] GetLayers()
{
var holes = Holes;
- if (holes.Length == 0) return null;
+ //if (holes.Length == 0) return null;
var bars = Bars;
var textSize = TextSize;
int featuresMarginX = (int)(Xppmm * _featuresMargin);
int featuresMarginY = (int)(Yppmm * _featuresMargin);
- int holePanelWidth = featuresMarginX * 2 + holes[^1];
-
-
- int yMaxSize = Math.Max(Math.Max(GetHolesLength(holes), GetBarsWidth(bars)), textSize.Width);
+ int holePanelWidth = holes.Length > 0 ? featuresMarginX * 2 + holes[^1] : featuresMarginX / 2;
+ int barsPanelHeight = GetBarsLength(bars);
+ int yMaxSize = Math.Max(Math.Max(GetHolesLength(holes), barsPanelHeight), textSize.Width);
int xSize = holePanelWidth * 2;
int ySize = featuresMarginX * 3 + yMaxSize + TextMarkingSpacing;
@@ -896,12 +977,13 @@ namespace UVtools.Core.Operations
if (bars.Length > 0)
{
barsPanelWidth = barLengthPx * 2 + _barVerticalSplitter;
+ if (_barFenceThickness > 0)
+ {
+ barsPanelWidth += _barFenceThickness * 2 + _barFenceOffset * 2;
+ }
xSize += barsPanelWidth + featuresMarginX;
-
}
-
-
if (!textSize.IsEmpty)
{
xSize += textSize.Height + featuresMarginX;
@@ -909,13 +991,18 @@ namespace UVtools.Core.Operations
int positiveSideWidth = xSize - holePanelWidth;
- Rectangle rect = new Rectangle(new Point(1, 1), new Size(xSize, ySize));
+ Rectangle rect = new(new Point(1, 1), new Size(xSize, ySize));
var layers = new Mat[2];
layers[0] = EmguExtensions.InitMat(rect.Size.Inflate(2));
CvInvoke.Rectangle(layers[0], rect, EmguExtensions.WhiteByte, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
layers[1] = layers[0].CloneBlank();
- CvInvoke.Rectangle(layers[1], new Rectangle(rect.Size.Width - holePanelWidth, 0, rect.Size.Width, layers[0].Height), EmguExtensions.WhiteByte, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ if (holes.Length > 0)
+ {
+ CvInvoke.Rectangle(layers[1],
+ new Rectangle(rect.Size.Width - holePanelWidth, 0, rect.Size.Width, layers[0].Height),
+ EmguExtensions.WhiteByte, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ }
// Print holes
int xPos = 0;
@@ -1028,7 +1115,10 @@ namespace UVtools.Core.Operations
// Print Zebra bars
if (bars.Length > 0)
{
- yPos = featuresMarginY;
+ int yStartPos = featuresMarginY;
+ int xStartPos = xPos;
+ yPos = yStartPos + _barFenceThickness / 2 + _barFenceOffset;
+ xPos += _barFenceThickness / 2 + _barFenceOffset;
for (int i = 0; i < bars.Length; i++)
{
// Print positive bottom
@@ -1045,13 +1135,27 @@ namespace UVtools.Core.Operations
CvInvoke.Rectangle(layers[1], new Rectangle(xPos, yPos, barLengthPx - 1, barSpacingPx - 1),
EmguExtensions.WhiteByte, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ yPos += barSpacingPx;
+
+ if (_barFenceThickness > 0)
+ {
+ CvInvoke.Rectangle(layers[1], new Rectangle(
+ xStartPos - 1,
+ yStartPos - 1,
+ barsPanelWidth - _barFenceThickness + 1,
+ yPos - yStartPos + _barFenceThickness / 2 + _barFenceOffset + 1),
+ EmguExtensions.WhiteByte, _barFenceThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+
+ yPos += _barFenceThickness * 2 + _barFenceOffset * 2;
+ }
+
xPos += featuresMarginX;
}
if (!textSize.IsEmpty)
{
CvInvoke.Rotate(layers[1], layers[1], RotateFlags.Rotate90CounterClockwise);
- CvInvoke.PutText(layers[1], _text, new Point(featuresMarginX, layers[1].Height - barsPanelWidth - xPos), _textFont, _textScale, EmguExtensions.WhiteByte, _textThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(layers[1], _text, new Point(featuresMarginX, layers[1].Height - barsPanelWidth - featuresMarginX * (barsPanelWidth > 0 ? 2 : 1)), _textFont, _textScale, EmguExtensions.WhiteByte, _textThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
CvInvoke.Rotate(layers[1], layers[1], RotateFlags.Rotate90Clockwise);
}
@@ -1116,205 +1220,396 @@ namespace UVtools.Core.Operations
CvInvoke.Line(thumbnail, new Point(thumbnail.Width - xSpacing, 0), new Point(thumbnail.Width - xSpacing, ySpacing + 5), new MCvScalar(255, 27, 245), 3);
CvInvoke.PutText(thumbnail, "Exposure Time Cal.", new Point(xSpacing, ySpacing * 2), fontFace, fontScale, new MCvScalar(0, 255, 255), fontThickness);
CvInvoke.PutText(thumbnail, $"{Microns}um @ {BottomExposure}s/{NormalExposure}s", new Point(xSpacing, ySpacing * 3), fontFace, fontScale, EmguExtensions.White3Byte, fontThickness);
- CvInvoke.PutText(thumbnail, $"Features: {Holes.Length+Bars.Length}", new Point(xSpacing, ySpacing * 4), fontFace, fontScale, EmguExtensions.White3Byte, fontThickness);
+ if (_patternModel)
+ {
+ CvInvoke.PutText(thumbnail, $"Patterned Model", new Point(xSpacing, ySpacing * 4), fontFace, fontScale, EmguExtensions.White3Byte, fontThickness);
+ }
+ else
+ {
+ CvInvoke.PutText(thumbnail, $"Features: {Holes.Length + Bars.Length}", new Point(xSpacing, ySpacing * 4), fontFace, fontScale, EmguExtensions.White3Byte, fontThickness);
+ }
+
return thumbnail;
}
protected override bool ExecuteInternally(OperationProgress progress)
{
- var layers = GetLayers();
- if (layers is null) return false;
- progress.ItemCount = 0;
- SanitizeExposureTable();
- if (layers[0].Width > SlicerFile.ResolutionX || layers[0].Height > SlicerFile.ResolutionY)
- {
- return false;
- }
-
- List<Layer> newLayers = new();
-
- Dictionary<ExposureItem, Point> table = new();
- var endLayerHeight = _multipleLayerHeight ? _multipleLayerHeightMaximum : _layerHeight;
- var totalHeight = TotalHeight;
int sideMarginPx = (int)Math.Floor(_leftRightMargin * Xppmm);
int topBottomMarginPx = (int)Math.Floor(_topBottomMargin * Yppmm);
- uint layerIndex = 0;
- int currentX = sideMarginPx;
- int currentY = topBottomMarginPx;
- int featuresMarginX = (int)(Xppmm * _featuresMargin);
- int featuresMarginY = (int)(Yppmm * _featuresMargin);
-
- var holes = Holes;
+ int partMarginXPx = (int) Math.Floor(_partMargin * Xppmm);
+ int partMarginYPx = (int) Math.Floor(_partMargin * Yppmm);
var anchor = new Point(-1, -1);
using var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor);
- var brightnesses = MultipleBrightnessValuesArray;
-
- if (brightnesses.Length == 0 || !_multipleBrightness) brightnesses = new[] {byte.MaxValue};
-
- void AddLayer(decimal currentHeight, decimal layerHeight, decimal bottomExposure, decimal normalExposure)
+ if (_patternModel)
{
- var layerDifference = currentHeight / layerHeight;
-
- if (!layerDifference.IsInteger()) return; // Not at right height to process with layer height
- //Debug.WriteLine($"{currentHeight} / {layerHeight} = {layerDifference}, Floor={Math.Floor(layerDifference)}");
+ ConcurrentBag<Layer> parallelLayers = new();
+ Dictionary<ExposureItem, Point> table = new();
+ var boundingRectangle = SlicerFile.BoundingRectangle;
+ int xHalf = boundingRectangle.Width / 2;
+ int yHalf = boundingRectangle.Height / 2;
- using var mat = EmguExtensions.InitMat(SlicerFile.Resolution);
- int layerCountOnHeight = (int)Math.Floor(currentHeight / layerHeight);
- bool isBottomLayer = layerCountOnHeight <= _bottomLayers;
- bool isBaseLayer = currentHeight <= _baseHeight;
- ushort microns = (ushort)Math.Floor(layerHeight * 1000);
- Point position;
- bool addSomething = false;
-
- foreach(var brightness in brightnesses)
+ var brightnesses = MultipleBrightnessValuesArray;
+ var multipleExposures = _exposureTable.Where(item => item.IsValid && item.LayerHeight == (decimal) SlicerFile.LayerHeight).ToArray();
+ if (brightnesses.Length == 0 || !_multipleBrightness) brightnesses = new[] { byte.MaxValue };
+ if (multipleExposures.Length == 0 || !_multipleExposures) multipleExposures = new[] { new ExposureItem((decimal)SlicerFile.LayerHeight, _bottomExposure, _normalExposure) };
+
+ int currentX = sideMarginPx;
+ int currentY = topBottomMarginPx;
+ Rectangle glueBottomLayerRectangle = new(new Point(currentX, currentY), Size.Empty);
+ foreach (var multipleExposure in multipleExposures)
{
- var bottomExposureTemp = bottomExposure;
- var normalExposureTemp = normalExposure;
- ExposureItem key = new(layerHeight, bottomExposure, normalExposure, brightness);
-
- if (table.TryGetValue(key, out var pos))
- {
- position = pos;
- }
- else
+ foreach (var brightness in brightnesses)
{
- if (currentX + layers[0].Width + sideMarginPx > SlicerFile.ResolutionX)
+ if (currentX + boundingRectangle.Width + sideMarginPx >= SlicerFile.ResolutionX)
{
currentX = sideMarginPx;
- currentY += layers[0].Height + (int)Math.Floor(_partMargin * Yppmm);
- }
-
- if (currentY + layers[0].Height + topBottomMarginPx > SlicerFile.ResolutionY)
- {
- break; // Reach the end
+ currentY += boundingRectangle.Height + partMarginYPx;
}
- position = new Point(currentX, currentY);
- table.Add(key, new Point(currentX, currentY));
-
- currentX += layers[0].Width + (int)Math.Floor(_partMargin * Xppmm);
- }
+ if (currentY + topBottomMarginPx >= SlicerFile.ResolutionY) break;
-
- Mat matRoi = new(mat, new Rectangle(position, layers[0].Size));
+ var item = multipleExposure.Clone();
+ item.Brightness = brightness;
+ table.Add(item, new Point(currentX, currentY));
- layers[isBaseLayer ? 0 : 1].CopyTo(matRoi);
+ glueBottomLayerRectangle.Size = new Size(currentX + boundingRectangle.Width, currentY + boundingRectangle.Height);
- if (isBottomLayer && _erodeBottomIterations > 0)
- {
- CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _erodeBottomIterations, BorderType.Reflect101, default);
+ currentX += boundingRectangle.Width + partMarginXPx;
}
+ }
- if (layerCountOnHeight < _chamferLayers)
- {
- CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _chamferLayers - layerCountOnHeight, BorderType.Reflect101, default);
- }
+ if (table.Count <= 1) return false;
+ ushort microns = SlicerFile.LayerHeightUm;
- if (_multipleBrightness && brightness < 255)
+ var tableGrouped = table.GroupBy(pair => new {pair.Key.LayerHeight, pair.Key.BottomExposure, pair.Key.Exposure}).Distinct();
+ SlicerFile.BottomLayerCount = _bottomLayers;
+ progress.ItemCount = (uint) (SlicerFile.LayerCount * table.Count);
+ Parallel.For(0, SlicerFile.LayerCount, layerIndex =>
+ {
+ if (progress.Token.IsCancellationRequested) return;
+ var layer = SlicerFile[layerIndex];
+ using var mat = layer.LayerMat;
+ var matRoi = new Mat(mat, boundingRectangle);
+ int layerCountOnHeight = (int)Math.Floor(layer.PositionZ / SlicerFile.LayerHeight);
+ foreach (var group in tableGrouped)
{
- // normalExposure - 255
- // x - brightness
- normalExposureTemp = Math.Round(normalExposure * brightness / byte.MaxValue, 2);
- if (_multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.None)
+ var newLayer = layer.Clone();
+ newLayer.ExposureTime = (float)(newLayer.IsBottomLayer ? group.Key.BottomExposure : group.Key.Exposure);
+ using var newMat = mat.CloneBlank();
+ foreach (var brightness in brightnesses)
{
- bottomExposureTemp = Math.Round(bottomExposure * brightness / byte.MaxValue, 2);
+ ExposureItem item = new(group.Key.LayerHeight, group.Key.BottomExposure, group.Key.Exposure, brightness);
+ if(!table.TryGetValue(item, out var point)) continue;
+
+ var newMatRoi = new Mat(newMat, new Rectangle(point, matRoi.Size));
+ matRoi.CopyTo(newMatRoi);
+
+ if (layer.IsBottomLayer)
+ {
+ if (_patternModelGlueBottomLayers)
+ {
+ newMatRoi.SetTo(EmguExtensions.WhiteByte);
+ }
+ }
+
+ if (layerCountOnHeight < _chamferLayers)
+ {
+ CvInvoke.Erode(newMatRoi, newMatRoi, kernel, anchor, _chamferLayers - layerCountOnHeight, BorderType.Reflect101, default);
+ }
+
+ if (layer.IsBottomLayer)
+ {
+ if (_erodeBottomIterations > 0)
+ {
+ CvInvoke.Erode(newMatRoi, newMatRoi, kernel, anchor, _erodeBottomIterations, BorderType.Reflect101, default);
+ }
+
+ if (_multipleBrightness)
+ {
+ CvInvoke.PutText(newMatRoi, brightness.ToString(), new(xHalf - 60, yHalf + 20 - TextMarkingLineBreak * 4), TextMarkingFontFace, 2, EmguExtensions.BlackByte, 3, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ }
+ CvInvoke.PutText(newMatRoi, $"{microns}u", new(xHalf - 60, yHalf + 20 - TextMarkingLineBreak * 2), TextMarkingFontFace, 2, EmguExtensions.BlackByte, 3, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(newMatRoi, $"{group.Key.BottomExposure}s", new(xHalf - 60, yHalf + 20), TextMarkingFontFace, 2, EmguExtensions.BlackByte, 3, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(newMatRoi, $"{group.Key.Exposure}s", new(xHalf - 60, yHalf + 20 + TextMarkingLineBreak * 2), TextMarkingFontFace, 2, EmguExtensions.BlackByte, 3, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ }
+
+ if (brightness < 255)
+ {
+ if (_multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.None ||
+ _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.Bottom && !layer.IsBottomLayer ||
+ _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.BottomAndBase && !layer.IsBottomLayer)
+ {
+ using var pattern = matRoi.New();
+ pattern.SetTo(new MCvScalar(byte.MaxValue - brightness));
+ CvInvoke.Subtract(newMatRoi, pattern, newMatRoi);
+ }
+ }
}
+
+
+ newLayer.LayerMat = newMat;
+ parallelLayers.Add(newLayer);
+ progress.LockAndIncrement();
}
+ });
+
+ progress.Token.ThrowIfCancellationRequested();
+ if (parallelLayers.IsEmpty) return false;
+ var layers = parallelLayers.OrderBy(layer => layer.PositionZ).ThenBy(layer => layer.ExposureTime).ToList();
- var textHeightStart = matRoi.Height - featuresMarginY - TextMarkingSpacing;
- CvInvoke.PutText(matRoi, $"{microns}u", new Point(TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{bottomExposureTemp}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{normalExposureTemp}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{microns}u", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{bottomExposureTemp}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{normalExposureTemp}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ progress.ResetNameAndProcessed("Optimized layers");
- if(_multipleBrightness)
+ Layer currentLayer = layers[0];
+ for (var layerIndex = 1; layerIndex < layers.Count; layerIndex++)
+ {
+ progress.Token.ThrowIfCancellationRequested();
+ progress++;
+ var layer = layers[layerIndex];
+ if (currentLayer.PositionZ != layer.PositionZ ||
+ currentLayer.ExposureTime != layer.ExposureTime) // Different layers, cache and continue
{
- CvInvoke.PutText(matRoi, brightness.ToString(), new Point(matRoi.Width / 3, 35), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- if (brightness < 255 &&
- (_multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.None ||
- _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.Bottom && !isBottomLayer ||
- _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.BottomAndBase && !isBottomLayer && !isBaseLayer)
- )
- {
- using var pattern = matRoi.CloneBlank();
- pattern.SetTo(new MCvScalar(brightness));
- CvInvoke.BitwiseAnd(matRoi, pattern, matRoi, matRoi);
- }
+ currentLayer = layer;
+ continue;
}
- addSomething = true;
+ using var matCurrent = currentLayer.LayerMat;
+ using var mat = layer.LayerMat;
+
+ CvInvoke.Add(matCurrent, mat, matCurrent); // Sum layers
+ currentLayer.LayerMat = matCurrent;
+
+ layers[layerIndex] = null; // Discard
}
- if (!addSomething) return;
+ layers.RemoveAll(layer => layer is null); // Discard equal layers
- Layer layer = new(layerIndex++, mat, SlicerFile)
+ SlicerFile.SuppressRebuildPropertiesWork(() =>
{
- PositionZ = (float)currentHeight,
- ExposureTime = isBottomLayer ? (float)bottomExposure : (float)normalExposure,
- LiftHeight = isBottomLayer ? SlicerFile.BottomLiftHeight : SlicerFile.LiftHeight,
- LiftSpeed = isBottomLayer ? SlicerFile.BottomLiftSpeed : SlicerFile.LiftSpeed,
- RetractSpeed = SlicerFile.RetractSpeed,
- LightOffDelay = isBottomLayer ? SlicerFile.BottomLightOffDelay : SlicerFile.LightOffDelay,
- LightPWM = isBottomLayer ? SlicerFile.BottomLightPWM : SlicerFile.LightPWM,
- IsModified = true
- };
- newLayers.Add(layer);
-
- progress++;
+ SlicerFile.BottomExposureTime = (float)BottomExposure;
+ SlicerFile.ExposureTime = (float)NormalExposure;
+ SlicerFile.LayerManager.Layers = layers.ToArray();
+ });
}
-
- for (decimal currentHeight = _layerHeight; currentHeight <= totalHeight; currentHeight += Layer.HeightPrecisionIncrement)
+ else
{
- currentHeight = Layer.RoundHeight(currentHeight);
- for (decimal layerHeight = _layerHeight; layerHeight <= endLayerHeight; layerHeight += _multipleLayerHeightStep)
+ var layers = GetLayers();
+ if (layers is null) return false;
+ progress.ItemCount = 0;
+ //SanitizeExposureTable();
+ if (layers[0].Width > SlicerFile.ResolutionX || layers[0].Height > SlicerFile.ResolutionY)
{
- progress.Token.ThrowIfCancellationRequested();
- layerHeight = Layer.RoundHeight(layerHeight);
+ return false;
+ }
+
+ List<Layer> newLayers = new();
+
+ Dictionary<ExposureItem, Point> table = new();
+ var endLayerHeight = _multipleLayerHeight ? _multipleLayerHeightMaximum : _layerHeight;
+ var totalHeight = TotalHeight;
+ uint layerIndex = 0;
+ int currentX = sideMarginPx;
+ int currentY = topBottomMarginPx;
+ int featuresMarginX = (int)(Xppmm * _featuresMargin);
+ int featuresMarginY = (int)(Yppmm * _featuresMargin);
+
+ var holes = Holes;
+
+ var brightnesses = MultipleBrightnessValuesArray;
+ if (brightnesses.Length == 0 || !_multipleBrightness) brightnesses = new[] { byte.MaxValue };
+
+ ExposureItem lastExposureItem = null;
+ decimal lastcurrentHeight = 0;
+
+ void AddLayer(decimal currentHeight, decimal layerHeight, decimal bottomExposure, decimal normalExposure)
+ {
+ var layerDifference = currentHeight / layerHeight;
+
+ if (!layerDifference.IsInteger()) return; // Not at right height to process with layer height
+ //Debug.WriteLine($"{currentHeight} / {layerHeight} = {layerDifference}, Floor={Math.Floor(layerDifference)}");
+
- if (_multipleExposures)
+ int layerCountOnHeight = (int)Math.Floor(currentHeight / layerHeight);
+ bool isBottomLayer = layerCountOnHeight <= _bottomLayers;
+ bool isBaseLayer = currentHeight <= _baseHeight;
+ ushort microns = (ushort)Math.Floor(layerHeight * 1000);
+ Point position;
+ bool addSomething = false;
+
+ bool reUseLastLayer =
+ lastExposureItem is not null &&
+ lastcurrentHeight == currentHeight &&
+ lastExposureItem.LayerHeight == layerHeight &&
+ (isBottomLayer && lastExposureItem.BottomExposure == bottomExposure || !isBottomLayer && lastExposureItem.Exposure == normalExposure);
+
+ using var mat = reUseLastLayer ? newLayers[^1].LayerMat : EmguExtensions.InitMat(SlicerFile.Resolution);
+
+ lastcurrentHeight = currentHeight;
+
+ foreach (var brightness in brightnesses)
{
- foreach (var exposureItem in _exposureTable)
+ var bottomExposureTemp = bottomExposure;
+ var normalExposureTemp = normalExposure;
+ ExposureItem key = new(layerHeight, bottomExposure, normalExposure, brightness);
+ lastExposureItem = key;
+
+ if (table.TryGetValue(key, out var pos))
+ {
+ position = pos;
+ }
+ else
{
- if (exposureItem.IsValid && exposureItem.LayerHeight == layerHeight)
+ if (currentX + layers[0].Width + sideMarginPx > SlicerFile.ResolutionX)
{
- AddLayer(currentHeight, layerHeight, exposureItem.BottomExposure, exposureItem.Exposure);
+ currentX = sideMarginPx;
+ currentY += layers[0].Height + partMarginYPx;
}
+
+ if (currentY + layers[0].Height + topBottomMarginPx > SlicerFile.ResolutionY)
+ {
+ break; // Reach the end
+ }
+
+ position = new Point(currentX, currentY);
+ table.Add(key, new Point(currentX, currentY));
+
+ currentX += layers[0].Width + partMarginXPx;
}
+
+
+ Mat matRoi = new(mat, new Rectangle(position, layers[0].Size));
+
+ layers[isBaseLayer ? 0 : 1].CopyTo(matRoi);
+
+ if (isBottomLayer && _erodeBottomIterations > 0)
+ {
+ CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _erodeBottomIterations, BorderType.Reflect101, default);
+ }
+
+ if (layerCountOnHeight < _chamferLayers)
+ {
+ CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _chamferLayers - layerCountOnHeight, BorderType.Reflect101, default);
+ }
+
+ if (_multipleBrightness && brightness < 255)
+ {
+ // normalExposure - 255
+ // x - brightness
+ normalExposureTemp = Math.Round(normalExposure * brightness / byte.MaxValue, 2);
+ if (_multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.None)
+ {
+ bottomExposureTemp = Math.Round(bottomExposure * brightness / byte.MaxValue, 2);
+ }
+ }
+
+ var textHeightStart = matRoi.Height - featuresMarginY - TextMarkingSpacing;
+ CvInvoke.PutText(matRoi, $"{microns}u", new Point(TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{bottomExposureTemp}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{normalExposureTemp}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ if (holes.Length > 0)
+ {
+ CvInvoke.PutText(matRoi, $"{microns}u", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{bottomExposureTemp}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{normalExposureTemp}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ }
+
+ if (_multipleBrightness)
+ {
+ CvInvoke.PutText(matRoi, brightness.ToString(), new Point(matRoi.Width / 3, 35), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ if (brightness < 255 &&
+ (_multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.None ||
+ _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.Bottom && !isBottomLayer ||
+ _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.BottomAndBase && !isBottomLayer && !isBaseLayer)
+ )
+ {
+ using var pattern = matRoi.New();
+ //pattern.SetTo(new MCvScalar(brightness)); OLD
+ //CvInvoke.BitwiseAnd(matRoi, pattern, matRoi, matRoi); OLD
+
+ pattern.SetTo(new MCvScalar(byte.MaxValue - brightness));
+ CvInvoke.Subtract(matRoi, pattern, matRoi);
+ }
+ }
+
+ addSomething = true;
+ }
+
+ if (!addSomething) return;
+
+ if (reUseLastLayer)
+ {
+ newLayers[^1].LayerMat = mat;
}
else
{
- AddLayer(currentHeight, layerHeight, _bottomExposure, _normalExposure);
+ Layer layer = new(layerIndex++, mat, SlicerFile)
+ {
+ PositionZ = (float)currentHeight,
+ ExposureTime = isBottomLayer ? (float)bottomExposure : (float)normalExposure,
+ LiftHeight = isBottomLayer ? SlicerFile.BottomLiftHeight : SlicerFile.LiftHeight,
+ LiftSpeed = isBottomLayer ? SlicerFile.BottomLiftSpeed : SlicerFile.LiftSpeed,
+ RetractSpeed = SlicerFile.RetractSpeed,
+ LightOffDelay = isBottomLayer ? SlicerFile.BottomLightOffDelay : SlicerFile.LightOffDelay,
+ LightPWM = isBottomLayer ? SlicerFile.BottomLightPWM : SlicerFile.LightPWM,
+ IsModified = true
+ };
+ newLayers.Add(layer);
+ }
+
+
+ progress++;
+ }
+
+ for (decimal currentHeight = _layerHeight; currentHeight <= totalHeight; currentHeight += Layer.HeightPrecisionIncrement)
+ {
+ currentHeight = Layer.RoundHeight(currentHeight);
+ for (decimal layerHeight = _layerHeight; layerHeight <= endLayerHeight; layerHeight += _multipleLayerHeightStep)
+ {
+ progress.Token.ThrowIfCancellationRequested();
+ layerHeight = Layer.RoundHeight(layerHeight);
+
+ if (_multipleExposures)
+ {
+ foreach (var exposureItem in _exposureTable)
+ {
+ if (exposureItem.IsValid && exposureItem.LayerHeight == layerHeight)
+ {
+ AddLayer(currentHeight, layerHeight, exposureItem.BottomExposure, exposureItem.Exposure);
+ }
+ }
+ }
+ else
+ {
+ AddLayer(currentHeight, layerHeight, _bottomExposure, _normalExposure);
+ }
}
}
+
+ SlicerFile.SuppressRebuildPropertiesWork(() =>
+ {
+ SlicerFile.LayerHeight = (float)LayerHeight;
+ SlicerFile.BottomExposureTime = (float)BottomExposure;
+ SlicerFile.ExposureTime = (float)NormalExposure;
+ SlicerFile.BottomLayerCount = BottomLayers;
+ SlicerFile.LayerManager.Layers = newLayers.ToArray();
+ });
+
+ if (_mirrorOutput)
+ {
+ new OperationFlip(SlicerFile) { FlipDirection = Enumerations.FlipDirection.Horizontally }.Execute(progress);
+ }
}
if (SlicerFile.ThumbnailsCount > 0)
SlicerFile.SetThumbnails(GetThumbnail());
- SlicerFile.SuppressRebuildPropertiesWork(() =>
- {
- SlicerFile.LayerHeight = (float)LayerHeight;
- SlicerFile.BottomExposureTime = (float)BottomExposure;
- SlicerFile.ExposureTime = (float)NormalExposure;
- SlicerFile.BottomLayerCount = BottomLayers;
- SlicerFile.LayerManager.Layers = newLayers.ToArray();
- });
-
if (_dontLiftSamePositionedLayers)
{
SlicerFile.LayerManager.SetNoLiftForSamePositionedLayers(_zeroLightOffSamePositionedLayers);
}
- if (_mirrorOutput)
- {
- new OperationFlip(SlicerFile){FlipDirection = Enumerations.FlipDirection.Horizontally}.Execute(progress);
- }
-
new OperationMove(SlicerFile).Execute(progress);
return !progress.Token.IsCancellationRequested;
diff --git a/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs b/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs
index 454bbbc..13f30e1 100644
--- a/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs
+++ b/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs
@@ -10,13 +10,11 @@ using System;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
-using System.Xml.Serialization;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using UVtools.Core.Extensions;
using UVtools.Core.FileFormats;
-using UVtools.Core.Objects;
namespace UVtools.Core.Operations
{
@@ -38,7 +36,7 @@ namespace UVtools.Core.Operations
private bool _centerHoleRelief = true;
private bool _hollowModel = true;
private bool _mirrorOutput;
- private decimal _wallThickness = 2.5M;
+ private decimal _wallThickness = 3.0M;
private decimal _observedXSize;
private decimal _observedYSize;
private decimal _observedZSize;
diff --git a/UVtools.Core/Operations/OperationProgress.cs b/UVtools.Core/Operations/OperationProgress.cs
index 1771536..732434a 100644
--- a/UVtools.Core/Operations/OperationProgress.cs
+++ b/UVtools.Core/Operations/OperationProgress.cs
@@ -184,6 +184,12 @@ namespace UVtools.Core.Operations
ProcessedItems = items;
}
+ public void ResetNameAndProcessed(string name = "", uint items = 0)
+ {
+ ItemName = name;
+ ProcessedItems = items;
+ }
+
public override string ToString()
{
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index 8dce5fe..0ab2bb8 100644
--- a/UVtools.Core/UVtools.Core.csproj
+++ b/UVtools.Core/UVtools.Core.csproj
@@ -10,7 +10,7 @@
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
- <Version>2.9.2</Version>
+ <Version>2.9.3</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.ScriptSample/README.md b/UVtools.ScriptSample/README.md
index d8c60d8..4bcdc23 100644
--- a/UVtools.ScriptSample/README.md
+++ b/UVtools.ScriptSample/README.md
@@ -26,7 +26,7 @@ If you unsure about a script, run UVtools under a sandbox.
## How to write scripts (For developers)
-The Roslyn Scripts runs C# code directly but require some commun data structures to be removed from the commun csharp file,
+The Roslyn Scripts runs C# code directly but require some common data structures to be removed from the common csharp file,
such as "namespace" which is obligatory on a normal csharp file, and also a csharp file requires an class to encapsulate your code, you can't have code outside classes.
Scripts in otherway can run code directly without any namespace or class, so you can have a script just with "1 + 1",
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
index 5691f10..3a1e20a 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
@@ -10,7 +10,7 @@
<Border BorderBrush="Black" BorderThickness="1" Padding="5">
<Expander IsExpanded="True">
<Expander.Header>
- <TextBlock Text="Commun properties"
+ <TextBlock Text="Common properties"
FontWeight="Bold"
Cursor="Hand"/>
</Expander.Header>
@@ -40,7 +40,6 @@
ToolTip.Tip="The printer display height. Required to calculate the pixels per mm."
Text="Display height:"/>
<NumericUpDown Grid.Row="0" Grid.Column="8"
-
Increment="0.1"
Minimum="0"
Maximum="10000"
@@ -51,15 +50,18 @@
Text="mm"/>
<TextBlock Grid.Row="2" Grid.Column="0"
+ IsEnabled="{Binding !Operation.PatternModel}"
VerticalAlignment="Center"
Text="Layer height:"/>
<NumericUpDown Grid.Row="2" Grid.Column="2"
+ IsEnabled="{Binding !Operation.PatternModel}"
Increment="0.01"
Minimum="0.01"
Maximum="0.30"
FormatString="F3"
Value="{Binding Operation.LayerHeight}"/>
<TextBlock Grid.Row="2" Grid.Column="4"
+ IsEnabled="{Binding !Operation.PatternModel}"
VerticalAlignment="Center"
Text="mm"/>
@@ -168,11 +170,13 @@
<CheckBox Grid.Row="12" Grid.Column="2" Grid.ColumnSpan="5"
VerticalAlignment="Center"
+ IsEnabled="{Binding !Operation.PatternModel}"
IsChecked="{Binding Operation.EnableAntiAliasing}"
Content="Enable Anti-Aliasing"/>
<CheckBox Grid.Row="12" Grid.Column="8"
Grid.ColumnSpan="3"
+ IsEnabled="{Binding !Operation.PatternModel}"
ToolTip.Tip="Most of the printers requires a mirror output to print with the correct orientation"
IsChecked="{Binding Operation.MirrorOutput}"
Content="Mirror output" />
@@ -181,7 +185,8 @@
</Expander>
</Border>
- <Border BorderBrush="Black" BorderThickness="1" Padding="5">
+ <Border BorderBrush="Black" BorderThickness="1" Padding="5"
+ IsVisible="{Binding !Operation.PatternModel}">
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock Text="Object configuration"
@@ -190,7 +195,7 @@
</Expander.Header>
- <Grid RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
+ <Grid RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
ColumnDefinitions="Auto,10,Auto,5,Auto,20,Auto,10,Auto,5,Auto,20,Auto,10,Auto,5,Auto">
<TextBlock Grid.Row="0" Grid.Column="0"
Text="Base height:"
@@ -337,75 +342,100 @@
Text="px"/>
<TextBlock Grid.Row="12" Grid.Column="0"
+ Text="Fence thick:"
+ VerticalAlignment="Center"/>
+ <NumericUpDown Grid.Row="12" Grid.Column="2"
+ Increment="2"
+ Minimum="0"
+ Maximum="255"
+ Value="{Binding Operation.BarFenceThickness}"/>
+ <TextBlock Grid.Row="12" Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="px"/>
+
+ <TextBlock Grid.Row="12" Grid.Column="6"
+ Text="Fence offset:"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center"/>
+ <NumericUpDown Grid.Row="12" Grid.Column="8"
+ Increment="1"
+ Minimum="0"
+ Maximum="255"
+ Value="{Binding Operation.BarFenceOffset}"/>
+ <TextBlock Grid.Row="12" Grid.Column="10"
+ VerticalAlignment="Center"
+ Text="px"/>
+
+ <TextBlock Grid.Row="14" Grid.Column="0"
Text="Thicknesses:"
VerticalAlignment="Center"/>
- <TextBox Grid.Row="12" Grid.Column="2"
+ <TextBox Grid.Row="14" Grid.Column="2"
Grid.ColumnSpan="13"
IsVisible="{Binding Operation.IsUnitOfMeasureMm}"
Text="{Binding Operation.BarThicknessesMm}"/>
- <TextBox Grid.Row="12" Grid.Column="2"
+ <TextBox Grid.Row="14" Grid.Column="2"
Grid.ColumnSpan="13"
IsVisible="{Binding !Operation.IsUnitOfMeasureMm}"
Text="{Binding Operation.BarThicknessesPx}"/>
- <TextBlock Grid.Row="12" Grid.Column="16"
+ <TextBlock Grid.Row="14" Grid.Column="16"
IsVisible="{Binding Operation.IsUnitOfMeasureMm}"
VerticalAlignment="Center"
Text="mm"/>
- <TextBlock Grid.Row="12" Grid.Column="16"
+ <TextBlock Grid.Row="14" Grid.Column="16"
IsVisible="{Binding !Operation.IsUnitOfMeasureMm}"
VerticalAlignment="Center"
Text="px"/>
- <TextBlock Grid.Row="14" Grid.Column="0"
+ <TextBlock Grid.Row="16" Grid.Column="0"
Grid.ColumnSpan="17"
FontWeight="Bold"
Text="Text:"
VerticalAlignment="Center"/>
- <TextBlock Grid.Row="16" Grid.Column="0"
+ <TextBlock Grid.Row="18" Grid.Column="0"
Text="Font:"
VerticalAlignment="Center"/>
- <ComboBox Grid.Row="16" Grid.Column="2"
+ <ComboBox Grid.Row="18" Grid.Column="2"
Grid.ColumnSpan="3"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Items="{Binding Operation.TextFonts}"
SelectedItem="{Binding Operation.TextFont}"/>
- <TextBlock Grid.Row="16" Grid.Column="6"
+ <TextBlock Grid.Row="18" Grid.Column="6"
Text="Text scale:"
HorizontalAlignment="Right"
VerticalAlignment="Center"/>
- <NumericUpDown Grid.Row="16" Grid.Column="8"
+ <NumericUpDown Grid.Row="18" Grid.Column="8"
Increment="0.5"
Minimum="0.1"
Maximum="100"
FormatString="F2"
Value="{Binding Operation.TextScale}"/>
- <TextBlock Grid.Row="16" Grid.Column="10"
+ <TextBlock Grid.Row="18" Grid.Column="10"
VerticalAlignment="Center"
Text="x"/>
- <TextBlock Grid.Row="16" Grid.Column="12"
+ <TextBlock Grid.Row="18" Grid.Column="12"
Text="Text thickness:"
HorizontalAlignment="Right"
VerticalAlignment="Center"/>
- <NumericUpDown Grid.Row="16" Grid.Column="14"
+ <NumericUpDown Grid.Row="18" Grid.Column="14"
Increment="1"
Minimum="1"
Maximum="255"
Value="{Binding Operation.TextThickness}"/>
- <TextBlock Grid.Row="16" Grid.Column="16"
+ <TextBlock Grid.Row="18" Grid.Column="16"
VerticalAlignment="Center"
Text="px"/>
- <TextBlock Grid.Row="18" Grid.Column="0"
+ <TextBlock Grid.Row="20" Grid.Column="0"
Text="Text:"
VerticalAlignment="Center"/>
- <TextBox Grid.Row="18" Grid.Column="2"
+ <TextBox Grid.Row="20" Grid.Column="2"
Grid.ColumnSpan="13"
Text="{Binding Operation.Text}"/>
@@ -417,7 +447,7 @@
<Border BorderBrush="Black"
BorderThickness="1"
Padding="5">
- <Expander IsExpanded="True">
+ <Expander IsExpanded="False">
<Expander.Header>
<TextBlock Text="Multiple brightness"
FontWeight="Bold"
@@ -454,7 +484,7 @@
VerticalAlignment="Center"/>
<TextBlock Grid.Row="0" Grid.Column="6"
- ToolTip.Tip="Append a brightness level to the list by giving a desired exposure time. Supplied time must be lower than the commun exposure time or you need to increase it on the commun 'Normal Exposure'."
+ ToolTip.Tip="Append a brightness level to the list by giving a desired exposure time. Supplied time must be lower than the common exposure time or you need to increase it on the common 'Normal Exposure'."
Text="Generate by exposure time:"
VerticalAlignment="Center"/>
@@ -530,9 +560,14 @@
<Border BorderBrush="Black"
BorderThickness="1"
- Padding="5"
- IsVisible="{Binding CanSupportPerLayerSettings}">
- <Expander IsExpanded="True">
+ Padding="5">
+ <Border.IsVisible>
+ <MultiBinding Converter="{x:Static BoolConverters.And}">
+ <Binding Path="CanSupportPerLayerSettings"/>
+ <Binding Path="!Operation.PatternModel"/>
+ </MultiBinding>
+ </Border.IsVisible>
+ <Expander IsExpanded="False">
<Expander.Header>
<TextBlock Text="Multiple layer height"
FontWeight="Bold"
@@ -591,6 +626,7 @@
VerticalAlignment="Center"
Text="mm"/>
</Grid>
+
</StackPanel>
</Expander>
@@ -770,8 +806,6 @@
</Button>
</Grid>
-
-
<Grid RowDefinitions="Auto" ColumnDefinitions="Auto,*,Auto"
IsEnabled="{Binding Operation.MultipleExposures}"
Margin="0,10,0,0">
@@ -841,6 +875,84 @@
</Expander>
</Border>
+ <Border BorderBrush="Black"
+ BorderThickness="1"
+ Padding="5"
+ IsVisible="{Binding Operation.CanPatternModel}">
+ <Expander IsExpanded="False">
+ <Expander.Header>
+ <TextBlock Text="Pattern loaded model"
+ FontWeight="Bold"
+ Cursor="Hand"/>
+
+ </Expander.Header>
+
+ <StackPanel Spacing="10">
+
+ <TextBlock Text="This option will pattern the current loaded model and generate multiple exposure tests with it.
+&#x0a;Only few printers support this, make sure your is supported or else it will print a malformed model.
+&#x0a;After this, do not apply any modification which reconstruct the z positions of the layers."/>
+
+ <CheckBox
+ Content="Enable - For advanced users only!"
+ IsChecked="{Binding Operation.PatternModel}"/>
+
+ <CheckBox
+ Content="Glue bottom layers to merge the model into one piece"
+ ToolTip.Tip="If enabled, it will turn the bottom layers within the model area with solid white to merge all clones into one merged piece.
+&#x0a;Requires 'Part margin = 0' for effectively merge the models"
+ IsEnabled="{Binding Operation.PatternModel}"
+ IsChecked="{Binding Operation.PatternModelGlueBottomLayers}"/>
+
+ <!--
+ <Grid RowDefinitions="Auto"
+ ColumnDefinitions="Auto,10,Auto,5,Auto,20,Auto,10,Auto,5,Auto,20,Auto,10,Auto,5,Auto"
+ IsEnabled="{Binding Operation.MultipleLayerHeight}">
+ <TextBlock Grid.Row="0" Grid.Column="0"
+ Text="Start layer height:"
+ VerticalAlignment="Center"/>
+ <NumericUpDown Grid.Row="0" Grid.Column="2"
+ Increment="0.01"
+ Minimum="0.01"
+ Maximum="0.30"
+ FormatString="F3"
+ Value="{Binding Operation.LayerHeight}"/>
+ <TextBlock Grid.Row="0" Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="mm"/>
+
+ <TextBlock Grid.Row="0" Grid.Column="6"
+ Text="Increment step:"
+ VerticalAlignment="Center"/>
+ <NumericUpDown Grid.Row="0" Grid.Column="8"
+ Increment="0.01"
+ Minimum="0.01"
+ Maximum="0.1"
+ FormatString="F3"
+ Value="{Binding Operation.MultipleLayerHeightStep}"/>
+ <TextBlock Grid.Row="0" Grid.Column="10"
+ VerticalAlignment="Center"
+ Text="mm"/>
+
+ <TextBlock Grid.Row="0" Grid.Column="12"
+ Text="Maximum layer height:"
+ VerticalAlignment="Center"/>
+ <NumericUpDown Grid.Row="0" Grid.Column="14"
+ Increment="0.01"
+ Minimum="{Binding Operation.LayerHeight}"
+ Maximum="0.3"
+ FormatString="F3"
+ Value="{Binding Operation.MultipleLayerHeightMaximum}"/>
+ <TextBlock Grid.Row="0" Grid.Column="16"
+ VerticalAlignment="Center"
+ Text="mm"/>
+ </Grid>
+ !-->
+ </StackPanel>
+
+ </Expander>
+ </Border>
+
</StackPanel>
<Image Grid.Column="2"
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml
index d409854..d93cbf8 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateStressTowerControl.axaml
@@ -10,7 +10,7 @@
<Border BorderBrush="Black" BorderThickness="1" Padding="5">
<Expander IsExpanded="True">
<Expander.Header>
- <TextBlock Text="Step 1 - Commun properties"
+ <TextBlock Text="Step 1 - Common properties"
FontWeight="Bold"
Cursor="Hand"/>
</Expander.Header>
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml
index 35a190e..7e0c6ef 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateToleranceControl.axaml
@@ -10,7 +10,7 @@
<Border BorderBrush="Black" BorderThickness="1" Padding="5">
<Expander IsExpanded="True">
<Expander.Header>
- <TextBlock Text="Step 1 - Commun properties"
+ <TextBlock Text="Step 1 - Common properties"
FontWeight="Bold"
Cursor="Hand"/>
</Expander.Header>
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index 1ddef0a..546c6cf 100644
--- a/UVtools.WPF/UVtools.WPF.csproj
+++ b/UVtools.WPF/UVtools.WPF.csproj
@@ -12,7 +12,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
- <Version>2.9.2</Version>
+ <Version>2.9.3</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -24,14 +24,14 @@
<NoWarn>1701;1702;</NoWarn>
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Avalonia" Version="0.10.2" />
+ <PackageReference Include="Avalonia" Version="0.10.3" />
<PackageReference Include="Avalonia.Angle.Windows.Natives" Version="2.1.0.2020091801" />
- <PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.2" />
- <PackageReference Include="Avalonia.Desktop" Version="0.10.2" />
- <PackageReference Include="Avalonia.Diagnostics" Version="0.10.2" />
+ <PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.3" />
+ <PackageReference Include="Avalonia.Desktop" Version="0.10.3" />
+ <PackageReference Include="Avalonia.Diagnostics" Version="0.10.3" />
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.5.1.4349" />
<PackageReference Include="MessageBox.Avalonia" Version="1.2.0" />
- <PackageReference Include="ThemeEditor.Controls.ColorPicker" Version="0.10.2" />
+ <PackageReference Include="ThemeEditor.Controls.ColorPicker" Version="0.10.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UVtools.Core\UVtools.Core.csproj" />