diff --git a/README.md b/README.md index 5c2cc0469f..d64ac1daad 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,139 @@ -![image](https://user-images.githubusercontent.com/106916061/179006347-497d24c0-9bd6-45b7-8c49-d5cc8ecfe5d7.png) +# 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](./SoftFever_doc/accelerations.png) +![image](./SoftFever_doc/printers1.png) +![image](./SoftFever_doc/printers2.png) +![image](./SoftFever_doc/printers3.png) +![image](./SoftFever_doc/printers4.png) +![image](./SoftFever_doc/voron.png) + + + +Image credits: + 1. Voron 2.4 and Trident: vorondesign.com + 3. Voron 0.1: myself + 4. Prusa MK3S: Prusa3d + + +=========================SPLIT========================= + +![image](https://user-images.githubusercontent.com/106916061/179006347-497d24c0-9bd6-45b7-8c49-d5cc8ecfe5d7.png) # 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 @@ + + + + + + image/svg+xml + + MK3_bottom + + + + + MK3_bottom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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")