mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-19 06:41:14 -06:00
Merge remote-tracking branch 'BS/v1.7.2'
Signed-off-by: SoftFever <103989404+SoftFever@users.noreply.github.com> # Conflicts: # .github/ISSUE_TEMPLATE/bug_report.md # .github/workflows/build_ubuntu.yml # .gitignore # Containerfile # Dockerfile # README.md # deps/Boost/Boost.cmake # deps/OpenEXR/OpenEXR.cmake # deps/OpenVDB/OpenVDB.cmake # doc/How to build - Mac OS.md # localization/i18n/OrcaSlicer.pot # localization/i18n/de/OrcaSlicer_de.po # localization/i18n/en/OrcaSlicer_en.po # localization/i18n/es/OrcaSlicer_es.po # localization/i18n/fr/OrcaSlicer_fr.po # localization/i18n/hu/OrcaSlicer_hu.po # localization/i18n/it/OrcaSlicer_it.po # localization/i18n/ja/OrcaSlicer_ja.po # localization/i18n/list.txt # localization/i18n/nl/OrcaSlicer_nl.po # localization/i18n/sv/OrcaSlicer_sv.po # localization/i18n/zh_cn/OrcaSlicer_zh_CN.po # resources/i18n/de/BambuStudio.mo # resources/i18n/en/BambuStudio.mo # resources/i18n/es/BambuStudio.mo # resources/i18n/fr/BambuStudio.mo # resources/i18n/hu/BambuStudio.mo # resources/i18n/it/BambuStudio.mo # resources/i18n/ja/BambuStudio.mo # resources/i18n/nl/BambuStudio.mo # resources/i18n/sv/BambuStudio.mo # resources/i18n/zh_cn/BambuStudio.mo # resources/images/im_all_plates_stats.svg # resources/profiles/Anker.json # resources/profiles/Anker/filament/Generic ASA @Anker.json # resources/profiles/Anker/filament/Generic PA @Anker.json # resources/profiles/Anker/filament/Generic PA-CF @Anker.json # resources/profiles/Anker/filament/Generic PC @Anker.json # resources/profiles/Anker/filament/Generic PETG @Anker.json # resources/profiles/Anker/filament/Generic PLA-CF @Anker.json # resources/profiles/Anker/filament/Generic PVA @Anker.json # resources/profiles/Anker/filament/Generic TPU @Anker.json # resources/profiles/Anker/machine/Anker M5 0.4 nozzle.json # resources/profiles/Anker/machine/Anker M5.json # resources/profiles/Anker/machine/Anker M5C 0.4 nozzle.json # resources/profiles/Anker/machine/Anker M5C.json # resources/profiles/Anker/machine/fdm_machine_common.json # resources/profiles/Anker/process/0.05mm Ultradetail @Anker.json # resources/profiles/Anker/process/0.15mm Fast @Anker.json # resources/profiles/Anker/process/0.20mm Fast @Anker.json # resources/profiles/Anker/process/0.20mm Standard @Anker.json # resources/profiles/Anker/process/0.25mm Fast @Anker.json # resources/profiles/Anker/process/fdm_process_common.json # resources/profiles/Anycubic.json # resources/profiles/Anycubic/machine/Anycubic 4Max Pro 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic 4Max Pro 2 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic 4Max Pro 2.json # resources/profiles/Anycubic/machine/Anycubic 4Max Pro.json # resources/profiles/Anycubic/machine/Anycubic Chiron 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic Chiron.json # resources/profiles/Anycubic/machine/Anycubic Kobra 2 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic Kobra Max 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic Kobra Max.json # resources/profiles/Anycubic/machine/Anycubic Vyper 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic Vyper.json # resources/profiles/Anycubic/machine/Anycubic i3 Mega S 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic i3 Mega S.json # resources/profiles/Anycubic/machine/fdm_machine_common.json # resources/profiles/Anycubic/process/0.15mm Optimal @Anycubic 4MaxPro2.json # resources/profiles/Anycubic/process/0.15mm Optimal @Anycubic Chiron.json # resources/profiles/Anycubic/process/0.15mm Optimal @Anycubic Kobra2.json # resources/profiles/Anycubic/process/0.15mm Optimal @Anycubic KobraMax.json # resources/profiles/Anycubic/process/0.15mm Optimal @Anycubic Vyper.json # resources/profiles/Anycubic/process/0.15mm Optimal @Anycubic i3MegaS.json # resources/profiles/Anycubic/process/0.20mm Standard @Anycubic 4MaxPro.json # resources/profiles/Anycubic/process/0.20mm Standard @Anycubic 4MaxPro2.json # resources/profiles/Anycubic/process/0.20mm Standard @Anycubic Chiron.json # resources/profiles/Anycubic/process/0.20mm Standard @Anycubic Kobra2.json # resources/profiles/Anycubic/process/0.20mm Standard @Anycubic KobraMax.json # resources/profiles/Anycubic/process/0.20mm Standard @Anycubic Vyper.json # resources/profiles/Anycubic/process/0.20mm Standard @Anycubic i3MegaS.json # resources/profiles/Anycubic/process/0.30mm Draft @Anycubic 4MaxPro2.json # resources/profiles/Anycubic/process/0.30mm Draft @Anycubic Chiron.json # resources/profiles/Anycubic/process/0.30mm Draft @Anycubic Kobra2.json # resources/profiles/Anycubic/process/0.30mm Draft @Anycubic KobraMax.json # resources/profiles/Anycubic/process/0.30mm Draft @Anycubic Vyper.json # resources/profiles/Anycubic/process/0.30mm Draft @Anycubic i3MegaS.json # resources/profiles/Anycubic/process/fdm_process_common.json # resources/profiles/BBL.json # resources/profiles/BBL/process/fdm_process_bbl_common.json # resources/profiles/Creality.json # resources/profiles/Creality/filament/fdm_filament_abs.json # resources/profiles/Creality/filament/fdm_filament_pla.json # resources/profiles/Creality/machine/Creality CR-10 Max 0.4 nozzle.json # resources/profiles/Creality/machine/Creality CR-10 Max.json # resources/profiles/Creality/machine/Creality CR-10 V2 0.4 nozzle.json # resources/profiles/Creality/machine/Creality CR-10 V2.json # resources/profiles/Creality/machine/Creality Ender-3 S1 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-3 S1 Pro 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-3 S1 Pro.json # resources/profiles/Creality/machine/Creality Ender-3 S1.json # resources/profiles/Creality/machine/Creality Ender-3 V2 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-3 V2.json # resources/profiles/Creality/machine/Creality Ender-5 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-5 Plus 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-5 Plus.json # resources/profiles/Creality/machine/Creality Ender-5 S1 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-5 S1.json # resources/profiles/Creality/machine/Creality Ender-5.json # resources/profiles/Creality/machine/Creality Ender-5S 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-5S.json # resources/profiles/Creality/machine/Creality Ender-6 0.4 nozzle.json # resources/profiles/Creality/machine/Creality Ender-6.json # resources/profiles/Creality/machine/fdm_creality_common.json # resources/profiles/Creality/machine/fdm_machine_common.json # resources/profiles/Creality/process/0.12mm Fine @Creality CR10Max.json # resources/profiles/Creality/process/0.12mm Fine @Creality Ender3V2.json # resources/profiles/Creality/process/0.15mm Optimal @Creality CR10Max.json # resources/profiles/Creality/process/0.15mm Optimal @Creality Ender3V2.json # resources/profiles/Creality/process/0.16mm Optimal @Creality CR10V2.json # resources/profiles/Creality/process/0.16mm Optimal @Creality Ender3S1.json # resources/profiles/Creality/process/0.16mm Optimal @Creality Ender3S1Pro.json # resources/profiles/Creality/process/0.16mm Optimal @Creality Ender5.json # resources/profiles/Creality/process/0.16mm Optimal @Creality Ender5Plus.json # resources/profiles/Creality/process/0.16mm Optimal @Creality Ender5S.json # resources/profiles/Creality/process/0.16mm Optimal @Creality Ender5S1.json # resources/profiles/Creality/process/0.16mm Optimal @Creality Ender6.json # resources/profiles/Creality/process/0.20mm Standard @Creality CR10Max.json # resources/profiles/Creality/process/0.20mm Standard @Creality CR10V2.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender3S1.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender3S1Pro.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender3V2.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender5.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender5Plus.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender5S.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender5S1.json # resources/profiles/Creality/process/0.20mm Standard @Creality Ender6.json # resources/profiles/Creality/process/0.24mm Draft @Creality CR10Max.json # resources/profiles/Creality/process/0.24mm Draft @Creality Ender3V2.json # resources/profiles/Creality/process/0.24mm Draft @Creality.json # resources/profiles/Creality/process/fdm_process_creality_common.json # resources/profiles/Custom/filament/My Generic PETG.json # resources/profiles/Custom/filament/My Generic PLA.json # resources/profiles/Elegoo.json # resources/profiles/Elegoo/filament/fdm_filament_common.json # resources/profiles/Elegoo/machine/Elegoo Neptune 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 2 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 2.json # resources/profiles/Elegoo/machine/Elegoo Neptune 2D 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 2D.json # resources/profiles/Elegoo/machine/Elegoo Neptune 2S 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 2S.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3 Max 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3 Max.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3 Plus 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3 Plus.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3 Pro 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3 Pro.json # resources/profiles/Elegoo/machine/Elegoo Neptune 3.json # resources/profiles/Elegoo/machine/Elegoo Neptune X 0.4 nozzle.json # resources/profiles/Elegoo/machine/Elegoo Neptune X.json # resources/profiles/Elegoo/machine/Elegoo Neptune.json # resources/profiles/Elegoo/machine/fdm_machine_common.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune2.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune2D.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune2S.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune3.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune3Max.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune3Plus.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo Neptune3Pro.json # resources/profiles/Elegoo/process/0.08mm Extra Fine @Elegoo NeptuneX.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune2.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune2D.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune2S.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune3.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune3Max.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune3Plus.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo Neptune3Pro.json # resources/profiles/Elegoo/process/0.12mm Fine @Elegoo NeptuneX.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune2.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune2D.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune2S.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune3.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune3Max.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune3Plus.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo Neptune3Pro.json # resources/profiles/Elegoo/process/0.16mm Optimal @Elegoo NeptuneX.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune2.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune2D.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune2S.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune3.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune3Max.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune3Plus.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo Neptune3Pro.json # resources/profiles/Elegoo/process/0.20mm Standard @Elegoo NeptuneX.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune2.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune2D.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune2S.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune3.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune3Max.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune3Plus.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo Neptune3Pro.json # resources/profiles/Elegoo/process/0.24mm Draft @Elegoo NeptuneX.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune2.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune2D.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune2S.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune3.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune3Max.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune3Plus.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo Neptune3Pro.json # resources/profiles/Elegoo/process/0.28mm Extra Draft @Elegoo NeptuneX.json # resources/profiles/Prusa.json # resources/profiles/Prusa/filament/fdm_filament_common.json # resources/profiles/Prusa/machine/Prusa MINI 0.4 nozzle.json # resources/profiles/Prusa/machine/Prusa MINI.json # resources/profiles/Prusa/machine/Prusa MK3S 0.4 nozzle.json # resources/profiles/Prusa/machine/Prusa MK3S.json # resources/profiles/Prusa/machine/fdm_machine_common.json # resources/profiles/Prusa/process/0.20mm Standard @MINI.json # resources/profiles/Prusa/process/0.20mm Standard @MK3S.json # resources/profiles/Qidi.json # resources/profiles/Qidi/filament/fdm_filament_abs.json # resources/profiles/Qidi/filament/fdm_filament_asa.json # resources/profiles/Qidi/filament/fdm_filament_common.json # resources/profiles/Qidi/filament/fdm_filament_pa.json # resources/profiles/Qidi/filament/fdm_filament_pc.json # resources/profiles/Qidi/filament/fdm_filament_pet.json # resources/profiles/Qidi/filament/fdm_filament_pla.json # resources/profiles/Qidi/filament/fdm_filament_pva.json # resources/profiles/Qidi/filament/fdm_filament_tpu.json # resources/profiles/Qidi/machine/Qidi X-CF Pro 0.4 nozzle.json # resources/profiles/Qidi/machine/Qidi X-CF Pro.json # resources/profiles/Qidi/machine/Qidi X-Max 0.4 nozzle.json # resources/profiles/Qidi/machine/Qidi X-Max 3 0.4 nozzle.json # resources/profiles/Qidi/machine/Qidi X-Max 3.json # resources/profiles/Qidi/machine/Qidi X-Max.json # resources/profiles/Qidi/machine/Qidi X-Plus 0.4 nozzle.json # resources/profiles/Qidi/machine/Qidi X-Plus 3 0.4 nozzle.json # resources/profiles/Qidi/machine/Qidi X-Plus 3.json # resources/profiles/Qidi/machine/Qidi X-Plus.json # resources/profiles/Qidi/machine/Qidi X-Smart 3 0.4 nozzle.json # resources/profiles/Qidi/machine/Qidi X-Smart 3.json # resources/profiles/Qidi/machine/fdm_machine_common.json # resources/profiles/Qidi/machine/fdm_qidi_common.json # resources/profiles/Qidi/machine/fdm_qidi_x3_common.json # resources/profiles/Qidi/process/0.12mm Fine @Qidi XCFPro.json # resources/profiles/Qidi/process/0.12mm Fine @Qidi XMax.json # resources/profiles/Qidi/process/0.12mm Fine @Qidi XMax3.json # resources/profiles/Qidi/process/0.12mm Fine @Qidi XPlus.json # resources/profiles/Qidi/process/0.12mm Fine @Qidi XPlus3.json # resources/profiles/Qidi/process/0.12mm Fine @Qidi XSmart3.json # resources/profiles/Qidi/process/0.16mm Optimal @Qidi XCFPro.json # resources/profiles/Qidi/process/0.16mm Optimal @Qidi XMax.json # resources/profiles/Qidi/process/0.16mm Optimal @Qidi XMax3.json # resources/profiles/Qidi/process/0.16mm Optimal @Qidi XPlus.json # resources/profiles/Qidi/process/0.16mm Optimal @Qidi XPlus3.json # resources/profiles/Qidi/process/0.16mm Optimal @Qidi XSmart3.json # resources/profiles/Qidi/process/0.20mm Standard @Qidi XCFPro.json # resources/profiles/Qidi/process/0.20mm Standard @Qidi XMax.json # resources/profiles/Qidi/process/0.20mm Standard @Qidi XMax3.json # resources/profiles/Qidi/process/0.20mm Standard @Qidi XPlus.json # resources/profiles/Qidi/process/0.20mm Standard @Qidi XPlus3.json # resources/profiles/Qidi/process/0.20mm Standard @Qidi XSmart3.json # resources/profiles/Qidi/process/0.25mm Draft @Qidi XCFPro.json # resources/profiles/Qidi/process/0.25mm Draft @Qidi XMax.json # resources/profiles/Qidi/process/0.25mm Draft @Qidi XMax3.json # resources/profiles/Qidi/process/0.25mm Draft @Qidi XPlus.json # resources/profiles/Qidi/process/0.25mm Draft @Qidi XPlus3.json # resources/profiles/Qidi/process/0.25mm Draft @Qidi XSmart3.json # resources/profiles/Qidi/process/0.30mm Extra Draft @Qidi XCFPro.json # resources/profiles/Qidi/process/0.30mm Extra Draft @Qidi XMax.json # resources/profiles/Qidi/process/0.30mm Extra Draft @Qidi XMax3.json # resources/profiles/Qidi/process/0.30mm Extra Draft @Qidi XPlus.json # resources/profiles/Qidi/process/0.30mm Extra Draft @Qidi XPlus3.json # resources/profiles/Qidi/process/0.30mm Extra Draft @Qidi XSmart3.json # resources/profiles/Qidi/process/fdm_process_common.json # resources/profiles/Qidi/process/fdm_process_qidi_common.json # resources/profiles/Qidi/process/fdm_process_qidi_x3_common.json # resources/profiles/Tronxy/filament/Tronxy Generic ABS.json # resources/profiles/Tronxy/process/0.12mm Fine @Tronxy.json # resources/profiles/Tronxy/process/0.15mm Optimal @Tronxy.json # resources/profiles/Tronxy/process/0.20mm Standard @Tronxy.json # resources/profiles/Tronxy/process/0.24mm Draft @Tronxy.json # resources/profiles/Voron.json # resources/profiles/Voron/filament/Generic ABS @Voron.json # resources/profiles/Voron/filament/Generic ASA @Voron.json # resources/profiles/Voron/filament/Generic PA @Voron.json # resources/profiles/Voron/filament/Generic PETG @Voron.json # resources/profiles/Voron/filament/Generic PVA @Voron.json # resources/profiles/Voron/filament/Voron Generic PA-CF.json # resources/profiles/Voron/filament/Voron Generic PC.json # resources/profiles/Voron/filament/Voron Generic PLA-CF.json # resources/profiles/Voron/filament/Voron Generic PLA.json # resources/profiles/Voron/filament/Voron Generic TPU.json # resources/profiles/Voron/machine/Voron 0.1.json # resources/profiles/Voron/machine/Voron 2.4 250.json # resources/profiles/Voron/machine/Voron 2.4 300.json # resources/profiles/Voron/machine/Voron 2.4 350.json # resources/profiles/Voron/machine/Voron Trident 250.json # resources/profiles/Voron/machine/Voron Trident 300.json # resources/profiles/Voron/machine/Voron Trident 350.json # resources/profiles/Voron/process/fdm_process_voron_common.json # resources/profiles/Voxelab.json # resources/profiles/Voxelab/filament/Generic ABS @Voxelab.json # resources/profiles/Voxelab/filament/Generic PLA @Voxelab.json # resources/profiles/Voxelab/filament/fdm_filament_common.json # resources/profiles/Voxelab/machine/Voxelab Aquila X2 0.4 nozzle.json # resources/profiles/Voxelab/machine/Voxelab Aquila X2.json # resources/profiles/Voxelab/machine/fdm_machine_common.json # resources/profiles/Voxelab/process/0.16mm Optimal @Voxelab AquilaX2.json # resources/profiles/Voxelab/process/0.20mm Standard @Voxelab AquilaX2.json # resources/web/data/text.js # resources/web/guide/21/21.js # resources/web/guide/24/24.js # src/BaseException.cpp # src/OrcaSlicer.cpp # src/libslic3r/AppConfig.cpp # src/libslic3r/BoundingBox.hpp # src/libslic3r/Extruder.hpp # src/libslic3r/Fill/Fill.cpp # src/libslic3r/Format/bbs_3mf.cpp # src/libslic3r/GCode.cpp # src/libslic3r/GCode.hpp # src/libslic3r/GCode/CoolingBuffer.cpp # src/libslic3r/GCode/GCodeProcessor.cpp # src/libslic3r/GCode/GCodeProcessor.hpp # src/libslic3r/GCode/WipeTower.cpp # src/libslic3r/GCodeWriter.cpp # src/libslic3r/GCodeWriter.hpp # src/libslic3r/Model.cpp # src/libslic3r/PerimeterGenerator.cpp # src/libslic3r/Preset.cpp # src/libslic3r/Preset.hpp # src/libslic3r/PresetBundle.cpp # src/libslic3r/PresetBundle.hpp # src/libslic3r/Print.cpp # src/libslic3r/Print.hpp # src/libslic3r/PrintBase.hpp # src/libslic3r/PrintConfig.cpp # src/libslic3r/PrintConfig.hpp # src/libslic3r/PrintObject.cpp # src/libslic3r/TreeSupport.cpp # src/libslic3r/Utils.hpp # src/mcut/CMakeLists.txt # src/slic3r/CMakeLists.txt # src/slic3r/GUI/3DBed.cpp # src/slic3r/GUI/AMSMaterialsSetting.cpp # src/slic3r/GUI/AMSMaterialsSetting.hpp # src/slic3r/GUI/BBLTopbar.cpp # src/slic3r/GUI/BBLTopbar.hpp # src/slic3r/GUI/BackgroundSlicingProcess.hpp # src/slic3r/GUI/BindDialog.cpp # src/slic3r/GUI/ConfigManipulation.cpp # src/slic3r/GUI/DeviceManager.cpp # src/slic3r/GUI/Field.cpp # src/slic3r/GUI/GLCanvas3D.cpp # src/slic3r/GUI/GUI_App.cpp # src/slic3r/GUI/GUI_App.hpp # src/slic3r/GUI/GUI_Factories.cpp # src/slic3r/GUI/GUI_Factories.hpp # src/slic3r/GUI/GUI_ObjectList.cpp # src/slic3r/GUI/Gizmos/GLGizmoMeshBoolean.cpp # src/slic3r/GUI/Jobs/ArrangeJob.cpp # src/slic3r/GUI/Jobs/FillBedJob.cpp # src/slic3r/GUI/MainFrame.cpp # src/slic3r/GUI/MediaPlayCtrl.cpp # src/slic3r/GUI/Monitor.cpp # src/slic3r/GUI/PartPlate.cpp # src/slic3r/GUI/PartPlate.hpp # src/slic3r/GUI/PlateSettingsDialog.cpp # src/slic3r/GUI/PlateSettingsDialog.hpp # src/slic3r/GUI/Plater.cpp # src/slic3r/GUI/Plater.hpp # src/slic3r/GUI/PresetComboBoxes.cpp # src/slic3r/GUI/ReleaseNote.cpp # src/slic3r/GUI/SelectMachine.cpp # src/slic3r/GUI/StatusPanel.cpp # src/slic3r/GUI/Tab.cpp # src/slic3r/GUI/Widgets/Label.cpp # src/slic3r/GUI/Widgets/Label.hpp # src/slic3r/GUI/Widgets/SideButton.cpp # src/slic3r/GUI/calib_dlg.cpp # src/slic3r/GUI/calib_dlg.hpp # src/slic3r/GUI/wxExtensions.hpp # src/slic3r/Utils/NetworkAgent.cpp # src/slic3r/Utils/bambu_networking.hpp # version.inc
This commit is contained in:
commit
e65b11a831
734 changed files with 72573 additions and 47919 deletions
|
@ -38,7 +38,7 @@ using namespace nlohmann;
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
static const std::string VERSION_CHECK_URL = "https://api.github.com/repos/softfever/OrcaSlicer/releases";
|
||||
static const std::string VERSION_CHECK_URL = "";
|
||||
static const std::string MODELS_STR = "models";
|
||||
|
||||
const std::string AppConfig::SECTION_FILAMENTS = "filaments";
|
||||
|
@ -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()
|
||||
|
@ -178,9 +178,6 @@ void AppConfig::set_defaults()
|
|||
set_bool("show_hints", true);
|
||||
//#endif
|
||||
|
||||
if (get("show_gcode_window").empty())
|
||||
set_bool("show_gcode_window", true);
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
|
@ -229,10 +226,6 @@ void AppConfig::set_defaults()
|
|||
set("slicer_uuid", to_string(uuid));
|
||||
}
|
||||
|
||||
// Orca
|
||||
if (get("stealth_mode").empty()) {
|
||||
set_bool("stealth_mode", false);
|
||||
}
|
||||
if (get("show_model_mesh").empty()) {
|
||||
set_bool("show_model_mesh", false);
|
||||
}
|
||||
|
@ -305,6 +298,10 @@ void AppConfig::set_defaults()
|
|||
set("max_recent_count", "18");
|
||||
}
|
||||
|
||||
if (get("staff_pick_switch").empty()) {
|
||||
set_bool("staff_pick_switch", true);
|
||||
}
|
||||
|
||||
if (get("sync_system_preset").empty()) {
|
||||
set_bool("sync_system_preset", true);
|
||||
}
|
||||
|
@ -321,19 +318,15 @@ void AppConfig::set_defaults()
|
|||
set("curr_bed_type", "1");
|
||||
}
|
||||
|
||||
// #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
|
||||
|
||||
if (get("presets", "filament_colors").empty()) {
|
||||
set_str("presets", "filament_colors", "#F2754E");
|
||||
#else
|
||||
if (get("iot_environment").empty()) {
|
||||
set("iot_environment", "1");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (get("print", "bed_leveling").empty()) {
|
||||
set_str("print", "bed_leveling", "1");
|
||||
|
@ -515,11 +508,30 @@ std::string AppConfig::load()
|
|||
m_storage[it.key()][iter.key()] = iter.value().get<std::string>();
|
||||
}
|
||||
}
|
||||
} else if (it.key() == "orca_presets") {
|
||||
for (auto& j_model : it.value()) {
|
||||
m_printer_settings[j_model["machine"].get<std::string>()] = j_model;
|
||||
} else if (it.key() == "calis") {
|
||||
for (auto &calis_j : it.value()) {
|
||||
PrinterCaliInfo cali_info;
|
||||
if (calis_j.contains("dev_id"))
|
||||
cali_info.dev_id = calis_j["dev_id"].get<std::string>();
|
||||
if (calis_j.contains("cali_finished"))
|
||||
cali_info.cali_finished = bool(calis_j["cali_finished"].get<int>());
|
||||
if (calis_j.contains("flow_ratio"))
|
||||
cali_info.cache_flow_ratio = calis_j["flow_ratio"].get<float>();
|
||||
if (calis_j.contains("presets")) {
|
||||
cali_info.selected_presets.clear();
|
||||
for (auto cali_it = calis_j["presets"].begin(); cali_it != calis_j["presets"].end(); cali_it++) {
|
||||
CaliPresetInfo preset_info;
|
||||
preset_info.tray_id = cali_it.value()["tray_id"].get<int>();
|
||||
preset_info.nozzle_diameter = cali_it.value()["nozzle_diameter"].get<float>();
|
||||
preset_info.filament_id = cali_it.value()["filament_id"].get<std::string>();
|
||||
preset_info.setting_id = cali_it.value()["setting_id"].get<std::string>();
|
||||
preset_info.name = cali_it.value()["name"].get<std::string>();
|
||||
cali_info.selected_presets.push_back(preset_info);
|
||||
}
|
||||
}
|
||||
m_printer_cali_infos.emplace_back(cali_info);
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
if (it.value().is_object()) {
|
||||
for (auto iter = it.value().begin(); iter != it.value().end(); iter++) {
|
||||
if (iter.value().is_boolean()) {
|
||||
|
@ -618,6 +630,23 @@ void AppConfig::save()
|
|||
j["app"]["filament_colors"].push_back(filament_color);
|
||||
}
|
||||
|
||||
for (const auto &cali_info : m_printer_cali_infos) {
|
||||
json cali_json;
|
||||
cali_json["dev_id"] = cali_info.dev_id;
|
||||
cali_json["flow_ratio"] = cali_info.cache_flow_ratio;
|
||||
cali_json["cali_finished"] = cali_info.cali_finished ? 1 : 0;
|
||||
for (auto filament_preset : cali_info.selected_presets) {
|
||||
json preset_json;
|
||||
preset_json["tray_id"] = filament_preset.tray_id;
|
||||
preset_json["nozzle_diameter"] = filament_preset.nozzle_diameter;
|
||||
preset_json["filament_id"] = filament_preset.filament_id;
|
||||
preset_json["setting_id"] = filament_preset.setting_id;
|
||||
preset_json["name"] = filament_preset.name;
|
||||
cali_json["presets"].push_back(preset_json);
|
||||
}
|
||||
j["calis"].push_back(cali_json);
|
||||
}
|
||||
|
||||
// Write the other categories.
|
||||
for (const auto& category : m_storage) {
|
||||
if (category.first.empty())
|
||||
|
@ -638,8 +667,7 @@ void AppConfig::save()
|
|||
j[category.first][kvp.first] = kvp.second;
|
||||
}
|
||||
}
|
||||
if(j_filament_array.size() > 0)
|
||||
j["presets"]["filaments"] = j_filament_array;
|
||||
j["presets"]["filaments"] = j_filament_array;
|
||||
continue;
|
||||
}
|
||||
for (const auto& kvp : category.second) {
|
||||
|
@ -674,10 +702,6 @@ void AppConfig::save()
|
|||
}
|
||||
}
|
||||
|
||||
// write machine settings
|
||||
for (const auto& preset : m_printer_settings) {
|
||||
j["orca_presets"].push_back(preset.second);
|
||||
}
|
||||
boost::nowide::ofstream c;
|
||||
c.open(path_pid, std::ios::out | std::ios::trunc);
|
||||
c << std::setw(4) << j << std::endl;
|
||||
|
@ -945,6 +969,22 @@ void AppConfig::set_vendors(const AppConfig &from)
|
|||
m_dirty = true;
|
||||
}
|
||||
|
||||
void AppConfig::save_printer_cali_infos(const PrinterCaliInfo &cali_info)
|
||||
{
|
||||
auto iter = std::find_if(m_printer_cali_infos.begin(), m_printer_cali_infos.end(), [&cali_info](const PrinterCaliInfo &cali_info_item) {
|
||||
return cali_info_item.dev_id == cali_info.dev_id;
|
||||
});
|
||||
|
||||
if (iter == m_printer_cali_infos.end()) {
|
||||
m_printer_cali_infos.emplace_back(cali_info);
|
||||
} else {
|
||||
(*iter).cali_finished = cali_info.cali_finished;
|
||||
(*iter).cache_flow_ratio = cali_info.cache_flow_ratio;
|
||||
(*iter).selected_presets = cali_info.selected_presets;
|
||||
}
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
std::string AppConfig::get_last_dir() const
|
||||
{
|
||||
const auto it = m_storage.find("recent");
|
||||
|
@ -1088,29 +1128,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")
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/Semver.hpp"
|
||||
#include "Calib.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
|
@ -204,6 +205,9 @@ public:
|
|||
m_dirty = true;
|
||||
}
|
||||
|
||||
const std::vector<PrinterCaliInfo> &get_printer_cali_infos() const { return m_printer_cali_infos; }
|
||||
void save_printer_cali_infos(const PrinterCaliInfo& cali_info);
|
||||
|
||||
// return recent/last_opened_folder or recent/settings_folder or empty string.
|
||||
std::string get_last_dir() const;
|
||||
void update_config_dir(const std::string &dir);
|
||||
|
@ -305,6 +309,8 @@ private:
|
|||
|
||||
std::vector<std::string> m_filament_presets;
|
||||
std::vector<std::string> m_filament_colors;
|
||||
|
||||
std::vector<PrinterCaliInfo> m_printer_cali_infos;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -268,13 +268,13 @@ void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extr
|
|||
{
|
||||
for (const ClipperLib_Z::Path &extrusion_path : extrusion_paths) {
|
||||
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion_path);
|
||||
Slic3r::append(dst, thick_polyline_to_extrusion_paths(thick_polyline, role, flow, scaled<float>(0.05), SCALED_EPSILON));
|
||||
Slic3r::append(dst, thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)).paths);
|
||||
}
|
||||
}
|
||||
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow)
|
||||
{
|
||||
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion);
|
||||
Slic3r::append(dst, thick_polyline_to_extrusion_paths(thick_polyline, role, flow, scaled<float>(0.05), SCALED_EPSILON));
|
||||
Slic3r::append(dst, thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)).paths);
|
||||
}
|
||||
} // namespace Slic3r
|
|
@ -70,23 +70,14 @@ public:
|
|||
return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) ||
|
||||
this->max(1) < other.min(1) || this->min(1) > other.max(1));
|
||||
}
|
||||
PointClass operator[](size_t idx) const {
|
||||
PointClass operator[](size_t idx) const
|
||||
{
|
||||
switch (idx) {
|
||||
case 0:
|
||||
return min;
|
||||
break;
|
||||
case 1:
|
||||
return PointClass(max(0), min(1));
|
||||
break;
|
||||
case 2:
|
||||
return max;
|
||||
break;
|
||||
case 3:
|
||||
return PointClass(min(0), max(1));
|
||||
break;
|
||||
default:
|
||||
return PointClass();
|
||||
break;
|
||||
case 0: return min; break;
|
||||
case 1: return PointClass(max(0), min(1)); break;
|
||||
case 2: return max; break;
|
||||
case 3: return PointClass(min(0), max(1)); break;
|
||||
default: return PointClass(); break;
|
||||
}
|
||||
return PointClass();
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ void make_brim(const Print& print, PrintTryCancel try_cancel,
|
|||
std::vector<unsigned int>& printExtruders);
|
||||
|
||||
// BBS: automatically make brim
|
||||
ExtrusionEntityCollection make_brim_auto(const Print &print, PrintTryCancel try_cancel, Polygons &islands_area);
|
||||
|
||||
ExtrusionEntityCollection make_brim_auto(const Print &print, PrintTryCancel try_cancel, Polygons &islands_area);
|
||||
|
||||
} // Slic3r
|
||||
|
||||
#endif // slic3r_Brim_hpp_
|
||||
|
|
|
@ -37,6 +37,8 @@ set(lisbslic3r_sources
|
|||
Brim.hpp
|
||||
BuildVolume.cpp
|
||||
BuildVolume.hpp
|
||||
Calib.cpp
|
||||
Calib.hpp
|
||||
Circle.cpp
|
||||
Circle.hpp
|
||||
clipper.cpp
|
||||
|
|
748
src/libslic3r/Calib.cpp
Normal file
748
src/libslic3r/Calib.cpp
Normal file
|
@ -0,0 +1,748 @@
|
|||
#include "Calib.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include <cmath>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx)
|
||||
{
|
||||
const double general_suggested_min_speed = 100.0;
|
||||
double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
|
||||
Flow pattern_line = Flow(line_width, layer_height, config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0));
|
||||
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloat>("outer_wall_speed")->value),
|
||||
filament_max_volumetric_speed / pattern_line.mm3_per_mm());
|
||||
|
||||
return std::floor(pa_speed);
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvance::move_to(Vec2d pt, GCodeWriter &writer, std::string comment)
|
||||
{
|
||||
std::stringstream gcode;
|
||||
|
||||
gcode << writer.retract();
|
||||
gcode << writer.travel_to_xy(pt, comment);
|
||||
gcode << writer.unretract();
|
||||
|
||||
m_last_pos = Vec3d(pt.x(), pt.y(), 0);
|
||||
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
double CalibPressureAdvance::e_per_mm(double line_width, double layer_height, float nozzle_diameter, float filament_diameter, float print_flow_ratio) const
|
||||
{
|
||||
const Flow line_flow = Flow(line_width, layer_height, nozzle_diameter);
|
||||
const double filament_area = M_PI * std::pow(filament_diameter / 2, 2);
|
||||
|
||||
return line_flow.mm3_per_mm() / filament_area * print_flow_ratio;
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvance::convert_number_to_string(double num) const
|
||||
{
|
||||
auto sNumber = std::to_string(num);
|
||||
sNumber.erase(sNumber.find_last_not_of('0') + 1, std::string::npos);
|
||||
sNumber.erase(sNumber.find_last_not_of('.') + 1, std::string::npos);
|
||||
|
||||
return sNumber;
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvance::draw_digit(
|
||||
double startx, double starty, char c, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, GCodeWriter &writer)
|
||||
{
|
||||
const double len = m_digit_segment_len;
|
||||
const double gap = line_width / 2.0;
|
||||
|
||||
const auto dE = e_per_mm * len;
|
||||
const auto two_dE = dE * 2;
|
||||
|
||||
Vec2d p0, p1, p2, p3, p4, p5;
|
||||
Vec2d p0_5, p4_5;
|
||||
Vec2d gap_p0_toward_p3, gap_p2_toward_p3;
|
||||
Vec2d dot_direction;
|
||||
|
||||
if (mode == CalibPressureAdvance::DrawDigitMode::Bottom_To_Top) {
|
||||
// 1-------2-------5
|
||||
// | | |
|
||||
// | | |
|
||||
// 0-------3-------4
|
||||
p0 = Vec2d(startx, starty);
|
||||
p0_5 = Vec2d(startx, starty + len / 2);
|
||||
p1 = Vec2d(startx, starty + len);
|
||||
p2 = Vec2d(startx + len, starty + len);
|
||||
p3 = Vec2d(startx + len, starty);
|
||||
p4 = Vec2d(startx + len * 2, starty);
|
||||
p4_5 = Vec2d(startx + len * 2, starty + len / 2);
|
||||
p5 = Vec2d(startx + len * 2, starty + len);
|
||||
|
||||
gap_p0_toward_p3 = p0 + Vec2d(gap, 0);
|
||||
gap_p2_toward_p3 = p2 + Vec2d(0, gap);
|
||||
|
||||
dot_direction = Vec2d(-len / 2, 0);
|
||||
} else {
|
||||
// 0-------1
|
||||
// | |
|
||||
// 3-------2
|
||||
// | |
|
||||
// 4-------5
|
||||
p0 = Vec2d(startx, starty);
|
||||
p0_5 = Vec2d(startx + len / 2, starty);
|
||||
p1 = Vec2d(startx + len, starty);
|
||||
p2 = Vec2d(startx + len, starty - len);
|
||||
p3 = Vec2d(startx, starty - len);
|
||||
p4 = Vec2d(startx, starty - len * 2);
|
||||
p4_5 = Vec2d(startx + len / 2, starty - len * 2);
|
||||
p5 = Vec2d(startx + len, starty - len * 2);
|
||||
|
||||
gap_p0_toward_p3 = p0 - Vec2d(0, gap);
|
||||
gap_p2_toward_p3 = p2 - Vec2d(gap, 0);
|
||||
|
||||
dot_direction = Vec2d(0, len / 2);
|
||||
}
|
||||
|
||||
std::stringstream gcode;
|
||||
|
||||
switch (c) {
|
||||
case '0':
|
||||
gcode << move_to(p0, writer, "Glyph: 0");
|
||||
gcode << writer.extrude_to_xy(p1, dE);
|
||||
gcode << writer.extrude_to_xy(p5, two_dE);
|
||||
gcode << writer.extrude_to_xy(p4, dE);
|
||||
gcode << writer.extrude_to_xy(gap_p0_toward_p3, two_dE);
|
||||
break;
|
||||
case '1':
|
||||
gcode << move_to(p0_5, writer, "Glyph: 1");
|
||||
gcode << writer.extrude_to_xy(p4_5, two_dE);
|
||||
break;
|
||||
case '2':
|
||||
gcode << move_to(p0, writer, "Glyph: 2");
|
||||
gcode << writer.extrude_to_xy(p1, dE);
|
||||
gcode << writer.extrude_to_xy(p2, dE);
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
gcode << writer.extrude_to_xy(p4, dE);
|
||||
gcode << writer.extrude_to_xy(p5, dE);
|
||||
break;
|
||||
case '3':
|
||||
gcode << move_to(p0, writer, "Glyph: 3");
|
||||
gcode << writer.extrude_to_xy(p1, dE);
|
||||
gcode << writer.extrude_to_xy(p5, two_dE);
|
||||
gcode << writer.extrude_to_xy(p4, dE);
|
||||
gcode << move_to(gap_p2_toward_p3, writer);
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
break;
|
||||
case '4':
|
||||
gcode << move_to(p0, writer, "Glyph: 4");
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
gcode << writer.extrude_to_xy(p2, dE);
|
||||
gcode << move_to(p1, writer);
|
||||
gcode << writer.extrude_to_xy(p5, two_dE);
|
||||
break;
|
||||
case '5':
|
||||
gcode << move_to(p1, writer, "Glyph: 5");
|
||||
gcode << writer.extrude_to_xy(p0, dE);
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
gcode << writer.extrude_to_xy(p2, dE);
|
||||
gcode << writer.extrude_to_xy(p5, dE);
|
||||
gcode << writer.extrude_to_xy(p4, dE);
|
||||
break;
|
||||
case '6':
|
||||
gcode << move_to(p1, writer, "Glyph: 6");
|
||||
gcode << writer.extrude_to_xy(p0, dE);
|
||||
gcode << writer.extrude_to_xy(p4, two_dE);
|
||||
gcode << writer.extrude_to_xy(p5, dE);
|
||||
gcode << writer.extrude_to_xy(p2, dE);
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
break;
|
||||
case '7':
|
||||
gcode << move_to(p0, writer, "Glyph: 7");
|
||||
gcode << writer.extrude_to_xy(p1, dE);
|
||||
gcode << writer.extrude_to_xy(p5, two_dE);
|
||||
break;
|
||||
case '8':
|
||||
gcode << move_to(p2, writer, "Glyph: 8");
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
gcode << writer.extrude_to_xy(p4, dE);
|
||||
gcode << writer.extrude_to_xy(p5, dE);
|
||||
gcode << writer.extrude_to_xy(p1, two_dE);
|
||||
gcode << writer.extrude_to_xy(p0, dE);
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
break;
|
||||
case '9':
|
||||
gcode << move_to(p5, writer, "Glyph: 9");
|
||||
gcode << writer.extrude_to_xy(p1, two_dE);
|
||||
gcode << writer.extrude_to_xy(p0, dE);
|
||||
gcode << writer.extrude_to_xy(p3, dE);
|
||||
gcode << writer.extrude_to_xy(p2, dE);
|
||||
break;
|
||||
case '.':
|
||||
gcode << move_to(p4_5, writer, "Glyph: .");
|
||||
gcode << writer.extrude_to_xy(p4_5 + dot_direction, dE);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvance::draw_number(
|
||||
double startx, double starty, double value, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, double speed, GCodeWriter &writer)
|
||||
{
|
||||
auto sNumber = convert_number_to_string(value);
|
||||
std::stringstream gcode;
|
||||
gcode << writer.set_speed(speed);
|
||||
|
||||
for (std::string::size_type i = 0; i < sNumber.length(); ++i) {
|
||||
if (i > m_max_number_len) { break; }
|
||||
switch (mode) {
|
||||
case DrawDigitMode::Bottom_To_Top: gcode << draw_digit(startx, starty + i * number_spacing(), sNumber[i], mode, line_width, e_per_mm, writer); break;
|
||||
default: gcode << draw_digit(startx + i * number_spacing(), starty, sNumber[i], mode, line_width, e_per_mm, writer);
|
||||
}
|
||||
}
|
||||
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
CalibPressureAdvanceLine::CalibPressureAdvanceLine(GCode *gcodegen)
|
||||
: mp_gcodegen(gcodegen)
|
||||
, m_nozzle_diameter(gcodegen->config().nozzle_diameter.get_at(0))
|
||||
{
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvanceLine::generate_test(double start_pa /*= 0*/, double step_pa /*= 0.002*/, int count /*= 10*/)
|
||||
{
|
||||
BoundingBoxf bed_ext = get_extents(mp_gcodegen->config().printable_area.values);
|
||||
if (is_delta()) { CalibPressureAdvanceLine::delta_scale_bed_ext(bed_ext); }
|
||||
|
||||
auto bed_sizes = mp_gcodegen->config().printable_area.values;
|
||||
const auto &w = bed_ext.size().x();
|
||||
const auto &h = bed_ext.size().y();
|
||||
count = std::min(count, int((h - 10) / m_space_y));
|
||||
|
||||
m_length_long = 40 + std::min(w - 120.0, 0.0);
|
||||
|
||||
auto startx = (w - m_length_short * 2 - m_length_long - 20) / 2;
|
||||
auto starty = (h - count * m_space_y) / 2;
|
||||
if (is_delta()) { CalibPressureAdvanceLine::delta_modify_start(startx, starty, count); }
|
||||
|
||||
return print_pa_lines(startx, starty, start_pa, step_pa, count);
|
||||
}
|
||||
|
||||
bool CalibPressureAdvanceLine::is_delta() const { return mp_gcodegen->config().printable_area.values.size() > 4; }
|
||||
|
||||
std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num)
|
||||
{
|
||||
auto & writer = mp_gcodegen->writer();
|
||||
const auto &config = mp_gcodegen->config();
|
||||
|
||||
const auto filament_diameter = config.filament_diameter.get_at(0);
|
||||
const auto print_flow_ratio = config.print_flow_ratio;
|
||||
|
||||
const double e_per_mm = CalibPressureAdvance::e_per_mm(m_line_width, m_height_layer, m_nozzle_diameter, filament_diameter, print_flow_ratio);
|
||||
const double thin_e_per_mm = CalibPressureAdvance::e_per_mm(m_thin_line_width, m_height_layer, m_nozzle_diameter, filament_diameter, print_flow_ratio);
|
||||
const double number_e_per_mm = CalibPressureAdvance::e_per_mm(m_number_line_width, m_height_layer, m_nozzle_diameter, filament_diameter, print_flow_ratio);
|
||||
|
||||
const double fast = CalibPressureAdvance::speed_adjust(m_fast_speed);
|
||||
const double slow = CalibPressureAdvance::speed_adjust(m_slow_speed);
|
||||
std::stringstream gcode;
|
||||
gcode << mp_gcodegen->writer().travel_to_z(m_height_layer);
|
||||
double y_pos = start_y;
|
||||
|
||||
// prime line
|
||||
auto prime_x = start_x - 2;
|
||||
gcode << move_to(Vec2d(prime_x, y_pos + (num - 4) * m_space_y), writer);
|
||||
gcode << writer.set_speed(slow);
|
||||
gcode << writer.extrude_to_xy(Vec2d(prime_x, y_pos + 3 * m_space_y), e_per_mm * m_space_y * num * 1.1);
|
||||
|
||||
for (int i = 0; i < num; ++i) {
|
||||
gcode << writer.set_pressure_advance(start_pa + i * step_pa);
|
||||
gcode << move_to(Vec2d(start_x, y_pos + i * m_space_y), writer);
|
||||
gcode << writer.set_speed(slow);
|
||||
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short, y_pos + i * m_space_y), e_per_mm * m_length_short);
|
||||
gcode << writer.set_speed(fast);
|
||||
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + i * m_space_y), e_per_mm * m_length_long);
|
||||
gcode << writer.set_speed(slow);
|
||||
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long + m_length_short, y_pos + i * m_space_y), e_per_mm * m_length_short);
|
||||
}
|
||||
gcode << writer.set_pressure_advance(0.0);
|
||||
|
||||
if (m_draw_numbers) {
|
||||
// draw indicator lines
|
||||
gcode << writer.set_speed(fast);
|
||||
gcode << move_to(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 2), writer);
|
||||
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 7), thin_e_per_mm * 7);
|
||||
gcode << move_to(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 7), writer);
|
||||
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 2), thin_e_per_mm * 7);
|
||||
|
||||
for (int i = 0; i < num; i += 2) {
|
||||
gcode << draw_number(start_x + m_length_short + m_length_long + m_length_short + 3, y_pos + i * m_space_y + m_space_y / 2, start_pa + i * step_pa, m_draw_digit_mode,
|
||||
m_number_line_width, number_e_per_mm, 3600, writer);
|
||||
}
|
||||
}
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
void CalibPressureAdvanceLine::delta_modify_start(double &startx, double &starty, int count)
|
||||
{
|
||||
startx = -startx;
|
||||
starty = -(count * m_space_y) / 2;
|
||||
}
|
||||
|
||||
CalibPressureAdvancePattern::CalibPressureAdvancePattern(const Calib_Params ¶ms, const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin)
|
||||
: m_params(params)
|
||||
{
|
||||
this->m_draw_digit_mode = DrawDigitMode::Bottom_To_Top;
|
||||
|
||||
refresh_setup(config, is_bbl_machine, model, origin);
|
||||
};
|
||||
|
||||
void CalibPressureAdvancePattern::generate_custom_gcodes(const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin)
|
||||
{
|
||||
std::stringstream gcode;
|
||||
gcode << "; start pressure advance pattern for layer\n";
|
||||
|
||||
refresh_setup(config, is_bbl_machine, model, origin);
|
||||
|
||||
gcode << move_to(Vec2d(m_starting_point.x(), m_starting_point.y()), m_writer, "Move to start XY position");
|
||||
gcode << m_writer.travel_to_z(height_first_layer(), "Move to start Z position");
|
||||
gcode << m_writer.set_pressure_advance(m_params.start);
|
||||
|
||||
const DrawBoxOptArgs default_box_opt_args(*this);
|
||||
|
||||
// create anchoring frame
|
||||
gcode << draw_box(m_starting_point.x(), m_starting_point.y(), print_size_x(), frame_size_y(), default_box_opt_args);
|
||||
|
||||
// create tab for numbers
|
||||
DrawBoxOptArgs draw_box_opt_args = default_box_opt_args;
|
||||
draw_box_opt_args.is_filled = true;
|
||||
draw_box_opt_args.num_perimeters = wall_count();
|
||||
gcode << draw_box(m_starting_point.x(), m_starting_point.y() + frame_size_y() + line_spacing_first_layer(), glyph_tab_max_x() - m_starting_point.x(),
|
||||
max_numbering_height() + line_spacing_first_layer() + m_glyph_padding_vertical * 2, draw_box_opt_args);
|
||||
|
||||
std::vector<CustomGCode::Item> gcode_items;
|
||||
const DrawLineOptArgs default_line_opt_args(*this);
|
||||
const int num_patterns = get_num_patterns(); // "cache" for use in loops
|
||||
|
||||
// draw pressure advance pattern
|
||||
for (int i = 0; i < m_num_layers; ++i) {
|
||||
if (i > 0) {
|
||||
gcode << "; end pressure advance pattern for layer\n";
|
||||
CustomGCode::Item item;
|
||||
item.print_z = height_first_layer() + (i - 1) * height_layer();
|
||||
item.type = CustomGCode::Type::Custom;
|
||||
item.extra = gcode.str();
|
||||
gcode_items.push_back(item);
|
||||
|
||||
gcode = std::stringstream(); // reset for next layer contents
|
||||
gcode << "; start pressure advance pattern for layer\n";
|
||||
|
||||
const double layer_height = height_first_layer() + (i * height_layer());
|
||||
gcode << m_writer.travel_to_z(layer_height, "Move to layer height");
|
||||
}
|
||||
|
||||
// line numbering
|
||||
if (i == 1) {
|
||||
gcode << m_writer.set_pressure_advance(m_params.start);
|
||||
|
||||
double number_e_per_mm = e_per_mm(line_width(), height_layer(), m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0));
|
||||
|
||||
// glyph on every other line
|
||||
for (int j = 0; j < num_patterns; j += 2) {
|
||||
gcode << draw_number(glyph_start_x(j), m_starting_point.y() + frame_size_y() + m_glyph_padding_vertical + line_width(), m_params.start + (j * m_params.step),
|
||||
m_draw_digit_mode, line_width(), number_e_per_mm, speed_first_layer(), m_writer);
|
||||
}
|
||||
}
|
||||
|
||||
DrawLineOptArgs draw_line_opt_args = default_line_opt_args;
|
||||
|
||||
double to_x = m_starting_point.x() + pattern_shift();
|
||||
double to_y = m_starting_point.y();
|
||||
double side_length = m_wall_side_length;
|
||||
|
||||
// shrink first layer to fit inside frame
|
||||
if (i == 0) {
|
||||
double shrink = (line_spacing_first_layer() * (wall_count() - 1) + (line_width_first_layer() * (1 - m_encroachment))) / std::sin(to_radians(m_corner_angle) / 2);
|
||||
side_length = m_wall_side_length - shrink;
|
||||
to_x += shrink * std::sin(to_radians(90) - to_radians(m_corner_angle) / 2);
|
||||
to_y += line_spacing_first_layer() * (wall_count() - 1) + (line_width_first_layer() * (1 - m_encroachment));
|
||||
}
|
||||
|
||||
double initial_x = to_x;
|
||||
double initial_y = to_y;
|
||||
|
||||
gcode << move_to(Vec2d(to_x, to_y), m_writer, "Move to pattern start");
|
||||
|
||||
for (int j = 0; j < num_patterns; ++j) {
|
||||
// increment pressure advance
|
||||
gcode << m_writer.set_pressure_advance(m_params.start + (j * m_params.step));
|
||||
|
||||
for (int k = 0; k < wall_count(); ++k) {
|
||||
to_x += std::cos(to_radians(m_corner_angle) / 2) * side_length;
|
||||
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
|
||||
|
||||
draw_line_opt_args = default_line_opt_args;
|
||||
draw_line_opt_args.height = i == 0 ? height_first_layer() : height_layer();
|
||||
draw_line_opt_args.line_width = line_width(); // don't use line_width_first_layer so results are consistent across all layers
|
||||
draw_line_opt_args.speed = i == 0 ? speed_adjust(speed_first_layer()) : speed_adjust(speed_perimeter());
|
||||
draw_line_opt_args.comment = "Print pattern wall";
|
||||
gcode << draw_line(Vec2d(to_x, to_y), draw_line_opt_args);
|
||||
|
||||
to_x -= std::cos(to_radians(m_corner_angle) / 2) * side_length;
|
||||
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
|
||||
|
||||
gcode << draw_line(Vec2d(to_x, to_y), draw_line_opt_args);
|
||||
|
||||
to_y = initial_y;
|
||||
if (k != wall_count() - 1) {
|
||||
// perimeters not done yet. move to next perimeter
|
||||
to_x += line_spacing_angle();
|
||||
gcode << move_to(Vec2d(to_x, to_y), m_writer, "Move to start next pattern wall");
|
||||
} else if (j != num_patterns - 1) {
|
||||
// patterns not done yet. move to next pattern
|
||||
to_x += m_pattern_spacing + line_width();
|
||||
gcode << move_to(Vec2d(to_x, to_y), m_writer, "Move to next pattern");
|
||||
} else if (i != m_num_layers - 1) {
|
||||
// layers not done yet. move back to start
|
||||
to_x = initial_x;
|
||||
gcode << move_to(Vec2d(to_x, to_y), m_writer, "Move back to start position");
|
||||
} else {
|
||||
// everything done
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gcode << m_writer.set_pressure_advance(m_params.start);
|
||||
gcode << "; end pressure advance pattern for layer\n";
|
||||
|
||||
CustomGCode::Item item;
|
||||
item.print_z = max_layer_z();
|
||||
item.type = CustomGCode::Type::Custom;
|
||||
item.extra = gcode.str();
|
||||
gcode_items.push_back(item);
|
||||
|
||||
CustomGCode::Info info;
|
||||
info.mode = CustomGCode::Mode::SingleExtruder;
|
||||
info.gcodes = gcode_items;
|
||||
|
||||
model.plates_custom_gcodes[model.curr_plate_index] = info;
|
||||
}
|
||||
|
||||
void CalibPressureAdvancePattern::refresh_setup(const DynamicPrintConfig &config, bool is_bbl_machine, const Model &model, const Vec3d &origin)
|
||||
{
|
||||
m_config = config;
|
||||
m_config.apply(model.objects.front()->config.get(), true);
|
||||
m_config.apply(model.objects.front()->volumes.front()->config.get(), true);
|
||||
|
||||
m_is_delta = (m_config.option<ConfigOptionPoints>("printable_area")->values.size() > 4);
|
||||
|
||||
_refresh_starting_point(model);
|
||||
_refresh_writer(is_bbl_machine, model, origin);
|
||||
}
|
||||
|
||||
void CalibPressureAdvancePattern::_refresh_starting_point(const Model &model)
|
||||
{
|
||||
ModelObject * obj = model.objects.front();
|
||||
BoundingBoxf3 bbox = obj->instance_bounding_box(*obj->instances.front(), false);
|
||||
|
||||
m_starting_point = Vec3d(bbox.min.x(), bbox.max.y(), 0);
|
||||
m_starting_point.y() += m_handle_spacing;
|
||||
|
||||
if (m_is_delta) {
|
||||
m_starting_point.x() *= -1;
|
||||
m_starting_point.y() -= (frame_size_y() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
void CalibPressureAdvancePattern::_refresh_writer(bool is_bbl_machine, const Model &model, const Vec3d &origin)
|
||||
{
|
||||
PrintConfig print_config;
|
||||
print_config.apply(m_config, true);
|
||||
|
||||
m_writer.apply_print_config(print_config);
|
||||
m_writer.set_xy_offset(origin(0), origin(1));
|
||||
//m_writer.set_is_bbl_machine(is_bbl_machine);
|
||||
|
||||
const unsigned int extruder_id = model.objects.front()->volumes.front()->extruder_id();
|
||||
m_writer.set_extruders({extruder_id});
|
||||
m_writer.set_extruder(extruder_id);
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvancePattern::draw_line(Vec2d to_pt, DrawLineOptArgs opt_args)
|
||||
{
|
||||
const double e_per_mm = CalibPressureAdvance::e_per_mm(opt_args.line_width, opt_args.height, m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0));
|
||||
|
||||
const double length = get_distance(Vec2d(m_last_pos.x(), m_last_pos.y()), to_pt);
|
||||
auto dE = e_per_mm * length;
|
||||
|
||||
std::stringstream gcode;
|
||||
|
||||
gcode << m_writer.set_speed(opt_args.speed);
|
||||
gcode << m_writer.extrude_to_xy(to_pt, dE, opt_args.comment);
|
||||
|
||||
m_last_pos = Vec3d(to_pt.x(), to_pt.y(), 0);
|
||||
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvancePattern::draw_box(double min_x, double min_y, double size_x, double size_y, DrawBoxOptArgs opt_args)
|
||||
{
|
||||
std::stringstream gcode;
|
||||
|
||||
double x = min_x;
|
||||
double y = min_y;
|
||||
const double max_x = min_x + size_x;
|
||||
const double max_y = min_y + size_y;
|
||||
|
||||
const double spacing = opt_args.line_width - opt_args.height * (1 - M_PI / 4);
|
||||
|
||||
// if number of perims exceeds size of box, reduce it to max
|
||||
const int max_perimeters = std::min(
|
||||
// this is the equivalent of number of perims for concentric fill
|
||||
std::floor(size_x * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))),
|
||||
std::floor(size_y * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))));
|
||||
|
||||
opt_args.num_perimeters = std::min(opt_args.num_perimeters, max_perimeters);
|
||||
|
||||
gcode << move_to(Vec2d(min_x, min_y), m_writer, "Move to box start");
|
||||
|
||||
DrawLineOptArgs line_opt_args(*this);
|
||||
line_opt_args.height = opt_args.height;
|
||||
line_opt_args.line_width = opt_args.line_width;
|
||||
line_opt_args.speed = opt_args.speed;
|
||||
|
||||
for (int i = 0; i < opt_args.num_perimeters; ++i) {
|
||||
if (i != 0) { // after first perimeter, step inwards to start next perimeter
|
||||
x += spacing;
|
||||
y += spacing;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Step inwards to print next perimeter");
|
||||
}
|
||||
|
||||
y += size_y - i * spacing * 2;
|
||||
line_opt_args.comment = "Draw perimeter (up)";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
|
||||
x += size_x - i * spacing * 2;
|
||||
line_opt_args.comment = "Draw perimeter (right)";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
|
||||
y -= size_y - i * spacing * 2;
|
||||
line_opt_args.comment = "Draw perimeter (down)";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
|
||||
x -= size_x - i * spacing * 2;
|
||||
line_opt_args.comment = "Draw perimeter (left)";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
|
||||
if (!opt_args.is_filled) { return gcode.str(); }
|
||||
|
||||
// create box infill
|
||||
const double spacing_45 = spacing / std::sin(to_radians(45));
|
||||
|
||||
const double bound_modifier = (spacing * (opt_args.num_perimeters - 1)) + (opt_args.line_width * (1 - m_encroachment));
|
||||
const double x_min_bound = min_x + bound_modifier;
|
||||
const double x_max_bound = max_x - bound_modifier;
|
||||
const double y_min_bound = min_y + bound_modifier;
|
||||
const double y_max_bound = max_y - bound_modifier;
|
||||
const int x_count = std::floor((x_max_bound - x_min_bound) / spacing_45);
|
||||
const int y_count = std::floor((y_max_bound - y_min_bound) / spacing_45);
|
||||
|
||||
double x_remainder = std::fmod((x_max_bound - x_min_bound), spacing_45);
|
||||
double y_remainder = std::fmod((y_max_bound - y_min_bound), spacing_45);
|
||||
|
||||
x = x_min_bound;
|
||||
y = y_min_bound;
|
||||
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Move to fill start");
|
||||
|
||||
for (int i = 0; i < x_count + y_count + (x_remainder + y_remainder >= spacing_45 ? 1 : 0);
|
||||
++i) { // this isn't the most robust way, but less expensive than finding line intersections
|
||||
if (i < std::min(x_count, y_count)) {
|
||||
if (i % 2 == 0) {
|
||||
x += spacing_45;
|
||||
y = y_min_bound;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
y += x - x_min_bound;
|
||||
x = x_min_bound;
|
||||
line_opt_args.comment = "Fill: Print up/left";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
} else {
|
||||
y += spacing_45;
|
||||
x = x_min_bound;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
|
||||
|
||||
x += y - y_min_bound;
|
||||
y = y_min_bound;
|
||||
line_opt_args.comment = "Fill: Print down/right";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
} else if (i < std::max(x_count, y_count)) {
|
||||
if (x_count > y_count) {
|
||||
// box is wider than tall
|
||||
if (i % 2 == 0) {
|
||||
x += spacing_45;
|
||||
y = y_min_bound;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
x -= y_max_bound - y_min_bound;
|
||||
y = y_max_bound;
|
||||
line_opt_args.comment = "Fill: Print up/left";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
} else {
|
||||
if (i == y_count) {
|
||||
x += spacing_45 - y_remainder;
|
||||
y_remainder = 0;
|
||||
} else {
|
||||
x += spacing_45;
|
||||
}
|
||||
y = y_max_bound;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
x += y_max_bound - y_min_bound;
|
||||
y = y_min_bound;
|
||||
line_opt_args.comment = "Fill: Print down/right";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
} else {
|
||||
// box is taller than wide
|
||||
if (i % 2 == 0) {
|
||||
x = x_max_bound;
|
||||
if (i == x_count) {
|
||||
y += spacing_45 - x_remainder;
|
||||
x_remainder = 0;
|
||||
} else {
|
||||
y += spacing_45;
|
||||
}
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
|
||||
|
||||
x = x_min_bound;
|
||||
y += x_max_bound - x_min_bound;
|
||||
line_opt_args.comment = "Fill: Print up/left";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
} else {
|
||||
x = x_min_bound;
|
||||
y += spacing_45;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
|
||||
|
||||
x = x_max_bound;
|
||||
y -= x_max_bound - x_min_bound;
|
||||
line_opt_args.comment = "Fill: Print down/right";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (i % 2 == 0) {
|
||||
x = x_max_bound;
|
||||
if (i == x_count) {
|
||||
y += spacing_45 - x_remainder;
|
||||
} else {
|
||||
y += spacing_45;
|
||||
}
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
|
||||
|
||||
x -= y_max_bound - y;
|
||||
y = y_max_bound;
|
||||
line_opt_args.comment = "Fill: Print up/left";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
} else {
|
||||
if (i == y_count) {
|
||||
x += spacing_45 - y_remainder;
|
||||
} else {
|
||||
x += spacing_45;
|
||||
}
|
||||
y = y_max_bound;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
y -= x_max_bound - x;
|
||||
x = x_max_bound;
|
||||
line_opt_args.comment = "Fill: Print down/right";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::get_distance(Vec2d from, Vec2d to) const { return std::hypot((to.x() - from.x()), (to.y() - from.y())); }
|
||||
|
||||
double CalibPressureAdvancePattern::object_size_x() const
|
||||
{
|
||||
return get_num_patterns() * ((wall_count() - 1) * line_spacing_angle()) + (get_num_patterns() - 1) * (m_pattern_spacing + line_width()) +
|
||||
std::cos(to_radians(m_corner_angle) / 2) * m_wall_side_length + line_spacing_first_layer() * wall_count();
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::object_size_y() const
|
||||
{
|
||||
return 2 * (std::sin(to_radians(m_corner_angle) / 2) * m_wall_side_length) + max_numbering_height() + m_glyph_padding_vertical * 2 + line_width_first_layer();
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::glyph_start_x(int pattern_i) const
|
||||
{
|
||||
// note that pattern_i is zero-based!
|
||||
// align glyph's start with first perimeter of specified pattern
|
||||
double x =
|
||||
// starting offset
|
||||
m_starting_point.x() + pattern_shift() +
|
||||
|
||||
// width of pattern extrusions
|
||||
pattern_i * (wall_count() - 1) * line_spacing_angle() + // center to center distance of extrusions
|
||||
pattern_i * line_width() + // endcaps. center to end on either side = 1 line width
|
||||
|
||||
// space between each pattern
|
||||
pattern_i * m_pattern_spacing;
|
||||
|
||||
// align to middle of pattern walls
|
||||
x += wall_count() * line_spacing_angle() / 2;
|
||||
|
||||
// shift so glyph is centered on pattern
|
||||
// m_digit_segment_len = half of X length of glyph
|
||||
x -= (glyph_length_x() / 2);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::glyph_length_x() const
|
||||
{
|
||||
// half of line_width sticks out on each side
|
||||
return line_width() + (2 * m_digit_segment_len);
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::glyph_tab_max_x() const
|
||||
{
|
||||
// only every other glyph is shown, starting with 1
|
||||
int num = get_num_patterns();
|
||||
int max_num = (num % 2 == 0) ? num - 1 : num;
|
||||
|
||||
// padding at end should be same as padding at start
|
||||
double padding = glyph_start_x(0) - m_starting_point.x();
|
||||
|
||||
return glyph_start_x(max_num - 1) + // glyph_start_x is zero-based
|
||||
(glyph_length_x() - line_width() / 2) + padding;
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::max_numbering_height() const
|
||||
{
|
||||
std::string::size_type most_characters = 0;
|
||||
const int num_patterns = get_num_patterns();
|
||||
|
||||
// note: only every other number is printed
|
||||
for (std::string::size_type i = 0; i < num_patterns; i += 2) {
|
||||
std::string sNumber = convert_number_to_string(m_params.start + (i * m_params.step));
|
||||
|
||||
if (sNumber.length() > most_characters) { most_characters = sNumber.length(); }
|
||||
}
|
||||
|
||||
most_characters = std::min(most_characters, m_max_number_len);
|
||||
|
||||
return (most_characters * m_digit_segment_len) + ((most_characters - 1) * m_digit_gap_len);
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::pattern_shift() const { return (wall_count() - 1) * line_spacing_first_layer() + line_width_first_layer() + m_glyph_padding_horizontal; }
|
||||
} // namespace Slic3r
|
||||
|
307
src/libslic3r/Calib.hpp
Normal file
307
src/libslic3r/Calib.hpp
Normal file
|
@ -0,0 +1,307 @@
|
|||
#pragma once
|
||||
|
||||
#include "GCodeWriter.hpp"
|
||||
#include "PrintConfig.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GCode;
|
||||
class Model;
|
||||
|
||||
enum class CalibMode : int {
|
||||
Calib_None = 0,
|
||||
Calib_PA_Line,
|
||||
Calib_PA_Pattern,
|
||||
Calib_PA_Tower,
|
||||
Calib_Flow_Rate,
|
||||
Calib_Temp_Tower,
|
||||
Calib_Vol_speed_Tower,
|
||||
Calib_VFA_Tower,
|
||||
Calib_Retraction_tower
|
||||
};
|
||||
|
||||
enum class CalibState {
|
||||
Start = 0,
|
||||
Preset,
|
||||
Calibration,
|
||||
CoarseSave,
|
||||
FineCalibration,
|
||||
Save,
|
||||
Finish
|
||||
};
|
||||
|
||||
struct Calib_Params
|
||||
{
|
||||
Calib_Params() : mode(CalibMode::Calib_None){}
|
||||
double start, end, step;
|
||||
bool print_numbers;
|
||||
CalibMode mode;
|
||||
};
|
||||
|
||||
class X1CCalibInfos
|
||||
{
|
||||
public:
|
||||
struct X1CCalibInfo
|
||||
{
|
||||
int tray_id;
|
||||
int bed_temp;
|
||||
int nozzle_temp;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
float max_volumetric_speed;
|
||||
float flow_rate = 0.98f; // for flow ratio
|
||||
};
|
||||
|
||||
std::vector<X1CCalibInfo> calib_datas;
|
||||
};
|
||||
|
||||
class CaliPresetInfo
|
||||
{
|
||||
public:
|
||||
int tray_id;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
std::string name;
|
||||
|
||||
CaliPresetInfo &operator=(const CaliPresetInfo &other)
|
||||
{
|
||||
this->tray_id = other.tray_id;
|
||||
this->nozzle_diameter = other.nozzle_diameter;
|
||||
this->filament_id = other.filament_id;
|
||||
this->setting_id = other.setting_id;
|
||||
this->name = other.name;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct PrinterCaliInfo
|
||||
{
|
||||
std::string dev_id;
|
||||
bool cali_finished = true;
|
||||
float cache_flow_ratio;
|
||||
std::vector<CaliPresetInfo> selected_presets;
|
||||
};
|
||||
|
||||
class PACalibResult
|
||||
{
|
||||
public:
|
||||
enum CalibResult {
|
||||
CALI_RESULT_SUCCESS = 0,
|
||||
CALI_RESULT_PROBLEM = 1,
|
||||
CALI_RESULT_FAILED = 2,
|
||||
};
|
||||
int tray_id;
|
||||
int cali_idx = -1;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
std::string name;
|
||||
float k_value = 0.0;
|
||||
float n_coef = 0.0;
|
||||
int confidence = -1; // 0: success 1: uncertain 2: failed
|
||||
};
|
||||
|
||||
struct PACalibIndexInfo
|
||||
{
|
||||
int tray_id;
|
||||
int cali_idx;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
};
|
||||
|
||||
class FlowRatioCalibResult
|
||||
{
|
||||
public:
|
||||
int tray_id;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
float flow_ratio;
|
||||
int confidence; // 0: success 1: uncertain 2: failed
|
||||
};
|
||||
|
||||
class CalibPressureAdvance
|
||||
{
|
||||
public:
|
||||
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx = 0);
|
||||
|
||||
protected:
|
||||
CalibPressureAdvance() = default;
|
||||
~CalibPressureAdvance() = default;
|
||||
|
||||
enum class DrawDigitMode { Left_To_Right, Bottom_To_Top };
|
||||
|
||||
void delta_scale_bed_ext(BoundingBoxf &bed_ext) const { bed_ext.scale(1.0f / 1.41421f); }
|
||||
|
||||
std::string move_to(Vec2d pt, GCodeWriter &writer, std::string comment = std::string());
|
||||
double e_per_mm(double line_width, double layer_height, float nozzle_diameter, float filament_diameter, float print_flow_ratio) const;
|
||||
double speed_adjust(int speed) const { return speed * 60; };
|
||||
|
||||
std::string convert_number_to_string(double num) const;
|
||||
double number_spacing() const { return m_digit_segment_len + m_digit_gap_len; };
|
||||
std::string draw_digit(double startx, double starty, char c, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, GCodeWriter &writer);
|
||||
std::string draw_number(
|
||||
double startx, double starty, double value, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, double speed, GCodeWriter &writer);
|
||||
|
||||
Vec3d m_last_pos;
|
||||
|
||||
DrawDigitMode m_draw_digit_mode{DrawDigitMode::Left_To_Right};
|
||||
const double m_digit_segment_len{2};
|
||||
const double m_digit_gap_len{1};
|
||||
const std::string::size_type m_max_number_len{5};
|
||||
};
|
||||
|
||||
class CalibPressureAdvanceLine : public CalibPressureAdvance
|
||||
{
|
||||
public:
|
||||
CalibPressureAdvanceLine(GCode *gcodegen);
|
||||
~CalibPressureAdvanceLine(){};
|
||||
|
||||
std::string generate_test(double start_pa = 0, double step_pa = 0.002, int count = 50);
|
||||
|
||||
void set_speed(double fast = 100.0, double slow = 20.0)
|
||||
{
|
||||
m_slow_speed = slow;
|
||||
m_fast_speed = fast;
|
||||
}
|
||||
|
||||
const double &line_width() { return m_line_width; };
|
||||
bool is_delta() const;
|
||||
bool & draw_numbers() { return m_draw_numbers; }
|
||||
|
||||
private:
|
||||
std::string print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num);
|
||||
|
||||
void delta_modify_start(double &startx, double &starty, int count);
|
||||
|
||||
GCode *mp_gcodegen;
|
||||
|
||||
double m_nozzle_diameter;
|
||||
double m_slow_speed, m_fast_speed;
|
||||
|
||||
const double m_height_layer{0.2};
|
||||
const double m_line_width{0.6};
|
||||
const double m_thin_line_width{0.44};
|
||||
const double m_number_line_width{0.48};
|
||||
const double m_space_y{3.5};
|
||||
|
||||
double m_length_short{20.0}, m_length_long{40.0};
|
||||
bool m_draw_numbers{true};
|
||||
};
|
||||
|
||||
struct SuggestedConfigCalibPAPattern
|
||||
{
|
||||
const std::vector<std::pair<std::string, double>> float_pairs{{"initial_layer_print_height", 0.25}, {"layer_height", 0.2}, {"initial_layer_speed", 30}};
|
||||
|
||||
const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs{{"line_width", 112.5}, {"initial_layer_line_width", 140}};
|
||||
|
||||
const std::vector<std::pair<std::string, int>> int_pairs{{"skirt_loops", 0}, {"wall_loops", 3}};
|
||||
|
||||
const std::pair<std::string, BrimType> brim_pair{"brim_type", BrimType::btNoBrim};
|
||||
};
|
||||
|
||||
class CalibPressureAdvancePattern : public CalibPressureAdvance
|
||||
{
|
||||
friend struct DrawLineOptArgs;
|
||||
friend struct DrawBoxOptArgs;
|
||||
|
||||
public:
|
||||
CalibPressureAdvancePattern(const Calib_Params ¶ms, const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin);
|
||||
|
||||
double handle_xy_size() const { return m_handle_xy_size; };
|
||||
double handle_spacing() const { return m_handle_spacing; };
|
||||
double print_size_x() const { return object_size_x() + pattern_shift(); };
|
||||
double print_size_y() const { return object_size_y(); };
|
||||
double max_layer_z() const { return height_first_layer() + ((m_num_layers - 1) * height_layer()); };
|
||||
|
||||
void generate_custom_gcodes(const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin);
|
||||
|
||||
protected:
|
||||
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
|
||||
double speed_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_speed")->value; };
|
||||
double line_width_first_layer() const { return m_config.get_abs_value("initial_layer_line_width"); };
|
||||
double line_width() const { return m_config.get_abs_value("line_width"); };
|
||||
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };
|
||||
|
||||
private:
|
||||
struct DrawLineOptArgs
|
||||
{
|
||||
DrawLineOptArgs(const CalibPressureAdvancePattern &p) : height{p.height_layer()}, line_width{p.line_width()}, speed{p.speed_adjust(p.speed_perimeter())} {};
|
||||
|
||||
double height;
|
||||
double line_width;
|
||||
double speed;
|
||||
std::string comment{"Print line"};
|
||||
};
|
||||
|
||||
struct DrawBoxOptArgs
|
||||
{
|
||||
DrawBoxOptArgs(const CalibPressureAdvancePattern &p)
|
||||
: num_perimeters{p.wall_count()}, height{p.height_first_layer()}, line_width{p.line_width_first_layer()}, speed{p.speed_adjust(p.speed_first_layer())} {};
|
||||
|
||||
bool is_filled{false};
|
||||
int num_perimeters;
|
||||
double height;
|
||||
double line_width;
|
||||
double speed;
|
||||
};
|
||||
|
||||
void refresh_setup(const DynamicPrintConfig &config, bool is_bbl_machine, const Model &model, const Vec3d &origin);
|
||||
void _refresh_starting_point(const Model &model);
|
||||
void _refresh_writer(bool is_bbl_machine, const Model &model, const Vec3d &origin);
|
||||
|
||||
double height_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_print_height")->value; };
|
||||
double height_layer() const { return m_config.option<ConfigOptionFloat>("layer_height")->value; };
|
||||
const int get_num_patterns() const { return std::ceil((m_params.end - m_params.start) / m_params.step + 1); }
|
||||
|
||||
std::string draw_line(Vec2d to_pt, DrawLineOptArgs opt_args);
|
||||
std::string draw_box(double min_x, double min_y, double size_x, double size_y, DrawBoxOptArgs opt_args);
|
||||
|
||||
double to_radians(double degrees) const { return degrees * M_PI / 180; };
|
||||
double get_distance(Vec2d from, Vec2d to) const;
|
||||
|
||||
/*
|
||||
from slic3r documentation: spacing = extrusion_width - layer_height * (1 - PI/4)
|
||||
"spacing" = center-to-center distance of adjacent extrusions, which partially overlap
|
||||
https://manual.slic3r.org/advanced/flow-math
|
||||
https://ellis3dp.com/Print-Tuning-Guide/articles/misconceptions.html#two-04mm-perimeters--08mm
|
||||
*/
|
||||
double line_spacing() const { return line_width() - height_layer() * (1 - M_PI / 4); };
|
||||
double line_spacing_first_layer() const { return line_width_first_layer() - height_first_layer() * (1 - M_PI / 4); };
|
||||
double line_spacing_angle() const { return line_spacing() / std::sin(to_radians(m_corner_angle) / 2); };
|
||||
|
||||
double object_size_x() const;
|
||||
double object_size_y() const;
|
||||
double frame_size_y() const { return std::sin(to_radians(double(m_corner_angle) / 2)) * m_wall_side_length * 2; };
|
||||
|
||||
double glyph_start_x(int pattern_i = 0) const;
|
||||
double glyph_length_x() const;
|
||||
double glyph_tab_max_x() const;
|
||||
double max_numbering_height() const;
|
||||
|
||||
double pattern_shift() const;
|
||||
|
||||
const Calib_Params &m_params;
|
||||
|
||||
DynamicPrintConfig m_config;
|
||||
GCodeWriter m_writer;
|
||||
bool m_is_delta;
|
||||
Vec3d m_starting_point;
|
||||
|
||||
const double m_handle_xy_size{5};
|
||||
const double m_handle_spacing{2};
|
||||
const int m_num_layers{4};
|
||||
|
||||
const double m_wall_side_length{30.0};
|
||||
const int m_corner_angle{90};
|
||||
const int m_pattern_spacing{2};
|
||||
const double m_encroachment{1. / 3.};
|
||||
|
||||
const double m_glyph_padding_horizontal{1};
|
||||
const double m_glyph_padding_vertical{1};
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
|
@ -1660,7 +1660,7 @@ public:
|
|||
ConfigOptionEnumsGenericTempl& operator= (const ConfigOption* opt) { this->set(opt); return *this; }
|
||||
bool operator< (const ConfigOptionInts& rhs) const throw() { return this->values < rhs.values; }
|
||||
|
||||
bool operator==(const ConfigOptionInts& rhs) const throw()
|
||||
bool operator==(const ConfigOptionInts& rhs) const
|
||||
{
|
||||
if (rhs.type() != this->type())
|
||||
throw ConfigurationError("ConfigOptionEnumsGeneric: Comparing incompatible types");
|
||||
|
|
|
@ -56,8 +56,6 @@ public:
|
|||
double retract_length_toolchange() const;
|
||||
double retract_restart_extra_toolchange() const;
|
||||
|
||||
bool use_firmware_retraction() const;
|
||||
|
||||
private:
|
||||
// Private constructor to create a key for a search in std::set.
|
||||
Extruder(unsigned int id) : m_id(id) {}
|
||||
|
@ -66,7 +64,7 @@ private:
|
|||
GCodeConfig *m_config;
|
||||
// Print-wide global ID of this extruder.
|
||||
unsigned int m_id;
|
||||
// Current state of the extruder axis, may be resetted if use_relative_e_distances.
|
||||
// Current state of the extruder axis, may be resetted if use_relative_e_distance.
|
||||
double m_E;
|
||||
// Current state of the extruder tachometer, used to output the extruded_volume() and used_filament() statistics.
|
||||
double m_absolute_E;
|
||||
|
|
|
@ -95,7 +95,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 &&
|
||||
|
@ -154,42 +154,26 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
//BBS
|
||||
params.with_loop = surface.surface_type == stInternalWithLoop;
|
||||
|
||||
if (surface.is_solid()) {
|
||||
if (surface.is_solid()) {
|
||||
params.density = 100.f;
|
||||
//FIXME for non-thick bridges, shall we allow a bottom surface pattern?
|
||||
if (surface.is_solid_infill())
|
||||
params.pattern = region_config.internal_solid_infill_pattern.value;
|
||||
else if (surface.is_external() && ! is_bridge) {
|
||||
if(surface.is_top())
|
||||
params.pattern = region_config.top_surface_pattern.value;
|
||||
else
|
||||
params.pattern = region_config.bottom_surface_pattern.value;
|
||||
}
|
||||
else {
|
||||
if(region_config.top_surface_pattern == ipMonotonic || region_config.top_surface_pattern == ipMonotonicLine)
|
||||
params.pattern = ipMonotonic;
|
||||
else
|
||||
params.pattern = ipRectilinear;
|
||||
}
|
||||
else if (surface.is_external() && !is_bridge)
|
||||
params.pattern = surface.is_top() ? region_config.top_surface_pattern.value : region_config.bottom_surface_pattern.value;
|
||||
else
|
||||
params.pattern = region_config.top_surface_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
|
||||
|
||||
} else if (params.density <= 0)
|
||||
continue;
|
||||
|
||||
params.extrusion_role = erInternalInfill;
|
||||
if (is_bridge) {
|
||||
if (surface.is_internal_bridge())
|
||||
params.extrusion_role = erInternalBridgeInfill;
|
||||
else
|
||||
params.extrusion_role = erBridgeInfill;
|
||||
} else if (surface.is_solid()) {
|
||||
if (surface.is_top()) {
|
||||
params.extrusion_role = erTopSolidInfill;
|
||||
} else if (surface.is_bottom()) {
|
||||
params.extrusion_role = erBottomSurface;
|
||||
} else {
|
||||
params.extrusion_role = erSolidInfill;
|
||||
}
|
||||
}
|
||||
params.bridge_angle = float(surface.bridge_angle);
|
||||
params.extrusion_role =
|
||||
is_bridge ?
|
||||
erBridgeInfill :
|
||||
(surface.is_solid() ?
|
||||
(surface.is_top() ? erTopSolidInfill : (surface.is_bottom()? erBottomSurface : erSolidInfill)) :
|
||||
erInternalInfill);
|
||||
params.bridge_angle = float(surface.bridge_angle);
|
||||
params.angle = float(Geometry::deg2rad(region_config.infill_direction.value));
|
||||
|
||||
// Calculate the actual flow we'll be using for this infill.
|
||||
|
@ -210,11 +194,11 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
// so that internall infill will be aligned over all layers of the current region.
|
||||
params.spacing = layerm.region().flow(*layer.object(), frInfill, layer.object()->config().layer_height, false).spacing();
|
||||
// Anchor a sparse infill to inner perimeters with the following anchor length:
|
||||
params.anchor_length = float(region_config.infill_anchor);
|
||||
if (region_config.infill_anchor.percent)
|
||||
params.anchor_length = float(region_config.sparse_infill_anchor);
|
||||
if (region_config.sparse_infill_anchor.percent)
|
||||
params.anchor_length = float(params.anchor_length * 0.01 * params.spacing);
|
||||
params.anchor_length_max = float(region_config.infill_anchor_max);
|
||||
if (region_config.infill_anchor_max.percent)
|
||||
params.anchor_length_max = float(region_config.sparse_infill_anchor_max);
|
||||
if (region_config.sparse_infill_anchor_max.percent)
|
||||
params.anchor_length_max = float(params.anchor_length_max * 0.01 * params.spacing);
|
||||
params.anchor_length = std::min(params.anchor_length, params.anchor_length_max);
|
||||
}
|
||||
|
@ -331,11 +315,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
if (internal_solid_fill == nullptr) {
|
||||
// Produce another solid fill.
|
||||
params.extruder = layerm.region().extruder(frSolidInfill);
|
||||
const auto top_pattern = layerm.region().config().top_surface_pattern;
|
||||
if(top_pattern == ipMonotonic || top_pattern == ipMonotonicLine)
|
||||
params.pattern = top_pattern;
|
||||
else
|
||||
params.pattern = ipRectilinear;
|
||||
params.pattern = layerm.region().config().top_surface_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
|
||||
params.density = 100.f;
|
||||
params.extrusion_role = erInternalInfill;
|
||||
params.angle = float(Geometry::deg2rad(layerm.region().config().infill_direction.value));
|
||||
|
@ -479,12 +459,10 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||
#endif
|
||||
}
|
||||
|
||||
LayerRegion* layerm = this->m_regions[surface_fill.region_id];
|
||||
|
||||
// Maximum length of the perimeter segment linking two infill lines.
|
||||
f->link_max_length = (coord_t)scale_(link_max_length);
|
||||
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
||||
f->loop_clipping = coord_t(scale_(layerm->region().config().seam_gap.get_abs_value(surface_fill.params.flow.nozzle_diameter())));
|
||||
f->loop_clipping = coord_t(scale_(surface_fill.params.flow.nozzle_diameter()) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER);
|
||||
|
||||
// apply half spacing using this flow's own spacing and generate infill
|
||||
FillParams params;
|
||||
|
@ -502,19 +480,14 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||
params.using_internal_flow = using_internal_flow;
|
||||
params.no_extrusion_overlap = surface_fill.params.overlap;
|
||||
params.with_loop = surface_fill.params.with_loop;
|
||||
params.config = &layerm->region().config();
|
||||
if (surface_fill.params.pattern == ipGrid)
|
||||
params.can_reverse = false;
|
||||
LayerRegion* layerm = this->m_regions[surface_fill.region_id];
|
||||
for (ExPolygon& expoly : surface_fill.expolygons) {
|
||||
f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes);
|
||||
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||
f->spacing = surface_fill.params.spacing;
|
||||
surface_fill.surface.expolygon = std::move(expoly);
|
||||
|
||||
if(surface_fill.params.bridge && surface_fill.surface.is_external() && surface_fill.params.density > 99.0){
|
||||
params.density = layerm->region().config().bridge_density.get_abs_value(1.0);
|
||||
params.dont_adjust = true;
|
||||
}
|
||||
// BBS: make fill
|
||||
f->fill_surface_extrusion(&surface_fill.surface,
|
||||
params,
|
||||
|
|
|
@ -28,11 +28,6 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
//BBS: 0% of sparse_infill_line_width, no anchor at the start of sparse infill
|
||||
float Fill::infill_anchor = 400;
|
||||
//BBS: 20mm
|
||||
float Fill::infill_anchor_max = 20;
|
||||
|
||||
Fill* Fill::new_from_type(const InfillPattern type)
|
||||
{
|
||||
switch (type) {
|
||||
|
|
|
@ -40,7 +40,7 @@ struct FillParams
|
|||
bool full_infill() const { return density > 0.9999f; }
|
||||
// Don't connect the fill lines around the inner perimeter.
|
||||
bool dont_connect() const { return anchor_length_max < 0.05f; }
|
||||
|
||||
double filter_out_gap_fill { 0.0 };
|
||||
// Fill density, fraction in <0, 1>
|
||||
float density { 0.f };
|
||||
|
||||
|
@ -110,9 +110,6 @@ public:
|
|||
// BBS: all no overlap expolygons in same layer
|
||||
ExPolygons no_overlap_expolygons;
|
||||
|
||||
static float infill_anchor;
|
||||
static float infill_anchor_max;
|
||||
|
||||
public:
|
||||
virtual ~Fill() {}
|
||||
virtual Fill* clone() const = 0;
|
||||
|
|
|
@ -3179,6 +3179,11 @@ void FillMonotonicLineWGapFill::fill_surface_extrusion(const Surface* surface, c
|
|||
}), polylines.end());
|
||||
|
||||
ExtrusionEntityCollection gap_fill;
|
||||
// OrcaSlicer: filter out tiny gap fills
|
||||
polylines.erase(std::remove_if(polylines.begin(), polylines.end(), [&](const ThickPolyline &p) {
|
||||
return p.length() < scale_(params.filter_out_gap_fill);
|
||||
}), polylines.end());
|
||||
|
||||
variable_width(polylines, erGapFill, params.flow, gap_fill.entities);
|
||||
coll_nosort->append(std::move(gap_fill.entities));
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ static constexpr const char* OBJECT_ID_ATTR = "object_id";
|
|||
static constexpr const char* INSTANCEID_ATTR = "instance_id";
|
||||
static constexpr const char* IDENTIFYID_ATTR = "identify_id";
|
||||
static constexpr const char* PLATERID_ATTR = "plater_id";
|
||||
static constexpr const char* PLATER_NAME_ATTR = "plater_name";
|
||||
static constexpr const char* PLATER_NAME_ATTR = "plater_name";
|
||||
static constexpr const char* PLATE_IDX_ATTR = "index";
|
||||
static constexpr const char* SLICE_PREDICTION_ATTR = "prediction";
|
||||
static constexpr const char* SLICE_WEIGHT_ATTR = "weight";
|
||||
|
@ -910,7 +910,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
bool m_load_restore = false;
|
||||
std::string m_backup_path;
|
||||
std::string m_origin_file;
|
||||
// Semantic version of Orca Slicer, that generated this 3MF.
|
||||
// Semantic version of Bambu Studio, that generated this 3MF.
|
||||
boost::optional<Semver> m_bambuslicer_generator_version;
|
||||
unsigned int m_fdm_supports_painting_version = 0;
|
||||
unsigned int m_seam_painting_version = 0;
|
||||
|
@ -1769,7 +1769,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
lock.close();
|
||||
|
||||
if (!m_is_bbl_3mf) {
|
||||
// if the 3mf was not produced by OrcaSlicer and there is more than one instance,
|
||||
// if the 3mf was not produced by BambuStudio and there is more than one instance,
|
||||
// split the object in as many objects as instances
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", found 3mf from other vendor, split as instance");
|
||||
for (const IdToModelObjectMap::value_type& object : m_objects) {
|
||||
|
@ -2046,7 +2046,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
}
|
||||
plate_data_list[it->first-1]->locked = it->second->locked;
|
||||
plate_data_list[it->first-1]->plate_index = it->second->plate_index-1;
|
||||
plate_data_list[it->first-1]->plate_name = it->second->plate_name;
|
||||
plate_data_list[it->first-1]->plate_name = it->second->plate_name;
|
||||
plate_data_list[it->first-1]->obj_inst_map = it->second->obj_inst_map;
|
||||
plate_data_list[it->first-1]->gcode_file = (m_load_restore || it->second->gcode_file.empty()) ? it->second->gcode_file : m_backup_path + "/" + it->second->gcode_file;
|
||||
plate_data_list[it->first-1]->gcode_prediction = it->second->gcode_prediction;
|
||||
|
@ -2616,7 +2616,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _BBS_3MF_Importer::_extract_layer_config_ranges_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, ConfigSubstitutionContext& config_substitutions)
|
||||
{
|
||||
if (stat.m_uncomp_size > 0) {
|
||||
|
@ -3121,7 +3121,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
}
|
||||
|
||||
if (!m_is_bbl_3mf) {
|
||||
// if the 3mf was not produced by OrcaSlicer and there is only one object,
|
||||
// if the 3mf was not produced by BambuStudio and there is only one object,
|
||||
// set the object name to match the filename
|
||||
if (m_model->objects.size() == 1)
|
||||
m_model->objects.front()->name = m_name;
|
||||
|
@ -3522,23 +3522,19 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
m_is_bbl_3mf = true;
|
||||
m_bambuslicer_generator_version = Semver::parse(m_curr_characters.substr(12));
|
||||
}
|
||||
else if (boost::starts_with(m_curr_characters, "OrcaSlicer-")) {
|
||||
m_is_bbl_3mf = true;
|
||||
m_bambuslicer_generator_version = Semver::parse(m_curr_characters.substr(11));
|
||||
}
|
||||
//TODO: currently use version 0, no need to load&&save this string
|
||||
/*} else if (m_curr_metadata_name == BBS_FDM_SUPPORTS_PAINTING_VERSION) {
|
||||
m_fdm_supports_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
|
||||
check_painting_version(m_fdm_supports_painting_version, FDM_SUPPORTS_PAINTING_VERSION,
|
||||
_(L("The selected 3MF contains FDM supports painted object using a newer version of OrcaSlicer and is not compatible.")));
|
||||
_(L("The selected 3MF contains FDM supports painted object using a newer version of BambuStudio and is not compatible.")));
|
||||
} else if (m_curr_metadata_name == BBS_SEAM_PAINTING_VERSION) {
|
||||
m_seam_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
|
||||
check_painting_version(m_seam_painting_version, SEAM_PAINTING_VERSION,
|
||||
_(L("The selected 3MF contains seam painted object using a newer version of OrcaSlicer and is not compatible.")));
|
||||
_(L("The selected 3MF contains seam painted object using a newer version of BambuStudio and is not compatible.")));
|
||||
} else if (m_curr_metadata_name == BBS_MM_PAINTING_VERSION) {
|
||||
m_mm_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
|
||||
check_painting_version(m_mm_painting_version, MM_PAINTING_VERSION,
|
||||
_(L("The selected 3MF contains multi-material painted object using a newer version of OrcaSlicer and is not compatible.")));*/
|
||||
_(L("The selected 3MF contains multi-material painted object using a newer version of BambuStudio and is not compatible.")));*/
|
||||
} else if (m_curr_metadata_name == BBL_MODEL_ID_TAG) {
|
||||
m_model_id = xml_unescape(m_curr_characters);
|
||||
} else if (m_curr_metadata_name == BBL_MODEL_NAME_TAG) {
|
||||
|
@ -3838,9 +3834,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
{
|
||||
m_curr_plater->plate_index = atoi(value.c_str());
|
||||
}
|
||||
else if(key == PLATER_NAME_ATTR)
|
||||
{
|
||||
m_curr_plater->plate_name = value.c_str();
|
||||
else if (key == PLATER_NAME_ATTR) {
|
||||
m_curr_plater->plate_name = xml_unescape(value.c_str());
|
||||
}
|
||||
else if (key == LOCK_ATTR)
|
||||
{
|
||||
|
@ -4548,7 +4543,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
TriangleMesh triangle_mesh(std::move(its), volume_data.mesh_stats);
|
||||
|
||||
if (!m_is_bbl_3mf) {
|
||||
// if the 3mf was not produced by OrcaSlicer and there is only one instance,
|
||||
// if the 3mf was not produced by BambuStudio and there is only one instance,
|
||||
// bake the transformation into the geometry to allow the reload from disk command
|
||||
// to work properly
|
||||
if (object.instances.size() == 1) {
|
||||
|
@ -5419,7 +5414,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
}
|
||||
|
||||
// Adds content types file ("[Content_Types].xml";).
|
||||
// The content of this file is the same for each OrcaSlicer 3mf.
|
||||
// The content of this file is the same for each BambuStudio 3mf.
|
||||
if (!_add_content_types_file_to_archive(archive)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -5774,7 +5769,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
}
|
||||
|
||||
// Adds relationships file ("_rels/.rels").
|
||||
// The content of this file is the same for each OrcaSlicer 3mf.
|
||||
// The content of this file is the same for each BambuStudio 3mf.
|
||||
// The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA.
|
||||
if (!_add_relationships_file_to_archive(archive, {}, {}, {}, temp_data, export_plate_idx)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", _add_relationships_file_to_archive failed\n");
|
||||
|
@ -5939,7 +5934,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
int i = 0;
|
||||
for (auto & path : targets) {
|
||||
for (auto & type : types)
|
||||
stream << " <Relationship Target=\"/" << xml_escape(path) << "\" Id=\"rel-" << std::to_string(++i) << "\" Type=\"" << type << "\"/>\n";
|
||||
stream << " <Relationship Target=\"/" << xml_escape(path) << "\" Id=\"rel-" << boost::to_string(++i) << "\" Type=\"" << type << "\"/>\n";
|
||||
}
|
||||
}
|
||||
stream << "</Relationships>";
|
||||
|
@ -6074,8 +6069,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
date = date.substr(0, 10);
|
||||
metadata_item_map[BBL_CREATION_DATE_TAG] = date;
|
||||
metadata_item_map[BBL_MODIFICATION_TAG] = date;
|
||||
//SoftFever: write BambuStudio tag to keep it compatible
|
||||
metadata_item_map[BBL_APPLICATION_TAG] = (boost::format("%1%-%2%") % "BambuStudio" % SLIC3R_VERSION).str();
|
||||
metadata_item_map[BBL_APPLICATION_TAG] = (boost::format("%1%-%2%") % SLIC3R_APP_KEY % SLIC3R_VERSION).str();
|
||||
}
|
||||
metadata_item_map[BBS_3MF_VERSION] = std::to_string(VERSION_BBS_3MF);
|
||||
|
||||
|
@ -7029,7 +7023,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
stream << " <" << PLATE_TAG << ">\n";
|
||||
//plate index
|
||||
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATERID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->plate_index + 1 << "\"/>\n";
|
||||
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATER_NAME_ATTR << "\" " << VALUE_ATTR << "=\"" << xml_escape(plate_data->plate_name) << "\"/>\n";
|
||||
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATER_NAME_ATTR << "\" " << VALUE_ATTR << "=\"" << xml_escape(plate_data->plate_name.c_str()) << "\"/>\n";
|
||||
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << LOCK_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->locked<< "\"/>\n";
|
||||
ConfigOption* bed_type_opt = plate_data->config.option("curr_bed_type");
|
||||
t_config_enum_names bed_type_names = ConfigOptionEnum<BedType>::get_enum_names();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,6 @@
|
|||
#include "PrintConfig.hpp"
|
||||
#include "GCode/AvoidCrossingPerimeters.hpp"
|
||||
#include "GCode/CoolingBuffer.hpp"
|
||||
#include "GCode/FanMover.hpp"
|
||||
#include "GCode/RetractWhenCrossingPerimeters.hpp"
|
||||
#include "GCode/SpiralVase.hpp"
|
||||
#include "GCode/ToolOrdering.hpp"
|
||||
|
@ -20,7 +19,6 @@
|
|||
#include "EdgeGrid.hpp"
|
||||
#include "GCode/ThumbnailData.hpp"
|
||||
#include "libslic3r/ObjectID.hpp"
|
||||
#include "GCode/ExtrusionProcessor.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
@ -181,7 +179,6 @@ public:
|
|||
const Point& last_pos() const { return m_last_pos; }
|
||||
Vec2d point_to_gcode(const Point &point) const;
|
||||
Point gcode_to_point(const Vec2d &point) const;
|
||||
Vec2d point_to_gcode_quantized(const Point& point) const;
|
||||
const FullPrintConfig &config() const { return m_config; }
|
||||
const Layer* layer() const { return m_layer; }
|
||||
GCodeWriter& writer() { return m_writer; }
|
||||
|
@ -198,19 +195,19 @@ public:
|
|||
void set_layer_count(unsigned int value) { m_layer_count = value; }
|
||||
void apply_print_config(const PrintConfig &print_config);
|
||||
|
||||
std::string travel_to(const Point& point, ExtrusionRole role, std::string comment);
|
||||
bool needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type);
|
||||
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift);
|
||||
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
||||
std::string set_extruder(unsigned int extruder_id, double print_z);
|
||||
bool is_BBL_Printer();
|
||||
|
||||
// SoftFever
|
||||
// OrcaSlicer
|
||||
std::string set_object_info(Print* print);
|
||||
|
||||
// append full config to the given string
|
||||
static void append_full_config(const Print& print, std::string& str);
|
||||
|
||||
// BBS: detect lift type in needs_retraction
|
||||
bool needs_retraction(const Polyline &travel, ExtrusionRole role, LiftType &lift_type);
|
||||
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift);
|
||||
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
||||
//BBS
|
||||
bool is_BBL_Printer();
|
||||
|
||||
// Object and support extrusions of the same PrintObject at the same print_z.
|
||||
// public, so that it could be accessed by free helper functions from GCode.cpp
|
||||
struct LayerToPrint
|
||||
|
@ -335,7 +332,7 @@ private:
|
|||
void set_extruders(const std::vector<unsigned int> &extruder_ids);
|
||||
std::string preamble();
|
||||
// BBS
|
||||
std::string change_layer(coordf_t print_z, bool lazy_raise = false);
|
||||
std::string change_layer(coordf_t print_z);
|
||||
std::string extrude_entity(const ExtrusionEntity &entity, std::string description = "", double speed = -1.);
|
||||
std::string extrude_loop(ExtrusionLoop loop, std::string description, double speed = -1.);
|
||||
std::string extrude_multi_path(ExtrusionMultiPath multipath, std::string description = "", double speed = -1.);
|
||||
|
@ -406,21 +403,20 @@ private:
|
|||
// For sequential print, the instance of the object to be printing has to be defined.
|
||||
const size_t single_object_instance_idx);
|
||||
|
||||
std::string extrude_perimeters(const Print& print, const std::vector<ObjectByExtruder::Island::Region>& by_region);
|
||||
std::string extrude_infill(const Print& print, const std::vector<ObjectByExtruder::Island::Region>& by_region, bool ironing);
|
||||
std::string extrude_support(const ExtrusionEntityCollection& support_fills);
|
||||
std::string extrude_perimeters(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region);
|
||||
std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, bool ironing);
|
||||
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
||||
|
||||
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
||||
// BBS
|
||||
LiftType to_lift_type(ZHopType z_hop_types);
|
||||
|
||||
std::string set_extruder(unsigned int extruder_id, double print_z);
|
||||
std::set<ObjectID> m_objsWithBrim; // indicates the objs with brim
|
||||
std::set<ObjectID> m_objSupportsWithBrim; // indicates the objs' supports with brim
|
||||
// Cache for custom seam enforcers/blockers for each layer.
|
||||
SeamPlacer m_seam_placer;
|
||||
|
||||
ExtrusionQualityEstimator m_extrusion_quality_estimator;
|
||||
|
||||
|
||||
/* Origin of print coordinates expressed in unscaled G-code coordinates.
|
||||
This affects the input arguments supplied to the extrude*() and travel_to()
|
||||
methods. */
|
||||
|
@ -444,13 +440,6 @@ private:
|
|||
// of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _OVERHANG_FAN_START, _OVERHANG_FAN_END
|
||||
// Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module.
|
||||
bool m_enable_cooling_markers;
|
||||
|
||||
bool m_enable_exclude_object;
|
||||
std::vector<size_t> m_label_objects_ids;
|
||||
std::string _encode_label_ids_to_base64(std::vector<size_t> ids);
|
||||
// Orca
|
||||
bool m_is_overhang_fan_on;
|
||||
bool m_is_supp_interface_fan_on;
|
||||
// Markers for the Pressure Equalizer to recognize the extrusion type.
|
||||
// The Pressure Equalizer removes the markers from the final G-code.
|
||||
bool m_enable_extrusion_role_markers;
|
||||
|
@ -469,8 +458,6 @@ private:
|
|||
//double m_volumetric_speed;
|
||||
// Support for the extrusion role markers. Which marker is active?
|
||||
ExtrusionRole m_last_extrusion_role;
|
||||
// To ignore gapfill role for retract_lift_enforce
|
||||
ExtrusionRole m_last_notgapfill_extrusion_role;
|
||||
// Support for G-Code Processor
|
||||
float m_last_height{ 0.0f };
|
||||
float m_last_layer_z{ 0.0f };
|
||||
|
@ -498,15 +485,16 @@ private:
|
|||
bool m_second_layer_things_done;
|
||||
// Index of a last object copy extruded.
|
||||
std::pair<const PrintObject*, Point> m_last_obj_copy;
|
||||
//BBS
|
||||
bool m_enable_label_object;
|
||||
std::vector<size_t> m_label_objects_ids;
|
||||
std::string _encode_label_ids_to_base64(std::vector<size_t> ids);
|
||||
|
||||
bool m_silent_time_estimator_enabled;
|
||||
|
||||
// Processor
|
||||
GCodeProcessor m_processor;
|
||||
|
||||
//some post-processing on the file, with their data class
|
||||
std::unique_ptr<FanMover> m_fan_mover;
|
||||
|
||||
// BBS
|
||||
Print* m_curr_print = nullptr;
|
||||
unsigned int m_toolchange_count;
|
||||
|
@ -523,12 +511,7 @@ private:
|
|||
void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
|
||||
// On the first printing layer. This flag triggers first layer speeds.
|
||||
//BBS
|
||||
bool on_first_layer() const { return m_layer != nullptr && m_layer->id() == 0 && abs(m_layer->bottom_z()) < EPSILON; }
|
||||
int layer_id() const {
|
||||
if (m_layer == nullptr)
|
||||
return -1;
|
||||
return m_layer->id();
|
||||
}
|
||||
bool on_first_layer() const { return m_layer != nullptr && m_layer->id() == 0 && abs(m_layer->bottom_z()) < EPSILON; }
|
||||
// To control print speed of 1st object layer over raft interface.
|
||||
bool object_layer_over_raft() const { return m_object_layer_over_raft; }
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <boost/log/trivial.hpp>
|
||||
#include <iostream>
|
||||
#include <float.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#if 0
|
||||
#define DEBUG
|
||||
|
@ -62,8 +61,7 @@ struct CoolingLine
|
|||
TYPE_G2 = 1 << 12,
|
||||
TYPE_G3 = 1 << 13,
|
||||
TYPE_FORCE_RESUME_FAN = 1 << 14,
|
||||
TYPE_SUPPORT_INTERFACE_FAN_START = 1 << 15,
|
||||
TYPE_SUPPORT_INTERFACE_FAN_END = 1 << 16,
|
||||
TYPE_SET_FAN_CHANGING_LAYER = 1 << 15,
|
||||
};
|
||||
|
||||
CoolingLine(unsigned int type, size_t line_start, size_t line_end) :
|
||||
|
@ -482,10 +480,6 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
|||
line.type = CoolingLine::TYPE_OVERHANG_FAN_START;
|
||||
} else if (boost::starts_with(sline, ";_OVERHANG_FAN_END")) {
|
||||
line.type = CoolingLine::TYPE_OVERHANG_FAN_END;
|
||||
} else if (boost::starts_with(sline, ";_SUPP_INTERFACE_FAN_START")) {
|
||||
line.type = CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START;
|
||||
} else if (boost::starts_with(sline, ";_SUPP_INTERFACE_FAN_END")) {
|
||||
line.type = CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_END;
|
||||
} else if (boost::starts_with(sline, "G4 ")) {
|
||||
// Parse the wait time.
|
||||
line.type = CoolingLine::TYPE_G4;
|
||||
|
@ -497,6 +491,8 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
|||
(pos_P > 0) ? atof(sline.c_str() + pos_P + 1) * 0.001 : 0.);
|
||||
} else if (boost::starts_with(sline, ";_FORCE_RESUME_FAN_SPEED")) {
|
||||
line.type = CoolingLine::TYPE_FORCE_RESUME_FAN;
|
||||
} else if (boost::starts_with(sline, ";_SET_FAN_SPEED_CHANGING_LAYER")) {
|
||||
line.type = CoolingLine::TYPE_SET_FAN_CHANGING_LAYER;
|
||||
}
|
||||
if (line.type != 0)
|
||||
adjustment->lines.emplace_back(std::move(line));
|
||||
|
@ -729,9 +725,14 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||
new_gcode.reserve(gcode.size() * 2);
|
||||
bool overhang_fan_control= false;
|
||||
int overhang_fan_speed = 0;
|
||||
bool supp_interface_fan_control= false;
|
||||
int supp_interface_fan_speed = 0;
|
||||
auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &overhang_fan_control, &overhang_fan_speed, &supp_interface_fan_control, &supp_interface_fan_speed](bool immediately_apply) {
|
||||
|
||||
enum class SetFanType {
|
||||
sfChangingLayer = 0,
|
||||
sfChangingFilament,
|
||||
sfImmediatelyApply
|
||||
};
|
||||
|
||||
auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &overhang_fan_control, &overhang_fan_speed](SetFanType type) {
|
||||
#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_current_extruder)
|
||||
int fan_min_speed = EXTRUDER_CONFIG(fan_min_speed);
|
||||
int fan_speed_new = EXTRUDER_CONFIG(reduce_fan_stop_start_freq) ? fan_min_speed : 0;
|
||||
|
@ -740,8 +741,6 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||
int close_fan_the_first_x_layers = EXTRUDER_CONFIG(close_fan_the_first_x_layers);
|
||||
// Is the fan speed ramp enabled?
|
||||
int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer);
|
||||
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
||||
|
||||
if (close_fan_the_first_x_layers <= 0 && full_fan_speed_layer > 0) {
|
||||
// When ramping up fan speed from close_fan_the_first_x_layers to full_fan_speed_layer, force close_fan_the_first_x_layers above zero,
|
||||
// so there will be a zero fan speed at least at the 1st layer.
|
||||
|
@ -770,9 +769,6 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||
fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255);
|
||||
overhang_fan_speed = std::clamp(int(float(overhang_fan_speed) * factor + 0.5f), 0, 255);
|
||||
}
|
||||
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
||||
supp_interface_fan_control = supp_interface_fan_speed >= 0;
|
||||
|
||||
#undef EXTRUDER_CONFIG
|
||||
overhang_fan_control= overhang_fan_speed > fan_speed_new;
|
||||
} else {
|
||||
|
@ -780,34 +776,34 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||
overhang_fan_speed = 0;
|
||||
fan_speed_new = 0;
|
||||
additional_fan_speed_new = 0;
|
||||
supp_interface_fan_control= false;
|
||||
supp_interface_fan_speed = 0;
|
||||
}
|
||||
if (fan_speed_new != m_fan_speed) {
|
||||
m_fan_speed = fan_speed_new;
|
||||
//BBS
|
||||
m_current_fan_speed = fan_speed_new;
|
||||
if (immediately_apply)
|
||||
if (type == SetFanType::sfImmediatelyApply)
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
|
||||
else if (type == SetFanType::sfChangingLayer)
|
||||
this->m_set_fan_changing_layer = true;
|
||||
//BBS: don't need to handle change filament, because we are always force to resume fan speed when filament change is finished
|
||||
}
|
||||
//BBS
|
||||
if (additional_fan_speed_new != m_additional_fan_speed) {
|
||||
m_additional_fan_speed = additional_fan_speed_new;
|
||||
if (immediately_apply && m_config.auxiliary_fan.value)
|
||||
if (type == SetFanType::sfImmediatelyApply)
|
||||
new_gcode += GCodeWriter::set_additional_fan(m_additional_fan_speed);
|
||||
else if (type == SetFanType::sfChangingLayer)
|
||||
this->m_set_addition_fan_changing_layer = true;
|
||||
//BBS: don't need to handle change filament, because we are always force to resume fan speed when filament change is finished
|
||||
}
|
||||
};
|
||||
|
||||
const char *pos = gcode.c_str();
|
||||
int current_feedrate = 0;
|
||||
change_extruder_set_fan(true);
|
||||
|
||||
// Reduce set fan commands by deferring the GCodeWriter::set_fan calls. Inspired by SuperSlicer
|
||||
// define fan_speed_change_requests and initialize it with all possible types fan speed change requests
|
||||
std::unordered_map<int, bool> fan_speed_change_requests = {{CoolingLine::TYPE_OVERHANG_FAN_START, false},
|
||||
{CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START, false},
|
||||
{CoolingLine::TYPE_FORCE_RESUME_FAN, false}};
|
||||
bool need_set_fan = false;
|
||||
|
||||
//BBS
|
||||
m_set_fan_changing_layer = false;
|
||||
m_set_addition_fan_changing_layer = false;
|
||||
change_extruder_set_fan(SetFanType::sfChangingLayer);
|
||||
for (const CoolingLine *line : lines) {
|
||||
const char *line_start = gcode.c_str() + line->line_start;
|
||||
const char *line_end = gcode.c_str() + line->line_end;
|
||||
|
@ -817,37 +813,37 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||
unsigned int new_extruder = (unsigned int)atoi(line_start + m_toolchange_prefix.size());
|
||||
if (new_extruder != m_current_extruder) {
|
||||
m_current_extruder = new_extruder;
|
||||
change_extruder_set_fan(false); //BBS: will force to resume fan speed when filament change is finished
|
||||
change_extruder_set_fan(SetFanType::sfChangingFilament); //BBS: will force to resume fan speed when filament change is finished
|
||||
}
|
||||
new_gcode.append(line_start, line_end - line_start);
|
||||
} else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_START) {
|
||||
if (overhang_fan_control && !fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) {
|
||||
need_set_fan = true;
|
||||
fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START] = true;
|
||||
}
|
||||
if (overhang_fan_control) {
|
||||
//BBS
|
||||
m_current_fan_speed = overhang_fan_speed;
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed);
|
||||
}
|
||||
} else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_END) {
|
||||
if (overhang_fan_control && fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) {
|
||||
fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START] = false;
|
||||
if (overhang_fan_control) {
|
||||
//BBS
|
||||
m_current_fan_speed = m_fan_speed;
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
|
||||
}
|
||||
need_set_fan = true;
|
||||
} else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START) {
|
||||
if (supp_interface_fan_control && !fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]) {
|
||||
fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START] = true;
|
||||
need_set_fan = true;
|
||||
}
|
||||
} else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_END && fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]) {
|
||||
if (supp_interface_fan_control) {
|
||||
fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START] = false;
|
||||
}
|
||||
need_set_fan = true;
|
||||
} else if (line->type & CoolingLine::TYPE_FORCE_RESUME_FAN) {
|
||||
// check if any fan speed change request is active
|
||||
if (m_fan_speed != -1 && !std::any_of(fan_speed_change_requests.begin(), fan_speed_change_requests.end(), [](const std::pair<int, bool>& p) { return p.second; })){
|
||||
fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] = true;
|
||||
need_set_fan = true;
|
||||
}
|
||||
if (m_additional_fan_speed != -1 && m_config.auxiliary_fan.value)
|
||||
//BBS: force to write a fan speed command again
|
||||
if (m_current_fan_speed != -1)
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed);
|
||||
if (m_additional_fan_speed != -1)
|
||||
new_gcode += GCodeWriter::set_additional_fan(m_additional_fan_speed);
|
||||
} else if (line->type & CoolingLine::TYPE_SET_FAN_CHANGING_LAYER) {
|
||||
//BBS: check whether fan speed need to changed when change layer
|
||||
if (m_current_fan_speed != -1 && m_set_fan_changing_layer) {
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed);
|
||||
m_set_fan_changing_layer = false;
|
||||
}
|
||||
if (m_additional_fan_speed != -1 && m_set_addition_fan_changing_layer) {
|
||||
new_gcode += GCodeWriter::set_additional_fan(m_additional_fan_speed);
|
||||
m_set_addition_fan_changing_layer = false;
|
||||
}
|
||||
}
|
||||
else if (line->type & CoolingLine::TYPE_EXTRUDE_END) {
|
||||
// Just remove this comment.
|
||||
|
@ -933,24 +929,6 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||
} else {
|
||||
new_gcode.append(line_start, line_end - line_start);
|
||||
}
|
||||
|
||||
if (need_set_fan) {
|
||||
if (fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]){
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed);
|
||||
m_current_fan_speed = overhang_fan_speed;
|
||||
}
|
||||
else if (fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]){
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed);
|
||||
m_current_fan_speed = supp_interface_fan_speed;
|
||||
}
|
||||
else if(fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] && m_current_fan_speed != -1){
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed);
|
||||
fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] = false;
|
||||
}
|
||||
else
|
||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
|
||||
need_set_fan = false;
|
||||
}
|
||||
pos = line_end;
|
||||
}
|
||||
const char *gcode_end = gcode.c_str() + gcode.size();
|
||||
|
|
|
@ -59,6 +59,9 @@ private:
|
|||
bool m_cooling_logic_proportional = false;
|
||||
//BBS: current fan speed
|
||||
int m_current_fan_speed;
|
||||
//BBS:
|
||||
bool m_set_fan_changing_layer = false;
|
||||
bool m_set_addition_fan_changing_layer = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "ExtrusionEntity.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
|
@ -17,7 +16,6 @@
|
|||
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
#include <regex>
|
||||
|
||||
#if __has_include(<charconv>)
|
||||
#include <charconv>
|
||||
|
@ -62,23 +60,6 @@ const std::vector<std::string> GCodeProcessor::Reserved_Tags = {
|
|||
"_GP_TOTAL_LAYER_NUMBER_PLACEHOLDER"
|
||||
};
|
||||
|
||||
const std::vector<std::string> GCodeProcessor::Reserved_Tags_compatible = {
|
||||
"TYPE:",
|
||||
"WIPE_START",
|
||||
"WIPE_END",
|
||||
"HEIGHT:",
|
||||
"WIDTH:",
|
||||
"LAYER_CHANGE",
|
||||
"COLOR_CHANGE",
|
||||
"PAUSE_PRINT",
|
||||
"CUSTOM_GCODE",
|
||||
"_GP_FIRST_LINE_M73_PLACEHOLDER",
|
||||
"_GP_LAST_LINE_M73_PLACEHOLDER",
|
||||
"_GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER",
|
||||
"_GP_TOTAL_LAYER_NUMBER_PLACEHOLDER"
|
||||
};
|
||||
|
||||
|
||||
const std::string GCodeProcessor::Flush_Start_Tag = " FLUSH_START";
|
||||
const std::string GCodeProcessor::Flush_End_Tag = " FLUSH_END";
|
||||
|
||||
|
@ -92,8 +73,6 @@ const std::map<NozzleType,int> GCodeProcessor::Nozzle_Type_To_HRC={
|
|||
const float GCodeProcessor::Wipe_Width = 0.05f;
|
||||
const float GCodeProcessor::Wipe_Height = 0.05f;
|
||||
|
||||
bool GCodeProcessor::s_IsBBLPrinter = true;
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "MM3_PER_MM:";
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
@ -122,16 +101,16 @@ static float intersection_distance(float initial_rate, float final_rate, float a
|
|||
|
||||
static float speed_from_distance(float initial_feedrate, float distance, float acceleration)
|
||||
{
|
||||
// to avoid invalid negative numbers due to numerical errors
|
||||
// to avoid invalid negative numbers due to numerical errors
|
||||
float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance);
|
||||
return ::sqrt(value);
|
||||
}
|
||||
|
||||
// Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the
|
||||
// Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the
|
||||
// acceleration within the allotted distance.
|
||||
static float max_allowable_speed(float acceleration, float target_velocity, float distance)
|
||||
{
|
||||
// to avoid invalid negative numbers due to numerical errors
|
||||
// to avoid invalid negative numbers due to numerical errors
|
||||
float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance);
|
||||
return std::sqrt(value);
|
||||
}
|
||||
|
@ -182,7 +161,7 @@ void GCodeProcessor::TimeBlock::calculate_trapezoid()
|
|||
float cruise_distance = distance - accelerate_distance - decelerate_distance;
|
||||
|
||||
// Not enough space to reach the nominal feedrate.
|
||||
// This means no cruising, and we'll have to use intersection_distance() to calculate when to abort acceleration
|
||||
// This means no cruising, and we'll have to use intersection_distance() to calculate when to abort acceleration
|
||||
// and start braking in order to reach the exit_feedrate exactly at the end of this block.
|
||||
if (cruise_distance < 0.0f) {
|
||||
accelerate_distance = std::clamp(intersection_distance(feedrate_profile.entry, feedrate_profile.exit, acceleration, distance), 0.0f, distance);
|
||||
|
@ -491,17 +470,12 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
|||
PrintEstimatedStatistics::ETimeMode mode = static_cast<PrintEstimatedStatistics::ETimeMode>(i);
|
||||
if (mode == PrintEstimatedStatistics::ETimeMode::Normal || machine.enabled) {
|
||||
char buf[128];
|
||||
if(!s_IsBBLPrinter)
|
||||
// SoftFever: compatibility with klipper_estimator
|
||||
sprintf(buf, "; estimated printing time (normal mode) = %s\n", get_time_dhms(machine.time).c_str());
|
||||
else {
|
||||
//sprintf(buf, "; estimated printing time (%s mode) = %s\n",
|
||||
// (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent",
|
||||
// get_time_dhms(machine.time).c_str());
|
||||
sprintf(buf, "; model printing time: %s; total estimated time: %s\n",
|
||||
get_time_dhms(machine.time - machine.prepare_time).c_str(),
|
||||
get_time_dhms(machine.time).c_str());
|
||||
}
|
||||
ret += buf;
|
||||
}
|
||||
}
|
||||
|
@ -662,7 +636,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
|||
if (processed && lines_added_count > 0)
|
||||
offsets.push_back({ line_id, lines_added_count });
|
||||
if (! processed && ! is_temporary_decoration(gcode_line) &&
|
||||
(GCodeReader::GCodeLine::cmd_is(gcode_line, "G1") ||
|
||||
(GCodeReader::GCodeLine::cmd_is(gcode_line, "G1") ||
|
||||
GCodeReader::GCodeLine::cmd_is(gcode_line, "G2") ||
|
||||
GCodeReader::GCodeLine::cmd_is(gcode_line, "G3"))) {
|
||||
// remove temporary lines, add lines M73 where needed
|
||||
|
@ -677,7 +651,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
|||
gcode_line.clear();
|
||||
}
|
||||
// Skip EOL.
|
||||
it = it_end;
|
||||
it = it_end;
|
||||
if (it != it_bufend && *it == '\r')
|
||||
++ it;
|
||||
if (it != it_bufend && *it == '\n')
|
||||
|
@ -848,12 +822,10 @@ void GCodeProcessorResult::reset() {
|
|||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
const std::vector<std::pair<GCodeProcessor::EProducer, std::string>> GCodeProcessor::Producers = {
|
||||
//BBS: OrcaSlicer is also "bambu". Otherwise the time estimation didn't work.
|
||||
//BBS: BambuStudio is also "bambu". Otherwise the time estimation didn't work.
|
||||
//FIXME: Workaround and should be handled when do removing-bambu
|
||||
{ EProducer::OrcaSlicer, SLIC3R_APP_NAME },
|
||||
{ EProducer::OrcaSlicer, "generated by OrcaSlicer" },
|
||||
{ EProducer::OrcaSlicer, "generated by BambuStudio" },
|
||||
{ EProducer::OrcaSlicer, "BambuStudio" }
|
||||
{ EProducer::BambuStudio, SLIC3R_APP_NAME },
|
||||
{ EProducer::BambuStudio, "generated by BambuStudio" }
|
||||
//{ EProducer::Slic3rPE, "generated by Slic3r Bambu Edition" },
|
||||
//{ EProducer::Slic3r, "generated by Slic3r" },
|
||||
//{ EProducer::SuperSlicer, "generated by SuperSlicer" },
|
||||
|
@ -871,12 +843,11 @@ bool GCodeProcessor::contains_reserved_tag(const std::string& gcode, std::string
|
|||
bool ret = false;
|
||||
|
||||
GCodeReader parser;
|
||||
auto& _tags = s_IsBBLPrinter ? Reserved_Tags : Reserved_Tags_compatible;
|
||||
parser.parse_buffer(gcode, [&ret, &found_tag, _tags](GCodeReader& parser, const GCodeReader::GCodeLine& line) {
|
||||
parser.parse_buffer(gcode, [&ret, &found_tag](GCodeReader& parser, const GCodeReader::GCodeLine& line) {
|
||||
std::string comment = line.raw();
|
||||
if (comment.length() > 2 && comment.front() == ';') {
|
||||
comment = comment.substr(1);
|
||||
for (const std::string& s : _tags) {
|
||||
for (const std::string& s : Reserved_Tags) {
|
||||
if (boost::starts_with(comment, s)) {
|
||||
ret = true;
|
||||
found_tag = comment;
|
||||
|
@ -899,12 +870,11 @@ bool GCodeProcessor::contains_reserved_tags(const std::string& gcode, unsigned i
|
|||
CNumericLocalesSetter locales_setter;
|
||||
|
||||
GCodeReader parser;
|
||||
auto& _tags = s_IsBBLPrinter ? Reserved_Tags : Reserved_Tags_compatible;
|
||||
parser.parse_buffer(gcode, [&ret, &found_tag, max_count, _tags](GCodeReader& parser, const GCodeReader::GCodeLine& line) {
|
||||
parser.parse_buffer(gcode, [&ret, &found_tag, max_count](GCodeReader& parser, const GCodeReader::GCodeLine& line) {
|
||||
std::string comment = line.raw();
|
||||
if (comment.length() > 2 && comment.front() == ';') {
|
||||
comment = comment.substr(1);
|
||||
for (const std::string& s : _tags) {
|
||||
for (const std::string& s : Reserved_Tags) {
|
||||
if (boost::starts_with(comment, s)) {
|
||||
ret = true;
|
||||
found_tag.push_back(comment);
|
||||
|
@ -947,7 +917,6 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
|||
m_result.filament_densities.resize(extruders_count);
|
||||
m_result.filament_vitrification_temperature.resize(extruders_count);
|
||||
m_extruder_temps.resize(extruders_count);
|
||||
m_result.nozzle_hrc = static_cast<int>(config.nozzle_hrc.getInt());
|
||||
m_result.nozzle_type = config.nozzle_type;
|
||||
for (size_t i = 0; i < extruders_count; ++ i) {
|
||||
m_extruder_offsets[i] = to_3d(config.extruder_offset.get_at(i).cast<float>().eval(), 0.f);
|
||||
|
@ -958,17 +927,12 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
|||
m_result.filament_vitrification_temperature[i] = static_cast<float>(config.temperature_vitrification.get_at(i));
|
||||
}
|
||||
|
||||
if (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware || m_flavor == gcfKlipper || m_flavor == gcfRepRapFirmware) {
|
||||
if (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware || m_flavor == gcfKlipper) {
|
||||
m_time_processor.machine_limits = reinterpret_cast<const MachineEnvelopeConfig&>(config);
|
||||
if (m_flavor == gcfMarlinLegacy) {
|
||||
// Legacy Marlin does not have separate travel acceleration, it uses the 'extruding' value instead.
|
||||
m_time_processor.machine_limits.machine_max_acceleration_travel = m_time_processor.machine_limits.machine_max_acceleration_extruding;
|
||||
}
|
||||
if (m_flavor == gcfRepRapFirmware) {
|
||||
// RRF does not support setting min feedrates. Set them to zero.
|
||||
m_time_processor.machine_limits.machine_min_travel_rate.values.assign(m_time_processor.machine_limits.machine_min_travel_rate.size(), 0.);
|
||||
m_time_processor.machine_limits.machine_min_extruding_rate.values.assign(m_time_processor.machine_limits.machine_min_extruding_rate.size(), 0.);
|
||||
}
|
||||
}
|
||||
|
||||
// Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful.
|
||||
|
@ -1009,9 +973,6 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
|||
if (nozzle_volume != nullptr)
|
||||
m_nozzle_volume = nozzle_volume->value;
|
||||
|
||||
const ConfigOptionInt *nozzle_HRC = config.option<ConfigOptionInt>("nozzle_hrc");
|
||||
if (nozzle_HRC != nullptr) m_result.nozzle_hrc = nozzle_HRC->value;
|
||||
|
||||
const ConfigOptionEnum<NozzleType>* nozzle_type = config.option<ConfigOptionEnum<NozzleType>>("nozzle_type");
|
||||
if (nozzle_type != nullptr)
|
||||
m_result.nozzle_type=nozzle_type->value;
|
||||
|
@ -1119,7 +1080,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_extruder_offsets.size() < m_result.extruders_count) {
|
||||
for (size_t i = m_extruder_offsets.size(); i < m_result.extruders_count; ++i) {
|
||||
m_extruder_offsets.emplace_back(DEFAULT_EXTRUDER_OFFSET);
|
||||
|
@ -1394,12 +1355,12 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
|
|||
});
|
||||
m_parser.reset();
|
||||
|
||||
// if the gcode was produced by OrcaSlicer,
|
||||
// if the gcode was produced by BambuStudio,
|
||||
// extract the config from it
|
||||
if (m_producer == EProducer::OrcaSlicer || m_producer == EProducer::Slic3rPE || m_producer == EProducer::Slic3r) {
|
||||
if (m_producer == EProducer::BambuStudio || m_producer == EProducer::Slic3rPE || m_producer == EProducer::Slic3r) {
|
||||
DynamicPrintConfig config;
|
||||
config.apply(FullPrintConfig::defaults());
|
||||
// Silently substitute unknown values by new ones for loading configurations from OrcaSlicer's own G-code.
|
||||
// Silently substitute unknown values by new ones for loading configurations from BambuStudio's own G-code.
|
||||
// Showing substitution log or errors may make sense, but we are not really reading many values from the G-code config,
|
||||
// thus a probability of incorrect substitution is low and the G-code viewer is a consumer-only anyways.
|
||||
config.load_from_gcode_file(filename, ForwardCompatibilitySubstitutionRule::EnableSilent);
|
||||
|
@ -1449,7 +1410,7 @@ void GCodeProcessor::initialize(const std::string& filename)
|
|||
void GCodeProcessor::process_buffer(const std::string &buffer)
|
||||
{
|
||||
//FIXME maybe cache GCodeLine gline to be over multiple parse_buffer() invocations.
|
||||
m_parser.parse_buffer(buffer, [this](GCodeReader&, const GCodeReader::GCodeLine& line) {
|
||||
m_parser.parse_buffer(buffer, [this](GCodeReader&, const GCodeReader::GCodeLine& line) {
|
||||
this->process_gcode_line(line, false);
|
||||
});
|
||||
}
|
||||
|
@ -1491,7 +1452,7 @@ void GCodeProcessor::finalize(bool post_process)
|
|||
else
|
||||
m_result.moves[i].layer_duration = 0;
|
||||
}
|
||||
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
std::cout << "\n";
|
||||
m_mm3_per_mm_compare.output();
|
||||
|
@ -1647,7 +1608,7 @@ void GCodeProcessor::apply_config_simplify3d(const std::string& filename)
|
|||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
begin = skip_whitespaces(begin, end);
|
||||
end = remove_eols(begin, end);
|
||||
if (begin != end) {
|
||||
|
@ -1705,6 +1666,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool
|
|||
m_start_position = m_end_position;
|
||||
|
||||
const std::string_view cmd = line.cmd();
|
||||
//OrcaSlicer
|
||||
if (m_flavor == gcfKlipper)
|
||||
{
|
||||
if (boost::iequals(cmd, "SET_VELOCITY_LIMIT"))
|
||||
|
@ -1728,7 +1690,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool
|
|||
case '2':
|
||||
case '3': { process_G2_G3(line); break; } // Move
|
||||
//BBS
|
||||
case 4: { process_G4(line); break; } // Delay
|
||||
case '4': { process_G4(line); break; } // Delay
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
@ -1928,7 +1890,7 @@ template<typename T>
|
|||
auto str_end = sv.data() + sv.size();
|
||||
auto [end_ptr, error_code] = std::from_chars(sv.data(), str_end, out);
|
||||
return error_code == std::errc() && end_ptr == str_end;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
@ -2081,7 +2043,7 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
|
|||
return;
|
||||
}
|
||||
|
||||
if (!producers_enabled || m_producer == EProducer::OrcaSlicer) {
|
||||
if (!producers_enabled || m_producer == EProducer::BambuStudio) {
|
||||
// height tag
|
||||
if (boost::starts_with(comment, reserved_tag(ETags::Height))) {
|
||||
if (!parse_number(comment.substr(reserved_tag(ETags::Height).size()), m_forced_height))
|
||||
|
@ -2219,9 +2181,9 @@ bool GCodeProcessor::process_producers_tags(const std::string_view comment)
|
|||
switch (m_producer)
|
||||
{
|
||||
case EProducer::Slic3rPE:
|
||||
case EProducer::Slic3r:
|
||||
case EProducer::Slic3r:
|
||||
case EProducer::SuperSlicer:
|
||||
case EProducer::OrcaSlicer: { return process_bambuslicer_tags(comment); }
|
||||
case EProducer::BambuStudio: { return process_bambuslicer_tags(comment); }
|
||||
case EProducer::Cura: { return process_cura_tags(comment); }
|
||||
case EProducer::Simplify3D: { return process_simplify3d_tags(comment); }
|
||||
case EProducer::CraftWare: { return process_craftware_tags(comment); }
|
||||
|
@ -2326,7 +2288,7 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment)
|
|||
set_extrusion_role(erSkirt);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ; outer perimeter
|
||||
pos = cmt.find(" outer perimeter");
|
||||
if (pos == 0) {
|
||||
|
@ -2370,13 +2332,6 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment)
|
|||
return true;
|
||||
}
|
||||
|
||||
// ; internal bridge
|
||||
pos = cmt.find(" internal bridge");
|
||||
if (pos == 0) {
|
||||
set_extrusion_role(erInternalBridgeInfill);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ; support
|
||||
pos = cmt.find(" support");
|
||||
if (pos == 0) {
|
||||
|
@ -2528,8 +2483,6 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string_view comment)
|
|||
set_extrusion_role(erInternalInfill);
|
||||
else if (type == "BRIDGE")
|
||||
set_extrusion_role(erBridgeInfill);
|
||||
else if (type == "INTERNAL BRIDGE")
|
||||
set_extrusion_role(erInternalBridgeInfill);
|
||||
else if (type == "SUPPORT")
|
||||
set_extrusion_role(erSupportMaterial);
|
||||
else {
|
||||
|
@ -2729,7 +2682,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
type = (delta_pos[Z] == 0.0f) ? EMoveType::Unretract : EMoveType::Travel;
|
||||
else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f)
|
||||
type = EMoveType::Extrude;
|
||||
}
|
||||
}
|
||||
else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f)
|
||||
type = EMoveType::Travel;
|
||||
|
||||
|
@ -2802,7 +2755,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
else if (m_extrusion_role == erExternalPerimeter)
|
||||
// cross section: rectangle
|
||||
m_width = delta_pos[E] * static_cast<float>(M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_height);
|
||||
else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erInternalBridgeInfill || m_extrusion_role == erNone)
|
||||
else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erNone)
|
||||
// cross section: circle
|
||||
m_width = static_cast<float>(m_result.filament_diameters[m_extruder_id]) * std::sqrt(delta_pos[E] / delta_xyz);
|
||||
else
|
||||
|
@ -2927,7 +2880,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
}
|
||||
|
||||
// calculates block acceleration
|
||||
float acceleration =
|
||||
float acceleration =
|
||||
(type == EMoveType::Travel) ? get_travel_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)) :
|
||||
(is_extrusion_only_move(delta_pos) ?
|
||||
get_retract_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)) :
|
||||
|
@ -3259,7 +3212,7 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line)
|
|||
else if (m_extrusion_role == erExternalPerimeter)
|
||||
//BBS: cross section: rectangle
|
||||
m_width = delta_pos[E] * static_cast<float>(M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_height);
|
||||
else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erInternalBridgeInfill || m_extrusion_role == erNone)
|
||||
else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erNone)
|
||||
//BBS: cross section: circle
|
||||
m_width = static_cast<float>(m_result.filament_diameters[m_extruder_id]) * std::sqrt(delta_pos[E] / delta_xyz);
|
||||
else
|
||||
|
@ -3402,7 +3355,7 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line)
|
|||
}
|
||||
else if (a == Y || a == Z) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
float v_exit = prev.axis_feedrate[a];
|
||||
float v_entry = curr.axis_feedrate[a];
|
||||
|
@ -3625,7 +3578,7 @@ void GCodeProcessor::process_G92(const GCodeReader::GCodeLine& line)
|
|||
simulate_st_synchronize();
|
||||
|
||||
if (!any_found && !line.has_unknown_axis()) {
|
||||
// The G92 may be called for axes that PrusaSlicer does not recognize, for example see GH issue #3510,
|
||||
// The G92 may be called for axes that PrusaSlicer does not recognize, for example see GH issue #3510,
|
||||
// where G92 A0 B0 is called although the extruder axis is till E.
|
||||
for (unsigned char a = X; a <= E; ++a) {
|
||||
m_origin[a] = m_end_position[a];
|
||||
|
@ -3873,7 +3826,7 @@ void GCodeProcessor::process_SET_VELOCITY_LIMIT(const GCodeReader::GCodeLine& li
|
|||
{
|
||||
_jerk = std::stof(matches[1]);
|
||||
}
|
||||
catch (...){}
|
||||
catch (...) {}
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, _jerk);
|
||||
set_option_value(m_time_processor.machine_limits.machine_max_jerk_y, i, _jerk);
|
||||
|
@ -3903,8 +3856,8 @@ void GCodeProcessor::process_SET_VELOCITY_LIMIT(const GCodeReader::GCodeLine& li
|
|||
}
|
||||
catch (...) {}
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
set_option_value(m_time_processor.machine_limits.machine_max_speed_x, i, _speed);
|
||||
set_option_value(m_time_processor.machine_limits.machine_max_speed_y, i, _speed);
|
||||
set_option_value(m_time_processor.machine_limits.machine_max_speed_x, i, _speed);
|
||||
set_option_value(m_time_processor.machine_limits.machine_max_speed_y, i, _speed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4336,9 +4289,7 @@ void GCodeProcessor::update_slice_warnings()
|
|||
warning.params.clear();
|
||||
warning.level=1;
|
||||
|
||||
int nozzle_hrc = m_result.nozzle_hrc;
|
||||
if(nozzle_hrc <= 0)
|
||||
nozzle_hrc = Nozzle_Type_To_HRC.find(m_result.nozzle_type)->second;
|
||||
int nozzle_hrc = Nozzle_Type_To_HRC.find(m_result.nozzle_type)->second;
|
||||
if (nozzle_hrc!=0) {
|
||||
for (size_t i = 0; i < used_extruders.size(); i++) {
|
||||
int HRC=0;
|
||||
|
@ -4359,3 +4310,4 @@ void GCodeProcessor::update_slice_warnings()
|
|||
}
|
||||
|
||||
} /* namespace Slic3r */
|
||||
|
||||
|
|
|
@ -97,11 +97,11 @@ namespace Slic3r {
|
|||
{
|
||||
std::string _objName1;
|
||||
std::string _objName2;
|
||||
double _height;
|
||||
float _height;
|
||||
const void *_obj1; // nullptr means wipe tower
|
||||
const void *_obj2;
|
||||
int layer = -1;
|
||||
ConflictResult(const std::string &objName1, const std::string &objName2, double height, const void *obj1, const void *obj2)
|
||||
ConflictResult(const std::string &objName1, const std::string &objName2, float height, const void *obj1, const void *obj2)
|
||||
: _objName1(objName1), _objName2(objName2), _height(height), _obj1(obj1), _obj2(obj2)
|
||||
{}
|
||||
ConflictResult() = default;
|
||||
|
@ -192,7 +192,6 @@ namespace Slic3r {
|
|||
std::vector<std::pair<float, std::pair<size_t, size_t>>> spiral_vase_layers;
|
||||
//BBS
|
||||
std::vector<SliceWarning> warnings;
|
||||
int nozzle_hrc;
|
||||
NozzleType nozzle_type;
|
||||
BedType bed_type = BedType::btCount;
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
@ -236,7 +235,6 @@ namespace Slic3r {
|
|||
class GCodeProcessor
|
||||
{
|
||||
static const std::vector<std::string> Reserved_Tags;
|
||||
static const std::vector<std::string> Reserved_Tags_compatible;
|
||||
static const std::string Flush_Start_Tag;
|
||||
static const std::string Flush_End_Tag;
|
||||
static const std::map<NozzleType, int>Nozzle_Type_To_HRC;
|
||||
|
@ -258,8 +256,8 @@ namespace Slic3r {
|
|||
Total_Layer_Number_Placeholder
|
||||
};
|
||||
|
||||
static const std::string& reserved_tag(ETags tag) { return s_IsBBLPrinter ? Reserved_Tags[static_cast<unsigned char>(tag)] : Reserved_Tags_compatible[static_cast<unsigned char>(tag)]; }
|
||||
// checks the given gcode for reserved tags and returns true when finding the 1st (which is returned into found_tag)
|
||||
static const std::string& reserved_tag(ETags tag) { return Reserved_Tags[static_cast<unsigned char>(tag)]; }
|
||||
// checks the given gcode for reserved tags and returns true when finding the 1st (which is returned into found_tag)
|
||||
static bool contains_reserved_tag(const std::string& gcode, std::string& found_tag);
|
||||
// checks the given gcode for reserved tags and returns true when finding any
|
||||
// (the first max_count found tags are returned into found_tag)
|
||||
|
@ -271,8 +269,6 @@ namespace Slic3r {
|
|||
static const float Wipe_Width;
|
||||
static const float Wipe_Height;
|
||||
|
||||
static bool s_IsBBLPrinter;
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
static const std::string Mm3_Per_Mm_Tag;
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
@ -369,7 +365,7 @@ namespace Slic3r {
|
|||
AxisCoords axis_feedrate; // mm/s
|
||||
AxisCoords abs_axis_feedrate; // mm/s
|
||||
|
||||
//BBS: unit vector of enter speed and exit speed in x-y-z space.
|
||||
//BBS: unit vector of enter speed and exit speed in x-y-z space.
|
||||
//For line move, there are same. For arc move, there are different.
|
||||
Vec3f enter_direction;
|
||||
Vec3f exit_direction;
|
||||
|
@ -673,7 +669,7 @@ namespace Slic3r {
|
|||
enum class EProducer
|
||||
{
|
||||
Unknown,
|
||||
OrcaSlicer,
|
||||
BambuStudio,
|
||||
Slic3rPE,
|
||||
Slic3r,
|
||||
SuperSlicer,
|
||||
|
|
|
@ -128,9 +128,9 @@ public:
|
|||
}
|
||||
|
||||
WipeTowerWriter& disable_linear_advance() {
|
||||
if(m_gcode_flavor == gcfKlipper)
|
||||
if (m_gcode_flavor == gcfKlipper)
|
||||
m_gcode += "SET_PRESSURE_ADVANCE ADVANCE=0\n";
|
||||
else if(m_gcode_flavor == gcfRepRapFirmware)
|
||||
else if (m_gcode_flavor == gcfRepRapFirmware)
|
||||
m_gcode += std::string("M572 D") + std::to_string(m_current_tool) + " S0\n";
|
||||
else
|
||||
m_gcode += "M900 K0\n";
|
||||
|
|
|
@ -15,21 +15,18 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
bool GCodeWriter::full_gcode_comment = true;
|
||||
const bool GCodeWriter::full_gcode_comment = false;
|
||||
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 use_mach_limits = print_config.gcode_flavor.value == gcfMarlinLegacy ||
|
||||
print_config.gcode_flavor.value == gcfMarlinFirmware ||
|
||||
print_config.gcode_flavor.value == gcfKlipper ||
|
||||
print_config.gcode_flavor.value == gcfRepRapFirmware;
|
||||
m_max_acceleration = std::lrint(use_mach_limits ? print_config.machine_max_acceleration_extruding.values.front() : 0);
|
||||
m_max_jerk = std::lrint(use_mach_limits ? std::min(print_config.machine_max_jerk_x.values.front(), print_config.machine_max_jerk_y.values.front()) : 0);
|
||||
m_max_jerk_z = print_config.machine_max_jerk_z.values.front();
|
||||
m_max_jerk_e = print_config.machine_max_jerk_e.values.front();
|
||||
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<unsigned int> extruder_ids)
|
||||
|
@ -176,16 +173,15 @@ std::string GCodeWriter::set_acceleration(unsigned int acceleration)
|
|||
// This is new MarlinFirmware with separated print/retraction/travel acceleration.
|
||||
// Use M204 P, we don't want to override travel acc by M204 S (which is deprecated anyway).
|
||||
gcode << "M204 P" << acceleration;
|
||||
} else if (FLAVOR_IS(gcfKlipper)) {
|
||||
gcode << "SET_VELOCITY_LIMIT ACCEL=" << acceleration;
|
||||
if (this->config.accel_to_decel_enable) {
|
||||
gcode << " ACCEL_TO_DECEL=" << acceleration * this->config.accel_to_decel_factor / 100;
|
||||
if (GCodeWriter::full_gcode_comment)
|
||||
gcode << " ; adjust ACCEL_TO_DECEL";
|
||||
}
|
||||
} else
|
||||
} else if (FLAVOR_IS(gcfKlipper) && this->config.accel_to_decel_enable) {
|
||||
gcode << "SET_VELOCITY_LIMIT ACCEL_TO_DECEL=" << acceleration * this->config.accel_to_decel_factor / 100;
|
||||
if (GCodeWriter::full_gcode_comment) gcode << " ; adjust ACCEL_TO_DECEL";
|
||||
gcode << "\nM204 S" << acceleration;
|
||||
// Set max accel to decel to half of acceleration
|
||||
} else {
|
||||
// M204: Set default acceleration
|
||||
gcode << "M204 S" << acceleration;
|
||||
|
||||
}
|
||||
//BBS
|
||||
if (GCodeWriter::full_gcode_comment) gcode << " ; adjust acceleration";
|
||||
gcode << "\n";
|
||||
|
@ -193,55 +189,45 @@ std::string GCodeWriter::set_acceleration(unsigned int acceleration)
|
|||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string GCodeWriter::set_pressure_advance(double pa) const
|
||||
{
|
||||
std::ostringstream gcode;
|
||||
if (pa < 0) return gcode.str();
|
||||
if (false) { // todo: bbl printer
|
||||
// OrcaSlicer: set L1000 to use linear model
|
||||
gcode << "M900 K" << std::setprecision(4) << pa << " L1000 M10 ; Override pressure advance value\n";
|
||||
} else {
|
||||
if (this->config.gcode_flavor == gcfKlipper)
|
||||
gcode << "SET_PRESSURE_ADVANCE ADVANCE=" << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else if (this->config.gcode_flavor == gcfRepRapFirmware)
|
||||
gcode << ("M572 D0 S") << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else
|
||||
gcode << "M900 K" << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
}
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
{
|
||||
// Clamp the jerk to the allowed maximum.
|
||||
if (m_max_jerk > 0 && jerk > m_max_jerk)
|
||||
jerk = m_max_jerk;
|
||||
if (m_max_jerk > 0 && jerk > m_max_jerk) jerk = m_max_jerk;
|
||||
|
||||
if (jerk < 0.01 || is_approx(jerk, m_last_jerk)) return std::string();
|
||||
|
||||
if (jerk < 0.01 || is_approx(jerk, m_last_jerk))
|
||||
return std::string();
|
||||
|
||||
m_last_jerk = jerk;
|
||||
|
||||
|
||||
std::ostringstream gcode;
|
||||
if(FLAVOR_IS(gcfKlipper))
|
||||
if (FLAVOR_IS(gcfKlipper))
|
||||
gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
|
||||
else
|
||||
gcode << "M205 X" << jerk << " Y" << jerk;
|
||||
|
||||
if (m_is_bbl_printers)
|
||||
gcode << std::setprecision(2) << " Z" << m_max_jerk_z << " E" << m_max_jerk_e;
|
||||
|
||||
if (GCodeWriter::full_gcode_comment) gcode << " ; adjust jerk";
|
||||
gcode << "\n";
|
||||
|
||||
return gcode.str();
|
||||
|
||||
}
|
||||
|
||||
std::string GCodeWriter::set_pressure_advance(double pa) const
|
||||
{
|
||||
std::ostringstream gcode;
|
||||
if (pa < 0)
|
||||
return gcode.str();
|
||||
if(m_is_bbl_printers){
|
||||
//SoftFever: set L1000 to use linear model
|
||||
gcode << "M900 K" <<std::setprecision(4)<< pa << " L1000 M10 ; Override pressure advance value\n";
|
||||
}
|
||||
else{
|
||||
if (FLAVOR_IS(gcfKlipper))
|
||||
gcode << "SET_PRESSURE_ADVANCE ADVANCE=" << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else if(FLAVOR_IS(gcfRepRapFirmware))
|
||||
gcode << ("M572 D0 S") << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else
|
||||
gcode << "M900 K" <<std::setprecision(4)<< pa << "; Override pressure advance value\n";
|
||||
}
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string GCodeWriter::reset_e(bool force)
|
||||
{
|
||||
if (FLAVOR_IS(gcfMach3)
|
||||
|
@ -255,7 +241,7 @@ std::string GCodeWriter::reset_e(bool force)
|
|||
m_extruder->reset_E();
|
||||
}
|
||||
|
||||
if (! this->config.use_relative_e_distances) {
|
||||
if (!this->config.use_relative_e_distances) {
|
||||
std::ostringstream gcode;
|
||||
gcode << "G92 E0";
|
||||
//BBS
|
||||
|
@ -310,12 +296,11 @@ std::string GCodeWriter::toolchange(unsigned int extruder_id)
|
|||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string GCodeWriter::set_speed(double F, const std::string &comment, const std::string &cooling_marker)
|
||||
std::string GCodeWriter::set_speed(double F, const std::string &comment, const std::string &cooling_marker) const
|
||||
{
|
||||
assert(F > 0.);
|
||||
assert(F < 100000.);
|
||||
|
||||
m_current_speed = F;
|
||||
|
||||
GCodeG1Formatter w;
|
||||
w.emit_f(F);
|
||||
//BBS
|
||||
|
@ -335,9 +320,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
|
|||
|
||||
GCodeG1Formatter w;
|
||||
w.emit_xy(point_on_plate);
|
||||
auto speed = m_is_first_layer
|
||||
? this->config.get_abs_value("initial_layer_travel_speed") : this->config.travel_speed.value;
|
||||
w.emit_f(speed * 60.0);
|
||||
w.emit_f(this->config.travel_speed.value * 60.0);
|
||||
//BBS
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
return w.string();
|
||||
|
@ -356,8 +339,6 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
|||
used for unlift. */
|
||||
// BBS
|
||||
Vec3d dest_point = point;
|
||||
auto travel_speed =
|
||||
m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed") : this->config.travel_speed.value;
|
||||
//BBS: a z_hop need to be handle when travel
|
||||
if (std::abs(m_to_lift) > EPSILON) {
|
||||
assert(std::abs(m_lifted) < EPSILON);
|
||||
|
@ -399,9 +380,9 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
|||
Vec3d slope_top_point = Vec3d(temp(0), temp(1), delta(2)) + source;
|
||||
GCodeG1Formatter w0;
|
||||
w0.emit_xyz(slope_top_point);
|
||||
w0.emit_f(travel_speed * 60.0);
|
||||
w0.emit_f(this->config.travel_speed.value * 60.0);
|
||||
//BBS
|
||||
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
w0.emit_comment(GCodeWriter::full_gcode_comment, "slope lift Z");
|
||||
slop_move = w0.string();
|
||||
}
|
||||
else if (m_to_lift_type == LiftType::NormalLift) {
|
||||
|
@ -414,13 +395,13 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
|||
GCodeG1Formatter w0;
|
||||
if (this->is_current_position_clear()) {
|
||||
w0.emit_xyz(target);
|
||||
w0.emit_f(travel_speed * 60.0);
|
||||
w0.emit_f(this->config.travel_speed.value * 60.0);
|
||||
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
xy_z_move = w0.string();
|
||||
}
|
||||
else {
|
||||
w0.emit_xy(Vec2d(target.x(), target.y()));
|
||||
w0.emit_f(travel_speed * 60.0);
|
||||
w0.emit_f(this->config.travel_speed.value * 60.0);
|
||||
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
xy_z_move = w0.string() + _travel_to_z(target.z(), comment);
|
||||
}
|
||||
|
@ -494,10 +475,8 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
|
|||
m_pos(2) = z;
|
||||
|
||||
double speed = this->config.travel_speed_z.value;
|
||||
if (speed == 0.) {
|
||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||
: this->config.travel_speed.value;
|
||||
}
|
||||
if (speed == 0.)
|
||||
speed = this->config.travel_speed.value;
|
||||
|
||||
GCodeG1Formatter w;
|
||||
w.emit_z(z);
|
||||
|
@ -512,10 +491,8 @@ std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, c
|
|||
m_pos(2) = z;
|
||||
|
||||
double speed = this->config.travel_speed_z.value;
|
||||
if (speed == 0.) {
|
||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||
: this->config.travel_speed.value;
|
||||
}
|
||||
if (speed == 0.)
|
||||
speed = this->config.travel_speed.value;
|
||||
|
||||
std::string output = "G17\n";
|
||||
GCodeG2G3Formatter w(true);
|
||||
|
@ -548,9 +525,6 @@ std::string GCodeWriter::extrude_to_xy(const Vec2d &point, double dE, const std:
|
|||
{
|
||||
m_pos(0) = point(0);
|
||||
m_pos(1) = point(1);
|
||||
if(std::abs(dE) <= std::numeric_limits<double>::epsilon())
|
||||
force_no_extrusion = true;
|
||||
|
||||
if (!force_no_extrusion)
|
||||
m_extruder->extrude(dE);
|
||||
|
||||
|
@ -631,26 +605,15 @@ std::string GCodeWriter::retract_for_toolchange(bool before_wipe)
|
|||
|
||||
std::string GCodeWriter::_retract(double length, double restart_extra, const std::string &comment)
|
||||
{
|
||||
/* If firmware retraction is enabled, we use a fake value of 1
|
||||
since we ignore the actual configured retract_length which
|
||||
might be 0, in which case the retraction logic gets skipped. */
|
||||
if (this->config.use_firmware_retraction)
|
||||
length = 1;
|
||||
|
||||
std::string gcode;
|
||||
if (double dE = m_extruder->retract(length, restart_extra); dE != 0) {
|
||||
if (this->config.use_firmware_retraction) {
|
||||
gcode = FLAVOR_IS(gcfMachinekit) ? "G22 ; retract\n" : "G10 ; retract\n";
|
||||
}
|
||||
else {
|
||||
// BBS
|
||||
GCodeG1Formatter w;
|
||||
w.emit_e(m_extruder->E());
|
||||
w.emit_f(m_extruder->retract_speed() * 60.);
|
||||
// BBS
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
gcode = w.string();
|
||||
}
|
||||
//BBS
|
||||
GCodeG1Formatter w;
|
||||
w.emit_e(m_extruder->E());
|
||||
w.emit_f(m_extruder->retract_speed() * 60.);
|
||||
//BBS
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
gcode = w.string();
|
||||
}
|
||||
|
||||
if (FLAVOR_IS(gcfMakerWare))
|
||||
|
@ -667,20 +630,14 @@ std::string GCodeWriter::unretract()
|
|||
gcode = "M101 ; extruder on\n";
|
||||
|
||||
if (double dE = m_extruder->unretract(); dE != 0) {
|
||||
if (this->config.use_firmware_retraction) {
|
||||
gcode += FLAVOR_IS(gcfMachinekit) ? "G23 ; unretract\n" : "G11 ; unretract\n";
|
||||
gcode += this->reset_e();
|
||||
}
|
||||
else {
|
||||
//BBS
|
||||
// use G1 instead of G0 because G0 will blend the restart with the previous travel move
|
||||
GCodeG1Formatter w;
|
||||
w.emit_e(m_extruder->E());
|
||||
w.emit_f(m_extruder->deretract_speed() * 60.);
|
||||
//BBS
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, " ; unretract");
|
||||
gcode += w.string();
|
||||
}
|
||||
//BBS
|
||||
// use G1 instead of G0 because G0 will blend the restart with the previous travel move
|
||||
GCodeG1Formatter w;
|
||||
w.emit_e(m_extruder->E());
|
||||
w.emit_f(m_extruder->deretract_speed() * 60.);
|
||||
//BBS
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, " ; unretract");
|
||||
gcode += w.string();
|
||||
}
|
||||
|
||||
return gcode;
|
||||
|
@ -694,10 +651,8 @@ std::string GCodeWriter::lift(LiftType lift_type, bool spiral_vase)
|
|||
// check whether the above/below conditions are met
|
||||
double target_lift = 0;
|
||||
{
|
||||
double above = this->config.retract_lift_above.get_at(m_extruder->id());
|
||||
double below = this->config.retract_lift_below.get_at(m_extruder->id());
|
||||
if (m_pos(2) >= above && (below == 0 || m_pos(2) <= below))
|
||||
target_lift = this->config.z_hop.get_at(m_extruder->id());
|
||||
//BBS
|
||||
target_lift = this->config.z_hop.get_at(m_extruder->id());
|
||||
}
|
||||
// BBS
|
||||
if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) {
|
||||
|
@ -747,9 +702,9 @@ std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int sp
|
|||
gcode << "M126"; break;
|
||||
case gcfMach3:
|
||||
case gcfMachinekit:
|
||||
gcode << "M106 P" << static_cast<unsigned int>(255.5 * speed / 100.0); break;
|
||||
gcode << "M106 P" << 255.0 * speed / 100.0; break;
|
||||
default:
|
||||
gcode << "M106 S" << static_cast<unsigned int>(255.5 * speed / 100.0); break;
|
||||
gcode << "M106 S" << 255.0 * speed / 100.0; break;
|
||||
}
|
||||
if (GCodeWriter::full_gcode_comment)
|
||||
gcode << " ; enable fan";
|
||||
|
@ -793,11 +748,6 @@ void GCodeWriter::add_object_end_labels(std::string& gcode)
|
|||
if (!m_gcode_label_objects_end.empty()) {
|
||||
gcode += m_gcode_label_objects_end;
|
||||
m_gcode_label_objects_end = "";
|
||||
|
||||
// Orca: reset E so that e value remain correct after skipping the object
|
||||
// ref to: https://github.com/SoftFever/OrcaSlicer/pull/205/commits/7f1fe0bd544077626080aa1a9a0576aa735da1a4#r1083470162
|
||||
if (!this->config.use_relative_e_distances)
|
||||
gcode += reset_e(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
enum class LiftType {
|
||||
NormalLift,
|
||||
LazyLift,
|
||||
SpiralLift
|
||||
};
|
||||
|
||||
class GCodeWriter {
|
||||
public:
|
||||
GCodeConfig config;
|
||||
|
@ -24,8 +30,7 @@ public:
|
|||
/*m_last_bed_temperature(0), */m_last_bed_temperature_reached(true),
|
||||
m_lifted(0),
|
||||
m_to_lift(0),
|
||||
m_to_lift_type(LiftType::NormalLift),
|
||||
m_current_speed(3600), m_is_first_layer(true)
|
||||
m_to_lift_type(LiftType::NormalLift)
|
||||
{}
|
||||
Extruder* extruder() { return m_extruder; }
|
||||
const Extruder* extruder() const { return m_extruder; }
|
||||
|
@ -46,8 +51,8 @@ public:
|
|||
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1) const;
|
||||
std::string set_bed_temperature(int temperature, bool wait = false);
|
||||
std::string set_acceleration(unsigned int acceleration);
|
||||
std::string set_jerk_xy(double jerk);
|
||||
std::string set_pressure_advance(double pa) const;
|
||||
std::string set_jerk_xy(double 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
|
||||
|
@ -59,9 +64,7 @@ public:
|
|||
// printed with the same extruder.
|
||||
std::string toolchange_prefix() const;
|
||||
std::string toolchange(unsigned int extruder_id);
|
||||
std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string());
|
||||
// SoftFever NOTE: the returned speed is mm/minute
|
||||
double get_current_speed() const { return m_current_speed;}
|
||||
std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string()) const;
|
||||
std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string());
|
||||
std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string());
|
||||
std::string travel_to_z(double z, const std::string &comment = std::string());
|
||||
|
@ -90,26 +93,22 @@ public:
|
|||
static std::string set_additional_fan(unsigned int speed);
|
||||
//BBS
|
||||
void set_object_start_str(std::string start_string) { m_gcode_label_objects_start = start_string; }
|
||||
bool is_object_start_str_empty() { return m_gcode_label_objects_start.empty(); }
|
||||
bool empty_object_start_str() { return m_gcode_label_objects_start.empty(); }
|
||||
void set_object_end_str(std::string end_string) { m_gcode_label_objects_end = end_string; }
|
||||
bool is_object_end_str_empty() { return m_gcode_label_objects_end.empty(); }
|
||||
void add_object_start_labels(std::string &gcode);
|
||||
void add_object_end_labels(std::string &gcode);
|
||||
bool empty_object_end_str() { return m_gcode_label_objects_end.empty(); }
|
||||
void add_object_start_labels(std::string& gcode);
|
||||
void add_object_end_labels(std::string& gcode);
|
||||
void add_object_change_labels(std::string& gcode);
|
||||
|
||||
//BBS:
|
||||
void set_current_position_clear(bool clear) { m_is_current_pos_clear = clear; };
|
||||
bool is_current_position_clear() const { return m_is_current_pos_clear; };
|
||||
//BBS:
|
||||
static bool full_gcode_comment;
|
||||
static const bool full_gcode_comment;
|
||||
//Radian threshold of slope for lazy lift and spiral lift;
|
||||
static const double slope_threshold;
|
||||
//SoftFever
|
||||
void set_is_bbl_machine(bool bval) {m_is_bbl_printers = bval;}
|
||||
const bool is_bbl_printers() const {return m_is_bbl_printers;}
|
||||
void set_is_first_layer(bool bval) { m_is_first_layer = bval; }
|
||||
|
||||
private:
|
||||
private:
|
||||
// Extruders are sorted by their ID, so that binary search is possible.
|
||||
std::vector<Extruder> m_extruders;
|
||||
bool m_single_extruder_multi_material;
|
||||
|
@ -118,15 +117,8 @@ public:
|
|||
// 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;
|
||||
double m_max_jerk;
|
||||
double m_last_jerk;
|
||||
double m_max_jerk_z;
|
||||
double m_max_jerk_e;
|
||||
|
||||
unsigned int m_travel_acceleration;
|
||||
unsigned int m_travel_jerk;
|
||||
|
||||
|
||||
double m_max_jerk;
|
||||
//BBS
|
||||
unsigned int m_last_additional_fan_speed;
|
||||
int m_last_bed_temperature;
|
||||
|
@ -144,15 +136,10 @@ public:
|
|||
//BBS: x, y offset for gcode generated
|
||||
double m_x_offset{ 0 };
|
||||
double m_y_offset{ 0 };
|
||||
|
||||
|
||||
std::string m_gcode_label_objects_start;
|
||||
std::string m_gcode_label_objects_end;
|
||||
|
||||
//SoftFever
|
||||
bool m_is_bbl_printers = false;
|
||||
double m_current_speed;
|
||||
bool m_is_first_layer = true;
|
||||
|
||||
std::string _travel_to_z(double z, const std::string &comment);
|
||||
std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment);
|
||||
std::string _retract(double length, double restart_extra, const std::string &comment);
|
||||
|
@ -184,13 +171,6 @@ public:
|
|||
// static constexpr const int XYZF_EXPORT_DIGITS = 6;
|
||||
// static constexpr const int E_EXPORT_DIGITS = 9;
|
||||
#endif
|
||||
static constexpr const std::array<double, 10> pow_10 { 1., 10., 100., 1000., 10000., 100000., 1000000., 10000000., 100000000., 1000000000. };
|
||||
static constexpr const std::array<double, 10> pow_10_inv { 1. / 1., 1. / 10., 1. / 100., 1. / 1000., 1. / 10000., 1. / 100000., 1. / 1000000., 1. / 10000000., 1. / 100000000., 1. / 1000000000. };
|
||||
|
||||
// Quantize doubles to a resolution of the G-code.
|
||||
static double quantize(double v, size_t ndigits) { return std::round(v * pow_10[ndigits]) * pow_10_inv[ndigits]; }
|
||||
static double quantize_xyzf(double v) { return quantize(v, XYZF_EXPORT_DIGITS); }
|
||||
static double quantize_e(double v) { return quantize(v, E_EXPORT_DIGITS); }
|
||||
|
||||
void emit_axis(const char axis, const double v, size_t digits);
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#ifdef SLIC3R_CURRENTLY_COMPILING_GUI_MODULE
|
||||
#ifndef SLIC3R_ALLOW_LIBSLIC3R_I18N_IN_SLIC3R
|
||||
#error You included libslic3r/I18N.hpp into a file belonging to slic3r module.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace I18N {
|
||||
|
@ -15,4 +21,17 @@ namespace I18N {
|
|||
|
||||
} // namespace Slic3r
|
||||
|
||||
// When this is included from slic3r, better do not define the translation functions.
|
||||
// Macros from slic3r/GUI/I18N.hpp should be used there.
|
||||
#ifndef SLIC3R_CURRENTLY_COMPILING_GUI_MODULE
|
||||
#ifdef L
|
||||
#error L macro is defined where it shouldn't be. Didn't you include slic3r/GUI/I18N.hpp in libslic3r by mistake?
|
||||
#endif
|
||||
namespace {
|
||||
[[maybe_unused]] const char* L(const char* s) { return s; }
|
||||
[[maybe_unused]] const char* L_CONTEXT(const char* s, const char* context) { return s; }
|
||||
[[maybe_unused]] std::string _u8L(const char* s) { return Slic3r::I18N::translate(s); }
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* slic3r_I18N_hpp_ */
|
||||
|
|
|
@ -174,6 +174,7 @@ void Layer::make_perimeters()
|
|||
&& config.gap_infill_speed.value == other_config.gap_infill_speed.value
|
||||
&& config.filter_out_gap_fill.value == other_config.filter_out_gap_fill.value
|
||||
&& config.detect_overhang_wall == other_config.detect_overhang_wall
|
||||
&& config.filter_out_gap_fill.value == other_config.filter_out_gap_fill.value
|
||||
&& config.opt_serialize("inner_wall_line_width") == other_config.opt_serialize("inner_wall_line_width")
|
||||
&& config.opt_serialize("outer_wall_line_width") == other_config.opt_serialize("outer_wall_line_width")
|
||||
&& config.detect_thin_wall == other_config.detect_thin_wall
|
||||
|
|
|
@ -71,12 +71,9 @@ Model& Model::assign_copy(const Model &rhs)
|
|||
// BBS
|
||||
this->plates_custom_gcodes = rhs.plates_custom_gcodes;
|
||||
this->curr_plate_index = rhs.curr_plate_index;
|
||||
this->calib_pa_pattern.reset();
|
||||
|
||||
if (rhs.calib_pa_pattern) {
|
||||
this->calib_pa_pattern = std::make_unique<CalibPressureAdvancePattern>(
|
||||
CalibPressureAdvancePattern(*rhs.calib_pa_pattern)
|
||||
);
|
||||
this->calib_pa_pattern = std::make_unique<CalibPressureAdvancePattern>(CalibPressureAdvancePattern(*rhs.calib_pa_pattern));
|
||||
}
|
||||
|
||||
// BBS: for design info
|
||||
|
@ -107,8 +104,7 @@ Model& Model::assign_copy(Model &&rhs)
|
|||
// BBS
|
||||
this->plates_custom_gcodes = std::move(rhs.plates_custom_gcodes);
|
||||
this->curr_plate_index = rhs.curr_plate_index;
|
||||
this->calib_pa_pattern.reset();
|
||||
this->calib_pa_pattern.swap(rhs.calib_pa_pattern);
|
||||
this->calib_pa_pattern = std::move(rhs.calib_pa_pattern);
|
||||
|
||||
//BBS: add auxiliary path logic
|
||||
// BBS: backup, all in one temp dir
|
||||
|
@ -814,7 +810,7 @@ std::string Model::get_backup_path()
|
|||
std::time_t t = std::time(0);
|
||||
std::tm* now_time = std::localtime(&t);
|
||||
std::stringstream buf;
|
||||
buf << "/orcaslicer_model/";
|
||||
buf << "/bamboo_model/";
|
||||
buf << std::put_time(now_time, "%a_%b_%d/%H_%M_%S#");
|
||||
buf << pid << "#";
|
||||
buf << this->id().id;
|
||||
|
@ -1382,11 +1378,19 @@ const BoundingBoxf3& ModelObject::raw_bounding_box() const
|
|||
}
|
||||
|
||||
// This returns an accurate snug bounding box of the transformed object instance, without the translation applied.
|
||||
BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_translate) const {
|
||||
return instance_bounding_box(*this->instances[instance_idx], dont_translate);
|
||||
BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_translate) const
|
||||
{
|
||||
BoundingBoxf3 bb;
|
||||
const Transform3d& inst_matrix = this->instances[instance_idx]->get_transformation().get_matrix(dont_translate);
|
||||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
if (v->is_model_part())
|
||||
bb.merge(v->mesh().transformed_bounding_box(inst_matrix * v->get_matrix()));
|
||||
}
|
||||
return bb;
|
||||
}
|
||||
|
||||
BoundingBoxf3 ModelObject::instance_bounding_box(const ModelInstance &instance, bool dont_translate) const {
|
||||
BoundingBoxf3 ModelObject::instance_bounding_box(const ModelInstance& instance, bool dont_translate) const {
|
||||
BoundingBoxf3 bbox;
|
||||
const auto& inst_mat = instance.get_transformation().get_matrix(dont_translate);
|
||||
for (auto vol : this->volumes) {
|
||||
|
@ -1396,7 +1400,6 @@ BoundingBoxf3 ModelObject::instance_bounding_box(const ModelInstance &instance,
|
|||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
//BBS: add convex bounding box
|
||||
BoundingBoxf3 ModelObject::instance_convex_hull_bounding_box(size_t instance_idx, bool dont_translate) const
|
||||
{
|
||||
|
@ -2458,6 +2461,7 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
|||
assert(instance_idx < this->instances.size());
|
||||
|
||||
const Geometry::Transformation reference_trafo = this->instances[instance_idx]->get_transformation();
|
||||
|
||||
if (Geometry::is_rotation_ninety_degrees(reference_trafo.get_rotation()))
|
||||
// nothing to do, scaling in the world coordinate space is possible in the representation of Geometry::Transformation.
|
||||
return;
|
||||
|
@ -3246,7 +3250,6 @@ double Model::findMaxSpeed(const ModelObject* object) {
|
|||
double solidInfillSpeedObj = Model::printSpeedMap.solidInfillSpeed;
|
||||
double topSolidInfillSpeedObj = Model::printSpeedMap.topSolidInfillSpeed;
|
||||
double supportSpeedObj = Model::printSpeedMap.supportSpeed;
|
||||
double smallPerimeterSpeedObj = Model::printSpeedMap.smallPerimeterSpeed;
|
||||
for (std::string objectKey : objectKeys) {
|
||||
if (objectKey == "inner_wall_speed"){
|
||||
perimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
|
@ -3262,10 +3265,8 @@ double Model::findMaxSpeed(const ModelObject* object) {
|
|||
supportSpeedObj = object->config.opt_float(objectKey);
|
||||
if (objectKey == "outer_wall_speed")
|
||||
externalPerimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
if (objectKey == "small_perimeter_speed")
|
||||
smallPerimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
}
|
||||
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, objMaxSpeed)))))));
|
||||
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, objMaxSpeed))))));
|
||||
if (objMaxSpeed <= 0) objMaxSpeed = 250.;
|
||||
return objMaxSpeed;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
//BBS: add stl
|
||||
#include "Format/STL.hpp"
|
||||
|
||||
#include "Calib.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "PerimeterGenerator.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "ExtrusionEntity.hpp"
|
||||
#include "ExtrusionEntityCollection.hpp"
|
||||
#include "ShortestPath.hpp"
|
||||
#include "VariableWidth.hpp"
|
||||
|
@ -276,7 +275,7 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
|
|||
Polylines remain_polines;
|
||||
|
||||
//BBS: don't calculate overhang degree when enable fuzzy skin. It's unmeaning
|
||||
if (perimeter_generator.config->overhang_speed_classic && perimeter_generator.config->enable_overhang_speed && perimeter_generator.config->fuzzy_skin == FuzzySkinType::None) {
|
||||
if (perimeter_generator.config->enable_overhang_speed && perimeter_generator.config->fuzzy_skin == FuzzySkinType::None) {
|
||||
for (auto it = lower_polygons_series->begin();
|
||||
it != lower_polygons_series->end(); it++)
|
||||
{
|
||||
|
@ -323,12 +322,31 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
|
|||
// outside the grown lower slices (thus where the distance between
|
||||
// the loop centerline and original lower slices is >= half nozzle diameter
|
||||
if (remain_polines.size() != 0) {
|
||||
extrusion_paths_append(paths, std::move(remain_polines), overhang_sampling_number - 1, int(0),
|
||||
erOverhangPerimeter, perimeter_generator.mm3_per_mm_overhang(),
|
||||
perimeter_generator.overhang_flow.width(),
|
||||
perimeter_generator.overhang_flow.height());
|
||||
}
|
||||
if (!((perimeter_generator.object_config->enable_support || perimeter_generator.object_config->enforce_support_layers > 0)
|
||||
&& perimeter_generator.object_config->support_top_z_distance.value == 0)) {
|
||||
extrusion_paths_append(
|
||||
paths,
|
||||
std::move(remain_polines),
|
||||
overhang_sampling_number - 1,
|
||||
int(0),
|
||||
erOverhangPerimeter,
|
||||
perimeter_generator.mm3_per_mm_overhang(),
|
||||
perimeter_generator.overhang_flow.width(),
|
||||
perimeter_generator.overhang_flow.height());
|
||||
} else {
|
||||
extrusion_paths_append(
|
||||
paths,
|
||||
std::move(remain_polines),
|
||||
overhang_sampling_number - 1,
|
||||
int(0),
|
||||
role,
|
||||
extrusion_mm3_per_mm,
|
||||
extrusion_width,
|
||||
(float)perimeter_generator.layer_height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Reapply the nearest point search for starting point.
|
||||
// We allow polyline reversal because Clipper may have randomly reversed polylines during clipping.
|
||||
chain_and_reorder_extrusion_paths(paths, &paths.front().first_point());
|
||||
|
@ -395,22 +413,38 @@ static ClipperLib_Z::Paths clip_extrusion(const ClipperLib_Z::Path& subject, con
|
|||
ClipperLib_Z::Clipper clipper;
|
||||
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint& e1bot, const ClipperLib_Z::IntPoint& e1top, const ClipperLib_Z::IntPoint& e2bot,
|
||||
const ClipperLib_Z::IntPoint& e2top, ClipperLib_Z::IntPoint& pt) {
|
||||
// The clipping contour may be simplified by clipping it with a bounding box of "subject" path.
|
||||
// The clipping function used may produce self intersections outside of the "subject" bounding box. Such self intersections are
|
||||
// harmless to the result of the clipping operation,
|
||||
// Both ends of each edge belong to the same source: Either they are from subject or from clipping path.
|
||||
assert(e1bot.z() >= 0 && e1top.z() >= 0);
|
||||
assert(e2bot.z() >= 0 && e2top.z() >= 0);
|
||||
assert((e1bot.z() == 0) == (e1top.z() == 0));
|
||||
assert((e2bot.z() == 0) == (e2top.z() == 0));
|
||||
|
||||
// Start & end points of the clipped polyline (extrusion path with a non-zero width).
|
||||
ClipperLib_Z::IntPoint start = e1bot;
|
||||
ClipperLib_Z::IntPoint end = e1top;
|
||||
|
||||
if (start.z() <= 0 && end.z() <= 0) {
|
||||
start = e2bot;
|
||||
end = e2top;
|
||||
}
|
||||
|
||||
assert(start.z() > 0 && end.z() > 0);
|
||||
if (start.z() <= 0 && end.z() <= 0) {
|
||||
// Self intersection on the source contour.
|
||||
assert(start.z() == 0 && end.z() == 0);
|
||||
pt.z() = 0;
|
||||
}
|
||||
else {
|
||||
// Interpolate extrusion line width.
|
||||
assert(start.z() > 0 && end.z() > 0);
|
||||
|
||||
// Interpolate extrusion line width.
|
||||
double length_sqr = (end - start).cast<double>().squaredNorm();
|
||||
double dist_sqr = (pt - start).cast<double>().squaredNorm();
|
||||
double t = std::sqrt(dist_sqr / length_sqr);
|
||||
double length_sqr = (end - start).cast<double>().squaredNorm();
|
||||
double dist_sqr = (pt - start).cast<double>().squaredNorm();
|
||||
double t = std::sqrt(dist_sqr / length_sqr);
|
||||
|
||||
pt.z() = start.z() + coord_t((end.z() - start.z()) * t);
|
||||
pt.z() = start.z() + coord_t((end.z() - start.z()) * t);
|
||||
}
|
||||
});
|
||||
|
||||
clipper.AddPath(subject, ClipperLib_Z::ptSubject, false);
|
||||
|
@ -577,7 +611,9 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
|
|||
|
||||
ExtrusionPaths paths;
|
||||
// detect overhanging/bridging perimeters
|
||||
if (perimeter_generator.config->detect_overhang_wall && perimeter_generator.layer_id > perimeter_generator.object_config->raft_layers) {
|
||||
if (perimeter_generator.config->detect_overhang_wall && perimeter_generator.layer_id > perimeter_generator.object_config->raft_layers
|
||||
&& !((perimeter_generator.object_config->enable_support || perimeter_generator.object_config->enforce_support_layers > 0) &&
|
||||
perimeter_generator.object_config->support_top_z_distance.value == 0)) {
|
||||
ClipperLib_Z::Path extrusion_path;
|
||||
extrusion_path.reserve(extrusion->size());
|
||||
BoundingBox extrusion_path_bbox;
|
||||
|
@ -609,7 +645,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
|
|||
extrusion_paths_append(temp_paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctIntersection), role,
|
||||
is_external ? perimeter_generator.ext_perimeter_flow : perimeter_generator.perimeter_flow);
|
||||
|
||||
if (perimeter_generator.config->overhang_speed_classic && perimeter_generator.config->enable_overhang_speed && perimeter_generator.config->fuzzy_skin == FuzzySkinType::None) {
|
||||
if (perimeter_generator.config->enable_overhang_speed && perimeter_generator.config->fuzzy_skin == FuzzySkinType::None) {
|
||||
|
||||
Flow flow = is_external ? perimeter_generator.ext_perimeter_flow : perimeter_generator.perimeter_flow;
|
||||
std::map<double, std::vector<Polygons>> clipper_serise;
|
||||
|
@ -759,100 +795,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
|
|||
return extrusion_coll;
|
||||
}
|
||||
|
||||
void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExPolygons &top_fills,
|
||||
ExPolygons &non_top_polygons, ExPolygons &fill_clip) const {
|
||||
// other perimeters
|
||||
coord_t perimeter_width = this->perimeter_flow.scaled_width();
|
||||
coord_t perimeter_spacing = this->perimeter_flow.scaled_spacing();
|
||||
|
||||
// external perimeters
|
||||
coord_t ext_perimeter_width = this->ext_perimeter_flow.scaled_width();
|
||||
coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
|
||||
|
||||
bool has_gap_fill = this->config->gap_infill_speed.value > 0;
|
||||
|
||||
// split the polygons with top/not_top
|
||||
// get the offset from solid surface anchor
|
||||
coord_t offset_top_surface =
|
||||
scale_(1.5 * (config->wall_loops.value == 0
|
||||
? 0.
|
||||
: unscaled(double(ext_perimeter_width +
|
||||
perimeter_spacing * int(int(config->wall_loops.value) - int(1))))));
|
||||
// if possible, try to not push the extra perimeters inside the sparse infill
|
||||
if (offset_top_surface >
|
||||
0.9 * (config->wall_loops.value <= 1 ? 0. : (perimeter_spacing * (config->wall_loops.value - 1))))
|
||||
offset_top_surface -=
|
||||
coord_t(0.9 * (config->wall_loops.value <= 1 ? 0. : (perimeter_spacing * (config->wall_loops.value - 1))));
|
||||
else
|
||||
offset_top_surface = 0;
|
||||
// don't takes into account too thin areas
|
||||
// skip if the exposed area is smaller than "min_width_top_surface"
|
||||
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), config->min_width_top_surface.get_abs_value(perimeter_width));
|
||||
|
||||
Polygons grown_upper_slices = offset(*this->upper_slices, min_width_top_surface);
|
||||
|
||||
// get boungding box of last
|
||||
BoundingBox last_box = get_extents(orig_polygons);
|
||||
last_box.offset(SCALED_EPSILON);
|
||||
|
||||
// get the Polygons upper the polygon this layer
|
||||
Polygons upper_polygons_series_clipped =
|
||||
ClipperUtils::clip_clipper_polygons_with_subject_bbox(grown_upper_slices, last_box);
|
||||
|
||||
// set the clip to a virtual "second perimeter"
|
||||
fill_clip = offset_ex(orig_polygons, -double(ext_perimeter_spacing));
|
||||
// get the real top surface
|
||||
ExPolygons grown_lower_slices;
|
||||
ExPolygons bridge_checker;
|
||||
auto nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->wall_filament - 1);
|
||||
// Check whether surface be bridge or not
|
||||
if (this->lower_slices != NULL) {
|
||||
// BBS: get the Polygons below the polygon this layer
|
||||
Polygons lower_polygons_series_clipped =
|
||||
ClipperUtils::clip_clipper_polygons_with_subject_bbox(*this->lower_slices, last_box);
|
||||
double bridge_offset = std::max(double(ext_perimeter_spacing), (double(perimeter_width)));
|
||||
// SoftFever: improve bridging
|
||||
const float bridge_margin =
|
||||
std::min(float(scale_(BRIDGE_INFILL_MARGIN)), float(scale_(nozzle_diameter * BRIDGE_INFILL_MARGIN / 0.4)));
|
||||
bridge_checker = offset_ex(diff_ex(orig_polygons, lower_polygons_series_clipped, ApplySafetyOffset::Yes),
|
||||
1.5 * bridge_offset + bridge_margin + perimeter_spacing / 2);
|
||||
}
|
||||
ExPolygons delete_bridge = diff_ex(orig_polygons, bridge_checker, ApplySafetyOffset::Yes);
|
||||
|
||||
ExPolygons top_polygons = diff_ex(delete_bridge, upper_polygons_series_clipped, ApplySafetyOffset::Yes);
|
||||
// get the not-top surface, from the "real top" but enlarged by external_infill_margin (and the
|
||||
// min_width_top_surface we removed a bit before)
|
||||
ExPolygons temp_gap = diff_ex(top_polygons, fill_clip);
|
||||
ExPolygons inner_polygons =
|
||||
diff_ex(orig_polygons,
|
||||
offset_ex(top_polygons, offset_top_surface + min_width_top_surface - double(ext_perimeter_spacing / 2)),
|
||||
ApplySafetyOffset::Yes);
|
||||
// get the enlarged top surface, by using inner_polygons instead of upper_slices, and clip it for it to be exactly
|
||||
// the polygons to fill.
|
||||
top_polygons = diff_ex(fill_clip, inner_polygons, ApplySafetyOffset::Yes);
|
||||
// increase by half peri the inner space to fill the frontier between last and stored.
|
||||
top_fills = union_ex(top_fills, top_polygons);
|
||||
//set the clip to the external wall but go back inside by infill_extrusion_width/2 to be sure the extrusion won't go outside even with a 100% overlap.
|
||||
double infill_spacing_unscaled = this->config->sparse_infill_line_width.get_abs_value(nozzle_diameter);
|
||||
if (infill_spacing_unscaled == 0) infill_spacing_unscaled = Flow::auto_extrusion_width(frInfill, nozzle_diameter);
|
||||
fill_clip = offset_ex(orig_polygons, double(ext_perimeter_spacing / 2) - scale_(infill_spacing_unscaled / 2));
|
||||
// ExPolygons oldLast = last;
|
||||
|
||||
non_top_polygons = intersection_ex(inner_polygons, orig_polygons);
|
||||
if (has_gap_fill)
|
||||
non_top_polygons = union_ex(non_top_polygons, temp_gap);
|
||||
//{
|
||||
// std::stringstream stri;
|
||||
// stri << this->layer_id << "_1_"<< i <<"_only_one_peri"<< ".svg";
|
||||
// SVG svg(stri.str());
|
||||
// svg.draw(to_polylines(top_fills), "green");
|
||||
// svg.draw(to_polylines(inner_polygons), "yellow");
|
||||
// svg.draw(to_polylines(top_polygons), "cyan");
|
||||
// svg.draw(to_polylines(oldLast), "orange");
|
||||
// svg.draw(to_polylines(last), "red");
|
||||
// svg.Close();
|
||||
//}
|
||||
}
|
||||
|
||||
void PerimeterGenerator::process_classic()
|
||||
{
|
||||
|
@ -860,17 +803,12 @@ void PerimeterGenerator::process_classic()
|
|||
m_mm3_per_mm = this->perimeter_flow.mm3_per_mm();
|
||||
coord_t perimeter_width = this->perimeter_flow.scaled_width();
|
||||
coord_t perimeter_spacing = this->perimeter_flow.scaled_spacing();
|
||||
|
||||
|
||||
// external perimeters
|
||||
m_ext_mm3_per_mm = this->ext_perimeter_flow.mm3_per_mm();
|
||||
coord_t ext_perimeter_width = this->ext_perimeter_flow.scaled_width();
|
||||
|
||||
coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
|
||||
coord_t ext_perimeter_spacing2;
|
||||
if(config->precise_outer_wall)
|
||||
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.width() + this->perimeter_flow.width()));
|
||||
else
|
||||
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
|
||||
coord_t ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
|
||||
|
||||
// overhang perimeters
|
||||
m_mm3_per_mm_overhang = this->overhang_flow.mm3_per_mm();
|
||||
|
@ -913,13 +851,17 @@ void PerimeterGenerator::process_classic()
|
|||
|
||||
// BBS: don't simplify too much which influence arc fitting when export gcode if arc_fitting is enabled
|
||||
double surface_simplify_resolution = (print_config->enable_arc_fitting && this->config->fuzzy_skin == FuzzySkinType::None) ? 0.2 * m_scaled_resolution : m_scaled_resolution;
|
||||
for (const Surface &surface : this->slices->surfaces) {
|
||||
//BBS: reorder the surface to reduce the travel time
|
||||
ExPolygons surface_exp;
|
||||
for (const Surface &surface : this->slices->surfaces)
|
||||
surface_exp.push_back(surface.expolygon);
|
||||
std::vector<size_t> surface_order = chain_expolygons(surface_exp);
|
||||
for (size_t order_idx = 0; order_idx < surface_order.size(); order_idx++) {
|
||||
const Surface &surface = this->slices->surfaces[surface_order[order_idx]];
|
||||
// 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)
|
||||
//BBS: set the topmost and bottom most layer to be one wall
|
||||
if (loop_number > 0 && ((this->object_config->top_one_wall_type != TopOneWallType::None && this->upper_slices == nullptr) || (this->object_config->only_one_wall_first_layer && layer_id == 0)))
|
||||
loop_number = 0;
|
||||
|
||||
ExPolygons last = union_ex(surface.expolygon.simplify_p(surface_simplify_resolution));
|
||||
|
@ -1066,8 +1008,68 @@ void PerimeterGenerator::process_classic()
|
|||
|
||||
//BBS: refer to superslicer
|
||||
//store surface for top infill if only_one_wall_top
|
||||
if (i == 0 && i!=loop_number && config->only_one_wall_top && this->upper_slices != NULL) {
|
||||
this->split_top_surfaces(last, top_fills, last, fill_clip);
|
||||
if (i == 0 && i != loop_number && this->object_config->top_one_wall_type == TopOneWallType::Alltop && this->upper_slices != NULL) {
|
||||
//split the polygons with top/not_top
|
||||
//get the offset from solid surface anchor
|
||||
coord_t offset_top_surface = scale_(1.5 * (config->wall_loops.value == 0 ? 0. : unscaled(double(ext_perimeter_width + perimeter_spacing * int(int(config->wall_loops.value) - int(1))))));
|
||||
// if possible, try to not push the extra perimeters inside the sparse infill
|
||||
if (offset_top_surface > 0.9 * (config->wall_loops.value <= 1 ? 0. : (perimeter_spacing * (config->wall_loops.value - 1))))
|
||||
offset_top_surface -= coord_t(0.9 * (config->wall_loops.value <= 1 ? 0. : (perimeter_spacing * (config->wall_loops.value - 1))));
|
||||
else
|
||||
offset_top_surface = 0;
|
||||
//don't takes into account too thin areas
|
||||
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), 1.0 * (double(perimeter_width)));
|
||||
|
||||
//BBS: get boungding box of last
|
||||
BoundingBox last_box = get_extents(last);
|
||||
last_box.offset(SCALED_EPSILON);
|
||||
|
||||
// BBS: get the Polygons upper the polygon this layer
|
||||
Polygons upper_polygons_series_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*this->upper_slices, last_box);
|
||||
upper_polygons_series_clipped = offset(upper_polygons_series_clipped, min_width_top_surface);
|
||||
|
||||
//set the clip to a virtual "second perimeter"
|
||||
fill_clip = offset_ex(last, -double(ext_perimeter_spacing));
|
||||
// get the real top surface
|
||||
ExPolygons grown_lower_slices;
|
||||
ExPolygons bridge_checker;
|
||||
// BBS: check whether surface be bridge or not
|
||||
if (this->lower_slices != NULL) {
|
||||
// BBS: get the Polygons below the polygon this layer
|
||||
Polygons lower_polygons_series_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*this->lower_slices, last_box);
|
||||
|
||||
double bridge_offset = std::max(double(ext_perimeter_spacing), (double(perimeter_width)));
|
||||
bridge_checker = offset_ex(diff_ex(last, lower_polygons_series_clipped, ApplySafetyOffset::Yes), 1.5 * bridge_offset);
|
||||
}
|
||||
ExPolygons delete_bridge = diff_ex(last, bridge_checker, ApplySafetyOffset::Yes);
|
||||
|
||||
ExPolygons top_polygons = diff_ex(delete_bridge, upper_polygons_series_clipped, ApplySafetyOffset::Yes);
|
||||
//get the not-top surface, from the "real top" but enlarged by external_infill_margin (and the min_width_top_surface we removed a bit before)
|
||||
ExPolygons temp_gap = diff_ex(top_polygons, fill_clip);
|
||||
ExPolygons inner_polygons = diff_ex(last,
|
||||
offset_ex(top_polygons, offset_top_surface + min_width_top_surface - double(ext_perimeter_spacing / 2)),
|
||||
ApplySafetyOffset::Yes);
|
||||
// get the enlarged top surface, by using inner_polygons instead of upper_slices, and clip it for it to be exactly the polygons to fill.
|
||||
top_polygons = diff_ex(fill_clip, inner_polygons, ApplySafetyOffset::Yes);
|
||||
// increase by half peri the inner space to fill the frontier between last and stored.
|
||||
top_fills = union_ex(top_fills, top_polygons);
|
||||
//set the clip to the external wall but go back inside by infill_extrusion_width/2 to be sure the extrusion won't go outside even with a 100% overlap.
|
||||
double infill_spacing_unscaled = this->config->sparse_infill_line_width.value;
|
||||
fill_clip = offset_ex(last, double(ext_perimeter_spacing / 2) - scale_(infill_spacing_unscaled / 2));
|
||||
last = intersection_ex(inner_polygons, last);
|
||||
if (has_gap_fill)
|
||||
last = union_ex(last,temp_gap);
|
||||
//{
|
||||
// std::stringstream stri;
|
||||
// stri << this->layer->id() << "_1_"<< i <<"_only_one_peri"<< ".svg";
|
||||
// SVG svg(stri.str());
|
||||
// svg.draw(to_polylines(top_fills), "green");
|
||||
// svg.draw(to_polylines(inner_polygons), "yellow");
|
||||
// svg.draw(to_polylines(top_polygons), "cyan");
|
||||
// svg.draw(to_polylines(oldLast), "orange");
|
||||
// svg.draw(to_polylines(last), "red");
|
||||
// svg.Close();
|
||||
//}
|
||||
}
|
||||
|
||||
if (i == loop_number && (! has_gap_fill || this->config->sparse_infill_density.value == 0)) {
|
||||
|
@ -1133,21 +1135,20 @@ void PerimeterGenerator::process_classic()
|
|||
}
|
||||
// at this point, all loops should be in contours[0]
|
||||
ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls);
|
||||
|
||||
// if brim will be printed, reverse the order of perimeters so that
|
||||
// we continue inwards after having finished the brim
|
||||
// TODO: add test for perimeter order
|
||||
bool is_outer_wall_first =
|
||||
this->config->wall_infill_order == WallInfillOrder::OuterInnerInfill ||
|
||||
this->config->wall_infill_order == WallInfillOrder::InfillOuterInner;
|
||||
bool is_outer_wall_first =
|
||||
this->print_config->wall_infill_order == WallInfillOrder::OuterInnerInfill ||
|
||||
this->print_config->wall_infill_order == WallInfillOrder::InfillOuterInner;
|
||||
if (is_outer_wall_first ||
|
||||
//BBS: always print outer wall first when there indeed has brim.
|
||||
(this->layer_id == 0 &&
|
||||
this->object_config->brim_type == BrimType::btOuterOnly &&
|
||||
this->object_config->brim_width.value > 0))
|
||||
this->object_config->brim_type == BrimType::btOuterOnly &&
|
||||
this->object_config->brim_width.value > 0))
|
||||
entities.reverse();
|
||||
// SoftFever: sandwich mode
|
||||
else if (this->config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill)
|
||||
//BBS. adjust wall generate seq
|
||||
else if (this->print_config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill)
|
||||
if (entities.entities.size() > 1){
|
||||
int last_outer=0;
|
||||
int outer = 0;
|
||||
|
@ -1160,7 +1161,6 @@ void PerimeterGenerator::process_classic()
|
|||
// append perimeters for this slice as a collection
|
||||
if (! entities.empty())
|
||||
this->loops->append(entities);
|
||||
|
||||
} // for each loop of an island
|
||||
|
||||
// fill gaps
|
||||
|
@ -1194,12 +1194,10 @@ void PerimeterGenerator::process_classic()
|
|||
++ irun;
|
||||
}
|
||||
#endif
|
||||
// SoftFever: filter out tiny gap fills
|
||||
polylines.erase(std::remove_if(polylines.begin(), polylines.end(),
|
||||
[&](const ThickPolyline& p) {
|
||||
return p.length() < scale_(config->filter_out_gap_fill.value);
|
||||
}), polylines.end());
|
||||
|
||||
// OrcaSlicer: filter out tiny gap fills
|
||||
polylines.erase(std::remove_if(polylines.begin(), polylines.end(), [&](const ThickPolyline &p) {
|
||||
return p.length()< scale_(this->config->filter_out_gap_fill.value);
|
||||
}), polylines.end());
|
||||
|
||||
if (! polylines.empty()) {
|
||||
ExtrusionEntityCollection gap_fill;
|
||||
|
@ -1213,8 +1211,7 @@ void PerimeterGenerator::process_classic()
|
|||
//FIXME Vojtech: This grows by a rounded extrusion width, not by line spacing,
|
||||
// therefore it may cover the area, but no the volume.
|
||||
last = diff_ex(last, gap_fill.polygons_covered_by_width(10.f));
|
||||
this->gap_fill->append(std::move(gap_fill.entities));
|
||||
|
||||
this->gap_fill->append(std::move(gap_fill.entities));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1275,6 +1272,39 @@ void PerimeterGenerator::process_classic()
|
|||
} // for each island
|
||||
}
|
||||
|
||||
//BBS:
|
||||
void PerimeterGenerator::add_infill_contour_for_arachne( ExPolygons infill_contour,
|
||||
int loops,
|
||||
coord_t ext_perimeter_spacing,
|
||||
coord_t perimeter_spacing,
|
||||
coord_t min_perimeter_infill_spacing,
|
||||
coord_t spacing,
|
||||
bool is_inner_part)
|
||||
{
|
||||
if( offset_ex(infill_contour, -float(spacing / 2.)).empty() )
|
||||
{
|
||||
infill_contour.clear(); // Infill region is too small, so let's filter it out.
|
||||
}
|
||||
|
||||
// create one more offset to be used as boundary for fill
|
||||
// we offset by half the perimeter spacing (to get to the actual infill boundary)
|
||||
// and then we offset back and forth by half the infill spacing to only consider the
|
||||
// non-collapsing regions
|
||||
coord_t insert = (loops < 0) ? 0: ext_perimeter_spacing;
|
||||
if (is_inner_part || loops > 0)
|
||||
insert = perimeter_spacing;
|
||||
|
||||
insert = coord_t(scale_(this->config->infill_wall_overlap.get_abs_value(unscale<double>(insert))));
|
||||
|
||||
Polygons inner_pp;
|
||||
for (ExPolygon &ex : infill_contour)
|
||||
ex.simplify_p(m_scaled_resolution, &inner_pp);
|
||||
|
||||
this->fill_surfaces->append(offset2_ex(union_ex(inner_pp), float(-min_perimeter_infill_spacing / 2.), float(insert + min_perimeter_infill_spacing / 2.)), stInternal);
|
||||
|
||||
append(*this->fill_no_overlap, offset2_ex(union_ex(inner_pp), float(-min_perimeter_infill_spacing / 2.), float(+min_perimeter_infill_spacing / 2.)));
|
||||
}
|
||||
|
||||
// Thanks, Cura developers, for implementing an algorithm for generating perimeters with variable width (Arachne) that is based on the paper
|
||||
// "A framework for adaptive width control of dense contour-parallel toolpaths in fused deposition modeling"
|
||||
void PerimeterGenerator::process_arachne()
|
||||
|
@ -1288,6 +1318,7 @@ void PerimeterGenerator::process_arachne()
|
|||
coord_t ext_perimeter_width = this->ext_perimeter_flow.scaled_width();
|
||||
coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
|
||||
coord_t ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
|
||||
|
||||
// overhang perimeters
|
||||
m_mm3_per_mm_overhang = this->overhang_flow.mm3_per_mm();
|
||||
|
||||
|
@ -1309,20 +1340,15 @@ void PerimeterGenerator::process_arachne()
|
|||
// we need to process each island separately because we might have different
|
||||
// extra perimeters for each one
|
||||
for (const Surface& surface : this->slices->surfaces) {
|
||||
coord_t bead_width_0 = ext_perimeter_spacing;
|
||||
if (config->precise_outer_wall)
|
||||
bead_width_0 = ext_perimeter_width + this->perimeter_flow.scaled_width() - perimeter_spacing;
|
||||
// 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)
|
||||
int loop_number = this->config->wall_loops + surface.extra_perimeters - 1; // 0-indexed loops
|
||||
if (loop_number > 0 && this->object_config->only_one_wall_first_layer && layer_id == 0 ||
|
||||
(this->object_config->top_one_wall_type == TopOneWallType::Topmost && this->upper_slices == nullptr))
|
||||
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;
|
||||
ExPolygons last = offset_ex(surface.expolygon.simplify_p(surface_simplify_resolution),
|
||||
config->precise_outer_wall ? -float(ext_perimeter_width / 2. - bead_width_0 / 2.)
|
||||
: -float(ext_perimeter_width / 2. - ext_perimeter_spacing / 2.));
|
||||
|
||||
|
||||
ExPolygons last = offset_ex(surface.expolygon.simplify_p(surface_simplify_resolution), -float(ext_perimeter_width / 2. - ext_perimeter_spacing / 2.));
|
||||
Polygons last_p = to_polygons(last);
|
||||
|
||||
double min_nozzle_diameter = *std::min_element(print_config->nozzle_diameter.values.begin(), print_config->nozzle_diameter.values.end());
|
||||
Arachne::WallToolPathsParams input_params;
|
||||
{
|
||||
|
@ -1341,67 +1367,76 @@ void PerimeterGenerator::process_arachne()
|
|||
input_params.wall_transition_angle = this->object_config->wall_transition_angle.value;
|
||||
input_params.wall_distribution_count = this->object_config->wall_distribution_count.value;
|
||||
}
|
||||
coord_t wall_0_inset = 0;
|
||||
//if (config->precise_outer_wall)
|
||||
// wall_0_inset = 0.5 * (ext_perimeter_width + this->perimeter_flow.scaled_width() - ext_perimeter_spacing -
|
||||
// perimeter_spacing);
|
||||
|
||||
std::vector<Arachne::VariableWidthLines> out_shell;
|
||||
ExPolygons top_fills;
|
||||
ExPolygons fill_clip;
|
||||
if (loop_number > 0 && config->only_one_wall_top && this->upper_slices != nullptr) {
|
||||
// Check if current layer has surfaces that are not covered by upper layer (i.e., top surfaces)
|
||||
ExPolygons non_top_polygons;
|
||||
this->split_top_surfaces(last, top_fills, non_top_polygons, fill_clip);
|
||||
int remain_loops = -1;
|
||||
if (this->object_config->top_one_wall_type == TopOneWallType::Alltop) {
|
||||
if (this->upper_slices != nullptr)
|
||||
remain_loops = loop_number - 1;
|
||||
|
||||
if (top_fills.empty()) {
|
||||
// No top surfaces, no special handling needed
|
||||
} else {
|
||||
// First we slice the outer shell
|
||||
Polygons last_p = to_polygons(last);
|
||||
Arachne::WallToolPaths wallToolPaths(last_p, bead_width_0, perimeter_spacing, coord_t(1),
|
||||
wall_0_inset, layer_height, input_params);
|
||||
out_shell = wallToolPaths.getToolPaths();
|
||||
// Make sure infill not overlap with wall
|
||||
top_fills = intersection_ex(top_fills, wallToolPaths.getInnerContour());
|
||||
|
||||
if (!top_fills.empty()) {
|
||||
// Then get the inner part that needs more walls
|
||||
last = intersection_ex(non_top_polygons, wallToolPaths.getInnerContour());
|
||||
loop_number--;
|
||||
} else {
|
||||
// Give up the outer shell because we don't have any meaningful top surface
|
||||
out_shell.clear();
|
||||
}
|
||||
}
|
||||
loop_number = 0;
|
||||
}
|
||||
|
||||
Polygons last_p = to_polygons(last);
|
||||
|
||||
Arachne::WallToolPaths wallToolPaths(last_p, bead_width_0, perimeter_spacing, coord_t(loop_number + 1),
|
||||
wall_0_inset, layer_height, input_params);
|
||||
|
||||
Arachne::WallToolPaths wallToolPaths(last_p, ext_perimeter_spacing, perimeter_spacing, coord_t(loop_number + 1), 0, layer_height, input_params);
|
||||
std::vector<Arachne::VariableWidthLines> perimeters = wallToolPaths.getToolPaths();
|
||||
loop_number = int(perimeters.size()) - 1;
|
||||
|
||||
if (!out_shell.empty()) {
|
||||
// Combine outer shells
|
||||
size_t inset_offset = 0;
|
||||
for (auto &p : out_shell) {
|
||||
for (auto &l : p) {
|
||||
if (l.inset_idx + 1 > inset_offset) {
|
||||
inset_offset = l.inset_idx + 1;
|
||||
//BBS: top one wall for arachne
|
||||
ExPolygons infill_contour = union_ex(wallToolPaths.getInnerContour());
|
||||
ExPolygons inner_infill_contour;
|
||||
|
||||
if( remain_loops >= 0 )
|
||||
{
|
||||
ExPolygons the_layer_surface = infill_contour;
|
||||
// BBS: get boungding box of last
|
||||
BoundingBox infill_contour_box = get_extents(infill_contour);
|
||||
infill_contour_box.offset(SCALED_EPSILON);
|
||||
|
||||
// BBS: get the Polygons upper the polygon this layer
|
||||
Polygons upper_polygons_series_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*this->upper_slices, infill_contour_box);
|
||||
|
||||
infill_contour = diff_ex(infill_contour, upper_polygons_series_clipped);
|
||||
|
||||
coord_t perimeter_width = this->perimeter_flow.scaled_width();
|
||||
//BBS: add bridge area
|
||||
if (this->lower_slices != nullptr) {
|
||||
BoundingBox infill_contour_box = get_extents(infill_contour);
|
||||
infill_contour_box.offset(SCALED_EPSILON);
|
||||
// BBS: get the Polygons below the polygon this layer
|
||||
Polygons lower_polygons_series_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*this->lower_slices, infill_contour_box);
|
||||
|
||||
ExPolygons bridge_area = offset_ex(diff_ex(infill_contour, lower_polygons_series_clipped), std::max(ext_perimeter_spacing, perimeter_width));
|
||||
infill_contour = diff_ex(infill_contour, bridge_area);
|
||||
}
|
||||
//BBS: filter small area and extend top surface a bit to hide the wall line
|
||||
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 4 + 10), double(perimeter_width / 4));
|
||||
infill_contour = offset2_ex(infill_contour, -min_width_top_surface, min_width_top_surface + perimeter_width);
|
||||
|
||||
//BBS: get the inner surface that not export to top
|
||||
ExPolygons surface_not_export_to_top = diff_ex(the_layer_surface, infill_contour);
|
||||
|
||||
//BBS: get real top surface
|
||||
infill_contour = intersection_ex(infill_contour, the_layer_surface);
|
||||
Polygons surface_not_export_to_top_p = to_polygons(surface_not_export_to_top);
|
||||
Arachne::WallToolPaths innerWallToolPaths(surface_not_export_to_top_p, ext_perimeter_spacing, perimeter_spacing, coord_t(remain_loops + 1), 0, layer_height, input_params);
|
||||
|
||||
std::vector<Arachne::VariableWidthLines> perimeters_inner = innerWallToolPaths.getToolPaths();
|
||||
remain_loops = int(perimeters_inner.size()) - 1;
|
||||
|
||||
//BBS: set wall's perporsity
|
||||
if (!perimeters.empty()) {
|
||||
for (int perimeter_idx = 0; perimeter_idx < perimeters_inner.size(); perimeter_idx++) {
|
||||
if (perimeters_inner[perimeter_idx].empty()) continue;
|
||||
|
||||
for (Arachne::ExtrusionLine &wall : perimeters_inner[perimeter_idx]) {
|
||||
// BBS: 0 means outer wall
|
||||
wall.inset_idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto &p : perimeters) {
|
||||
for (auto &l : p) {
|
||||
l.inset_idx += inset_offset;
|
||||
}
|
||||
}
|
||||
perimeters.insert(perimeters.end(), perimeters_inner.begin(), perimeters_inner.end());
|
||||
|
||||
perimeters.insert(perimeters.begin(), out_shell.begin(), out_shell.end());
|
||||
inner_infill_contour = union_ex(innerWallToolPaths.getInnerContour());
|
||||
}
|
||||
loop_number = int(perimeters.size()) - 1;
|
||||
|
||||
#ifdef ARACHNE_DEBUG
|
||||
{
|
||||
|
@ -1426,9 +1461,8 @@ void PerimeterGenerator::process_arachne()
|
|||
int direction = -1;
|
||||
|
||||
bool is_outer_wall_first =
|
||||
this->config->wall_infill_order == WallInfillOrder::OuterInnerInfill ||
|
||||
this->config->wall_infill_order == WallInfillOrder::InfillOuterInner ||
|
||||
this->config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill;
|
||||
this->print_config->wall_infill_order == WallInfillOrder::OuterInnerInfill ||
|
||||
this->print_config->wall_infill_order == WallInfillOrder::InfillOuterInner;
|
||||
if (is_outer_wall_first) {
|
||||
start_perimeter = 0;
|
||||
end_perimeter = int(perimeters.size());
|
||||
|
@ -1554,102 +1588,32 @@ void PerimeterGenerator::process_arachne()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this->config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill) {
|
||||
if (ordered_extrusions.size() > 2) { // 3 walls minimum needed to do inner outer inner ordering
|
||||
int position = 0; // index to run the re-ordering for multiple external perimeters in a single island.
|
||||
int arr_i = 0; // index to run through the walls
|
||||
int outer, first_internal, second_internal; // allocate index values
|
||||
// run the re-ordering for all wall loops in the same island
|
||||
while (position < ordered_extrusions.size()) {
|
||||
outer = first_internal = second_internal = -1; // initialise all index values to -1
|
||||
// run through the walls to get the index values that need re-ordering until the first one for each
|
||||
// is found. Start at "position" index to enable the for loop to iterate for multiple external
|
||||
// perimeters in a single island
|
||||
for (arr_i = position; arr_i < ordered_extrusions.size(); ++arr_i) {
|
||||
switch (ordered_extrusions[arr_i].extrusion->inset_idx) {
|
||||
case 0: // external perimeter
|
||||
if (outer == -1)
|
||||
outer = arr_i;
|
||||
break;
|
||||
case 1: // first internal wall
|
||||
if (first_internal == -1 && arr_i > outer)
|
||||
first_internal = arr_i;
|
||||
break;
|
||||
case 2: // second internal wall
|
||||
if (ordered_extrusions[arr_i].extrusion->inset_idx == 2 && second_internal == -1 &&
|
||||
arr_i > first_internal)
|
||||
second_internal = arr_i;
|
||||
break;
|
||||
}
|
||||
if (second_internal != -1)
|
||||
break; // found all three perimeters to re-order
|
||||
// BBS. adjust wall generate seq
|
||||
if (this->print_config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill)
|
||||
if (ordered_extrusions.size() > 1) {
|
||||
int last_outer = 0;
|
||||
int outer = 0;
|
||||
for (; outer < ordered_extrusions.size(); ++outer)
|
||||
if (ordered_extrusions[outer].extrusion->inset_idx == 0 && outer - last_outer > 1) {
|
||||
std::swap(ordered_extrusions[outer], ordered_extrusions[outer - 1]);
|
||||
last_outer = outer;
|
||||
}
|
||||
if (outer > -1 && first_internal > -1 && second_internal > -1) { // found perimeters to re-order?
|
||||
const auto temp = ordered_extrusions[second_internal];
|
||||
ordered_extrusions[second_internal] = ordered_extrusions[first_internal];
|
||||
ordered_extrusions[first_internal] = ordered_extrusions[outer];
|
||||
ordered_extrusions[outer] = temp;
|
||||
} else
|
||||
break; // did not find any more candidates to re-order, so stop the while loop early
|
||||
// go to the next perimeter to continue scanning for external walls in the same island
|
||||
position = arr_i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(*this, ordered_extrusions); !extrusion_coll.empty())
|
||||
this->loops->append(extrusion_coll);
|
||||
|
||||
ExPolygons infill_contour = union_ex(wallToolPaths.getInnerContour());
|
||||
const coord_t spacing = (perimeters.size() == 1) ? ext_perimeter_spacing2 : perimeter_spacing;
|
||||
if (offset_ex(infill_contour, -float(spacing / 2.)).empty())
|
||||
infill_contour.clear(); // Infill region is too small, so let's filter it out.
|
||||
|
||||
// create one more offset to be used as boundary for fill
|
||||
// we offset by half the perimeter spacing (to get to the actual infill boundary)
|
||||
// and then we offset back and forth by half the infill spacing to only consider the
|
||||
// non-collapsing regions
|
||||
coord_t inset =
|
||||
(loop_number < 0) ? 0 :
|
||||
(loop_number == 0) ?
|
||||
// one loop
|
||||
ext_perimeter_spacing :
|
||||
// two or more loops?
|
||||
perimeter_spacing;
|
||||
|
||||
inset = coord_t(scale_(this->config->infill_wall_overlap.get_abs_value(unscale<double>(inset))));
|
||||
// simplify infill contours according to resolution
|
||||
Polygons pp;
|
||||
for (ExPolygon& ex : infill_contour)
|
||||
ex.simplify_p(m_scaled_resolution, &pp);
|
||||
ExPolygons not_filled_exp = union_ex(pp);
|
||||
// collapse too narrow infill areas
|
||||
const auto min_perimeter_infill_spacing = coord_t(solid_infill_spacing * (1. - INSET_OVERLAP_TOLERANCE));
|
||||
|
||||
ExPolygons infill_exp = offset2_ex(
|
||||
not_filled_exp,
|
||||
float(-min_perimeter_infill_spacing / 2.),
|
||||
float(inset + min_perimeter_infill_spacing / 2.));
|
||||
// append infill areas to fill_surfaces
|
||||
if (!top_fills.empty()) {
|
||||
infill_exp = union_ex(infill_exp, offset_ex(top_fills, double(inset)));
|
||||
}
|
||||
this->fill_surfaces->append(infill_exp, stInternal);
|
||||
add_infill_contour_for_arachne(infill_contour, loop_number, ext_perimeter_spacing, perimeter_spacing, min_perimeter_infill_spacing, spacing, false);
|
||||
|
||||
//BBS: add infill_contour of top one wall part
|
||||
if( !inner_infill_contour.empty() )
|
||||
add_infill_contour_for_arachne(inner_infill_contour, remain_loops, ext_perimeter_spacing, perimeter_spacing, min_perimeter_infill_spacing, spacing, true);
|
||||
|
||||
// BBS: get the no-overlap infill expolygons
|
||||
{
|
||||
ExPolygons polyWithoutOverlap;
|
||||
polyWithoutOverlap = offset2_ex(
|
||||
not_filled_exp,
|
||||
float(-min_perimeter_infill_spacing / 2.),
|
||||
float(+min_perimeter_infill_spacing / 2.));
|
||||
if (!top_fills.empty())
|
||||
polyWithoutOverlap = union_ex(polyWithoutOverlap, top_fills);
|
||||
this->fill_no_overlap->insert(this->fill_no_overlap->end(), polyWithoutOverlap.begin(), polyWithoutOverlap.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1680,7 +1644,6 @@ std::map<int, Polygons> PerimeterGenerator::generate_lower_polygons_series(float
|
|||
// BBS: increase start_offset a little to avoid to calculate 90 degree as overhang
|
||||
offset_series[0] = start_offset + 0.5 * (end_offset - start_offset) / (overhang_sampling_number - 1);
|
||||
offset_series[overhang_sampling_number - 2] = end_offset;
|
||||
offset_series.back() = 0.1 * nozzle_diameter;
|
||||
|
||||
std::map<int, Polygons> lower_polygons_series;
|
||||
if (this->lower_slices == NULL) {
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
void process_classic();
|
||||
void process_arachne();
|
||||
|
||||
void add_infill_contour_for_arachne( ExPolygons infill_contour, int loops, coord_t ext_perimeter_spacing, coord_t perimeter_spacing, coord_t min_perimeter_infill_spacing, coord_t spacing, bool is_inner_part );
|
||||
|
||||
double ext_mm3_per_mm() const { return m_ext_mm3_per_mm; }
|
||||
double mm3_per_mm() const { return m_mm3_per_mm; }
|
||||
double mm3_per_mm_overhang() const { return m_mm3_per_mm_overhang; }
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <cassert>
|
||||
|
||||
#include "Config.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "Preset.hpp"
|
||||
#include "PresetBundle.hpp"
|
||||
|
@ -678,6 +677,25 @@ std::string Preset::get_current_printer_type(PresetBundle *preset_bundle)
|
|||
return "";
|
||||
}
|
||||
|
||||
bool Preset::has_lidar(PresetBundle *preset_bundle)
|
||||
{
|
||||
bool has_lidar = false;
|
||||
if (preset_bundle) {
|
||||
auto config = &preset_bundle->printers.get_edited_preset().config;
|
||||
std::string vendor_name;
|
||||
for (auto vendor_profile : preset_bundle->vendors) {
|
||||
for (auto vendor_model : vendor_profile.second.models)
|
||||
if (vendor_model.name == config->opt_string("printer_model")) {
|
||||
vendor_name = vendor_profile.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
has_lidar = vendor_name.compare("BBL") == 0 ? true : false;
|
||||
}
|
||||
return has_lidar;
|
||||
}
|
||||
|
||||
bool Preset::is_custom_defined()
|
||||
{
|
||||
if (custom_defined == "1")
|
||||
|
@ -685,9 +703,9 @@ bool Preset::is_custom_defined()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Preset::has_lidar(PresetBundle *preset_bundle)
|
||||
bool Preset::is_bbl_vendor_preset(PresetBundle *preset_bundle)
|
||||
{
|
||||
bool has_lidar = false;
|
||||
bool is_bbl_vendor_preset = true;
|
||||
if (preset_bundle) {
|
||||
auto config = &preset_bundle->printers.get_edited_preset().config;
|
||||
std::string vendor_name;
|
||||
|
@ -700,9 +718,9 @@ bool Preset::has_lidar(PresetBundle *preset_bundle)
|
|||
}
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
has_lidar = vendor_name.compare("BBL") == 0 ? true : false;
|
||||
is_bbl_vendor_preset = vendor_name.compare("BBL") == 0 ? true : false;
|
||||
}
|
||||
return has_lidar;
|
||||
return is_bbl_vendor_preset;
|
||||
}
|
||||
|
||||
BedType Preset::get_default_bed_type(PresetBundle* preset_bundle)
|
||||
|
@ -739,10 +757,10 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
"layer_height", "initial_layer_print_height", "wall_loops", "slice_closing_radius", "spiral_mode", "slicing_mode",
|
||||
"top_shell_layers", "top_shell_thickness", "bottom_shell_layers", "bottom_shell_thickness",
|
||||
"ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall",
|
||||
"seam_position", "staggered_inner_seams", "wall_infill_order", "sparse_infill_density", "sparse_infill_pattern", "top_surface_pattern", "bottom_surface_pattern",
|
||||
"infill_direction",
|
||||
"minimum_sparse_infill_area", "reduce_infill_retraction","internal_solid_infill_pattern",
|
||||
"ironing_type", "ironing_pattern", "ironing_flow", "ironing_speed", "ironing_spacing",
|
||||
"seam_position", "wall_infill_order", "sparse_infill_density", "sparse_infill_pattern", "sparse_infill_anchor", "sparse_infill_anchor_max",
|
||||
"top_surface_pattern", "bottom_surface_pattern", "internal_solid_infill_pattern", "infill_direction", "bridge_angle",
|
||||
"minimum_sparse_infill_area", "reduce_infill_retraction", "ironing_pattern", "ironing_type",
|
||||
"ironing_flow", "ironing_speed", "ironing_spacing",
|
||||
"max_travel_detour_distance",
|
||||
"fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance",
|
||||
#ifdef HAS_PRESSURE_EQUALIZER
|
||||
|
@ -750,15 +768,19 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
#endif /* HAS_PRESSURE_EQUALIZER */
|
||||
"inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed",
|
||||
"top_surface_speed", "support_speed", "support_object_xy_distance", "support_interface_speed",
|
||||
"bridge_speed", "internal_bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
|
||||
"outer_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "skirt_loops", "skirt_speed", "skirt_distance", "skirt_height", "draft_shield",
|
||||
"brim_width", "brim_object_gap", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "enforce_support_layers",
|
||||
"bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed", "outer_wall_acceleration",
|
||||
"initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "inner_wall_acceleration", "sparse_infill_acceleration",
|
||||
"accel_to_decel_enable", "accel_to_decel_factor", "skirt_loops", "skirt_distance",
|
||||
"skirt_height", "draft_shield",
|
||||
"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_expansion", "support_style",
|
||||
// BBS
|
||||
"independent_support_layer_height",
|
||||
"support_angle", "support_interface_top_layers", "support_interface_bottom_layers",
|
||||
"support_interface_pattern", "support_interface_spacing", "support_interface_loop_pattern",
|
||||
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "max_bridge_length", "print_sequence", "support_remove_small_overhang",
|
||||
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "support_remove_small_overhang",
|
||||
"bridge_no_support", "thick_bridges", "max_bridge_length", "print_sequence",
|
||||
"filename_format", "wall_filament", "support_bottom_z_distance",
|
||||
"sparse_infill_filament", "solid_infill_filament", "support_filament", "support_interface_filament",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "line_width", "initial_layer_line_width",
|
||||
|
@ -768,25 +790,23 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
"prime_tower_width", "prime_tower_brim_width", "prime_volume",
|
||||
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
"flush_into_infill", "flush_into_objects", "flush_into_support",
|
||||
// BBS
|
||||
"tree_support_branch_angle", "tree_support_wall_count", "tree_support_branch_distance",
|
||||
"tree_support_branch_diameter",
|
||||
"tree_support_branch_diameter","tree_support_brim_width",
|
||||
"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",
|
||||
"initial_layer_infill_speed", "top_one_wall_type", "only_one_wall_first_layer",
|
||||
"timelapse_type", "internal_bridge_support_thickness",
|
||||
"wall_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
|
||||
"wall_distribution_count", "min_feature_size", "min_bead_width", "post_process",
|
||||
"small_perimeter_speed", "small_perimeter_threshold","bridge_angle", "filter_out_gap_fill", "travel_acceleration","inner_wall_acceleration", "min_width_top_surface",
|
||||
"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk",
|
||||
"top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio","only_one_wall_first_layer", "print_flow_ratio", "seam_gap",
|
||||
"role_based_wipe_speed", "wipe_speed", "accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops",
|
||||
"bridge_density", "precise_outer_wall", "overhang_speed_classic", "bridge_acceleration",
|
||||
"sparse_infill_acceleration", "internal_solid_infill_acceleration", "tree_support_adaptive_layer_height", "tree_support_auto_brim",
|
||||
"tree_support_brim_width", "gcode_comments", "gcode_label_objects",
|
||||
"initial_layer_travel_speed", "exclude_object", "slow_down_layers", "infill_anchor", "infill_anchor_max",
|
||||
"make_overhang_printable", "make_overhang_printable_angle", "make_overhang_printable_hole_size"
|
||||
|
||||
"seam_gap", "wipe_speed", "top_solid_infill_flow_ratio", "initial_layer_flow_ratio",
|
||||
"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk", "travel_jerk",
|
||||
"filter_out_gap_fill",
|
||||
// calib
|
||||
"print_flow_ratio",
|
||||
//Orca
|
||||
"exclude_object"
|
||||
};
|
||||
|
||||
static std::vector<std::string> s_Preset_filament_options {
|
||||
|
@ -802,15 +822,15 @@ static std::vector<std::string> s_Preset_filament_options {
|
|||
"fan_max_speed", "enable_overhang_bridge_fan", "overhang_fan_speed", "overhang_fan_threshold", "close_fan_the_first_x_layers", "full_fan_speed_layer", "fan_cooling_layer_time", "slow_down_layer_time", "slow_down_min_speed",
|
||||
"filament_start_gcode", "filament_end_gcode",
|
||||
// Retract overrides
|
||||
"filament_retraction_length", "filament_z_hop", "filament_z_hop_types", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_lift_enforce", "filament_retraction_speed", "filament_deretraction_speed", "filament_retract_restart_extra", "filament_retraction_minimum_travel",
|
||||
"filament_retraction_length", "filament_z_hop", "filament_z_hop_types", "filament_retraction_speed", "filament_deretraction_speed", "filament_retract_restart_extra", "filament_retraction_minimum_travel",
|
||||
"filament_retract_when_changing_layer", "filament_wipe", "filament_retract_before_wipe",
|
||||
// Profile compatibility
|
||||
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
//BBS
|
||||
"filament_wipe_distance", "additional_cooling_fan_speed",
|
||||
"bed_temperature_difference", "nozzle_temperature_range_low", "nozzle_temperature_range_high",
|
||||
//SoftFever
|
||||
"enable_pressure_advance", "pressure_advance","chamber_temperature", "filament_shrink", "support_material_interface_fan_speed" /*,"filament_seam_gap"*/
|
||||
//OrcaSlicer
|
||||
"enable_pressure_advance", "pressure_advance", "chamber_temperatures"
|
||||
};
|
||||
|
||||
static std::vector<std::string> s_Preset_machine_limits_options {
|
||||
|
@ -824,20 +844,20 @@ static std::vector<std::string> s_Preset_machine_limits_options {
|
|||
static std::vector<std::string> s_Preset_printer_options {
|
||||
"printer_technology",
|
||||
"printable_area", "bed_exclude_area","bed_custom_texture", "bed_custom_model", "gcode_flavor",
|
||||
"fan_kickstart", "fan_speedup_time", "fan_speedup_overhangs",
|
||||
"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",
|
||||
"printer_model", "printer_variant", "printable_height", "extruder_clearance_radius", "extruder_clearance_max_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", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types", "retract_lift_enforce",
|
||||
//SoftFever
|
||||
"nozzle_type","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types",
|
||||
//OrcaSlicer
|
||||
"host_type", "print_host", "printhost_apikey",
|
||||
"print_host_webui",
|
||||
"printhost_cafile","printhost_port","printhost_authorization_type",
|
||||
"printhost_user", "printhost_password", "printhost_ssl_ignore_revoke", "thumbnails",
|
||||
"use_firmware_retraction", "use_relative_e_distances", "bbl_calib_mark_logo"};
|
||||
"printhost_user", "printhost_password", "printhost_ssl_ignore_revoke",
|
||||
"use_relative_e_distances", "extruder_type"
|
||||
};
|
||||
|
||||
static std::vector<std::string> s_Preset_sla_print_options {
|
||||
"layer_height",
|
||||
|
@ -1725,14 +1745,12 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
|||
{
|
||||
// Load the preset over a default preset, so that the missing fields are filled in from the default preset.
|
||||
DynamicPrintConfig cfg(this->default_preset_for(combined_config).config);
|
||||
// SoftFever: ignore print connection info from project
|
||||
auto keys = cfg.keys();
|
||||
keys.erase(std::remove_if(keys.begin(), keys.end(),
|
||||
[](std::string &val) {
|
||||
return val == "print_host" || val == "print_host_webui" || val == "printhost_apikey" ||
|
||||
val == "printhost_cafile";
|
||||
}),
|
||||
keys.end());
|
||||
// OrcaSlicer: ignore print connection info from project
|
||||
cfg.erase("print_host");
|
||||
cfg.erase("print_host_webui");
|
||||
cfg.erase("printhost_apikey");
|
||||
cfg.erase("printhost_cafile");
|
||||
const auto &keys = cfg.keys();
|
||||
cfg.apply_only(combined_config, keys, true);
|
||||
std::string &inherits = Preset::inherits(cfg);
|
||||
|
||||
|
@ -2345,7 +2363,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" || opt_key == "thumbnails") {
|
||||
if (opt_key == "printable_area" || opt_key == "bed_exclude_area" || opt_key == "compatible_prints" || opt_key == "compatible_printers") {
|
||||
// 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);
|
||||
|
@ -2667,7 +2685,6 @@ static std::vector<std::string> s_PhysicalPrinter_opts {
|
|||
"printer_technology",
|
||||
"host_type",
|
||||
"print_host",
|
||||
"print_host_webui",
|
||||
"printhost_apikey",
|
||||
"printhost_cafile",
|
||||
"printhost_port",
|
||||
|
@ -2839,8 +2856,6 @@ 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<PhysicalPrinter> printers_loaded;
|
||||
|
@ -3220,9 +3235,6 @@ namespace PresetUtils {
|
|||
if (!boost::filesystem::exists(boost::filesystem::path(out)))
|
||||
out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->hotend_model;
|
||||
}
|
||||
|
||||
if (out.empty() ||!boost::filesystem::exists(boost::filesystem::path(out)))
|
||||
out = Slic3r::resources_dir() + "/profiles/hotend.stl";
|
||||
return out;
|
||||
}
|
||||
} // namespace PresetUtils
|
||||
|
|
|
@ -300,9 +300,11 @@ public:
|
|||
std::string get_filament_type(std::string &display_filament_type);
|
||||
std::string get_printer_type(PresetBundle *preset_bundle); // get edited preset type
|
||||
std::string get_current_printer_type(PresetBundle *preset_bundle); // get current preset type
|
||||
bool is_custom_defined();
|
||||
|
||||
bool has_lidar(PresetBundle *preset_bundle);
|
||||
bool is_custom_defined();
|
||||
|
||||
bool is_bbl_vendor_preset(PresetBundle *preset_bundle);
|
||||
BedType get_default_bed_type(PresetBundle *preset_bundle);
|
||||
bool has_cali_lines(PresetBundle* preset_bundle);
|
||||
|
||||
|
|
|
@ -42,10 +42,10 @@ static std::vector<std::string> s_project_options {
|
|||
};
|
||||
|
||||
//BBS: add BBL as default
|
||||
const char *PresetBundle::BBL_BUNDLE = "Custom";
|
||||
const char *PresetBundle::BBL_DEFAULT_PRINTER_MODEL = "MyKlipper 0.4 nozzle";
|
||||
const char *PresetBundle::BBL_BUNDLE = "BBL";
|
||||
const char *PresetBundle::BBL_DEFAULT_PRINTER_MODEL = "Bambu Lab X1 Carbon";
|
||||
const char *PresetBundle::BBL_DEFAULT_PRINTER_VARIANT = "0.4";
|
||||
const char *PresetBundle::BBL_DEFAULT_FILAMENT = "My Generic PLA";
|
||||
const char *PresetBundle::BBL_DEFAULT_FILAMENT = "Generic PLA";
|
||||
|
||||
PresetBundle::PresetBundle()
|
||||
: prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const PrintRegionConfig &>(FullPrintConfig::defaults()))
|
||||
|
@ -88,7 +88,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", "thumbnails"}) preset.config.optptr(key, true);
|
||||
for (const char *key : {"printer_settings_id", "printer_model", "printer_variant"}) preset.config.optptr(key, true);
|
||||
//if (i == 0) {
|
||||
preset.config.optptr("default_print_profile", true);
|
||||
preset.config.option<ConfigOptionStrings>("default_filament_profile", true);
|
||||
|
@ -512,9 +512,6 @@ std::string PresetBundle::get_hotend_model_for_printer_model(std::string model_n
|
|||
out = Slic3r::resources_dir() + "/profiles/" + vendor_name + "/" + hotend_stl;
|
||||
}
|
||||
|
||||
if (out.empty() ||!boost::filesystem::exists(boost::filesystem::path(out)))
|
||||
out = Slic3r::resources_dir() + "/profiles/hotend.stl";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -919,7 +916,7 @@ void PresetBundle::remove_users_preset(AppConfig &config, std::map<std::string,
|
|||
bool need_reset_print_preset = false;
|
||||
// remove preset if user_id is not current user
|
||||
for (auto it = prints.begin(); it != prints.end();) {
|
||||
if (it->is_user() && !it->user_id.empty() && it->user_id.compare(preset_folder_user_id) == 0 && check_removed(*it)) {
|
||||
if (it->is_user() && it->user_id.compare(preset_folder_user_id) == 0 && check_removed(*it)) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":prints erase %1%, type %2%, user_id %3%")%it->name %Preset::get_type_string(it->type) %it->user_id;
|
||||
if (it->name == selected_print_name)
|
||||
need_reset_print_preset = true;
|
||||
|
@ -939,7 +936,7 @@ void PresetBundle::remove_users_preset(AppConfig &config, std::map<std::string,
|
|||
std::string selected_filament_name = filaments.get_selected_preset().name;
|
||||
bool need_reset_filament_preset = false;
|
||||
for (auto it = filaments.begin(); it != filaments.end();) {
|
||||
if (it->is_user() && !it->user_id.empty() && it->user_id.compare(preset_folder_user_id) == 0 && check_removed(*it)) {
|
||||
if (it->is_user() && it->user_id.compare(preset_folder_user_id) == 0 && check_removed(*it)) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":filaments erase %1%, type %2%, user_id %3%")%it->name %Preset::get_type_string(it->type) %it->user_id;
|
||||
if (it->name == selected_filament_name)
|
||||
need_reset_filament_preset = true;
|
||||
|
@ -1267,72 +1264,6 @@ void PresetBundle::load_installed_sla_materials(AppConfig &config)
|
|||
preset.set_visible_from_appconfig(config);
|
||||
}
|
||||
|
||||
void PresetBundle::update_selections(AppConfig &config)
|
||||
{
|
||||
std::string initial_printer_profile_name = printers.get_selected_preset_name();
|
||||
// Orca: load from orca_presets
|
||||
std::string initial_print_profile_name = config.get_printer_setting(initial_printer_profile_name, PRESET_PRINT_NAME);
|
||||
std::string initial_filament_profile_name = config.get_printer_setting(initial_printer_profile_name, PRESET_FILAMENT_NAME);
|
||||
|
||||
// Selects the profiles, which were selected at the last application close.
|
||||
prints.select_preset_by_name_strict(initial_print_profile_name);
|
||||
filaments.select_preset_by_name_strict(initial_filament_profile_name);
|
||||
|
||||
// Load the names of the other filament profiles selected for a multi-material printer.
|
||||
// Load it even if the current printer technology is SLA.
|
||||
// The possibly excessive filament names will be later removed with this->update_multi_material_filament_presets()
|
||||
// once the FFF technology gets selected.
|
||||
this->filament_presets = { filaments.get_selected_preset_name() };
|
||||
for (unsigned int i = 1; i < 1000; ++ i) {
|
||||
char name[64];
|
||||
sprintf(name, "filament_%02u", i);
|
||||
auto f_name = config.get_printer_setting(initial_printer_profile_name, name);
|
||||
if (f_name.empty())
|
||||
break;
|
||||
this->filament_presets.emplace_back(remove_ini_suffix(f_name));
|
||||
}
|
||||
std::vector<std::string> filament_colors;
|
||||
auto f_colors = config.get_printer_setting(initial_printer_profile_name, "filament_colors");
|
||||
if (!f_colors.empty()) {
|
||||
boost::algorithm::split(filament_colors, f_colors, boost::algorithm::is_any_of(","));
|
||||
}
|
||||
filament_colors.resize(filament_presets.size(), "#FF8040");
|
||||
project_config.option<ConfigOptionStrings>("filament_colour")->values = filament_colors;
|
||||
std::vector<std::string> matrix;
|
||||
if (config.has_printer_setting(initial_printer_profile_name, "flush_volumes_matrix")) {
|
||||
boost::algorithm::split(matrix, config.get_printer_setting(initial_printer_profile_name, "flush_volumes_matrix"), boost::algorithm::is_any_of("|"));
|
||||
auto flush_volumes_matrix = matrix | boost::adaptors::transformed(boost::lexical_cast<double, std::string>);
|
||||
project_config.option<ConfigOptionFloats>("flush_volumes_matrix")->values = std::vector<double>(flush_volumes_matrix.begin(), flush_volumes_matrix.end());
|
||||
}
|
||||
if (config.has_printer_setting(initial_printer_profile_name, "flush_volumes_vector")) {
|
||||
boost::algorithm::split(matrix, config.get_printer_setting(initial_printer_profile_name, "flush_volumes_vector"), boost::algorithm::is_any_of("|"));
|
||||
auto flush_volumes_vector = matrix | boost::adaptors::transformed(boost::lexical_cast<double, std::string>);
|
||||
project_config.option<ConfigOptionFloats>("flush_volumes_vector")->values = std::vector<double>(flush_volumes_vector.begin(), flush_volumes_vector.end());
|
||||
}
|
||||
if (config.has("app", "flush_multiplier")) {
|
||||
std::string str_flush_multiplier = config.get("app", "flush_multiplier");
|
||||
if (!str_flush_multiplier.empty())
|
||||
project_config.option<ConfigOptionFloat>("flush_multiplier")->set(new ConfigOptionFloat(std::stof(str_flush_multiplier)));
|
||||
}
|
||||
|
||||
// Update visibility of presets based on their compatibility with the active printer.
|
||||
// Always try to select a compatible print and filament preset to the current printer preset,
|
||||
// as the application may have been closed with an active "external" preset, which does not
|
||||
// exist.
|
||||
this->update_compatible(PresetSelectCompatibleType::Always);
|
||||
this->update_multi_material_filament_presets();
|
||||
|
||||
std::string first_visible_filament_name;
|
||||
for (auto & fp : filament_presets) {
|
||||
if (auto it = filaments.find_preset_internal(fp); it == filaments.end() || !it->is_visible || !it->is_compatible) {
|
||||
if (first_visible_filament_name.empty())
|
||||
first_visible_filament_name = filaments.first_compatible().name;
|
||||
fp = first_visible_filament_name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load selections (current print, current filaments, current printer) from config.ini
|
||||
// This is done on application start up or after updates are applied.
|
||||
void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& preferred_selection/* = PresetPreferences()*/)
|
||||
|
@ -1346,8 +1277,10 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p
|
|||
this->load_installed_sla_materials(config);
|
||||
|
||||
// Parse the initial print / filament / printer profile names.
|
||||
// std::string initial_sla_print_profile_name = remove_ini_suffix(config.get("presets", PRESET_SLA_PRINT_NAME));
|
||||
// std::string initial_sla_material_profile_name = remove_ini_suffix(config.get("presets", PRESET_SLA_MATERIALS_NAME));
|
||||
std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", PRESET_PRINT_NAME));
|
||||
std::string initial_sla_print_profile_name = remove_ini_suffix(config.get("presets", PRESET_SLA_PRINT_NAME));
|
||||
std::string initial_filament_profile_name = remove_ini_suffix(config.get("presets", PRESET_FILAMENT_NAME));
|
||||
std::string initial_sla_material_profile_name = remove_ini_suffix(config.get("presets", PRESET_SLA_MATERIALS_NAME));
|
||||
std::string initial_printer_profile_name = remove_ini_suffix(config.get("presets", PRESET_PRINTER_NAME));
|
||||
|
||||
// Activate print / filament / printer profiles from either the config,
|
||||
|
@ -1361,11 +1294,6 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p
|
|||
const Preset *preferred_printer = printers.find_system_preset_by_model_and_variant(preferred_selection.printer_model_id, preferred_selection.printer_variant);
|
||||
printers.select_preset_by_name(preferred_printer ? preferred_printer->name : initial_printer_profile_name, true);
|
||||
|
||||
// Orca: load from orca_presets
|
||||
// const auto os_presets = config.get_machine_settings(initial_printer_profile_name);
|
||||
std::string initial_print_profile_name = config.get_printer_setting(initial_printer_profile_name, PRESET_PRINT_NAME);
|
||||
std::string initial_filament_profile_name = config.get_printer_setting(initial_printer_profile_name, PRESET_FILAMENT_NAME);
|
||||
|
||||
//BBS: set default print/filament profiles to BBL's default setting
|
||||
if (preferred_printer)
|
||||
{
|
||||
|
@ -1381,8 +1309,8 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p
|
|||
// Selects the profile, leaves it to -1 if the initial profile name is empty or if it was not found.
|
||||
prints.select_preset_by_name_strict(initial_print_profile_name);
|
||||
filaments.select_preset_by_name_strict(initial_filament_profile_name);
|
||||
// sla_prints.select_preset_by_name_strict(initial_sla_print_profile_name);
|
||||
// sla_materials.select_preset_by_name_strict(initial_sla_material_profile_name);
|
||||
sla_prints.select_preset_by_name_strict(initial_sla_print_profile_name);
|
||||
sla_materials.select_preset_by_name_strict(initial_sla_material_profile_name);
|
||||
|
||||
// Load the names of the other filament profiles selected for a multi-material printer.
|
||||
// Load it even if the current printer technology is SLA.
|
||||
|
@ -1392,26 +1320,24 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p
|
|||
for (unsigned int i = 1; i < 1000; ++ i) {
|
||||
char name[64];
|
||||
sprintf(name, "filament_%02u", i);
|
||||
auto f_name = config.get_printer_setting(initial_printer_profile_name, name);
|
||||
if (f_name.empty())
|
||||
if (! config.has("presets", name))
|
||||
break;
|
||||
this->filament_presets.emplace_back(remove_ini_suffix(f_name));
|
||||
this->filament_presets.emplace_back(remove_ini_suffix(config.get("presets", name)));
|
||||
}
|
||||
std::vector<std::string> filament_colors;
|
||||
auto f_colors = config.get_printer_setting(initial_printer_profile_name, "filament_colors");
|
||||
if (!f_colors.empty()) {
|
||||
boost::algorithm::split(filament_colors, f_colors, boost::algorithm::is_any_of(","));
|
||||
if (config.has("presets", "filament_colors")) {
|
||||
boost::algorithm::split(filament_colors, config.get("presets", "filament_colors"), boost::algorithm::is_any_of(","));
|
||||
}
|
||||
filament_colors.resize(filament_presets.size(), "#FF8040");
|
||||
filament_colors.resize(filament_presets.size(), "#00AE42");
|
||||
project_config.option<ConfigOptionStrings>("filament_colour")->values = filament_colors;
|
||||
std::vector<std::string> matrix;
|
||||
if (config.has_printer_setting(initial_printer_profile_name, "flush_volumes_matrix")) {
|
||||
boost::algorithm::split(matrix, config.get_printer_setting(initial_printer_profile_name, "flush_volumes_matrix"), boost::algorithm::is_any_of("|"));
|
||||
if (config.has("presets", "flush_volumes_matrix")) {
|
||||
boost::algorithm::split(matrix, config.get("presets", "flush_volumes_matrix"), boost::algorithm::is_any_of("|"));
|
||||
auto flush_volumes_matrix = matrix | boost::adaptors::transformed(boost::lexical_cast<double, std::string>);
|
||||
project_config.option<ConfigOptionFloats>("flush_volumes_matrix")->values = std::vector<double>(flush_volumes_matrix.begin(), flush_volumes_matrix.end());
|
||||
}
|
||||
if (config.has_printer_setting(initial_printer_profile_name, "flush_volumes_vector")) {
|
||||
boost::algorithm::split(matrix, config.get_printer_setting(initial_printer_profile_name, "flush_volumes_vector"), boost::algorithm::is_any_of("|"));
|
||||
if (config.has("presets", "flush_volumes_vector")) {
|
||||
boost::algorithm::split(matrix, config.get("presets", "flush_volumes_vector"), boost::algorithm::is_any_of("|"));
|
||||
auto flush_volumes_vector = matrix | boost::adaptors::transformed(boost::lexical_cast<double, std::string>);
|
||||
project_config.option<ConfigOptionFloats>("flush_volumes_vector")->values = std::vector<double>(flush_volumes_vector.begin(), flush_volumes_vector.end());
|
||||
}
|
||||
|
@ -1473,32 +1399,27 @@ void PresetBundle::export_selections(AppConfig &config)
|
|||
assert(this->printers.get_edited_preset().printer_technology() != ptFFF || filament_presets.size() >= 1);
|
||||
//assert(this->printers.get_edited_preset().printer_technology() != ptFFF || filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front());
|
||||
config.clear_section("presets");
|
||||
auto printer_name = printers.get_selected_preset_name();
|
||||
config.set("presets", PRESET_PRINTER_NAME, printer_name);
|
||||
|
||||
config.clear_printer_settings(printer_name);
|
||||
config.set_printer_setting(printer_name, PRESET_PRINTER_NAME, printer_name);
|
||||
config.set_printer_setting(printer_name, PRESET_PRINT_NAME, prints.get_selected_preset_name());
|
||||
config.set_printer_setting(printer_name, PRESET_FILAMENT_NAME, filament_presets.front());
|
||||
config.set_printer_setting(printer_name, "curr_bed_type", config.get("curr_bed_type"));
|
||||
config.set("presets", PRESET_PRINT_NAME, prints.get_selected_preset_name());
|
||||
config.set("presets", PRESET_FILAMENT_NAME, filament_presets.front());
|
||||
for (unsigned i = 1; i < filament_presets.size(); ++i) {
|
||||
char name[64];
|
||||
assert(!filament_presets[i].empty());
|
||||
sprintf(name, "filament_%02u", i);
|
||||
config.set_printer_setting(printer_name, name, filament_presets[i]);
|
||||
config.set("presets", name, filament_presets[i]);
|
||||
}
|
||||
CNumericLocalesSetter locales_setter;
|
||||
std::string filament_colors = boost::algorithm::join(project_config.option<ConfigOptionStrings>("filament_colour")->values, ",");
|
||||
config.set_printer_setting(printer_name, "filament_colors", filament_colors);
|
||||
config.set("presets", "filament_colors", filament_colors);
|
||||
std::string flush_volumes_matrix = boost::algorithm::join(project_config.option<ConfigOptionFloats>("flush_volumes_matrix")->values |
|
||||
boost::adaptors::transformed(static_cast<std::string (*)(double)>(std::to_string)),
|
||||
"|");
|
||||
config.set_printer_setting(printer_name, "flush_volumes_matrix", flush_volumes_matrix);
|
||||
config.set("presets", "flush_volumes_matrix", flush_volumes_matrix);
|
||||
std::string flush_volumes_vector = boost::algorithm::join(project_config.option<ConfigOptionFloats>("flush_volumes_vector")->values |
|
||||
boost::adaptors::transformed(static_cast<std::string (*)(double)>(std::to_string)),
|
||||
"|");
|
||||
config.set_printer_setting(printer_name, "flush_volumes_vector", flush_volumes_vector);
|
||||
config.set("presets", "flush_volumes_vector", flush_volumes_vector);
|
||||
|
||||
config.set("presets", PRESET_PRINTER_NAME, printers.get_selected_preset_name());
|
||||
|
||||
auto flush_multi_opt = project_config.option<ConfigOptionFloat>("flush_multiplier");
|
||||
config.set("flush_multiplier", std::to_string(flush_multi_opt ? flush_multi_opt->getFloat() : 1.0f));
|
||||
|
@ -1539,7 +1460,8 @@ unsigned int PresetBundle::sync_ams_list(unsigned int &unknowns)
|
|||
{
|
||||
std::vector<std::string> filament_presets;
|
||||
std::vector<std::string> filament_colors;
|
||||
for (auto &ams : filament_ams_list) {
|
||||
for (auto &entry : filament_ams_list) {
|
||||
auto & ams = entry.second;
|
||||
auto filament_id = ams.opt_string("filament_id", 0u);
|
||||
auto filament_color = ams.opt_string("filament_colour", 0u);
|
||||
auto filament_changed = !ams.has("filament_changed") || ams.opt_bool("filament_changed");
|
||||
|
@ -1552,10 +1474,14 @@ unsigned int PresetBundle::sync_ams_list(unsigned int &unknowns)
|
|||
auto iter = std::find_if(filaments.begin(), filaments.end(), [&filament_id](auto &f) { return f.is_compatible && f.is_system && f.filament_id == filament_id; });
|
||||
if (iter == filaments.end()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": filament_id %1% not found or system or compatible") % filament_id;
|
||||
auto filament_type = "Generic " + ams.opt_string("filament_type", 0u);
|
||||
iter = std::find_if(filaments.begin(), filaments.end(), [&filament_type](auto &f) { return f.is_compatible && f.is_system
|
||||
auto filament_type = ams.opt_string("filament_type", 0u);
|
||||
if (!filament_type.empty()) {
|
||||
filament_type = "Generic " + filament_type;
|
||||
iter = std::find_if(filaments.begin(), filaments.end(), [&filament_type](auto &f) {
|
||||
return f.is_compatible && f.is_system
|
||||
&& boost::algorithm::starts_with(f.name, filament_type);
|
||||
});
|
||||
}
|
||||
if (iter == filaments.end())
|
||||
iter = std::find_if(filaments.begin(), filaments.end(), [&filament_type](auto &f) { return f.is_compatible && f.is_system; });
|
||||
if (iter == filaments.end())
|
||||
|
@ -1637,11 +1563,11 @@ DynamicPrintConfig PresetBundle::full_config() const
|
|||
DynamicPrintConfig PresetBundle::full_config_secure() const
|
||||
{
|
||||
DynamicPrintConfig config = this->full_config();
|
||||
//FIXME legacy, the keys should not be there after conversion to a Physical Printer profile.
|
||||
config.erase("print_host");
|
||||
//BBS example: config.erase("print_host");
|
||||
config.erase("print_host_webui");
|
||||
config.erase("printhost_apikey");
|
||||
config.erase("printhost_cafile"); return config;
|
||||
config.erase("printhost_cafile");
|
||||
return config;
|
||||
}
|
||||
|
||||
const std::set<std::string> ignore_settings_list ={
|
||||
|
@ -3645,9 +3571,9 @@ std::vector<std::string> PresetBundle::export_current_configs(const std::string
|
|||
if (overwrite == 0) overwrite = 1;
|
||||
if (boost::filesystem::exists(file) && overwrite < 2) {
|
||||
overwrite = override_confirm(preset->name);
|
||||
if (overwrite == 0 || overwrite == 2)
|
||||
continue;
|
||||
}
|
||||
if (overwrite == 0 || overwrite == 2)
|
||||
continue;
|
||||
preset->config.save_to_json(file, preset->name, "", preset->version.to_string());
|
||||
result.push_back(file);
|
||||
}
|
||||
|
|
|
@ -86,8 +86,6 @@ public:
|
|||
//BBS: check whether this is the only edited filament
|
||||
bool is_the_only_edited_filament(unsigned int filament_index);
|
||||
|
||||
// Orca: update selected filament and print
|
||||
void update_selections(AppConfig &config);
|
||||
void set_calibrate_printer(std::string name);
|
||||
|
||||
PresetCollection prints;
|
||||
|
@ -102,7 +100,7 @@ public:
|
|||
// extruders.size() should be the same as printers.get_edited_preset().config.nozzle_diameter.size()
|
||||
std::vector<std::string> filament_presets;
|
||||
// BBS: ams
|
||||
std::vector<DynamicPrintConfig> filament_ams_list;
|
||||
std::map<int, DynamicPrintConfig> filament_ams_list;
|
||||
// Calibrate
|
||||
Preset const * calibrate_printer = nullptr;
|
||||
std::set<Preset const *> calibrate_filaments;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
//BBS: add json support
|
||||
#include "nlohmann/json.hpp"
|
||||
|
@ -80,7 +79,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
"before_layer_change_gcode",
|
||||
"enable_pressure_advance",
|
||||
"pressure_advance",
|
||||
"enable_overhang_bridge_fan",
|
||||
"enable_overhang_bridge_fan"
|
||||
"overhang_fan_speed",
|
||||
"overhang_fan_threshold",
|
||||
"slow_down_for_layer_cooling",
|
||||
|
@ -93,28 +92,23 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
"extruder_clearance_height_to_rod",
|
||||
"extruder_clearance_height_to_lid",
|
||||
"extruder_clearance_radius",
|
||||
"extruder_clearance_max_radius",
|
||||
"extruder_colour",
|
||||
"extruder_offset",
|
||||
"filament_flow_ratio",
|
||||
"reduce_fan_stop_start_freq",
|
||||
"fan_cooling_layer_time",
|
||||
"full_fan_speed_layer",
|
||||
"fan_kickstart",
|
||||
"fan_speedup_overhangs",
|
||||
"fan_speedup_time",
|
||||
"filament_colour",
|
||||
"default_filament_colour",
|
||||
"filament_diameter",
|
||||
"filament_density",
|
||||
"filament_cost",
|
||||
"outer_wall_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"top_surface_acceleration",
|
||||
"bridge_acceleration",
|
||||
"travel_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration"
|
||||
"accel_to_decel_enable",
|
||||
"accel_to_decel_factor",
|
||||
// BBS
|
||||
"cool_plate_temp_initial_layer",
|
||||
"eng_plate_temp_initial_layer",
|
||||
|
@ -137,14 +131,10 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
"retract_when_changing_layer",
|
||||
"retraction_length",
|
||||
"retract_length_toolchange",
|
||||
"z_hop",
|
||||
"retract_lift_above",
|
||||
"retract_lift_below",
|
||||
"retract_lift_enforce",
|
||||
"z_hop",
|
||||
"retract_restart_extra",
|
||||
"retract_restart_extra_toolchange",
|
||||
"retraction_speed",
|
||||
"use_firmware_retraction",
|
||||
"slow_down_layer_time",
|
||||
"standby_temperature_delta",
|
||||
"machine_start_gcode",
|
||||
|
@ -155,23 +145,23 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
"wipe_distance",
|
||||
"curr_bed_type",
|
||||
"nozzle_volume",
|
||||
"chamber_temperature",
|
||||
"thumbnails",
|
||||
"nozzle_hrc",
|
||||
"chamber_temperatures",
|
||||
"required_nozzle_HRC",
|
||||
"upward_compatible_machine",
|
||||
// SoftFever
|
||||
//OrcaSlicer
|
||||
"seam_gap",
|
||||
"role_based_wipe_speed",
|
||||
"wipe_speed",
|
||||
"use_relative_e_distances",
|
||||
"accel_to_decel_enable",
|
||||
"accel_to_decel_factor",
|
||||
"wipe_on_loops",
|
||||
"gcode_comments",
|
||||
"gcode_label_objects",
|
||||
"wipe_speed"
|
||||
"default_jerk",
|
||||
"outer_wall_jerk",
|
||||
"inner_wall_jerk",
|
||||
"infill_jerk",
|
||||
"top_surface_jerk",
|
||||
"initial_layer_jerk",
|
||||
"travel_jerk",
|
||||
"inner_wall_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"exclude_object",
|
||||
"support_material_interface_fan_speed"
|
||||
"use_relative_e_distances"
|
||||
};
|
||||
|
||||
static std::unordered_set<std::string> steps_ignore;
|
||||
|
@ -189,7 +179,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
// These steps have no influence on the G-code whatsoever. Just ignore them.
|
||||
} else if (
|
||||
opt_key == "skirt_loops"
|
||||
|| opt_key == "skirt_speed"
|
||||
|| opt_key == "skirt_height"
|
||||
|| opt_key == "draft_shield"
|
||||
|| opt_key == "skirt_distance"
|
||||
|
@ -201,7 +190,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
} else if (
|
||||
opt_key == "initial_layer_print_height"
|
||||
|| opt_key == "nozzle_diameter"
|
||||
|| opt_key == "filament_shrink"
|
||||
|| opt_key == "resolution"
|
||||
// Spiral Vase forces different kind of slicing than the normal model:
|
||||
// In Spiral Vase mode, holes are closed and only the largest area contour is kept at each layer.
|
||||
|
@ -210,8 +198,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
osteps.emplace_back(posSlice);
|
||||
} else if (
|
||||
opt_key == "print_sequence"
|
||||
|| opt_key == "chamber_temperatures"
|
||||
|| 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"
|
||||
|
@ -236,9 +224,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
|| opt_key == "initial_layer_infill_speed"
|
||||
|| opt_key == "travel_speed"
|
||||
|| opt_key == "travel_speed_z"
|
||||
|| opt_key == "initial_layer_speed"
|
||||
|| opt_key == "initial_layer_travel_speed"
|
||||
|| opt_key == "slow_down_layers") {
|
||||
|| opt_key == "initial_layer_speed") {
|
||||
//|| opt_key == "z_offset") {
|
||||
steps.emplace_back(psWipeTower);
|
||||
steps.emplace_back(psSkirtBrim);
|
||||
|
@ -262,7 +248,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
osteps.emplace_back(posPerimeters);
|
||||
osteps.emplace_back(posInfill);
|
||||
osteps.emplace_back(posSupportMaterial);
|
||||
osteps.emplace_back(posSimplifyPath);
|
||||
osteps.emplace_back(posSimplifyWall);
|
||||
osteps.emplace_back(posSimplifyInfill);
|
||||
osteps.emplace_back(posSimplifySupportPath);
|
||||
steps.emplace_back(psSkirtBrim);
|
||||
|
@ -288,9 +274,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
return invalidated;
|
||||
}
|
||||
|
||||
void Print::set_calib_params(const Calib_Params& params) {
|
||||
m_calib_params = params;
|
||||
m_calib_params.mode = params.mode;
|
||||
void Print::set_calib_params(const Calib_Params ¶ms)
|
||||
{
|
||||
m_calib_params = params;
|
||||
}
|
||||
|
||||
bool Print::invalidate_step(PrintStep step)
|
||||
|
@ -541,7 +527,7 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
|||
auto tmp = offset(convex_hull_no_offset,
|
||||
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
|
||||
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
|
||||
float(scale_(0.5 * print.config().extruder_clearance_radius.value - EPSILON)),
|
||||
float(scale_(0.5 * print.config().extruder_clearance_max_radius.value - EPSILON)),
|
||||
jtRound, scale_(0.1));
|
||||
if (!tmp.empty()) { // tmp may be empty due to clipper's bug, see STUDIO-2452
|
||||
convex_hull = tmp.front();
|
||||
|
@ -954,10 +940,6 @@ StringObjectException Print::check_multi_filament_valid(const Print& print)
|
|||
return {std::string()};
|
||||
}
|
||||
|
||||
// Orca: this g92e0 regex is used copied from PrusaSlicer
|
||||
// Matches "G92 E0" with various forms of writing the zero and with an optional comment.
|
||||
boost::regex regex_g92e0 { "^[ \\t]*[gG]92[ \\t]*[eE](0(\\.0*)?|\\.0+)[ \\t]*(;.*)?$" };
|
||||
|
||||
// Precondition: Print::validate() requires the Print::apply() to be called its invocation.
|
||||
//BBS: refine seq-print validation logic
|
||||
StringObjectException Print::validate(StringObjectException *warning, Polygons* collison_polygons, std::vector<std::pair<Polygon, float>>* height_polygons) const
|
||||
|
@ -1138,15 +1120,19 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
|||
return ("One or more object were assigned an extruder that the printer does not have.");
|
||||
#endif
|
||||
|
||||
auto validate_extrusion_width = [min_nozzle_diameter, max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool {
|
||||
double extrusion_width_min = config.get_abs_value(opt_key, min_nozzle_diameter);
|
||||
double extrusion_width_max = config.get_abs_value(opt_key, max_nozzle_diameter);
|
||||
auto validate_extrusion_width = [/*min_nozzle_diameter,*/ max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool {
|
||||
// This may change in the future, if we switch to "extrusion width wrt. nozzle diameter"
|
||||
// instead of currently used logic "extrusion width wrt. layer height", see GH issues #1923 #2829.
|
||||
// double extrusion_width_min = config.get_abs_value(opt_key, min_nozzle_diameter);
|
||||
// double extrusion_width_max = config.get_abs_value(opt_key, max_nozzle_diameter);
|
||||
double extrusion_width_min = config.get_abs_value(opt_key);
|
||||
double extrusion_width_max = config.get_abs_value(opt_key);
|
||||
if (extrusion_width_min == 0) {
|
||||
// Default "auto-generated" extrusion width is always valid.
|
||||
} else if (extrusion_width_min <= layer_height) {
|
||||
err_msg = L("Too small line width");
|
||||
return false;
|
||||
} else if (extrusion_width_max > max_nozzle_diameter * 5) {
|
||||
} else if (extrusion_width_max >= max_nozzle_diameter * 2.5) {
|
||||
err_msg = L("Too large line width");
|
||||
return false;
|
||||
}
|
||||
|
@ -1232,56 +1218,33 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
|||
}
|
||||
}
|
||||
|
||||
// Orca: G92 E0 is not supported when using absolute extruder addressing
|
||||
// This check is copied from PrusaSlicer, the original author is Vojtech Bubnik
|
||||
{
|
||||
bool before_layer_gcode_resets_extruder =
|
||||
boost::regex_search(m_config.before_layer_change_gcode.value, regex_g92e0);
|
||||
bool layer_gcode_resets_extruder = boost::regex_search(m_config.layer_change_gcode.value, regex_g92e0);
|
||||
if (m_config.use_relative_e_distances) {
|
||||
// See GH issues #6336 #5073
|
||||
if ((m_config.gcode_flavor == gcfMarlinLegacy || m_config.gcode_flavor == gcfMarlinFirmware) &&
|
||||
!before_layer_gcode_resets_extruder && !layer_gcode_resets_extruder)
|
||||
return {L("Relative extruder addressing requires resetting the extruder position at each layer to "
|
||||
"prevent loss of floating point accuracy. Add \"G92 E0\" to layer_gcode."),
|
||||
nullptr, "before_layer_change_gcode"};
|
||||
} else if (before_layer_gcode_resets_extruder)
|
||||
return {L("\"G92 E0\" was found in before_layer_gcode, which is incompatible with absolute extruder "
|
||||
"addressing."),
|
||||
nullptr, "before_layer_change_gcode"};
|
||||
else if (layer_gcode_resets_extruder)
|
||||
return {L("\"G92 E0\" was found in layer_gcode, which is incompatible with absolute extruder addressing."),
|
||||
nullptr, "layer_change_gcode"};
|
||||
}
|
||||
|
||||
const ConfigOptionDef* bed_type_def = print_config_def.get("curr_bed_type");
|
||||
assert(bed_type_def != nullptr);
|
||||
|
||||
if (is_BBL_printer()) {
|
||||
const t_config_enum_values* bed_type_keys_map = bed_type_def->enum_keys_map;
|
||||
for (unsigned int extruder_id : extruders) {
|
||||
const ConfigOptionInts* bed_temp_opt = m_config.option<ConfigOptionInts>(get_bed_temp_key(m_config.curr_bed_type));
|
||||
for (unsigned int extruder_id : extruders) {
|
||||
int curr_bed_temp = bed_temp_opt->get_at(extruder_id);
|
||||
if (curr_bed_temp == 0 && bed_type_keys_map != nullptr) {
|
||||
std::string bed_type_name;
|
||||
for (auto item : *bed_type_keys_map) {
|
||||
if (item.second == m_config.curr_bed_type) {
|
||||
bed_type_name = item.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const t_config_enum_values* bed_type_keys_map = bed_type_def->enum_keys_map;
|
||||
for (unsigned int extruder_id : extruders) {
|
||||
const ConfigOptionInts* bed_temp_opt = m_config.option<ConfigOptionInts>(get_bed_temp_key(m_config.curr_bed_type));
|
||||
for (unsigned int extruder_id : extruders) {
|
||||
int curr_bed_temp = bed_temp_opt->get_at(extruder_id);
|
||||
if (curr_bed_temp == 0 && bed_type_keys_map != nullptr) {
|
||||
std::string bed_type_name;
|
||||
for (auto item : *bed_type_keys_map) {
|
||||
if (item.second == m_config.curr_bed_type) {
|
||||
bed_type_name = item.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StringObjectException except;
|
||||
except.string = format(L("Plate %d: %s does not support filament %s"), this->get_plate_index() + 1, L(bed_type_name), extruder_id + 1);
|
||||
except.string += "\n";
|
||||
except.type = STRING_EXCEPT_FILAMENT_NOT_MATCH_BED_TYPE;
|
||||
except.params.push_back(std::to_string(this->get_plate_index() + 1));
|
||||
except.params.push_back(L(bed_type_name));
|
||||
except.params.push_back(std::to_string(extruder_id+1));
|
||||
except.object = nullptr;
|
||||
return except;
|
||||
}
|
||||
StringObjectException except;
|
||||
except.string = format(L("Plate %d: %s does not support filament %s"), this->get_plate_index() + 1, L(bed_type_name), extruder_id + 1);
|
||||
except.string += "\n";
|
||||
except.type = STRING_EXCEPT_FILAMENT_NOT_MATCH_BED_TYPE;
|
||||
except.params.push_back(std::to_string(this->get_plate_index() + 1));
|
||||
except.params.push_back(L(bed_type_name));
|
||||
except.params.push_back(std::to_string(extruder_id+1));
|
||||
except.object = nullptr;
|
||||
return except;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1353,10 +1316,10 @@ double Print::skirt_first_layer_height() const
|
|||
|
||||
Flow Print::brim_flow() const
|
||||
{
|
||||
ConfigOptionFloatOrPercent width = m_config.initial_layer_line_width;
|
||||
if (width.value <= 0)
|
||||
ConfigOptionFloat width = m_config.initial_layer_line_width;
|
||||
if (width.value == 0)
|
||||
width = m_print_regions.front()->config().inner_wall_line_width;
|
||||
if (width.value <= 0)
|
||||
if (width.value == 0)
|
||||
width = m_objects.front()->config().line_width;
|
||||
|
||||
/* We currently use a random region's perimeter extruder.
|
||||
|
@ -1366,7 +1329,6 @@ Flow Print::brim_flow() const
|
|||
generation as well. */
|
||||
return Flow::new_from_config_width(
|
||||
frPerimeter,
|
||||
// Flow::new_from_config_width takes care of the percent to value substitution
|
||||
width,
|
||||
(float)m_config.nozzle_diameter.get_at(m_print_regions.front()->config().wall_filament-1),
|
||||
(float)this->skirt_first_layer_height());
|
||||
|
@ -1374,8 +1336,8 @@ Flow Print::brim_flow() const
|
|||
|
||||
Flow Print::skirt_flow() const
|
||||
{
|
||||
ConfigOptionFloatOrPercent width = m_config.initial_layer_line_width;
|
||||
if (width.value <= 0)
|
||||
ConfigOptionFloat width = m_config.initial_layer_line_width;
|
||||
if (width.value == 0)
|
||||
width = m_objects.front()->config().line_width;
|
||||
|
||||
/* We currently use a random object's support material extruder.
|
||||
|
@ -1385,7 +1347,6 @@ Flow Print::skirt_flow() const
|
|||
generation as well. */
|
||||
return Flow::new_from_config_width(
|
||||
frPerimeter,
|
||||
// Flow::new_from_config_width takes care of the percent to value substitution
|
||||
width,
|
||||
(float)m_config.nozzle_diameter.get_at(m_objects.front()->config().support_filament-1),
|
||||
(float)this->skirt_first_layer_height());
|
||||
|
@ -1776,7 +1737,7 @@ void Print::process(bool use_cache)
|
|||
// BBS: m_brimMap and m_supportBrimMap are used instead of m_brim to generate brim of objs and supports seperately
|
||||
m_brimMap.clear();
|
||||
m_supportBrimMap.clear();
|
||||
m_first_layer_convex_hull.points.clear();
|
||||
m_first_layer_convex_hull.points.clear(); // BBS: plate offset is contained in this convexhull
|
||||
if (this->has_brim()) {
|
||||
Polygons islands_area;
|
||||
make_brim(*this, this->make_try_cancel(), islands_area, m_brimMap,
|
||||
|
@ -1805,8 +1766,8 @@ void Print::process(bool use_cache)
|
|||
obj->simplify_extrusion_path();
|
||||
}
|
||||
else {
|
||||
if (obj->set_started(posSimplifyPath))
|
||||
obj->set_done(posSimplifyPath);
|
||||
if (obj->set_started(posSimplifyWall))
|
||||
obj->set_done(posSimplifyWall);
|
||||
if (obj->set_started(posSimplifyInfill))
|
||||
obj->set_done(posSimplifyInfill);
|
||||
if (obj->set_started(posSimplifySupportPath))
|
||||
|
@ -2109,15 +2070,16 @@ std::vector<Point> Print::first_layer_wipe_tower_corners(bool check_wipe_tower_e
|
|||
return corners;
|
||||
}
|
||||
|
||||
//SoftFever
|
||||
Vec2d Print::translate_to_print_space(const Vec2d &point) const {
|
||||
//OrcaSlicer
|
||||
Vec2d Print::translate_to_print_space(const Vec2d& point) const {
|
||||
//const BoundingBoxf bed_bbox(config().printable_area.values);
|
||||
return Vec2d(point(0) - m_origin(0), point(1) - m_origin(1));
|
||||
}
|
||||
|
||||
Vec2d Print::translate_to_print_space(const Point &point) const {
|
||||
Vec2d Print::translate_to_print_space(const Point& point) const {
|
||||
return Vec2d(unscaled(point.x()) - m_origin(0), unscaled(point.y()) - m_origin(1));
|
||||
}
|
||||
|
||||
void Print::finalize_first_layer_convex_hull()
|
||||
{
|
||||
append(m_first_layer_convex_hull.points, m_skirt_convex_hull);
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
#include "GCode/ThumbnailData.hpp"
|
||||
#include "GCode/GCodeProcessor.hpp"
|
||||
#include "MultiMaterialSegmentation.hpp"
|
||||
|
||||
#include "libslic3r.h"
|
||||
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
#include "calib.hpp"
|
||||
#include "Calib.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -87,9 +87,9 @@ enum PrintStep {
|
|||
|
||||
enum PrintObjectStep {
|
||||
posSlice, posPerimeters, posPrepareInfill,
|
||||
posInfill, posIroning, posSupportMaterial, posSimplifyPath, posSimplifySupportPath,
|
||||
posInfill, posIroning, posSupportMaterial,
|
||||
// BBS
|
||||
posSimplifyInfill,
|
||||
posSimplifyWall, posSimplifyInfill, posSimplifySupportPath,
|
||||
posDetectOverhangsForLift,
|
||||
posCount,
|
||||
};
|
||||
|
@ -194,11 +194,11 @@ struct PrintInstance
|
|||
const ModelInstance *model_instance;
|
||||
// Shift of this instance's center into the world coordinates.
|
||||
Point shift;
|
||||
|
||||
|
||||
BoundingBoxf3 get_bounding_box();
|
||||
Polygon get_convex_hull_2d();
|
||||
// SoftFever
|
||||
//
|
||||
// OrcaSlicer
|
||||
//
|
||||
// instance id
|
||||
size_t id;
|
||||
|
||||
|
@ -305,7 +305,7 @@ public:
|
|||
Transform3d trafo_centered() const
|
||||
{ Transform3d t = this->trafo(); t.pretranslate(Vec3d(- unscale<double>(m_center_offset.x()), - unscale<double>(m_center_offset.y()), 0)); return t; }
|
||||
const PrintInstances& instances() const { return m_instances; }
|
||||
PrintInstances &instances() { return m_instances; }
|
||||
PrintInstances& instances() { return m_instances; }
|
||||
|
||||
// Whoever will get a non-const pointer to PrintObject will be able to modify its layers.
|
||||
LayerPtrs& layers() { return m_layers; }
|
||||
|
@ -434,11 +434,11 @@ public:
|
|||
// BBS: Boundingbox of the first layer
|
||||
BoundingBox firstLayerObjectBrimBoundingBox;
|
||||
|
||||
// SoftFever
|
||||
size_t get_id() const { return m_id; }
|
||||
void set_id(size_t id) { m_id = id; }
|
||||
// OrcaSlicer
|
||||
size_t get_klipper_object_id() const { return m_klipper_object_id; }
|
||||
void set_klipper_object_id(size_t id) { m_klipper_object_id = id; }
|
||||
|
||||
private:
|
||||
private:
|
||||
// to be called from Print only.
|
||||
friend class Print;
|
||||
|
||||
|
@ -522,12 +522,10 @@ private:
|
|||
|
||||
PrintObject* m_shared_object{ nullptr };
|
||||
|
||||
|
||||
// SoftFever
|
||||
//
|
||||
// object id
|
||||
size_t m_id;
|
||||
void apply_conical_overhang();
|
||||
// OrcaSlicer
|
||||
//
|
||||
// object id for klipper firmware only
|
||||
size_t m_klipper_object_id;
|
||||
|
||||
public:
|
||||
//BBS: When printing multi-material objects, this settings will make slicer to clip the overlapping object parts one by the other.
|
||||
|
@ -739,7 +737,7 @@ public:
|
|||
|
||||
const PrintConfig& config() const { return m_config; }
|
||||
const PrintObjectConfig& default_object_config() const { return m_default_object_config; }
|
||||
const PrintRegionConfig& default_region_config() const { return m_default_region_config; }
|
||||
const PrintRegionConfig& default_region_config() const { return m_default_region_config; }
|
||||
ConstPrintObjectPtrsAdaptor objects() const { return ConstPrintObjectPtrsAdaptor(&m_objects); }
|
||||
PrintObject* get_object(size_t idx) { return const_cast<PrintObject*>(m_objects[idx]); }
|
||||
const PrintObject* get_object(size_t idx) const { return m_objects[idx]; }
|
||||
|
@ -797,6 +795,8 @@ public:
|
|||
int get_modified_count() const {return m_modified_count;}
|
||||
//BBS: add status for whether support used
|
||||
bool is_support_used() const {return m_support_used;}
|
||||
bool is_BBL_Printer() const { return m_isBBLPrinter;}
|
||||
void set_BBL_Printer(const bool isBBL) { m_isBBLPrinter = isBBL;}
|
||||
std::string get_conflict_string() const
|
||||
{
|
||||
std::string result;
|
||||
|
@ -806,28 +806,23 @@ public:
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
//BBS
|
||||
static StringObjectException sequential_print_clearance_valid(const Print &print, Polygons *polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr);
|
||||
ConflictResultOpt get_conflict_result() const { return m_conflict_result; }
|
||||
|
||||
// Return 4 wipe tower corners in the world coordinates (shifted and rotated), including the wipe tower brim.
|
||||
std::vector<Point> first_layer_wipe_tower_corners(bool check_wipe_tower_existance=true) const;
|
||||
|
||||
//SoftFever
|
||||
bool &is_BBL_printer() { return m_isBBLPrinter; }
|
||||
const bool is_BBL_printer() const { return m_isBBLPrinter; }
|
||||
CalibMode& calib_mode() { return m_calib_params.mode; }
|
||||
const CalibMode calib_mode() const { return m_calib_params.mode; }
|
||||
void set_calib_params(const Calib_Params& params);
|
||||
//OrcaSlicer
|
||||
CalibMode & calib_mode() { return m_calib_params.mode; }
|
||||
const CalibMode& calib_mode() const { return m_calib_params.mode; }
|
||||
void set_calib_params(const Calib_Params ¶ms);
|
||||
const Calib_Params& calib_params() const { return m_calib_params; }
|
||||
Vec2d translate_to_print_space(const Vec2d &point) const;
|
||||
Vec2d translate_to_print_space(const Vec2d& point) const;
|
||||
// scaled point
|
||||
Vec2d translate_to_print_space(const Point &point) const;
|
||||
Vec2d translate_to_print_space(const Point& point) const;
|
||||
|
||||
static bool check_multi_filaments_compatibility(const std::vector<std::string>& filament_types);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// Invalidates the step, and its depending steps in Print.
|
||||
bool invalidate_step(PrintStep step);
|
||||
|
||||
|
@ -849,10 +844,8 @@ private:
|
|||
PrintRegionConfig m_default_region_config;
|
||||
PrintObjectPtrs m_objects;
|
||||
PrintRegionPtrs m_print_regions;
|
||||
|
||||
//SoftFever
|
||||
bool m_isBBLPrinter;
|
||||
|
||||
//BBS.
|
||||
bool m_isBBLPrinter = false;
|
||||
// Ordered collections of extrusion paths to build skirt loops and brim.
|
||||
ExtrusionEntityCollection m_skirt;
|
||||
// BBS: collecting extrusion paths to build brim by objs
|
||||
|
@ -881,8 +874,8 @@ private:
|
|||
//BBS
|
||||
ConflictResultOpt m_conflict_result;
|
||||
FakeWipeTower m_fake_wipe_tower;
|
||||
|
||||
//SoftFever: calibration
|
||||
|
||||
// OrcaSlicer: calibration
|
||||
Calib_Params m_calib_params;
|
||||
|
||||
// To allow GCode to set the Print's GCodeExport step status.
|
||||
|
|
|
@ -581,7 +581,7 @@ static void transformed_its_bboxes_in_z_ranges(
|
|||
if (p2->z() <= z_range.first || p1->z() >= z_range.second) {
|
||||
// Out of this slab.
|
||||
} else if (p1->z() < z_range.first) {
|
||||
if (p1->z() > z_range.second) {
|
||||
if (p2->z() > z_range.second) {
|
||||
// Two intersections.
|
||||
float zspan = p2->z() - p1->z();
|
||||
float t1 = (z_range.first - p1->z()) / zspan;
|
||||
|
|
|
@ -516,9 +516,9 @@ public:
|
|||
bool get_no_check_flag() const { return m_no_check; }
|
||||
void set_no_check_flag(bool no_check) { m_no_check = no_check; }
|
||||
|
||||
//SoftFever plate name
|
||||
std::string get_plate_name() const { return m_plate_name; }
|
||||
void set_plate_name(const std::string& name) { m_plate_name = name; }
|
||||
void set_plate_name(const std::string &name) { m_plate_name = name; }
|
||||
|
||||
protected:
|
||||
friend class PrintObjectBase;
|
||||
friend class BackgroundSlicingProcess;
|
||||
|
@ -554,9 +554,8 @@ protected:
|
|||
int m_plate_index{ 0 };
|
||||
bool m_no_check = false;
|
||||
|
||||
// SoftFever: current plate name
|
||||
std::string m_plate_name;
|
||||
|
||||
// current plate name
|
||||
std::string m_plate_name; // utf8 string
|
||||
// Callback to be evoked regularly to update state of the UI thread.
|
||||
status_callback_type m_status_callback;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,7 +32,7 @@
|
|||
namespace Slic3r {
|
||||
|
||||
enum GCodeFlavor : unsigned char {
|
||||
gcfMarlinLegacy, gcfKlipper, gcfRepRapFirmware, gcfRepRapSprinter, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlinFirmware, gcfSailfish, gcfMach3, gcfMachinekit,
|
||||
gcfMarlinLegacy, gcfKlipper, gcfRepRapSprinter, gcfRepRapFirmware, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlinFirmware, gcfSailfish, gcfMach3, gcfMachinekit,
|
||||
gcfSmoothie, gcfNoExtrusion
|
||||
};
|
||||
|
||||
|
@ -129,12 +129,6 @@ enum SeamPosition {
|
|||
spNearest, spAligned, spRear, spRandom
|
||||
};
|
||||
|
||||
enum LiftType {
|
||||
NormalLift,
|
||||
SpiralLift,
|
||||
LazyLift
|
||||
};
|
||||
|
||||
enum SLAMaterial {
|
||||
slamTough,
|
||||
slamFlex,
|
||||
|
@ -156,7 +150,6 @@ enum SLAPillarConnectionMode {
|
|||
|
||||
enum BrimType {
|
||||
btAutoBrim, // BBS
|
||||
btEar, // Orca
|
||||
btOuterOnly,
|
||||
btInnerOnly,
|
||||
btOuterAndInner,
|
||||
|
@ -181,6 +174,13 @@ enum class PerimeterGeneratorType
|
|||
Arachne
|
||||
};
|
||||
|
||||
enum class TopOneWallType
|
||||
{
|
||||
None,
|
||||
Alltop,
|
||||
Topmost
|
||||
};
|
||||
|
||||
// BBS
|
||||
enum OverhangFanThreshold {
|
||||
Overhang_threshold_none = 0,
|
||||
|
@ -219,11 +219,10 @@ enum ZHopType {
|
|||
zhtCount
|
||||
};
|
||||
|
||||
enum RetractLiftEnforceType {
|
||||
rletAllSurfaces = 0,
|
||||
rletTopOnly,
|
||||
rletBottomOnly,
|
||||
rletTopAndBottom
|
||||
// BBS
|
||||
enum ExtruderType {
|
||||
etDirectDrive = 0,
|
||||
etBowden
|
||||
};
|
||||
|
||||
static std::string bed_type_to_gcode_string(const BedType type)
|
||||
|
@ -312,7 +311,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ForwardCompatibilitySubstitutionRule)
|
|||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrintHostType)
|
||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AuthorizationType)
|
||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType)
|
||||
|
||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(TopOneWallType)
|
||||
#undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS
|
||||
|
||||
// Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs.
|
||||
|
@ -641,12 +640,10 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloat, brim_object_gap))
|
||||
((ConfigOptionEnum<BrimType>, brim_type))
|
||||
((ConfigOptionFloat, brim_width))
|
||||
((ConfigOptionFloat, brim_ears_detection_length))
|
||||
((ConfigOptionFloat, brim_ears_max_angle))
|
||||
((ConfigOptionBool, bridge_no_support))
|
||||
((ConfigOptionFloat, elefant_foot_compensation))
|
||||
((ConfigOptionFloat, max_bridge_length))
|
||||
((ConfigOptionFloatOrPercent, line_width))
|
||||
((ConfigOptionFloat, line_width))
|
||||
// Force the generation of solid shells between adjacent materials/volumes.
|
||||
((ConfigOptionBool, interface_shells))
|
||||
((ConfigOptionFloat, layer_height))
|
||||
|
@ -656,7 +653,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloat, raft_first_layer_expansion))
|
||||
((ConfigOptionInt, raft_layers))
|
||||
((ConfigOptionEnum<SeamPosition>, seam_position))
|
||||
((ConfigOptionBool, staggered_inner_seams))
|
||||
((ConfigOptionFloat, slice_closing_radius))
|
||||
((ConfigOptionEnum<SlicingMode>, slicing_mode))
|
||||
((ConfigOptionBool, enable_support))
|
||||
|
@ -671,7 +667,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloat, support_bottom_z_distance))
|
||||
((ConfigOptionInt, enforce_support_layers))
|
||||
((ConfigOptionInt, support_filament))
|
||||
((ConfigOptionFloatOrPercent, support_line_width))
|
||||
((ConfigOptionFloat, support_line_width))
|
||||
((ConfigOptionBool, support_interface_loop_pattern))
|
||||
((ConfigOptionInt, support_interface_filament))
|
||||
((ConfigOptionInt, support_interface_top_layers))
|
||||
|
@ -703,8 +699,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloat, tree_support_branch_diameter))
|
||||
((ConfigOptionFloat, tree_support_branch_angle))
|
||||
((ConfigOptionInt, tree_support_wall_count))
|
||||
((ConfigOptionBool, tree_support_adaptive_layer_height))
|
||||
((ConfigOptionBool, tree_support_auto_brim))
|
||||
((ConfigOptionFloat, tree_support_brim_width))
|
||||
((ConfigOptionBool, detect_narrow_internal_solid_infill))
|
||||
// ((ConfigOptionBool, adaptive_layer_height))
|
||||
|
@ -717,39 +711,39 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionInt, wall_distribution_count))
|
||||
((ConfigOptionPercent, min_feature_size))
|
||||
((ConfigOptionPercent, min_bead_width))
|
||||
|
||||
// Orca
|
||||
((ConfigOptionFloat, make_overhang_printable_angle))
|
||||
((ConfigOptionFloat, make_overhang_printable_hole_size))
|
||||
((ConfigOptionEnum<TopOneWallType>, top_one_wall_type))
|
||||
((ConfigOptionBool, only_one_wall_first_layer))
|
||||
// OrcaSlicer
|
||||
((ConfigOptionPercent, seam_gap))
|
||||
((ConfigOptionPercent, wipe_speed))
|
||||
)
|
||||
|
||||
// This object is mapped to Perl as Slic3r::Config::PrintRegion.
|
||||
PRINT_CONFIG_CLASS_DEFINE(
|
||||
PrintRegionConfig,
|
||||
|
||||
((ConfigOptionInt, bottom_shell_layers))
|
||||
((ConfigOptionFloat, bottom_shell_thickness))
|
||||
((ConfigOptionFloat, bridge_angle))
|
||||
((ConfigOptionFloat, bridge_flow))
|
||||
((ConfigOptionFloat, bridge_speed))
|
||||
((ConfigOptionFloatOrPercent, internal_bridge_speed))
|
||||
((ConfigOptionBool, ensure_vertical_shell_thickness))
|
||||
((ConfigOptionEnum<InfillPattern>, top_surface_pattern))
|
||||
((ConfigOptionEnum<InfillPattern>, bottom_surface_pattern))
|
||||
((ConfigOptionInt, bottom_shell_layers))
|
||||
((ConfigOptionFloat, bottom_shell_thickness))
|
||||
((ConfigOptionFloat, bridge_angle))
|
||||
((ConfigOptionFloat, bridge_flow))
|
||||
((ConfigOptionFloat, bridge_speed))
|
||||
((ConfigOptionBool, ensure_vertical_shell_thickness))
|
||||
((ConfigOptionEnum<InfillPattern>, top_surface_pattern))
|
||||
((ConfigOptionEnum<InfillPattern>, bottom_surface_pattern))
|
||||
((ConfigOptionEnum<InfillPattern>, internal_solid_infill_pattern))
|
||||
((ConfigOptionFloatOrPercent, outer_wall_line_width))
|
||||
((ConfigOptionFloat, outer_wall_speed))
|
||||
((ConfigOptionFloat, infill_direction))
|
||||
((ConfigOptionPercent, sparse_infill_density))
|
||||
((ConfigOptionEnum<InfillPattern>, sparse_infill_pattern))
|
||||
((ConfigOptionEnum<FuzzySkinType>, fuzzy_skin))
|
||||
((ConfigOptionFloat, fuzzy_skin_thickness))
|
||||
((ConfigOptionFloat, fuzzy_skin_point_distance))
|
||||
((ConfigOptionFloat, gap_infill_speed))
|
||||
((ConfigOptionInt, sparse_infill_filament))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_line_width))
|
||||
((ConfigOptionPercent, infill_wall_overlap))
|
||||
((ConfigOptionFloat, sparse_infill_speed))
|
||||
((ConfigOptionFloat, outer_wall_line_width))
|
||||
((ConfigOptionFloat, outer_wall_speed))
|
||||
((ConfigOptionFloat, infill_direction))
|
||||
((ConfigOptionPercent, sparse_infill_density))
|
||||
((ConfigOptionEnum<InfillPattern>, sparse_infill_pattern))
|
||||
((ConfigOptionEnum<FuzzySkinType>, fuzzy_skin))
|
||||
((ConfigOptionFloat, fuzzy_skin_thickness))
|
||||
((ConfigOptionFloat, fuzzy_skin_point_distance))
|
||||
((ConfigOptionFloat, gap_infill_speed))
|
||||
((ConfigOptionInt, sparse_infill_filament))
|
||||
((ConfigOptionFloat, sparse_infill_line_width))
|
||||
((ConfigOptionPercent, infill_wall_overlap))
|
||||
((ConfigOptionFloat, sparse_infill_speed))
|
||||
//BBS
|
||||
((ConfigOptionBool, infill_combination))
|
||||
// Ironing options
|
||||
|
@ -761,51 +755,34 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
// Detect bridging perimeters
|
||||
((ConfigOptionBool, detect_overhang_wall))
|
||||
((ConfigOptionInt, wall_filament))
|
||||
((ConfigOptionFloatOrPercent, inner_wall_line_width))
|
||||
((ConfigOptionFloat, inner_wall_line_width))
|
||||
((ConfigOptionFloat, inner_wall_speed))
|
||||
// Total number of perimeters.
|
||||
((ConfigOptionInt, wall_loops))
|
||||
((ConfigOptionFloat, minimum_sparse_infill_area))
|
||||
((ConfigOptionInt, solid_infill_filament))
|
||||
((ConfigOptionFloatOrPercent, internal_solid_infill_line_width))
|
||||
((ConfigOptionFloat, internal_solid_infill_line_width))
|
||||
((ConfigOptionFloat, internal_solid_infill_speed))
|
||||
// Detect thin walls.
|
||||
((ConfigOptionBool, detect_thin_wall))
|
||||
((ConfigOptionFloatOrPercent, top_surface_line_width))
|
||||
((ConfigOptionFloat, top_surface_line_width))
|
||||
((ConfigOptionInt, top_shell_layers))
|
||||
((ConfigOptionFloat, top_shell_thickness))
|
||||
((ConfigOptionFloat, top_surface_speed))
|
||||
//BBS
|
||||
((ConfigOptionBool, enable_overhang_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_1_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_2_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_3_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_4_4_speed))
|
||||
((ConfigOptionBool, only_one_wall_top))
|
||||
|
||||
//SoftFever
|
||||
((ConfigOptionFloatOrPercent, min_width_top_surface))
|
||||
((ConfigOptionBool, only_one_wall_first_layer))
|
||||
((ConfigOptionFloat, print_flow_ratio))
|
||||
((ConfigOptionFloatOrPercent, seam_gap))
|
||||
((ConfigOptionBool, role_based_wipe_speed))
|
||||
((ConfigOptionFloatOrPercent, wipe_speed))
|
||||
((ConfigOptionBool, wipe_on_loops))
|
||||
((ConfigOptionEnum<WallInfillOrder>, wall_infill_order))
|
||||
((ConfigOptionBool, precise_outer_wall))
|
||||
((ConfigOptionBool, overhang_speed_classic))
|
||||
((ConfigOptionPercent, bridge_density))
|
||||
((ConfigOptionFloat, filter_out_gap_fill))
|
||||
((ConfigOptionFloatOrPercent, small_perimeter_speed))
|
||||
((ConfigOptionFloat, small_perimeter_threshold))
|
||||
((ConfigOptionFloat, top_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloat, bottom_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloatOrPercent, infill_anchor))
|
||||
((ConfigOptionFloatOrPercent, infill_anchor_max))
|
||||
|
||||
// Orca
|
||||
((ConfigOptionBool, make_overhang_printable))
|
||||
)
|
||||
((ConfigOptionBool, enable_overhang_speed))
|
||||
((ConfigOptionFloat, overhang_1_4_speed))
|
||||
((ConfigOptionFloat, overhang_2_4_speed))
|
||||
((ConfigOptionFloat, overhang_3_4_speed))
|
||||
((ConfigOptionFloat, overhang_4_4_speed))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_anchor))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_anchor_max))
|
||||
//OrcaSlicer
|
||||
((ConfigOptionFloat, top_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloat, initial_layer_flow_ratio))
|
||||
((ConfigOptionFloat, filter_out_gap_fill))
|
||||
//calib
|
||||
((ConfigOptionFloat, print_flow_ratio)))
|
||||
|
||||
PRINT_CONFIG_CLASS_DEFINE(
|
||||
MachineEnvelopeConfig,
|
||||
|
@ -850,9 +827,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloats, filament_flow_ratio))
|
||||
((ConfigOptionBools, enable_pressure_advance))
|
||||
((ConfigOptionFloats, pressure_advance))
|
||||
((ConfigOptionFloat, fan_kickstart))
|
||||
((ConfigOptionBool, fan_speedup_overhangs))
|
||||
((ConfigOptionFloat, fan_speedup_time))
|
||||
((ConfigOptionFloats, filament_diameter))
|
||||
((ConfigOptionFloats, filament_density))
|
||||
((ConfigOptionStrings, filament_type))
|
||||
|
@ -872,7 +846,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionBool, gcode_add_line_number))
|
||||
((ConfigOptionBool, bbl_bed_temperature_gcode))
|
||||
((ConfigOptionEnum<GCodeFlavor>, gcode_flavor))
|
||||
|
||||
((ConfigOptionString, layer_change_gcode))
|
||||
//#ifdef HAS_PRESSURE_EQUALIZER
|
||||
// ((ConfigOptionFloat, max_volumetric_extrusion_rate_slope_positive))
|
||||
|
@ -884,9 +857,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloats, z_hop))
|
||||
// BBS
|
||||
((ConfigOptionEnumsGeneric, z_hop_types))
|
||||
((ConfigOptionFloats, retract_lift_above))
|
||||
((ConfigOptionFloats, retract_lift_below))
|
||||
((ConfigOptionEnumsGeneric, retract_lift_enforce))
|
||||
((ConfigOptionFloats, retract_restart_extra))
|
||||
((ConfigOptionFloats, retract_restart_extra_toolchange))
|
||||
((ConfigOptionFloats, retraction_speed))
|
||||
|
@ -897,21 +867,16 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionString, change_filament_gcode))
|
||||
((ConfigOptionFloat, travel_speed))
|
||||
((ConfigOptionFloat, travel_speed_z))
|
||||
((ConfigOptionBool, use_relative_e_distances))
|
||||
((ConfigOptionBool, silent_mode))
|
||||
((ConfigOptionString, machine_pause_gcode))
|
||||
((ConfigOptionString, template_custom_gcode))
|
||||
//BBS
|
||||
((ConfigOptionEnum<NozzleType>, nozzle_type))
|
||||
((ConfigOptionInt, nozzle_hrc))
|
||||
((ConfigOptionBool, auxiliary_fan))
|
||||
// SoftFever
|
||||
((ConfigOptionBool, use_firmware_retraction))
|
||||
((ConfigOptionBool, use_relative_e_distances))
|
||||
((ConfigOptionBool, accel_to_decel_enable))
|
||||
((ConfigOptionPercent, accel_to_decel_factor))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_travel_speed))
|
||||
((ConfigOptionBool, bbl_calib_mark_logo))
|
||||
|
||||
((ConfigOptionEnumsGeneric, extruder_type))
|
||||
)
|
||||
|
||||
// This object is mapped to Perl as Slic3r::Config::Print.
|
||||
|
@ -943,39 +908,30 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionInts, first_layer_print_sequence))
|
||||
((ConfigOptionBools, slow_down_for_layer_cooling))
|
||||
((ConfigOptionFloat, default_acceleration))
|
||||
((ConfigOptionFloat, inner_wall_acceleration))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_acceleration))
|
||||
((ConfigOptionInts, close_fan_the_first_x_layers))
|
||||
((ConfigOptionEnum<DraftShield>, draft_shield))
|
||||
((ConfigOptionFloat, extruder_clearance_height_to_rod))//BBs
|
||||
((ConfigOptionFloat, extruder_clearance_height_to_lid))//BBS
|
||||
((ConfigOptionFloat, extruder_clearance_radius))
|
||||
((ConfigOptionFloat, extruder_clearance_max_radius))
|
||||
((ConfigOptionStrings, extruder_colour))
|
||||
((ConfigOptionPoints, extruder_offset))
|
||||
((ConfigOptionBools, reduce_fan_stop_start_freq))
|
||||
((ConfigOptionFloats, fan_cooling_layer_time))
|
||||
((ConfigOptionInts, fan_cooling_layer_time))
|
||||
((ConfigOptionStrings, filament_colour))
|
||||
((ConfigOptionFloat, outer_wall_acceleration))
|
||||
((ConfigOptionFloat, inner_wall_acceleration))
|
||||
((ConfigOptionFloat, top_surface_acceleration))
|
||||
((ConfigOptionFloat, outer_wall_acceleration))
|
||||
((ConfigOptionFloat, initial_layer_acceleration))
|
||||
((ConfigOptionFloatOrPercent, bridge_acceleration))
|
||||
((ConfigOptionFloat, travel_acceleration))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_acceleration))
|
||||
((ConfigOptionFloatOrPercent, internal_solid_infill_acceleration))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_line_width))
|
||||
((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, infill_jerk))
|
||||
((ConfigOptionFloat, top_surface_jerk))
|
||||
((ConfigOptionFloat, initial_layer_jerk))
|
||||
((ConfigOptionFloat, travel_jerk))
|
||||
|
||||
//BBS
|
||||
((ConfigOptionFloat, initial_layer_infill_speed))
|
||||
((ConfigOptionInts, nozzle_temperature_initial_layer))
|
||||
((ConfigOptionInts, full_fan_speed_layer))
|
||||
((ConfigOptionEnum<WallInfillOrder>,wall_infill_order))
|
||||
((ConfigOptionInts, fan_max_speed))
|
||||
((ConfigOptionFloats, max_layer_height))
|
||||
((ConfigOptionInts, fan_min_speed))
|
||||
|
@ -994,12 +950,11 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionFloat, skirt_distance))
|
||||
((ConfigOptionInt, skirt_height))
|
||||
((ConfigOptionInt, skirt_loops))
|
||||
((ConfigOptionFloat, skirt_speed))
|
||||
((ConfigOptionFloats, slow_down_layer_time))
|
||||
((ConfigOptionInts, slow_down_layer_time))
|
||||
((ConfigOptionBool, spiral_mode))
|
||||
((ConfigOptionInt, standby_temperature_delta))
|
||||
((ConfigOptionInts, nozzle_temperature))
|
||||
((ConfigOptionInts , chamber_temperature))
|
||||
((ConfigOptionInts, chamber_temperatures))
|
||||
((ConfigOptionBools, wipe))
|
||||
// BBS
|
||||
((ConfigOptionInts, bed_temperature_difference))
|
||||
|
@ -1028,18 +983,17 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionFloat, nozzle_volume))
|
||||
((ConfigOptionPoints, start_end_points))
|
||||
((ConfigOptionEnum<TimelapseType>, timelapse_type))
|
||||
((ConfigOptionPoints, thumbnails))
|
||||
((ConfigOptionFloat, default_jerk))
|
||||
((ConfigOptionFloat, outer_wall_jerk))
|
||||
((ConfigOptionFloat, inner_wall_jerk))
|
||||
((ConfigOptionFloat, infill_jerk))
|
||||
((ConfigOptionFloat, top_surface_jerk))
|
||||
((ConfigOptionFloat, initial_layer_jerk))
|
||||
((ConfigOptionFloat, travel_jerk))
|
||||
|
||||
// BBS: move from PrintObjectConfig
|
||||
((ConfigOptionBool, independent_support_layer_height))
|
||||
// SoftFever
|
||||
((ConfigOptionPercents, filament_shrink))
|
||||
((ConfigOptionBool, gcode_label_objects))
|
||||
((ConfigOptionBool, exclude_object))
|
||||
((ConfigOptionBool, gcode_comments))
|
||||
((ConfigOptionInt, slow_down_layers))
|
||||
((ConfigOptionInts, support_material_interface_fan_speed))
|
||||
|
||||
|
||||
((ConfigOptionBool, independent_support_layer_height))
|
||||
((ConfigOptionBool, exclude_object))
|
||||
)
|
||||
|
||||
// This object is mapped to Perl as Slic3r::Config::Full.
|
||||
|
@ -1408,12 +1362,7 @@ public:
|
|||
const ConfigOption* option(const t_config_option_key &opt_key) const { return m_data.option(opt_key); }
|
||||
int opt_int(const t_config_option_key &opt_key) const { return m_data.opt_int(opt_key); }
|
||||
int extruder() const { return opt_int("extruder"); }
|
||||
double opt_float(const t_config_option_key &opt_key) const {
|
||||
return m_data.opt_float(opt_key);
|
||||
}
|
||||
double get_abs_value(const t_config_option_key &opt_key) const {
|
||||
return m_data.get_abs_value(opt_key);
|
||||
}
|
||||
double opt_float(const t_config_option_key &opt_key) const { return m_data.opt_float(opt_key); }
|
||||
std::string opt_serialize(const t_config_option_key &opt_key) const { return m_data.opt_serialize(opt_key); }
|
||||
|
||||
// Return an optional timestamp of this object.
|
||||
|
|
|
@ -423,10 +423,7 @@ static const float g_min_overhang_percent_for_lift = 0.3f;
|
|||
void PrintObject::detect_overhangs_for_lift()
|
||||
{
|
||||
if (this->set_started(posDetectOverhangsForLift)) {
|
||||
const double nozzle_diameter = m_print->config().nozzle_diameter.get_at(0);
|
||||
const coordf_t line_width = this->config().get_abs_value("line_width", nozzle_diameter);
|
||||
|
||||
const float min_overlap = line_width * g_min_overhang_percent_for_lift;
|
||||
const float min_overlap = m_config.line_width * g_min_overhang_percent_for_lift;
|
||||
size_t num_layers = this->layer_count();
|
||||
size_t num_raft_layers = m_slicing_params.raft_layers();
|
||||
|
||||
|
@ -436,18 +433,17 @@ void PrintObject::detect_overhangs_for_lift()
|
|||
|
||||
tbb::spin_mutex layer_storage_mutex;
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(num_raft_layers + 1, num_layers),
|
||||
[this, min_overlap, line_width](const tbb::blocked_range<size_t>& range)
|
||||
[this, min_overlap](const tbb::blocked_range<size_t>& range)
|
||||
{
|
||||
for (size_t layer_id = range.begin(); layer_id < range.end(); ++layer_id) {
|
||||
Layer& layer = *m_layers[layer_id];
|
||||
Layer& lower_layer = *layer.lower_layer;
|
||||
|
||||
ExPolygons overhangs = diff_ex(layer.lslices, offset_ex(lower_layer.lslices, scale_(min_overlap)));
|
||||
layer.loverhangs = std::move(offset2_ex(overhangs, -0.1f * scale_(line_width), 0.1f * scale_(line_width)));
|
||||
layer.loverhangs = std::move(offset2_ex(overhangs, -0.1f * scale_(m_config.line_width), 0.1f * scale_(m_config.line_width)));
|
||||
layer.loverhangs_bbox = get_extents(layer.loverhangs);
|
||||
}
|
||||
});
|
||||
|
||||
this->set_done(posDetectOverhangsForLift);
|
||||
}
|
||||
}
|
||||
|
@ -499,10 +495,10 @@ void PrintObject::generate_support_material()
|
|||
|
||||
void PrintObject::simplify_extrusion_path()
|
||||
{
|
||||
if (this->set_started(posSimplifyPath)) {
|
||||
if (this->set_started(posSimplifyWall)) {
|
||||
m_print->set_status(75, L("Optimizing toolpath"));
|
||||
BOOST_LOG_TRIVIAL(debug) << "Simplify extrusion path of object in parallel - start";
|
||||
//BBS: infill and walls
|
||||
BOOST_LOG_TRIVIAL(debug) << "Simplify wall extrusion path of object in parallel - start";
|
||||
//BBS: walls
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||
[this](const tbb::blocked_range<size_t>& range) {
|
||||
|
@ -514,7 +510,7 @@ void PrintObject::simplify_extrusion_path()
|
|||
);
|
||||
m_print->throw_if_canceled();
|
||||
BOOST_LOG_TRIVIAL(debug) << "Simplify wall extrusion path of object in parallel - end";
|
||||
this->set_done(posSimplifyPath);
|
||||
this->set_done(posSimplifyWall);
|
||||
}
|
||||
|
||||
if (this->set_started(posSimplifyInfill)) {
|
||||
|
@ -694,12 +690,8 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
if ( opt_key == "brim_width"
|
||||
|| opt_key == "brim_object_gap"
|
||||
|| opt_key == "brim_type"
|
||||
|| opt_key == "brim_ears_max_angle"
|
||||
|| opt_key == "brim_ears_detection_length"
|
||||
// BBS: brim generation depends on printing speed
|
||||
|| opt_key == "outer_wall_speed"
|
||||
|| opt_key == "small_perimeter_speed"
|
||||
|| opt_key == "small_perimeter_threshold"
|
||||
|| opt_key == "sparse_infill_speed"
|
||||
|| opt_key == "inner_wall_speed"
|
||||
|| opt_key == "support_speed"
|
||||
|
@ -717,18 +709,13 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
}
|
||||
} else if (
|
||||
opt_key == "wall_loops"
|
||||
|| opt_key == "only_one_wall_top"
|
||||
|| opt_key == "top_one_wall_type"
|
||||
|| opt_key == "only_one_wall_first_layer"
|
||||
|| opt_key == "initial_layer_line_width"
|
||||
|| opt_key == "inner_wall_line_width"
|
||||
|| opt_key == "infill_wall_overlap"
|
||||
|| opt_key == "seam_gap"
|
||||
|| opt_key == "role_based_wipe_speed"
|
||||
|| opt_key == "wipe_on_loops"
|
||||
|| opt_key == "wipe_speed") {
|
||||
|| opt_key == "infill_wall_overlap") {
|
||||
steps.emplace_back(posPerimeters);
|
||||
} else if (opt_key == "gap_infill_speed"
|
||||
|| opt_key == "filter_out_gap_fill" ) {
|
||||
} else if (opt_key == "gap_infill_speed" || opt_key == "filter_out_gap_fill") {
|
||||
// Return true if gap-fill speed has changed from zero value to non-zero or from non-zero value to zero.
|
||||
auto is_gap_fill_changed_state_due_to_speed = [&opt_key, &old_config, &new_config]() -> bool {
|
||||
if (opt_key == "gap_infill_speed") {
|
||||
|
@ -742,9 +729,9 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
};
|
||||
|
||||
// Filtering of unprintable regions in multi-material segmentation depends on if gap-fill is enabled or not.
|
||||
// So step posSlice is invalidated when gap-fill was enabled/disabled by option "filter_out_gap_fill" or by
|
||||
// So step posSlice is invalidated when gap-fill was enabled/disabled by option "gap_fill_enabled" or by
|
||||
// changing "gap_infill_speed" to force recomputation of the multi-material segmentation.
|
||||
if (this->is_mm_painted() && (opt_key == "filter_out_gap_fill" && (opt_key == "gap_infill_speed" && is_gap_fill_changed_state_due_to_speed())))
|
||||
if (this->is_mm_painted() && ((opt_key == "gap_infill_speed" || opt_key == "filter_out_gap_fill") && is_gap_fill_changed_state_due_to_speed()))
|
||||
steps.emplace_back(posSlice);
|
||||
steps.emplace_back(posPerimeters);
|
||||
} else if (
|
||||
|
@ -752,24 +739,14 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
|| opt_key == "raft_layers"
|
||||
|| opt_key == "raft_contact_distance"
|
||||
|| opt_key == "slice_closing_radius"
|
||||
|| opt_key == "slicing_mode"
|
||||
|| opt_key == "make_overhang_printable"
|
||||
|| opt_key == "make_overhang_printable_angle"
|
||||
|| opt_key == "make_overhang_printable_hole_size") {
|
||||
|| opt_key == "slicing_mode") {
|
||||
steps.emplace_back(posSlice);
|
||||
} else if (
|
||||
opt_key == "elefant_foot_compensation"
|
||||
|| opt_key == "support_top_z_distance"
|
||||
|| opt_key == "support_bottom_z_distance"
|
||||
|| opt_key == "xy_hole_compensation"
|
||||
|| opt_key == "xy_contour_compensation"
|
||||
//BBS: [Arthur] the following params affect bottomBridge surface type detection
|
||||
|| opt_key == "support_type"
|
||||
|| opt_key == "bridge_no_support"
|
||||
|| opt_key == "max_bridge_length"
|
||||
|| opt_key == "support_interface_top_layers"
|
||||
|| opt_key == "support_critical_regions_only"
|
||||
) {
|
||||
|| opt_key == "xy_contour_compensation") {
|
||||
steps.emplace_back(posSlice);
|
||||
} else if (opt_key == "enable_support") {
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
|
@ -809,12 +786,10 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
|| opt_key == "bridge_no_support"
|
||||
|| opt_key == "max_bridge_length"
|
||||
|| opt_key == "initial_layer_line_width"
|
||||
|| opt_key == "tree_support_adaptive_layer_height"
|
||||
|| opt_key == "tree_support_auto_brim"
|
||||
|| opt_key == "tree_support_brim_width"
|
||||
|| opt_key == "tree_support_branch_distance"
|
||||
|| opt_key == "tree_support_branch_diameter"
|
||||
|| opt_key == "tree_support_branch_angle"
|
||||
|| opt_key == "tree_support_brim_width"
|
||||
|| opt_key == "tree_support_wall_count") {
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
} else if (
|
||||
|
@ -847,21 +822,19 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
|| opt_key == "sparse_infill_filament"
|
||||
|| opt_key == "solid_infill_filament"
|
||||
|| opt_key == "sparse_infill_line_width"
|
||||
|| opt_key == "infill_direction"
|
||||
|| opt_key == "ensure_vertical_shell_thickness"
|
||||
|| opt_key == "bridge_angle"
|
||||
//BBS
|
||||
|| opt_key == "internal_bridge_support_thickness"
|
||||
|| opt_key == "bridge_density") {
|
||||
|| opt_key == "internal_bridge_support_thickness") {
|
||||
steps.emplace_back(posPrepareInfill);
|
||||
} else if (
|
||||
opt_key == "top_surface_pattern"
|
||||
|| opt_key == "bottom_surface_pattern"
|
||||
|| opt_key == "internal_solid_infill_pattern"
|
||||
|| opt_key == "external_fill_link_max_length"
|
||||
|| opt_key == "sparse_infill_pattern"
|
||||
|| opt_key == "infill_anchor"
|
||||
|| opt_key == "infill_anchor_max"
|
||||
|| opt_key == "infill_direction"
|
||||
|| opt_key == "sparse_infill_anchor"
|
||||
|| opt_key == "sparse_infill_anchor_max"
|
||||
|| opt_key == "top_surface_line_width"
|
||||
|| opt_key == "initial_layer_line_width") {
|
||||
steps.emplace_back(posInfill);
|
||||
|
@ -898,9 +871,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
|| opt_key == "detect_overhang_wall"
|
||||
//BBS
|
||||
|| opt_key == "enable_overhang_speed"
|
||||
|| opt_key == "detect_thin_wall"
|
||||
|| opt_key == "precise_outer_wall"
|
||||
|| opt_key == "overhang_speed_classic") {
|
||||
|| opt_key == "detect_thin_wall") {
|
||||
steps.emplace_back(posPerimeters);
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
} else if (opt_key == "bridge_flow") {
|
||||
|
@ -922,6 +893,8 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
steps.emplace_back(posSlice);
|
||||
} else if (
|
||||
opt_key == "seam_position"
|
||||
|| opt_key == "seam_gap"
|
||||
|| opt_key == "wipe_speed"
|
||||
|| opt_key == "support_speed"
|
||||
|| opt_key == "support_interface_speed"
|
||||
|| opt_key == "overhang_1_4_speed"
|
||||
|
@ -929,10 +902,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
|| opt_key == "overhang_3_4_speed"
|
||||
|| opt_key == "overhang_4_4_speed"
|
||||
|| opt_key == "bridge_speed"
|
||||
|| opt_key == "internal_bridge_speed"
|
||||
|| opt_key == "outer_wall_speed"
|
||||
|| opt_key == "small_perimeter_speed"
|
||||
|| opt_key == "small_perimeter_threshold"
|
||||
|| opt_key == "sparse_infill_speed"
|
||||
|| opt_key == "inner_wall_speed"
|
||||
|| opt_key == "internal_solid_infill_speed"
|
||||
|
@ -963,15 +933,15 @@ bool PrintObject::invalidate_step(PrintObjectStep step)
|
|||
|
||||
// propagate to dependent steps
|
||||
if (step == posPerimeters) {
|
||||
invalidated |= this->invalidate_steps({ posPrepareInfill, posInfill, posIroning, posSimplifyPath, posSimplifyInfill });
|
||||
invalidated |= this->invalidate_steps({ posPrepareInfill, posInfill, posIroning, posSimplifyWall, posSimplifyInfill });
|
||||
invalidated |= m_print->invalidate_steps({ psSkirtBrim });
|
||||
} else if (step == posPrepareInfill) {
|
||||
invalidated |= this->invalidate_steps({ posInfill, posIroning, posSimplifyPath, posSimplifyInfill });
|
||||
invalidated |= this->invalidate_steps({ posInfill, posIroning, posSimplifyWall, posSimplifyInfill });
|
||||
} else if (step == posInfill) {
|
||||
invalidated |= this->invalidate_steps({ posIroning, posSimplifyInfill });
|
||||
invalidated |= m_print->invalidate_steps({ psSkirtBrim });
|
||||
} else if (step == posSlice) {
|
||||
invalidated |= this->invalidate_steps({ posPerimeters, posPrepareInfill, posInfill, posIroning, posSupportMaterial, posSimplifyPath, posSimplifyInfill });
|
||||
invalidated |= this->invalidate_steps({ posPerimeters, posPrepareInfill, posInfill, posIroning, posSupportMaterial, posSimplifyWall, posSimplifyInfill });
|
||||
invalidated |= m_print->invalidate_steps({ psSkirtBrim });
|
||||
m_slicing_params.valid = false;
|
||||
} else if (step == posSupportMaterial) {
|
||||
|
@ -2646,7 +2616,6 @@ SupportNecessaryType PrintObject::is_support_necessary()
|
|||
#if 0
|
||||
double threshold_rad = (m_config.support_threshold_angle.value < EPSILON ? 30 : m_config.support_threshold_angle.value + 1) * M_PI / 180.;
|
||||
int enforce_support_layers = m_config.enforce_support_layers;
|
||||
// not fixing in extrusion width % PR b/c never called
|
||||
const coordf_t extrusion_width = m_config.line_width.value;
|
||||
const coordf_t extrusion_width_scaled = scale_(extrusion_width);
|
||||
float max_bridge_length = scale_(m_config.max_bridge_length.value);
|
||||
|
|
|
@ -164,27 +164,27 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||
// Convert layer_config_ranges to layer_height_profile. Both are referenced to z=0, meaning the raft layers are not accounted for
|
||||
// in the height profile and the printed object may be lifted by the raft thickness at the time of the G-code generation.
|
||||
std::vector<coordf_t> layer_height_profile_from_ranges(
|
||||
const SlicingParameters &slicing_params,
|
||||
const t_layer_config_ranges &layer_config_ranges)
|
||||
const SlicingParameters& slicing_params,
|
||||
const t_layer_config_ranges& layer_config_ranges)
|
||||
{
|
||||
// 1) If there are any height ranges, trim one by the other to make them non-overlapping. Insert the 1st layer if fixed.
|
||||
std::vector<std::pair<t_layer_height_range,coordf_t>> ranges_non_overlapping;
|
||||
std::vector<std::pair<t_layer_height_range, coordf_t>> ranges_non_overlapping;
|
||||
ranges_non_overlapping.reserve(layer_config_ranges.size() * 4);
|
||||
if (slicing_params.first_object_layer_height_fixed())
|
||||
ranges_non_overlapping.push_back(std::pair<t_layer_height_range,coordf_t>(
|
||||
t_layer_height_range(0., slicing_params.first_object_layer_height),
|
||||
ranges_non_overlapping.push_back(std::pair<t_layer_height_range, coordf_t>(
|
||||
t_layer_height_range(0., slicing_params.first_object_layer_height),
|
||||
slicing_params.first_object_layer_height));
|
||||
// The height ranges are sorted lexicographically by low / high layer boundaries.
|
||||
for (t_layer_config_ranges::const_iterator it_range = layer_config_ranges.begin(); it_range != layer_config_ranges.end(); ++ it_range) {
|
||||
for (t_layer_config_ranges::const_iterator it_range = layer_config_ranges.begin(); it_range != layer_config_ranges.end(); ++it_range) {
|
||||
coordf_t lo = it_range->first.first;
|
||||
coordf_t hi = std::min(it_range->first.second, slicing_params.object_print_z_height());
|
||||
coordf_t height = it_range->second.option("layer_height")->getFloat();
|
||||
if (! ranges_non_overlapping.empty())
|
||||
if (!ranges_non_overlapping.empty())
|
||||
// Trim current low with the last high.
|
||||
lo = std::max(lo, ranges_non_overlapping.back().first.second);
|
||||
if (lo + EPSILON < hi)
|
||||
// Ignore too narrow ranges.
|
||||
ranges_non_overlapping.push_back(std::pair<t_layer_height_range,coordf_t>(t_layer_height_range(lo, hi), height));
|
||||
ranges_non_overlapping.push_back(std::pair<t_layer_height_range, coordf_t>(t_layer_height_range(lo, hi), height));
|
||||
}
|
||||
|
||||
// 2) Convert the trimmed ranges to a height profile, fill in the undefined intervals between z=0 and z=slicing_params.object_print_z_max()
|
||||
|
@ -233,7 +233,7 @@ std::vector<coordf_t> layer_height_profile_from_ranges(
|
|||
lh_append(slicing_params.object_print_z_height(), slicing_params.layer_height);
|
||||
}
|
||||
|
||||
return layer_height_profile;
|
||||
return layer_height_profile;
|
||||
}
|
||||
|
||||
// Based on the work of @platsch
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#define TAU (2.0 * M_PI)
|
||||
#define NO_INDEX (std::numeric_limits<unsigned int>::max())
|
||||
|
||||
// #define SUPPORT_TREE_DEBUG_TO_SVG
|
||||
//#define SUPPORT_TREE_DEBUG_TO_SVG
|
||||
|
||||
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
|
||||
#include "nlohmann/json.hpp"
|
||||
|
@ -687,12 +687,12 @@ TreeSupport::TreeSupport(PrintObject& object, const SlicingParameters &slicing_p
|
|||
m_object_config->support_interface_pattern == smipConcentric ?
|
||||
ipConcentric :
|
||||
(m_support_params.interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
||||
|
||||
const auto nozzle_diameter = object.print()->config().nozzle_diameter.get_at(object.config().support_interface_filament-1);
|
||||
const coordf_t extrusion_width = m_object_config->line_width.get_abs_value(nozzle_diameter);
|
||||
const coordf_t support_extrusion_width = m_object_config->support_line_width.get_abs_value(nozzle_diameter);
|
||||
|
||||
m_support_params.support_extrusion_width = support_extrusion_width > 0 ? support_extrusion_width : extrusion_width;
|
||||
m_support_params.support_extrusion_width = m_object_config->support_line_width.value > 0 ? m_object_config->support_line_width : m_object_config->line_width;
|
||||
// Check if set to zero, use default if so.
|
||||
if (m_support_params.support_extrusion_width <= 0.0) {
|
||||
const auto nozzle_diameter = object.print()->config().nozzle_diameter.get_at(object.config().support_interface_filament - 1);
|
||||
m_support_params.support_extrusion_width = Flow::auto_extrusion_width(FlowRole::frSupportMaterial, (float)nozzle_diameter);
|
||||
}
|
||||
is_slim = is_tree_slim(support_type, support_style);
|
||||
is_strong = is_tree(support_type) && support_style == smsTreeStrong;
|
||||
MAX_BRANCH_RADIUS = 10.0;
|
||||
|
@ -726,8 +726,7 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
|
|||
const PrintObjectConfig& config = m_object->config();
|
||||
SupportType stype = support_type;
|
||||
const coordf_t radius_sample_resolution = g_config_tree_support_collision_resolution;
|
||||
const double nozzle_diameter = m_object->print()->config().nozzle_diameter.get_at(0);
|
||||
const coordf_t extrusion_width = config.get_abs_value("line_width", nozzle_diameter);
|
||||
const coordf_t extrusion_width = config.line_width.value;
|
||||
const coordf_t extrusion_width_scaled = scale_(extrusion_width);
|
||||
const coordf_t max_bridge_length = scale_(config.max_bridge_length.value);
|
||||
const bool bridge_no_support = max_bridge_length > 0;
|
||||
|
@ -1405,10 +1404,6 @@ void TreeSupport::generate_toolpaths()
|
|||
coordf_t layer_height = object_config.layer_height.value;
|
||||
const size_t wall_count = object_config.tree_support_wall_count.value;
|
||||
|
||||
// Check if set to zero, use default if so.
|
||||
if (support_extrusion_width <= 0.0)
|
||||
support_extrusion_width = Flow::auto_extrusion_width(FlowRole::frSupportMaterial, (float)nozzle_diameter);
|
||||
|
||||
// coconut: use same intensity settings as SupportMaterial.cpp
|
||||
auto m_support_material_interface_flow = support_material_interface_flow(m_object, float(m_slicing_params.layer_height));
|
||||
coordf_t interface_spacing = object_config.support_interface_spacing.value + m_support_material_interface_flow.spacing();
|
||||
|
@ -1908,10 +1903,10 @@ void TreeSupport::generate()
|
|||
|
||||
smooth_nodes(contact_nodes);
|
||||
|
||||
if (!m_object->config().tree_support_adaptive_layer_height)
|
||||
// Adjust support layer heights
|
||||
adjust_layer_heights(contact_nodes);
|
||||
|
||||
#if !USE_PLAN_LAYER_HEIGHTS
|
||||
// Adjust support layer heights
|
||||
adjust_layer_heights(contact_nodes);
|
||||
#endif
|
||||
|
||||
//Generate support areas.
|
||||
profiler.stage_start(STAGE_DRAW_CIRCLES);
|
||||
|
@ -2116,13 +2111,11 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
|
|||
const size_t top_interface_layers = config.support_interface_top_layers.value;
|
||||
const size_t bottom_interface_layers = config.support_interface_bottom_layers.value;
|
||||
const double diameter_angle_scale_factor = tan(tree_support_branch_diameter_angle * M_PI / 180.);// * layer_height / branch_radius; //Scale factor per layer to produce the desired angle.
|
||||
const double nozzle_diameter = m_object->print()->config().nozzle_diameter.get_at(0);
|
||||
const coordf_t line_width = config.get_abs_value("support_line_width", nozzle_diameter);
|
||||
const coordf_t line_width_scaled = scale_(line_width);
|
||||
|
||||
const bool with_lightning_infill = m_support_params.base_fill_pattern == ipLightning;
|
||||
coordf_t support_extrusion_width = m_support_params.support_extrusion_width;
|
||||
const size_t wall_count = config.tree_support_wall_count.value;
|
||||
const coordf_t line_width_scaled = scale_(support_extrusion_width);
|
||||
const float tree_brim_width = config.tree_support_brim_width.value;
|
||||
|
||||
const PrintObjectConfig& object_config = m_object->config();
|
||||
BOOST_LOG_TRIVIAL(info) << "draw_circles for object: " << m_object->model_object()->name;
|
||||
|
@ -2212,11 +2205,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
|
|||
}
|
||||
}
|
||||
if (layer_nr == 0 && m_raft_layers == 0) {
|
||||
double brim_width =
|
||||
config.tree_support_auto_brim
|
||||
? layers_to_top * layer_height /
|
||||
(scale * branch_radius) * 0.5
|
||||
: config.tree_support_brim_width;
|
||||
double brim_width = tree_brim_width > 0 ? tree_brim_width : layers_to_top * layer_height / (scale * branch_radius) * 0.5;
|
||||
circle = offset(circle, scale_(brim_width))[0];
|
||||
}
|
||||
area.emplace_back(ExPolygon(circle));
|
||||
|
@ -2301,7 +2290,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
|
|||
if (SQUARE_SUPPORT) {
|
||||
// simplify support contours
|
||||
ExPolygons base_areas_simplified;
|
||||
for (auto &area : base_areas) { area.simplify(scale_(line_width / 2), &base_areas_simplified); }
|
||||
for (auto &area : base_areas) { area.simplify(scale_(support_extrusion_width / 2), &base_areas_simplified); }
|
||||
base_areas = std::move(base_areas_simplified);
|
||||
}
|
||||
//Subtract support floors. We can only compute floor_areas here instead of with roof_areas,
|
||||
|
@ -2580,14 +2569,12 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
|
|||
const size_t bottom_interface_layers = config.support_interface_bottom_layers.value;
|
||||
const size_t top_interface_layers = config.support_interface_top_layers.value;
|
||||
float DO_NOT_MOVER_UNDER_MM = is_slim ? 0 : 5; // do not move contact points under 5mm
|
||||
const auto nozzle_diameter = m_object->print()->config().nozzle_diameter.get_at(m_object->config().support_interface_filament-1);
|
||||
const auto support_line_width = config.support_line_width.get_abs_value(nozzle_diameter);
|
||||
|
||||
auto get_branch_angle = [this,&config](coordf_t radius) {
|
||||
if (config.tree_support_branch_angle.value < 30.0) return config.tree_support_branch_angle.value;
|
||||
return (radius - MIN_BRANCH_RADIUS) / (MAX_BRANCH_RADIUS - MIN_BRANCH_RADIUS) * (config.tree_support_branch_angle.value - 30.0) + 30.0;
|
||||
};
|
||||
auto get_max_move_dist = [this, &config, branch_radius, tip_layers, diameter_angle_scale_factor, wall_count, support_extrusion_width, support_line_width](const Node *node, int power = 1) {
|
||||
auto get_max_move_dist = [this, &config, branch_radius, tip_layers, diameter_angle_scale_factor, wall_count, support_extrusion_width](const Node *node, int power = 1) {
|
||||
double move_dist = node->max_move_dist;
|
||||
if (node->max_move_dist == 0) {
|
||||
if (node->radius == 0) node->radius = calc_branch_radius(branch_radius, node->dist_mm_to_top, diameter_angle_scale_factor);
|
||||
|
@ -2595,7 +2582,7 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
|
|||
if (angle > 30.0 && node->radius > MIN_BRANCH_RADIUS)
|
||||
angle = (node->radius - MIN_BRANCH_RADIUS) / (MAX_BRANCH_RADIUS - MIN_BRANCH_RADIUS) * (config.tree_support_branch_angle.value - 30.0) + 30.0;
|
||||
double tan_angle = tan(angle * M_PI / 180);
|
||||
int wall_count_ = node->radius > 2 * support_line_width ? wall_count : 1;
|
||||
int wall_count_ = node->radius > 2 * support_extrusion_width ? wall_count : 1;
|
||||
node->max_move_dist = (angle < 90) ? (coordf_t) (tan_angle * node->height) * wall_count_ : std::numeric_limits<coordf_t>::max();
|
||||
node->max_move_dist = std::min(node->max_move_dist, support_extrusion_width);
|
||||
move_dist = node->max_move_dist;
|
||||
|
@ -3075,7 +3062,7 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "after m_avoidance_cache.size()=" << m_ts_data->m_avoidance_cache.size();
|
||||
|
||||
for (Node *node : to_free_node_set)
|
||||
|
@ -3282,7 +3269,7 @@ std::vector<LayerHeightData> TreeSupport::plan_layer_heights(std::vector<std::ve
|
|||
std::vector<LayerHeightData> layer_heights(contact_nodes.size());
|
||||
std::vector<int> bounds;
|
||||
|
||||
if (!config.tree_support_adaptive_layer_height || layer_height == max_layer_height || !print_config.independent_support_layer_height) {
|
||||
if (!USE_PLAN_LAYER_HEIGHTS || layer_height == max_layer_height || !print_config.independent_support_layer_height) {
|
||||
for (int layer_nr = 0; layer_nr < contact_nodes.size(); layer_nr++) {
|
||||
layer_heights[layer_nr] = {m_object->get_layer(layer_nr)->print_z, m_object->get_layer(layer_nr)->height, layer_nr > 0 ? size_t(layer_nr - 1) : 0};
|
||||
}
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/date_time.hpp>
|
||||
#include "boost/date_time/posix_time/ptime.hpp"
|
||||
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include "libslic3r.h"
|
||||
|
@ -558,21 +554,6 @@ inline std::string get_bbl_monitor_time_dhm(float time_in_secs)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
inline std::string get_bbl_monitor_end_time_dhm(float time_in_secs)
|
||||
{
|
||||
if (time_in_secs == 0.0f)
|
||||
return {};
|
||||
|
||||
std::stringstream stream;
|
||||
boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
|
||||
auto endTime = now + boost::posix_time::seconds(static_cast<int>(time_in_secs));
|
||||
auto facet = new boost::posix_time::time_facet("%H:%M");//%Y-%m-%d %H:%M:%S
|
||||
stream.imbue(std::locale(std::locale::classic(), facet));
|
||||
stream << endTime;
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
inline std::string get_bbl_remain_time_dhms(float time_in_secs)
|
||||
{
|
||||
int days = (int) (time_in_secs / 86400.0f);
|
||||
|
@ -610,9 +591,6 @@ inline std::string filter_characters(const std::string& str, const std::string&
|
|||
return filteredStr;
|
||||
}
|
||||
|
||||
void copy_directory_recursively(const boost::filesystem::path &source, const boost::filesystem::path &target);
|
||||
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#if WIN32
|
||||
|
|
|
@ -2,18 +2,29 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
|
||||
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance)
|
||||
{
|
||||
ExtrusionPaths paths;
|
||||
ExtrusionPath path(role);
|
||||
ThickLines lines = thick_polyline.thicklines();
|
||||
|
||||
ExtrusionMultiPath multi_path;
|
||||
ExtrusionPath path(role);
|
||||
ThickLines lines = thick_polyline.thicklines();
|
||||
|
||||
for (int i = 0; i < (int)lines.size(); ++i) {
|
||||
const ThickLine& line = lines[i];
|
||||
assert(line.a_width >= SCALED_EPSILON && line.b_width >= SCALED_EPSILON);
|
||||
|
||||
const coordf_t line_len = line.length();
|
||||
if (line_len < SCALED_EPSILON) continue;
|
||||
if (line_len < SCALED_EPSILON) {
|
||||
// The line is so tiny that we don't care about its width when we connect it to another line.
|
||||
if (!path.empty())
|
||||
path.polyline.points.back() = line.b; // If the variable path is non-empty, connect this tiny line to it.
|
||||
else if (i + 1 < (int)lines.size()) // If there is at least one following line, connect this tiny line to it.
|
||||
lines[i + 1].a = line.a;
|
||||
else if (!multi_path.paths.empty())
|
||||
multi_path.paths.back().polyline.points.back() = line.b; // Connect this tiny line to the last finished path.
|
||||
|
||||
// If any of the above isn't satisfied, then remove this tiny line.
|
||||
continue;
|
||||
}
|
||||
|
||||
double thickness_delta = fabs(line.a_width - line.b_width);
|
||||
if (thickness_delta > tolerance) {
|
||||
|
@ -73,15 +84,15 @@ ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_poly
|
|||
path.polyline.append(line.b);
|
||||
} else {
|
||||
// we need to initialize a new line
|
||||
paths.emplace_back(std::move(path));
|
||||
multi_path.paths.emplace_back(std::move(path));
|
||||
path = ExtrusionPath(role);
|
||||
-- i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (path.polyline.is_valid())
|
||||
paths.emplace_back(std::move(path));
|
||||
return paths;
|
||||
multi_path.paths.emplace_back(std::move(path));
|
||||
return multi_path;
|
||||
}
|
||||
|
||||
//BBS: new function to filter width to avoid too fragmented segments
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "Flow.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance);
|
||||
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance);
|
||||
void variable_width(const ThickPolylines& polylines, ExtrusionRole role, const Flow& flow, std::vector<ExtrusionEntity*>& out);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
#include "calib.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
#include "Calib.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include <cmath>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Calculate the optimal Pressure Advance speed
|
||||
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height,
|
||||
int filament_idx) {
|
||||
const double general_suggested_min_speed = 100.0;
|
||||
double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
|
||||
Flow pattern_line = Flow(line_width, layer_height, config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0));
|
||||
auto pa_speed = std::min(std::max(general_suggested_min_speed,config.option<ConfigOptionFloat>("outer_wall_speed")->value), filament_max_volumetric_speed / pattern_line.mm3_per_mm());
|
||||
namespace Slic3r {
|
||||
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx)
|
||||
{
|
||||
const double general_suggested_min_speed = 100.0;
|
||||
double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
|
||||
Flow pattern_line = Flow(line_width, layer_height, config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0));
|
||||
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloat>("outer_wall_speed")->value),
|
||||
filament_max_volumetric_speed / pattern_line.mm3_per_mm());
|
||||
|
||||
return std::floor(pa_speed);
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvance::move_to(Vec2d pt, GCodeWriter& writer, std::string comment)
|
||||
std::string CalibPressureAdvance::move_to(Vec2d pt, GCodeWriter &writer, std::string comment)
|
||||
{
|
||||
std::stringstream gcode;
|
||||
|
||||
|
@ -27,18 +27,12 @@ std::string CalibPressureAdvance::move_to(Vec2d pt, GCodeWriter& writer, std::st
|
|||
|
||||
m_last_pos = Vec3d(pt.x(), pt.y(), 0);
|
||||
|
||||
return gcode.str();
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
double CalibPressureAdvance::e_per_mm(
|
||||
double line_width,
|
||||
double layer_height,
|
||||
float nozzle_diameter,
|
||||
float filament_diameter,
|
||||
float print_flow_ratio
|
||||
) const
|
||||
double CalibPressureAdvance::e_per_mm(double line_width, double layer_height, float nozzle_diameter, float filament_diameter, float print_flow_ratio) const
|
||||
{
|
||||
const Flow line_flow = Flow(line_width, layer_height, nozzle_diameter);
|
||||
const Flow line_flow = Flow(line_width, layer_height, nozzle_diameter);
|
||||
const double filament_area = M_PI * std::pow(filament_diameter / 2, 2);
|
||||
|
||||
return line_flow.mm3_per_mm() / filament_area * print_flow_ratio;
|
||||
|
@ -54,19 +48,12 @@ std::string CalibPressureAdvance::convert_number_to_string(double num) const
|
|||
}
|
||||
|
||||
std::string CalibPressureAdvance::draw_digit(
|
||||
double startx,
|
||||
double starty,
|
||||
char c,
|
||||
CalibPressureAdvance::DrawDigitMode mode,
|
||||
double line_width,
|
||||
double e_per_mm,
|
||||
GCodeWriter& writer
|
||||
)
|
||||
double startx, double starty, char c, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, GCodeWriter &writer)
|
||||
{
|
||||
const double len = m_digit_segment_len;
|
||||
const double gap = line_width / 2.0;
|
||||
|
||||
const auto dE = e_per_mm * len;
|
||||
const auto dE = e_per_mm * len;
|
||||
const auto two_dE = dE * 2;
|
||||
|
||||
Vec2d p0, p1, p2, p3, p4, p5;
|
||||
|
@ -79,33 +66,33 @@ std::string CalibPressureAdvance::draw_digit(
|
|||
// | | |
|
||||
// | | |
|
||||
// 0-------3-------4
|
||||
p0 = Vec2d(startx, starty);
|
||||
p0 = Vec2d(startx, starty);
|
||||
p0_5 = Vec2d(startx, starty + len / 2);
|
||||
p1 = Vec2d(startx, starty + len);
|
||||
p2 = Vec2d(startx + len, starty + len);
|
||||
p3 = Vec2d(startx + len, starty);
|
||||
p4 = Vec2d(startx + len * 2, starty);
|
||||
p1 = Vec2d(startx, starty + len);
|
||||
p2 = Vec2d(startx + len, starty + len);
|
||||
p3 = Vec2d(startx + len, starty);
|
||||
p4 = Vec2d(startx + len * 2, starty);
|
||||
p4_5 = Vec2d(startx + len * 2, starty + len / 2);
|
||||
p5 = Vec2d(startx + len * 2, starty + len);
|
||||
p5 = Vec2d(startx + len * 2, starty + len);
|
||||
|
||||
gap_p0_toward_p3 = p0 + Vec2d(gap, 0);
|
||||
gap_p2_toward_p3 = p2 + Vec2d(0, gap);
|
||||
|
||||
dot_direction = Vec2d(-len / 2, 0);
|
||||
} else {
|
||||
// 0-------1
|
||||
// 0-------1
|
||||
// | |
|
||||
// 3-------2
|
||||
// | |
|
||||
// 4-------5
|
||||
p0 = Vec2d(startx, starty);
|
||||
p0 = Vec2d(startx, starty);
|
||||
p0_5 = Vec2d(startx + len / 2, starty);
|
||||
p1 = Vec2d(startx + len, starty);
|
||||
p2 = Vec2d(startx + len, starty - len);
|
||||
p3 = Vec2d(startx, starty - len);
|
||||
p4 = Vec2d(startx, starty - len * 2);
|
||||
p1 = Vec2d(startx + len, starty);
|
||||
p2 = Vec2d(startx + len, starty - len);
|
||||
p3 = Vec2d(startx, starty - len);
|
||||
p4 = Vec2d(startx, starty - len * 2);
|
||||
p4_5 = Vec2d(startx + len / 2, starty - len * 2);
|
||||
p5 = Vec2d(startx + len, starty - len * 2);
|
||||
p5 = Vec2d(startx + len, starty - len * 2);
|
||||
|
||||
gap_p0_toward_p3 = p0 - Vec2d(0, gap);
|
||||
gap_p2_toward_p3 = p2 - Vec2d(gap, 0);
|
||||
|
@ -191,120 +178,71 @@ std::string CalibPressureAdvance::draw_digit(
|
|||
gcode << move_to(p4_5, writer, "Glyph: .");
|
||||
gcode << writer.extrude_to_xy(p4_5 + dot_direction, dE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvance::draw_number(
|
||||
double startx,
|
||||
double starty,
|
||||
double value,
|
||||
CalibPressureAdvance::DrawDigitMode mode,
|
||||
double line_width,
|
||||
double e_per_mm,
|
||||
double speed,
|
||||
GCodeWriter& writer
|
||||
)
|
||||
double startx, double starty, double value, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, double speed, GCodeWriter &writer)
|
||||
{
|
||||
auto sNumber = convert_number_to_string(value);
|
||||
auto sNumber = convert_number_to_string(value);
|
||||
std::stringstream gcode;
|
||||
gcode << writer.set_speed(speed);
|
||||
|
||||
for (std::string::size_type i = 0; i < sNumber.length(); ++i) {
|
||||
if (i > m_max_number_len) {
|
||||
break;
|
||||
}
|
||||
if (i > m_max_number_len) { break; }
|
||||
switch (mode) {
|
||||
case DrawDigitMode::Bottom_To_Top:
|
||||
gcode << draw_digit(
|
||||
startx,
|
||||
starty + i * number_spacing(),
|
||||
sNumber[i],
|
||||
mode,
|
||||
line_width,
|
||||
e_per_mm,
|
||||
writer
|
||||
);
|
||||
break;
|
||||
default:
|
||||
gcode << draw_digit(
|
||||
startx + i * number_spacing(),
|
||||
starty,
|
||||
sNumber[i],
|
||||
mode,
|
||||
line_width,
|
||||
e_per_mm,
|
||||
writer
|
||||
);
|
||||
case DrawDigitMode::Bottom_To_Top: gcode << draw_digit(startx, starty + i * number_spacing(), sNumber[i], mode, line_width, e_per_mm, writer); break;
|
||||
default: gcode << draw_digit(startx + i * number_spacing(), starty, sNumber[i], mode, line_width, e_per_mm, writer);
|
||||
}
|
||||
}
|
||||
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
CalibPressureAdvanceLine::CalibPressureAdvanceLine(GCode *gcodegen)
|
||||
: mp_gcodegen(gcodegen)
|
||||
, m_nozzle_diameter(gcodegen->config().nozzle_diameter.get_at(0))
|
||||
{
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvanceLine::generate_test(double start_pa /*= 0*/, double step_pa /*= 0.002*/, int count /*= 10*/)
|
||||
{
|
||||
BoundingBoxf bed_ext = get_extents(mp_gcodegen->config().printable_area.values);
|
||||
if (is_delta()) {
|
||||
CalibPressureAdvanceLine::delta_scale_bed_ext(bed_ext);
|
||||
}
|
||||
if (is_delta()) { CalibPressureAdvanceLine::delta_scale_bed_ext(bed_ext); }
|
||||
|
||||
auto bed_sizes = mp_gcodegen->config().printable_area.values;
|
||||
const auto &w = bed_ext.size().x();
|
||||
const auto &h = bed_ext.size().y();
|
||||
count = std::min(count, int((h - 10) / m_space_y));
|
||||
auto bed_sizes = mp_gcodegen->config().printable_area.values;
|
||||
const auto &w = bed_ext.size().x();
|
||||
const auto &h = bed_ext.size().y();
|
||||
count = std::min(count, int((h - 10) / m_space_y));
|
||||
|
||||
m_length_long = 40 + std::min(w - 120.0, 0.0);
|
||||
|
||||
auto startx = (w - m_length_short * 2 - m_length_long - 20) / 2;
|
||||
auto starty = (h - count * m_space_y) / 2;
|
||||
if (is_delta()) {
|
||||
CalibPressureAdvanceLine::delta_modify_start(startx, starty, count);
|
||||
}
|
||||
if (is_delta()) { CalibPressureAdvanceLine::delta_modify_start(startx, starty, count); }
|
||||
|
||||
return print_pa_lines(startx, starty, start_pa, step_pa, count);
|
||||
}
|
||||
|
||||
bool CalibPressureAdvanceLine::is_delta() const
|
||||
{
|
||||
return mp_gcodegen->config().printable_area.values.size() > 4;
|
||||
}
|
||||
bool CalibPressureAdvanceLine::is_delta() const { return mp_gcodegen->config().printable_area.values.size() > 4; }
|
||||
|
||||
std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num)
|
||||
{
|
||||
auto& writer = mp_gcodegen->writer();
|
||||
const auto& config = mp_gcodegen->config();
|
||||
auto & writer = mp_gcodegen->writer();
|
||||
const auto &config = mp_gcodegen->config();
|
||||
|
||||
const auto filament_diameter = config.filament_diameter.get_at(0);
|
||||
const auto print_flow_ratio = config.print_flow_ratio;
|
||||
const auto print_flow_ratio = config.print_flow_ratio;
|
||||
|
||||
const double e_per_mm = CalibPressureAdvance::e_per_mm(
|
||||
m_line_width,
|
||||
m_height_layer,
|
||||
m_nozzle_diameter,
|
||||
filament_diameter,
|
||||
print_flow_ratio
|
||||
);
|
||||
const double thin_e_per_mm = CalibPressureAdvance::e_per_mm(
|
||||
m_thin_line_width,
|
||||
m_height_layer,
|
||||
m_nozzle_diameter,
|
||||
filament_diameter,
|
||||
print_flow_ratio
|
||||
);
|
||||
const double number_e_per_mm = CalibPressureAdvance::e_per_mm(
|
||||
m_number_line_width,
|
||||
m_height_layer,
|
||||
m_nozzle_diameter,
|
||||
filament_diameter,
|
||||
print_flow_ratio
|
||||
);
|
||||
const double e_per_mm = CalibPressureAdvance::e_per_mm(m_line_width, m_height_layer, m_nozzle_diameter, filament_diameter, print_flow_ratio);
|
||||
const double thin_e_per_mm = CalibPressureAdvance::e_per_mm(m_thin_line_width, m_height_layer, m_nozzle_diameter, filament_diameter, print_flow_ratio);
|
||||
const double number_e_per_mm = CalibPressureAdvance::e_per_mm(m_number_line_width, m_height_layer, m_nozzle_diameter, filament_diameter, print_flow_ratio);
|
||||
|
||||
const double fast = CalibPressureAdvance::speed_adjust(m_fast_speed);
|
||||
const double slow = CalibPressureAdvance::speed_adjust(m_slow_speed);
|
||||
const double fast = CalibPressureAdvance::speed_adjust(m_fast_speed);
|
||||
const double slow = CalibPressureAdvance::speed_adjust(m_slow_speed);
|
||||
std::stringstream gcode;
|
||||
gcode << mp_gcodegen->writer().travel_to_z(m_height_layer);
|
||||
double y_pos = start_y;
|
||||
|
@ -336,47 +274,28 @@ std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double star
|
|||
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 2), thin_e_per_mm * 7);
|
||||
|
||||
for (int i = 0; i < num; i += 2) {
|
||||
gcode << draw_number(
|
||||
start_x + m_length_short + m_length_long + m_length_short + 3,
|
||||
y_pos + i * m_space_y + m_space_y / 2,
|
||||
start_pa + i * step_pa,
|
||||
m_draw_digit_mode,
|
||||
m_number_line_width,
|
||||
number_e_per_mm,
|
||||
3600,
|
||||
writer
|
||||
);
|
||||
gcode << draw_number(start_x + m_length_short + m_length_long + m_length_short + 3, y_pos + i * m_space_y + m_space_y / 2, start_pa + i * step_pa, m_draw_digit_mode,
|
||||
m_number_line_width, number_e_per_mm, 3600, writer);
|
||||
}
|
||||
}
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
void CalibPressureAdvanceLine::delta_modify_start(double& startx, double& starty, int count)
|
||||
void CalibPressureAdvanceLine::delta_modify_start(double &startx, double &starty, int count)
|
||||
{
|
||||
startx = -startx;
|
||||
starty = -(count * m_space_y) / 2;
|
||||
}
|
||||
|
||||
CalibPressureAdvancePattern::CalibPressureAdvancePattern(
|
||||
const Calib_Params& params,
|
||||
const DynamicPrintConfig& config,
|
||||
bool is_bbl_machine,
|
||||
Model& model,
|
||||
const Vec3d& origin
|
||||
) :
|
||||
m_params(params)
|
||||
CalibPressureAdvancePattern::CalibPressureAdvancePattern(const Calib_Params ¶ms, const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin)
|
||||
: m_params(params)
|
||||
{
|
||||
this->m_draw_digit_mode = DrawDigitMode::Bottom_To_Top;
|
||||
|
||||
refresh_setup(config, is_bbl_machine, model, origin);
|
||||
};
|
||||
|
||||
void CalibPressureAdvancePattern::generate_custom_gcodes(
|
||||
const DynamicPrintConfig& config,
|
||||
bool is_bbl_machine,
|
||||
Model& model,
|
||||
const Vec3d& origin
|
||||
)
|
||||
void CalibPressureAdvancePattern::generate_custom_gcodes(const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin)
|
||||
{
|
||||
std::stringstream gcode;
|
||||
gcode << "; start pressure advance pattern for layer\n";
|
||||
|
@ -390,29 +309,18 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
|
|||
const DrawBoxOptArgs default_box_opt_args(*this);
|
||||
|
||||
// create anchoring frame
|
||||
gcode << draw_box(
|
||||
m_starting_point.x(),
|
||||
m_starting_point.y(),
|
||||
print_size_x(),
|
||||
frame_size_y(),
|
||||
default_box_opt_args
|
||||
);
|
||||
gcode << draw_box(m_starting_point.x(), m_starting_point.y(), print_size_x(), frame_size_y(), default_box_opt_args);
|
||||
|
||||
// create tab for numbers
|
||||
DrawBoxOptArgs draw_box_opt_args = default_box_opt_args;
|
||||
draw_box_opt_args.is_filled = true;
|
||||
draw_box_opt_args.is_filled = true;
|
||||
draw_box_opt_args.num_perimeters = wall_count();
|
||||
gcode << draw_box(
|
||||
m_starting_point.x(),
|
||||
m_starting_point.y() + frame_size_y() + line_spacing_first_layer(),
|
||||
glyph_tab_max_x() - m_starting_point.x(),
|
||||
max_numbering_height() + line_spacing_first_layer() + m_glyph_padding_vertical * 2,
|
||||
draw_box_opt_args
|
||||
);
|
||||
gcode << draw_box(m_starting_point.x(), m_starting_point.y() + frame_size_y() + line_spacing_first_layer(), glyph_tab_max_x() - m_starting_point.x(),
|
||||
max_numbering_height() + line_spacing_first_layer() + m_glyph_padding_vertical * 2, draw_box_opt_args);
|
||||
|
||||
std::vector<CustomGCode::Item> gcode_items;
|
||||
const DrawLineOptArgs default_line_opt_args(*this);
|
||||
const int num_patterns = get_num_patterns(); // "cache" for use in loops
|
||||
const DrawLineOptArgs default_line_opt_args(*this);
|
||||
const int num_patterns = get_num_patterns(); // "cache" for use in loops
|
||||
|
||||
// draw pressure advance pattern
|
||||
for (int i = 0; i < m_num_layers; ++i) {
|
||||
|
@ -420,13 +328,13 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
|
|||
gcode << "; end pressure advance pattern for layer\n";
|
||||
CustomGCode::Item item;
|
||||
item.print_z = height_first_layer() + (i - 1) * height_layer();
|
||||
item.type = CustomGCode::Type::Custom;
|
||||
item.extra = gcode.str();
|
||||
item.type = CustomGCode::Type::Custom;
|
||||
item.extra = gcode.str();
|
||||
gcode_items.push_back(item);
|
||||
|
||||
gcode = std::stringstream(); // reset for next layer contents
|
||||
gcode << "; start pressure advance pattern for layer\n";
|
||||
|
||||
|
||||
const double layer_height = height_first_layer() + (i * height_layer());
|
||||
gcode << m_writer.travel_to_z(layer_height, "Move to layer height");
|
||||
}
|
||||
|
@ -435,49 +343,29 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
|
|||
if (i == 1) {
|
||||
gcode << m_writer.set_pressure_advance(m_params.start);
|
||||
|
||||
double number_e_per_mm = e_per_mm(
|
||||
line_width(),
|
||||
height_layer(),
|
||||
m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0)
|
||||
);
|
||||
double number_e_per_mm = e_per_mm(line_width(), height_layer(), m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0));
|
||||
|
||||
// glyph on every other line
|
||||
for (int j = 0; j < num_patterns; j += 2) {
|
||||
gcode << draw_number(
|
||||
glyph_start_x(j),
|
||||
m_starting_point.y() + frame_size_y() + m_glyph_padding_vertical + line_width(),
|
||||
m_params.start + (j * m_params.step),
|
||||
m_draw_digit_mode,
|
||||
line_width(),
|
||||
number_e_per_mm,
|
||||
speed_first_layer(),
|
||||
m_writer
|
||||
);
|
||||
gcode << draw_number(glyph_start_x(j), m_starting_point.y() + frame_size_y() + m_glyph_padding_vertical + line_width(), m_params.start + (j * m_params.step),
|
||||
m_draw_digit_mode, line_width(), number_e_per_mm, speed_first_layer(), m_writer);
|
||||
}
|
||||
}
|
||||
|
||||
DrawLineOptArgs draw_line_opt_args = default_line_opt_args;
|
||||
|
||||
double to_x = m_starting_point.x() + pattern_shift();
|
||||
double to_y = m_starting_point.y();
|
||||
double to_x = m_starting_point.x() + pattern_shift();
|
||||
double to_y = m_starting_point.y();
|
||||
double side_length = m_wall_side_length;
|
||||
|
||||
// shrink first layer to fit inside frame
|
||||
if (i == 0) {
|
||||
double shrink =
|
||||
(
|
||||
line_spacing_first_layer() * (wall_count() - 1) +
|
||||
(line_width_first_layer() * (1 - m_encroachment))
|
||||
) / std::sin(to_radians(m_corner_angle) / 2)
|
||||
;
|
||||
side_length = m_wall_side_length - shrink;
|
||||
double shrink = (line_spacing_first_layer() * (wall_count() - 1) + (line_width_first_layer() * (1 - m_encroachment))) / std::sin(to_radians(m_corner_angle) / 2);
|
||||
side_length = m_wall_side_length - shrink;
|
||||
to_x += shrink * std::sin(to_radians(90) - to_radians(m_corner_angle) / 2);
|
||||
to_y +=
|
||||
line_spacing_first_layer() * (wall_count() - 1) +
|
||||
(line_width_first_layer() * (1 - m_encroachment))
|
||||
;
|
||||
to_y += line_spacing_first_layer() * (wall_count() - 1) + (line_width_first_layer() * (1 - m_encroachment));
|
||||
}
|
||||
|
||||
double initial_x = to_x;
|
||||
|
@ -492,12 +380,12 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
|
|||
for (int k = 0; k < wall_count(); ++k) {
|
||||
to_x += std::cos(to_radians(m_corner_angle) / 2) * side_length;
|
||||
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
|
||||
|
||||
draw_line_opt_args = default_line_opt_args;
|
||||
draw_line_opt_args.height = i == 0 ? height_first_layer() : height_layer();
|
||||
draw_line_opt_args.line_width = line_width(); // don't use line_width_first_layer so results are consistent across all layers
|
||||
draw_line_opt_args.speed = i == 0 ? speed_adjust(speed_first_layer()) : speed_adjust(speed_perimeter());
|
||||
draw_line_opt_args.comment = "Print pattern wall";
|
||||
|
||||
draw_line_opt_args = default_line_opt_args;
|
||||
draw_line_opt_args.height = i == 0 ? height_first_layer() : height_layer();
|
||||
draw_line_opt_args.line_width = line_width(); // don't use line_width_first_layer so results are consistent across all layers
|
||||
draw_line_opt_args.speed = i == 0 ? speed_adjust(speed_first_layer()) : speed_adjust(speed_perimeter());
|
||||
draw_line_opt_args.comment = "Print pattern wall";
|
||||
gcode << draw_line(Vec2d(to_x, to_y), draw_line_opt_args);
|
||||
|
||||
to_x -= std::cos(to_radians(m_corner_angle) / 2) * side_length;
|
||||
|
@ -530,23 +418,18 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
|
|||
|
||||
CustomGCode::Item item;
|
||||
item.print_z = max_layer_z();
|
||||
item.type = CustomGCode::Type::Custom;
|
||||
item.extra = gcode.str();
|
||||
item.type = CustomGCode::Type::Custom;
|
||||
item.extra = gcode.str();
|
||||
gcode_items.push_back(item);
|
||||
|
||||
CustomGCode::Info info;
|
||||
info.mode = CustomGCode::Mode::SingleExtruder;
|
||||
info.mode = CustomGCode::Mode::SingleExtruder;
|
||||
info.gcodes = gcode_items;
|
||||
|
||||
model.plates_custom_gcodes[model.curr_plate_index] = info;
|
||||
}
|
||||
|
||||
void CalibPressureAdvancePattern::refresh_setup(
|
||||
const DynamicPrintConfig& config,
|
||||
bool is_bbl_machine,
|
||||
const Model& model,
|
||||
const Vec3d& origin
|
||||
)
|
||||
void CalibPressureAdvancePattern::refresh_setup(const DynamicPrintConfig &config, bool is_bbl_machine, const Model &model, const Vec3d &origin)
|
||||
{
|
||||
m_config = config;
|
||||
m_config.apply(model.objects.front()->config.get(), true);
|
||||
|
@ -558,15 +441,10 @@ void CalibPressureAdvancePattern::refresh_setup(
|
|||
_refresh_writer(is_bbl_machine, model, origin);
|
||||
}
|
||||
|
||||
void CalibPressureAdvancePattern::_refresh_starting_point(const Model& model)
|
||||
void CalibPressureAdvancePattern::_refresh_starting_point(const Model &model)
|
||||
{
|
||||
ModelObject* obj = model.objects.front();
|
||||
BoundingBoxf3 bbox =
|
||||
obj->instance_bounding_box(
|
||||
*obj->instances.front(),
|
||||
false
|
||||
)
|
||||
;
|
||||
ModelObject * obj = model.objects.front();
|
||||
BoundingBoxf3 bbox = obj->instance_bounding_box(*obj->instances.front(), false);
|
||||
|
||||
m_starting_point = Vec3d(bbox.min.x(), bbox.max.y(), 0);
|
||||
m_starting_point.y() += m_handle_spacing;
|
||||
|
@ -577,39 +455,28 @@ void CalibPressureAdvancePattern::_refresh_starting_point(const Model& model)
|
|||
}
|
||||
}
|
||||
|
||||
void CalibPressureAdvancePattern::_refresh_writer(
|
||||
bool is_bbl_machine,
|
||||
const Model& model,
|
||||
const Vec3d& origin
|
||||
)
|
||||
void CalibPressureAdvancePattern::_refresh_writer(bool is_bbl_machine, const Model &model, const Vec3d &origin)
|
||||
{
|
||||
PrintConfig print_config;
|
||||
print_config.apply(m_config, true);
|
||||
|
||||
m_writer.apply_print_config(print_config);
|
||||
m_writer.set_xy_offset(origin(0), origin(1));
|
||||
m_writer.set_is_bbl_machine(is_bbl_machine);
|
||||
|
||||
//m_writer.set_is_bbl_machine(is_bbl_machine);
|
||||
|
||||
const unsigned int extruder_id = model.objects.front()->volumes.front()->extruder_id();
|
||||
m_writer.set_extruders({ extruder_id });
|
||||
m_writer.set_extruders({extruder_id});
|
||||
m_writer.set_extruder(extruder_id);
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvancePattern::draw_line(
|
||||
Vec2d to_pt,
|
||||
DrawLineOptArgs opt_args
|
||||
)
|
||||
std::string CalibPressureAdvancePattern::draw_line(Vec2d to_pt, DrawLineOptArgs opt_args)
|
||||
{
|
||||
const double e_per_mm = CalibPressureAdvance::e_per_mm(
|
||||
opt_args.line_width,
|
||||
opt_args.height,
|
||||
m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0)
|
||||
);
|
||||
const double e_per_mm = CalibPressureAdvance::e_per_mm(opt_args.line_width, opt_args.height, m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
|
||||
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0));
|
||||
|
||||
const double length = get_distance(Vec2d(m_last_pos.x(), m_last_pos.y()), to_pt);
|
||||
auto dE = e_per_mm * length;
|
||||
auto dE = e_per_mm * length;
|
||||
|
||||
std::stringstream gcode;
|
||||
|
||||
|
@ -621,40 +488,31 @@ std::string CalibPressureAdvancePattern::draw_line(
|
|||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string CalibPressureAdvancePattern::draw_box(
|
||||
double min_x,
|
||||
double min_y,
|
||||
double size_x,
|
||||
double size_y,
|
||||
DrawBoxOptArgs opt_args
|
||||
)
|
||||
std::string CalibPressureAdvancePattern::draw_box(double min_x, double min_y, double size_x, double size_y, DrawBoxOptArgs opt_args)
|
||||
{
|
||||
std::stringstream gcode;
|
||||
|
||||
double x = min_x;
|
||||
double y = min_y;
|
||||
double x = min_x;
|
||||
double y = min_y;
|
||||
const double max_x = min_x + size_x;
|
||||
const double max_y = min_y + size_y;
|
||||
|
||||
const double spacing = opt_args.line_width - opt_args.height * (1 - M_PI / 4);
|
||||
|
||||
// if number of perims exceeds size of box, reduce it to max
|
||||
const int max_perimeters =
|
||||
std::min(
|
||||
// this is the equivalent of number of perims for concentric fill
|
||||
std::floor(size_x * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))),
|
||||
std::floor(size_y * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45)))
|
||||
)
|
||||
;
|
||||
const int max_perimeters = std::min(
|
||||
// this is the equivalent of number of perims for concentric fill
|
||||
std::floor(size_x * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))),
|
||||
std::floor(size_y * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))));
|
||||
|
||||
opt_args.num_perimeters = std::min(opt_args.num_perimeters, max_perimeters);
|
||||
|
||||
gcode << move_to(Vec2d(min_x, min_y), m_writer, "Move to box start");
|
||||
|
||||
DrawLineOptArgs line_opt_args(*this);
|
||||
line_opt_args.height = opt_args.height;
|
||||
line_opt_args.height = opt_args.height;
|
||||
line_opt_args.line_width = opt_args.line_width;
|
||||
line_opt_args.speed = opt_args.speed;
|
||||
line_opt_args.speed = opt_args.speed;
|
||||
|
||||
for (int i = 0; i < opt_args.num_perimeters; ++i) {
|
||||
if (i != 0) { // after first perimeter, step inwards to start next perimeter
|
||||
|
@ -680,23 +538,18 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
|
||||
if (!opt_args.is_filled) {
|
||||
return gcode.str();
|
||||
}
|
||||
if (!opt_args.is_filled) { return gcode.str(); }
|
||||
|
||||
// create box infill
|
||||
const double spacing_45 = spacing / std::sin(to_radians(45));
|
||||
|
||||
const double bound_modifier =
|
||||
(spacing * (opt_args.num_perimeters - 1)) +
|
||||
(opt_args.line_width * (1 - m_encroachment))
|
||||
;
|
||||
const double x_min_bound = min_x + bound_modifier;
|
||||
const double x_max_bound = max_x - bound_modifier;
|
||||
const double y_min_bound = min_y + bound_modifier;
|
||||
const double y_max_bound = max_y - bound_modifier;
|
||||
const int x_count = std::floor((x_max_bound - x_min_bound) / spacing_45);
|
||||
const int y_count = std::floor((y_max_bound - y_min_bound) / spacing_45);
|
||||
const double bound_modifier = (spacing * (opt_args.num_perimeters - 1)) + (opt_args.line_width * (1 - m_encroachment));
|
||||
const double x_min_bound = min_x + bound_modifier;
|
||||
const double x_max_bound = max_x - bound_modifier;
|
||||
const double y_min_bound = min_y + bound_modifier;
|
||||
const double y_max_bound = max_y - bound_modifier;
|
||||
const int x_count = std::floor((x_max_bound - x_min_bound) / spacing_45);
|
||||
const int y_count = std::floor((y_max_bound - y_min_bound) / spacing_45);
|
||||
|
||||
double x_remainder = std::fmod((x_max_bound - x_min_bound), spacing_45);
|
||||
double y_remainder = std::fmod((y_max_bound - y_min_bound), spacing_45);
|
||||
|
@ -706,7 +559,8 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Move to fill start");
|
||||
|
||||
for (int i = 0; i < x_count + y_count + (x_remainder + y_remainder >= spacing_45 ? 1 : 0); ++i) { // this isn't the most robust way, but less expensive than finding line intersections
|
||||
for (int i = 0; i < x_count + y_count + (x_remainder + y_remainder >= spacing_45 ? 1 : 0);
|
||||
++i) { // this isn't the most robust way, but less expensive than finding line intersections
|
||||
if (i < std::min(x_count, y_count)) {
|
||||
if (i % 2 == 0) {
|
||||
x += spacing_45;
|
||||
|
@ -714,7 +568,7 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
y += x - x_min_bound;
|
||||
x = x_min_bound;
|
||||
x = x_min_bound;
|
||||
line_opt_args.comment = "Fill: Print up/left";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
} else {
|
||||
|
@ -723,7 +577,7 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
|
||||
|
||||
x += y - y_min_bound;
|
||||
y = y_min_bound;
|
||||
y = y_min_bound;
|
||||
line_opt_args.comment = "Fill: Print down/right";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
|
@ -736,7 +590,7 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
x -= y_max_bound - y_min_bound;
|
||||
y = y_max_bound;
|
||||
y = y_max_bound;
|
||||
line_opt_args.comment = "Fill: Print up/left";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
} else {
|
||||
|
@ -748,9 +602,9 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
}
|
||||
y = y_max_bound;
|
||||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
|
||||
x += y_max_bound - y_min_bound;
|
||||
y = y_min_bound;
|
||||
y = y_min_bound;
|
||||
line_opt_args.comment = "Fill: Print down/right";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
|
@ -792,7 +646,7 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
|
||||
|
||||
x -= y_max_bound - y;
|
||||
y = y_max_bound;
|
||||
y = y_max_bound;
|
||||
line_opt_args.comment = "Fill: Print up/left";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
} else {
|
||||
|
@ -805,7 +659,7 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
|
||||
|
||||
y -= x_max_bound - x;
|
||||
x = x_max_bound;
|
||||
x = x_max_bound;
|
||||
line_opt_args.comment = "Fill: Print down/right";
|
||||
gcode << draw_line(Vec2d(x, y), line_opt_args);
|
||||
}
|
||||
|
@ -815,26 +669,17 @@ std::string CalibPressureAdvancePattern::draw_box(
|
|||
return gcode.str();
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::get_distance(Vec2d from, Vec2d to) const
|
||||
{
|
||||
return std::hypot((to.x() - from.x()), (to.y() - from.y()));
|
||||
}
|
||||
double CalibPressureAdvancePattern::get_distance(Vec2d from, Vec2d to) const { return std::hypot((to.x() - from.x()), (to.y() - from.y())); }
|
||||
|
||||
double CalibPressureAdvancePattern::object_size_x() const
|
||||
{
|
||||
return get_num_patterns() * ((wall_count() - 1) * line_spacing_angle()) +
|
||||
(get_num_patterns() - 1) * (m_pattern_spacing + line_width()) +
|
||||
std::cos(to_radians(m_corner_angle) / 2) * m_wall_side_length +
|
||||
line_spacing_first_layer() * wall_count()
|
||||
;
|
||||
return get_num_patterns() * ((wall_count() - 1) * line_spacing_angle()) + (get_num_patterns() - 1) * (m_pattern_spacing + line_width()) +
|
||||
std::cos(to_radians(m_corner_angle) / 2) * m_wall_side_length + line_spacing_first_layer() * wall_count();
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::object_size_y() const
|
||||
{
|
||||
return 2 * (std::sin(to_radians(m_corner_angle) / 2) * m_wall_side_length) +
|
||||
max_numbering_height() +
|
||||
m_glyph_padding_vertical * 2 +
|
||||
line_width_first_layer();
|
||||
return 2 * (std::sin(to_radians(m_corner_angle) / 2) * m_wall_side_length) + max_numbering_height() + m_glyph_padding_vertical * 2 + line_width_first_layer();
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::glyph_start_x(int pattern_i) const
|
||||
|
@ -843,16 +688,14 @@ double CalibPressureAdvancePattern::glyph_start_x(int pattern_i) const
|
|||
// align glyph's start with first perimeter of specified pattern
|
||||
double x =
|
||||
// starting offset
|
||||
m_starting_point.x() +
|
||||
pattern_shift() +
|
||||
m_starting_point.x() + pattern_shift() +
|
||||
|
||||
// width of pattern extrusions
|
||||
pattern_i * (wall_count() - 1) * line_spacing_angle() + // center to center distance of extrusions
|
||||
pattern_i * line_width() + // endcaps. center to end on either side = 1 line width
|
||||
pattern_i * line_width() + // endcaps. center to end on either side = 1 line width
|
||||
|
||||
// space between each pattern
|
||||
pattern_i * m_pattern_spacing
|
||||
;
|
||||
pattern_i * m_pattern_spacing;
|
||||
|
||||
// align to middle of pattern walls
|
||||
x += wall_count() * line_spacing_angle() / 2;
|
||||
|
@ -873,35 +716,26 @@ double CalibPressureAdvancePattern::glyph_length_x() const
|
|||
double CalibPressureAdvancePattern::glyph_tab_max_x() const
|
||||
{
|
||||
// only every other glyph is shown, starting with 1
|
||||
int num = get_num_patterns();
|
||||
int max_num =
|
||||
(num % 2 == 0)
|
||||
? num - 1
|
||||
: num
|
||||
;
|
||||
int num = get_num_patterns();
|
||||
int max_num = (num % 2 == 0) ? num - 1 : num;
|
||||
|
||||
// padding at end should be same as padding at start
|
||||
double padding = glyph_start_x(0) - m_starting_point.x();
|
||||
|
||||
return
|
||||
glyph_start_x(max_num - 1) + // glyph_start_x is zero-based
|
||||
(glyph_length_x() - line_width() / 2) +
|
||||
padding
|
||||
;
|
||||
|
||||
return glyph_start_x(max_num - 1) + // glyph_start_x is zero-based
|
||||
(glyph_length_x() - line_width() / 2) + padding;
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::max_numbering_height() const
|
||||
{
|
||||
std::string::size_type most_characters = 0;
|
||||
const int num_patterns = get_num_patterns();
|
||||
const int num_patterns = get_num_patterns();
|
||||
|
||||
// note: only every other number is printed
|
||||
for (std::string::size_type i = 0; i < num_patterns; i += 2) {
|
||||
std::string sNumber = convert_number_to_string(m_params.start + (i * m_params.step));
|
||||
|
||||
if (sNumber.length() > most_characters) {
|
||||
most_characters = sNumber.length();
|
||||
}
|
||||
if (sNumber.length() > most_characters) { most_characters = sNumber.length(); }
|
||||
}
|
||||
|
||||
most_characters = std::min(most_characters, m_max_number_len);
|
||||
|
@ -909,12 +743,6 @@ double CalibPressureAdvancePattern::max_numbering_height() const
|
|||
return (most_characters * m_digit_segment_len) + ((most_characters - 1) * m_digit_gap_len);
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::pattern_shift() const
|
||||
{
|
||||
return
|
||||
(wall_count() - 1) * line_spacing_first_layer() +
|
||||
line_width_first_layer() +
|
||||
m_glyph_padding_horizontal
|
||||
;
|
||||
}
|
||||
double CalibPressureAdvancePattern::pattern_shift() const { return (wall_count() - 1) * line_spacing_first_layer() + line_width_first_layer() + m_glyph_padding_horizontal; }
|
||||
} // namespace Slic3r
|
||||
|
||||
|
|
|
@ -1,157 +1,215 @@
|
|||
#pragma once
|
||||
#define calib_pressure_advance_dd
|
||||
|
||||
#include "GCode.hpp"
|
||||
#include "GCodeWriter.hpp"
|
||||
#include "PrintConfig.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GCode;
|
||||
class Model;
|
||||
|
||||
enum class CalibMode : int {
|
||||
Calib_None = 0,
|
||||
Calib_PA_Line,
|
||||
Calib_PA_Pattern,
|
||||
Calib_PA_Tower,
|
||||
Calib_Flow_Rate,
|
||||
Calib_Temp_Tower,
|
||||
Calib_Vol_speed_Tower,
|
||||
Calib_VFA_Tower,
|
||||
Calib_Retraction_tower
|
||||
};
|
||||
|
||||
struct Calib_Params {
|
||||
Calib_Params() : mode(CalibMode::Calib_None) { };
|
||||
enum class CalibState {
|
||||
Start = 0,
|
||||
Preset,
|
||||
Calibration,
|
||||
CoarseSave,
|
||||
FineCalibration,
|
||||
Save,
|
||||
Finish
|
||||
};
|
||||
|
||||
struct Calib_Params
|
||||
{
|
||||
Calib_Params() : mode(CalibMode::Calib_None){}
|
||||
double start, end, step;
|
||||
bool print_numbers;
|
||||
CalibMode mode;
|
||||
};
|
||||
|
||||
class CalibPressureAdvance {
|
||||
public:
|
||||
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height,
|
||||
int filament_idx = 0);
|
||||
|
||||
protected:
|
||||
CalibPressureAdvance() =default;
|
||||
~CalibPressureAdvance() =default;
|
||||
|
||||
enum class DrawDigitMode {
|
||||
Left_To_Right,
|
||||
Bottom_To_Top
|
||||
class X1CCalibInfos
|
||||
{
|
||||
public:
|
||||
struct X1CCalibInfo
|
||||
{
|
||||
int tray_id;
|
||||
int bed_temp;
|
||||
int nozzle_temp;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
float max_volumetric_speed;
|
||||
float flow_rate = 0.98f; // for flow ratio
|
||||
};
|
||||
|
||||
void delta_scale_bed_ext(BoundingBoxf& bed_ext) const { bed_ext.scale(1.0f / 1.41421f); }
|
||||
|
||||
std::string move_to(Vec2d pt, GCodeWriter& writer, std::string comment = std::string());
|
||||
double e_per_mm(
|
||||
double line_width,
|
||||
double layer_height,
|
||||
float nozzle_diameter,
|
||||
float filament_diameter,
|
||||
float print_flow_ratio
|
||||
) const;
|
||||
double speed_adjust(int speed) const { return speed * 60; };
|
||||
|
||||
std::string convert_number_to_string(double num) const;
|
||||
double number_spacing() const { return m_digit_segment_len + m_digit_gap_len; };
|
||||
std::string draw_digit(
|
||||
double startx,
|
||||
double starty,
|
||||
char c,
|
||||
CalibPressureAdvance::DrawDigitMode mode,
|
||||
double line_width,
|
||||
double e_per_mm,
|
||||
GCodeWriter& writer
|
||||
);
|
||||
std::string draw_number(
|
||||
double startx,
|
||||
double starty,
|
||||
double value,
|
||||
CalibPressureAdvance::DrawDigitMode mode,
|
||||
double line_width,
|
||||
double e_per_mm,
|
||||
double speed,
|
||||
GCodeWriter& writer
|
||||
);
|
||||
|
||||
Vec3d m_last_pos;
|
||||
|
||||
DrawDigitMode m_draw_digit_mode {DrawDigitMode::Left_To_Right};
|
||||
const double m_digit_segment_len {2};
|
||||
const double m_digit_gap_len {1};
|
||||
const std::string::size_type m_max_number_len {5};
|
||||
std::vector<X1CCalibInfo> calib_datas;
|
||||
};
|
||||
|
||||
class CalibPressureAdvanceLine : public CalibPressureAdvance {
|
||||
class CaliPresetInfo
|
||||
{
|
||||
public:
|
||||
CalibPressureAdvanceLine(GCode* gcodegen) :
|
||||
mp_gcodegen(gcodegen),
|
||||
m_nozzle_diameter(gcodegen->config().nozzle_diameter.get_at(0))
|
||||
{ };
|
||||
~CalibPressureAdvanceLine() { };
|
||||
int tray_id;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
std::string name;
|
||||
|
||||
CaliPresetInfo &operator=(const CaliPresetInfo &other)
|
||||
{
|
||||
this->tray_id = other.tray_id;
|
||||
this->nozzle_diameter = other.nozzle_diameter;
|
||||
this->filament_id = other.filament_id;
|
||||
this->setting_id = other.setting_id;
|
||||
this->name = other.name;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct PrinterCaliInfo
|
||||
{
|
||||
std::string dev_id;
|
||||
bool cali_finished = true;
|
||||
float cache_flow_ratio;
|
||||
std::vector<CaliPresetInfo> selected_presets;
|
||||
};
|
||||
|
||||
class PACalibResult
|
||||
{
|
||||
public:
|
||||
enum CalibResult {
|
||||
CALI_RESULT_SUCCESS = 0,
|
||||
CALI_RESULT_PROBLEM = 1,
|
||||
CALI_RESULT_FAILED = 2,
|
||||
};
|
||||
int tray_id;
|
||||
int cali_idx = -1;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
std::string name;
|
||||
float k_value = 0.0;
|
||||
float n_coef = 0.0;
|
||||
int confidence = -1; // 0: success 1: uncertain 2: failed
|
||||
};
|
||||
|
||||
struct PACalibIndexInfo
|
||||
{
|
||||
int tray_id;
|
||||
int cali_idx;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
};
|
||||
|
||||
class FlowRatioCalibResult
|
||||
{
|
||||
public:
|
||||
int tray_id;
|
||||
float nozzle_diameter;
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
float flow_ratio;
|
||||
int confidence; // 0: success 1: uncertain 2: failed
|
||||
};
|
||||
|
||||
class CalibPressureAdvance
|
||||
{
|
||||
public:
|
||||
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx = 0);
|
||||
|
||||
protected:
|
||||
CalibPressureAdvance() = default;
|
||||
~CalibPressureAdvance() = default;
|
||||
|
||||
enum class DrawDigitMode { Left_To_Right, Bottom_To_Top };
|
||||
|
||||
void delta_scale_bed_ext(BoundingBoxf &bed_ext) const { bed_ext.scale(1.0f / 1.41421f); }
|
||||
|
||||
std::string move_to(Vec2d pt, GCodeWriter &writer, std::string comment = std::string());
|
||||
double e_per_mm(double line_width, double layer_height, float nozzle_diameter, float filament_diameter, float print_flow_ratio) const;
|
||||
double speed_adjust(int speed) const { return speed * 60; };
|
||||
|
||||
std::string convert_number_to_string(double num) const;
|
||||
double number_spacing() const { return m_digit_segment_len + m_digit_gap_len; };
|
||||
std::string draw_digit(double startx, double starty, char c, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, GCodeWriter &writer);
|
||||
std::string draw_number(
|
||||
double startx, double starty, double value, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, double speed, GCodeWriter &writer);
|
||||
|
||||
Vec3d m_last_pos;
|
||||
|
||||
DrawDigitMode m_draw_digit_mode{DrawDigitMode::Left_To_Right};
|
||||
const double m_digit_segment_len{2};
|
||||
const double m_digit_gap_len{1};
|
||||
const std::string::size_type m_max_number_len{5};
|
||||
};
|
||||
|
||||
class CalibPressureAdvanceLine : public CalibPressureAdvance
|
||||
{
|
||||
public:
|
||||
CalibPressureAdvanceLine(GCode *gcodegen);
|
||||
~CalibPressureAdvanceLine(){};
|
||||
|
||||
std::string generate_test(double start_pa = 0, double step_pa = 0.002, int count = 50);
|
||||
|
||||
void set_speed(double fast = 100.0, double slow = 20.0) {
|
||||
void set_speed(double fast = 100.0, double slow = 20.0)
|
||||
{
|
||||
m_slow_speed = slow;
|
||||
m_fast_speed = fast;
|
||||
}
|
||||
|
||||
const double& line_width() { return m_line_width; };
|
||||
bool is_delta() const;
|
||||
bool& draw_numbers() { return m_draw_numbers; }
|
||||
|
||||
const double &line_width() { return m_line_width; };
|
||||
bool is_delta() const;
|
||||
bool & draw_numbers() { return m_draw_numbers; }
|
||||
|
||||
private:
|
||||
std::string print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num);
|
||||
|
||||
void delta_modify_start(double& startx, double& starty, int count);
|
||||
|
||||
GCode* mp_gcodegen;
|
||||
void delta_modify_start(double &startx, double &starty, int count);
|
||||
|
||||
GCode *mp_gcodegen;
|
||||
|
||||
double m_nozzle_diameter;
|
||||
double m_slow_speed, m_fast_speed;
|
||||
|
||||
const double m_height_layer {0.2};
|
||||
const double m_line_width {0.6};
|
||||
const double m_thin_line_width {0.44};
|
||||
const double m_number_line_width {0.48};
|
||||
const double m_space_y {3.5};
|
||||
|
||||
double m_length_short {20.0}, m_length_long {40.0};
|
||||
bool m_draw_numbers {true};
|
||||
const double m_height_layer{0.2};
|
||||
const double m_line_width{0.6};
|
||||
const double m_thin_line_width{0.44};
|
||||
const double m_number_line_width{0.48};
|
||||
const double m_space_y{3.5};
|
||||
|
||||
double m_length_short{20.0}, m_length_long{40.0};
|
||||
bool m_draw_numbers{true};
|
||||
};
|
||||
|
||||
struct SuggestedConfigCalibPAPattern {
|
||||
const std::vector<std::pair<std::string, double>> float_pairs {
|
||||
{"initial_layer_print_height", 0.25},
|
||||
{"layer_height", 0.2},
|
||||
{"initial_layer_speed", 30}
|
||||
};
|
||||
struct SuggestedConfigCalibPAPattern
|
||||
{
|
||||
const std::vector<std::pair<std::string, double>> float_pairs{{"initial_layer_print_height", 0.25}, {"layer_height", 0.2}, {"initial_layer_speed", 30}};
|
||||
|
||||
const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs {
|
||||
{"line_width", 112.5},
|
||||
{"initial_layer_line_width", 140}
|
||||
};
|
||||
const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs{{"line_width", 112.5}, {"initial_layer_line_width", 140}};
|
||||
|
||||
const std::vector<std::pair<std::string, int>> int_pairs {
|
||||
{"skirt_loops", 0},
|
||||
{"wall_loops", 3}
|
||||
};
|
||||
const std::vector<std::pair<std::string, int>> int_pairs{{"skirt_loops", 0}, {"wall_loops", 3}};
|
||||
|
||||
const std::pair<std::string, BrimType> brim_pair {"brim_type", BrimType::btNoBrim};
|
||||
const std::pair<std::string, BrimType> brim_pair{"brim_type", BrimType::btNoBrim};
|
||||
};
|
||||
|
||||
class CalibPressureAdvancePattern : public CalibPressureAdvance {
|
||||
friend struct DrawLineOptArgs;
|
||||
friend struct DrawBoxOptArgs;
|
||||
class CalibPressureAdvancePattern : public CalibPressureAdvance
|
||||
{
|
||||
friend struct DrawLineOptArgs;
|
||||
friend struct DrawBoxOptArgs;
|
||||
|
||||
public:
|
||||
CalibPressureAdvancePattern(
|
||||
const Calib_Params& params,
|
||||
const DynamicPrintConfig& config,
|
||||
bool is_bbl_machine,
|
||||
Model& model,
|
||||
const Vec3d& origin
|
||||
);
|
||||
CalibPressureAdvancePattern(const Calib_Params ¶ms, const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin);
|
||||
|
||||
double handle_xy_size() const { return m_handle_xy_size; };
|
||||
double handle_spacing() const { return m_handle_spacing; };
|
||||
|
@ -159,85 +217,53 @@ public:
|
|||
double print_size_y() const { return object_size_y(); };
|
||||
double max_layer_z() const { return height_first_layer() + ((m_num_layers - 1) * height_layer()); };
|
||||
|
||||
void generate_custom_gcodes(
|
||||
const DynamicPrintConfig& config,
|
||||
bool is_bbl_machine,
|
||||
Model& model,
|
||||
const Vec3d& origin
|
||||
);
|
||||
void generate_custom_gcodes(const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin);
|
||||
|
||||
protected:
|
||||
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
|
||||
double speed_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_speed")->value; };
|
||||
double line_width_first_layer() const { return m_config.get_abs_value("initial_layer_line_width"); };
|
||||
double line_width() const { return m_config.get_abs_value("line_width"); };
|
||||
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };
|
||||
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };
|
||||
|
||||
private:
|
||||
struct DrawLineOptArgs {
|
||||
DrawLineOptArgs(const CalibPressureAdvancePattern& p) :
|
||||
height {p.height_layer()},
|
||||
line_width {p.line_width()},
|
||||
speed {p.speed_adjust(p.speed_perimeter())}
|
||||
{ };
|
||||
|
||||
double height;
|
||||
double line_width;
|
||||
double speed;
|
||||
std::string comment {"Print line"};
|
||||
};
|
||||
|
||||
struct DrawBoxOptArgs {
|
||||
DrawBoxOptArgs(const CalibPressureAdvancePattern& p) :
|
||||
num_perimeters {p.wall_count()},
|
||||
height {p.height_first_layer()},
|
||||
line_width {p.line_width_first_layer()},
|
||||
speed {p.speed_adjust(p.speed_first_layer())}
|
||||
{ };
|
||||
|
||||
bool is_filled {false};
|
||||
int num_perimeters;
|
||||
double height;
|
||||
double line_width;
|
||||
double speed;
|
||||
};
|
||||
|
||||
void refresh_setup(
|
||||
const DynamicPrintConfig& config,
|
||||
bool is_bbl_machine,
|
||||
const Model& model,
|
||||
const Vec3d& origin
|
||||
);
|
||||
void _refresh_starting_point(const Model& model);
|
||||
void _refresh_writer(
|
||||
bool is_bbl_machine,
|
||||
const Model& model,
|
||||
const Vec3d& origin
|
||||
);
|
||||
|
||||
double height_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_print_height")->value; };
|
||||
double height_layer() const { return m_config.option<ConfigOptionFloat>("layer_height")->value; };
|
||||
const int get_num_patterns() const
|
||||
struct DrawLineOptArgs
|
||||
{
|
||||
return std::ceil((m_params.end - m_params.start) / m_params.step + 1);
|
||||
}
|
||||
DrawLineOptArgs(const CalibPressureAdvancePattern &p) : height{p.height_layer()}, line_width{p.line_width()}, speed{p.speed_adjust(p.speed_perimeter())} {};
|
||||
|
||||
std::string draw_line(
|
||||
Vec2d to_pt,
|
||||
DrawLineOptArgs opt_args
|
||||
);
|
||||
std::string draw_box(
|
||||
double min_x,
|
||||
double min_y,
|
||||
double size_x,
|
||||
double size_y,
|
||||
DrawBoxOptArgs opt_args
|
||||
);
|
||||
double height;
|
||||
double line_width;
|
||||
double speed;
|
||||
std::string comment{"Print line"};
|
||||
};
|
||||
|
||||
struct DrawBoxOptArgs
|
||||
{
|
||||
DrawBoxOptArgs(const CalibPressureAdvancePattern &p)
|
||||
: num_perimeters{p.wall_count()}, height{p.height_first_layer()}, line_width{p.line_width_first_layer()}, speed{p.speed_adjust(p.speed_first_layer())} {};
|
||||
|
||||
bool is_filled{false};
|
||||
int num_perimeters;
|
||||
double height;
|
||||
double line_width;
|
||||
double speed;
|
||||
};
|
||||
|
||||
void refresh_setup(const DynamicPrintConfig &config, bool is_bbl_machine, const Model &model, const Vec3d &origin);
|
||||
void _refresh_starting_point(const Model &model);
|
||||
void _refresh_writer(bool is_bbl_machine, const Model &model, const Vec3d &origin);
|
||||
|
||||
double height_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_print_height")->value; };
|
||||
double height_layer() const { return m_config.option<ConfigOptionFloat>("layer_height")->value; };
|
||||
const int get_num_patterns() const { return std::ceil((m_params.end - m_params.start) / m_params.step + 1); }
|
||||
|
||||
std::string draw_line(Vec2d to_pt, DrawLineOptArgs opt_args);
|
||||
std::string draw_box(double min_x, double min_y, double size_x, double size_y, DrawBoxOptArgs opt_args);
|
||||
|
||||
double to_radians(double degrees) const { return degrees * M_PI / 180; };
|
||||
double get_distance(Vec2d from, Vec2d to) const;
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
from slic3r documentation: spacing = extrusion_width - layer_height * (1 - PI/4)
|
||||
"spacing" = center-to-center distance of adjacent extrusions, which partially overlap
|
||||
https://manual.slic3r.org/advanced/flow-math
|
||||
|
@ -258,23 +284,24 @@ private:
|
|||
|
||||
double pattern_shift() const;
|
||||
|
||||
const Calib_Params& m_params;
|
||||
const Calib_Params &m_params;
|
||||
|
||||
DynamicPrintConfig m_config;
|
||||
GCodeWriter m_writer;
|
||||
bool m_is_delta;
|
||||
Vec3d m_starting_point;
|
||||
GCodeWriter m_writer;
|
||||
bool m_is_delta;
|
||||
Vec3d m_starting_point;
|
||||
|
||||
const double m_handle_xy_size {5};
|
||||
const double m_handle_spacing {2};
|
||||
const int m_num_layers {4};
|
||||
|
||||
const double m_wall_side_length {30.0};
|
||||
const int m_corner_angle {90};
|
||||
const int m_pattern_spacing {2};
|
||||
const double m_encroachment {1. / 3.};
|
||||
const double m_handle_xy_size{5};
|
||||
const double m_handle_spacing{2};
|
||||
const int m_num_layers{4};
|
||||
|
||||
const double m_glyph_padding_horizontal {1};
|
||||
const double m_glyph_padding_vertical {1};
|
||||
const double m_wall_side_length{30.0};
|
||||
const int m_corner_angle{90};
|
||||
const int m_pattern_spacing{2};
|
||||
const double m_encroachment{1. / 3.};
|
||||
|
||||
const double m_glyph_padding_horizontal{1};
|
||||
const double m_glyph_padding_vertical{1};
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -89,7 +89,6 @@ static constexpr double BRIDGE_INFILL_MARGIN = 1;
|
|||
|
||||
//BBS: some global const config which user can not change, but developer can
|
||||
static constexpr bool g_config_support_sharp_tails = true;
|
||||
static constexpr bool g_config_remove_small_overhangs = true;
|
||||
static constexpr float g_config_tree_support_collision_resolution = 0.2;
|
||||
|
||||
// Write slices as SVG images into out directory during the 2D processing of the slices.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue