diff --git a/README.md b/README.md
index 5c2cc0469f..d64ac1daad 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,139 @@
-
+# Bambu Studio - SoftFever
+A modified version of Bambu Studio with many handy features.
+It's fully compatible with Bambulab X1/X1-C printers.
+It also supports Voron and Prusa MK3S printers.
+You can download it here: https://github.com/SoftFever/BambuStudio-SoftFever/releases
+
+## BambuStudio SoftFever change notes:
+
+### [V1.3.1 changes](https://github.com/SoftFever/BambuStudio-SoftFever/releases/tag/v1.3.1-sf):
+1. Support change bed size and nozzle diameter
+2. Allow users to specify the bridge infill direction
+3. bridge_infill_direction1
+4. bridge_infill_direction2
+5. Change to ISO view angle for preview image
+6. Add an option to change Z Hop action: NormalLift/SpiralLift
+7. Optimise g-code generation for both Bambu printers and 3rd party printers
+8. Support Klipper Exclude Objects
+9. Better support for Moonraker's metadata.
+
+### [V1.2.5.3 changes](https://github.com/SoftFever/BambuStudio-SoftFever/releases/tag/v1.2.5.3-sf):
+1. Label objects to support Klipper Exclude Objects feature
+2. Allow users to change output file name format
+3. Fix a bug that pressure advance value was not saved in the profile
+4. Optimize non-Bambu printer profiles
+5. Remove M900 S0 which is not necessary.
+
+### [V1.2.5 changes](https://github.com/SoftFever/BambuStudio-SoftFever/releases/tag/v1.2.5-sf):
+1. Add options to adjust jerk for different line types
+2. Add an option to adjust acceleration for travel. Higher acceleration for travel and lower acceleration for the outer wall makes it possible to print faster and nicer.
+3. Add an option to manually override the Pressure Advance / Linear Advance for each filament.
+
+### [V1.2.4 changes](https://github.com/SoftFever/BambuStudio-SoftFever/releases/tag/v1.2.4-sf):
+1. Allow users to adjust accelerations for inner/outer walls separately.
+2. Allow users to adjust the bottom surface flow-rate
+3. Fix an issue that bed temperature for other layers is not set properly. This bug exists in the upstream as well. My PR here(bambulab#319)
+
+### [V1.2 changes](https://github.com/SoftFever/BambuStudio-SoftFever/releases/tag/v1.2-sf):
+1. Allow user to change machine limits
+2. Allow users to adjust the top surface flow-rate.
+3. Unlock some cool hidden features in BambuStudio.
+4. Fix an issue that the software connected to Bambulab's staging server by default. (Only Bambulab machines were affected)
+
+### [V1.1 changes](https://github.com/SoftFever/BambuStudio-SoftFever/releases/tag/v1.1):
+1. Support third-party printers:
+ - Voron 2.4
+ - Voron Trident
+ - Voron 0.1
+ - Prusa MK3S
+2. Export to to .gcode file.
+3. Send gcode file to printer
+4. Support single wall mode on first layer
+5. Support Chamber temperature. This setting can be use in machine start G-Gcode
+6. Support thumbview for third-party printers
+
+Demo video: https://youtu.be/vSNE9iGj2II
+
+## NOTE:
+## - If you have troubles to run the build, you might need to install following runtimes:
+- [MicrosoftEdgeWebView2RuntimeInstallerX64](https://github.com/SoftFever/BambuStudio-SoftFever/releases/download/v1.0.10-sf2/MicrosoftEdgeWebView2RuntimeInstallerX64.exe)
+- [vcredist2019_x64](https://github.com/SoftFever/BambuStudio-SoftFever/releases/download/v1.0.10-sf2/vcredist2019_x64.exe)
+
+## - BambuStudio use G2/G3 commands by default. You need to turn on ARC support in your printer's firmware use with this slicer.
+- For Voron and any Klipper based printers:
+You can enable gcode_arcs(G2/G3) support by adding following section into you printer.cfg file:
+```
+[gcode_arcs]
+resolution: 0.1
+
+[gcode_macro m201]
+gcode:
+ {% if 'X' in params or 'Y' in params %}
+ {% set accel = (params.X|default(params.Y)|float,
+ params.Y|default(params.X)|float)|min %}
+ SET_VELOCITY_LIMIT ACCEL={accel} ACCEL_TO_DECEL={accel * 0.5}
+ {% else %}
+ SET_VELOCITY_LIMIT
+ {% endif %}
+
+[gcode_macro m203]
+gcode:
+ {% if 'X' in params or 'Y' in params %}
+ {% set speed = (params.X|default(params.Y)|float,
+ params.Y|default(params.X)|float)|min %}
+ SET_VELOCITY_LIMIT VELOCITY={speed}
+ {% else %}
+ SET_VELOCITY_LIMIT
+ {% endif %}
+
+[gcode_macro M205]
+gcode:
+ {% if 'X' in params or 'Y' in params %}
+ {% set corner_speed = (params.X|default(params.Y)|float,
+ params.Y|default(params.X)|float)|min %}
+ SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY={corner_speed}
+ {% else %}
+ SET_VELOCITY_LIMIT
+ {% endif %}
+
+[gcode_macro M900]
+gcode:
+ SET_PRESSURE_ADVANCE ADVANCE={params.K}
+
+```
+
+It's also recommended to add followinging dummy macros to make Klipper happy
+```
+# Make BambuStudio happy
+[gcode_macro G17]
+gcode:
+
+```
+
+- For Prusa MK3S:
+ARC movement are supported by default.
+
+
+# Gallery
+
+
+
+
+
+
+
+
+
+Image credits:
+ 1. Voron 2.4 and Trident: vorondesign.com
+ 3. Voron 0.1: myself
+ 4. Prusa MK3S: Prusa3d
+
+
+=========================SPLIT=========================
+
+
# BambuStudio
Bambu Studio is a cutting-edge, feature-rich slicing software.
It contains project-based workflows, systematically optimized slicing algorithms, and an easy-to-use graphic interface, bringing users an incredibly smooth printing experience.
diff --git a/SoftFever_doc/1.2.5_feature1.png b/SoftFever_doc/1.2.5_feature1.png
new file mode 100644
index 0000000000..a6530a2883
Binary files /dev/null and b/SoftFever_doc/1.2.5_feature1.png differ
diff --git a/SoftFever_doc/1.2.5_feature2.png b/SoftFever_doc/1.2.5_feature2.png
new file mode 100644
index 0000000000..febba89dd4
Binary files /dev/null and b/SoftFever_doc/1.2.5_feature2.png differ
diff --git a/SoftFever_doc/accelerations.png b/SoftFever_doc/accelerations.png
new file mode 100644
index 0000000000..21e79aaa68
Binary files /dev/null and b/SoftFever_doc/accelerations.png differ
diff --git a/SoftFever_doc/chamber_temperature.png b/SoftFever_doc/chamber_temperature.png
new file mode 100644
index 0000000000..c41932d0c8
Binary files /dev/null and b/SoftFever_doc/chamber_temperature.png differ
diff --git a/SoftFever_doc/chamber_temperature_custom_gcode.png b/SoftFever_doc/chamber_temperature_custom_gcode.png
new file mode 100644
index 0000000000..d6b1c39ee6
Binary files /dev/null and b/SoftFever_doc/chamber_temperature_custom_gcode.png differ
diff --git a/SoftFever_doc/export_gcode.png b/SoftFever_doc/export_gcode.png
new file mode 100644
index 0000000000..ac6f64fd7e
Binary files /dev/null and b/SoftFever_doc/export_gcode.png differ
diff --git a/SoftFever_doc/hidden_features.png b/SoftFever_doc/hidden_features.png
new file mode 100644
index 0000000000..ff5f61ac00
Binary files /dev/null and b/SoftFever_doc/hidden_features.png differ
diff --git a/SoftFever_doc/machine_limits.png b/SoftFever_doc/machine_limits.png
new file mode 100644
index 0000000000..5f23ac43fa
Binary files /dev/null and b/SoftFever_doc/machine_limits.png differ
diff --git a/SoftFever_doc/print_host.png b/SoftFever_doc/print_host.png
new file mode 100644
index 0000000000..7c7bde717e
Binary files /dev/null and b/SoftFever_doc/print_host.png differ
diff --git a/SoftFever_doc/printers1.png b/SoftFever_doc/printers1.png
new file mode 100644
index 0000000000..3f9d99e194
Binary files /dev/null and b/SoftFever_doc/printers1.png differ
diff --git a/SoftFever_doc/printers2.png b/SoftFever_doc/printers2.png
new file mode 100644
index 0000000000..876efced92
Binary files /dev/null and b/SoftFever_doc/printers2.png differ
diff --git a/SoftFever_doc/printers3.png b/SoftFever_doc/printers3.png
new file mode 100644
index 0000000000..0ab6eaf479
Binary files /dev/null and b/SoftFever_doc/printers3.png differ
diff --git a/SoftFever_doc/printers4.png b/SoftFever_doc/printers4.png
new file mode 100644
index 0000000000..b431e3bf12
Binary files /dev/null and b/SoftFever_doc/printers4.png differ
diff --git a/SoftFever_doc/send_to_print.png b/SoftFever_doc/send_to_print.png
new file mode 100644
index 0000000000..68144974c6
Binary files /dev/null and b/SoftFever_doc/send_to_print.png differ
diff --git a/SoftFever_doc/single_wall_first_layer.png b/SoftFever_doc/single_wall_first_layer.png
new file mode 100644
index 0000000000..1ae304e24c
Binary files /dev/null and b/SoftFever_doc/single_wall_first_layer.png differ
diff --git a/SoftFever_doc/topsurface_flowrate.png b/SoftFever_doc/topsurface_flowrate.png
new file mode 100644
index 0000000000..dc6550beff
Binary files /dev/null and b/SoftFever_doc/topsurface_flowrate.png differ
diff --git a/SoftFever_doc/voron.png b/SoftFever_doc/voron.png
new file mode 100644
index 0000000000..e1fbc68877
Binary files /dev/null and b/SoftFever_doc/voron.png differ
diff --git a/bbl/i18n/BambuStudio.pot b/bbl/i18n/BambuStudio.pot
index d03d422aee..16cbd476dc 100644
--- a/bbl/i18n/BambuStudio.pot
+++ b/bbl/i18n/BambuStudio.pot
@@ -5140,6 +5140,20 @@ msgstr ""
msgid "Bridge flow"
msgstr ""
+msgid "Top surface flow ratio"
+msgstr ""
+
+msgid "Bottom surface flow ratio"
+msgstr ""
+
+msgid "This factor affects the amount of material for bottom solid infill"
+msgstr ""
+
+msgid ""
+"This factor affects the amount of material for top solid infill. "
+"You can decrease it slightly to have smooth surface finish"
+msgstr ""
+
msgid ""
"Decrease this value slightly(for example 0.9) to reduce the amount of "
"material for bridge, to improve sag"
@@ -5148,11 +5162,19 @@ msgstr ""
msgid "Only one wall on top surfaces"
msgstr ""
+msgid "Only one wall on first layer"
+msgstr ""
+
msgid ""
"Use only one wall on flat top surface, to give more space to the top infill "
"pattern"
msgstr ""
+msgid ""
+"Use only one wall on first layer, to give more space to the bottom infill "
+"pattern"
+msgstr ""
+
msgid "Slow down for overhang"
msgstr ""
diff --git a/bbl/i18n/zh_cn/BambuStudio_zh_CN.po b/bbl/i18n/zh_cn/BambuStudio_zh_CN.po
index 263722376c..8d76c1ac1d 100644
--- a/bbl/i18n/zh_cn/BambuStudio_zh_CN.po
+++ b/bbl/i18n/zh_cn/BambuStudio_zh_CN.po
@@ -3065,7 +3065,7 @@ msgid "Click to edit preset"
msgstr "点击编辑配置"
msgid "Connection"
-msgstr ""
+msgstr "连接打印机"
msgid "Bed type"
msgstr "热床类型"
@@ -5267,19 +5267,41 @@ msgstr ""
msgid "Bridge flow"
msgstr "桥接流量"
+msgid "Top surface flow ratio"
+msgstr "顶面流量"
+
+msgid "Bottom surface flow ratio"
+msgstr "首层流量"
+
+msgid "This factor affects the amount of material for bottom solid infill"
+msgstr "首层流量调整系数,默认为1.0"
+
+msgid ""
+"This factor affects the amount of material for top solid infill. "
+"You can decrease it slightly to have smooth surface finish"
+msgstr "稍微减小这个数值(比如0.97)可以来改善顶面的光滑程度。"
+
msgid ""
"Decrease this value slightly(for example 0.9) to reduce the amount of "
"material for bridge, to improve sag"
msgstr "稍微减小这个数值(比如0.9)可以减小桥接的材料量,来改善下垂。"
-msgid "Only one wall on top surfaces"
-msgstr "顶面单层墙"
+msgid "Only one wall on first layer"
+msgstr "首层单层墙"
msgid ""
"Use only one wall on flat top surface, to give more space to the top infill "
"pattern"
msgstr "顶面只使用单层墙,从而更多的空间能够使用顶部填充图案"
+msgid "Only one wall on top surfaces"
+msgstr "顶面单层墙"
+
+msgid ""
+"Use only one wall on first layer, to give more space to the bottom infill "
+"pattern"
+msgstr "首层只使用单层墙,从而更多的空间能够使用底部填充图案"
+
msgid "Slow down for overhang"
msgstr "悬垂降速"
@@ -5655,6 +5677,9 @@ msgstr "(未定义)"
msgid "Infill direction"
msgstr "填充方向"
+msgid "Bridge infill direction"
+msgstr "拉桥填充方向"
+
msgid ""
"Angle for sparse infill pattern, which controls the start or main direction "
"of line"
@@ -5707,6 +5732,45 @@ msgid ""
"adhensive"
msgstr "首层加速度。使用较低值可以改善和构建板的粘接。"
+msgid "Acceleration of outer walls"
+msgstr "外墙的加速度。它通常使用比内壁速度慢的加速度,以获得更好的质量"
+
+msgid "Acceleration of inner walls"
+msgstr "内圈墙加速度,使用较低值可以改善质量。"
+
+msgid "Acceleration of travel moves"
+msgstr "空驶加速度"
+
+msgid "Jerk(XY)"
+msgstr "抖动(XY)"
+
+msgid "Jerk of outer walls"
+msgstr "外墙抖动值"
+
+msgid "Jerk of inner walls"
+msgstr "内墙抖动值"
+
+msgid "Jerk for top surface"
+msgstr "顶面抖动值"
+
+msgid "Jerk for initial layer"
+msgstr "首层抖动值"
+
+msgid "Jerk for travel"
+msgstr "空驶抖动值"
+
+msgid "Enable pressure advance"
+msgstr "启用压力提前"
+
+msgid "Pressure advance"
+msgstr "压力提前"
+
+msgid "Pressure advnce(Klipper) AKA Linear advance factor(Marlin)"
+msgstr "压力提前(Klipper)或者线性提前(Marlin)"
+
+msgid "Enable pressure advance, auto calibration result will be overwriten once enabled."
+msgstr "启用压力提前,一旦启用会覆盖自动检测的结果"
+
msgid "Line width of initial layer"
msgstr "首层的线宽"
@@ -5831,6 +5895,9 @@ msgstr "如果机器有辅助部件冷却风扇,勾选该选项"
msgid "G-code flavor"
msgstr "G-code风格"
+msgid "G-code thumbnails"
+msgstr "G-code缩略图尺寸"
+
msgid "What kind of gcode the printer is compatible with"
msgstr "打印机兼容的G-code风格'"
@@ -6210,6 +6277,15 @@ msgstr ""
msgid "Z hop when retract"
msgstr "回抽时抬升Z"
+msgid "Z hop type"
+msgstr "抬Z类型"
+
+msgid "NormalLift"
+msgstr "直接抬Z"
+
+msgid "SpiralLift"
+msgstr "螺旋抬Z"
+
msgid ""
"Whenever the retraction is done, the nozzle is lifted a little to create "
"clearance between nozzle and the print. It prevents nozzle from hitting the "
@@ -6539,6 +6615,9 @@ msgstr "除首层外的其它层的喷嘴温度"
msgid "Nozzle temperature"
msgstr "喷嘴温度"
+msgid "Chamber temperature"
+msgstr "机箱温度"
+
msgid "Bed temperature difference"
msgstr "热床温差"
diff --git a/build_release.bat b/build_release.bat
new file mode 100644
index 0000000000..4f5aebef50
--- /dev/null
+++ b/build_release.bat
@@ -0,0 +1,14 @@
+set WP=%CD%
+cd deps
+mkdir build
+cd build
+set DEPS=%CD%/BambuStudio_dep
+cmake ../ -G "Visual Studio 16 2019" -DDESTDIR="%CD%/BambuStudio_dep" -DCMAKE_BUILD_TYPE=Release
+cmake --build . --config Release --target ALL_BUILD -- -m
+
+cd %WP%
+mkdir build
+cd build
+cmake .. -G "Visual Studio 16 2019" -DBBL_RELEASE_TO_PUBLIC=0 -DCMAKE_PREFIX_PATH="%DEPS%/usr/local" -DCMAKE_INSTALL_PREFIX="./BambuStudio-SoftFever" -DCMAKE_BUILD_TYPE=Release -DWIN10SDK_PATH="C:/Program Files (x86)/Windows Kits/10/Include/10.0.19041.0"
+cmake --build . --config Release --target ALL_BUILD -- -m
+cmake --build . --target install --config Release
\ No newline at end of file
diff --git a/build_release_macos.sh b/build_release_macos.sh
new file mode 100755
index 0000000000..4a2b513eb2
--- /dev/null
+++ b/build_release_macos.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+WD=$(pwd)
+cd deps
+mkdir -p build
+cd build
+DEPS=$PWD/BambuStudio_dep
+mkdir -p $DEPS
+cmake ../ -DDESTDIR="$DEPS" -DOPENSSL_ARCH="darwin64-$(uname -m)-cc" -DCMAKE_BUILD_TYPE=Release
+make -j10
+
+cd $WD
+mkdir -p build
+cd build
+cmake .. -DBBL_RELEASE_TO_PUBLIC=0 -DCMAKE_PREFIX_PATH="$DEPS/usr/local" -DCMAKE_INSTALL_PREFIX="$PWD/BambuStudio-SoftFever" -DCMAKE_BUILD_TYPE=Release -DCMAKE_MACOSX_RPATH=ON -DCMAKE_INSTALL_RPATH="$DEPS/usr/local" -DCMAKE_MACOSX_BUNDLE=ON
+cmake --build . --config Release --target all -j10
+cmake --build . --target install --config Release -j10
+cd BambuStudio-SoftFever
+cp -r bin/BambuStudio.app/Contents/MacOS BambuStudio.app/Contents
+cp -r bin/BambuStudio.app/Contents/Info.plist BambuStudio.app/Contents/
\ No newline at end of file
diff --git a/build_relwithdebinfo.bat b/build_relwithdebinfo.bat
new file mode 100644
index 0000000000..9502fe0170
--- /dev/null
+++ b/build_relwithdebinfo.bat
@@ -0,0 +1,14 @@
+set WP=%CD%
+cd deps
+mkdir build
+cd build
+set DEPS=%CD%/BambuStudio_dep
+cmake ../ -G "Visual Studio 16 2019" -DDESTDIR="%CD%/BambuStudio_dep" -DCMAKE_BUILD_TYPE=Release
+cmake --build . --config Release --target ALL_BUILD -- -m
+
+cd %WP%
+mkdir build
+cd build
+cmake .. -G "Visual Studio 16 2019" -DBBL_RELEASE_TO_PUBLIC=0 -DCMAKE_PREFIX_PATH="%DEPS%/usr/local" -DCMAKE_INSTALL_PREFIX="./BambuStudio-SoftFever" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWIN10SDK_PATH="C:/Program Files (x86)/Windows Kits/10/Include/10.0.19041.0"
+cmake --build . --config RelWithDebInfo --target ALL_BUILD -- -m
+@REM cmake --build . --target install --config RelWithDebInfo
\ No newline at end of file
diff --git a/resources/i18n/zh_cn/BambuStudio.mo b/resources/i18n/zh_cn/BambuStudio.mo
index b015d98c9d..d052221a54 100644
Binary files a/resources/i18n/zh_cn/BambuStudio.mo and b/resources/i18n/zh_cn/BambuStudio.mo differ
diff --git a/resources/images/add.svg b/resources/images/add.svg
new file mode 100644
index 0000000000..37050d7481
--- /dev/null
+++ b/resources/images/add.svg
@@ -0,0 +1,22 @@
+
+
+
diff --git a/resources/images/add_copies.svg b/resources/images/add_copies.svg
new file mode 100644
index 0000000000..45b1d27cf9
--- /dev/null
+++ b/resources/images/add_copies.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/resources/images/browse.svg b/resources/images/browse.svg
new file mode 100644
index 0000000000..c4297c41da
--- /dev/null
+++ b/resources/images/browse.svg
@@ -0,0 +1,11 @@
+
+
+
diff --git a/resources/profiles/Anycubic.json b/resources/profiles/Anycubic.json
new file mode 100644
index 0000000000..3d15169e5e
--- /dev/null
+++ b/resources/profiles/Anycubic.json
@@ -0,0 +1,110 @@
+{
+ "name": "Anycubic",
+ "version": "01.02.00.03",
+ "force_update": "0",
+ "description": "Anycubic configurations",
+ "machine_model_list": [
+ {
+ "name": "Anycubic 4Max Pro",
+ "sub_path": "machine/Anycubic 4Max Pro.json"
+ }
+ ],
+ "process_list": [
+ {
+ "name": "fdm_process_common",
+ "sub_path": "process/fdm_process_common.json"
+ },
+ {
+ "name": "0.20mm Standard @4MaxPro",
+ "sub_path": "process/0.20mm Standard @4MaxPro.json"
+ }
+ ],
+ "filament_list": [
+ {
+ "name": "fdm_filament_common",
+ "sub_path": "filament/fdm_filament_common.json"
+ },
+ {
+ "name": "fdm_filament_pla",
+ "sub_path": "filament/fdm_filament_pla.json"
+ },
+ {
+ "name": "fdm_filament_tpu",
+ "sub_path": "filament/fdm_filament_tpu.json"
+ },
+ {
+ "name": "fdm_filament_pet",
+ "sub_path": "filament/fdm_filament_pet.json"
+ },
+ {
+ "name": "fdm_filament_abs",
+ "sub_path": "filament/fdm_filament_abs.json"
+ },
+ {
+ "name": "fdm_filament_pc",
+ "sub_path": "filament/fdm_filament_pc.json"
+ },
+ {
+ "name": "fdm_filament_asa",
+ "sub_path": "filament/fdm_filament_asa.json"
+ },
+ {
+ "name": "fdm_filament_pva",
+ "sub_path": "filament/fdm_filament_pva.json"
+ },
+ {
+ "name": "fdm_filament_pa",
+ "sub_path": "filament/fdm_filament_pa.json"
+ },
+ {
+ "name": "Anycubic Generic PLA",
+ "sub_path": "filament/Anycubic Generic PLA.json"
+ },
+ {
+ "name": "Anycubic Generic PLA-CF",
+ "sub_path": "filament/Anycubic Generic PLA-CF.json"
+ },
+ {
+ "name": "Anycubic Generic PETG",
+ "sub_path": "filament/Anycubic Generic PETG.json"
+ },
+ {
+ "name": "Anycubic Generic ABS",
+ "sub_path": "filament/Anycubic Generic ABS.json"
+ },
+ {
+ "name": "Anycubic Generic TPU",
+ "sub_path": "filament/Anycubic Generic TPU.json"
+ },
+ {
+ "name": "Anycubic Generic ASA",
+ "sub_path": "filament/Anycubic Generic ASA.json"
+ },
+ {
+ "name": "Anycubic Generic PC",
+ "sub_path": "filament/Anycubic Generic PC.json"
+ },
+ {
+ "name": "Anycubic Generic PVA",
+ "sub_path": "filament/Anycubic Generic PVA.json"
+ },
+ {
+ "name": "Anycubic Generic PA",
+ "sub_path": "filament/Anycubic Generic PA.json"
+ },
+ {
+ "name": "Anycubic Generic PA-CF",
+ "sub_path": "filament/Anycubic Generic PA-CF.json"
+ }
+ ],
+ "machine_list": [
+ {
+ "name": "fdm_machine_common",
+ "sub_path": "machine/fdm_machine_common.json"
+ },
+ {
+ "name": "Anycubic 4Max Pro 0.4 nozzle",
+ "sub_path": "machine/Anycubic 4Max Pro 0.4 nozzle.json"
+ }
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic ABS.json b/resources/profiles/Anycubic/filament/Anycubic Generic ABS.json
new file mode 100644
index 0000000000..62800f76a8
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic ABS.json
@@ -0,0 +1,18 @@
+{
+ "type": "filament",
+ "filament_id": "GFB99",
+ "setting_id": "GFSB99",
+ "name": "Anycubic Generic ABS",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_abs",
+ "filament_flow_ratio": [
+ "0.926"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic ASA.json b/resources/profiles/Anycubic/filament/Anycubic Generic ASA.json
new file mode 100644
index 0000000000..04dcaf1cd3
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic ASA.json
@@ -0,0 +1,18 @@
+{
+ "type": "filament",
+ "filament_id": "GFB98",
+ "setting_id": "GFSB98",
+ "name": "Anycubic Generic ASA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_asa",
+ "filament_flow_ratio": [
+ "0.93"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic PA-CF.json b/resources/profiles/Anycubic/filament/Anycubic Generic PA-CF.json
new file mode 100644
index 0000000000..65e093d8dc
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic PA-CF.json
@@ -0,0 +1,24 @@
+{
+ "type": "filament",
+ "filament_id": "GFN98",
+ "setting_id": "GFSN99",
+ "name": "Anycubic Generic PA-CF",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pa",
+ "filament_type": [
+ "PA-CF"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "280"
+ ],
+ "nozzle_temperature": [
+ "280"
+ ],
+ "filament_max_volumetric_speed": [
+ "8"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic PA.json b/resources/profiles/Anycubic/filament/Anycubic Generic PA.json
new file mode 100644
index 0000000000..1aa1fd9771
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic PA.json
@@ -0,0 +1,21 @@
+{
+ "type": "filament",
+ "filament_id": "GFN99",
+ "setting_id": "GFSN98",
+ "name": "Anycubic Generic PA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pa",
+ "nozzle_temperature_initial_layer": [
+ "280"
+ ],
+ "nozzle_temperature": [
+ "280"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic PC.json b/resources/profiles/Anycubic/filament/Anycubic Generic PC.json
new file mode 100644
index 0000000000..a82eb93fc9
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic PC.json
@@ -0,0 +1,18 @@
+{
+ "type": "filament",
+ "filament_id": "GFC99",
+ "setting_id": "GFSC99",
+ "name": "Anycubic Generic PC",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pc",
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "filament_flow_ratio": [
+ "0.94"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic PETG.json b/resources/profiles/Anycubic/filament/Anycubic Generic PETG.json
new file mode 100644
index 0000000000..2bbd4fdd91
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic PETG.json
@@ -0,0 +1,48 @@
+{
+ "type": "filament",
+ "filament_id": "GFG99",
+ "setting_id": "GFSG99",
+ "name": "Anycubic Generic PETG",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pet",
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_cooling_layer_time": [
+ "30"
+ ],
+ "overhang_fan_speed": [
+ "90"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "fan_max_speed": [
+ "90"
+ ],
+ "fan_min_speed": [
+ "40"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "8"
+ ],
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_max_volumetric_speed": [
+ "10"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic PLA-CF.json b/resources/profiles/Anycubic/filament/Anycubic Generic PLA-CF.json
new file mode 100644
index 0000000000..b67874dfb5
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic PLA-CF.json
@@ -0,0 +1,24 @@
+{
+ "type": "filament",
+ "filament_id": "GFL98",
+ "setting_id": "GFSL98",
+ "name": "Anycubic Generic PLA-CF",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pla",
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_type": [
+ "PLA-CF"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "slow_down_layer_time": [
+ "7"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic PLA.json b/resources/profiles/Anycubic/filament/Anycubic Generic PLA.json
new file mode 100644
index 0000000000..57300b19b0
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic PLA.json
@@ -0,0 +1,21 @@
+{
+ "type": "filament",
+ "filament_id": "GFL99",
+ "setting_id": "GFSL99",
+ "name": "Anycubic Generic PLA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pla",
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "slow_down_layer_time": [
+ "8"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic PVA.json b/resources/profiles/Anycubic/filament/Anycubic Generic PVA.json
new file mode 100644
index 0000000000..eb1938040e
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic PVA.json
@@ -0,0 +1,24 @@
+{
+ "type": "filament",
+ "filament_id": "GFS99",
+ "setting_id": "GFSS99",
+ "name": "Anycubic Generic PVA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pva",
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "slow_down_layer_time": [
+ "7"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/Anycubic Generic TPU.json b/resources/profiles/Anycubic/filament/Anycubic Generic TPU.json
new file mode 100644
index 0000000000..9b27254381
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/Anycubic Generic TPU.json
@@ -0,0 +1,15 @@
+{
+ "type": "filament",
+ "filament_id": "GFU99",
+ "setting_id": "GFSR99",
+ "name": "Anycubic Generic TPU",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_tpu",
+ "filament_max_volumetric_speed": [
+ "3.2"
+ ],
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_abs.json b/resources/profiles/Anycubic/filament/fdm_filament_abs.json
new file mode 100644
index 0000000000..1aaa31323a
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_abs.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_abs",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "105"
+ ],
+ "eng_plate_temp" : [
+ "105"
+ ],
+ "hot_plate_temp" : [
+ "105"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "30"
+ ],
+ "filament_max_volumetric_speed": [
+ "28.6"
+ ],
+ "filament_type": [
+ "ABS"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "260"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "80"
+ ],
+ "fan_min_speed": [
+ "10"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "overhang_fan_speed": [
+ "80"
+ ],
+ "nozzle_temperature": [
+ "260"
+ ],
+ "temperature_vitrification": [
+ "110"
+ ],
+ "nozzle_temperature_range_low": [
+ "240"
+ ],
+ "nozzle_temperature_range_high": [
+ "270"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "3"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_asa.json b/resources/profiles/Anycubic/filament/fdm_filament_asa.json
new file mode 100644
index 0000000000..c8de040b7f
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_asa.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_asa",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "105"
+ ],
+ "eng_plate_temp" : [
+ "105"
+ ],
+ "hot_plate_temp" : [
+ "105"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "35"
+ ],
+ "filament_max_volumetric_speed": [
+ "28.6"
+ ],
+ "filament_type": [
+ "ASA"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "260"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "80"
+ ],
+ "fan_min_speed": [
+ "10"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "overhang_fan_speed": [
+ "80"
+ ],
+ "nozzle_temperature": [
+ "260"
+ ],
+ "temperature_vitrification": [
+ "110"
+ ],
+ "nozzle_temperature_range_low": [
+ "240"
+ ],
+ "nozzle_temperature_range_high": [
+ "270"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "3"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_common.json b/resources/profiles/Anycubic/filament/fdm_filament_common.json
new file mode 100644
index 0000000000..5212d445a5
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_common.json
@@ -0,0 +1,135 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_common",
+ "from": "system",
+ "instantiation": "false",
+ "cool_plate_temp" : [
+ "60"
+ ],
+ "eng_plate_temp" : [
+ "60"
+ ],
+ "hot_plate_temp" : [
+ "60"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "overhang_fan_threshold": [
+ "95%"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode \n"
+ ],
+ "filament_flow_ratio": [
+ "1"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "0"
+ ],
+ "fan_cooling_layer_time": [
+ "60"
+ ],
+ "filament_cost": [
+ "0"
+ ],
+ "filament_density": [
+ "0"
+ ],
+ "filament_deretraction_speed": [
+ "nil"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_max_volumetric_speed": [
+ "0"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_retraction_minimum_travel": [
+ "nil"
+ ],
+ "filament_retract_before_wipe": [
+ "nil"
+ ],
+ "filament_retract_when_changing_layer": [
+ "nil"
+ ],
+ "filament_retraction_length": [
+ "nil"
+ ],
+ "filament_z_hop": [
+ "nil"
+ ],
+ "filament_retract_restart_extra": [
+ "nil"
+ ],
+ "filament_retraction_speed": [
+ "nil"
+ ],
+ "filament_settings_id": [
+ ""
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "filament_type": [
+ "PLA"
+ ],
+ "filament_vendor": [
+ "Generic"
+ ],
+ "filament_wipe": [
+ "nil"
+ ],
+ "filament_wipe_distance": [
+ "nil"
+ ],
+ "bed_type": [
+ "Cool Plate"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "200"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "35"
+ ],
+ "slow_down_min_speed": [
+ "10"
+ ],
+ "slow_down_layer_time": [
+ "8"
+ ],
+ "filament_start_gcode": [
+ "; Filament gcode\n"
+ ],
+ "nozzle_temperature": [
+ "200"
+ ],
+ "temperature_vitrification": [
+ "100"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_pa.json b/resources/profiles/Anycubic/filament/fdm_filament_pa.json
new file mode 100644
index 0000000000..67c8ff050f
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_pa.json
@@ -0,0 +1,79 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pa",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "0"
+ ],
+ "eng_plate_temp" : [
+ "100"
+ ],
+ "hot_plate_temp" : [
+ "100"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "100"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "4"
+ ],
+ "filament_max_volumetric_speed": [
+ "8"
+ ],
+ "filament_type": [
+ "PA"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "290"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "60"
+ ],
+ "fan_min_speed": [
+ "0"
+ ],
+ "overhang_fan_speed": [
+ "30"
+ ],
+ "nozzle_temperature": [
+ "290"
+ ],
+ "temperature_vitrification": [
+ "108"
+ ],
+ "nozzle_temperature_range_low": [
+ "270"
+ ],
+ "nozzle_temperature_range_high": [
+ "300"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "2"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_pc.json b/resources/profiles/Anycubic/filament/fdm_filament_pc.json
new file mode 100644
index 0000000000..9174d53530
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_pc.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pc",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "0"
+ ],
+ "eng_plate_temp" : [
+ "110"
+ ],
+ "hot_plate_temp" : [
+ "110"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "110"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "110"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "30"
+ ],
+ "filament_max_volumetric_speed": [
+ "23.2"
+ ],
+ "filament_type": [
+ "PC"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "270"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "60"
+ ],
+ "fan_min_speed": [
+ "10"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "overhang_fan_speed": [
+ "60"
+ ],
+ "nozzle_temperature": [
+ "280"
+ ],
+ "temperature_vitrification": [
+ "140"
+ ],
+ "nozzle_temperature_range_low": [
+ "260"
+ ],
+ "nozzle_temperature_range_high": [
+ "280"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "2"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_pet.json b/resources/profiles/Anycubic/filament/fdm_filament_pet.json
new file mode 100644
index 0000000000..2f98be665f
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_pet.json
@@ -0,0 +1,76 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pet",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "60"
+ ],
+ "eng_plate_temp" : [
+ "0"
+ ],
+ "hot_plate_temp" : [
+ "80"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "80"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "20"
+ ],
+ "filament_max_volumetric_speed": [
+ "25"
+ ],
+ "filament_type": [
+ "PETG"
+ ],
+ "filament_density": [
+ "1.27"
+ ],
+ "filament_cost": [
+ "30"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "255"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "20"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "nozzle_temperature": [
+ "255"
+ ],
+ "temperature_vitrification": [
+ "80"
+ ],
+ "nozzle_temperature_range_low": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "260"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_pla.json b/resources/profiles/Anycubic/filament/fdm_filament_pla.json
new file mode 100644
index 0000000000..87d61ebb86
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_pla.json
@@ -0,0 +1,88 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pla",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "fan_cooling_layer_time": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "filament_type": [
+ "PLA"
+ ],
+ "filament_density": [
+ "1.24"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "cool_plate_temp" : [
+ "35"
+ ],
+ "eng_plate_temp" : [
+ "0"
+ ],
+ "hot_plate_temp" : [
+ "45"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "35"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "45"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "overhang_fan_threshold": [
+ "50%"
+ ],
+ "close_fan_the_first_x_layers": [
+ "1"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "nozzle_temperature_range_high": [
+ "230"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "additional_cooling_fan_speed": [
+ "70"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_pva.json b/resources/profiles/Anycubic/filament/fdm_filament_pva.json
new file mode 100644
index 0000000000..0d3e26c134
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_pva.json
@@ -0,0 +1,94 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pva",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "35"
+ ],
+ "eng_plate_temp" : [
+ "0"
+ ],
+ "hot_plate_temp" : [
+ "45"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "35"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "45"
+ ],
+ "fan_cooling_layer_time": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_soluble": [
+ "1"
+ ],
+ "filament_is_support": [
+ "1"
+ ],
+ "filament_type": [
+ "PVA"
+ ],
+ "filament_density": [
+ "1.24"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "overhang_fan_threshold": [
+ "50%"
+ ],
+ "close_fan_the_first_x_layers": [
+ "1"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "50"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "nozzle_temperature_range_high": [
+ "250"
+ ],
+ "slow_down_min_speed": [
+ "50"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "additional_cooling_fan_speed": [
+ "70"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Anycubic/filament/fdm_filament_tpu.json b/resources/profiles/Anycubic/filament/fdm_filament_tpu.json
new file mode 100644
index 0000000000..d5cc57fbcc
--- /dev/null
+++ b/resources/profiles/Anycubic/filament/fdm_filament_tpu.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_tpu",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "30"
+ ],
+ "eng_plate_temp" : [
+ "30"
+ ],
+ "hot_plate_temp" : [
+ "35"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "30"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "30"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "35"
+ ],
+ "fan_cooling_layer_time": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_type": [
+ "TPU"
+ ],
+ "filament_density": [
+ "1.24"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "filament_retraction_length": [
+ "0.4"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "240"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "additional_cooling_fan_speed": [
+ "70"
+ ],
+ "close_fan_the_first_x_layers": [
+ "1"
+ ],
+ "nozzle_temperature": [
+ "240"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "nozzle_temperature_range_low": [
+ "200"
+ ],
+ "nozzle_temperature_range_high": [
+ "250"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Anycubic/machine/Anycubic 4Max Pro 0.4 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic 4Max Pro 0.4 nozzle.json
new file mode 100644
index 0000000000..ff17e30560
--- /dev/null
+++ b/resources/profiles/Anycubic/machine/Anycubic 4Max Pro 0.4 nozzle.json
@@ -0,0 +1,30 @@
+{
+ "type": "machine",
+ "setting_id": "GM003",
+ "name": "Anycubic 4Max Pro 0.4 nozzle",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_machine_common",
+ "printer_model": "Anycubic 4Max Pro",
+ "default_print_profile": "0.20mm Standard @4MaxPro",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "bed_exclude_area": [
+ "0x0"
+ ],
+ "printable_area": [
+ "0x0",
+ "270x0",
+ "270x205",
+ "0x205"
+ ],
+ "printable_height": "200",
+ "machine_start_gcode": ";M190 S0\n;M104 S0\nPRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single]\n; You can use following code instead if your PRINT_START macro support Chamber and print area bedmesh\n; PRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single] Chamber=[chamber_temperature] PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}",
+ "machine_end_gcode": "PRINT_END",
+ "layer_change_gcode": "",
+ "scan_first_layer": "0",
+ "nozzle_type": "hardened_steel",
+ "auxiliary_fan": "0"
+ }
+
\ No newline at end of file
diff --git a/resources/profiles/Anycubic/machine/Anycubic 4Max Pro.json b/resources/profiles/Anycubic/machine/Anycubic 4Max Pro.json
new file mode 100644
index 0000000000..acb451e1c2
--- /dev/null
+++ b/resources/profiles/Anycubic/machine/Anycubic 4Max Pro.json
@@ -0,0 +1,12 @@
+{
+ "type": "machine_model",
+ "name": "Anycubic 4Max Pro",
+ "model_id": "AC-4maxpro",
+ "nozzle_diameter": "0.4",
+ "machine_tech": "FFF",
+ "family": "Anycubic",
+ "bed_model": "",
+ "bed_texture": "",
+ "hotend_model": "bbl-3dp-hotend.stl",
+ "default_materials": "Anycubic Generic ABS;Anycubic Generic PLA;Anycubic Generic PLA-CF;Anycubic Generic PETG;Anycubic Generic TPU;Anycubic Generic ASA;Anycubic Generic PC;Anycubic Generic PVA;Anycubic Generic PA;Anycubic Generic PA-CF"
+}
diff --git a/resources/profiles/Anycubic/machine/fdm_machine_common.json b/resources/profiles/Anycubic/machine/fdm_machine_common.json
new file mode 100644
index 0000000000..8897f0444f
--- /dev/null
+++ b/resources/profiles/Anycubic/machine/fdm_machine_common.json
@@ -0,0 +1,139 @@
+{
+ "type": "machine",
+ "name": "fdm_machine_common",
+ "from": "system",
+ "instantiation": "false",
+ "gcode_flavor": "marlin",
+ "machine_start_gcode": "",
+ "machine_end_gcode": "",
+ "extruder_colour": [
+ "#018001"
+ ],
+ "extruder_offset": [
+ "0x0"
+ ],
+ "machine_max_acceleration_e": [
+ "5000",
+ "5000"
+ ],
+ "machine_max_acceleration_extruding": [
+ "2000",
+ "2000"
+ ],
+ "machine_max_acceleration_retracting": [
+ "5000",
+ "5000"
+ ],
+ "machine_max_acceleration_travel": [
+ "3000",
+ "3000"
+ ],
+ "machine_max_acceleration_x": [
+ "2000",
+ "2000"
+ ],
+ "machine_max_acceleration_y": [
+ "2000",
+ "2000"
+ ],
+ "machine_max_acceleration_z": [
+ "300",
+ "200"
+ ],
+ "machine_max_speed_e": [
+ "25",
+ "25"
+ ],
+ "machine_max_speed_x": [
+ "300",
+ "200"
+ ],
+ "machine_max_speed_y": [
+ "300",
+ "200"
+ ],
+ "machine_max_speed_z": [
+ "12",
+ "12"
+ ],
+ "machine_max_jerk_e": [
+ "2.5",
+ "2.5"
+ ],
+ "machine_max_jerk_x": [
+ "9",
+ "9"
+ ],
+ "machine_max_jerk_y": [
+ "9",
+ "9"
+ ],
+ "machine_max_jerk_z": [
+ "0.2",
+ "0.4"
+ ],
+ "machine_min_extruding_rate": [
+ "0",
+ "0"
+ ],
+ "machine_min_travel_rate": [
+ "0",
+ "0"
+ ],
+ "max_layer_height": [
+ "0.3"
+ ],
+ "min_layer_height": [
+ "0.08"
+ ],
+ "printable_height": "250",
+ "extruder_clearance_radius": "65",
+ "extruder_clearance_height_to_rod": "36",
+ "extruder_clearance_height_to_lid": "140",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "printer_settings_id": "",
+ "printer_technology": "FFF",
+ "printer_variant": "0.4",
+ "retraction_minimum_travel": [
+ "1"
+ ],
+ "retract_before_wipe": [
+ "70%"
+ ],
+ "retract_when_changing_layer": [
+ "1"
+ ],
+ "retraction_length": [
+ "0.8"
+ ],
+ "retract_length_toolchange": [
+ "2"
+ ],
+ "z_hop": [
+ "0.4"
+ ],
+ "retract_restart_extra": [
+ "0"
+ ],
+ "retract_restart_extra_toolchange": [
+ "0"
+ ],
+ "retraction_speed": [
+ "30"
+ ],
+ "deretraction_speed": [
+ "30"
+ ],
+ "silent_mode": "0",
+ "single_extruder_multi_material": "1",
+ "change_filament_gcode": "",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
+ "layer_change_gcode": "",
+ "machine_pause_gcode": "M400 U1\n",
+ "wipe": [
+ "1"
+ ],
+ "z_lift_type": "NormalLift"
+}
diff --git a/resources/profiles/Anycubic/process/0.20mm Standard @4MaxPro.json b/resources/profiles/Anycubic/process/0.20mm Standard @4MaxPro.json
new file mode 100644
index 0000000000..12ad73c809
--- /dev/null
+++ b/resources/profiles/Anycubic/process/0.20mm Standard @4MaxPro.json
@@ -0,0 +1,20 @@
+{
+ "type": "process",
+ "setting_id": "Anycubic-1",
+ "name": "0.20mm Standard @4MaxPro",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_process_common",
+ "initial_layer_speed": "40",
+ "initial_layer_infill_speed": "50",
+ "outer_wall_speed": "35",
+ "inner_wall_speed": "60",
+ "sparse_infill_speed": "200",
+ "internal_solid_infill_speed": "200",
+ "top_surface_speed": "50",
+ "gap_infill_speed": "40",
+ "travel_speed": "180",
+ "compatible_printers": [
+ "Anycubic 4Max Pro 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Anycubic/process/fdm_process_common.json b/resources/profiles/Anycubic/process/fdm_process_common.json
new file mode 100644
index 0000000000..d1e28bb1d5
--- /dev/null
+++ b/resources/profiles/Anycubic/process/fdm_process_common.json
@@ -0,0 +1,107 @@
+{
+ "type": "process",
+ "name": "fdm_process_common",
+ "from": "system",
+ "instantiation": "false",
+ "adaptive_layer_height": "0",
+ "reduce_crossing_wall": "0",
+ "max_travel_detour_distance": "0",
+ "bottom_surface_pattern": "monotonic",
+ "bottom_shell_thickness": "0",
+ "bridge_speed": "50",
+ "brim_width": "5",
+ "brim_object_gap": "0.1",
+ "compatible_printers": [],
+ "compatible_printers_condition": "",
+ "print_sequence": "by layer",
+ "default_acceleration": "1000",
+ "initial_layer_acceleration": "500",
+ "top_surface_acceleration": "800",
+ "travel_acceleration": "1000",
+ "inner_wall_acceleration": "900",
+ "outer_wall_acceleration": "700",
+ "bridge_no_support": "0",
+ "draft_shield": "disabled",
+ "elefant_foot_compensation": "0",
+ "enable_arc_fitting": "1",
+ "outer_wall_line_width": "0.4",
+ "wall_infill_order": "inner wall/outer wall/infill",
+ "line_width": "0.4",
+ "infill_direction": "45",
+ "sparse_infill_density": "15%",
+ "sparse_infill_pattern": "grid",
+ "initial_layer_line_width": "0.5",
+ "initial_layer_print_height": "0.2",
+ "infill_combination": "0",
+ "sparse_infill_line_width": "0.45",
+ "infill_wall_overlap": "25%",
+ "interface_shells": "0",
+ "ironing_flow": "10%",
+ "ironing_spacing": "0.15",
+ "ironing_speed": "30",
+ "ironing_type": "no ironing",
+ "reduce_infill_retraction": "1",
+ "filename_format": "{input_filename_base}_{filament_type[0]}_{print_time}.gcode",
+ "detect_overhang_wall": "1",
+ "overhang_1_4_speed": "0",
+ "overhang_2_4_speed": "50",
+ "overhang_3_4_speed": "30",
+ "overhang_4_4_speed": "10",
+ "inner_wall_line_width": "0.45",
+ "wall_loops": "2",
+ "print_settings_id": "",
+ "raft_layers": "0",
+ "seam_position": "aligned",
+ "skirt_distance": "2",
+ "skirt_height": "1",
+ "skirt_loops": "0",
+ "minimum_sparse_infill_area": "15",
+ "internal_solid_infill_line_width": "0.4",
+ "spiral_mode": "0",
+ "standby_temperature_delta": "-5",
+ "enable_support": "0",
+ "resolution": "0.012",
+ "support_type": "normal(auto)",
+ "support_on_build_plate_only": "0",
+ "support_top_z_distance": "0.2",
+ "support_filament": "0",
+ "support_line_width": "0.4",
+ "support_interface_loop_pattern": "0",
+ "support_interface_filament": "0",
+ "support_interface_top_layers": "2",
+ "support_interface_bottom_layers": "2",
+ "support_interface_spacing": "0.5",
+ "support_interface_speed": "80",
+ "support_base_pattern": "rectilinear",
+ "support_base_pattern_spacing": "2.5",
+ "support_speed": "150",
+ "support_threshold_angle": "30",
+ "support_object_xy_distance": "0.35",
+ "tree_support_branch_angle": "30",
+ "tree_support_wall_count": "0",
+ "tree_support_with_infill": "0",
+ "detect_thin_wall": "0",
+ "top_surface_pattern": "monotonicline",
+ "top_surface_line_width": "0.4",
+ "top_shell_thickness": "0.8",
+ "enable_prime_tower": "1",
+ "wipe_tower_no_sparse_layers": "0",
+ "prime_tower_width": "35",
+ "xy_hole_compensation": "0",
+ "xy_contour_compensation": "0",
+ "layer_height": "0.2",
+ "bottom_shell_layers": "3",
+ "top_shell_layers": "4",
+ "bridge_flow": "1",
+ "initial_layer_speed": "45",
+ "initial_layer_infill_speed": "45",
+ "outer_wall_speed": "45",
+ "inner_wall_speed": "80",
+ "sparse_infill_speed": "150",
+ "internal_solid_infill_speed": "150",
+ "top_surface_speed": "50",
+ "gap_infill_speed": "30",
+ "travel_speed": "200",
+ "enable_arc_fitting": "0"
+
+}
diff --git a/resources/profiles/Creality.json b/resources/profiles/Creality.json
index 6ea8e4f1ce..23b372e27c 100644
--- a/resources/profiles/Creality.json
+++ b/resources/profiles/Creality.json
@@ -1,6 +1,6 @@
{
"name": "Creality",
- "version": "01.02.01.03",
+ "version": "01.02.01.04",
"force_update": "0",
"description": "Creality configurations",
"machine_model_list": [
diff --git a/resources/profiles/Creality/machine/fdm_creality_common.json b/resources/profiles/Creality/machine/fdm_creality_common.json
index d2f871b686..0e6f818147 100644
--- a/resources/profiles/Creality/machine/fdm_creality_common.json
+++ b/resources/profiles/Creality/machine/fdm_creality_common.json
@@ -102,7 +102,7 @@
"2"
],
"z_hop": [
- "0"
+ "0.4"
],
"retract_restart_extra": [
"0"
diff --git a/resources/profiles/Creality/machine/fdm_machine_common.json b/resources/profiles/Creality/machine/fdm_machine_common.json
index 37891fb1a5..8884d46f0c 100644
--- a/resources/profiles/Creality/machine/fdm_machine_common.json
+++ b/resources/profiles/Creality/machine/fdm_machine_common.json
@@ -110,6 +110,7 @@
"wipe": [
"1"
],
+ "z_lift_type": "NormalLift",
"default_print_profile": "0.16mm Optimal @Bambu Lab X1 Carbon 0.4 nozzle",
"machine_start_gcode": "G0 Z20 F9000\nG92 E0; G1 E-10 F1200\nG28\nM970 Q1 A10 B10 C130 K0\nM970 Q1 A10 B131 C250 K1\nM974 Q1 S1 P0\nM970 Q0 A10 B10 C130 H20 K0\nM970 Q0 A10 B131 C250 K1\nM974 Q0 S1 P0\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nG29 ;Home\nG90;\nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM109 S205;\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder \nG1 X110 Y110 Z2.0 F3000 ;Move Z Axis up",
"machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-4.0 F3600; retract \nG91\nG1 Z3;\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nG90 \nG0 X110 Y200 F3600 \nprint_end"
diff --git a/resources/profiles/Prusa.json b/resources/profiles/Prusa.json
new file mode 100644
index 0000000000..4fecebfc82
--- /dev/null
+++ b/resources/profiles/Prusa.json
@@ -0,0 +1,110 @@
+{
+ "name": "Prusa",
+ "version": "01.02.00.02",
+ "force_update": "0",
+ "description": "Prusa configurations",
+ "machine_model_list": [
+ {
+ "name": "Prusa MK3S",
+ "sub_path": "machine/Prusa MK3S.json"
+ }
+ ],
+ "process_list": [
+ {
+ "name": "fdm_process_common",
+ "sub_path": "process/fdm_process_common.json"
+ },
+ {
+ "name": "0.20mm Standard @MK3S",
+ "sub_path": "process/0.20mm Standard @MK3S.json"
+ }
+ ],
+ "filament_list": [
+ {
+ "name": "fdm_filament_common",
+ "sub_path": "filament/fdm_filament_common.json"
+ },
+ {
+ "name": "fdm_filament_pla",
+ "sub_path": "filament/fdm_filament_pla.json"
+ },
+ {
+ "name": "fdm_filament_tpu",
+ "sub_path": "filament/fdm_filament_tpu.json"
+ },
+ {
+ "name": "fdm_filament_pet",
+ "sub_path": "filament/fdm_filament_pet.json"
+ },
+ {
+ "name": "fdm_filament_abs",
+ "sub_path": "filament/fdm_filament_abs.json"
+ },
+ {
+ "name": "fdm_filament_pc",
+ "sub_path": "filament/fdm_filament_pc.json"
+ },
+ {
+ "name": "fdm_filament_asa",
+ "sub_path": "filament/fdm_filament_asa.json"
+ },
+ {
+ "name": "fdm_filament_pva",
+ "sub_path": "filament/fdm_filament_pva.json"
+ },
+ {
+ "name": "fdm_filament_pa",
+ "sub_path": "filament/fdm_filament_pa.json"
+ },
+ {
+ "name": "Prusa Generic PLA",
+ "sub_path": "filament/Prusa Generic PLA.json"
+ },
+ {
+ "name": "Prusa Generic PLA-CF",
+ "sub_path": "filament/Prusa Generic PLA-CF.json"
+ },
+ {
+ "name": "Prusa Generic PETG",
+ "sub_path": "filament/Prusa Generic PETG.json"
+ },
+ {
+ "name": "Prusa Generic ABS",
+ "sub_path": "filament/Prusa Generic ABS.json"
+ },
+ {
+ "name": "Prusa Generic TPU",
+ "sub_path": "filament/Prusa Generic TPU.json"
+ },
+ {
+ "name": "Prusa Generic ASA",
+ "sub_path": "filament/Prusa Generic ASA.json"
+ },
+ {
+ "name": "Prusa Generic PC",
+ "sub_path": "filament/Prusa Generic PC.json"
+ },
+ {
+ "name": "Prusa Generic PVA",
+ "sub_path": "filament/Prusa Generic PVA.json"
+ },
+ {
+ "name": "Prusa Generic PA",
+ "sub_path": "filament/Prusa Generic PA.json"
+ },
+ {
+ "name": "Prusa Generic PA-CF",
+ "sub_path": "filament/Prusa Generic PA-CF.json"
+ }
+ ],
+ "machine_list": [
+ {
+ "name": "fdm_machine_common",
+ "sub_path": "machine/fdm_machine_common.json"
+ },
+ {
+ "name": "Prusa MK3S 0.4 nozzle",
+ "sub_path": "machine/Prusa MK3S 0.4 nozzle.json"
+ }
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/Prusa Generic ABS.json b/resources/profiles/Prusa/filament/Prusa Generic ABS.json
new file mode 100644
index 0000000000..d0e3899431
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic ABS.json
@@ -0,0 +1,18 @@
+{
+ "type": "filament",
+ "filament_id": "GFB99",
+ "setting_id": "GFSB99",
+ "name": "Prusa Generic ABS",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_abs",
+ "filament_flow_ratio": [
+ "0.926"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/Prusa Generic ASA.json b/resources/profiles/Prusa/filament/Prusa Generic ASA.json
new file mode 100644
index 0000000000..616b01bee9
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic ASA.json
@@ -0,0 +1,18 @@
+{
+ "type": "filament",
+ "filament_id": "GFB98",
+ "setting_id": "GFSB98",
+ "name": "Prusa Generic ASA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_asa",
+ "filament_flow_ratio": [
+ "0.93"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/Prusa Generic PA-CF.json b/resources/profiles/Prusa/filament/Prusa Generic PA-CF.json
new file mode 100644
index 0000000000..0583ff3478
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic PA-CF.json
@@ -0,0 +1,24 @@
+{
+ "type": "filament",
+ "filament_id": "GFN98",
+ "setting_id": "GFSN99",
+ "name": "Prusa Generic PA-CF",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pa",
+ "filament_type": [
+ "PA-CF"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "280"
+ ],
+ "nozzle_temperature": [
+ "280"
+ ],
+ "filament_max_volumetric_speed": [
+ "8"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Prusa/filament/Prusa Generic PA.json b/resources/profiles/Prusa/filament/Prusa Generic PA.json
new file mode 100644
index 0000000000..8088e2375a
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic PA.json
@@ -0,0 +1,21 @@
+{
+ "type": "filament",
+ "filament_id": "GFN99",
+ "setting_id": "GFSN98",
+ "name": "Prusa Generic PA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pa",
+ "nozzle_temperature_initial_layer": [
+ "280"
+ ],
+ "nozzle_temperature": [
+ "280"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Prusa/filament/Prusa Generic PC.json b/resources/profiles/Prusa/filament/Prusa Generic PC.json
new file mode 100644
index 0000000000..7d7fa4f4de
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic PC.json
@@ -0,0 +1,18 @@
+{
+ "type": "filament",
+ "filament_id": "GFC99",
+ "setting_id": "GFSC99",
+ "name": "Prusa Generic PC",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pc",
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "filament_flow_ratio": [
+ "0.94"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Prusa/filament/Prusa Generic PETG.json b/resources/profiles/Prusa/filament/Prusa Generic PETG.json
new file mode 100644
index 0000000000..819b19e7ee
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic PETG.json
@@ -0,0 +1,48 @@
+{
+ "type": "filament",
+ "filament_id": "GFG99",
+ "setting_id": "GFSG99",
+ "name": "Prusa Generic PETG",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pet",
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_cooling_layer_time": [
+ "30"
+ ],
+ "overhang_fan_speed": [
+ "90"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "fan_max_speed": [
+ "90"
+ ],
+ "fan_min_speed": [
+ "40"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "8"
+ ],
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_max_volumetric_speed": [
+ "10"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/Prusa Generic PLA-CF.json b/resources/profiles/Prusa/filament/Prusa Generic PLA-CF.json
new file mode 100644
index 0000000000..68990c5bc3
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic PLA-CF.json
@@ -0,0 +1,24 @@
+{
+ "type": "filament",
+ "filament_id": "GFL98",
+ "setting_id": "GFSL98",
+ "name": "Prusa Generic PLA-CF",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pla",
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_type": [
+ "PLA-CF"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "slow_down_layer_time": [
+ "7"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Prusa/filament/Prusa Generic PLA.json b/resources/profiles/Prusa/filament/Prusa Generic PLA.json
new file mode 100644
index 0000000000..36aa0004ed
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic PLA.json
@@ -0,0 +1,21 @@
+{
+ "type": "filament",
+ "filament_id": "GFL99",
+ "setting_id": "GFSL99",
+ "name": "Prusa Generic PLA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pla",
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "slow_down_layer_time": [
+ "8"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/Prusa Generic PVA.json b/resources/profiles/Prusa/filament/Prusa Generic PVA.json
new file mode 100644
index 0000000000..6daa2dd06a
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic PVA.json
@@ -0,0 +1,24 @@
+{
+ "type": "filament",
+ "filament_id": "GFS99",
+ "setting_id": "GFSS99",
+ "name": "Prusa Generic PVA",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_pva",
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "slow_down_layer_time": [
+ "7"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/Prusa Generic TPU.json b/resources/profiles/Prusa/filament/Prusa Generic TPU.json
new file mode 100644
index 0000000000..ada6cec7a5
--- /dev/null
+++ b/resources/profiles/Prusa/filament/Prusa Generic TPU.json
@@ -0,0 +1,15 @@
+{
+ "type": "filament",
+ "filament_id": "GFU99",
+ "setting_id": "GFSR99",
+ "name": "Prusa Generic TPU",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_filament_tpu",
+ "filament_max_volumetric_speed": [
+ "3.2"
+ ],
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_abs.json b/resources/profiles/Prusa/filament/fdm_filament_abs.json
new file mode 100644
index 0000000000..1aaa31323a
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_abs.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_abs",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "105"
+ ],
+ "eng_plate_temp" : [
+ "105"
+ ],
+ "hot_plate_temp" : [
+ "105"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "30"
+ ],
+ "filament_max_volumetric_speed": [
+ "28.6"
+ ],
+ "filament_type": [
+ "ABS"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "260"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "80"
+ ],
+ "fan_min_speed": [
+ "10"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "overhang_fan_speed": [
+ "80"
+ ],
+ "nozzle_temperature": [
+ "260"
+ ],
+ "temperature_vitrification": [
+ "110"
+ ],
+ "nozzle_temperature_range_low": [
+ "240"
+ ],
+ "nozzle_temperature_range_high": [
+ "270"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "3"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_asa.json b/resources/profiles/Prusa/filament/fdm_filament_asa.json
new file mode 100644
index 0000000000..c8de040b7f
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_asa.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_asa",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "105"
+ ],
+ "eng_plate_temp" : [
+ "105"
+ ],
+ "hot_plate_temp" : [
+ "105"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "105"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "35"
+ ],
+ "filament_max_volumetric_speed": [
+ "28.6"
+ ],
+ "filament_type": [
+ "ASA"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "260"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "80"
+ ],
+ "fan_min_speed": [
+ "10"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "overhang_fan_speed": [
+ "80"
+ ],
+ "nozzle_temperature": [
+ "260"
+ ],
+ "temperature_vitrification": [
+ "110"
+ ],
+ "nozzle_temperature_range_low": [
+ "240"
+ ],
+ "nozzle_temperature_range_high": [
+ "270"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "3"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_common.json b/resources/profiles/Prusa/filament/fdm_filament_common.json
new file mode 100644
index 0000000000..5212d445a5
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_common.json
@@ -0,0 +1,135 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_common",
+ "from": "system",
+ "instantiation": "false",
+ "cool_plate_temp" : [
+ "60"
+ ],
+ "eng_plate_temp" : [
+ "60"
+ ],
+ "hot_plate_temp" : [
+ "60"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "overhang_fan_threshold": [
+ "95%"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode \n"
+ ],
+ "filament_flow_ratio": [
+ "1"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "0"
+ ],
+ "fan_cooling_layer_time": [
+ "60"
+ ],
+ "filament_cost": [
+ "0"
+ ],
+ "filament_density": [
+ "0"
+ ],
+ "filament_deretraction_speed": [
+ "nil"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_max_volumetric_speed": [
+ "0"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_retraction_minimum_travel": [
+ "nil"
+ ],
+ "filament_retract_before_wipe": [
+ "nil"
+ ],
+ "filament_retract_when_changing_layer": [
+ "nil"
+ ],
+ "filament_retraction_length": [
+ "nil"
+ ],
+ "filament_z_hop": [
+ "nil"
+ ],
+ "filament_retract_restart_extra": [
+ "nil"
+ ],
+ "filament_retraction_speed": [
+ "nil"
+ ],
+ "filament_settings_id": [
+ ""
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "filament_type": [
+ "PLA"
+ ],
+ "filament_vendor": [
+ "Generic"
+ ],
+ "filament_wipe": [
+ "nil"
+ ],
+ "filament_wipe_distance": [
+ "nil"
+ ],
+ "bed_type": [
+ "Cool Plate"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "200"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "35"
+ ],
+ "slow_down_min_speed": [
+ "10"
+ ],
+ "slow_down_layer_time": [
+ "8"
+ ],
+ "filament_start_gcode": [
+ "; Filament gcode\n"
+ ],
+ "nozzle_temperature": [
+ "200"
+ ],
+ "temperature_vitrification": [
+ "100"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_pa.json b/resources/profiles/Prusa/filament/fdm_filament_pa.json
new file mode 100644
index 0000000000..67c8ff050f
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_pa.json
@@ -0,0 +1,79 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pa",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "0"
+ ],
+ "eng_plate_temp" : [
+ "100"
+ ],
+ "hot_plate_temp" : [
+ "100"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "100"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "4"
+ ],
+ "filament_max_volumetric_speed": [
+ "8"
+ ],
+ "filament_type": [
+ "PA"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "290"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "60"
+ ],
+ "fan_min_speed": [
+ "0"
+ ],
+ "overhang_fan_speed": [
+ "30"
+ ],
+ "nozzle_temperature": [
+ "290"
+ ],
+ "temperature_vitrification": [
+ "108"
+ ],
+ "nozzle_temperature_range_low": [
+ "270"
+ ],
+ "nozzle_temperature_range_high": [
+ "300"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "2"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_pc.json b/resources/profiles/Prusa/filament/fdm_filament_pc.json
new file mode 100644
index 0000000000..9174d53530
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_pc.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pc",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "0"
+ ],
+ "eng_plate_temp" : [
+ "110"
+ ],
+ "hot_plate_temp" : [
+ "110"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "110"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "110"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "30"
+ ],
+ "filament_max_volumetric_speed": [
+ "23.2"
+ ],
+ "filament_type": [
+ "PC"
+ ],
+ "filament_density": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "270"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "60"
+ ],
+ "fan_min_speed": [
+ "10"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "overhang_fan_speed": [
+ "60"
+ ],
+ "nozzle_temperature": [
+ "280"
+ ],
+ "temperature_vitrification": [
+ "140"
+ ],
+ "nozzle_temperature_range_low": [
+ "260"
+ ],
+ "nozzle_temperature_range_high": [
+ "280"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "2"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_pet.json b/resources/profiles/Prusa/filament/fdm_filament_pet.json
new file mode 100644
index 0000000000..2f98be665f
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_pet.json
@@ -0,0 +1,76 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pet",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "60"
+ ],
+ "eng_plate_temp" : [
+ "0"
+ ],
+ "hot_plate_temp" : [
+ "80"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "60"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "80"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "fan_cooling_layer_time": [
+ "20"
+ ],
+ "filament_max_volumetric_speed": [
+ "25"
+ ],
+ "filament_type": [
+ "PETG"
+ ],
+ "filament_density": [
+ "1.27"
+ ],
+ "filament_cost": [
+ "30"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "255"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "20"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "nozzle_temperature": [
+ "255"
+ ],
+ "temperature_vitrification": [
+ "80"
+ ],
+ "nozzle_temperature_range_low": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "260"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_pla.json b/resources/profiles/Prusa/filament/fdm_filament_pla.json
new file mode 100644
index 0000000000..87d61ebb86
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_pla.json
@@ -0,0 +1,88 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pla",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "fan_cooling_layer_time": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "filament_type": [
+ "PLA"
+ ],
+ "filament_density": [
+ "1.24"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "cool_plate_temp" : [
+ "35"
+ ],
+ "eng_plate_temp" : [
+ "0"
+ ],
+ "hot_plate_temp" : [
+ "45"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "35"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "45"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "overhang_fan_threshold": [
+ "50%"
+ ],
+ "close_fan_the_first_x_layers": [
+ "1"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "nozzle_temperature_range_high": [
+ "230"
+ ],
+ "slow_down_min_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "additional_cooling_fan_speed": [
+ "70"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_pva.json b/resources/profiles/Prusa/filament/fdm_filament_pva.json
new file mode 100644
index 0000000000..0d3e26c134
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_pva.json
@@ -0,0 +1,94 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_pva",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "35"
+ ],
+ "eng_plate_temp" : [
+ "0"
+ ],
+ "hot_plate_temp" : [
+ "45"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "35"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "45"
+ ],
+ "fan_cooling_layer_time": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_soluble": [
+ "1"
+ ],
+ "filament_is_support": [
+ "1"
+ ],
+ "filament_type": [
+ "PVA"
+ ],
+ "filament_density": [
+ "1.24"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "overhang_fan_threshold": [
+ "50%"
+ ],
+ "close_fan_the_first_x_layers": [
+ "1"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "50"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "nozzle_temperature_range_high": [
+ "250"
+ ],
+ "slow_down_min_speed": [
+ "50"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "additional_cooling_fan_speed": [
+ "70"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Prusa/filament/fdm_filament_tpu.json b/resources/profiles/Prusa/filament/fdm_filament_tpu.json
new file mode 100644
index 0000000000..d5cc57fbcc
--- /dev/null
+++ b/resources/profiles/Prusa/filament/fdm_filament_tpu.json
@@ -0,0 +1,82 @@
+{
+ "type": "filament",
+ "name": "fdm_filament_tpu",
+ "from": "system",
+ "instantiation": "false",
+ "inherits": "fdm_filament_common",
+ "cool_plate_temp" : [
+ "30"
+ ],
+ "eng_plate_temp" : [
+ "30"
+ ],
+ "hot_plate_temp" : [
+ "35"
+ ],
+ "cool_plate_temp_initial_layer" : [
+ "30"
+ ],
+ "eng_plate_temp_initial_layer" : [
+ "30"
+ ],
+ "hot_plate_temp_initial_layer" : [
+ "35"
+ ],
+ "fan_cooling_layer_time": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_type": [
+ "TPU"
+ ],
+ "filament_density": [
+ "1.24"
+ ],
+ "filament_cost": [
+ "20"
+ ],
+ "filament_retraction_length": [
+ "0.4"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "240"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "additional_cooling_fan_speed": [
+ "70"
+ ],
+ "close_fan_the_first_x_layers": [
+ "1"
+ ],
+ "nozzle_temperature": [
+ "240"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "nozzle_temperature_range_low": [
+ "200"
+ ],
+ "nozzle_temperature_range_high": [
+ "250"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ]
+}
diff --git a/resources/profiles/Prusa/machine/Prusa MK3S 0.4 nozzle.json b/resources/profiles/Prusa/machine/Prusa MK3S 0.4 nozzle.json
new file mode 100644
index 0000000000..f1f52683f6
--- /dev/null
+++ b/resources/profiles/Prusa/machine/Prusa MK3S 0.4 nozzle.json
@@ -0,0 +1,34 @@
+{
+ "type": "machine",
+ "setting_id": "GM003",
+ "name": "Prusa MK3S 0.4 nozzle",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_machine_common",
+ "printer_model": "Prusa MK3S",
+ "default_filament_profile": [
+ "Prusa Generic PLA"
+ ],
+ "default_print_profile": "0.20mm Standard @MK3S",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "bed_exclude_area": [
+ "0x0"
+ ],
+ "printable_area": [
+ "0x0",
+ "250x0",
+ "250x210",
+ "0x210"
+ ],
+ "printable_height": "210",
+ "machine_start_gcode": "M862.3 P \"[printer_model]\" ; printer model check\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S170 ; set extruder temp for bed leveling\nM140 S[bed_temperature_initial_layer_single] ; set bed temp\nM109 R170 ; wait for bed leveling temp\nM190 S[bed_temperature_initial_layer_single] ; wait for bed temp\nM204 T1250 ; set travel acceleration\nG28 ; home all without mesh bed level\nG29 ; mesh bed leveling \nM204 T[machine_max_acceleration_travel] ; restore travel acceleration\nM104 S[nozzle_temperature_initial_layer] ; set extruder temp\nG92 E0\nG1 Y-2 X179 F2400\nG1 Z3 F720\nM109 S[nozzle_temperature_initial_layer] ; wait for extruder temp\n\n; intro line\nG1 X170 F1000\nG1 Z0.2 F720\nG1 X110 E8 F900\nG1 X40 E10 F700\nG92 E0\n\nM221 S95 ; set flow",
+ "machine_end_gcode": "G1 E-1 F2100 ; retract\n{if max_layer_z < 210}G1 Z{min(max_layer_z+2, 210)} F720 ; Move print head up{endif}\nG1 X178 Y178 F4200 ; park print head\n{if max_layer_z < 210}G1 Z{min(max_layer_z+30, 210)} F720 ; Move print head further up{endif}\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM221 S100 ; reset flow\nM900 K0 ; reset LA\nM84 ; disable motors",
+ "layer_change_gcode": "",
+ "scan_first_layer": "0",
+ "machine_load_filament_time": "17",
+ "machine_unload_filament_time": "16",
+ "nozzle_type": "hardened_steel",
+ "auxiliary_fan": "0"
+}
diff --git a/resources/profiles/Prusa/machine/Prusa MK3S.json b/resources/profiles/Prusa/machine/Prusa MK3S.json
new file mode 100644
index 0000000000..d279367a2f
--- /dev/null
+++ b/resources/profiles/Prusa/machine/Prusa MK3S.json
@@ -0,0 +1,12 @@
+{
+ "type": "machine_model",
+ "name": "Prusa MK3S",
+ "model_id": "MK3S",
+ "nozzle_diameter": "0.4",
+ "machine_tech": "FFF",
+ "family": "Prusa",
+ "bed_model": "mk3_bed.stl",
+ "bed_texture": "mk3.svg",
+ "hotend_model": "bbl-3dp-hotend.stl",
+ "default_materials": "Prusa Generic ABS;Prusa Generic PLA;Prusa Generic PLA-CF;Prusa Generic PETG;Prusa Generic TPU;Prusa Generic ASA;Prusa Generic PC;Prusa Generic PVA;Prusa Generic PA;Prusa Generic PA-CF"
+}
diff --git a/resources/profiles/Prusa/machine/fdm_machine_common.json b/resources/profiles/Prusa/machine/fdm_machine_common.json
new file mode 100644
index 0000000000..a6f78e6f0c
--- /dev/null
+++ b/resources/profiles/Prusa/machine/fdm_machine_common.json
@@ -0,0 +1,137 @@
+{
+ "type": "machine",
+ "name": "fdm_machine_common",
+ "from": "system",
+ "instantiation": "false",
+ "gcode_flavor": "marlin",
+ "machine_start_gcode": "",
+ "machine_end_gcode": "",
+ "extruder_colour": [
+ "#018001"
+ ],
+ "extruder_offset": [
+ "0x0"
+ ],
+ "machine_max_acceleration_e": [
+ "5000",
+ "5000"
+ ],
+ "machine_max_acceleration_extruding": [
+ "2000",
+ "2000"
+ ],
+ "machine_max_acceleration_retracting": [
+ "5000",
+ "5000"
+ ],
+ "machine_max_acceleration_travel": [
+ "3000",
+ "3000"
+ ],
+ "machine_max_acceleration_x": [
+ "2000",
+ "2000"
+ ],
+ "machine_max_acceleration_y": [
+ "2000",
+ "2000"
+ ],
+ "machine_max_acceleration_z": [
+ "300",
+ "200"
+ ],
+ "machine_max_speed_e": [
+ "25",
+ "25"
+ ],
+ "machine_max_speed_x": [
+ "300",
+ "200"
+ ],
+ "machine_max_speed_y": [
+ "300",
+ "200"
+ ],
+ "machine_max_speed_z": [
+ "12",
+ "12"
+ ],
+ "machine_max_jerk_e": [
+ "2.5",
+ "2.5"
+ ],
+ "machine_max_jerk_x": [
+ "9",
+ "9"
+ ],
+ "machine_max_jerk_y": [
+ "9",
+ "9"
+ ],
+ "machine_max_jerk_z": [
+ "0.2",
+ "0.4"
+ ],
+ "machine_min_extruding_rate": [
+ "0",
+ "0"
+ ],
+ "machine_min_travel_rate": [
+ "0",
+ "0"
+ ],
+ "max_layer_height": [
+ "0.3"
+ ],
+ "min_layer_height": [
+ "0.08"
+ ],
+ "printable_height": "250",
+ "extruder_clearance_radius": "65",
+ "extruder_clearance_height_to_rod": "36",
+ "extruder_clearance_height_to_lid": "140",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "printer_settings_id": "",
+ "printer_technology": "FFF",
+ "printer_variant": "0.4",
+ "retraction_minimum_travel": [
+ "1"
+ ],
+ "retract_before_wipe": [
+ "70%"
+ ],
+ "retract_when_changing_layer": [
+ "1"
+ ],
+ "retraction_length": [
+ "0.8"
+ ],
+ "retract_length_toolchange": [
+ "2"
+ ],
+ "z_hop": [
+ "0.4"
+ ],
+ "retract_restart_extra": [
+ "0"
+ ],
+ "retract_restart_extra_toolchange": [
+ "0"
+ ],
+ "retraction_speed": [
+ "30"
+ ],
+ "deretraction_speed": [
+ "30"
+ ],
+ "silent_mode": "0",
+ "single_extruder_multi_material": "1",
+ "change_filament_gcode": "",
+ "layer_change_gcode": "",
+ "machine_pause_gcode": "M400 U1\n",
+ "wipe": [
+ "1"
+ ]
+}
diff --git a/resources/profiles/Prusa/mk3.svg b/resources/profiles/Prusa/mk3.svg
new file mode 100644
index 0000000000..678213ac5f
--- /dev/null
+++ b/resources/profiles/Prusa/mk3.svg
@@ -0,0 +1,930 @@
+
+
diff --git a/resources/profiles/Prusa/mk3_bed.stl b/resources/profiles/Prusa/mk3_bed.stl
new file mode 100644
index 0000000000..6aff36f0bc
Binary files /dev/null and b/resources/profiles/Prusa/mk3_bed.stl differ
diff --git a/resources/profiles/Prusa/process/0.20mm Standard @MK3S.json b/resources/profiles/Prusa/process/0.20mm Standard @MK3S.json
new file mode 100644
index 0000000000..6376487ed3
--- /dev/null
+++ b/resources/profiles/Prusa/process/0.20mm Standard @MK3S.json
@@ -0,0 +1,20 @@
+{
+ "type": "process",
+ "setting_id": "MK3S-2",
+ "name": "0.20mm Standard @MK3S",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_process_common",
+ "initial_layer_speed": "20",
+ "initial_layer_infill_speed": "25",
+ "outer_wall_speed": "35",
+ "inner_wall_speed": "60",
+ "sparse_infill_speed": "200",
+ "internal_solid_infill_speed": "200",
+ "top_surface_speed": "50",
+ "gap_infill_speed": "40",
+ "travel_speed": "180",
+ "compatible_printers": [
+ "Prusa MK3S 0.4 nozzle"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Prusa/process/fdm_process_common.json b/resources/profiles/Prusa/process/fdm_process_common.json
new file mode 100644
index 0000000000..f942a8f49f
--- /dev/null
+++ b/resources/profiles/Prusa/process/fdm_process_common.json
@@ -0,0 +1,105 @@
+{
+ "type": "process",
+ "name": "fdm_process_common",
+ "from": "system",
+ "instantiation": "false",
+ "adaptive_layer_height": "0",
+ "reduce_crossing_wall": "0",
+ "max_travel_detour_distance": "0",
+ "bottom_surface_pattern": "monotonic",
+ "bottom_shell_thickness": "0",
+ "bridge_speed": "50",
+ "brim_width": "5",
+ "brim_object_gap": "0.1",
+ "compatible_printers": [],
+ "compatible_printers_condition": "",
+ "print_sequence": "by layer",
+ "default_acceleration": "1000",
+ "initial_layer_acceleration": "500",
+ "top_surface_acceleration": "1000",
+ "travel_acceleration": "1000",
+ "inner_wall_acceleration": "1000",
+ "outer_wall_acceleration": "700",
+ "bridge_no_support": "0",
+ "draft_shield": "disabled",
+ "elefant_foot_compensation": "0",
+ "enable_arc_fitting": "1",
+ "outer_wall_line_width": "0.4",
+ "wall_infill_order": "inner wall/outer wall/infill",
+ "line_width": "0.4",
+ "infill_direction": "45",
+ "sparse_infill_density": "15%",
+ "sparse_infill_pattern": "grid",
+ "initial_layer_line_width": "0.5",
+ "initial_layer_print_height": "0.2",
+ "infill_combination": "0",
+ "sparse_infill_line_width": "0.45",
+ "infill_wall_overlap": "25%",
+ "interface_shells": "0",
+ "ironing_flow": "10%",
+ "ironing_spacing": "0.15",
+ "ironing_speed": "30",
+ "ironing_type": "no ironing",
+ "reduce_infill_retraction": "1",
+ "filename_format": "{input_filename_base}_{filament_type[0]}_{print_time}.gcode",
+ "detect_overhang_wall": "1",
+ "overhang_1_4_speed": "0",
+ "overhang_2_4_speed": "50",
+ "overhang_3_4_speed": "30",
+ "overhang_4_4_speed": "10",
+ "inner_wall_line_width": "0.45",
+ "wall_loops": "2",
+ "print_settings_id": "",
+ "raft_layers": "0",
+ "seam_position": "aligned",
+ "skirt_distance": "2",
+ "skirt_height": "1",
+ "skirt_loops": "0",
+ "minimum_sparse_infill_area": "15",
+ "internal_solid_infill_line_width": "0.4",
+ "spiral_mode": "0",
+ "standby_temperature_delta": "-5",
+ "enable_support": "0",
+ "resolution": "0.012",
+ "support_type": "normal(auto)",
+ "support_on_build_plate_only": "0",
+ "support_top_z_distance": "0.2",
+ "support_filament": "0",
+ "support_line_width": "0.4",
+ "support_interface_loop_pattern": "0",
+ "support_interface_filament": "0",
+ "support_interface_top_layers": "2",
+ "support_interface_bottom_layers": "2",
+ "support_interface_spacing": "0.5",
+ "support_interface_speed": "80",
+ "support_base_pattern": "rectilinear",
+ "support_base_pattern_spacing": "2.5",
+ "support_speed": "150",
+ "support_threshold_angle": "30",
+ "support_object_xy_distance": "0.35",
+ "tree_support_branch_angle": "30",
+ "tree_support_wall_count": "0",
+ "tree_support_with_infill": "0",
+ "detect_thin_wall": "0",
+ "top_surface_pattern": "monotonicline",
+ "top_surface_line_width": "0.4",
+ "top_shell_thickness": "0.8",
+ "enable_prime_tower": "1",
+ "wipe_tower_no_sparse_layers": "0",
+ "prime_tower_width": "35",
+ "xy_hole_compensation": "0",
+ "xy_contour_compensation": "0",
+ "layer_height": "0.2",
+ "bottom_shell_layers": "3",
+ "top_shell_layers": "4",
+ "bridge_flow": "1",
+ "initial_layer_speed": "45",
+ "initial_layer_infill_speed": "45",
+ "outer_wall_speed": "45",
+ "inner_wall_speed": "80",
+ "sparse_infill_speed": "150",
+ "internal_solid_infill_speed": "150",
+ "top_surface_speed": "50",
+ "gap_infill_speed": "30",
+ "travel_speed": "200"
+}
diff --git a/resources/profiles/Voron/machine/fdm_klipper_common.json b/resources/profiles/Voron/machine/fdm_klipper_common.json
index 9d9e6e0373..44ec1123c8 100644
--- a/resources/profiles/Voron/machine/fdm_klipper_common.json
+++ b/resources/profiles/Voron/machine/fdm_klipper_common.json
@@ -116,6 +116,7 @@
"deretraction_speed": [
"30"
],
+ "z_lift_type": "NormalLift",
"silent_mode": "0",
"single_extruder_multi_material": "1",
"change_filament_gcode": "",
@@ -130,9 +131,10 @@
"bed_exclude_area": [
"0x0"
],
- "machine_start_gcode": "; M190 S0\n; M104 S0\nPRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single]\n; You can use following code instead if your PRINT_START macro support Chamber and print area bedmesh\n; PRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single] PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}",
+ "machine_start_gcode": ";M190 S0\n;M104 S0\nPRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single]\n; You can use following code instead if your PRINT_START macro support Chamber and print area bedmesh\n; PRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer_single] Chamber=[chamber_temperature] PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}",
"machine_end_gcode": "PRINT_END",
"layer_change_gcode": "",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
"scan_first_layer": "0",
"nozzle_type": "undefine",
"auxiliary_fan": "0"
diff --git a/resources/profiles/Voron/process/0.20mm Bambu Support W @Voron.json b/resources/profiles/Voron/process/0.20mm Bambu Support W @Voron.json
new file mode 100644
index 0000000000..b456342d93
--- /dev/null
+++ b/resources/profiles/Voron/process/0.20mm Bambu Support W @Voron.json
@@ -0,0 +1,35 @@
+{
+ "type": "process",
+ "setting_id": "GP008",
+ "name": "0.20mm Bambu Support W @Voron",
+ "from": "system",
+ "instantiation": "true",
+ "inherits": "fdm_process_bbl_0.20",
+ "enable_support": "1",
+ "support_interface_top_layers": "3",
+ "support_top_z_distance": "0.2",
+ "support_interface_loop_pattern": "1",
+ "support_interface_spacing": "0",
+ "support_interface_speed": "80",
+ "support_filament": "0",
+ "support_interface_filament": "0",
+ "enable_prime_tower": "1",
+ "initial_layer_speed": "50",
+ "initial_layer_infill_speed": "105",
+ "outer_wall_speed": "120",
+ "inner_wall_speed": "200",
+ "sparse_infill_speed": "300",
+ "internal_solid_infill_speed": "200",
+ "top_surface_speed": "100",
+ "gap_infill_speed": "100",
+ "travel_speed": "350",
+ "compatible_printers": [
+ "Voron 2.4 250 0.4 nozzle",
+ "Voron 2.4 300 0.4 nozzle",
+ "Voron 2.4 350 0.4 nozzle",
+ "Voron Trident 250 0.4 nozzle",
+ "Voron Trident 300 0.4 nozzle",
+ "Voron Trident 350 0.4 nozzle",
+ "Voron 0.1 0.4 nozzle"
+ ]
+}
diff --git a/resources/profiles/Voron/process/fdm_process_voron_common.json b/resources/profiles/Voron/process/fdm_process_voron_common.json
index 47de08ca08..d29395944a 100644
--- a/resources/profiles/Voron/process/fdm_process_voron_common.json
+++ b/resources/profiles/Voron/process/fdm_process_voron_common.json
@@ -16,8 +16,11 @@
"brim_object_gap": "0.1",
"compatible_printers_condition": "",
"print_sequence": "by layer",
- "default_acceleration": "7000",
+ "default_acceleration": "5000",
"top_surface_acceleration": "3000",
+ "travel_acceleration": "7000",
+ "inner_wall_acceleration": "5000",
+ "outer_wall_acceleration": "3000",
"bridge_no_support": "0",
"draft_shield": "disabled",
"elefant_foot_compensation": "0",
@@ -99,6 +102,7 @@
"prime_tower_width": "35",
"xy_hole_compensation": "0",
"xy_contour_compensation": "0",
+ "enable_arc_fitting": "0",
"compatible_printers": [
"Voron 2.4 250 0.4 nozzle",
"Voron 2.4 300 0.4 nozzle",
diff --git a/resources/web/image/printer/Anycubic 4Max Pro_cover.png b/resources/web/image/printer/Anycubic 4Max Pro_cover.png
new file mode 100644
index 0000000000..cf3115e5a8
Binary files /dev/null and b/resources/web/image/printer/Anycubic 4Max Pro_cover.png differ
diff --git a/resources/web/image/printer/Prusa MK3S_cover.png b/resources/web/image/printer/Prusa MK3S_cover.png
new file mode 100644
index 0000000000..4c72c2c57d
Binary files /dev/null and b/resources/web/image/printer/Prusa MK3S_cover.png differ
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index e2d8b7e6e4..0298585704 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -65,19 +65,19 @@ std::string AppConfig::get_hms_host()
{
std::string sel = get("iot_environment");
std::string host = "";
-#if !BBL_RELEASE_TO_PUBLIC
- if (sel == ENV_DEV_HOST)
- host = "e-dev.bambu-lab.com";
- else if (sel == ENV_QAT_HOST)
- host = "e-qa.bambu-lab.com";
- else if (sel == ENV_PRE_HOST)
- host = "e-pre.bambu-lab.com";
- else if (sel == ENV_PRODUCT_HOST)
- host = "e.bambulab.com";
- return host;
-#else
+// #if !BBL_RELEASE_TO_PUBLIC
+// if (sel == ENV_DEV_HOST)
+// host = "e-dev.bambu-lab.com";
+// else if (sel == ENV_QAT_HOST)
+// host = "e-qa.bambu-lab.com";
+// else if (sel == ENV_PRE_HOST)
+// host = "e-pre.bambu-lab.com";
+// else if (sel == ENV_PRODUCT_HOST)
+// host = "e.bambulab.com";
+// return host;
+// #else
return "e.bambulab.com";
-#endif
+// #endif
}
void AppConfig::reset()
@@ -293,15 +293,15 @@ void AppConfig::set_defaults()
set("curr_bed_type", "0");
}
-#if BBL_RELEASE_TO_PUBLIC
+// #if BBL_RELEASE_TO_PUBLIC
if (get("iot_environment").empty()) {
set("iot_environment", "3");
}
-#else
- if (get("iot_environment").empty()) {
- set("iot_environment", "1");
- }
-#endif
+// #else
+// if (get("iot_environment").empty()) {
+// set("iot_environment", "1");
+// }
+// #endif
// Remove legacy window positions/sizes
erase("app", "main_frame_maximized");
@@ -1030,29 +1030,29 @@ void AppConfig::update_last_backup_dir(const std::string& dir)
std::string AppConfig::get_region()
{
-#if BBL_RELEASE_TO_PUBLIC
+// #if BBL_RELEASE_TO_PUBLIC
return this->get("region");
-#else
- std::string sel = get("iot_environment");
- std::string region;
- if (sel == ENV_DEV_HOST)
- region = "ENV_CN_DEV";
- else if (sel == ENV_QAT_HOST)
- region = "ENV_CN_QA";
- else if (sel == ENV_PRE_HOST)
- region = "ENV_CN_PRE";
- if (region.empty())
- return this->get("region");
- return region;
-#endif
+// #else
+// std::string sel = get("iot_environment");
+// std::string region;
+// if (sel == ENV_DEV_HOST)
+// region = "ENV_CN_DEV";
+// else if (sel == ENV_QAT_HOST)
+// region = "ENV_CN_QA";
+// else if (sel == ENV_PRE_HOST)
+// region = "ENV_CN_PRE";
+// if (region.empty())
+// return this->get("region");
+// return region;
+// #endif
}
std::string AppConfig::get_country_code()
{
std::string region = get_region();
-#if !BBL_RELEASE_TO_PUBLIC
- if (is_engineering_region()) { return region; }
-#endif
+// #if !BBL_RELEASE_TO_PUBLIC
+// if (is_engineering_region()) { return region; }
+// #endif
if (region == "CHN" || region == "China")
return "CN";
else if (region == "USA")
diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp
index 6863a0df3b..e08cd5ce0b 100644
--- a/src/libslic3r/ExtrusionEntity.hpp
+++ b/src/libslic3r/ExtrusionEntity.hpp
@@ -55,6 +55,16 @@ inline bool is_perimeter(ExtrusionRole role)
|| role == erOverhangPerimeter;
}
+inline bool is_internal_perimeter(ExtrusionRole role)
+{
+ return role == erPerimeter;
+}
+
+inline bool is_external_perimeter(ExtrusionRole role)
+{
+ return role == erExternalPerimeter;
+}
+
inline bool is_infill(ExtrusionRole role)
{
return role == erBridgeInfill
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 0e22ac9b18..38f48b67d5 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -92,7 +92,7 @@ struct SurfaceFillParams
this->overlap == rhs.overlap &&
this->angle == rhs.angle &&
this->bridge == rhs.bridge &&
-// this->bridge_angle == rhs.bridge_angle &&
+ this->bridge_angle == rhs.bridge_angle &&
this->density == rhs.density &&
// this->dont_adjust == rhs.dont_adjust &&
this->anchor_length == rhs.anchor_length &&
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 7b7508d092..da77a0e13d 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -14,7 +14,7 @@
#include "libslic3r.h"
#include "LocalesUtils.hpp"
#include "libslic3r/format.hpp"
-
+#include "Time.hpp"
#include
#include
#include
@@ -79,7 +79,7 @@ static const float g_min_purge_volume = 100.f;
static const float g_purge_volume_one_time = 135.f;
static const int g_max_flush_count = 4;
-bool GCode::gcode_label_objects = false;
+bool GCode::gcode_label_objects = true;
// Only add a newline in case the current G-code does not end with a newline.
static inline void check_add_eol(std::string& gcode)
@@ -908,6 +908,11 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
BOOST_LOG_TRIVIAL(info) << boost::format("Will export G-code to %1% soon")%path;
print->set_started(psGCodeExport);
+ if (print->is_BBL_printer())
+ gcode_label_objects = false;
+ else
+ gcode_label_objects = true;
+
// check if any custom gcode contains keywords used by the gcode processor to
// produce time estimation and gcode toolpaths
std::vector> validation_res = DoExport::validate_custom_gcode(*print);
@@ -1164,10 +1169,10 @@ namespace DoExport {
print_statistics.clear();
print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges);
if (! extruders.empty()) {
- //std::pair out_filament_used_mm ("; filament used [mm] = ", 0);
- //std::pair out_filament_used_cm3("; filament used [cm3] = ", 0);
- //std::pair out_filament_used_g ("; filament used [g] = ", 0);
- //std::pair out_filament_cost ("; filament cost = ", 0);
+ std::pair out_filament_used_mm ("; filament used [mm] = ", 0);
+ std::pair out_filament_used_cm3("; filament used [cm3] = ", 0);
+ std::pair out_filament_used_g ("; filament used [g] = ", 0);
+ std::pair out_filament_cost ("; filament cost = ", 0);
for (const Extruder &extruder : extruders) {
double used_filament = extruder.used_filament() + (has_wipe_tower ? wipe_tower_data.used_filament[extruder.id()] : 0.f);
double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? wipe_tower_data.used_filament[extruder.id()] * 2.4052f : 0.f); // assumes 1.75mm filament diameter
@@ -1187,14 +1192,14 @@ namespace DoExport {
dst.first += buf;
++ dst.second;
};
- //append(out_filament_used_mm, "%.2lf", used_filament);
- //append(out_filament_used_cm3, "%.2lf", extruded_volume * 0.001);
+ append(out_filament_used_mm, "%.2lf", used_filament);
+ append(out_filament_used_cm3, "%.2lf", extruded_volume * 0.001);
if (filament_weight > 0.) {
print_statistics.total_weight = print_statistics.total_weight + filament_weight;
- //append(out_filament_used_g, "%.2lf", filament_weight);
+ append(out_filament_used_g, "%.2lf", filament_weight);
if (filament_cost > 0.) {
print_statistics.total_cost = print_statistics.total_cost + filament_cost;
- //append(out_filament_cost, "%.2lf", filament_cost);
+ append(out_filament_cost, "%.2lf", filament_cost);
}
}
print_statistics.total_used_filament += used_filament;
@@ -1202,12 +1207,12 @@ namespace DoExport {
print_statistics.total_wipe_tower_filament += has_wipe_tower ? used_filament - extruder.used_filament() : 0.;
print_statistics.total_wipe_tower_cost += has_wipe_tower ? (extruded_volume - extruder.extruded_volume())* extruder.filament_density() * 0.001 * extruder.filament_cost() * 0.001 : 0.;
}
- //filament_stats_string_out += out_filament_used_mm.first;
- //filament_stats_string_out += "\n" + out_filament_used_cm3.first;
- //if (out_filament_used_g.second)
- //filament_stats_string_out += "\n" + out_filament_used_g.first;
- //if (out_filament_cost.second)
- // filament_stats_string_out += "\n" + out_filament_cost.first;
+ filament_stats_string_out += out_filament_used_mm.first;
+ filament_stats_string_out += "\n" + out_filament_used_cm3.first;
+ if (out_filament_used_g.second)
+ filament_stats_string_out += "\n" + out_filament_used_g.first;
+ if (out_filament_cost.second)
+ filament_stats_string_out += "\n" + out_filament_cost.first;
}
return filament_stats_string_out;
}
@@ -1285,7 +1290,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// modifies m_silent_time_estimator_enabled
DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled);
-
+ const bool is_bbl_printers = print.is_BBL_printer();
// resets analyzer's tracking data
m_last_height = 0.f;
m_last_layer_z = 0.f;
@@ -1349,30 +1354,65 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
file.write_format("; HEADER_BLOCK_END\n\n");
- //BBS: write global config at the beginning of gcode file because printer need these config information
- // Append full config, delimited by two 'phony' configuration keys CONFIG_BLOCK_START and CONFIG_BLOCK_END.
- // The delimiters are structured as configuration key / value pairs to be parsable by older versions of PrusaSlicer G-code viewer.
+
+ // BBS: write global config at the beginning of gcode file because printer
+ // need these config information
+ // Append full config, delimited by two 'phony' configuration keys
+ // CONFIG_BLOCK_START and CONFIG_BLOCK_END. The delimiters are structured
+ // as configuration key / value pairs to be parsable by older versions of
+ // PrusaSlicer G-code viewer.
{
+ if (is_bbl_printers) {
file.write("; CONFIG_BLOCK_START\n");
std::string full_config;
append_full_config(print, full_config);
if (!full_config.empty())
- file.write(full_config);
+ file.write(full_config);
+
+ // SoftFever: write compatiple image
+ std::vector temps_per_bed;
+ int first_layer_bed_temperature = 0;
+ get_bed_temperature(0, true, temps_per_bed,
+ first_layer_bed_temperature);
+ file.write_format("; first_layer_bed_temperature = %d\n",
+ first_layer_bed_temperature);
+ file.write_format(
+ "; first_layer_temperature = %d\n",
+ print.config().nozzle_temperature_initial_layer.get_at(0));
file.write("; CONFIG_BLOCK_END\n\n");
+ } else {
+ file.write_format("; hack-fix: write fake slicer info here so that "
+ "Moonraker will extract thumbs.\n");
+ file.write_format(
+ "; %s\n\n",
+ std::string(
+ std::string("generated by SuperSlicer " SLIC3R_VERSION " on ") +
+ Slic3r::Utils::utc_timestamp())
+ .c_str());
+
+ // BBS: add plate id into thumbnail render logic
+ // if (const auto [thumbnails, thumbnails_format] = std::make_pair(
+ // print.full_print_config().option("thumbnails"),
+ // print.full_print_config().option>("thumbnails_format"));
+ // thumbnails)
+ // GCodeThumbnails::export_thumbnails_to_file(
+ // thumbnail_cb, thumbnails->values, thumbnails_format ? thumbnails_format->value : GCodeThumbnailsFormat::PNG,
+ // [&file](const char* sz) { file.write(sz); },
+ // [&print]() { print.throw_if_canceled(); });
+
+
+ DoExport::export_thumbnails_to_file(
+ thumbnail_cb, print.get_plate_index(), print.full_print_config().option("thumbnails")->values,
+ [&file](const char *sz) { file.write(sz); },
+ [&print]() { print.throw_if_canceled(); });
+ }
}
-
- //BBS: add plate id into thumbnail render logic
- //DoExport::export_thumbnails_to_file(thumbnail_cb, print.get_plate_index(), THUMBNAIL_SIZE,
- // [&file](const char* sz) { file.write(sz); },
- // [&print]() { print.throw_if_canceled(); });
-
+
// Write some terse information on the slicing parameters.
const PrintObject *first_object = print.objects().front();
const double layer_height = first_object->config().layer_height.value;
const double initial_layer_print_height = print.config().initial_layer_print_height.value;
- //BBS: remove useless information in gcode file
-#if 0
for (size_t region_id = 0; region_id < print.num_print_regions(); ++ region_id) {
const PrintRegion ®ion = print.get_print_region(region_id);
file.write_format("; external perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frExternalPerimeter, layer_height).width());
@@ -1386,8 +1426,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write_format("; first layer extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, initial_layer_print_height, true).width());
file.write_format("\n");
}
- print.throw_if_canceled();
-#endif
file.write_format("; EXECUTABLE_BLOCK_START\n");
// adds tags for time estimators
@@ -1512,7 +1550,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_placeholder_parser.set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
}
-
+ float outer_wall_volumetric_speed = 0.0f;
{
int curr_bed_type = m_config.curr_bed_type.getInt();
@@ -1524,6 +1562,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_placeholder_parser.set("bed_temperature", new ConfigOptionInts(*bed_temp_opt));
m_placeholder_parser.set("bed_temperature_initial_layer_single", new ConfigOptionInt(first_bed_temp_opt->get_at(initial_extruder_id)));
m_placeholder_parser.set("bed_temperature_initial_layer_vector", new ConfigOptionString(""));
+ m_placeholder_parser.set("chamber_temperature",new ConfigOptionInt(m_config.chamber_temperature));
//BBS: calculate the volumetric speed of outer wall. Ignore pre-object setting and multi-filament, and just use the default setting
{
@@ -1535,7 +1574,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
Flow outer_wall_flow = Flow(outer_wall_line_width, m_config.layer_height, m_config.nozzle_diameter.get_at(initial_extruder_id));
float outer_wall_speed = print.default_region_config().outer_wall_speed.value;
- float outer_wall_volumetric_speed = outer_wall_speed * outer_wall_flow.mm3_per_mm();
+ outer_wall_volumetric_speed = outer_wall_speed * outer_wall_flow.mm3_per_mm();
if (outer_wall_volumetric_speed > filament_max_volumetric_speed)
outer_wall_volumetric_speed = filament_max_volumetric_speed;
m_placeholder_parser.set("outer_wall_volumetric_speed", new ConfigOptionFloat(outer_wall_volumetric_speed));
@@ -1598,8 +1637,23 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (this->m_objsWithBrim.empty() && this->m_objSupportsWithBrim.empty()) m_brim_done = true;
//BBS: open spaghetti detector
- // if (print.config().spaghetti_detector.value)
- file.write("M981 S1 P20000 ;open spaghetti detector\n");
+ if (is_bbl_printers) {
+ // if (print.config().spaghetti_detector.value)
+ file.write("M981 S1 P20000 ;open spaghetti detector\n");
+ file.write_format("M900 K%.3f M%0.3f ; Override pressure advance value\n",
+ m_config.pressure_advance.values.front(),
+ outer_wall_volumetric_speed / (1.75 * 1.75 / 4 * 3.14) *
+ m_config.pressure_advance.values.front());
+ } else {
+ if (m_config.enable_pressure_advance.value) {
+ if(print.config().gcode_flavor.value == gcfKlipper)
+ file.write_format("SET_PRESSURE_ADVANCE ADVANCE=%.3f ; Override pressure advance value\n",
+ m_config.pressure_advance.values.front());
+ else
+ file.write_format("M900 K%.3f ; Override pressure advance value\n",
+ m_config.pressure_advance.values.front());
+ }
+ }
// Do all objects for each layer.
if (print.config().print_sequence == PrintSequence::ByObject) {
@@ -1663,7 +1717,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file, prime_extruder);
//BBS: close powerlost recovery
{
- if (m_second_layer_things_done) {
+ if (is_bbl_printers && m_second_layer_things_done) {
file.write("; close powerlost recovery\n");
file.write("M1003 S0\n");
}
@@ -1734,7 +1788,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file);
//BBS: close powerlost recovery
{
- if (m_second_layer_things_done) {
+ if (is_bbl_printers && m_second_layer_things_done) {
file.write("; close powerlost recovery\n");
file.write("M1003 S0\n");
}
@@ -1754,10 +1808,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write(m_writer.set_fan(0));
//BBS: make sure the additional fan is closed when end
file.write(m_writer.set_additional_fan(0));
- //BBS: close spaghetti detector
- //Note: M981 is also used to tell xcam the last layer is finished, so we need always send it even if spaghetti option is disabled.
- //if (print.config().spaghetti_detector.value)
- file.write("M981 S0 P20000 ; close spaghetti detector\n");
+ if (is_bbl_printers) {
+ //BBS: close spaghetti detector
+ //Note: M981 is also used to tell xcam the last layer is finished, so we need always send it even if spaghetti option is disabled.
+ //if (print.config().spaghetti_detector.value)
+ file.write("M981 S0 P20000 ; close spaghetti detector\n");
+ }
// adds tag for processor
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
@@ -1800,11 +1856,41 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_writer.extruders(),
// Modifies
print.m_print_statistics));
- //file.write("\n");
- //file.write_format("; total filament weight [g] = %.2lf\n", print.m_print_statistics.total_weight);
- //file.write_format("; total filament cost = %.2lf\n", print.m_print_statistics.total_cost);
- //if (print.m_print_statistics.total_toolchanges > 0)
- // file.write_format("; total filament change = %i\n", print.m_print_statistics.total_toolchanges);
+ if (!is_bbl_printers) {
+ file.write("\n");
+ file.write("; CONFIG_BLOCK_START\n");
+ std::string full_config;
+ append_full_config(print, full_config);
+ if (!full_config.empty())
+ file.write(full_config);
+
+ // SoftFever: write compatiple info
+ std::vector temps_per_bed;
+ int first_layer_bed_temperature = 0;
+ get_bed_temperature(0, true, temps_per_bed, first_layer_bed_temperature);
+ file.write_format("; first_layer_bed_temperature = %d\n",
+ first_layer_bed_temperature);
+ file.write_format(
+ "; first_layer_temperature = %d\n",
+ print.config().nozzle_temperature_initial_layer.get_at(0));
+ file.write("; CONFIG_BLOCK_END\n\n");
+ file.write_format("; total filament used [g] = %.2lf\n",
+ print.m_print_statistics.total_weight);
+ file.write_format("; total filament cost = %.2lf\n",
+ print.m_print_statistics.total_cost);
+ if (print.m_print_statistics.total_toolchanges > 0)
+ file.write_format("; total filament change = %i\n",
+ print.m_print_statistics.total_toolchanges);
+
+ file.write_format("; total layers count = %i\n", m_layer_count);
+ file.write_format(
+ ";%s\n",
+ GCodeProcessor::reserved_tag(
+ GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder)
+ .c_str());
+
+ }
+ file.write("\n");
print.throw_if_canceled();
}
@@ -2501,28 +2587,41 @@ GCode::LayerResult GCode::process_layer(
double acceleration = m_config.initial_layer_acceleration.value;
gcode += m_writer.set_acceleration((unsigned int)floor(acceleration + 0.5));
}
+
+ if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) {
+ double jerk = m_config.initial_layer_jerk.value;
+ gcode += m_writer.set_jerk_xy((unsigned int)floor(jerk + 0.5));
+ }
+
}
if (! first_layer && ! m_second_layer_things_done) {
- //BBS: open powerlost recovery
+ if (print.is_BBL_printer()) {
+ // BBS: open powerlost recovery
{
- gcode += "; open powerlost recovery\n";
- gcode += "M1003 S1\n";
+ gcode += "; open powerlost recovery\n";
+ gcode += "M1003 S1\n";
}
// BBS: open first layer inspection at second layer
if (print.config().scan_first_layer.value) {
- // BBS: retract first to avoid droping when scan model
- gcode += this->retract();
- gcode += "M976 S1 P1 ; scan model before printing 2nd layer\n";
- gcode += "M400 P100\n";
- gcode += this->unretract();
+ // BBS: retract first to avoid droping when scan model
+ gcode += this->retract();
+ gcode += "M976 S1 P1 ; scan model before printing 2nd layer\n";
+ gcode += "M400 P100\n";
+ gcode += this->unretract();
}
-
+ }
//BBS: reset acceleration at sencond layer
if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) {
double acceleration = m_config.default_acceleration.value;
gcode += m_writer.set_acceleration((unsigned int)floor(acceleration + 0.5));
}
+
+ if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) {
+ double jerk = m_config.default_jerk.value;
+ gcode += m_writer.set_jerk_xy((unsigned int)floor(jerk + 0.5));
+ }
+
// Transition from 1st to 2nd layer. Adjust nozzle temperatures as prescribed by the nozzle dependent
// nozzle_temperature_initial_layer vs. temperature settings.
for (const Extruder &extruder : m_writer.extruders()) {
@@ -3237,9 +3336,13 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
}
//BBS: don't reset acceleration when printing first layer. During first layer, acceleration is always same value.
- if (!this->on_first_layer())
+ if (!this->on_first_layer()){
// reset acceleration
- gcode += m_writer.set_acceleration((unsigned int)(m_config.default_acceleration.value + 0.5));
+ if(m_config.default_acceleration.value > 0)
+ gcode += m_writer.set_acceleration((unsigned int)(m_config.default_acceleration.value + 0.5));
+ if(m_config.default_jerk.value > 0)
+ gcode += m_writer.set_jerk_xy((unsigned int)(m_config.default_jerk.value + 0.5));
+ }
// BBS
if (m_wipe.enable) {
@@ -3312,9 +3415,12 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string
m_wipe.path.reverse();
}
//BBS: don't reset acceleration when printing first layer. During first layer, acceleration is always same value.
- if (!this->on_first_layer())
+ if (!this->on_first_layer()) {
// reset acceleration
gcode += m_writer.set_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
+ if(m_config.default_jerk.value > 0)
+ gcode += m_writer.set_jerk_xy((unsigned int)floor(m_config.default_jerk.value + 0.5));
+ }
return gcode;
}
@@ -3340,9 +3446,13 @@ std::string GCode::extrude_path(ExtrusionPath path, std::string description, dou
m_wipe.path.reverse();
}
//BBS: don't reset acceleration when printing first layer. During first layer, acceleration is always same value.
- if (!this->on_first_layer())
+ if (!this->on_first_layer()){
// reset acceleration
gcode += m_writer.set_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
+ if(m_config.default_jerk.value > 0)
+ gcode += m_writer.set_jerk_xy((unsigned int)floor(m_config.default_jerk.value + 0.5));
+
+ }
return gcode;
}
@@ -3541,6 +3651,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
} else if (m_config.perimeter_acceleration.value > 0 && is_perimeter(path.role())) {
acceleration = m_config.perimeter_acceleration.value;
#endif
+ } else if (m_config.outer_wall_acceleration.value > 0 && is_external_perimeter(path.role())) {
+ acceleration = m_config.outer_wall_acceleration.value;
+ } else if (m_config.inner_wall_acceleration.value > 0 && is_internal_perimeter(path.role())) {
+ acceleration = m_config.inner_wall_acceleration.value;
} else if (m_config.top_surface_acceleration.value > 0 && is_top_surface(path.role())) {
acceleration = m_config.top_surface_acceleration.value;
} else {
@@ -3549,6 +3663,23 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
gcode += m_writer.set_acceleration((unsigned int)floor(acceleration + 0.5));
}
+ // adjust X Y jerk
+ if (m_config.default_jerk.value > 0) {
+ double jerk;
+ if (this->on_first_layer() && m_config.initial_layer_jerk.value > 0) {
+ jerk = m_config.initial_layer_jerk.value;
+ } else if (m_config.outer_wall_jerk.value > 0 && is_external_perimeter(path.role())) {
+ jerk = m_config.outer_wall_jerk.value;
+ } else if (m_config.inner_wall_jerk.value > 0 && is_internal_perimeter(path.role())) {
+ jerk = m_config.inner_wall_jerk.value;
+ } else if (m_config.top_surface_jerk.value > 0 && is_top_surface(path.role())) {
+ jerk = m_config.top_surface_jerk.value;
+ } else {
+ jerk = m_config.default_jerk.value;
+ }
+ gcode += m_writer.set_jerk_xy((unsigned int)floor(jerk + 0.5));
+ }
+
// calculate extrusion length per distance unit
double e_per_mm = m_writer.extruder()->e_per_mm3() * path.mm3_per_mm;
@@ -3761,7 +3892,34 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
bool could_be_wipe_disabled = false;
// Save state of use_external_mp_once for the case that will be needed to call twice m_avoid_crossing_perimeters.travel_to.
const bool used_external_mp_once = m_avoid_crossing_perimeters.used_external_mp_once();
+ std::string gcode;
+ // SoftFever
+ if (this->on_first_layer()) {
+ if(m_config.default_acceleration.value > 0)
+ {
+ auto jerk = (unsigned int)floor(m_config.initial_layer_jerk.value + 0.5);
+ auto accel = (unsigned int)floor(m_config.initial_layer_acceleration.value + 0.5);
+ if(jerk > 0)
+ gcode += m_writer.set_jerk_xy(jerk);
+
+ if(accel > 0)
+ gcode += m_writer.set_acceleration(accel);
+ }
+ }
+ else
+ {
+ if(m_config.default_jerk.value > 0)
+ {
+ auto jerk = (unsigned int)floor(m_config.travel_jerk.value + 0.5);
+ auto accel = (unsigned int)floor(m_config.travel_acceleration.value + 0.5);
+ if(jerk > 0)
+ gcode += m_writer.set_jerk_xy(jerk);
+
+ if(accel > 0)
+ gcode += m_writer.set_acceleration(accel);
+ }
+ }
// if a retraction would be needed, try to use reduce_crossing_wall to plan a
// multi-hop travel path inside the configuration space
if (needs_retraction
@@ -3777,7 +3935,6 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
m_avoid_crossing_perimeters.reset_once_modifiers();
// generate G-code for the travel move
- std::string gcode;
if (needs_retraction) {
if (m_config.reduce_crossing_wall && could_be_wipe_disabled)
m_wipe.reset_path();
@@ -3808,9 +3965,9 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
if (i == travel.size() - 1 && !m_spiral_vase) {
Vec2d dest2d = this->point_to_gcode(travel.points[i]);
Vec3d dest3d(dest2d(0), dest2d(1), m_nominal_z);
- gcode += m_writer.travel_to_xyz(dest3d, comment);
+ gcode += m_writer.travel_to_xyz(dest3d, comment+" travel_to_xyz");
} else {
- gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment);
+ gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment+" travel_to_xy");
}
}
this->set_last_pos(travel.points.back());
@@ -3884,7 +4041,11 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction)
if (m_writer.extruder()->retraction_length() > 0) {
// BBS: don't do lazy_lift when enable spiral vase
size_t extruder_id = m_writer.extruder()->id();
- gcode += m_writer.lift(!m_spiral_vase ? LiftType::SpiralLift : LiftType::NormalLift);
+ auto _lift = m_config.z_lift_type.value;
+ if(m_spiral_vase)
+ _lift = NormalLift;
+
+ gcode += m_writer.lift(_lift);
}
return gcode;
diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp
index 312389a4d8..88b65d7b82 100644
--- a/src/libslic3r/GCode/GCodeProcessor.cpp
+++ b/src/libslic3r/GCode/GCodeProcessor.cpp
@@ -453,10 +453,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
PrintEstimatedStatistics::ETimeMode mode = static_cast(i);
if (mode == PrintEstimatedStatistics::ETimeMode::Normal || machine.enabled) {
char buf[128];
- //sprintf(buf, "; estimated printing time (%s mode) = %s\n",
- // (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent",
- // get_time_dhms(machine.time).c_str());
- sprintf(buf, "; total estimated time: %s\n", get_time_dhms(machine.time).c_str());
+ sprintf(buf, "; estimated printing time: %s\n", get_time_dhms(machine.time).c_str());
ret += buf;
}
}
diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp
index 79da522399..b87b6af672 100644
--- a/src/libslic3r/GCode/WipeTower.cpp
+++ b/src/libslic3r/GCode/WipeTower.cpp
@@ -99,8 +99,7 @@ public:
}
WipeTowerWriter& disable_linear_advance() {
- m_gcode += (m_gcode_flavor == gcfRepRapSprinter || m_gcode_flavor == gcfRepRapFirmware
- ? (std::string("M572 D") + std::to_string(m_current_tool) + " S0\n")
+ m_gcode += (m_gcode_flavor == gcfKlipper ? (std::string("SET_PRESSURE_ADVANCE ADVANCE=0\n"))
: std::string("M900 K0\n"));
return *this;
}
diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp
index 4b0739b9c8..9bdd1d59a8 100644
--- a/src/libslic3r/GCodeWriter.cpp
+++ b/src/libslic3r/GCodeWriter.cpp
@@ -15,15 +15,16 @@
namespace Slic3r {
-const bool GCodeWriter::full_gcode_comment = false;
+const bool GCodeWriter::full_gcode_comment = true;
const double GCodeWriter::slope_threshold = 3 * PI / 180;
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
{
this->config.apply(print_config, true);
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
- bool is_marlin = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware;
+ bool is_marlin = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware || print_config.gcode_flavor.value == gcfKlipper;
m_max_acceleration = std::lrint(is_marlin ? print_config.machine_max_acceleration_extruding.values.front() : 0);
+ m_max_jerk = std::lrint(is_marlin ? std::min(print_config.machine_max_jerk_x.values.front(), print_config.machine_max_jerk_y.values.front()) : 0);
}
void GCodeWriter::set_extruders(std::vector extruder_ids)
@@ -54,7 +55,8 @@ std::string GCodeWriter::preamble()
FLAVOR_IS(gcfMarlinFirmware) ||
FLAVOR_IS(gcfTeacup) ||
FLAVOR_IS(gcfRepetier) ||
- FLAVOR_IS(gcfSmoothie))
+ FLAVOR_IS(gcfSmoothie) ||
+ FLAVOR_IS(gcfKlipper))
{
if (RELATIVE_E_AXIS) {
gcode << "M83 ; only support relative e\n";
@@ -183,6 +185,30 @@ std::string GCodeWriter::set_acceleration(unsigned int acceleration)
return gcode.str();
}
+std::string GCodeWriter::set_jerk_xy(unsigned int jerk)
+{
+ // Clamp the jerk to the allowed maximum.
+ if (m_max_jerk > 0 && jerk > m_max_jerk)
+ jerk = m_max_jerk;
+
+ if (jerk < 1 || jerk == m_last_jerk)
+ return std::string();
+
+ m_last_jerk = jerk;
+
+ std::ostringstream gcode;
+ if(FLAVOR_IS(gcfKlipper))
+ gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
+ else
+ gcode << "M205 X" << jerk << " Y" << jerk;
+
+ if (GCodeWriter::full_gcode_comment) gcode << " ; adjust jerk";
+ gcode << "\n";
+
+ return gcode.str();
+
+}
+
std::string GCodeWriter::reset_e(bool force)
{
if (FLAVOR_IS(gcfMach3)
diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp
index 23d3b5ec72..3920b71808 100644
--- a/src/libslic3r/GCodeWriter.hpp
+++ b/src/libslic3r/GCodeWriter.hpp
@@ -11,12 +11,6 @@
namespace Slic3r {
-enum class LiftType {
- NormalLift,
- LazyLift,
- SpiralLift
-};
-
class GCodeWriter {
public:
GCodeConfig config;
@@ -26,6 +20,7 @@ public:
multiple_extruders(false), m_extruder(nullptr),
m_single_extruder_multi_material(false),
m_last_acceleration(0), m_max_acceleration(0),
+ m_last_jerk(0), m_max_jerk(0),
/*m_last_bed_temperature(0), */m_last_bed_temperature_reached(true),
m_lifted(0),
m_to_lift(0),
@@ -51,6 +46,7 @@ public:
// BBS
std::string set_bed_temperature(std::vector temps_per_bed, int default_temp, bool wait = false);
std::string set_acceleration(unsigned int acceleration);
+ std::string set_jerk_xy(unsigned int jerk);
std::string reset_e(bool force = false);
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
// return false if this extruder was already selected
@@ -104,6 +100,13 @@ private:
// Limit for setting the acceleration, to respect the machine limits set for the Marlin firmware.
// If set to zero, the limit is not in action.
unsigned int m_max_acceleration;
+ unsigned int m_max_jerk;
+ unsigned int m_last_jerk;
+
+ unsigned int m_travel_acceleration;
+ unsigned int m_travel_jerk;
+
+
//BBS
unsigned int m_last_additional_fan_speed;
// BBS
diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp
index d674680822..4ab0be7d76 100644
--- a/src/libslic3r/LayerRegion.cpp
+++ b/src/libslic3r/LayerRegion.cpp
@@ -296,8 +296,10 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
printf("Processing bridge at layer %zu:\n", this->layer()->id());
#endif
//BBS: use 0 as custom angle to enable auto detection all the time
- double custom_angle = Geometry::deg2rad(0.0);
- if (bd.detect_angle(custom_angle)) {
+ double custom_angle = Geometry::deg2rad(this->region().config().bridge_angle.value);
+ if(custom_angle > 0)
+ bridges[idx_last].bridge_angle = custom_angle;
+ else if (bd.detect_angle(custom_angle)) {
bridges[idx_last].bridge_angle = bd.angle;
if (this->layer()->object()->has_support()) {
// polygons_append(this->bridged, bd.coverage());
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index 3b67a7c12e..3b1a3145f3 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -412,6 +412,8 @@ void PerimeterGenerator::process()
for (const Surface &surface : this->slices->surfaces) {
// detect how many perimeters must be generated for this island
int loop_number = this->config->wall_loops + surface.extra_perimeters - 1; // 0-indexed loops
+ if (this->layer_id == 0 && this->config->only_one_wall_first_layer)
+ loop_number = 0;
//BBS: set the topmost layer to be one wall
if (loop_number > 0 && config->only_one_wall_top && this->upper_slices == nullptr)
loop_number = 0;
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 3c3c1d936a..d8e9c373d2 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -697,8 +697,9 @@ static std::vector s_Preset_print_options {
#endif /* HAS_PRESSURE_EQUALIZER */
"inner_wall_speed", "outer_wall_speed", "small_perimeter_speed", "sparse_infill_speed", "internal_solid_infill_speed",
"top_surface_speed", "support_speed", "support_object_xy_distance", "support_interface_speed",
- "bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
- "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "skirt_loops", "skirt_distance", "skirt_height", "draft_shield",
+ "bridge_speed", "bridge_angle", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
+ "outer_wall_acceleration", "inner_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "travel_acceleration", "skirt_loops", "skirt_distance", "skirt_height", "draft_shield",
+ "default_jerk", "outer_wall_jerk", "inner_wall_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk",
"brim_width", "brim_object_gap", "brim_type", "enable_support", "support_type", "support_threshold_angle", "enforce_support_layers",
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
"support_base_pattern", "support_base_pattern_spacing", "support_style",
@@ -722,14 +723,17 @@ static std::vector s_Preset_print_options {
"detect_narrow_internal_solid_infill",
"gcode_add_line_number", "enable_arc_fitting", "infill_combination", "adaptive_layer_height",
"support_bottom_interface_spacing", "enable_overhang_speed", "overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed",
- "initial_layer_infill_speed", "only_one_wall_top",
- "timelapse_type"
+ "initial_layer_infill_speed", "only_one_wall_top", "only_one_wall_first_layer",
+ "timelapse_type",
+ //SoftFever
+ "top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio"
+
};
static std::vector s_Preset_filament_options {
/*"filament_colour", */"filament_diameter", "filament_type", "filament_soluble", "filament_is_support", "filament_max_volumetric_speed",
- "filament_flow_ratio", "filament_density", "filament_cost", "filament_minimal_purge_on_wipe_tower",
- "nozzle_temperature", "nozzle_temperature_initial_layer",
+ "filament_flow_ratio", "enable_pressure_advance", "pressure_advance", "filament_density", "filament_cost", "filament_minimal_purge_on_wipe_tower",
+ "chamber_temperature", "nozzle_temperature", "nozzle_temperature_initial_layer",
// BBS
"cool_plate_temp", "eng_plate_temp", "hot_plate_temp", "textured_plate_temp", "cool_plate_temp_initial_layer", "eng_plate_temp_initial_layer", "hot_plate_temp_initial_layer","textured_plate_temp_initial_layer",
// "bed_type",
@@ -757,18 +761,20 @@ static std::vector s_Preset_machine_limits_options {
static std::vector s_Preset_printer_options {
"printer_technology",
- "printable_area", "bed_exclude_area", "gcode_flavor",
+ "printable_area", "bed_exclude_area", "gcode_flavor","z_lift_type",
"single_extruder_multi_material", "machine_start_gcode", "machine_end_gcode", "before_layer_change_gcode", "layer_change_gcode", "change_filament_gcode",
"printer_model", "printer_variant", "printable_height", "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
"default_print_profile", "inherits",
"silent_mode",
// BBS
"scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode",
- "nozzle_type", "auxiliary_fan", "nozzle_volume",
+ "nozzle_type", "nozzle_diameter", "auxiliary_fan", "nozzle_volume",
//SoftFever
"host_type", "print_host", "printhost_apikey",
"printhost_cafile","printhost_port","printhost_authorization_type",
- "printhost_user", "printhost_password", "printhost_ssl_ignore_revoke"
+ "printhost_user",
+ "printhost_password",
+ "printhost_ssl_ignore_revoke", "thumbnails"
};
static std::vector s_Preset_sla_print_options {
@@ -2238,6 +2244,21 @@ void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys&
}
}
+// template
+// void add_correct_opt_to_diff(const std::string &opt_key, t_config_option_keys& vec, const ConfigBase &other, const ConfigBase &this_c)
+// {
+// const T* opt_init = static_cast(other.option(opt_key));
+// const T* opt_cur = static_cast(this_c.option(opt_key));
+// int opt_init_max_id = opt_init->values.size() - 1;
+// for (int i = 0; i < int(opt_cur->values.size()); i++)
+// {
+// int init_id = i <= opt_init_max_id ? i : 0;
+// if (opt_cur->values[i] != opt_init->values[init_id])
+// vec.emplace_back(opt_key + "#" + std::to_string(i));
+// }
+// }
+
+
// Use deep_diff to correct return of changed options, considering individual options for each extruder.
inline t_config_option_keys deep_diff(const ConfigBase &config_this, const ConfigBase &config_other)
{
@@ -2248,7 +2269,7 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt)
{
//BBS: add bed_exclude_area
- if (opt_key == "printable_area" || opt_key == "bed_exclude_area" || opt_key == "compatible_prints" || opt_key == "compatible_printers") {
+ if (opt_key == "printable_area" || opt_key == "bed_exclude_area" || opt_key == "compatible_prints" || opt_key == "compatible_printers" || opt_key == "thumbnails") {
// Scalar variable, or a vector variable, which is independent from number of extruders,
// thus the vector is presented to the user as a single input.
diff.emplace_back(opt_key);
@@ -2261,6 +2282,7 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
case coBools: add_correct_opts_to_diff(opt_key, diff, config_other, config_this); break;
case coFloats: add_correct_opts_to_diff(opt_key, diff, config_other, config_this); break;
case coStrings: add_correct_opts_to_diff(opt_key, diff, config_other, config_this); break;
+ // case coString: add_correct_opts_to_diff(opt_key, diff, config_other, config_this); break;
case coPercents:add_correct_opts_to_diff(opt_key, diff, config_other, config_this); break;
case coPoints: add_correct_opts_to_diff(opt_key, diff, config_other, config_this); break;
// BBS
@@ -2741,6 +2763,8 @@ void PhysicalPrinterCollection::load_printers(
// see https://github.com/prusa3d/PrusaSlicer/issues/732
boost::filesystem::path dir = boost::filesystem::absolute(boost::filesystem::path(dir_path) / subdir).make_preferred();
m_dir_path = dir.string();
+ if(!boost::filesystem::exists(dir))
+ return;
std::string errors_cummulative;
// Store the loaded printers into a new vector, otherwise the binary search for already existing presets would be broken.
std::deque printers_loaded;
diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp
index 154a5f295a..e2aa72b607 100644
--- a/src/libslic3r/PresetBundle.cpp
+++ b/src/libslic3r/PresetBundle.cpp
@@ -38,9 +38,9 @@ static std::vector s_project_options {
"wipe_tower_y",
"wipe_tower_rotation_angle",
"curr_bed_type",
-#if !BBL_RELEASE_TO_PUBLIC
+// #if !BBL_RELEASE_TO_PUBLIC
"flush_multiplier",
-#endif
+// #endif
};
//BBS: add BBL as default
@@ -90,7 +90,7 @@ PresetBundle::PresetBundle()
for (size_t i = 0; i < 1; ++i) {
// The following ugly switch is to avoid printers.preset(0) to return the edited instance, as the 0th default is the current one.
Preset &preset = this->printers.default_preset(i);
- for (const char *key : {"printer_settings_id", "printer_model", "printer_variant"}) preset.config.optptr(key, true);
+ for (const char *key : {"printer_settings_id", "printer_model", "printer_variant", "thumbnails"}) preset.config.optptr(key, true);
//if (i == 0) {
preset.config.optptr("default_print_profile", true);
preset.config.option("default_filament_profile", true);
@@ -1419,8 +1419,10 @@ DynamicPrintConfig PresetBundle::full_config() const
DynamicPrintConfig PresetBundle::full_config_secure() const
{
DynamicPrintConfig config = this->full_config();
- //BBS example: config.erase("print_host");
- return config;
+ //FIXME legacy, the keys should not be there after conversion to a Physical Printer profile.
+ config.erase("print_host");
+ config.erase("printhost_apikey");
+ config.erase("printhost_cafile"); return config;
}
const std::set ignore_settings_list ={
@@ -2960,7 +2962,7 @@ std::pair PresetBundle::load_vendor_configs_
//parse error
std::string subfile_path = path + "/" + vendor_name + "/" + subfile.second;
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", got error when parse process setting from %1%") % subfile_path;
- throw ConfigurationError((boost::format("Failed loading configuration file %1%\nSuggest cleaning the directory %2% firstly") % subfile_path %vendor_system_path).str());
+ throw ConfigurationError((boost::format("Failed loading configuration file %1%\nSuggest cleaning the directory %2% firstly.\nReason: %3%") % subfile_path %vendor_system_path %reason).str());
}
}
@@ -3435,4 +3437,4 @@ void PresetBundle::set_default_suppressed(bool default_suppressed)
printers.set_default_suppressed(default_suppressed);
}
-} // namespace Slic3r
+} // namespace Slic3r
\ No newline at end of file
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 2eadc0cd6a..6322d9b91b 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -68,7 +68,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
//BBS: add bed_exclude_area
"bed_exclude_area",
"before_layer_change_gcode",
- "enable_overhang_bridge_fan"
+ "enable_pressure_advance",
+ "pressure_advance",
+ "enable_overhang_bridge_fan",
"overhang_fan_speed",
"overhang_fan_threshold",
"slow_down_for_layer_cooling",
@@ -90,8 +92,11 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"filament_diameter",
"filament_density",
"filament_cost",
+ "outer_wall_acceleration",
+ "inner_wall_acceleration",
"initial_layer_acceleration",
"top_surface_acceleration",
+ "travel_acceleration",
// BBS
"cool_plate_temp_initial_layer",
"eng_plate_temp_initial_layer",
@@ -124,10 +129,13 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"filament_start_gcode",
"change_filament_gcode",
"wipe",
+ "z_lift_type",
// BBS
"wipe_distance",
"curr_bed_type",
- "nozzle_volume"
+ "nozzle_volume",
+ "chamber_temperature",
+ "thumbnails"
};
static std::unordered_set steps_ignore;
@@ -164,6 +172,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
} else if (
opt_key == "print_sequence"
|| opt_key == "filament_type"
+ || opt_key == "chamber_temperature"
|| opt_key == "nozzle_temperature_initial_layer"
|| opt_key == "filament_minimal_purge_on_wipe_tower"
|| opt_key == "filament_max_volumetric_speed"
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index 761422e7bf..34809ac6ab 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -728,7 +728,11 @@ public:
// Return 4 wipe tower corners in the world coordinates (shifted and rotated), including the wipe tower brim.
std::vector first_layer_wipe_tower_corners(bool check_wipe_tower_existance=true) const;
-protected:
+ //SoftFever
+ bool &is_BBL_printer() { return m_isBBLPrinter; }
+ const bool is_BBL_printer() const { return m_isBBLPrinter; }
+
+ protected:
// Invalidates the step, and its depending steps in Print.
bool invalidate_step(PrintStep step);
@@ -750,6 +754,9 @@ private:
PrintRegionConfig m_default_region_config;
PrintObjectPtrs m_objects;
PrintRegionPtrs m_print_regions;
+
+ //SoftFever
+ bool m_isBBLPrinter;
// Ordered collections of extrusion paths to build skirt loops and brim.
ExtrusionEntityCollection m_skirt;
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 2b88f0c4b4..40fa408a45 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -72,18 +72,18 @@ static t_config_enum_values s_keys_map_PrinterTechnology {
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrinterTechnology)
-static t_config_enum_values s_keys_map_PrintHostType{
+static t_config_enum_values s_keys_map_PrintHostType {
{ "prusalink", htPrusaLink },
{ "octoprint", htOctoPrint },
- //{ "duet", htDuet },
- //{ "flashair", htFlashAir },
- //{ "astrobox", htAstroBox },
- //{ "repetier", htRepetier },
- //{ "mks", htMKS }
+ { "duet", htDuet },
+ { "flashair", htFlashAir },
+ { "astrobox", htAstroBox },
+ { "repetier", htRepetier },
+ { "mks", htMKS }
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrintHostType)
-static t_config_enum_values s_keys_map_AuthorizationType{
+static t_config_enum_values s_keys_map_AuthorizationType {
{ "key", atKeyPassword },
{ "user", atUserPassword }
};
@@ -98,6 +98,7 @@ static t_config_enum_values s_keys_map_GCodeFlavor {
{ "makerware", gcfMakerWare },
{ "marlin2", gcfMarlinFirmware },
{ "sailfish", gcfSailfish },
+ { "klipper", gcfKlipper },
{ "smoothie", gcfSmoothie },
{ "mach3", gcfMach3 },
{ "machinekit", gcfMachinekit },
@@ -105,6 +106,15 @@ static t_config_enum_values s_keys_map_GCodeFlavor {
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(GCodeFlavor)
+
+static t_config_enum_values s_keys_map_LiftType {
+ { "NormalLift", int(LiftType::NormalLift) },
+ { "LazyLift", int(LiftType::LazyLift) },
+ { "SpiralLift", int(LiftType::SpiralLift) }
+};
+CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(LiftType)
+
+
static t_config_enum_values s_keys_map_FuzzySkinType {
{ "none", int(FuzzySkinType::None) },
{ "external", int(FuzzySkinType::External) },
@@ -317,7 +327,7 @@ void PrintConfigDef::init_common_params()
def = this->add("printable_area", coPoints);
def->label = L("Printable area");
//BBS
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) });
//BBS: add "bed_exclude_area"
@@ -575,7 +585,7 @@ void PrintConfigDef::init_fff_params()
def->multiline = true;
def->full_width = true;
def->height = 5;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString(""));
def = this->add("bottom_shell_layers", coInt);
@@ -644,12 +654,38 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(1));
+ def = this->add("top_solid_infill_flow_ratio", coFloat);
+ def->label = L("Top surface flow ratio");
+ def->category = L("Advanced");
+ def->tooltip = L("This factor affects the amount of material for top solid infill. "
+ "You can decrease it slightly to have smooth surface finish");
+ def->min = 0;
+ def->max = 2;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(1));
+
+ def = this->add("bottom_solid_infill_flow_ratio", coFloat);
+ def->label = L("Bottom surface flow ratio");
+ def->category = L("Advanced");
+ def->tooltip = L("This factor affects the amount of material for bottom solid infill");
+ def->min = 0;
+ def->max = 2;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(1));
+
+
def = this->add("only_one_wall_top", coBool);
def->label = L("Only one wall on top surfaces");
def->category = L("Quality");
def->tooltip = L("Use only one wall on flat top surface, to give more space to the top infill pattern");
def->set_default_value(new ConfigOptionBool(false));
+ def = this->add("only_one_wall_first_layer", coBool);
+ def->label = L("Only one wall on first layer");
+ def->category = L("Quality");
+ def->tooltip = L("Use only one wall on first layer, to give more space to the bottom infill pattern");
+ def->set_default_value(new ConfigOptionBool(false));
+
def = this->add("enable_overhang_speed", coBool);
def->label = L("Slow down for overhang");
def->category = L("Speed");
@@ -975,7 +1011,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back("3");
def->enum_labels.push_back("4");
def->enum_labels.push_back("5");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def = this->add("extruder_clearance_height_to_rod", coFloat);
def->label = L("Height to rod");
@@ -1009,7 +1045,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Only used as a visual help on UI");
def->gui_type = ConfigOptionDef::GUIType::color;
// Empty string means no color assigned yet.
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionStrings { "" });
def = this->add("extruder_offset", coPoints);
@@ -1019,7 +1055,7 @@ void PrintConfigDef::init_fff_params()
// "with respect to the first one. It expects positive coordinates (they will be subtracted "
// "from the XY coordinate).");
def->sidetext = L("mm");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPoints { Vec2d(0,0) });
def = this->add("filament_flow_ratio", coFloats);
@@ -1032,6 +1068,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 1. });
+ def = this->add("enable_pressure_advance", coBool);
+ def->label = L("Enable pressure advance");
+ def->tooltip = L("Enable pressure advance, auto calibration result will be overwriten once enabled.");
+ def->set_default_value(new ConfigOptionBool(false));
+
+ def = this->add("pressure_advance", coFloats);
+ def->label = L("Pressure advance");
+ def->tooltip = L("Pressure advnce(Klipper) AKA Linear advance factor(Marlin)");
+ def->max = 2;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloats { 0.02 });
+
def = this->add("line_width", coFloat);
def->label = L("Default");
def->category = L("Quality");
@@ -1062,7 +1110,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Color");
def->tooltip = L("Only used as a visual help on UI");
def->gui_type = ConfigOptionDef::GUIType::color;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionStrings{ "#00AE42" });
def = this->add("filament_max_volumetric_speed", coFloats);
@@ -1077,13 +1125,13 @@ void PrintConfigDef::init_fff_params()
def = this->add("filament_minimal_purge_on_wipe_tower", coFloats);
def->label = L("Minimal purge on wipe tower");
- //def->tooltip = L("After a tool change, the exact position of the newly loaded filament inside "
- // "the nozzle may not be known, and the filament pressure is likely not yet stable. "
- // "Before purging the print head into an infill or a sacrificial object, Slic3r will always prime "
- // "this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably.");
+ def->tooltip = L("After a tool change, the exact position of the newly loaded filament inside "
+ "the nozzle may not be known, and the filament pressure is likely not yet stable. "
+ "Before purging the print head into an infill or a sacrificial object, Slic3r will always prime "
+ "this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably.");
def->sidetext = L("mm³");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 15. });
def = this->add("machine_load_filament_time", coFloat);
@@ -1139,13 +1187,13 @@ void PrintConfigDef::init_fff_params()
def = this->add("filament_soluble", coBools);
def->label = L("Soluble material");
def->tooltip = L("Soluble material is commonly used to print support and support interface");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBools { false });
def = this->add("filament_is_support", coBools);
def->label = L("Support material");
def->tooltip = L("Support material is commonly used to print support and support interface");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBools { false });
// BBS
@@ -1186,6 +1234,16 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(45));
+ def = this->add("bridge_angle", coFloat);
+ def->label = L("Bridge infill direction");
+ def->category = L("Strength");
+ def->tooltip = L("Angle for bridge infill pattern, which controls the start or main direction of line");
+ def->sidetext = L("°");
+ def->min = 0;
+ def->max = 360;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(0));
+
def = this->add("sparse_infill_density", coPercent);
def->label = L("Sparse infill density");
def->category = L("Strength");
@@ -1240,6 +1298,30 @@ void PrintConfigDef::init_fff_params()
#endif // HAS_LIGHTNING_INFILL
def->set_default_value(new ConfigOptionEnum(ipCubic));
+ def = this->add("outer_wall_acceleration", coFloat);
+ def->label = L("Outer wall");
+ def->tooltip = L("Acceleration of outer walls");
+ def->sidetext = L("mm/s²");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(10000));
+
+ def = this->add("inner_wall_acceleration", coFloat);
+ def->label = L("Inner wall");
+ def->tooltip = L("Acceleration of inner walls");
+ def->sidetext = L("mm/s²");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(10000));
+
+ def = this->add("travel_acceleration", coFloat);
+ def->label = L("Travel");
+ def->tooltip = L("Acceleration of travel moves");
+ def->sidetext = L("mm/s²");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(10000));
+
def = this->add("top_surface_acceleration", coFloat);
def->label = L("Top surface");
def->tooltip = L("Acceleration of top surface infill. Using a lower value may improve top surface quality");
@@ -1256,6 +1338,54 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(300));
+ def = this->add("default_jerk", coFloat);
+ def->label = L("Default");
+ def->tooltip = L("Default");
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(0));
+
+ def = this->add("outer_wall_jerk", coFloat);
+ def->label = L("Outer wall");
+ def->tooltip = L("Jerk of outer walls");
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(9));
+
+ def = this->add("inner_wall_jerk", coFloat);
+ def->label = L("Inner wall");
+ def->tooltip = L("Jerk of inner walls");
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(9));
+
+ def = this->add("top_surface_jerk", coFloat);
+ def->label = L("Top surface");
+ def->tooltip = L("Jerk for top surface");
+ def->sidetext = L("mm/s");
+ def->min = 1;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(9));
+
+ def = this->add("initial_layer_jerk", coFloat);
+ def->label = L("Initial layer");
+ def->tooltip = L("Jerk for initial layer");
+ def->sidetext = L("mm/s");
+ def->min = 1;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(9));
+
+ def = this->add("travel_jerk", coFloat);
+ def->label = L("Travel");
+ def->tooltip = L("Jerk for travel");
+ def->sidetext = L("mm/s");
+ def->min = 1;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(12));
+
def = this->add("initial_layer_line_width", coFloat);
def->label = L("Initial layer");
def->category = L("Quality");
@@ -1338,7 +1468,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("The width within which to jitter. It's adversed to be below outer wall line width");
def->sidetext = L("mm");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.3));
def = this->add("fuzzy_skin_point_distance", coFloat);
@@ -1346,7 +1476,7 @@ void PrintConfigDef::init_fff_params()
def->category = L("Others");
def->tooltip = L("The average diatance between the random points introducded on each line segment");
def->sidetext = L("mm");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.8));
def = this->add("gap_infill_speed", coFloat);
@@ -1376,7 +1506,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("scan_first_layer", coBool);
def->label = L("Scan first layer");
def->tooltip = L("Enable this to enable the camera on printer to check the quality of first layer");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
//BBS
// def = this->add("spaghetti_detector", coBool);
@@ -1398,13 +1528,13 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back(L("Hardened steel"));
def->enum_labels.push_back(L("Stainless steel"));
def->enum_labels.push_back(L("Brass"));
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum(ntUndefine));
def = this->add("auxiliary_fan", coBool);
def->label = L("Auxiliary part cooling fan");
def->tooltip = L("Enable this option if machine has auxiliary part cooling fan");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
def = this->add("gcode_flavor", coEnum);
@@ -1412,7 +1542,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("What kind of gcode the printer is compatible with");
def->enum_keys_map = &ConfigOptionEnum::get_enum_values();
def->enum_values.push_back("marlin");
- //def->enum_values.push_back("reprap");
+ def->enum_values.push_back("klipper");
//def->enum_values.push_back("reprapfirmware");
//def->enum_values.push_back("repetier");
//def->enum_values.push_back("teacup");
@@ -1435,6 +1565,7 @@ void PrintConfigDef::init_fff_params()
//def->enum_labels.push_back("Machinekit");
//def->enum_labels.push_back("Smoothie");
//def->enum_labels.push_back(L("No extrusion"));
+ def->enum_labels.push_back(L("Klipper"));
def->mode = comAdvanced;
def->readonly = false;
def->set_default_value(new ConfigOptionEnum(gcfMarlinLegacy));
@@ -1500,13 +1631,13 @@ void PrintConfigDef::init_fff_params()
def->cli = ConfigOptionDef::nocli;
def = this->add("interface_shells", coBool);
- //def->label = L("Interface shells");
+ def->label = L("Interface shells");
def->label = "Interface shells";
- //def->tooltip = L("Force the generation of solid shells between adjacent materials/volumes. "
- // "Useful for multi-extruder prints with translucent materials or manual soluble "
- // "support material");
+ def->tooltip = L("Force the generation of solid shells between adjacent materials/volumes. "
+ "Useful for multi-extruder prints with translucent materials or manual soluble "
+ "support material");
def->category = L("Quality");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
def = this->add("ironing_type", coEnum);
@@ -1554,7 +1685,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Print speed of ironing lines");
def->sidetext = L("mm/s");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(20));
def = this->add("layer_change_gcode", coString);
@@ -1715,7 +1846,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Maximum acceleration for travel (M204 T)");
def->sidetext = L("mm/s²");
def->min = 0;
- def->readonly = true;
+ def->readonly = false;
def->mode = comDevelop;
def->set_default_value(new ConfigOptionFloats{ 1500., 1250. });
@@ -1735,7 +1866,7 @@ void PrintConfigDef::init_fff_params()
"the maximum layer hight when enable adaptive layer height");
def->sidetext = L("mm");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0. });
#ifdef HAS_PRESSURE_EQUALIZER
@@ -1787,7 +1918,7 @@ void PrintConfigDef::init_fff_params()
"the minimum layer hight when enable adaptive layer height");
def->sidetext = L("mm");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0.07 });
def = this->add("slow_down_min_speed", coFloats);
@@ -1795,44 +1926,45 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("The minimum printing speed when slow down for cooling");
def->sidetext = L("mm/s");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 10. });
def = this->add("nozzle_diameter", coFloats);
def->label = L("Nozzle diameter");
def->tooltip = L("Diameter of nozzle");
def->sidetext = L("mm");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0.4 });
def = this->add("host_type", coEnum);
def->label = L("Host Type");
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field must contain "
- "the kind of the host.");
+ "the kind of the host.");
def->enum_keys_map = &ConfigOptionEnum::get_enum_values();
def->enum_values.push_back("prusalink");
def->enum_values.push_back("octoprint");
- //def->enum_values.push_back("duet");
- //def->enum_values.push_back("flashair");
- //def->enum_values.push_back("astrobox");
- //def->enum_values.push_back("repetier");
- //def->enum_values.push_back("mks");
+ def->enum_values.push_back("duet");
+ def->enum_values.push_back("flashair");
+ def->enum_values.push_back("astrobox");
+ def->enum_values.push_back("repetier");
+ def->enum_values.push_back("mks");
def->enum_labels.push_back("PrusaLink");
def->enum_labels.push_back("OctoPrint");
- //def->enum_labels.push_back("Duet");
- //def->enum_labels.push_back("FlashAir");
- //def->enum_labels.push_back("AstroBox");
- //def->enum_labels.push_back("Repetier");
- //def->enum_labels.push_back("MKS");
+ def->enum_labels.push_back("Duet");
+ def->enum_labels.push_back("FlashAir");
+ def->enum_labels.push_back("AstroBox");
+ def->enum_labels.push_back("Repetier");
+ def->enum_labels.push_back("MKS");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionEnum(htOctoPrint));
+
def = this->add("nozzle_volume", coFloat);
def->label = L("Nozzle volume");
def->tooltip = L("Volume of nozzle between the cutter and the end of nozzle");
def->sidetext = L("mm³");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->readonly = true;
def->set_default_value(new ConfigOptionFloat { 0.0 });
@@ -1856,15 +1988,15 @@ void PrintConfigDef::init_fff_params()
def->label = L("Filename format");
def->tooltip = L("User can self-define the project file name when export");
def->full_width = true;
- def->mode = comDevelop;
- def->set_default_value(new ConfigOptionString("[input_filename_base].gcode"));
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionString("{input_filename_base}_{filament_type[0]}_{print_time}.gcode"));
def = this->add("detect_overhang_wall", coBool);
def->label = L("Detect overhang wall");
def->category = L("Quality");
def->tooltip = L("Detect the overhang percentage relative to line width and use different speed to print. "
"For 100%% overhang, bridge speed is used.");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(true));
def = this->add("wall_filament", coInt);
@@ -1936,7 +2068,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Z gap between object and raft. Ignored for soluble interface");
def->sidetext = L("mm");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.1));
def = this->add("raft_expansion", coFloat);
@@ -1945,7 +2077,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Expand all raft layers in XY plane");
def->sidetext = L("mm");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(1.5));
def = this->add("raft_first_layer_density", coPercent);
@@ -1955,7 +2087,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("%");
def->min = 10;
def->max = 100;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercent(90));
def = this->add("raft_first_layer_expansion", coFloat);
@@ -1964,7 +2096,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Expand the first raft or support layer to improve bed plate adhesion");
def->sidetext = L("mm");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
//BBS: change from 3.0 to 2.0
def->set_default_value(new ConfigOptionFloat(2.0));
@@ -1976,7 +2108,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("layers");
def->min = 0;
def->max = 100;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(0));
def = this->add("resolution", coFloat);
@@ -1999,7 +2131,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Retract amount before wipe");
def->tooltip = L("The length of fast retraction before wipe, relative to retraction length");
def->sidetext = L("%");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercents { 100 });
def = this->add("retract_when_changing_layer", coBools);
@@ -2025,7 +2157,7 @@ void PrintConfigDef::init_fff_params()
// "by the specified amount (the length is measured on raw filament, before it enters "
// "the extruder).");
def->sidetext = L("mm");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 10. });
def = this->add("z_hop", coFloats);
@@ -2038,21 +2170,21 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloats { 0.4 });
def = this->add("retract_restart_extra", coFloats);
- //def->label = L("Extra length on restart");
+ def->label = L("Extra length on restart");
def->label = "Extra length on restart";
- //def->tooltip = L("When the retraction is compensated after the travel move, the extruder will push "
- // "this additional amount of filament. This setting is rarely needed.");
+ def->tooltip = L("When the retraction is compensated after the travel move, the extruder will push "
+ "this additional amount of filament. This setting is rarely needed.");
def->sidetext = L("mm");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0. });
def = this->add("retract_restart_extra_toolchange", coFloats);
- //def->label = L("Extra length on restart");
+ def->label = L("Extra length on restart");
def->label = "Extra length on restart";
- //def->tooltip = L("When the retraction is compensated after changing tool, the extruder will push "
- // "this additional amount of filament.");
+ def->tooltip = L("When the retraction is compensated after changing tool, the extruder will push "
+ "this additional amount of filament.");
def->sidetext = L("mm");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0. });
def = this->add("retraction_speed", coFloats);
@@ -2093,7 +2225,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("mm");
def->min = 0;
def->max = 10;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(2));
def = this->add("skirt_height", coInt);
@@ -2101,7 +2233,7 @@ void PrintConfigDef::init_fff_params()
def->label = "Skirt height";
//def->tooltip = L("How many layers of skirt. Usually only one layer");
def->sidetext = L("layers");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->max = 10000;
def->set_default_value(new ConfigOptionInt(1));
@@ -2303,7 +2435,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("°");
def->min = 0;
def->max = 359;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));
def = this->add("support_on_build_plate_only", coBool);
@@ -2419,7 +2551,7 @@ void PrintConfigDef::init_fff_params()
//TRN To be shown in Print Settings "Bottom interface layers". Have to be as short as possible
def->enum_labels.push_back("-1");
append(def->enum_labels, support_interface_top_layers->enum_labels);
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(0));
def = this->add("support_interface_spacing", coFloat);
@@ -2438,7 +2570,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Spacing of bottom interface lines. Zero means solid interface");
def->sidetext = L("mm");
def->min = 0;
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.5));
def = this->add("support_interface_speed", coFloat);
@@ -2515,7 +2647,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("snug");
def->enum_labels.push_back(L("Grid"));
def->enum_labels.push_back(L("Snug"));
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum(smsGrid));
def = this->add("independent_support_layer_height", coBool);
@@ -2581,6 +2713,15 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
+ def = this->add("chamber_temperature", coInt);
+ def->label = L("Chamber temperature");
+ def->tooltip = L("Target chamber temperature");
+ def->sidetext = L("°C");
+ def->full_label = L("Chamber temperature");
+ def->min = 0;
+ def->max = max_temp;
+ def->set_default_value(new ConfigOptionInt(0));
+
def = this->add("nozzle_temperature", coInts);
def->label = L("Other layers");
def->tooltip = L("Nozzle temperature for layers after the initial one");
@@ -2697,6 +2838,19 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBools { false });
+ def = this->add("z_lift_type", coEnum);
+ def->label = L("Z hop type");
+ def->tooltip = L("Z hop type");
+ def->enum_keys_map = &ConfigOptionEnum::get_enum_values();
+ def->enum_values.push_back("NormalLift");
+ def->enum_values.push_back("SpiralLift");
+ // def->enum_values.push_back("LazyLift");
+ def->enum_labels.push_back(L("NormalLift"));
+ def->enum_labels.push_back(L("SpiralLift"));
+ // def->enum_labels.push_back(L("LazyLift"));
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionEnum(LiftType::SpiralLift));
+
def = this->add("wipe_distance", coFloats);
def->label = L("Wipe Distance");
def->tooltip = L("Discribe how long the nozzle will move along the last path when retracting");
@@ -2735,7 +2889,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Flush multiplier");
def->tooltip = L("");
def->sidetext = L("");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->min = 0;
def->set_default_value(new ConfigOptionFloat(1.0));
@@ -2836,6 +2990,13 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));
+ def = this->add("thumbnails", coPoints);
+ def->label = L("G-code thumbnails");
+ def->tooltip = L("Picture sizes to be stored into a .gcode and .sl1 / .sl1s files, in the following format: \"XxY, XxY, ...\"");
+ def->mode = comAdvanced;
+ def->gui_type = ConfigOptionDef::GUIType::one_string;
+ def->set_default_value(new ConfigOptionPoints{Vec2d(300, 300)});
+
// Declare retract values for filament profile, overriding the printer's extruder profile.
for (const char *opt_key : {
// floats
@@ -2857,8 +3018,6 @@ void PrintConfigDef::init_fff_params()
if ((strcmp(opt_key, "retraction_length") == 0) ||
(strcmp(opt_key, "z_hop") == 0))
def->mode = comSimple;
- else if (strcmp(opt_key, "retract_before_wipe") == 0)
- def->mode = comDevelop;
else
def->mode = comAdvanced;
switch (def->type) {
@@ -2875,7 +3034,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("This option will auto detect narrow internal solid infill area."
" If enabled, concentric pattern will be used for the area to speed printing up."
" Otherwise, rectilinear pattern is used defaultly.");
- def->mode = comDevelop;
+ def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(true));
}
@@ -3629,7 +3788,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
static std::set ignore = {
"acceleration", "scale", "rotate", "duplicate", "duplicate_grid",
"bed_size",
- "print_center", "g0", "pressure_advance", "wipe_tower_per_color_wipe"
+ "print_center", "g0", "wipe_tower_per_color_wipe"
#ifndef HAS_PRESSURE_EQUALIZER
, "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative"
#endif /* HAS_PRESSURE_EQUALIZER */
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 146f27e766..533e4823f3 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -32,8 +32,8 @@
namespace Slic3r {
enum GCodeFlavor : unsigned char {
- gcfMarlinLegacy, gcfRepRapSprinter, gcfRepRapFirmware, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlinFirmware, gcfSailfish, gcfMach3, gcfMachinekit,
- gcfSmoothie, gcfNoExtrusion,
+ gcfMarlinLegacy, gcfKlipper, gcfRepRapSprinter, gcfRepRapFirmware, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlinFirmware, gcfSailfish, gcfMach3, gcfMachinekit,
+ gcfSmoothie, gcfNoExtrusion
};
enum class FuzzySkinType {
@@ -118,6 +118,12 @@ enum SeamPosition {
spNearest, spAligned, spRear, spRandom
};
+enum LiftType {
+ NormalLift,
+ SpiralLift,
+ LazyLift
+};
+
enum SLAMaterial {
slamTough,
slamFlex,
@@ -658,7 +664,10 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, bottom_shell_thickness))
((ConfigOptionFloat, bridge_flow))
((ConfigOptionFloat, bridge_speed))
+ ((ConfigOptionFloat, bridge_angle))
((ConfigOptionEnum, top_surface_pattern))
+ ((ConfigOptionFloat, top_solid_infill_flow_ratio))
+ ((ConfigOptionFloat, bottom_solid_infill_flow_ratio))
((ConfigOptionEnum, bottom_surface_pattern))
((ConfigOptionFloat, outer_wall_line_width))
((ConfigOptionFloat, outer_wall_speed))
@@ -705,6 +714,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, overhang_3_4_speed))
((ConfigOptionFloat, overhang_4_4_speed))
((ConfigOptionBool, only_one_wall_top))
+ ((ConfigOptionBool, only_one_wall_first_layer))
)
PRINT_CONFIG_CLASS_DEFINE(
@@ -748,6 +758,8 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionString, machine_end_gcode))
((ConfigOptionStrings, filament_end_gcode))
((ConfigOptionFloats, filament_flow_ratio))
+ ((ConfigOptionBool, enable_pressure_advance))
+ ((ConfigOptionFloats, pressure_advance))
((ConfigOptionFloats, filament_diameter))
((ConfigOptionFloats, filament_density))
((ConfigOptionStrings, filament_type))
@@ -774,6 +786,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloats, retraction_length))
((ConfigOptionFloats, retract_length_toolchange))
((ConfigOptionFloats, z_hop))
+ ((ConfigOptionEnum, z_lift_type))
((ConfigOptionFloats, retract_restart_extra))
((ConfigOptionFloats, retract_restart_extra_toolchange))
((ConfigOptionFloats, retraction_speed))
@@ -790,6 +803,7 @@ PRINT_CONFIG_CLASS_DEFINE(
//BBS
((ConfigOptionEnum, nozzle_type))
((ConfigOptionBool, auxiliary_fan))
+
)
// This object is mapped to Perl as Slic3r::Config::Print.
@@ -830,11 +844,21 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionBools, reduce_fan_stop_start_freq))
((ConfigOptionInts, fan_cooling_layer_time))
((ConfigOptionStrings, filament_colour))
+ ((ConfigOptionFloat, outer_wall_acceleration))
+ ((ConfigOptionFloat, inner_wall_acceleration))
((ConfigOptionFloat, top_surface_acceleration))
((ConfigOptionFloat, initial_layer_acceleration))
+ ((ConfigOptionFloat, travel_acceleration))
((ConfigOptionFloat, initial_layer_line_width))
((ConfigOptionFloat, initial_layer_print_height))
((ConfigOptionFloat, initial_layer_speed))
+ ((ConfigOptionFloat, default_jerk))
+ ((ConfigOptionFloat, outer_wall_jerk))
+ ((ConfigOptionFloat, inner_wall_jerk))
+ ((ConfigOptionFloat, top_surface_jerk))
+ ((ConfigOptionFloat, initial_layer_jerk))
+ ((ConfigOptionFloat, travel_jerk))
+
//BBS
((ConfigOptionFloat, initial_layer_infill_speed))
((ConfigOptionInts, nozzle_temperature_initial_layer))
@@ -861,6 +885,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionBool, spiral_mode))
((ConfigOptionInt, standby_temperature_delta))
((ConfigOptionInts, nozzle_temperature))
+ ((ConfigOptionInt , chamber_temperature))
((ConfigOptionBools, wipe))
// BBS
((ConfigOptionInts, bed_temperature_difference))
@@ -888,7 +913,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionBool, has_prime_tower))
((ConfigOptionFloat, nozzle_volume))
((ConfigOptionEnum, timelapse_type))
-
+ ((ConfigOptionPoints, thumbnails))
)
// This object is mapped to Perl as Slic3r::Config::Full.
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 98f642a9f7..eca777cbb3 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -667,6 +667,7 @@ bool PrintObject::invalidate_state_by_config_options(
} else if (
opt_key == "wall_loops"
|| opt_key == "only_one_wall_top"
+ || opt_key == "only_one_wall_first_layer"
|| opt_key == "initial_layer_line_width"
|| opt_key == "inner_wall_line_width"
|| opt_key == "infill_wall_overlap") {
@@ -762,13 +763,15 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "minimum_sparse_infill_area"
|| opt_key == "sparse_infill_filament"
|| opt_key == "solid_infill_filament"
- || opt_key == "sparse_infill_line_width") {
+ || opt_key == "sparse_infill_line_width"
+ || opt_key == "infill_direction"
+ || opt_key == "bridge_angle") {
steps.emplace_back(posPrepareInfill);
} else if (
opt_key == "top_surface_pattern"
|| opt_key == "bottom_surface_pattern"
|| opt_key == "external_fill_link_max_length"
- || opt_key == "infill_direction"
+ || opt_key == "sparse_infill_pattern"
|| opt_key == "top_surface_line_width"
|| opt_key == "initial_layer_line_width") {
steps.emplace_back(posInfill);
diff --git a/src/libslic3r/PrintRegion.cpp b/src/libslic3r/PrintRegion.cpp
index 0f9f92e488..2dfc5826ae 100644
--- a/src/libslic3r/PrintRegion.cpp
+++ b/src/libslic3r/PrintRegion.cpp
@@ -22,10 +22,15 @@ Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_he
{
const PrintConfig &print_config = object.print()->config();
ConfigOptionFloat config_width;
+ double flow_ratio = 1.0;
// Get extrusion width from configuration.
// (might be an absolute value, or a percent value, or zero for auto)
- if (first_layer && print_config.initial_layer_line_width.value > 0) {
- config_width = print_config.initial_layer_line_width;
+ if (first_layer) {
+ if(role != frExternalPerimeter)
+ flow_ratio = m_config.bottom_solid_infill_flow_ratio;
+ if(print_config.initial_layer_line_width.value > 0) {
+ config_width = print_config.initial_layer_line_width;
+ }
} else if (role == frExternalPerimeter) {
config_width = m_config.outer_wall_line_width;
} else if (role == frPerimeter) {
@@ -36,6 +41,7 @@ Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_he
config_width = m_config.internal_solid_infill_line_width;
} else if (role == frTopSolidInfill) {
config_width = m_config.top_surface_line_width;
+ flow_ratio = m_config.top_solid_infill_flow_ratio;
} else {
throw Slic3r::InvalidArgument("Unknown role");
}
@@ -46,7 +52,7 @@ Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_he
// Get the configured nozzle_diameter for the extruder associated to the flow role requested.
// Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right.
auto nozzle_diameter = float(print_config.nozzle_diameter.get_at(this->extruder(role) - 1));
- return Flow::new_from_config_width(role, config_width, nozzle_diameter, float(layer_height));
+ return Flow::new_from_config_width(role, config_width, nozzle_diameter, float(layer_height)).with_flow_ratio(flow_ratio);
}
coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
diff --git a/src/libslic3r/libslic3r_version.h.in b/src/libslic3r/libslic3r_version.h.in
index 15f5803db5..d05746b8e8 100644
--- a/src/libslic3r/libslic3r_version.h.in
+++ b/src/libslic3r/libslic3r_version.h.in
@@ -4,6 +4,7 @@
#define SLIC3R_APP_NAME "@SLIC3R_APP_NAME@"
#define SLIC3R_APP_KEY "@SLIC3R_APP_KEY@"
#define SLIC3R_VERSION "@SLIC3R_VERSION@"
+#define SoftFever_VERSION "@SoftFever_VERSION@"
#define SLIC3R_BUILD_ID "@SLIC3R_BUILD_ID@"
//#define SLIC3R_RC_VERSION "@SLIC3R_VERSION@"
#define BBL_RELEASE_TO_PUBLIC @BBL_RELEASE_TO_PUBLIC@
diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp
index 731848ed55..0e1565117e 100644
--- a/src/libslic3r/utils.cpp
+++ b/src/libslic3r/utils.cpp
@@ -1106,7 +1106,7 @@ std::string string_printf(const char *format, ...)
std::string header_slic3r_generated()
{
- return std::string(SLIC3R_APP_NAME " " SLIC3R_VERSION);
+ return std::string(SLIC3R_APP_NAME "-SoftFever" " " SLIC3R_VERSION);
}
std::string header_gcodeviewer_generated()
diff --git a/src/minilzo/CMakeLists.txt b/src/minilzo/CMakeLists.txt
index c5122ccf0f..d23e871472 100644
--- a/src/minilzo/CMakeLists.txt
+++ b/src/minilzo/CMakeLists.txt
@@ -1,5 +1,5 @@
project(minilzo)
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 3.0)
add_library(minilzo INTERFACE)
diff --git a/src/qhull/CMakeLists.txt b/src/qhull/CMakeLists.txt
index ab9aba9afa..6f0e090dc7 100644
--- a/src/qhull/CMakeLists.txt
+++ b/src/qhull/CMakeLists.txt
@@ -28,7 +28,7 @@ endif()
else(Qhull_FOUND)
project(qhull)
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 3.1)
# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri
set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 56cff773cf..c55d867649 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -181,6 +181,10 @@ set(SLIC3R_GUI_SOURCES
GUI/SavePresetDialog.cpp
GUI/GUI_Colors.hpp
GUI/GUI_Colors.cpp
+ GUI/PhysicalPrinterDialog.hpp
+ GUI/PhysicalPrinterDialog.cpp
+ GUI/PrintHostDialogs.cpp
+ GUI/PrintHostDialogs.hpp
GUI/GUI_Factories.cpp
GUI/GUI_Factories.hpp
GUI/GUI_ObjectList.cpp
@@ -231,6 +235,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Monitor.hpp
GUI/WebViewDialog.cpp
GUI/WebViewDialog.hpp
+ GUI/PrinterWebView.cpp
+ GUI/PrinterWebView.hpp
GUI/WebDownPluginDlg.hpp
GUI/WebDownPluginDlg.cpp
GUI/WebGuideDialog.hpp
@@ -368,6 +374,10 @@ set(SLIC3R_GUI_SOURCES
GUI/Calibration.cpp
GUI/PrintOptionsDialog.hpp
GUI/PrintOptionsDialog.cpp
+ GUI/BonjourDialog.hpp
+ GUI/BonjourDialog.cpp
+ GUI/BedShapeDialog.hpp
+ GUI/BedShapeDialog.cpp
Utils/json_diff.hpp
Utils/json_diff.cpp
GUI/KBShortcutsDialog.hpp
@@ -399,6 +409,22 @@ set(SLIC3R_GUI_SOURCES
Utils/PrintHost.cpp
Utils/NetworkAgent.cpp
Utils/NetworkAgent.hpp
+ Utils/OctoPrint.cpp
+ Utils/OctoPrint.hpp
+ Utils/PrintHost.cpp
+ Utils/PrintHost.hpp
+ Utils/Serial.cpp
+ Utils/Serial.hpp
+ Utils/MKS.hpp
+ Utils/MKS.cpp
+ Utils/Duet.cpp
+ Utils/Duet.hpp
+ Utils/FlashAir.cpp
+ Utils/FlashAir.hpp
+ Utils/AstroBox.cpp
+ Utils/AstroBox.hpp
+ Utils/Repetier.cpp
+ Utils/Repetier.hpp
)
if (APPLE)
diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp
index 2a09ae1805..9b03cfe15b 100644
--- a/src/slic3r/GUI/AboutDialog.cpp
+++ b/src/slic3r/GUI/AboutDialog.cpp
@@ -244,11 +244,8 @@ AboutDialog::AboutDialog()
// version
{
vesizer->Add(0, FromDIP(165), 1, wxEXPAND, FromDIP(5));
-#if BBL_INTERNAL_TESTING
- auto version_string = _L("Internal Version") + " " + std::string(SLIC3R_VERSION);
-#else
- auto version_string = _L("Version") + " " + std::string(SLIC3R_VERSION);
-#endif
+
+ auto version_string = _L("SoftFever Version") + " " + std::string(SoftFever_VERSION);
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
wxFont version_font = GetFont();
#ifdef __WXMSW__
diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp
index 801a5a6862..b7b02be750 100644
--- a/src/slic3r/GUI/BBLTopbar.cpp
+++ b/src/slic3r/GUI/BBLTopbar.cpp
@@ -250,13 +250,13 @@ void BBLTopbar::Init(wxFrame* parent)
this->AddSpacer(FromDIP(10));
this->AddStretchSpacer(1);
-#if !BBL_RELEASE_TO_PUBLIC
+// #if !BBL_RELEASE_TO_PUBLIC
/*wxBitmap m_publish_bitmap = create_scaled_bitmap("topbar_publish", nullptr, TOPBAR_ICON_SIZE);
m_publish_item = this->AddTool(ID_PUBLISH, "", m_publish_bitmap);
wxBitmap m_publish_disable_bitmap = create_scaled_bitmap("topbar_publish_disable", nullptr, TOPBAR_ICON_SIZE);
m_publish_item->SetDisabledBitmap(m_publish_disable_bitmap);
this->AddSpacer(FromDIP(12));*/
-#endif
+// #endif
/*wxBitmap model_store_bitmap = create_scaled_bitmap("topbar_store", nullptr, TOPBAR_ICON_SIZE);
m_model_store_item = this->AddTool(ID_MODEL_STORE, "", model_store_bitmap);
diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
index 6da922ce48..55ce786201 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
@@ -183,6 +183,13 @@ std::string BackgroundSlicingProcess::output_filepath_for_project(const boost::f
void BackgroundSlicingProcess::process_fff()
{
assert(m_print == m_fff_print);
+ PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
+
+ m_fff_print->is_BBL_printer() =
+ preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(
+ &preset_bundle);
+
+
//BBS: add the logic to process from an existed gcode file
if (m_print->finished()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: skip slicing, to process previous gcode file")%__LINE__;
@@ -837,8 +844,9 @@ void BackgroundSlicingProcess::prepare_upload()
m_upload_job.upload_data.upload_path = output_name_str;
} else {
m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
+
ThumbnailsList thumbnails = this->render_thumbnails(
- ThumbnailsParams{current_print()->full_print_config().option("thumbnails")->values, true, true, true, true});
+ ThumbnailsParams{current_print()->full_print_config().option("thumbnails")->values, true, true, true, true});
// true, false, true, true); // renders also supports and pad
Zipper zipper{source_path.string()};
m_sla_archive.export_print(zipper, *m_sla_print, m_upload_job.upload_data.upload_path.string());
diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp
index 246c8b63e3..e8713a775a 100644
--- a/src/slic3r/GUI/BedShapeDialog.cpp
+++ b/src/slic3r/GUI/BedShapeDialog.cpp
@@ -56,6 +56,7 @@ void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter para
def.max = 600;
def.label = get_option_label(param);
def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle.");
+ def.readonly = true;
key = "rect_origin";
break;
case Parameter::Diameter:
@@ -191,9 +192,9 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
BedShape::append_option_line(optgroup, BedShape::Parameter::RectOrigin);
activate_options_page(optgroup);
- optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Circle));
- BedShape::append_option_line(optgroup, BedShape::Parameter::Diameter);
- activate_options_page(optgroup);
+ // optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Circle));
+ // BedShape::append_option_line(optgroup, BedShape::Parameter::Diameter);
+ // activate_options_page(optgroup);
optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Custom));
diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp
index ca37795489..24a7388e71 100644
--- a/src/slic3r/GUI/Camera.cpp
+++ b/src/slic3r/GUI/Camera.cpp
@@ -554,17 +554,14 @@ void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up
void Camera::set_default_orientation()
{
- // BBS modify default orientation
- look_at(m_target - 0.707 * m_distance * Vec3d::UnitY() + 0.707 * m_distance * Vec3d::UnitZ(), m_target, Vec3d::UnitY() + Vec3d::UnitZ());
-
- /*m_zenit = 45.0f;
+ m_zenit = 45.0f;
const double theta_rad = Geometry::deg2rad(-(double)m_zenit);
const double phi_rad = Geometry::deg2rad(45.0);
const double sin_theta = ::sin(theta_rad);
const Vec3d camera_pos = m_target + m_distance * Vec3d(sin_theta * ::sin(phi_rad), sin_theta * ::cos(phi_rad), ::cos(theta_rad));
m_view_rotation = Eigen::AngleAxisd(theta_rad, Vec3d::UnitX()) * Eigen::AngleAxisd(phi_rad, Vec3d::UnitZ());
m_view_rotation.normalize();
- m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-camera_pos), m_view_rotation, Vec3d::Ones());*/
+ m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-camera_pos), m_view_rotation, Vec3d::Ones());
}
Vec3d Camera::validate_target(const Vec3d& target) const
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index b11def56c7..b7f28d73c2 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -469,7 +469,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_field(el, has_solid_infill);
for (auto el : { "infill_direction", "sparse_infill_line_width",
- "sparse_infill_speed", "bridge_speed" })
+ "sparse_infill_speed", "bridge_speed", "bridge_angle" })
toggle_field(el, have_infill || has_solid_infill);
toggle_field("top_shell_thickness", ! has_spiral_vase && has_top_solid_infill);
@@ -483,9 +483,14 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
bool have_default_acceleration = config->opt_float("default_acceleration") > 0;
//BBS
- for (auto el : { "initial_layer_acceleration", "top_surface_acceleration" })
+ for (auto el : { "outer_wall_acceleration", "inner_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration","travel_acceleration" })
toggle_field(el, have_default_acceleration);
+ bool have_default_jerk = config->opt_float("default_jerk") > 0;
+
+ for (auto el : { "outer_wall_jerk", "inner_wall_jerk", "initial_layer_jerk", "top_surface_jerk","travel_jerk" })
+ toggle_field(el, have_default_jerk);
+
bool have_skirt = config->opt_int("skirt_loops") > 0;
toggle_field("skirt_height", have_skirt && config->opt_enum("draft_shield") != dsEnabled);
for (auto el : { "skirt_distance", "draft_shield"})
diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp
index 165778584c..1b4c09136b 100644
--- a/src/slic3r/GUI/ConfigWizard.cpp
+++ b/src/slic3r/GUI/ConfigWizard.cpp
@@ -2394,7 +2394,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
p->load_vendors();
//BBS: add bed exclude areas
p->custom_config.reset(DynamicPrintConfig::new_from_defaults_keys({
- "gcode_flavor", "printable_area", "bed_exclude_area", "nozzle_diameter", "filament_diameter", "nozzle_temperature", /*"bed_temperature",*/
+ "gcode_flavor", "printable_area", "bed_exclude_area", "filament_diameter", "nozzle_temperature", "thumbnails"/*"bed_temperature",*/
}));
auto *vsizer = new wxBoxSizer(wxVERTICAL);
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 145b0a9f18..e932b867b0 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -4708,12 +4708,12 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
double width = volumes_box.max.x() - volumes_box.min.x();
double depth = volumes_box.max.y() - volumes_box.min.y();
double height = volumes_box.max.z() - volumes_box.min.z();
- volumes_box.max.x() = volumes_box.max.x() + width * 0.25f;
- volumes_box.min.x() = volumes_box.min.x() - width * 0.25f;
- volumes_box.max.y() = volumes_box.max.y() + depth * 0.25f;
- volumes_box.min.y() = volumes_box.min.y() - depth * 0.25f;
- volumes_box.max.z() = volumes_box.max.z() + height * 0.25f;
- volumes_box.min.z() = volumes_box.min.z() - height * 0.25f;
+ volumes_box.max.x() = volumes_box.max.x() + width * 0.05f;
+ volumes_box.min.x() = volumes_box.min.x() - width * 0.05f;
+ volumes_box.max.y() = volumes_box.max.y() + depth * 0.05f;
+ volumes_box.min.y() = volumes_box.min.y() - depth * 0.05f;
+ volumes_box.max.z() = volumes_box.max.z() + height * 0.05f;
+ volumes_box.min.z() = volumes_box.min.z() - height * 0.05f;
Camera camera;
camera.set_type(camera_type);
@@ -4728,16 +4728,11 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
camera.zoom_to_box(volumes_box);
const Vec3d& target = camera.get_target();
double distance = camera.get_distance();
- //camera.select_view("topfront");
- camera.look_at(target - 0.707 * distance * Vec3d::UnitY() + 0.3 * distance * Vec3d::UnitZ(), target, Vec3d::UnitY() + Vec3d::UnitZ());
+ camera.select_view("iso");
camera.apply_view_matrix();
camera.apply_projection(plate_build_volume);
- //double near_z = -1.0;
- //double far_z = -1.0;
- //camera.apply_projection(volumes_box, near_z, far_z);
-
//GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
if (shader == nullptr) {
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail: shader is null, return directly");
@@ -4745,7 +4740,7 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
}
//if (thumbnail_params.transparent_background)
- glsafe(::glClearColor(0.906f, 0.906f, 0.906f, 1.0f));
+ glsafe(::glClearColor(0.2f, 0.2f, 0.2f, 0.0f));
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
glsafe(::glEnable(GL_DEPTH_TEST));
diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp
index 4c302392b2..1d9fa035da 100644
--- a/src/slic3r/GUI/GUI.cpp
+++ b/src/slic3r/GUI/GUI.cpp
@@ -197,7 +197,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
}
break;
case coPoints:{
- if (opt_key == "printable_area" || opt_key == "bed_exclude_area") {
+ if (opt_key == "printable_area" || opt_key == "bed_exclude_area" || opt_key == "thumbnails") {
config.option(opt_key)->values = boost::any_cast>(value);
break;
}
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 435ef51042..c9f4ad8f20 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -280,14 +280,15 @@ public:
memDc.SetTextForeground(wxColor(134, 134, 134));
memDc.DrawLabel(m_constant_text.version, version_rect, wxALIGN_LEFT | wxALIGN_BOTTOM);
-#if BBL_INTERNAL_TESTING
- wxSize text_rect = memDc.GetTextExtent("Internal Version");
+// #if BBL_INTERNAL_TESTING
+ auto sf_version = wxString::Format("SoftFever %s",std::string(SoftFever_VERSION)).ToStdString();
+ wxSize text_rect = memDc.GetTextExtent(sf_version);
int start_x = (title_rect.GetLeft() + version_rect.GetRight()) / 2 - text_rect.GetWidth();
int start_y = version_rect.GetBottom() + 10;
wxRect internal_sign_rect(wxPoint(start_x, start_y), wxSize(text_rect));
- memDc.SetFont(m_constant_text.title_font);
- memDc.DrawLabel("Internal Version", internal_sign_rect, wxALIGN_TOP | wxALIGN_LEFT);
-#endif
+ memDc.SetFont(m_constant_text.version_font);
+ memDc.DrawLabel(sf_version, internal_sign_rect, wxALIGN_CENTER);
+// #endif
// load bitmap for logo
BitmapCache bmp_cache;
@@ -554,11 +555,11 @@ private:
title = wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME;
// dynamically get the version to display
-#if BBL_INTERNAL_TESTING
- version = _L("Internal Version") + " " + std::string(SLIC3R_VERSION);
-#else
- version = _L("Version") + " " + std::string(SLIC3R_VERSION);
-#endif
+// #if BBL_INTERNAL_TESTING
+ // version = _L("Internal Version") + " " + std::string(SLIC3R_VERSION);
+// #else
+ version = _L("SoftFever Version") + " " + std::string(SoftFever_VERSION);
+// #endif
// credits infornation
credits = title;
@@ -1812,7 +1813,7 @@ void GUI_App::init_download_path()
void GUI_App::init_app_config()
{
// Profiles for the alpha are stored into the PrusaSlicer-alpha directory to not mix with the current release.
- SetAppName(SLIC3R_APP_KEY);
+ SetAppName("BambuStudio-SoftFever");
// SetAppName(SLIC3R_APP_KEY "-alpha");
// SetAppName(SLIC3R_APP_KEY "-beta");
// SetAppDisplayName(SLIC3R_APP_NAME);
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index e5fcba012a..561c609db7 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -7,6 +7,7 @@
#include "ConfigWizard.hpp"
#include "OpenGLManager.hpp"
#include "libslic3r/Preset.hpp"
+#include "wxExtensions.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "slic3r/GUI/DeviceManager.hpp"
#include "slic3r/Utils/NetworkAgent.hpp"
@@ -45,6 +46,7 @@ class AppConfig;
class PresetBundle;
class PresetUpdater;
class ModelObject;
+// class PrintHostJobQueue;
class Model;
class DeviceManager;
class NetworkAgent;
diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp
index 5a3ff39590..be52035df8 100644
--- a/src/slic3r/GUI/GUI_Factories.cpp
+++ b/src/slic3r/GUI/GUI_Factories.cpp
@@ -94,7 +94,7 @@ std::map> SettingsFactory::PART_CAT
{ L("Strength"), {{"wall_loops", "",1},{"top_shell_layers", L("Top Solid Layers"),1},{"top_shell_thickness", L("Top Minimum Shell Thickness"),1},
{"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1},
{"sparse_infill_density", "",1},{"sparse_infill_pattern", "",1},{"top_surface_pattern", "",1},{"bottom_surface_pattern", "",1},
- {"infill_combination", "",1}, {"infill_wall_overlap", "",1}, {"infill_direction", "",1}, {"minimum_sparse_infill_area", "",1}
+ {"infill_combination", "",1}, {"infill_wall_overlap", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1}, {"minimum_sparse_infill_area", "",1}
}},
{ L("Speed"), {{"outer_wall_speed", "",1},{"inner_wall_speed", "",2},{"sparse_infill_speed", "",3},{"top_surface_speed", "",4}, {"internal_solid_infill_speed", "",5},
{"enable_overhang_speed", "",6}, {"overhang_1_4_speed", "",7}, {"overhang_2_4_speed", "",8}, {"overhang_3_4_speed", "",9}, {"overhang_4_4_speed", "",10},
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index c126ad771e..d61976afb8 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -73,6 +73,7 @@ wxDEFINE_EVENT(EVT_USER_LOGIN, wxCommandEvent);
// BBS: backup
wxDEFINE_EVENT(EVT_BACKUP_POST, wxCommandEvent);
wxDEFINE_EVENT(EVT_LOAD_URL, wxCommandEvent);
+wxDEFINE_EVENT(EVT_LOAD_PRINTER_URL, wxCommandEvent);
enum class ERescaleTarget
{
@@ -934,6 +935,13 @@ void MainFrame::init_tabpanel()
m_monitor = new MonitorPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_tabpanel->AddPage(m_monitor, _L("Device"), std::string("tab_monitor_active"), std::string("tab_monitor_active"));
+ m_printer_view = new PrinterWebView(m_tabpanel);
+ Bind(EVT_LOAD_PRINTER_URL, [this](wxCommandEvent &evt) {
+ wxString url = evt.GetString();
+ //select_tab(MainFrame::tpMonitor);
+ m_printer_view->load_url(url);
+ });
+
m_auxiliary = new AuxiliaryPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_tabpanel->AddPage(m_auxiliary, _L("Project"), std::string("tab_auxiliary_avtice"), std::string("tab_auxiliary_avtice"));
@@ -951,6 +959,33 @@ void MainFrame::init_tabpanel()
}
}
+ // SoftFever
+void MainFrame::show_device(bool bBBLPrinter) {
+ if (m_tabpanel->GetPage(3) != m_monitor &&
+ m_tabpanel->GetPage(3) != m_printer_view) {
+ BOOST_LOG_TRIVIAL(error) << "Failed to find device tab";
+ return;
+ }
+ if (bBBLPrinter) {
+ if (m_tabpanel->GetPage(3) != m_monitor) {
+ m_tabpanel->RemovePage(3);
+ m_tabpanel->InsertPage(3, m_monitor, _L("Device"),
+ std::string("tab_monitor_active"),
+ std::string("tab_monitor_active"));
+ }
+ } else {
+ if (m_tabpanel->GetPage(3) != m_printer_view) {
+ m_tabpanel->RemovePage(3);
+ m_tabpanel->InsertPage(3, m_printer_view, _L("Device"),
+ std::string("tab_monitor_active"),
+ std::string("tab_monitor_active"));
+ }
+ }
+
+
+}
+
+
#ifdef WIN32
void MainFrame::register_win32_callbacks()
{
@@ -2859,6 +2894,13 @@ void MainFrame::load_url(wxString url)
wxQueueEvent(this, evt);
}
+void MainFrame::load_printer_url(wxString url)
+{
+ BOOST_LOG_TRIVIAL(trace) << "load_printer_url:" << url;
+ auto evt = new wxCommandEvent(EVT_LOAD_PRINTER_URL, this->GetId());
+ evt->SetString(url);
+ wxQueueEvent(this, evt);
+}
void MainFrame::refresh_plugin_tips()
{
if (m_webview != nullptr)
diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp
index 416552743b..94841f09be 100644
--- a/src/slic3r/GUI/MainFrame.hpp
+++ b/src/slic3r/GUI/MainFrame.hpp
@@ -28,6 +28,8 @@
#include "BBLTopbar.hpp"
+#include "PrinterWebView.hpp"
+
#define ENABEL_PRINT_ALL 0
class Notebook;
@@ -307,9 +309,13 @@ public:
//BBS
void load_url(wxString url);
+ void load_printer_url(wxString url);
void refresh_plugin_tips();
void RunScript(wxString js);
+ //SoftFever
+ void show_device(bool bBBLPrinter);
+
// BBS. Replace title bar and menu bar with top bar.
BBLTopbar* m_topbar{ nullptr };
PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; }
@@ -318,6 +324,7 @@ public:
MonitorPanel* m_monitor{ nullptr };
AuxiliaryPanel* m_auxiliary{ nullptr };
WebViewPanel* m_webview { nullptr };
+ PrinterWebView* m_printer_view{nullptr};
wxLogWindow* m_log_window { nullptr };
// BBS
//wxBookCtrlBase* m_tabpanel { nullptr };
diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp
index ad1b8e1532..f90656410e 100644
--- a/src/slic3r/GUI/MsgDialog.cpp
+++ b/src/slic3r/GUI/MsgDialog.cpp
@@ -114,9 +114,13 @@ Button* MsgDialog::add_button(wxWindowID btn_id, bool set_focus /*= false*/, con
else if (label.length() >= 5 && label.length() < 8) {
type = ButtonSizeMiddle;
btn->SetMinSize(MSG_DIALOG_MIDDLE_BUTTON_SIZE);
+ }
+ else if (label.length() >= 8 && label.length() < 12) {
+ type = ButtonSizeMiddle;
+ btn->SetMinSize(MSG_DIALOG_LONG_BUTTON_SIZE);
} else {
type = ButtonSizeLong;
- btn->SetMinSize(MSG_DIALOG_LONG_BUTTON_SIZE);
+ btn->SetMinSize(MSG_DIALOG_LONGER_BUTTON_SIZE);
}
btn->SetCornerRadius(FromDIP(12));
diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp
index e00ce5689b..c6dc0b5637 100644
--- a/src/slic3r/GUI/MsgDialog.hpp
+++ b/src/slic3r/GUI/MsgDialog.hpp
@@ -29,6 +29,7 @@ enum ButtonSizeType{
#define MSG_DIALOG_BUTTON_SIZE wxSize(FromDIP(58), FromDIP(24))
#define MSG_DIALOG_MIDDLE_BUTTON_SIZE wxSize(FromDIP(76), FromDIP(24))
#define MSG_DIALOG_LONG_BUTTON_SIZE wxSize(FromDIP(90), FromDIP(24))
+#define MSG_DIALOG_LONGER_BUTTON_SIZE wxSize(FromDIP(120), FromDIP(24))
namespace Slic3r {
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 8bd9a4d3b4..46f880c3ae 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -670,7 +670,7 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
else if (m_opt_map.find(opt_key) == m_opt_map.end() ||
// This option don't have corresponded field
opt_key == "printable_area" ||
- opt_key == "compatible_printers" || opt_key == "compatible_prints" ) {
+ opt_key == "compatible_printers" || opt_key == "compatible_prints" || opt_key == "thumbnails" ) {
value = get_config_value(config, opt_key);
this->change_opt_value(opt_key, value);
return;
@@ -950,6 +950,14 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
case coInts:
ret = config.option(opt_key)->get_at(idx);
break;
+ case coPoints:
+ if (opt_key == "bed_shape")
+ ret = config.option(opt_key)->values;
+ else if (opt_key == "thumbnails")
+ ret = get_thumbnails_string(config.option(opt_key)->values);
+ else
+ ret = config.option(opt_key)->get_at(idx);
+ break;
default:
break;
}
@@ -1026,6 +1034,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
if (opt_key == "printable_area")
ret = config.option(opt_key)->values;
else if (opt_key == "bed_exclude_area")
+ ret = get_thumbnails_string(config.option(opt_key)->values);
+ else if (opt_key == "thumbnails")
ret = get_thumbnails_string(config.option(opt_key)->values);
else
ret = config.option(opt_key)->get_at(idx);
@@ -1137,6 +1147,8 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi
ret = config.option(opt_key)->values;
else if (opt_key == "bed_exclude_area")
ret = get_thumbnails_string(config.option(opt_key)->values);
+ else if (opt_key == "thumbnails")
+ ret = get_thumbnails_string(config.option(opt_key)->values);
else
ret = config.option(opt_key)->get_at(idx);
break;
diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp
index b0106a6a65..aca9071c48 100644
--- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp
+++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp
@@ -23,7 +23,7 @@
#include "format.hpp"
#include "Tab.hpp"
#include "wxExtensions.hpp"
-//#include "PrintHostDialogs.hpp"
+#include "PrintHostDialogs.hpp"
#include "../Utils/ASCIIFolding.hpp"
#include "../Utils/PrintHost.hpp"
#include "../Utils/FixModelByWin10.hpp"
@@ -189,7 +189,6 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
Option option = m_optgroup->get_option("print_host");
option.opt.width = Field::def_width_wider();
Line host_line = m_optgroup->create_single_option_line(option);
- //do not support now
host_line.append_widget(printhost_browse);
host_line.append_widget(print_host_test);
m_optgroup->append_line(host_line);
@@ -228,36 +227,36 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
};
cafile_line.append_widget(printhost_cafile_browse);
- //m_optgroup->append_line(cafile_line);
+ m_optgroup->append_line(cafile_line);
- /*Line cafile_hint{ "", "" };
+ Line cafile_hint{ "", "" };
cafile_hint.full_width = 1;
cafile_hint.widget = [ca_file_hint](wxWindow* parent) {
auto txt = new wxStaticText(parent, wxID_ANY, ca_file_hint);
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(txt);
return sizer;
- };*/
- //m_optgroup->append_line(cafile_hint);
+ };
+ m_optgroup->append_line(cafile_hint);
}
else {
- //Line line{ "", "" };
- //line.full_width = 1;
+ Line line{ "", "" };
+ line.full_width = 1;
- //line.widget = [ca_file_hint](wxWindow* parent) {
- // std::string info = _u8L("HTTPS CA File") + ":\n\t" +
- // (boost::format(_u8L("On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.")) % SLIC3R_APP_NAME).str() +
- // "\n\t" + _u8L("To use a custom CA file, please import your CA file into Certificate Store / Keychain.");
+ line.widget = [ca_file_hint](wxWindow* parent) {
+ std::string info = _u8L("HTTPS CA File") + ":\n\t" +
+ (boost::format(_u8L("On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.")) % SLIC3R_APP_NAME).str() +
+ "\n\t" + _u8L("To use a custom CA file, please import your CA file into Certificate Store / Keychain.");
- // //auto txt = new wxStaticText(parent, wxID_ANY, from_u8((boost::format("%1%\n\n\t%2%") % info % ca_file_hint).str()));
- // auto txt = new wxStaticText(parent, wxID_ANY, from_u8((boost::format("%1%\n\t%2%") % info % ca_file_hint).str()));
- // txt->SetFont(wxGetApp().normal_font());
- // auto sizer = new wxBoxSizer(wxHORIZONTAL);
- // sizer->Add(txt, 1, wxEXPAND);
- // return sizer;
- //};
- //m_optgroup->append_line(line);
+ //auto txt = new wxStaticText(parent, wxID_ANY, from_u8((boost::format("%1%\n\n\t%2%") % info % ca_file_hint).str()));
+ auto txt = new wxStaticText(parent, wxID_ANY, from_u8((boost::format("%1%\n\t%2%") % info % ca_file_hint).str()));
+ txt->SetFont(wxGetApp().normal_font());
+ auto sizer = new wxBoxSizer(wxHORIZONTAL);
+ sizer->Add(txt, 1, wxEXPAND);
+ return sizer;
+ };
+ m_optgroup->append_line(line);
}
for (const std::string& opt_key : std::vector{ "printhost_user", "printhost_password" }) {
@@ -267,13 +266,10 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
}
#ifdef WIN32
- /*
option = m_optgroup->get_option("printhost_ssl_ignore_revoke");
option.opt.width = Field::def_width_wider();
m_optgroup->append_single_option_line(option);
- */
#endif
-
m_optgroup->activate();
@@ -422,6 +418,7 @@ void PhysicalPrinterDialog::update(bool printer_change)
m_optgroup->hide_field(opt_key);
supports_multiple_printers = opt && opt->value == htRepetier;
}
+
}
else {
m_optgroup->set_value("host_type", int(PrintHostType::htOctoPrint), false);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 545700c45c..10e31bf8fe 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -911,17 +911,22 @@ void Sidebar::update_all_preset_comboboxes()
bool is_bbl_preset = preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(&preset_bundle);
+ auto p_mainframe = wxGetApp().mainframe;
+
+ p_mainframe->show_device(is_bbl_preset);
if (is_bbl_preset) {
//only show connection button for not-BBL printer
connection_btn->Hide();
//only show sync-ams button for BBL printer
ams_btn->Show();
//update print button default value for bbl or third-party printer
- wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::ePrintPlate);
+ p_mainframe->set_print_button_to_default(MainFrame::PrintSelectType::ePrintPlate);
+
} else {
connection_btn->Show();
ams_btn->Hide();
- wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::eSendGcode);
+ p_mainframe->set_print_button_to_default(MainFrame::PrintSelectType::eSendGcode);
+ p_mainframe->load_printer_url(wxString::Format("http://%s",preset_bundle.printers.get_edited_preset().config.opt_string("print_host")));
}
// Update the print choosers to only contain the compatible presets, update the dirty flags.
@@ -9080,7 +9085,7 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn, bool up
upload_job.printhost->get_groups(groups);
}
- PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups, upload_only);
+ PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups);
if (dlg.ShowModal() == wxID_OK) {
upload_job.upload_data.upload_path = dlg.filename();
upload_job.upload_data.post_action = dlg.post_action();
@@ -10646,4 +10651,4 @@ SuppressBackgroundProcessingUpdate::~SuppressBackgroundProcessingUpdate()
wxGetApp().plater()->schedule_background_process(m_was_scheduled);
}
-}} // namespace Slic3r::GUI
+}} // namespace Slic3r::GUI
\ No newline at end of file
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 36442e2bfc..4c5b947b60 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -687,4 +687,4 @@ private:
} // namespace GUI
} // namespace Slic3r
-#endif
+#endif
\ No newline at end of file
diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp
index 8bc4e3ceca..0f8705f112 100644
--- a/src/slic3r/GUI/PrintHostDialogs.cpp
+++ b/src/slic3r/GUI/PrintHostDialogs.cpp
@@ -36,8 +36,8 @@ namespace GUI {
static const char *CONFIG_KEY_PATH = "printhost_path";
static const char *CONFIG_KEY_GROUP = "printhost_group";
-PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUploadActions post_actions, const wxArrayString &groups, bool upload_only)
- : MsgDialog(static_cast(wxGetApp().mainframe), _L("Upload and Print"), _L("Upload to Printer Host with the following filename:"),0)
+PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUploadActions post_actions, const wxArrayString &groups)
+ : MsgDialog(static_cast(wxGetApp().mainframe), _L("Send to print"), _L("Upload to Printer Host with the following filename:"),0)
, txt_filename(new wxTextCtrl(this, wxID_ANY))
, combo_groups(!groups.IsEmpty() ? new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, groups, wxCB_READONLY) : nullptr)
, post_upload_action(PrintHostPostUploadAction::None)
@@ -88,19 +88,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
return true;
};
- auto* btn_confirm = add_button(wxID_YES, false, _L("Confirm"));
- btn_confirm->Bind(wxEVT_BUTTON, [this, upload_only, validate_path](wxCommandEvent&) {
- if (validate_path(txt_filename->GetValue())) {
- if (upload_only) {
- post_upload_action = PrintHostPostUploadAction::None;
- } else {
- post_upload_action = PrintHostPostUploadAction::StartPrint;
- }
- EndDialog(wxID_OK);
- }
- });
-
- /*auto* btn_upload = add_button(wxID_YES, false, _L("Upload"));
+ auto* btn_upload = add_button(wxID_YES, false, _L("Upload"));
btn_upload->Bind(wxEVT_BUTTON, [this, validate_path](wxCommandEvent&) {
if (validate_path(txt_filename->GetValue())) {
post_upload_action = PrintHostPostUploadAction::None;
@@ -108,7 +96,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
}
});
- if (post_actions.has(PrintHostPostUploadAction::StartPrint) && !upload_only) {
+ if (post_actions.has(PrintHostPostUploadAction::StartPrint)) {
auto* btn_print = add_button(wxID_YES, false, _L("Upload and Print"));
btn_print->Bind(wxEVT_BUTTON, [this, validate_path](wxCommandEvent&) {
if (validate_path(txt_filename->GetValue())) {
@@ -128,9 +116,8 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
}
});
}
- */
- add_button(wxID_CANCEL, false, "Cancel");
+ add_button(wxID_CANCEL,false,"Cancel");
finalize();
#ifdef __linux__
diff --git a/src/slic3r/GUI/PrintHostDialogs.hpp b/src/slic3r/GUI/PrintHostDialogs.hpp
index 83bf6a966d..ff3eb60125 100644
--- a/src/slic3r/GUI/PrintHostDialogs.hpp
+++ b/src/slic3r/GUI/PrintHostDialogs.hpp
@@ -26,7 +26,7 @@ namespace GUI {
class PrintHostSendDialog : public GUI::MsgDialog
{
public:
- PrintHostSendDialog(const boost::filesystem::path &path, PrintHostPostUploadActions post_actions, const wxArrayString& groups, bool upload_only);
+ PrintHostSendDialog(const boost::filesystem::path &path, PrintHostPostUploadActions post_actions, const wxArrayString& groups);
boost::filesystem::path filename() const;
PrintHostPostUploadAction post_action() const;
std::string group() const;
diff --git a/src/slic3r/GUI/PrinterWebView.cpp b/src/slic3r/GUI/PrinterWebView.cpp
new file mode 100644
index 0000000000..9635e8543f
--- /dev/null
+++ b/src/slic3r/GUI/PrinterWebView.cpp
@@ -0,0 +1,125 @@
+#include "PrinterWebView.hpp"
+
+#include "I18N.hpp"
+#include "slic3r/GUI/wxExtensions.hpp"
+#include "slic3r/GUI/GUI_App.hpp"
+#include "slic3r/GUI/MainFrame.hpp"
+#include "libslic3r_version.h"
+
+#include
+#include
+#include
+
+#include
+
+namespace pt = boost::property_tree;
+
+namespace Slic3r {
+namespace GUI {
+
+PrinterWebView::PrinterWebView(wxWindow *parent)
+ : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
+ {
+
+ wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
+
+ // Create the button
+ bSizer_toolbar = new wxBoxSizer(wxHORIZONTAL);
+
+ //m_button_reload = new wxButton(this, wxID_ANY, wxT("Reload"), wxDefaultPosition, wxDefaultSize, 0);
+ //bSizer_toolbar->Add(m_button_reload, 0, wxALL, 5);
+
+ m_url = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
+ bSizer_toolbar->Add(m_url, 1, wxALL | wxEXPAND, 5);
+
+
+ // Create the webview
+ m_browser = WebView::CreateWebView(this, "");
+ if (m_browser == nullptr) {
+ wxLogError("Could not init m_browser");
+ return;
+ }
+
+ SetSizer(topsizer);
+
+ topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
+
+ // Log backend information
+ if (wxGetApp().get_mode() == comDevelop) {
+ wxLogMessage(wxWebView::GetBackendVersionInfo().ToString());
+ wxLogMessage("Backend: %s Version: %s", m_browser->GetClassInfo()->GetClassName(),
+ wxWebView::GetBackendVersionInfo().ToString());
+ wxLogMessage("User Agent: %s", m_browser->GetUserAgent());
+ }
+
+ //Zoom
+ m_zoomFactor = 100;
+
+ // Connect the button events
+ //Bind(wxEVT_BUTTON, &PrinterWebView::OnReload, this, m_button_reload->GetId());
+ Bind(wxEVT_TEXT_ENTER, &PrinterWebView::OnUrl, this, m_url->GetId());
+ //Connect the idle events
+ Bind(wxEVT_CLOSE_WINDOW, &PrinterWebView::OnClose, this);
+
+ }
+
+PrinterWebView::~PrinterWebView()
+{
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Start";
+ SetEvtHandlerEnabled(false);
+
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " End";
+}
+
+
+void PrinterWebView::load_url(wxString& url)
+{
+ //this->Show();
+ //this->Raise();
+ m_url->SetLabelText(url);
+
+ if (wxGetApp().get_mode() == comDevelop)
+ wxLogMessage(m_url->GetValue());
+ m_browser->LoadURL(url);
+ //m_browser->SetFocus();
+ UpdateState();
+}
+/**
+ * Method that retrieves the current state from the web control and updates the
+ * GUI the reflect this current state.
+ */
+void PrinterWebView::UpdateState() {
+ // SetTitle(m_browser->GetCurrentTitle());
+ m_url->SetValue(m_browser->GetCurrentURL());
+}
+
+/**
+ * Callback invoked when user entered an URL and pressed enter
+ */
+void PrinterWebView::OnUrl(wxCommandEvent& WXUNUSED(evt))
+{
+ if (wxGetApp().get_mode() == comDevelop)
+ wxLogMessage(m_url->GetValue());
+ m_browser->LoadURL(m_url->GetValue());
+ m_browser->SetFocus();
+ UpdateState();
+}
+
+/**
+ * Callback invoked when user pressed the "reload" button
+ */
+void PrinterWebView::OnReload(wxCommandEvent& WXUNUSED(evt))
+{
+ m_browser->Reload();
+ UpdateState();
+}
+
+void PrinterWebView::OnClose(wxCloseEvent& evt)
+{
+ this->Hide();
+}
+
+
+
+} // GUI
+} // Slic3r
diff --git a/src/slic3r/GUI/PrinterWebView.hpp b/src/slic3r/GUI/PrinterWebView.hpp
new file mode 100644
index 0000000000..4a02019153
--- /dev/null
+++ b/src/slic3r/GUI/PrinterWebView.hpp
@@ -0,0 +1,64 @@
+#ifndef slic3r_PrinterWebView_hpp_
+#define slic3r_PrinterWebView_hpp_
+
+
+#include "wx/artprov.h"
+#include "wx/cmdline.h"
+#include "wx/notifmsg.h"
+#include "wx/settings.h"
+#include "wx/webview.h"
+
+#if wxUSE_WEBVIEW_EDGE
+#include "wx/msw/webview_edge.h"
+#endif
+
+#include "wx/webviewarchivehandler.h"
+#include "wx/webviewfshandler.h"
+#include "wx/numdlg.h"
+#include "wx/infobar.h"
+#include "wx/filesys.h"
+#include "wx/fs_arc.h"
+#include "wx/fs_mem.h"
+#include "wx/stdpaths.h"
+#include
+#include
+#include "wx/textctrl.h"
+#include
+
+
+namespace Slic3r {
+namespace GUI {
+
+
+class PrinterWebView : public wxPanel {
+public:
+ PrinterWebView(wxWindow *parent);
+ virtual ~PrinterWebView();
+
+ void load_url(wxString& url);
+
+ void UpdateState();
+ void OnUrl(wxCommandEvent& evt);
+ void OnReload(wxCommandEvent& evt);
+ void OnClose(wxCloseEvent& evt);
+
+private:
+
+ wxWebView* m_browser;
+ wxBoxSizer *bSizer_toolbar;
+ wxButton * m_button_reload;
+ wxTextCtrl *m_url;
+
+ long m_zoomFactor;
+
+ // Last executed JavaScript snippet, for convenience.
+ // wxString m_javascript;
+ // wxString m_response_js;
+
+ // DECLARE_EVENT_TABLE()
+};
+
+} // GUI
+} // Slic3r
+
+#endif /* slic3r_Tab_hpp_ */
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 2a0b2b651e..5e4db9fdda 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -43,6 +43,8 @@
#include "MarkdownTip.hpp"
#include "Search.hpp"
+#include "BedShapeDialog.hpp"
+// #include "BonjourDialog.hpp"
#ifdef WIN32
#include
#endif // WIN32
@@ -853,7 +855,7 @@ void TabPrinter::init_options_list()
for (const std::string& opt_key : m_config->keys())
{
- if (opt_key == "printable_area" || opt_key == "bed_exclude_area") {
+ if (opt_key == "printable_area" || opt_key == "bed_exclude_area" | opt_key == "thumbnails") {
m_options_list.emplace(opt_key, m_opt_status_value);
continue;
}
@@ -1779,8 +1781,11 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
optgroup->append_single_option_line("wall_infill_order");
optgroup->append_single_option_line("bridge_flow");
+ optgroup->append_single_option_line("top_solid_infill_flow_ratio");
+ optgroup->append_single_option_line("bottom_solid_infill_flow_ratio");
optgroup->append_single_option_line("thick_bridges");
optgroup->append_single_option_line("only_one_wall_top");
+ optgroup->append_single_option_line("only_one_wall_first_layer");
optgroup->append_single_option_line("detect_overhang_wall");
optgroup->append_single_option_line("reduce_crossing_wall");
optgroup->append_single_option_line("max_travel_detour_distance");
@@ -1805,6 +1810,7 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
optgroup->append_single_option_line("infill_wall_overlap");
optgroup->append_single_option_line("infill_direction");
+ optgroup->append_single_option_line("bridge_angle");
optgroup->append_single_option_line("minimum_sparse_infill_area");
optgroup->append_single_option_line("infill_combination");
optgroup->append_single_option_line("detect_narrow_internal_solid_infill");
@@ -1837,9 +1843,20 @@ void TabPrint::build()
optgroup->append_single_option_line("travel_speed");
optgroup = page->new_optgroup(L("Acceleration"), L"param_acceleration", 15);
+ optgroup->append_single_option_line("default_acceleration");
+ optgroup->append_single_option_line("outer_wall_acceleration");
+ optgroup->append_single_option_line("inner_wall_acceleration");
optgroup->append_single_option_line("initial_layer_acceleration");
optgroup->append_single_option_line("top_surface_acceleration");
- optgroup->append_single_option_line("default_acceleration");
+ optgroup->append_single_option_line("travel_acceleration");
+
+ optgroup = page->new_optgroup(L("Jerk(XY)"));
+ optgroup->append_single_option_line("default_jerk");
+ optgroup->append_single_option_line("outer_wall_jerk");
+ optgroup->append_single_option_line("inner_wall_jerk");
+ optgroup->append_single_option_line("top_surface_jerk");
+ optgroup->append_single_option_line("initial_layer_jerk");
+ optgroup->append_single_option_line("travel_jerk");
#ifdef HAS_PRESSURE_EQUALIZER
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive");
@@ -1922,7 +1939,10 @@ void TabPrint::build()
optgroup->append_single_option_line("reduce_infill_retraction");
optgroup->append_single_option_line("gcode_add_line_number");
Option option = optgroup->get_option("filename_format");
- option.opt.full_width = true;
+ // option.opt.full_width = true;
+ option.opt.is_code = true;
+ option.opt.multiline = true;
+ // option.opt.height = 5;
optgroup->append_single_option_line(option);
#if 0
@@ -2424,6 +2444,10 @@ void TabFilament::build()
//optgroup->append_single_option_line("filament_colour");
optgroup->append_single_option_line("filament_diameter");
optgroup->append_single_option_line("filament_flow_ratio");
+
+ optgroup->append_single_option_line("enable_pressure_advance");
+ optgroup->append_single_option_line("pressure_advance");
+
optgroup->append_single_option_line("filament_density");
optgroup->append_single_option_line("filament_cost");
//BBS
@@ -2439,6 +2463,10 @@ void TabFilament::build()
optgroup = page->new_optgroup(L("Print temperature"), L"param_temperature");
optgroup->split_multi_line = true;
optgroup->option_label_at_right = true;
+ line = { L("Chamber temperature"), L("Chamber temperature") };
+ line.append_option(optgroup->get_option("chamber_temperature"));
+ optgroup->append_line(line);
+
line = { L("Nozzle"), L("Nozzle temperature when printing") };
line.append_option(optgroup->get_option("nozzle_temperature_initial_layer"));
line.append_option(optgroup->get_option("nozzle_temperature"));
@@ -2637,7 +2665,11 @@ void TabFilament::toggle_options()
for (auto el : { "overhang_fan_speed", "overhang_fan_threshold" })
toggle_option(el, has_enable_overhang_bridge_fan);
}
-
+ if (m_active_page->title() == "Filament")
+ {
+ bool pa = m_config->opt_bool("enable_pressure_advance");
+ toggle_option("pressure_advance", pa);
+ }
if (m_active_page->title() == "Setting Overrides")
update_filament_overrides_page();
}
@@ -2729,12 +2761,13 @@ void TabPrinter::build_fff()
auto page = add_options_page(L("Basic information"), "printer");
auto optgroup = page->new_optgroup(L("Printable space")/*, L"param_printable_space"*/);
- //create_line_with_widget(optgroup.get(), "printable_area", "custom-svg-and-png-bed-textures_124612", [this](wxWindow* parent) {
- // return create_bed_shape_widget(parent);
- //});
+ create_line_with_widget(optgroup.get(), "printable_area", "custom-svg-and-png-bed-textures_124612", [this](wxWindow* parent) {
+ return create_bed_shape_widget(parent);
+ });
Option option = optgroup->get_option("bed_exclude_area");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
+ // optgroup->append_single_option_line("printable_area");
optgroup->append_single_option_line("printable_height");
optgroup->append_single_option_line("nozzle_volume");
// BBS
@@ -2835,6 +2868,9 @@ void TabPrinter::build_fff()
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
optgroup->append_single_option_line("gcode_flavor");
+ option = optgroup->get_option("thumbnails");
+ option.opt.full_width = true;
+ optgroup->append_single_option_line(option);
optgroup->append_single_option_line("scan_first_layer");
// optgroup->append_single_option_line("spaghetti_detector");
optgroup->append_single_option_line("machine_load_filament_time");
@@ -2870,8 +2906,8 @@ void TabPrinter::build_fff()
option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
-#if 0
- optgroup = page->new_optgroup(L("Before layer change G-code"), 0);
+
+ optgroup = page->new_optgroup(L("Before layer change G-code"),"param_gcode", 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
};
@@ -2880,7 +2916,6 @@ void TabPrinter::build_fff()
option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
-#endif
optgroup = page->new_optgroup(L("Layer change G-code"), L"param_gcode", 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
@@ -2926,7 +2961,6 @@ void TabPrinter::build_fff()
// build_preset_description_line(optgroup.get());
#endif
-
build_unregular_pages(true);
}
@@ -3100,7 +3134,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
{
size_t n_before_extruders = 2; // Count of pages before Extruder pages
auto flavor = m_config->option>("gcode_flavor")->value;
- bool is_marlin_flavor = (flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware);
+ bool is_marlin_flavor = (flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware || flavor == gcfKlipper);
/* ! Freeze/Thaw in this function is needed to avoid call OnPaint() for erased pages
* and be cause of application crash, when try to change Preset in moment,
@@ -3231,6 +3265,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
optgroup = page->new_optgroup(L("Retraction"), L"param_retraction");
optgroup->append_single_option_line("retraction_length", "", extruder_idx);
optgroup->append_single_option_line("z_hop", "", extruder_idx);
+ optgroup->append_single_option_line("z_lift_type", "", extruder_idx);
optgroup->append_single_option_line("retraction_speed", "", extruder_idx);
optgroup->append_single_option_line("deretraction_speed", "", extruder_idx);
//optgroup->append_single_option_line("retract_restart_extra", "", extruder_idx);
@@ -3447,9 +3482,9 @@ void TabPrinter::toggle_options()
toggle_option("retract_restart_extra_toolchange", have_multiple_extruders && toolchange_retraction, i);
}
- if (m_active_page->title() == "Motion ability") {
- assert(m_config->option>("gcode_flavor")->value == gcfMarlinLegacy
- || m_config->option>("gcode_flavor")->value == gcfMarlinFirmware);
+ auto gcf = m_config->option>("gcode_flavor")->value;
+ if (m_active_page->title() == "Motion ability") {
+ assert(gcf == gcfMarlinLegacy || gcf == gcfMarlinFirmware || gcf == gcfKlipper);
bool silent_mode = m_config->opt_bool("silent_mode");
int max_field = silent_mode ? 2 : 1;
//BBS: limits of BBL printer can't be edited.
@@ -3481,7 +3516,9 @@ void TabPrinter::update_fff()
m_use_silent_mode = m_config->opt_bool("silent_mode");
}
- bool supports_travel_acceleration = (m_config->option>("gcode_flavor")->value == gcfMarlinFirmware);
+ auto gcf_ =
+ m_config->option>("gcode_flavor")->value;
+ bool supports_travel_acceleration = (gcf_ == gcfMarlinFirmware || gcf_ == gcfMarlinLegacy || gcf_ == gcfKlipper);
if (m_supports_travel_acceleration != supports_travel_acceleration) {
m_rebuild_kinematics_page = true;
m_supports_travel_acceleration = supports_travel_acceleration;
@@ -4609,7 +4646,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
}
// Return a callback to create a TabPrinter widget to edit bed shape
-/*wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
+wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
{
ScalableButton* btn = new ScalableButton(parent, wxID_ANY, "printer", " " + _(L("Set")) + " " + dots,
wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT, true);
@@ -4639,7 +4676,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
}
return sizer;
-}*/
+}
void TabPrinter::cache_extruder_cnt()
{
diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp
index 44e8061d30..512e77a8e8 100644
--- a/src/slic3r/GUI/Tab.hpp
+++ b/src/slic3r/GUI/Tab.hpp
@@ -547,6 +547,7 @@ private:
std::vector m_pages_fff;
std::vector m_pages_sla;
+ wxBoxSizer* m_presets_sizer {nullptr};
public:
ScalableButton* m_reset_to_filament_color = nullptr;
@@ -582,9 +583,10 @@ public:
void msw_rescale() override;
bool supports_printer_technology(const PrinterTechnology /* tech */) const override { return true; }
- //wxSizer* create_bed_shape_widget(wxWindow* parent);
+ wxSizer* create_bed_shape_widget(wxWindow* parent);
void cache_extruder_cnt();
bool apply_extruder_cnt_from_cache();
+
};
class TabSLAMaterial : public Tab
diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp
index 9afc212a4e..b72591a3e8 100644
--- a/src/slic3r/GUI/UnsavedChangesDialog.cpp
+++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp
@@ -1315,7 +1315,7 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
}
case coPoints: {
//BBS: add bed_exclude_area
- if (opt_key == "printable_area") {
+ if (opt_key == "printable_area" || opt_key == "thumbnails") {
ConfigOptionPoints points = *config.option(opt_key);
//BuildVolume build_volume = {points.values, 0.};
return get_thumbnails_string(points.values);
diff --git a/src/slic3r/Utils/AstroBox.cpp b/src/slic3r/Utils/AstroBox.cpp
new file mode 100644
index 0000000000..8781549a20
--- /dev/null
+++ b/src/slic3r/Utils/AstroBox.cpp
@@ -0,0 +1,173 @@
+#include "AstroBox.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "libslic3r/PrintConfig.hpp"
+#include "slic3r/GUI/I18N.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "Http.hpp"
+
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+
+
+namespace Slic3r {
+
+AstroBox::AstroBox(DynamicPrintConfig *config) :
+ host(config->opt_string("print_host")),
+ apikey(config->opt_string("printhost_apikey")),
+ cafile(config->opt_string("printhost_cafile"))
+{}
+
+const char* AstroBox::get_name() const { return "AstroBox"; }
+
+bool AstroBox::test(wxString &msg) const
+{
+ // Since the request is performed synchronously here,
+ // it is ok to refer to `msg` from within the closure
+
+ const char *name = get_name();
+
+ bool res = true;
+ auto url = make_url("api/version");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get version at: %2%") % name % url;
+
+ auto http = Http::get(std::move(url));
+ set_auth(http);
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ res = false;
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&, this](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got version: %2%") % name % body;
+
+ try {
+ std::stringstream ss(body);
+ pt::ptree ptree;
+ pt::read_json(ss, ptree);
+
+ if (! ptree.get_optional("api")) {
+ res = false;
+ return;
+ }
+
+ const auto text = ptree.get_optional("text");
+ res = validate_version_text(text);
+ if (! res) {
+ msg = GUI::from_u8((boost::format(_utf8(L("Mismatched type of print host: %s"))) % (text ? *text : "AstroBox")).str());
+ }
+ }
+ catch (const std::exception &) {
+ res = false;
+ msg = "Could not parse server response";
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+wxString AstroBox::get_test_ok_msg () const
+{
+ return _(L("Connection to AstroBox works correctly."));
+}
+
+wxString AstroBox::get_test_failed_msg (wxString &msg) const
+{
+ return GUI::from_u8((boost::format("%s: %s\n\n%s")
+ % _utf8(L("Could not connect to AstroBox"))
+ % std::string(msg.ToUTF8())
+ % _utf8(L("Note: AstroBox version at least 1.1.0 is required."))).str());
+}
+
+bool AstroBox::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const
+{
+ const char *name = get_name();
+
+ const auto upload_filename = upload_data.upload_path.filename();
+ const auto upload_parent_path = upload_data.upload_path.parent_path();
+
+ wxString test_msg;
+ if (! test(test_msg)) {
+ error_fn(std::move(test_msg));
+ return false;
+ }
+
+ bool res = true;
+
+ auto url = make_url("api/files/local");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%")
+ % name
+ % upload_data.source_path
+ % url
+ % upload_filename.string()
+ % upload_parent_path.string()
+ % (upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false");
+
+ auto http = Http::post(std::move(url));
+ set_auth(http);
+ http.form_add("print", upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false")
+ .form_add("path", upload_parent_path.string()) // XXX: slashes on windows ???
+ .form_add_file("file", upload_data.source_path.string(), upload_filename.string())
+ .on_complete([&](std::string body, unsigned status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body;
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error uploading file: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ error_fn(format_error(body, error, status));
+ res = false;
+ })
+ .on_progress([&](Http::Progress progress, bool &cancel) {
+ prorgess_fn(std::move(progress), cancel);
+ if (cancel) {
+ // Upload was canceled
+ BOOST_LOG_TRIVIAL(info) << "AstroBox: Upload canceled";
+ res = false;
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+bool AstroBox::validate_version_text(const boost::optional &version_text) const
+{
+ return version_text ? boost::starts_with(*version_text, "AstroBox") : true;
+}
+
+void AstroBox::set_auth(Http &http) const
+{
+ http.header("X-Api-Key", apikey);
+
+ if (! cafile.empty()) {
+ http.ca_file(cafile);
+ }
+}
+
+std::string AstroBox::make_url(const std::string &path) const
+{
+ if (host.find("http://") == 0 || host.find("https://") == 0) {
+ if (host.back() == '/') {
+ return (boost::format("%1%%2%") % host % path).str();
+ } else {
+ return (boost::format("%1%/%2%") % host % path).str();
+ }
+ } else {
+ return (boost::format("http://%1%/%2%") % host % path).str();
+ }
+}
+
+}
diff --git a/src/slic3r/Utils/AstroBox.hpp b/src/slic3r/Utils/AstroBox.hpp
new file mode 100644
index 0000000000..15a8863a90
--- /dev/null
+++ b/src/slic3r/Utils/AstroBox.hpp
@@ -0,0 +1,46 @@
+#ifndef slic3r_AstroBox_hpp_
+#define slic3r_AstroBox_hpp_
+
+#include
+#include
+#include
+
+#include "PrintHost.hpp"
+
+namespace Slic3r {
+
+class DynamicPrintConfig;
+class Http;
+
+class AstroBox : public PrintHost
+{
+public:
+ AstroBox(DynamicPrintConfig *config);
+ ~AstroBox() override = default;
+
+ const char* get_name() const override;
+
+ bool test(wxString &curl_msg) const override;
+ wxString get_test_ok_msg () const override;
+ wxString get_test_failed_msg (wxString &msg) const override;
+ bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
+ bool has_auto_discovery() const override { return true; }
+ bool can_test() const override { return true; }
+ PrintHostPostUploadActions get_post_upload_actions() const override { return PrintHostPostUploadAction::StartPrint; }
+ std::string get_host() const override { return host; }
+
+protected:
+ bool validate_version_text(const boost::optional &version_text) const;
+
+private:
+ std::string host;
+ std::string apikey;
+ std::string cafile;
+
+ void set_auth(Http &http) const;
+ std::string make_url(const std::string &path) const;
+};
+
+}
+
+#endif
diff --git a/src/slic3r/Utils/Duet.cpp b/src/slic3r/Utils/Duet.cpp
new file mode 100644
index 0000000000..3293a3ff2b
--- /dev/null
+++ b/src/slic3r/Utils/Duet.cpp
@@ -0,0 +1,286 @@
+#include "Duet.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "libslic3r/PrintConfig.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/I18N.hpp"
+#include "slic3r/GUI/MsgDialog.hpp"
+#include "Http.hpp"
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+
+namespace Slic3r {
+
+Duet::Duet(DynamicPrintConfig *config) :
+ host(config->opt_string("print_host")),
+ password(config->opt_string("printhost_apikey"))
+{}
+
+const char* Duet::get_name() const { return "Duet"; }
+
+bool Duet::test(wxString &msg) const
+{
+ auto connectionType = connect(msg);
+ disconnect(connectionType);
+
+ return connectionType != ConnectionType::error;
+}
+
+wxString Duet::get_test_ok_msg () const
+{
+ return _(L("Connection to Duet works correctly."));
+}
+
+wxString Duet::get_test_failed_msg (wxString &msg) const
+{
+ return GUI::from_u8((boost::format("%s: %s")
+ % _utf8(L("Could not connect to Duet"))
+ % std::string(msg.ToUTF8())).str());
+}
+
+bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const
+{
+ wxString connect_msg;
+ auto connectionType = connect(connect_msg);
+ if (connectionType == ConnectionType::error) {
+ error_fn(std::move(connect_msg));
+ return false;
+ }
+
+ bool res = true;
+ bool dsf = (connectionType == ConnectionType::dsf);
+
+ auto upload_cmd = get_upload_url(upload_data.upload_path.string(), connectionType);
+ BOOST_LOG_TRIVIAL(info) << boost::format("Duet: Uploading file %1%, filepath: %2%, post_action: %3%, command: %4%")
+ % upload_data.source_path
+ % upload_data.upload_path
+ % int(upload_data.post_action)
+ % upload_cmd;
+
+ auto http = (dsf ? Http::put(std::move(upload_cmd)) : Http::post(std::move(upload_cmd)));
+ if (dsf) {
+ http.set_put_body(upload_data.source_path);
+ } else {
+ http.set_post_body(upload_data.source_path);
+ }
+ http.on_complete([&](std::string body, unsigned status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: File uploaded: HTTP %1%: %2%") % status % body;
+
+ int err_code = dsf ? (status == 201 ? 0 : 1) : get_err_code_from_body(body);
+ if (err_code != 0) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Request completed but error code was received: %1%") % err_code;
+ error_fn(format_error(body, L("Unknown error occured"), 0));
+ res = false;
+ } else if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
+ wxString errormsg;
+ res = start_print(errormsg, upload_data.upload_path.string(), connectionType, false);
+ if (! res) {
+ error_fn(std::move(errormsg));
+ }
+ } else if (upload_data.post_action == PrintHostPostUploadAction::StartSimulation) {
+ wxString errormsg;
+ res = start_print(errormsg, upload_data.upload_path.string(), connectionType, true);
+ if (! res) {
+ error_fn(std::move(errormsg));
+ }
+ }
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ error_fn(format_error(body, error, status));
+ res = false;
+ })
+ .on_progress([&](Http::Progress progress, bool &cancel) {
+ prorgess_fn(std::move(progress), cancel);
+ if (cancel) {
+ // Upload was canceled
+ BOOST_LOG_TRIVIAL(info) << "Duet: Upload canceled";
+ res = false;
+ }
+ })
+ .perform_sync();
+
+ disconnect(connectionType);
+
+ return res;
+}
+
+Duet::ConnectionType Duet::connect(wxString &msg) const
+{
+ auto res = ConnectionType::error;
+ auto url = get_connect_url(false);
+
+ auto http = Http::get(std::move(url));
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ auto dsfUrl = get_connect_url(true);
+ auto dsfHttp = Http::get(std::move(dsfUrl));
+ dsfHttp.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error connecting: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&](std::string body, unsigned) {
+ res = ConnectionType::dsf;
+ })
+ .perform_sync();
+ })
+ .on_complete([&](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: Got: %1%") % body;
+
+ int err_code = get_err_code_from_body(body);
+ switch (err_code) {
+ case 0:
+ res = ConnectionType::rrf;
+ break;
+ case 1:
+ msg = format_error(body, L("Wrong password"), 0);
+ break;
+ case 2:
+ msg = format_error(body, L("Could not get resources to create a new connection"), 0);
+ break;
+ default:
+ msg = format_error(body, L("Unknown error occured"), 0);
+ break;
+ }
+
+ })
+ .perform_sync();
+
+ return res;
+}
+
+void Duet::disconnect(ConnectionType connectionType) const
+{
+ // we don't need to disconnect from DSF or if it failed anyway
+ if (connectionType != ConnectionType::rrf) {
+ return;
+ }
+ auto url = (boost::format("%1%rr_disconnect")
+ % get_base_url()).str();
+
+ auto http = Http::get(std::move(url));
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ // we don't care about it, if disconnect is not working Duet will disconnect automatically after some time
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error disconnecting: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ })
+ .perform_sync();
+}
+
+std::string Duet::get_upload_url(const std::string &filename, ConnectionType connectionType) const
+{
+ assert(connectionType != ConnectionType::error);
+
+ if (connectionType == ConnectionType::dsf) {
+ return (boost::format("%1%machine/file/gcodes/%2%")
+ % get_base_url()
+ % Http::url_encode(filename)).str();
+ } else {
+ return (boost::format("%1%rr_upload?name=0:/gcodes/%2%&%3%")
+ % get_base_url()
+ % Http::url_encode(filename)
+ % timestamp_str()).str();
+ }
+}
+
+std::string Duet::get_connect_url(const bool dsfUrl) const
+{
+ if (dsfUrl) {
+ return (boost::format("%1%machine/status")
+ % get_base_url()).str();
+ } else {
+ return (boost::format("%1%rr_connect?password=%2%&%3%")
+ % get_base_url()
+ % (password.empty() ? "reprap" : password)
+ % timestamp_str()).str();
+ }
+}
+
+std::string Duet::get_base_url() const
+{
+ if (host.find("http://") == 0 || host.find("https://") == 0) {
+ if (host.back() == '/') {
+ return host;
+ } else {
+ return (boost::format("%1%/") % host).str();
+ }
+ } else {
+ return (boost::format("http://%1%/") % host).str();
+ }
+}
+
+std::string Duet::timestamp_str() const
+{
+ enum { BUFFER_SIZE = 32 };
+
+ auto t = std::time(nullptr);
+ auto tm = *std::localtime(&t);
+
+ char buffer[BUFFER_SIZE];
+ std::strftime(buffer, BUFFER_SIZE, "time=%Y-%m-%dT%H:%M:%S", &tm);
+
+ return std::string(buffer);
+}
+
+bool Duet::start_print(wxString &msg, const std::string &filename, ConnectionType connectionType, bool simulationMode) const
+{
+ assert(connectionType != ConnectionType::error);
+
+ bool res = false;
+ bool dsf = (connectionType == ConnectionType::dsf);
+
+ auto url = dsf
+ ? (boost::format("%1%machine/code")
+ % get_base_url()).str()
+ : (boost::format(simulationMode
+ ? "%1%rr_gcode?gcode=M37%%20P\"0:/gcodes/%2%\""
+ : "%1%rr_gcode?gcode=M32%%20\"0:/gcodes/%2%\"")
+ % get_base_url()
+ % Http::url_encode(filename)).str();
+
+ auto http = (dsf ? Http::post(std::move(url)) : Http::get(std::move(url)));
+ if (dsf) {
+ http.set_post_body(
+ (boost::format(simulationMode
+ ? "M37 P\"0:/gcodes/%1%\""
+ : "M32 \"0:/gcodes/%1%\"")
+ % filename).str()
+ );
+ }
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error starting print: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: Got: %1%") % body;
+ res = true;
+ })
+ .perform_sync();
+
+ return res;
+}
+
+int Duet::get_err_code_from_body(const std::string &body) const
+{
+ pt::ptree root;
+ std::istringstream iss (body); // wrap returned json to istringstream
+ pt::read_json(iss, root);
+
+ return root.get("err", 0);
+}
+
+}
diff --git a/src/slic3r/Utils/Duet.hpp b/src/slic3r/Utils/Duet.hpp
new file mode 100644
index 0000000000..edca66ce0c
--- /dev/null
+++ b/src/slic3r/Utils/Duet.hpp
@@ -0,0 +1,48 @@
+#ifndef slic3r_Duet_hpp_
+#define slic3r_Duet_hpp_
+
+#include
+#include
+
+#include "PrintHost.hpp"
+
+namespace Slic3r {
+
+class DynamicPrintConfig;
+class Http;
+
+class Duet : public PrintHost
+{
+public:
+ explicit Duet(DynamicPrintConfig *config);
+ ~Duet() override = default;
+
+ const char* get_name() const override;
+
+ bool test(wxString &curl_msg) const override;
+ wxString get_test_ok_msg() const override;
+ wxString get_test_failed_msg(wxString &msg) const override;
+ bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
+ bool has_auto_discovery() const override { return false; }
+ bool can_test() const override { return true; }
+ PrintHostPostUploadActions get_post_upload_actions() const override { return PrintHostPostUploadAction::StartPrint | PrintHostPostUploadAction::StartSimulation; }
+ std::string get_host() const override { return host; }
+
+private:
+ enum class ConnectionType { rrf, dsf, error };
+ std::string host;
+ std::string password;
+
+ std::string get_upload_url(const std::string &filename, ConnectionType connectionType) const;
+ std::string get_connect_url(const bool dsfUrl) const;
+ std::string get_base_url() const;
+ std::string timestamp_str() const;
+ ConnectionType connect(wxString &msg) const;
+ void disconnect(ConnectionType connectionType) const;
+ bool start_print(wxString &msg, const std::string &filename, ConnectionType connectionType, bool simulationMode) const;
+ int get_err_code_from_body(const std::string &body) const;
+};
+
+}
+
+#endif
diff --git a/src/slic3r/Utils/FlashAir.cpp b/src/slic3r/Utils/FlashAir.cpp
new file mode 100644
index 0000000000..2337ac2904
--- /dev/null
+++ b/src/slic3r/Utils/FlashAir.cpp
@@ -0,0 +1,229 @@
+#include "FlashAir.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "libslic3r/PrintConfig.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/I18N.hpp"
+#include "slic3r/GUI/MsgDialog.hpp"
+#include "Http.hpp"
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+
+namespace Slic3r {
+
+FlashAir::FlashAir(DynamicPrintConfig *config) :
+ host(config->opt_string("print_host"))
+{}
+
+const char* FlashAir::get_name() const { return "FlashAir"; }
+
+bool FlashAir::test(wxString &msg) const
+{
+ // Since the request is performed synchronously here,
+ // it is ok to refer to `msg` from within the closure
+
+ const char *name = get_name();
+
+ bool res = false;
+ auto url = make_url("command.cgi", "op", "118");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get upload enabled at: %2%") % name % url;
+
+ auto http = Http::get(std::move(url));
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting upload enabled: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ res = false;
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got upload enabled: %2%") % name % body;
+
+ res = boost::starts_with(body, "1");
+ if (! res) {
+ msg = _(L("Upload not enabled on FlashAir card."));
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+wxString FlashAir::get_test_ok_msg () const
+{
+ return _(L("Connection to FlashAir works correctly and upload is enabled."));
+}
+
+wxString FlashAir::get_test_failed_msg (wxString &msg) const
+{
+ return GUI::from_u8((boost::format("%s: %s\n%s")
+ % _utf8(L("Could not connect to FlashAir"))
+ % std::string(msg.ToUTF8())
+ % _utf8(L("Note: FlashAir with firmware 2.00.02 or newer and activated upload function is required."))).str());
+}
+
+bool FlashAir::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const
+{
+ const char *name = get_name();
+
+ const auto upload_filename = upload_data.upload_path.filename();
+ const auto upload_parent_path = upload_data.upload_path.parent_path();
+ wxString test_msg;
+ if (! test(test_msg)) {
+ error_fn(std::move(test_msg));
+ return false;
+ }
+
+ bool res = false;
+
+ std::string strDest = upload_parent_path.string();
+ if (strDest.front()!='/') // Needs a leading / else root uploads fail.
+ {
+ strDest.insert(0,"/");
+ }
+
+ auto urlPrepare = make_url("upload.cgi", "WRITEPROTECT=ON&FTIME", timestamp_str());
+ auto urlSetDir = make_url("upload.cgi","UPDIR",strDest);
+ auto urlUpload = make_url("upload.cgi");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3% / %4%, filename: %5%")
+ % name
+ % upload_data.source_path
+ % urlPrepare
+ % urlUpload
+ % upload_filename.string();
+
+ // set filetime for upload and make card writeprotect to prevent filesystem damage
+ auto httpPrepare = Http::get(std::move(urlPrepare));
+ httpPrepare.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error preparing upload: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ error_fn(format_error(body, error, status));
+ res = false;
+ })
+ .on_complete([&, this](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got prepare result: %2%") % name % body;
+ res = boost::icontains(body, "SUCCESS");
+ if (! res) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Request completed but no SUCCESS message was received.") % name;
+ error_fn(format_error(body, L("Unknown error occured"), 0));
+ }
+ })
+ .perform_sync();
+
+ if(! res ) {
+ return res;
+ }
+
+ // start file upload
+ auto httpDir = Http::get(std::move(urlSetDir));
+ httpDir.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error setting upload dir: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ error_fn(format_error(body, error, status));
+ res = false;
+ })
+ .on_complete([&, this](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got dir select result: %2%") % name % body;
+ res = boost::icontains(body, "SUCCESS");
+ if (! res) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Request completed but no SUCCESS message was received.") % name;
+ error_fn(format_error(body, L("Unknown error occured"), 0));
+ }
+ })
+ .perform_sync();
+
+ if(! res ) {
+ return res;
+ }
+
+ auto http = Http::post(std::move(urlUpload));
+ http.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
+ .on_complete([&](std::string body, unsigned status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body;
+ res = boost::icontains(body, "SUCCESS");
+ if (! res) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Request completed but no SUCCESS message was received.") % name;
+ error_fn(format_error(body, L("Unknown error occured"), 0));
+ }
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error uploading file: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ error_fn(format_error(body, error, status));
+ res = false;
+ })
+ .on_progress([&](Http::Progress progress, bool &cancel) {
+ prorgess_fn(std::move(progress), cancel);
+ if (cancel) {
+ // Upload was canceled
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Upload canceled") % name;
+ res = false;
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+std::string FlashAir::timestamp_str() const
+{
+ auto t = std::time(nullptr);
+ auto tm = *std::localtime(&t);
+
+ unsigned long fattime = ((tm.tm_year - 80) << 25) |
+ ((tm.tm_mon + 1) << 21) |
+ (tm.tm_mday << 16) |
+ (tm.tm_hour << 11) |
+ (tm.tm_min << 5) |
+ (tm.tm_sec >> 1);
+
+ return (boost::format("%1$#x") % fattime).str();
+}
+
+std::string FlashAir::make_url(const std::string &path) const
+{
+ if (host.find("http://") == 0 || host.find("https://") == 0) {
+ if (host.back() == '/') {
+ return (boost::format("%1%%2%") % host % path).str();
+ } else {
+ return (boost::format("%1%/%2%") % host % path).str();
+ }
+ } else {
+ if (host.back() == '/') {
+ return (boost::format("http://%1%%2%") % host % path).str();
+ } else {
+ return (boost::format("http://%1%/%2%") % host % path).str();
+ }
+ }
+}
+
+std::string FlashAir::make_url(const std::string &path, const std::string &arg, const std::string &val) const
+{
+ if (host.find("http://") == 0 || host.find("https://") == 0) {
+ if (host.back() == '/') {
+ return (boost::format("%1%%2%?%3%=%4%") % host % path % arg % val).str();
+ } else {
+ return (boost::format("%1%/%2%?%3%=%4%") % host % path % arg % val).str();
+ }
+ } else {
+ if (host.back() == '/') {
+ return (boost::format("http://%1%%2%?%3%=%4%") % host % path % arg % val).str();
+ } else {
+ return (boost::format("http://%1%/%2%?%3%=%4%") % host % path % arg % val).str();
+ }
+ }
+}
+
+}
diff --git a/src/slic3r/Utils/FlashAir.hpp b/src/slic3r/Utils/FlashAir.hpp
new file mode 100644
index 0000000000..14e3f00156
--- /dev/null
+++ b/src/slic3r/Utils/FlashAir.hpp
@@ -0,0 +1,42 @@
+#ifndef slic3r_FlashAir_hpp_
+#define slic3r_FlashAir_hpp_
+
+#include
+#include
+
+#include "PrintHost.hpp"
+
+
+namespace Slic3r {
+
+class DynamicPrintConfig;
+class Http;
+
+class FlashAir : public PrintHost
+{
+public:
+ FlashAir(DynamicPrintConfig *config);
+ ~FlashAir() override = default;
+
+ const char* get_name() const override;
+
+ bool test(wxString &curl_msg) const override;
+ wxString get_test_ok_msg() const override;
+ wxString get_test_failed_msg(wxString &msg) const override;
+ bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
+ bool has_auto_discovery() const override { return false; }
+ bool can_test() const override { return true; }
+ PrintHostPostUploadActions get_post_upload_actions() const override { return {}; }
+ std::string get_host() const override { return host; }
+
+private:
+ std::string host;
+
+ std::string timestamp_str() const;
+ std::string make_url(const std::string &path) const;
+ std::string make_url(const std::string &path, const std::string &arg, const std::string &val) const;
+};
+
+}
+
+#endif
diff --git a/src/slic3r/Utils/MKS.cpp b/src/slic3r/Utils/MKS.cpp
new file mode 100644
index 0000000000..80a79537d5
--- /dev/null
+++ b/src/slic3r/Utils/MKS.cpp
@@ -0,0 +1,150 @@
+#include "MKS.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "libslic3r/PrintConfig.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/I18N.hpp"
+#include "slic3r/GUI/MsgDialog.hpp"
+#include "Http.hpp"
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+
+namespace Slic3r {
+
+MKS::MKS(DynamicPrintConfig* config) :
+ m_host(config->opt_string("print_host")), m_console_port("8080")
+{}
+
+const char* MKS::get_name() const { return "MKS"; }
+
+bool MKS::test(wxString& msg) const
+{
+ Utils::TCPConsole console(m_host, m_console_port);
+
+ console.enqueue_cmd("M105");
+ bool ret = console.run_queue();
+
+ if (!ret)
+ msg = wxString::FromUTF8(console.error_message().c_str());
+
+ return ret;
+}
+
+wxString MKS::get_test_ok_msg() const
+{
+ return _(L("Connection to MKS works correctly."));
+}
+
+wxString MKS::get_test_failed_msg(wxString& msg) const
+{
+ return GUI::from_u8((boost::format("%s: %s")
+ % _utf8(L("Could not connect to MKS"))
+ % std::string(msg.ToUTF8())).str());
+}
+
+bool MKS::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const
+{
+ bool res = true;
+
+ auto upload_cmd = get_upload_url(upload_data.upload_path.string());
+ BOOST_LOG_TRIVIAL(info) << boost::format("MKS: Uploading file %1%, filepath: %2%, print: %3%, command: %4%")
+ % upload_data.source_path
+ % upload_data.upload_path
+ % (upload_data.post_action == PrintHostPostUploadAction::StartPrint)
+ % upload_cmd;
+
+ auto http = Http::post(std::move(upload_cmd));
+ http.set_post_body(upload_data.source_path);
+
+ http.on_complete([&](std::string body, unsigned status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("MKS: File uploaded: HTTP %1%: %2%") % status % body;
+
+ int err_code = get_err_code_from_body(body);
+ if (err_code != 0) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("MKS: Request completed but error code was received: %1%") % err_code;
+ error_fn(format_error(body, L("Unknown error occured"), 0));
+ res = false;
+ }
+ else if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
+ wxString errormsg;
+ res = start_print(errormsg, upload_data.upload_path.string());
+ if (!res) {
+ error_fn(std::move(errormsg));
+ }
+ }
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("MKS: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ error_fn(format_error(body, error, status));
+ res = false;
+ })
+ .on_progress([&](Http::Progress progress, bool& cancel) {
+ prorgess_fn(std::move(progress), cancel);
+ if (cancel) {
+ // Upload was canceled
+ BOOST_LOG_TRIVIAL(info) << "MKS: Upload canceled";
+ res = false;
+ }
+ }).perform_sync();
+
+
+ return res;
+}
+
+std::string MKS::get_upload_url(const std::string& filename) const
+{
+ return (boost::format("http://%1%/upload?X-Filename=%2%")
+ % m_host
+ % Http::url_encode(filename)).str();
+}
+
+bool MKS::start_print(wxString& msg, const std::string& filename) const
+{
+ // For some reason printer firmware does not want to respond on gcode commands immediately after file upload.
+ // So we just introduce artificial delay to workaround it.
+ // TODO: Inspect reasons
+ std::this_thread::sleep_for(std::chrono::milliseconds(1500));
+
+ Utils::TCPConsole console(m_host, m_console_port);
+
+ console.enqueue_cmd(std::string("M23 ") + filename);
+ console.enqueue_cmd("M24");
+
+ bool ret = console.run_queue();
+
+ if (!ret)
+ msg = wxString::FromUTF8(console.error_message().c_str());
+
+ return ret;
+}
+
+int MKS::get_err_code_from_body(const std::string& body) const
+{
+ pt::ptree root;
+ std::istringstream iss(body); // wrap returned json to istringstream
+ pt::read_json(iss, root);
+
+ return root.get("err", 0);
+}
+
+} // Slic3r
diff --git a/src/slic3r/Utils/MKS.hpp b/src/slic3r/Utils/MKS.hpp
new file mode 100644
index 0000000000..22455436ae
--- /dev/null
+++ b/src/slic3r/Utils/MKS.hpp
@@ -0,0 +1,42 @@
+#ifndef slic3r_MKS_hpp_
+#define slic3r_MKS_hpp_
+
+#include
+#include
+
+#include "PrintHost.hpp"
+#include "TCPConsole.hpp"
+
+namespace Slic3r {
+class DynamicPrintConfig;
+class Http;
+
+class MKS : public PrintHost
+{
+public:
+ explicit MKS(DynamicPrintConfig* config);
+ ~MKS() override = default;
+
+ const char* get_name() const override;
+
+ bool test(wxString& curl_msg) const override;
+ wxString get_test_ok_msg() const override;
+ wxString get_test_failed_msg(wxString& msg) const override;
+ bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
+ bool has_auto_discovery() const override { return false; }
+ bool can_test() const override { return true; }
+ PrintHostPostUploadActions get_post_upload_actions() const override { return PrintHostPostUploadAction::StartPrint; }
+ std::string get_host() const override { return m_host; }
+
+private:
+ std::string m_host;
+ std::string m_console_port;
+
+ std::string get_upload_url(const std::string& filename) const;
+ bool start_print(wxString& msg, const std::string& filename) const;
+ int get_err_code_from_body(const std::string& body) const;
+};
+
+}
+
+#endif
diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp
index aa50b1b1cb..86f6101b6d 100644
--- a/src/slic3r/Utils/PrintHost.cpp
+++ b/src/slic3r/Utils/PrintHost.cpp
@@ -14,11 +14,11 @@
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/Channel.hpp"
#include "OctoPrint.hpp"
-//#include "Duet.hpp"
-//#include "FlashAir.hpp"
-//#include "AstroBox.hpp"
-//#include "Repetier.hpp"
-//#include "MKS.hpp"
+#include "Duet.hpp"
+#include "FlashAir.hpp"
+#include "AstroBox.hpp"
+#include "Repetier.hpp"
+#include "MKS.hpp"
#include "../GUI/PrintHostDialogs.hpp"
namespace fs = boost::filesystem;
@@ -47,12 +47,12 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config)
switch (host_type) {
case htOctoPrint: return new OctoPrint(config);
- //case htDuet: return new Duet(config);
- //case htFlashAir: return new FlashAir(config);
- //case htAstroBox: return new AstroBox(config);
- //case htRepetier: return new Repetier(config);
+ case htDuet: return new Duet(config);
+ case htFlashAir: return new FlashAir(config);
+ case htAstroBox: return new AstroBox(config);
+ case htRepetier: return new Repetier(config);
case htPrusaLink: return new PrusaLink(config);
- //case htMKS: return new MKS(config);
+ case htMKS: return new MKS(config);
default: return nullptr;
}
} else {
diff --git a/src/slic3r/Utils/Repetier.cpp b/src/slic3r/Utils/Repetier.cpp
new file mode 100644
index 0000000000..0569d97fae
--- /dev/null
+++ b/src/slic3r/Utils/Repetier.cpp
@@ -0,0 +1,274 @@
+#include "Repetier.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+
+#include "libslic3r/PrintConfig.hpp"
+#include "slic3r/GUI/I18N.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/format.hpp"
+#include "Http.hpp"
+
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+
+
+namespace Slic3r {
+
+Repetier::Repetier(DynamicPrintConfig *config) :
+ host(config->opt_string("print_host")),
+ apikey(config->opt_string("printhost_apikey")),
+ cafile(config->opt_string("printhost_cafile")),
+ port(config->opt_string("printhost_port"))
+{}
+
+const char* Repetier::get_name() const { return "Repetier"; }
+
+bool Repetier::test(wxString &msg) const
+{
+ // Since the request is performed synchronously here,
+ // it is ok to refer to `msg` from within the closure
+
+ const char *name = get_name();
+
+ bool res = true;
+ auto url = make_url("printer/info");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: List version at: %2%") % name % url;
+
+ auto http = Http::get(std::move(url));
+ set_auth(http);
+
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ res = false;
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&, this](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got version: %2%") % name % body;
+
+ try {
+ std::stringstream ss(body);
+ pt::ptree ptree;
+ pt::read_json(ss, ptree);
+
+ const auto text = ptree.get_optional("name");
+ res = validate_version_text(text);
+ if (! res) {
+ msg = GUI::from_u8((boost::format(_utf8(L("Mismatched type of print host: %s"))) % (text ? *text : "Repetier")).str());
+ }
+ }
+ catch (const std::exception &) {
+ res = false;
+ msg = "Could not parse server response";
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+wxString Repetier::get_test_ok_msg () const
+{
+ return _(L("Connection to Repetier works correctly."));
+}
+
+wxString Repetier::get_test_failed_msg (wxString &msg) const
+{
+ return GUI::from_u8((boost::format("%s: %s\n\n%s")
+ % _utf8(L("Could not connect to Repetier"))
+ % std::string(msg.ToUTF8())
+ % _utf8(L("Note: Repetier version at least 0.90.0 is required."))).str());
+}
+
+bool Repetier::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const
+{
+ const char *name = get_name();
+
+ const auto upload_filename = upload_data.upload_path.filename();
+ const auto upload_parent_path = upload_data.upload_path.parent_path();
+
+ wxString test_msg;
+ if (! test(test_msg)) {
+ error_fn(std::move(test_msg));
+ return false;
+ }
+
+ bool res = true;
+
+ auto url = upload_data.post_action == PrintHostPostUploadAction::StartPrint
+ ? make_url((boost::format("printer/job/%1%") % port).str())
+ : make_url((boost::format("printer/model/%1%") % port).str());
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%, group: %7%")
+ % name
+ % upload_data.source_path
+ % url
+ % upload_filename.string()
+ % upload_parent_path.string()
+ % (upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false")
+ % upload_data.group;
+
+ auto http = Http::post(std::move(url));
+ set_auth(http);
+
+ if (! upload_data.group.empty() && upload_data.group != _utf8(L("Default"))) {
+ http.form_add("group", upload_data.group);
+ }
+
+ if(upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
+ http.form_add("name", upload_filename.string());
+ }
+
+ http.form_add("a", "upload")
+ .form_add_file("filename", upload_data.source_path.string(), upload_filename.string())
+ .on_complete([&](std::string body, unsigned status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body;
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error uploading file: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ error_fn(format_error(body, error, status));
+ res = false;
+ })
+ .on_progress([&](Http::Progress progress, bool &cancel) {
+ prorgess_fn(std::move(progress), cancel);
+ if (cancel) {
+ // Upload was canceled
+ BOOST_LOG_TRIVIAL(info) << "Repetier: Upload canceled";
+ res = false;
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+bool Repetier::validate_version_text(const boost::optional &version_text) const
+{
+ return version_text ? boost::starts_with(*version_text, "Repetier") : true;
+}
+
+void Repetier::set_auth(Http &http) const
+{
+ http.header("X-Api-Key", apikey);
+
+ if (! cafile.empty()) {
+ http.ca_file(cafile);
+ }
+}
+
+std::string Repetier::make_url(const std::string &path) const
+{
+ if (host.find("http://") == 0 || host.find("https://") == 0) {
+ if (host.back() == '/') {
+ return (boost::format("%1%%2%") % host % path).str();
+ } else {
+ return (boost::format("%1%/%2%") % host % path).str();
+ }
+ } else {
+ return (boost::format("http://%1%/%2%") % host % path).str();
+ }
+}
+
+bool Repetier::get_groups(wxArrayString& groups) const
+{
+ bool res = true;
+
+ const char *name = get_name();
+ auto url = make_url((boost::format("printer/api/%1%") % port).str());
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get groups at: %2%") % name % url;
+
+ auto http = Http::get(std::move(url));
+ set_auth(http);
+ http.form_add("a", "listModelGroups");
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ })
+ .on_complete([&](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got groups: %2%") % name % body;
+
+ try {
+ std::stringstream ss(body);
+ pt::ptree ptree;
+ pt::read_json(ss, ptree);
+
+ BOOST_FOREACH(boost::property_tree::ptree::value_type &v, ptree.get_child("groupNames.")) {
+ if (v.second.data() == "#") {
+ groups.push_back(_utf8(L("Default")));
+ } else {
+ // Is it safe to assume that the data are utf-8 encoded?
+ groups.push_back(GUI::from_u8(v.second.data()));
+ }
+ }
+ }
+ catch (const std::exception &) {
+ //msg = "Could not parse server response";
+ res = false;
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+bool Repetier::get_printers(wxArrayString& printers) const
+{
+ const char *name = get_name();
+
+ bool res = true;
+ auto url = make_url("printer/list");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1%: List printers at: %2%") % name % url;
+
+ auto http = Http::get(std::move(url));
+ set_auth(http);
+
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error listing printers: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
+ res = false;
+ })
+ .on_complete([&](std::string body, unsigned http_status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got printers: %2%, HTTP status: %3%") % name % body % http_status;
+
+ if (http_status != 200)
+ throw HostNetworkError(GUI::format(_L("HTTP status: %1%\nMessage body: \"%2%\""), http_status, body));
+
+ std::stringstream ss(body);
+ pt::ptree ptree;
+ try {
+ pt::read_json(ss, ptree);
+ } catch (const pt::ptree_error &err) {
+ throw HostNetworkError(GUI::format(_L("Parsing of host response failed.\nMessage body: \"%1%\"\nError: \"%2%\""), body, err.what()));
+ }
+
+ const auto error = ptree.get_optional("error");
+ if (error)
+ throw HostNetworkError(*error);
+
+ try {
+ BOOST_FOREACH(boost::property_tree::ptree::value_type &v, ptree.get_child("data.")) {
+ const auto port = v.second.get("slug");
+ printers.push_back(Slic3r::GUI::from_u8(port));
+ }
+ } catch (const std::exception &err) {
+ throw HostNetworkError(GUI::format(_L("Enumeration of host printers failed.\nMessage body: \"%1%\"\nError: \"%2%\""), body, err.what()));
+ }
+ })
+ .perform_sync();
+
+ return res;
+}
+
+}
diff --git a/src/slic3r/Utils/Repetier.hpp b/src/slic3r/Utils/Repetier.hpp
new file mode 100644
index 0000000000..6f33102604
--- /dev/null
+++ b/src/slic3r/Utils/Repetier.hpp
@@ -0,0 +1,51 @@
+#ifndef slic3r_Repetier_hpp_
+#define slic3r_Repetier_hpp_
+
+#include
+#include
+#include
+
+#include "PrintHost.hpp"
+
+namespace Slic3r {
+
+class DynamicPrintConfig;
+class Http;
+
+class Repetier : public PrintHost
+{
+public:
+ Repetier(DynamicPrintConfig *config);
+ ~Repetier() override = default;
+
+ const char* get_name() const override;
+
+ bool test(wxString &curl_msg) const override;
+ wxString get_test_ok_msg () const override;
+ wxString get_test_failed_msg (wxString &msg) const override;
+ bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
+ bool has_auto_discovery() const override { return false; }
+ bool can_test() const override { return true; }
+ PrintHostPostUploadActions get_post_upload_actions() const override { return PrintHostPostUploadAction::StartPrint; }
+ bool supports_multiple_printers() const override { return true; }
+ std::string get_host() const override { return host; }
+
+ bool get_groups(wxArrayString &groups) const override;
+ bool get_printers(wxArrayString &printers) const override;
+
+protected:
+ virtual bool validate_version_text(const boost::optional &version_text) const;
+
+private:
+ std::string host;
+ std::string apikey;
+ std::string cafile;
+ std::string port;
+
+ void set_auth(Http &http) const;
+ std::string make_url(const std::string &path) const;
+};
+
+}
+
+#endif
diff --git a/src/slic3r/Utils/Serial.cpp b/src/slic3r/Utils/Serial.cpp
new file mode 100644
index 0000000000..4db1acc6b6
--- /dev/null
+++ b/src/slic3r/Utils/Serial.cpp
@@ -0,0 +1,504 @@
+#include "Serial.hpp"
+
+#include "libslic3r/Exception.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#if _WIN32
+ #include
+ #include
+ #include
+ #include
+ #include
+ // Undefine min/max macros incompatible with the standard library
+ // For example, std::numeric_limits::max()
+ // produces some weird errors
+ #ifdef min
+ #undef min
+ #endif
+ #ifdef max
+ #undef max
+ #endif
+ #include "boost/nowide/convert.hpp"
+ #pragma comment(lib, "user32.lib")
+#elif __APPLE__
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+#endif
+
+#ifndef _WIN32
+ #include
+ #include
+ #include
+ #include
+#endif
+
+#if defined(__APPLE__) || defined(__OpenBSD__)
+ #include
+#elif defined __linux__
+ #include
+ #include
+#endif
+
+using boost::optional;
+
+
+namespace Slic3r {
+namespace Utils {
+
+static bool looks_like_printer(const std::string &friendly_name)
+{
+ return friendly_name.find("Original Prusa") != std::string::npos;
+}
+
+#if _WIN32
+void parse_hardware_id(const std::string &hardware_id, SerialPortInfo &spi)
+{
+ unsigned vid, pid;
+ std::regex pattern("USB\\\\.*VID_([[:xdigit:]]+)&PID_([[:xdigit:]]+).*");
+ std::smatch matches;
+ if (std::regex_match(hardware_id, matches, pattern)) {
+ vid = std::stoul(matches[1].str(), 0, 16);
+ pid = std::stoul(matches[2].str(), 0, 16);
+ spi.id_vendor = vid;
+ spi.id_product = pid;
+ }
+}
+#endif
+
+#ifdef __linux__
+optional sysfs_tty_prop(const std::string &tty_dev, const std::string &name)
+{
+ const auto prop_path = (boost::format("/sys/class/tty/%1%/device/../%2%") % tty_dev % name).str();
+ std::ifstream file(prop_path);
+ std::string res;
+
+ std::getline(file, res);
+ if (file.good()) { return res; }
+ else { return boost::none; }
+}
+
+optional sysfs_tty_prop_hex(const std::string &tty_dev, const std::string &name)
+{
+ auto prop = sysfs_tty_prop(tty_dev, name);
+ if (!prop) { return boost::none; }
+
+ try { return std::stoul(*prop, 0, 16); }
+ catch (const std::exception&) { return boost::none; }
+}
+#endif
+
+std::vector scan_serial_ports_extended()
+{
+ std::vector output;
+
+#ifdef _WIN32
+ SP_DEVINFO_DATA devInfoData = { 0 };
+ devInfoData.cbSize = sizeof(devInfoData);
+ // Get the tree containing the info for the ports.
+ HDEVINFO hDeviceInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, 0, nullptr, DIGCF_PRESENT);
+ if (hDeviceInfo != INVALID_HANDLE_VALUE) {
+ // Iterate over all the devices in the tree.
+ for (int nDevice = 0; SetupDiEnumDeviceInfo(hDeviceInfo, nDevice, &devInfoData); ++ nDevice) {
+ SerialPortInfo port_info;
+ // Get the registry key which stores the ports settings.
+ HKEY hDeviceKey = SetupDiOpenDevRegKey(hDeviceInfo, &devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
+ if (hDeviceKey) {
+ // Read in the name of the port.
+ wchar_t pszPortName[4096];
+ DWORD dwSize = sizeof(pszPortName);
+ DWORD dwType = 0;
+ if (RegQueryValueEx(hDeviceKey, L"PortName", NULL, &dwType, (LPBYTE)pszPortName, &dwSize) == ERROR_SUCCESS)
+ port_info.port = boost::nowide::narrow(pszPortName);
+ RegCloseKey(hDeviceKey);
+ if (port_info.port.empty())
+ continue;
+ }
+
+ // Find the size required to hold the device info.
+ DWORD regDataType;
+ DWORD reqSize = 0;
+ SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, nullptr, nullptr, 0, &reqSize);
+ std::vector hardware_id(reqSize > 1 ? reqSize : 1);
+ // Now store it in a buffer.
+ if (! SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, ®DataType, (BYTE*)hardware_id.data(), reqSize, nullptr))
+ continue;
+ parse_hardware_id(boost::nowide::narrow(hardware_id.data()), port_info);
+
+ // Find the size required to hold the friendly name.
+ reqSize = 0;
+ SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &reqSize);
+ std::vector friendly_name;
+ friendly_name.reserve(reqSize > 1 ? reqSize : 1);
+ // Now store it in a buffer.
+ if (! SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, (BYTE*)friendly_name.data(), reqSize, nullptr)) {
+ port_info.friendly_name = port_info.port;
+ } else {
+ port_info.friendly_name = boost::nowide::narrow(friendly_name.data());
+ port_info.is_printer = looks_like_printer(port_info.friendly_name);
+ }
+ output.emplace_back(std::move(port_info));
+ }
+ }
+#elif __APPLE__
+ // inspired by https://sigrok.org/wiki/Libserialport
+ CFMutableDictionaryRef classes = IOServiceMatching(kIOSerialBSDServiceValue);
+ if (classes != 0) {
+ io_iterator_t iter;
+ if (IOServiceGetMatchingServices(kIOMasterPortDefault, classes, &iter) == KERN_SUCCESS) {
+ io_object_t port;
+ while ((port = IOIteratorNext(iter)) != 0) {
+ CFTypeRef cf_property = IORegistryEntryCreateCFProperty(port, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
+ if (cf_property) {
+ char path[PATH_MAX];
+ Boolean result = CFStringGetCString((CFStringRef)cf_property, path, sizeof(path), kCFStringEncodingUTF8);
+ CFRelease(cf_property);
+ if (result) {
+ SerialPortInfo port_info;
+ port_info.port = path;
+
+ // Attempt to read out the device friendly name
+ if ((cf_property = IORegistryEntrySearchCFProperty(port, kIOServicePlane,
+ CFSTR("USB Interface Name"), kCFAllocatorDefault,
+ kIORegistryIterateRecursively | kIORegistryIterateParents)) ||
+ (cf_property = IORegistryEntrySearchCFProperty(port, kIOServicePlane,
+ CFSTR("USB Product Name"), kCFAllocatorDefault,
+ kIORegistryIterateRecursively | kIORegistryIterateParents)) ||
+ (cf_property = IORegistryEntrySearchCFProperty(port, kIOServicePlane,
+ CFSTR("Product Name"), kCFAllocatorDefault,
+ kIORegistryIterateRecursively | kIORegistryIterateParents)) ||
+ (cf_property = IORegistryEntryCreateCFProperty(port,
+ CFSTR(kIOTTYDeviceKey), kCFAllocatorDefault, 0))) {
+ // Description limited to 127 char, anything longer would not be user friendly anyway.
+ char description[128];
+ if (CFStringGetCString((CFStringRef)cf_property, description, sizeof(description), kCFStringEncodingUTF8)) {
+ port_info.friendly_name = std::string(description) + " (" + port_info.port + ")";
+ port_info.is_printer = looks_like_printer(port_info.friendly_name);
+ }
+ CFRelease(cf_property);
+ }
+ if (port_info.friendly_name.empty())
+ port_info.friendly_name = port_info.port;
+
+ // Attempt to read out the VID & PID
+ int vid, pid;
+ auto cf_vendor = IORegistryEntrySearchCFProperty(port, kIOServicePlane, CFSTR("idVendor"),
+ kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents);
+ auto cf_product = IORegistryEntrySearchCFProperty(port, kIOServicePlane, CFSTR("idProduct"),
+ kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents);
+ if (cf_vendor && cf_product) {
+ if (CFNumberGetValue((CFNumberRef)cf_vendor, kCFNumberIntType, &vid) &&
+ CFNumberGetValue((CFNumberRef)cf_product, kCFNumberIntType, &pid)) {
+ port_info.id_vendor = vid;
+ port_info.id_product = pid;
+ }
+ }
+ if (cf_vendor) { CFRelease(cf_vendor); }
+ if (cf_product) { CFRelease(cf_product); }
+
+ output.emplace_back(std::move(port_info));
+ }
+ }
+ IOObjectRelease(port);
+ }
+ }
+ }
+#else
+ // UNIX / Linux
+ std::initializer_list prefixes { "ttyUSB" , "ttyACM", "tty.", "cu.", "rfcomm" };
+ for (auto &dir_entry : boost::filesystem::directory_iterator(boost::filesystem::path("/dev"))) {
+ std::string name = dir_entry.path().filename().string();
+ for (const char *prefix : prefixes) {
+ if (boost::starts_with(name, prefix)) {
+ const auto path = dir_entry.path().string();
+ SerialPortInfo spi;
+ spi.port = path;
+#ifdef __linux__
+ auto friendly_name = sysfs_tty_prop(name, "product");
+ if (friendly_name) {
+ spi.is_printer = looks_like_printer(*friendly_name);
+ spi.friendly_name = (boost::format("%1% (%2%)") % *friendly_name % path).str();
+ } else {
+ spi.friendly_name = path;
+ }
+ auto vid = sysfs_tty_prop_hex(name, "idVendor");
+ auto pid = sysfs_tty_prop_hex(name, "idProduct");
+ if (vid && pid) {
+ spi.id_vendor = *vid;
+ spi.id_product = *pid;
+ }
+#else
+ spi.friendly_name = path;
+#endif
+ output.emplace_back(std::move(spi));
+ break;
+ }
+ }
+ }
+#endif
+
+ output.erase(std::remove_if(output.begin(), output.end(),
+ [](const SerialPortInfo &info) {
+ return boost::starts_with(info.port, "Bluetooth") || boost::starts_with(info.port, "FireFly");
+ }),
+ output.end());
+ return output;
+}
+
+std::vector scan_serial_ports()
+{
+ std::vector ports = scan_serial_ports_extended();
+ std::vector output;
+ output.reserve(ports.size());
+ for (const SerialPortInfo &spi : ports)
+ output.emplace_back(std::move(spi.port));
+ return output;
+}
+
+
+
+// Class Serial
+
+namespace asio = boost::asio;
+using boost::system::error_code;
+
+Serial::Serial(asio::io_service& io_service) :
+ asio::serial_port(io_service)
+{}
+
+Serial::Serial(asio::io_service& io_service, const std::string &name, unsigned baud_rate) :
+ asio::serial_port(io_service, name)
+{
+ set_baud_rate(baud_rate);
+}
+
+Serial::~Serial() {}
+
+void Serial::set_baud_rate(unsigned baud_rate)
+{
+ try {
+ // This does not support speeds > 115200
+ set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
+ } catch (boost::system::system_error &) {
+ auto handle = native_handle();
+
+ auto handle_errno = [](int retval) {
+ if (retval != 0) {
+ throw Slic3r::RuntimeError(
+ (boost::format("Could not set baud rate: %1%") % strerror(errno)).str()
+ );
+ }
+ };
+
+#if __APPLE__
+ termios ios;
+ handle_errno(::tcgetattr(handle, &ios));
+ handle_errno(::cfsetspeed(&ios, baud_rate));
+ speed_t newSpeed = baud_rate;
+ handle_errno(::ioctl(handle, IOSSIOSPEED, &newSpeed));
+ handle_errno(::tcsetattr(handle, TCSANOW, &ios));
+#elif __linux__
+
+ /* The following definitions are kindly borrowed from:
+ /usr/include/asm-generic/termbits.h
+ Unfortunately we cannot just include that one because
+ it would redefine the "struct termios" already defined
+ the already included by Boost.ASIO. */
+#define K_NCCS 19
+ struct termios2 {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[K_NCCS];
+ speed_t c_ispeed;
+ speed_t c_ospeed;
+ };
+#define BOTHER CBAUDEX
+
+ termios2 ios;
+ handle_errno(::ioctl(handle, TCGETS2, &ios));
+ ios.c_ispeed = ios.c_ospeed = baud_rate;
+ ios.c_cflag &= ~CBAUD;
+ ios.c_cflag |= BOTHER | CLOCAL | CREAD;
+ ios.c_cc[VMIN] = 1; // Minimum of characters to read, prevents eof errors when 0 bytes are read
+ ios.c_cc[VTIME] = 1;
+ handle_errno(::ioctl(handle, TCSETS2, &ios));
+
+#elif __OpenBSD__
+ struct termios ios;
+ handle_errno(::tcgetattr(handle, &ios));
+ handle_errno(::cfsetspeed(&ios, baud_rate));
+ handle_errno(::tcsetattr(handle, TCSAFLUSH, &ios));
+#else
+ throw Slic3r::RuntimeError("Custom baud rates are not currently supported on this OS");
+#endif
+ }
+}
+
+
+/*
+void Serial::set_DTR(bool on)
+{
+ auto handle = native_handle();
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ if (! EscapeCommFunction(handle, on ? SETDTR : CLRDTR)) {
+ throw Slic3r::RuntimeError("Could not set serial port DTR");
+ }
+#else
+ int status;
+ if (::ioctl(handle, TIOCMGET, &status) == 0) {
+ on ? status |= TIOCM_DTR : status &= ~TIOCM_DTR;
+ if (::ioctl(handle, TIOCMSET, &status) == 0) {
+ return;
+ }
+ }
+
+ throw Slic3r::RuntimeError(
+ (boost::format("Could not set serial port DTR: %1%") % strerror(errno)).str()
+ );
+#endif
+}
+
+void Serial::reset_line_num()
+{
+ // See https://github.com/MarlinFirmware/Marlin/wiki/M110
+ write_string("M110 N0\n");
+ m_line_num = 0;
+}
+
+bool Serial::read_line(unsigned timeout, std::string &line, error_code &ec)
+{
+ auto& io_service =
+#if BOOST_VERSION >= 107000
+ //FIXME this is most certainly wrong!
+ (boost::asio::io_context&)this->get_executor().context();
+ #else
+ this->get_io_service();
+#endif
+ asio::deadline_timer timer(io_service);
+ char c = 0;
+ bool fail = false;
+
+ while (true) {
+ io_service.reset();
+
+ asio::async_read(*this, boost::asio::buffer(&c, 1), [&](const error_code &read_ec, size_t size) {
+ if (ec || size == 0) {
+ fail = true;
+ ec = read_ec; // FIXME: only if operation not aborted
+ }
+ timer.cancel(); // FIXME: ditto
+ });
+
+ if (timeout > 0) {
+ timer.expires_from_now(boost::posix_time::milliseconds(timeout));
+ timer.async_wait([&](const error_code &ec) {
+ // Ignore timer aborts
+ if (!ec) {
+ fail = true;
+ this->cancel();
+ }
+ });
+ }
+
+ io_service.run();
+
+ if (fail) {
+ return false;
+ } else if (c != '\n') {
+ line += c;
+ } else {
+ return true;
+ }
+ }
+}
+
+void Serial::printer_setup()
+{
+ printer_reset();
+ write_string("\r\r\r\r\r\r\r\r\r\r"); // Gets rid of line noise, if any
+}
+
+size_t Serial::write_string(const std::string &str)
+{
+ // TODO: might be wise to timeout here as well
+ return asio::write(*this, asio::buffer(str));
+}
+
+bool Serial::printer_ready_wait(unsigned retries, unsigned timeout)
+{
+ std::string line;
+ error_code ec;
+
+ for (; retries > 0; retries--) {
+ reset_line_num();
+
+ while (read_line(timeout, line, ec)) {
+ if (line == "ok") {
+ return true;
+ }
+ line.clear();
+ }
+
+ line.clear();
+ }
+
+ return false;
+}
+
+size_t Serial::printer_write_line(const std::string &line, unsigned line_num)
+{
+ const auto formatted_line = Utils::Serial::printer_format_line(line, line_num);
+ return write_string(formatted_line);
+}
+
+size_t Serial::printer_write_line(const std::string &line)
+{
+ m_line_num++;
+ return printer_write_line(line, m_line_num);
+}
+
+void Serial::printer_reset()
+{
+ this->set_DTR(false);
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ this->set_DTR(true);
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ this->set_DTR(false);
+ std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+}
+
+std::string Serial::printer_format_line(const std::string &line, unsigned line_num)
+{
+ const auto line_num_str = std::to_string(line_num);
+
+ unsigned checksum = 'N';
+ for (auto c : line_num_str) { checksum ^= c; }
+ checksum ^= ' ';
+ for (auto c : line) { checksum ^= c; }
+
+ return (boost::format("N%1% %2%*%3%\n") % line_num_str % line % checksum).str();
+}
+*/
+
+
+} // namespace Utils
+} // namespace Slic3r
diff --git a/src/slic3r/Utils/Serial.hpp b/src/slic3r/Utils/Serial.hpp
new file mode 100644
index 0000000000..8bad75b315
--- /dev/null
+++ b/src/slic3r/Utils/Serial.hpp
@@ -0,0 +1,97 @@
+#ifndef slic3r_GUI_Utils_Serial_hpp_
+#define slic3r_GUI_Utils_Serial_hpp_
+
+#include
+#include
+#include
+#include
+
+
+namespace Slic3r {
+namespace Utils {
+
+struct SerialPortInfo {
+ std::string port;
+ unsigned id_vendor = -1;
+ unsigned id_product = -1;
+ std::string friendly_name;
+ bool is_printer = false;
+
+ SerialPortInfo() {}
+ SerialPortInfo(std::string port) : port(port), friendly_name(std::move(port)) {}
+
+ bool id_match(unsigned id_vendor, unsigned id_product) const { return id_vendor == this->id_vendor && id_product == this->id_product; }
+};
+
+inline bool operator==(const SerialPortInfo &sp1, const SerialPortInfo &sp2)
+{
+ return
+ sp1.port == sp2.port &&
+ sp1.id_vendor == sp2.id_vendor &&
+ sp1.id_product == sp2.id_product &&
+ sp1.is_printer == sp2.is_printer;
+}
+
+extern std::vector scan_serial_ports();
+extern std::vector scan_serial_ports_extended();
+
+
+class Serial : public boost::asio::serial_port
+{
+public:
+ Serial(boost::asio::io_service &io_service);
+ Serial(boost::asio::io_service &io_service, const std::string &name, unsigned baud_rate);
+ Serial(const Serial &) = delete;
+ Serial &operator=(const Serial &) = delete;
+ ~Serial();
+
+ void set_baud_rate(unsigned baud_rate);
+
+ // The Serial implementation is currently in disarray and therefore commented out.
+ // The boost implementation seems to have several problems, such as lack of support
+ // for custom baud rates, few weird implementation bugs and a history of API breakages.
+ // It's questionable whether it solves more problems than causes. Probably not.
+ // TODO: Custom implementation not based on asio.
+ //
+ // As of now, this class is only kept for the purpose of rebooting AVR109,
+ // see FirmwareDialog::priv::avr109_reboot()
+
+/*
+ void set_DTR(bool on);
+
+ // Resets the line number both internally as well as with the firmware using M110
+ void reset_line_num();
+
+ // Reads a line or times out, the timeout is in milliseconds
+ bool read_line(unsigned timeout, std::string &line, boost::system::error_code &ec);
+
+ // Perform an initial setup for communicating with a printer
+ void printer_setup();
+
+ // Write data from a string
+ size_t write_string(const std::string &str);
+
+ // Attempts to reset the line numer and waits until the printer says "ok"
+ bool printer_ready_wait(unsigned retries, unsigned timeout);
+
+ // Write Marlin-formatted line, with a line number and a checksum
+ size_t printer_write_line(const std::string &line, unsigned line_num);
+
+ // Same as above, but with internally-managed line number
+ size_t printer_write_line(const std::string &line);
+
+ // Toggles DTR to reset the printer
+ void printer_reset();
+
+ // Formats a line Marlin-style, ie. with a sequential number and a checksum
+ static std::string printer_format_line(const std::string &line, unsigned line_num);
+private:
+ unsigned m_line_num = 0;
+*/
+};
+
+
+} // Utils
+} // Slic3r
+
+#endif /* slic3r_GUI_Utils_Serial_hpp_ */
diff --git a/version.inc b/version.inc
index 02813d839f..fe04c4d142 100644
--- a/version.inc
+++ b/version.inc
@@ -11,3 +11,4 @@ if(NOT DEFINED BBL_INTERNAL_TESTING)
set(BBL_INTERNAL_TESTING "1")
endif()
set(SLIC3R_VERSION "01.03.00.12")
+set(SoftFever_VERSION "1.3.2-beta")