diff --git a/CMakeLists.txt b/CMakeLists.txt index b6d40a0346..633ab3f19a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,7 +256,7 @@ if(NOT WIN32) # boost::process was introduced first in version 1.64.0 set(MINIMUM_BOOST_VERSION "1.64.0") endif() -set(_boost_components "system;filesystem;thread;log;locale;regex") +set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time") find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components}) add_library(boost_libs INTERFACE) diff --git a/deps/blosc-mods.patch b/deps/blosc-mods.patch index 9a91b4974c..9b1b9cb27d 100644 --- a/deps/blosc-mods.patch +++ b/deps/blosc-mods.patch @@ -1,8 +1,9 @@ -From 5669891dfaaa4c814f3ec667ca6bf4e693aea978 Mon Sep 17 00:00:00 2001 +From 7cf6c014a36f1712efbdbe9bc52d2d4922b54673 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 30 Oct 2019 12:54:52 +0100 Subject: [PATCH] Blosc 1.17 fixes and cmake config script +Signed-off-by: tamasmeszaros --- CMakeLists.txt | 105 +++++++++++++++++----------------- blosc/CMakeLists.txt | 118 +++++++++------------------------------ diff --git a/deps/deps-macos.cmake b/deps/deps-macos.cmake index fc08c62903..9e51735fd5 100644 --- a/deps/deps-macos.cmake +++ b/deps/deps-macos.cmake @@ -16,8 +16,8 @@ include("deps-unix-common.cmake") ExternalProject_Add(dep_boost EXCLUDE_FROM_ALL 1 - URL "https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.gz" - URL_HASH SHA256=96b34f7468f26a141f6020efb813f1a2f3dfb9797ecf76a7d7cbd843cc95f5bd + URL "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz" + URL_HASH SHA256=882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9 BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ./bootstrap.sh --with-toolset=clang @@ -90,8 +90,6 @@ ExternalProject_Add(dep_wxwidgets EXCLUDE_FROM_ALL 1 GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets" GIT_TAG v3.1.1-patched -# URL "https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.2/wxWidgets-3.1.2.tar.bz2" -# URL_HASH SHA256=4cb8d23d70f9261debf7d6cfeca667fc0a7d2b6565adb8f1c484f9b674f1f27a BUILD_IN_SOURCE 1 # PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/wxwidgets-pngprefix.h" src/png/pngprefix.h CONFIGURE_COMMAND env "CXXFLAGS=${DEP_WERRORS_SDK}" "CFLAGS=${DEP_WERRORS_SDK}" ./configure diff --git a/deps/deps-unix-common.cmake b/deps/deps-unix-common.cmake index eae319efc6..7491aafe1f 100644 --- a/deps/deps-unix-common.cmake +++ b/deps/deps-unix-common.cmake @@ -55,14 +55,14 @@ find_package(Git REQUIRED) ExternalProject_Add(dep_qhull EXCLUDE_FROM_ALL 1 - URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" - URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 + #URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" + #URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 + GIT_REPOSITORY https://github.com/qhull/qhull.git + GIT_TAG 7afedcc73666e46a9f1d74632412ebecf53b1b30 # v7.3.2 plus the mac build patch CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local ${DEP_CMAKE_OPTS} - UPDATE_COMMAND "" - PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch ) ExternalProject_Add(dep_blosc @@ -80,8 +80,8 @@ ExternalProject_Add(dep_blosc -DBUILD_TESTS=OFF -DBUILD_BENCHMARKS=OFF -DPREFER_EXTERNAL_ZLIB=ON - UPDATE_COMMAND "" - PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch + PATCH_COMMAND ${GIT_EXECUTABLE} reset --hard && git clean -df && + ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch ) ExternalProject_Add(dep_openexr @@ -96,7 +96,6 @@ ExternalProject_Add(dep_openexr -DPYILMBASE_ENABLE:BOOL=OFF -DOPENEXR_VIEWERS_ENABLE:BOOL=OFF -DOPENEXR_BUILD_UTILS:BOOL=OFF - UPDATE_COMMAND "" ) ExternalProject_Add(dep_openvdb @@ -116,6 +115,6 @@ ExternalProject_Add(dep_openvdb -DOPENVDB_CORE_STATIC=ON -DTBB_STATIC=ON -DOPENVDB_BUILD_VDB_PRINT=ON - UPDATE_COMMAND "" - PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch + PATCH_COMMAND PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df && + ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch ) \ No newline at end of file diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 514a90a9ec..603f249317 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -218,16 +218,16 @@ find_package(Git REQUIRED) ExternalProject_Add(dep_qhull EXCLUDE_FROM_ALL 1 - URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" - URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 + #URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" + #URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 + GIT_REPOSITORY https://github.com/qhull/qhull.git + GIT_TAG 7afedcc73666e46a9f1d74632412ebecf53b1b30 # v7.3.2 plus the mac build patch CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_DEBUG_POSTFIX=d - UPDATE_COMMAND "" - PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) @@ -288,8 +288,8 @@ ExternalProject_Add(dep_blosc -DPREFER_EXTERNAL_ZLIB=ON -DBLOSC_IS_SUBPROJECT:BOOL=ON -DBLOSC_INSTALL:BOOL=ON - UPDATE_COMMAND "" - PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch + PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df && + ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) @@ -311,7 +311,6 @@ ExternalProject_Add(dep_openexr -DPYILMBASE_ENABLE:BOOL=OFF -DOPENEXR_VIEWERS_ENABLE:BOOL=OFF -DOPENEXR_BUILD_UTILS:BOOL=OFF - UPDATE_COMMAND "" BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) @@ -324,7 +323,7 @@ ExternalProject_Add(dep_openvdb #URL_HASH SHA256=dc337399dce8e1c9f21f20e97b1ce7e4933cb0a63bb3b8b734d8fcc464aa0c48 GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git GIT_TAG aebaf8d95be5e57fd33949281ec357db4a576c2e #v6.2.1 - DEPENDS dep_blosc dep_openexr #dep_tbb dep_boost + DEPENDS dep_blosc dep_openexr dep_tbb dep_boost CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_ARGS @@ -340,8 +339,8 @@ ExternalProject_Add(dep_openvdb -DTBB_STATIC=ON -DOPENVDB_BUILD_VDB_PRINT=ON BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj - UPDATE_COMMAND "" - PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch + PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df && + ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch INSTALL_COMMAND "" ) diff --git a/deps/openvdb-mods.patch b/deps/openvdb-mods.patch index 60687b8d17..023cb53087 100644 --- a/deps/openvdb-mods.patch +++ b/deps/openvdb-mods.patch @@ -1,8 +1,9 @@ -From e48f4a835fe7cb391f9f90945472bd367fb4c4f1 Mon Sep 17 00:00:00 2001 +From dbe038fce8a15ddc9a5c83ec5156d7bc9e178015 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 16 Oct 2019 17:42:50 +0200 Subject: [PATCH] Build fixes for PrusaSlicer integration +Signed-off-by: tamasmeszaros --- CMakeLists.txt | 3 - cmake/FindBlosc.cmake | 218 --------------- diff --git a/resources/icons/bed/ender3.svg b/resources/icons/bed/ender3.svg new file mode 100644 index 0000000000..06910afdf8 --- /dev/null +++ b/resources/icons/bed/ender3.svg @@ -0,0 +1,47 @@ + + ender3_bed_texture + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/bed/mini.svg b/resources/icons/bed/mini.svg new file mode 100644 index 0000000000..1b9476ef8b --- /dev/null +++ b/resources/icons/bed/mini.svg @@ -0,0 +1,109 @@ + + bed_texture_denser + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/printers/Creality_Ender3.png b/resources/icons/printers/Creality_Ender3.png new file mode 100644 index 0000000000..52861197c7 Binary files /dev/null and b/resources/icons/printers/Creality_Ender3.png differ diff --git a/resources/icons/printers/PrusaResearch_MINI.png b/resources/icons/printers/PrusaResearch_MINI.png new file mode 100644 index 0000000000..01780f9ca8 Binary files /dev/null and b/resources/icons/printers/PrusaResearch_MINI.png differ diff --git a/resources/models/ender3_bed.stl b/resources/models/ender3_bed.stl new file mode 100644 index 0000000000..fb8f86d094 Binary files /dev/null and b/resources/models/ender3_bed.stl differ diff --git a/resources/models/mini_bed.stl b/resources/models/mini_bed.stl new file mode 100644 index 0000000000..2f4c45b7b1 Binary files /dev/null and b/resources/models/mini_bed.stl differ diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini new file mode 100644 index 0000000000..aa95ed6df0 --- /dev/null +++ b/resources/profiles/Creality.ini @@ -0,0 +1,415 @@ +# Print profiles for the Creality printers. + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = Creality +# Configuration version of this file. Config file will only be installed, if the config_version differs. +# This means, the server may force the PrusaSlicer configuration to be downgraded. +config_version = 0.0.1 +# Where to get the updates from? +config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/ +# changelog_url = http://files.prusa3d.com/?latest=slicer-profiles&lng=%1% + +# The printer models will be shown by the Configuration Wizard in this order, +# also the first model installed & the first nozzle installed will be activated after install. +# Printer model name will be shown by the installation wizard. + +[printer_model:ENDER3] +name = Creality Ender-3 +variants = 0.4 +technology = FFF + +# All presets starting with asterisk, for example *common*, are intermediate and they will +# not make it into the user interface. + +# Common print preset +[print:*common*] +avoid_crossing_perimeters = 0 +bridge_angle = 0 +bridge_flow_ratio = 0.95 +bridge_speed = 25 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +complete_objects = 0 +dont_support_bridges = 1 +elefant_foot_compensation = 0 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeters_first = 0 +external_perimeter_extrusion_width = 0.45 +extra_perimeters = 0 +extruder_clearance_height = 25 +extruder_clearance_radius = 45 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 20 +gap_fill_speed = 30 +gcode_comments = 0 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +interface_shells = 0 +max_print_speed = 100 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +overhangs = 0 +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode +perimeters = 2 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +single_extruder_multi_material_priming = 1 +skirts = 1 +skirt_distance = 2 +skirt_height = 2 +small_perimeter_speed = 25 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.4 +support_material_interface_extruder = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_enforce_layers = 0 +support_material_contact_distance = 0.15 +support_material_interface_contact_loops = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 40 +support_material_synchronize_layers = 0 +support_material_threshold = 45 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +top_infill_extrusion_width = 0.45 +top_solid_infill_speed = 40 +travel_speed = 100 +wipe_tower = 0 +wipe_tower_bridging = 10 +wipe_tower_rotation_angle = 0 +wipe_tower_width = 60 +wipe_tower_x = 170 +wipe_tower_y = 140 +xy_size_compensation = 0 + +[print:*0.12mm*] +inherits = *common* +perimeter_speed = 40 +external_perimeter_speed = 25 +infill_speed = 50 +solid_infill_speed = 40 +layer_height = 0.12 +perimeters = 3 +top_infill_extrusion_width = 0.4 +bottom_solid_layers = 6 +top_solid_layers = 7 + +[print:*0.20mm*] +inherits = *common* +perimeter_speed = 40 +external_perimeter_speed = 25 +infill_speed = 50 +solid_infill_speed = 40 +layer_height = 0.20 +top_infill_extrusion_width = 0.4 +bottom_solid_layers = 4 +top_solid_layers = 5 + +[print:*0.24mm*] +inherits = *common* +perimeter_speed = 40 +external_perimeter_speed = 25 +infill_speed = 50 +solid_infill_speed = 40 +layer_height = 0.24 +top_infill_extrusion_width = 0.45 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:0.12mm DETAIL ENDER3] +inherits = *0.12mm* +alias=0.12mm DETAIL +travel_speed = 150 +infill_speed = 50 +solid_infill_speed = 40 +top_solid_infill_speed = 30 +support_material_extrusion_width = 0.38 +compatible_printers_condition = printer_model=="ENDER3" and nozzle_diameter[0]==0.4 + +[print:0.20mm NORMAL ENDER3] +inherits = *0.20mm* +alias=0.20mm NORMAL +travel_speed = 150 +infill_speed = 50 +solid_infill_speed = 40 +top_solid_infill_speed = 30 +support_material_extrusion_width = 0.38 +compatible_printers_condition = printer_model=="ENDER3" and nozzle_diameter[0]==0.4 + +[print:0.24mm DRAFT ENDER3] +inherits = *0.24mm* +alias=0.24mm DRAFT +travel_speed = 150 +infill_speed = 50 +solid_infill_speed = 40 +top_solid_infill_speed = 30 +support_material_extrusion_width = 0.38 +compatible_printers_condition = printer_model=="ENDER3" and nozzle_diameter[0]==0.4 + +# Common filament preset +[filament:*common*] +cooling = 0 +compatible_printers = +compatible_printers_condition = +extrusion_multiplier = 1 +filament_cost = 0 +filament_density = 0 +filament_diameter = 1.75 +filament_notes = "" +filament_settings_id = "" +filament_soluble = 0 +min_print_speed = 15 +slowdown_below_layer_time = 20 + +[filament:*PLA*] +inherits = *common* +bed_temperature = 40 +fan_below_layer_time = 100 +filament_colour = #FF3232 +filament_max_volumetric_speed = 15 +filament_type = PLA +filament_density = 1.24 +filament_cost = 20 +first_layer_bed_temperature = 40 +first_layer_temperature = 215 +fan_always_on = 1 +cooling = 1 +max_fan_speed = 100 +min_fan_speed = 100 +bridge_fan_speed = 100 +disable_fan_first_layers = 1 +temperature = 210 + +[filament:*PET*] +inherits = *common* +bed_temperature = 70 +cooling = 1 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #FF8000 +filament_max_volumetric_speed = 8 +filament_type = PETG +filament_density = 1.27 +filament_cost = 30 +first_layer_bed_temperature =70 +first_layer_temperature = 240 +fan_always_on = 1 +max_fan_speed = 50 +min_fan_speed = 20 +bridge_fan_speed = 100 +temperature = 240 + +[filament:*ABS*] +inherits = *common* +bed_temperature = 100 +cooling = 0 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #3A80CA +filament_max_volumetric_speed = 11 +filament_type = PLA +filament_density = 1.04 +filament_cost = 20 +first_layer_bed_temperature = 100 +first_layer_temperature = 245 +fan_always_on = 0 +max_fan_speed = 0 +min_fan_speed = 0 +bridge_fan_speed = 30 +top_fan_speed = 0 +temperature = 245 + +[filament:Generic PLA ENDER3] +inherits = *PLA* +alias=Generic PLA + +[filament:Generic PET ENDER3] +inherits = *PET* +alias=Generic PET + +[filament:Generic ABS ENDER3] +inherits = *ABS* +alias=Generic ABS +first_layer_bed_temperature = 90 +bed_temperature = 90 + +[filament:Creality PLA ENDER3] +inherits = *PLA* +alias=Creality PLA +temperature = 205 +bed_temperature = 40 +first_layer_temperature = 210 +first_layer_bed_temperature =40 + +[filament:Creality PET ENDER3] +inherits = *PET* +alias=Creality PET +temperature = 240 +bed_temperature = 70 +first_layer_temperature = 240 +first_layer_bed_temperature =70 +max_fan_speed = 40 +min_fan_speed = 20 + +[filament:Creality ABS ENDER3] +inherits = *ABS* +alias=Creality ABS +temperature = 240 +bed_temperature = 90 +first_layer_temperature = 240 +first_layer_bed_temperature =90 + +[filament:Prusament PLA ENDER3] +inherits = *PLA* +alias=Prusament PLA +temperature = 215 +bed_temperature = 40 +first_layer_temperature = 215 +first_layer_bed_temperature =40 +filament_cost = 24.99 +filament_density = 1.24 + +[filament:Prusament PETG ENDER3] +inherits = *PET* +alias=Prusament PETG +temperature = 245 +bed_temperature = 70 +first_layer_temperature = 245 +first_layer_bed_temperature =70 +filament_cost = 24.99 +filament_density = 1.27 + +# Common printer preset +[printer:*common*] +printer_technology = FFF +bed_shape = 0x0,200x0,200x200,0x200 +before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\n\n +between_objects_gcode = +deretract_speed = 0 +extruder_colour = #FFFF00 +extruder_offset = 0x0 +gcode_flavor = marlin +silent_mode = 0 +remaining_times = 0 +machine_max_acceleration_e = 10000 +machine_max_acceleration_extruding = 2000 +machine_max_acceleration_retracting = 1500 +machine_max_acceleration_x = 3000 +machine_max_acceleration_y = 3000 +machine_max_acceleration_z = 500 +machine_max_feedrate_e = 120 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 12 +machine_max_jerk_e = 2.5 +machine_max_jerk_x = 20 +machine_max_jerk_y = 20 +machine_max_jerk_z = 0.4 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] +max_layer_height = 0.3 +min_layer_height = 0.07 +max_print_height = 200 +nozzle_diameter = 0.4 +octoprint_apikey = +octoprint_host = +printer_notes = +printer_settings_id = +retract_before_travel = 1 +retract_before_wipe = 0% +retract_layer_change = 1 +retract_length = 1 +retract_length_toolchange = 1 +retract_lift = 0 +retract_lift_above = 0 +retract_lift_below = 0 +retract_restart_extra = 0 +retract_restart_extra_toolchange = 0 +retract_speed = 35 +serial_port = +serial_speed = 250000 +single_extruder_multi_material = 0 +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all\nG92 E0.0\nG1 Z0.15 F240\nG1 X60.0 E9.0 F800.0 ; intro line\nG1 X100.0 E12.5 F800 ; intro line\nG92 E0.0 +end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 F3000 ; home X axis\nM84 ; disable motors +toolchange_gcode = +use_firmware_retraction = 0 +use_relative_e_distances = 1 +use_volumetric_e = 0 +variable_layer_height = 1 +wipe = 1 +z_offset = 0 +printer_model = +default_print_profile = +default_filament_profile = + +[printer:Creality ENDER-3] +inherits = *common* +printer_model = ENDER3 +printer_variant = 0.4 +max_layer_height = 0.25 +min_layer_height = 0.1 +bed_shape = 0x0,220x0,220x220,0x220 +max_print_height = 250 +machine_max_acceleration_e = 5000 +machine_max_acceleration_extruding = 500 +machine_max_acceleration_retracting = 1000 +machine_max_acceleration_x = 500 +machine_max_acceleration_y = 500 +machine_max_acceleration_z = 100 +machine_max_feedrate_e = 60 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 10 +machine_max_jerk_e = 5 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 0.4 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +printer_notes = +nozzle_diameter = 0.4 +retract_before_travel = 2 +retract_length = 5 +retract_speed = 60 +deretract_speed = 40 +retract_before_wipe = 70% +default_print_profile = 0.20mm NORMAL +default_filament_profile = Creality PLA +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0.0\nG1 Y190 E15.0 F1500.0 ; intro line\nG1 X2.3 F5000\nG1 Y10 E30 F1200.0 ; intro line\nG92 E0.0 +end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+10, max_print_height)} F600{endif} ; Move print head up\nG1 X0 Y200 F3000 ; present print\nM84 X Y E ; disable motors \ No newline at end of file diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index 9add73b4dc..a741f4656e 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -5,7 +5,7 @@ name = Prusa Research # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.0.1 +config_version = 1.0.4 # Where to get the updates from? config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/ changelog_url = http://files.prusa3d.com/?latest=slicer-profiles&lng=%1% @@ -16,6 +16,13 @@ changelog_url = http://files.prusa3d.com/?latest=slicer-profiles&lng=%1% #for example by the melt zone size, or whether the nozzle is hardened. # Printer model name will be shown by the installation wizard. + +[printer_model:MINI] +name = Original Prusa MINI +variants = 0.4; 0.25 +technology = FFF +family = MINI + [printer_model:MK3S] name = Original Prusa i3 MK3S variants = 0.4; 0.25; 0.6 @@ -82,29 +89,6 @@ variants = default technology = SLA family = SL1 -[default_filaments] -Generic PLA = 1 -Generic PLA MMU2 = 1 -Prusa PLA = 1 -Prusa PLA MMU2 = 1 -Prusament PLA = 1 -Prusament PLA MMU2 = 1 - -[default_sla_materials] -Prusa Azure Blue Tough 0.05 = 1 -Prusa Black Tough 0.05 = 1 -Prusa Green Casting 0.05 = 1 -Prusa Grey Tough 0.05 = 1 -Prusa Maroon Tough 0.05 = 1 -Prusa Orange Tough 0.025 = 1 -Prusa Orange Tough 0.035 = 1 -Prusa Orange Tough 0.05 = 1 -Prusa Orange Tough 0.1 = 1 -Prusa Pink Tough 0.05 = 1 -Prusa Skin Tough 0.05 = 1 -Prusa Transparent Red Tough 0.05 = 1 -Prusa White Tough 0.05 = 1 - # All presets starting with asterisk, for example *common*, are intermediate and they will # not make it into the user interface. @@ -222,11 +206,24 @@ travel_speed = 180 wipe_tower_x = 170 wipe_tower_y = 125 +## MINI + +[print:*MINI*] +fill_pattern = grid +travel_speed = 150 +wipe_tower = 0 +default_acceleration = 1250 +first_layer_acceleration = 800 +infill_acceleration = 1000 +bridge_acceleration = 1000 +support_material_speed = 40 +max_print_speed = 150 + # Print parameters common to a 0.25mm diameter nozzle. [print:*0.25nozzle*] external_perimeter_extrusion_width = 0.25 extrusion_width = 0.25 -first_layer_extrusion_width = 0.25 +first_layer_extrusion_width = 0.3 infill_extrusion_width = 0.25 perimeter_extrusion_width = 0.25 solid_infill_extrusion_width = 0.25 @@ -241,7 +238,7 @@ output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_heig [print:*0.25nozzleMK3*] external_perimeter_extrusion_width = 0.25 extrusion_width = 0.25 -first_layer_extrusion_width = 0.35 +first_layer_extrusion_width = 0.3 infill_extrusion_width = 0.25 perimeter_extrusion_width = 0.25 solid_infill_extrusion_width = 0.25 @@ -271,6 +268,38 @@ fill_pattern = grid fill_density = 20% output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode +[print:*0.25nozzleMINI*] +external_perimeter_extrusion_width = 0.25 +extrusion_width = 0.25 +first_layer_extrusion_width = 0.3 +infill_extrusion_width = 0.25 +perimeter_extrusion_width = 0.25 +solid_infill_extrusion_width = 0.25 +top_infill_extrusion_width = 0.25 +support_material_extrusion_width = 0.2 +support_material_interface_layers = 0 +support_material_interface_spacing = 0.15 +support_material_spacing = 1 +support_material_xy_spacing = 150% +perimeter_speed = 30 +external_perimeter_speed = 20 +small_perimeter_speed = 20 +infill_speed = 40 +solid_infill_speed = 40 +top_solid_infill_speed = 30 +support_material_speed = 40 +bridge_speed = 20 +gap_fill_speed = 30 +perimeter_acceleration = 500 +infill_acceleration = 800 +bridge_acceleration = 500 +first_layer_acceleration = 500 +max_print_speed = 80 +perimeters = 3 +fill_pattern = grid +fill_density = 20% +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode + # Print parameters common to a 0.6mm diameter nozzle. [print:*0.6nozzle*] external_perimeter_extrusion_width = 0.61 @@ -324,7 +353,7 @@ inherits = *common* bottom_solid_layers = 10 bridge_acceleration = 300 bridge_flow_ratio = 0.7 -default_acceleration = 500 +default_acceleration = 1000 external_perimeter_speed = 20 fill_density = 20% first_layer_acceleration = 500 @@ -346,12 +375,14 @@ top_solid_layers = 15 [print:0.05mm ULTRADETAIL] inherits = *0.05mm* +alias = 0.05mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders==1 infill_extrusion_width = 0.5 # MK3 # [print:0.05mm ULTRADETAIL MK3] inherits = *0.05mm*; *MK3* +alias = 0.05mm ULTRADETAIL fill_pattern = gyroid fill_density = 15% compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and ! single_extruder_multi_material @@ -360,6 +391,7 @@ top_infill_extrusion_width = 0.4 # MK2 # [print:0.05mm ULTRADETAIL 0.25 nozzle] inherits = *0.05mm*; *0.25nozzle* +alias = 0.05mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 fill_density = 20% infill_speed = 20 @@ -372,10 +404,10 @@ support_material_speed = 20 # MK3 # [print:0.05mm ULTRADETAIL 0.25 nozzle MK3] inherits = *0.05mm*; *0.25nozzle*; *MK3* +alias = 0.05mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 fill_pattern = grid fill_density = 20% -first_layer_extrusion_width = 0.35 # XXXXXXXXXXXXXXXXXXXX # XXX--- 0.07mm ---XXX @@ -387,7 +419,7 @@ bottom_solid_layers = 8 bridge_acceleration = 300 bridge_flow_ratio = 0.7 bridge_speed = 20 -default_acceleration = 500 +default_acceleration = 1000 external_perimeter_speed = 20 fill_density = 15% first_layer_acceleration = 500 @@ -410,12 +442,14 @@ top_solid_layers = 11 # MK3 # [print:0.07mm ULTRADETAIL MK3] inherits = *0.07mm*; *MK3* +alias = 0.07mm ULTRADETAIL fill_pattern = gyroid compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and ! single_extruder_multi_material top_infill_extrusion_width = 0.4 [print:0.07mm ULTRADETAIL 0.25 nozzle MK3] inherits = *0.07mm*; *0.25nozzle*; *MK3* +alias = 0.07mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 infill_speed = 30 solid_infill_speed = 30 @@ -423,7 +457,6 @@ support_material_speed = 30 top_solid_infill_speed = 20 fill_pattern = grid fill_density = 20% -first_layer_extrusion_width = 0.35 # XXXXXXXXXXXXXXXXXXXX # XXX--- 0.10mm ---XXX @@ -442,6 +475,7 @@ top_solid_layers = 9 # MK2 # [print:0.10mm DETAIL] inherits = *0.10mm* +alias = 0.10mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders==1 external_perimeter_speed = 40 infill_acceleration = 2000 @@ -452,6 +486,7 @@ solid_infill_speed = 50 # MK3 # [print:0.10mm DETAIL MK3] inherits = *0.10mm*; *MK3* +alias = 0.10mm DETAIL bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and ! single_extruder_multi_material external_perimeter_speed = 25 @@ -468,10 +503,11 @@ fill_density = 15% # MK2 # [print:0.10mm DETAIL 0.25 nozzle] inherits = *0.10mm*; *0.25nozzle* +alias = 0.10mm DETAIL bridge_acceleration = 600 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 external_perimeter_speed = 20 -infill_acceleration = 1600 +infill_acceleration = 1000 infill_speed = 40 perimeter_acceleration = 600 perimeter_speed = 25 @@ -482,6 +518,7 @@ top_solid_infill_speed = 30 # MK3 # [print:0.10mm DETAIL 0.25 nozzle MK3] inherits = *0.10mm*; *0.25nozzleMK3*; *MK3* +alias = 0.10mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 fill_pattern = grid fill_density = 20% @@ -520,17 +557,19 @@ top_solid_infill_speed = 70 # MK2 # [print:0.15mm OPTIMAL] inherits = *0.15mm* +alias = 0.15mm OPTIMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2[^\.].*/ and nozzle_diameter[0]==0.4 top_infill_extrusion_width = 0.45 # MK2 # [print:0.15mm OPTIMAL 0.25 nozzle] inherits = *0.15mm*; *0.25nozzle* +alias = 0.15mm OPTIMAL bridge_acceleration = 600 bridge_flow_ratio = 0.7 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 external_perimeter_speed = 20 -infill_acceleration = 1600 +infill_acceleration = 1000 infill_speed = 40 perimeter_acceleration = 600 perimeter_speed = 25 @@ -541,11 +580,13 @@ top_solid_infill_speed = 30 # MK2 # [print:0.15mm OPTIMAL 0.6 nozzle] inherits = *0.15mm*; *0.6nozzle* +alias = 0.15mm OPTIMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 # MK3 # [print:0.15mm QUALITY MK3] inherits = *0.15mm*; *MK3* +alias = 0.15mm QUALITY bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 25 @@ -560,6 +601,7 @@ fill_density = 15% [print:0.15mm SPEED MK3] inherits = *0.15mm*; *MK3* +alias = 0.15mm SPEED bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 35 @@ -573,6 +615,7 @@ top_solid_infill_speed = 50 # MK3 MMU # [print:0.15mm SOLUBLE FULL MK3] inherits = 0.15mm SPEED MK3; *soluble_support* +alias = 0.15mm SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 notes = Set your soluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder support_material_extruder = 5 @@ -585,6 +628,7 @@ top_solid_infill_speed = 30 # MK3 MMU # [print:0.15mm SOLUBLE INTERFACE MK3] inherits = 0.15mm SOLUBLE FULL MK3 +alias = 0.15mm SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -593,6 +637,7 @@ support_material_with_sheath = 0 # MK2 MMU # [print:0.15mm OPTIMAL SOLUBLE FULL] inherits = *0.15mm*; *soluble_support* +alias = 0.15mm OPTIMAL SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2[^\.].*/ and nozzle_diameter[0]==0.4 and num_extruders>1 external_perimeter_speed = 25 notes = Set your soluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder @@ -604,6 +649,7 @@ top_solid_infill_speed = 30 # MK2 MMU # [print:0.15mm OPTIMAL SOLUBLE INTERFACE] inherits = 0.15mm OPTIMAL SOLUBLE FULL +alias = 0.15mm OPTIMAL SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -613,6 +659,7 @@ support_material_xy_spacing = 80% # MK3 # [print:0.15mm QUALITY 0.25 nozzle MK3] inherits = *0.15mm*; *0.25nozzleMK3*; *MK3* +alias = 0.15mm QUALITY compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 fill_pattern = grid fill_density = 20% @@ -620,6 +667,7 @@ fill_density = 20% # MK3 # [print:0.15mm DETAIL 0.6 nozzle MK3] inherits = *0.15mm*; *0.6nozzleMK3*; *MK306* +alias = 0.15mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1250 @@ -663,6 +711,7 @@ top_solid_infill_speed = 70 # MK3 # [print:0.20mm QUALITY MK3] inherits = *0.20mm*; *MK3* +alias = 0.20mm QUALITY bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 25 @@ -677,6 +726,7 @@ fill_density = 15% [print:0.20mm SPEED MK3] inherits = *0.20mm*; *MK3* +alias = 0.20mm SPEED bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 35 @@ -690,6 +740,7 @@ top_solid_infill_speed = 50 # MK3 MMU # [print:0.20mm SOLUBLE FULL MK3] inherits = 0.20mm SPEED MK3; *soluble_support* +alias = 0.20mm SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 notes = Set your soluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder support_material_extruder = 5 @@ -702,6 +753,7 @@ top_solid_infill_speed = 30 # MK3 MMU # [print:0.20mm SOLUBLE INTERFACE MK3] inherits = 0.20mm SOLUBLE FULL MK3 +alias = 0.20mm SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -715,6 +767,7 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and # MK2 # [print:0.20mm NORMAL 0.6 nozzle] inherits = *0.20mm*; *0.6nozzle* +alias = 0.20mm NORMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 # MK2 MMU # @@ -739,6 +792,7 @@ support_material_xy_spacing = 80% # MK3 # [print:0.20mm DETAIL 0.6 nozzle MK3] inherits = *0.20mm*; *0.6nozzleMK3*; *MK306* +alias = 0.20mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1250 @@ -748,6 +802,21 @@ perimeter_speed = 45 solid_infill_speed = 70 top_solid_infill_speed = 45 + +# XXXXXXXXXXXXXXXXXXXX +# XXX--- 0.25mm ---XXX +# XXXXXXXXXXXXXXXXXXXX + +[print:*0.25mm*] +inherits = *common* +bottom_solid_layers = 4 +bridge_flow_ratio = 0.95 +external_perimeter_speed = 40 +perimeter_acceleration = 800 +layer_height = 0.25 +perimeter_speed = 50 +top_solid_layers = 4 + # XXXXXXXXXXXXXXXXXXXX # XXX--- 0.30mm ---XXX # XXXXXXXXXXXXXXXXXXXX @@ -768,6 +837,7 @@ top_solid_layers = 4 [print:0.30mm QUALITY 0.6 nozzle MK3] inherits = *0.30mm*; *0.6nozzleMK3*; *MK306* +alias = 0.30mm QUALITY compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1250 @@ -779,6 +849,7 @@ top_solid_infill_speed = 45 [print:0.30mm SOLUBLE FULL 0.6 nozzle MK3] inherits = 0.30mm QUALITY 0.6 nozzle MK3; *soluble_support* +alias = 0.30mm SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 and num_extruders>1 notes = Set your soluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder support_material_extruder = 5 @@ -793,6 +864,7 @@ support_material_xy_spacing = 80% [print:0.30mm SOLUBLE INTERFACE 0.6 nozzle MK3] inherits = 0.30mm SOLUBLE FULL 0.6 nozzle MK3 +alias = 0.30mm SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -800,6 +872,7 @@ support_material_with_sheath = 0 [print:0.30mm DRAFT MK3] inherits = *0.30mm*; *MK3* +alias = 0.30mm DRAFT bottom_solid_layers = 3 bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 @@ -851,15 +924,18 @@ first_layer_extrusion_width = 0.42 perimeter_extrusion_width = 0.43 solid_infill_extrusion_width = 0.7 top_infill_extrusion_width = 0.43 +support_material_extrusion_width = 0.37 # MK2 # [print:0.35mm FAST 0.6 nozzle] inherits = *0.35mm*; *0.6nozzle* +alias = 0.35mm FAST compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 # MK2 MMU # [print:0.35mm FAST sol full 0.6 nozzle] inherits = *0.35mm*; *0.6nozzle*; *soluble_support* +alias = 0.35mm FAST SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_model=="MK2SMM" and nozzle_diameter[0]==0.6 and num_extruders>1 external_perimeter_extrusion_width = 0.6 external_perimeter_speed = 30 @@ -874,6 +950,7 @@ support_material_extrusion_width = 0.6 # MK2 MMU # [print:0.35mm FAST sol int 0.6 nozzle] inherits = 0.35mm FAST sol full 0.6 nozzle +alias = 0.35mm FAST SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_layers = 3 support_material_with_sheath = 0 @@ -882,6 +959,7 @@ support_material_xy_spacing = 150% # MK3 # [print:0.35mm SPEED 0.6 nozzle MK3] inherits = *0.35mm*; *0.6nozzleMK3*; *MK306* +alias = 0.35mm SPEED compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1250 @@ -917,6 +995,7 @@ top_solid_layers = 4 # MK3 # [print:0.40mm DRAFT 0.6 nozzle MK3] inherits = *0.40mm*; *0.6nozzleMK3*; *MK306* +alias = 0.40mm DRAFT compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1250 @@ -943,12 +1022,14 @@ single_extruder_multi_material_priming = 0 # MK2.5 # [print:0.15mm OPTIMAL MK2.5] inherits = 0.15mm OPTIMAL +alias = 0.15mm OPTIMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 single_extruder_multi_material_priming = 0 # MK2.5 MMU2 # [print:0.15mm OPTIMAL SOLUBLE FULL MK2.5] inherits = 0.15mm OPTIMAL SOLUBLE FULL +alias = 0.15mm OPTIMAL SOLUBLE FULL support_material_extruder = 5 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -956,6 +1037,7 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and # MK2.5 MMU2 # [print:0.15mm OPTIMAL SOLUBLE INTERFACE MK2.5] inherits = 0.15mm OPTIMAL SOLUBLE INTERFACE +alias = 0.15mm OPTIMAL SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -963,18 +1045,21 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and # MK2.5 # [print:0.20mm 100mms Linear Advance MK2.5] inherits = 0.20mm 100mms Linear Advance +alias = 0.20mm 100mms Linear Advance compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 single_extruder_multi_material_priming = 0 # MK2.5 # [print:0.20mm NORMAL MK2.5] inherits = 0.20mm NORMAL +alias = 0.20mm NORMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 single_extruder_multi_material_priming = 0 # MK2.5 MMU2 # [print:0.20mm NORMAL SOLUBLE FULL MK2.5] inherits = 0.20mm NORMAL SOLUBLE FULL +alias = 0.20mm NORMAL SOLUBLE FULL support_material_extruder = 5 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -983,6 +1068,7 @@ single_extruder_multi_material_priming = 0 # MK2.5 MMU2 # [print:0.20mm NORMAL SOLUBLE INTERFACE MK2.5] inherits = 0.20mm NORMAL SOLUBLE INTERFACE +alias = 0.20mm NORMAL SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -991,12 +1077,14 @@ single_extruder_multi_material_priming = 0 # MK2.5 # [print:0.35mm FAST MK2.5] inherits = 0.35mm FAST +alias = 0.35mm FAST compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 single_extruder_multi_material_priming = 0 # MK2.5 MMU2 0.6 nozzle# [print:0.35mm SOLUBLE FULL 0.6 nozzle MK2.5] inherits = *0.35mm*; *0.6nozzle*; *soluble_support* +alias = 0.35mm SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and printer_model!="MK2SMM" and nozzle_diameter[0]==0.6 and num_extruders>1 external_perimeter_extrusion_width = 0.6 external_perimeter_speed = 30 @@ -1012,11 +1100,154 @@ support_material_extrusion_width = 0.6 [print:0.35mm SOLUBLE INTERFACE 0.6 nozzle MK2.5] inherits = 0.35mm SOLUBLE FULL 0.6 nozzle MK2.5 +alias = 0.35mm SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_layers = 3 support_material_with_sheath = 0 support_material_xy_spacing = 80% +## MINI print profiles + +# 0.4mm nozzle + +[print:0.05mm ULTRADETAIL MINI] +inherits = *0.05mm*; *MINI* +alias = 0.05mm ULTRADETAIL +fill_pattern = gyroid +fill_density = 15% +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +top_infill_extrusion_width = 0.4 +small_perimeter_speed = 15 +perimeter_extrusion_width = 0.4 +external_perimeter_extrusion_width = 0.4 + +[print:0.07mm ULTRADETAIL MINI] +inherits = *0.07mm*; *MINI* +alias = 0.07mm ULTRADETAIL +fill_pattern = gyroid +fill_density = 15% +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +top_infill_extrusion_width = 0.4 +small_perimeter_speed = 15 +perimeter_extrusion_width = 0.4 +external_perimeter_extrusion_width = 0.4 + +[print:0.10mm DETAIL MINI] +inherits = *0.10mm*; *MINI* +alias = 0.10mm DETAIL +bridge_speed = 30 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +perimeter_speed = 40 +external_perimeter_speed = 30 +infill_speed = 80 +solid_infill_speed = 80 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 40 +fill_pattern = gyroid +fill_density = 15% +perimeters = 3 +bridge_acceleration = 800 + +[print:0.15mm QUALITY MINI] +inherits = *0.15mm*; *MINI* +alias = 0.15mm QUALITY +bridge_speed = 30 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +perimeter_speed = 40 +external_perimeter_speed = 30 +infill_speed = 80 +solid_infill_speed = 80 +top_solid_infill_speed = 40 +fill_pattern = gyroid +fill_density = 15% +bridge_flow_ratio = 0.85 + +[print:0.15mm SPEED MINI] +inherits = *0.15mm*; *MINI* +alias = 0.15mm SPEED +bridge_speed = 30 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +perimeter_speed = 50 +external_perimeter_speed = 40 +infill_speed = 140 +solid_infill_speed = 140 +top_solid_infill_speed = 40 +bridge_flow_ratio = 0.85 + +[print:0.20mm QUALITY MINI] +inherits = *0.20mm*; *MINI* +alias = 0.20mm QUALITY +bridge_speed = 30 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +perimeter_speed = 40 +external_perimeter_speed = 30 +infill_speed = 80 +solid_infill_speed = 80 +top_solid_infill_speed = 40 +fill_pattern = gyroid +fill_density = 15% + +[print:0.20mm SPEED MINI] +inherits = *0.20mm*; *MINI* +alias = 0.20mm SPEED +bridge_speed = 30 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +perimeter_speed = 50 +external_perimeter_speed = 40 +infill_speed = 140 +max_print_speed = 150 +solid_infill_speed = 140 +top_solid_infill_speed = 40 + +[print:0.25mm DRAFT MINI] +inherits = *0.25mm*; *MINI* +alias = 0.25mm DRAFT +bridge_speed = 30 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 +external_perimeter_speed = 40 +infill_speed = 90 +perimeter_speed = 50 +small_perimeter_speed = 25 +solid_infill_speed = 85 +top_solid_infill_speed = 45 +first_layer_extrusion_width = 0.42 +infill_extrusion_width = 0.48 +solid_infill_extrusion_width = 0.48 +top_infill_extrusion_width = 0.4 + +# 0.25mm nozzle +[print:0.05mm ULTRADETAIL 0.25 nozzle MINI] +inherits = *0.05mm*; *0.25nozzle*; *MINI* +alias = 0.05mm ULTRADETAIL +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 +fill_pattern = grid +fill_density = 20% + +[print:0.07mm ULTRADETAIL 0.25 nozzle MINI] +inherits = *0.07mm*; *0.25nozzle*; *MINI* +alias = 0.07mm ULTRADETAIL +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 +infill_speed = 30 +solid_infill_speed = 30 +support_material_speed = 30 +top_solid_infill_speed = 20 +fill_pattern = grid +fill_density = 20% + +[print:0.10mm DETAIL 0.25 nozzle MINI] +inherits = *0.10mm*; *0.25nozzleMINI*; *MINI* +alias = 0.10mm DETAIL +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 +fill_pattern = grid +fill_density = 20% + +[print:0.15mm QUALITY 0.25 nozzle MINI] +inherits = *0.15mm*; *0.25nozzleMINI*; *MINI* +alias = 0.15mm QUALITY +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 +fill_pattern = grid +fill_density = 20% + # XXXXXXxxXXXXXXXXXXXXXX # XXX--- filament ---XXX # XXXXXXXXxxXXXXXXXXXXXX @@ -1048,7 +1279,7 @@ filament_settings_id = "" filament_soluble = 0 min_print_speed = 15 slowdown_below_layer_time = 20 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif} ; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif} ; Filament gcode" [filament:*PLA*] inherits = *common* @@ -1057,7 +1288,7 @@ bridge_fan_speed = 100 disable_fan_first_layers = 1 fan_always_on = 1 fan_below_layer_time = 100 -filament_colour = #FF3232 +filament_colour = #FF8000 filament_max_volumetric_speed = 15 filament_type = PLA first_layer_bed_temperature = 60 @@ -1065,7 +1296,7 @@ first_layer_temperature = 215 max_fan_speed = 100 min_fan_speed = 100 temperature = 210 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}18{else}30{endif} ; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}18{else}30{endif} ; Filament gcode" [filament:*PET*] inherits = *common* @@ -1076,7 +1307,7 @@ fan_always_on = 1 fan_below_layer_time = 20 filament_colour = #FF8000 filament_max_volumetric_speed = 8 -filament_type = PET +filament_type = PETG first_layer_bed_temperature = 85 first_layer_temperature = 230 max_fan_speed = 50 @@ -1085,7 +1316,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el temperature = 240 filament_retract_length = 1.4 filament_retract_lift = 0.2 -compatible_printers_condition = printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:*PET06*] inherits = *PET* @@ -1099,6 +1330,49 @@ filament_retract_speed = nil filament_retract_lift = 0.2 compatible_printers_condition = printer_model=="MK2SMM" +[filament:*PETMINI*] +inherits = *PET* +filament_retract_length = nil +filament_retract_speed = 40 +filament_deretract_speed = 25 +filament_retract_lift = nil +filament_retract_before_travel = 1 +filament_max_volumetric_speed = 7 +compatible_printers_condition = printer_model=="MINI" +start_filament_gcode = "M900 K0.2 ; Filament gcode" + +[filament:*ABSMINI*] +inherits = *ABS* +bed_temperature = 100 +filament_retract_length = 2.7 +filament_retract_speed = nil +filament_deretract_speed = nil +filament_retract_lift = nil +filament_retract_before_travel = 3 +filament_wipe = 0 +filament_max_volumetric_speed = 10 +compatible_printers_condition = printer_model=="MINI" +start_filament_gcode = "M900 K0.2 ; Filament gcode" + +[filament:*FLEXMINI*] +inherits = *FLEX* +filament_retract_length = 6 +filament_retract_speed = 40 +filament_deretract_speed = 15 +filament_retract_lift = 0 +filament_retract_before_travel = 7 +filament_wipe = 0 +bridge_fan_speed = 70 +fan_always_on = 1 +cooling = 0 +max_fan_speed = 40 +min_fan_speed = 40 +filament_max_volumetric_speed = 1.6 +compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model=="MINI" +disable_fan_first_layers = 3 +extrusion_multiplier = 1.2 +start_filament_gcode = "M900 K0 ; Filament gcode" + [filament:*ABS*] inherits = *common* bed_temperature = 110 @@ -1117,13 +1391,14 @@ max_fan_speed = 30 min_fan_speed = 20 temperature = 255 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{elsif nozzle_diameter[0]==0.6}18{else}30{endif} ; Filament gcode" +compatible_printers_condition = printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:*FLEX*] inherits = *common* bed_temperature = 50 -bridge_fan_speed = 100 +bridge_fan_speed = 80 # For now, all but selected filaments are disabled for the MMU 2.0 -compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MK2SMM" and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MK2SMM" and printer_model!="MINI" and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) cooling = 0 disable_fan_first_layers = 1 extrusion_multiplier = 1.2 @@ -1141,27 +1416,46 @@ temperature = 240 filament_retract_length = 0.4 filament_retract_lift = 0 -[filament:ColorFabb Brass Bronze] +[filament:ColorFabb bronzeFill] inherits = *PLA* -# For now, all but selected filaments are disabled for the MMU 2.0 +filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.2 -filament_cost = 56.64 +filament_cost = 72.89 filament_density = 3.9 filament_colour = #804040 filament_max_volumetric_speed = 9 -filament_notes = "List of materials tested with standard print settings:\n\nColorFabb bronzeFill\nColorFabb brassFill\nColorFabb steelFill\nColorFabb copperFill" + +[filament:ColorFabb steelFill] +inherits = *PLA* filament_vendor = ColorFabb +compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +extrusion_multiplier = 1.2 +filament_cost = 72.89 +filament_density = 3.13 +filament_colour = #808080 +filament_max_volumetric_speed = 8 + +[filament:ColorFabb copperFill] +inherits = *PLA* +filament_vendor = ColorFabb +compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +extrusion_multiplier = 1.2 +filament_cost = 72.89 +filament_density = 3.9 +filament_colour = #82603E +filament_max_volumetric_speed = 9 [filament:ColorFabb HT] inherits = *PET* +filament_vendor = ColorFabb bed_temperature = 110 bridge_fan_speed = 30 cooling = 1 disable_fan_first_layers = 3 fan_always_on = 0 fan_below_layer_time = 10 -filament_cost = 58.66 +filament_cost = 65.66 filament_density = 1.18 first_layer_bed_temperature = 105 first_layer_temperature = 270 @@ -1169,56 +1463,53 @@ max_fan_speed = 20 min_fan_speed = 10 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 -filament_vendor = ColorFabb [filament:ColorFabb PLA-PHA] inherits = *PLA* -filament_cost = 55.5 -filament_density = 1.24 filament_vendor = ColorFabb +filament_cost = 52.46 +filament_density = 1.24 [filament:ColorFabb woodFill] inherits = *PLA* -# For now, all but selected filaments are disabled for the MMU 2.0 +filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.2 -filament_cost = 62.9 +filament_cost = 58.30 filament_density = 1.15 filament_colour = #dfc287 -filament_max_volumetric_speed = 10 +filament_max_volumetric_speed = 9 first_layer_temperature = 200 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 200 -filament_vendor = ColorFabb [filament:ColorFabb corkFill] inherits = *PLA* +filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.2 -filament_cost = 45.45 +filament_cost = 58.30 filament_density = 1.18 filament_colour = #634d33 filament_max_volumetric_speed = 6 first_layer_temperature = 220 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 220 -filament_vendor = ColorFabb [filament:ColorFabb XT] inherits = *PET* -filament_type = PET -filament_cost = 62.9 +filament_vendor = ColorFabb +filament_cost = 58.30 filament_density = 1.27 first_layer_bed_temperature = 90 first_layer_temperature = 260 temperature = 270 -filament_vendor = ColorFabb [filament:ColorFabb XT-CF20] inherits = *PET* -compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +filament_vendor = ColorFabb extrusion_multiplier = 1.2 -filament_cost = 80.65 +filament_cost = 72.89 filament_density = 1.35 filament_colour = #804040 filament_max_volumetric_speed = 1 @@ -1228,11 +1519,11 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el temperature = 260 filament_retract_length = nil filament_retract_lift = 0.2 -filament_vendor = ColorFabb [filament:ColorFabb nGen] inherits = *PET* -filament_cost = 21.2 +filament_vendor = ColorFabb +filament_cost = 52.46 filament_density = 1.2 bridge_fan_speed = 40 fan_always_on = 0 @@ -1241,11 +1532,11 @@ filament_type = NGEN first_layer_temperature = 240 max_fan_speed = 35 min_fan_speed = 20 -filament_vendor = ColorFabb [filament:ColorFabb nGen flex] inherits = *FLEX* -filament_cost = 0 +filament_vendor = ColorFabb +filament_cost = 58.30 filament_density = 1 bed_temperature = 85 bridge_fan_speed = 40 @@ -1261,35 +1552,42 @@ min_fan_speed = 20 temperature = 260 filament_retract_length = nil filament_retract_lift = 0 -compatible_printers_condition = nozzle_diameter[0]>0.35 and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) -filament_vendor = ColorFabb +compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MINI" and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) [filament:E3D Edge] inherits = *PET* +filament_vendor = E3D filament_cost = 56.9 filament_density = 1.26 filament_type = EDGE -filament_vendor = E3D +compatible_printers_condition = printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:E3D PC-ABS] inherits = *ABS* +filament_vendor = E3D filament_cost = 0 filament_type = PC filament_density = 1.05 first_layer_temperature = 270 temperature = 270 -filament_vendor = E3D + +[filament:Fillamentum PLA] +inherits = *PLA* +filament_vendor = Fillamentum +filament_cost = 25.4 +filament_density = 1.24 [filament:Fillamentum ABS] inherits = *ABS* +filament_vendor = Fillamentum filament_cost = 32.4 filament_density = 1.04 first_layer_temperature = 240 temperature = 240 -filament_vendor = Fillamentum [filament:Fillamentum ASA] inherits = *ABS* +filament_vendor = Fillamentum filament_cost = 38.7 filament_density = 1.07 fan_always_on = 1 @@ -1301,10 +1599,10 @@ slowdown_below_layer_time = 15 first_layer_temperature = 265 temperature = 265 filament_type = ASA -filament_vendor = Fillamentum [filament:Prusament ASA] inherits = *ABS* +filament_vendor = Prusa Polymers filament_cost = 35.28 filament_density = 1.07 fan_always_on = 1 @@ -1324,6 +1622,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el [filament:Fillamentum CPE] inherits = *PET* +filament_vendor = Fillamentum filament_cost = 54.1 filament_density = 1.25 filament_type = CPE @@ -1332,11 +1631,10 @@ first_layer_temperature = 275 max_fan_speed = 50 min_fan_speed = 50 temperature = 275 -filament_vendor = Fillamentum [filament:Fillamentum Timberfill] inherits = *PLA* -# For now, all but selected filaments are disabled for the MMU 2.0 +filament_vendor = Fillamentum compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.2 filament_cost = 68 @@ -1344,33 +1642,33 @@ filament_density = 1.15 filament_colour = #804040 filament_max_volumetric_speed = 10 first_layer_temperature = 190 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 190 -filament_vendor = Fillamentum [filament:Generic ABS] inherits = *ABS* +filament_vendor = Generic filament_cost = 27.82 filament_density = 1.04 filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS" -filament_vendor = Generic [filament:Generic PET] inherits = *PET* +filament_vendor = Generic filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladec PETG" -filament_vendor = Generic [filament:Generic PLA] inherits = *PLA* +filament_vendor = Generic filament_cost = 25.4 filament_density = 1.24 filament_notes = "List of materials tested with standard PLA print settings:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH" -filament_vendor = Generic [filament:Generic FLEX] inherits = *FLEX* +filament_vendor = Generic filament_cost = 82 filament_density = 1.22 filament_max_volumetric_speed = 1.2 @@ -1380,6 +1678,7 @@ filament_retract_lift = nil [filament:Polymaker PC-Max] inherits = *ABS* +filament_vendor = Polymaker filament_cost = 77.3 filament_density = 1.20 filament_type = PC @@ -1388,10 +1687,11 @@ filament_colour = #3A80CA first_layer_bed_temperature = 100 first_layer_temperature = 270 temperature = 270 -filament_vendor = Polymaker +bridge_fan_speed = 0 [filament:PrimaSelect PVA+] inherits = *PLA* +filament_vendor = PrimaSelect filament_cost = 108 filament_density = 1.23 cooling = 0 @@ -1403,16 +1703,15 @@ filament_ramming_parameters = "120 100 8.3871 8.6129 8.93548 9.22581 9.48387 9.7 filament_soluble = 1 filament_type = PVA first_layer_temperature = 195 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 195 -filament_vendor = PrimaSelect [filament:Prusa ABS] inherits = *ABS* +filament_vendor = Prusa filament_cost = 27.82 filament_density = 1.08 filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS" -filament_vendor = Prusa [filament:*ABS MMU2*] inherits = Prusa ABS @@ -1429,10 +1728,13 @@ filament_unloading_speed = 20 [filament:Generic ABS MMU2] inherits = *ABS MMU2* +alias = Generic ABS filament_vendor = Generic [filament:Prusament ASA MMU2] inherits = *ABS MMU2* +alias = Prusament ASA +filament_vendor = Prusa Polymers filament_cost = 35.28 filament_density = 1.07 fan_always_on = 1 @@ -1455,10 +1757,12 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el [filament:Prusa ABS MMU2] inherits = *ABS MMU2* +alias = Prusa ABS filament_vendor = Prusa [filament:Prusa HIPS] inherits = *ABS* +filament_vendor = Prusa filament_cost = 27.3 filament_density = 1.04 bridge_fan_speed = 50 @@ -1472,43 +1776,44 @@ filament_type = HIPS first_layer_temperature = 220 max_fan_speed = 20 min_fan_speed = 20 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 220 -filament_vendor = Prusa [filament:Prusa PET] inherits = *PET* +filament_vendor = Prusa filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG" -compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) -filament_vendor = Prusa +compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:Prusament PETG] inherits = *PET* +filament_vendor = Prusa Polymers first_layer_temperature = 240 temperature = 250 filament_cost = 24.99 filament_density = 1.27 filament_type = PETG -compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) -filament_vendor = Prusa +compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:Prusa PET 0.6 nozzle] inherits = *PET06* +alias = Prusa PET +filament_vendor = Prusa filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG" -filament_vendor = Prusa [filament:Prusament PETG 0.6 nozzle] inherits = *PET06* +alias = Prusament PETG +filament_vendor = Prusa Polymers first_layer_temperature = 240 temperature = 250 filament_cost = 24.99 filament_density = 1.27 filament_type = PETG -filament_vendor = Prusa [filament:*PET MMU2*] inherits = Prusa PET @@ -1536,42 +1841,50 @@ filament_max_volumetric_speed = 13 [filament:Generic PET MMU2] inherits = *PET MMU2* +alias = Generic PET filament_vendor = Generic [filament:Prusa PET MMU2] inherits = *PET MMU2* +alias = Prusa PET filament_vendor = Prusa [filament:Prusament PETG MMU2] inherits = *PET MMU2* filament_type = PETG +alias = Prusament PETG +filament_vendor = Prusa Polymers [filament:Generic PET MMU2 0.6 nozzle] inherits = *PET MMU2 06* +alias = Generic PET +filament_vendor = Generic [filament:Prusa PET MMU2 0.6 nozzle] inherits = *PET MMU2 06* +alias = Prusa PET filament_vendor = Prusa [filament:Prusament PETG MMU2 0.6 nozzle] inherits = *PET MMU2 06* filament_type = PETG -filament_vendor = Prusa +alias = Prusament PETG +filament_vendor = Prusa Polymers [filament:Prusa PLA] inherits = *PLA* +filament_vendor = Prusa filament_cost = 25.4 filament_density = 1.24 -filament_notes = "List of materials tested with standard PLA print settings:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFiberlogy PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nAmazonBasics PLA" -filament_vendor = Prusa +filament_notes = "List of materials tested with standard PLA print settings:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFiberlogy PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nAmazonBasics PLA" [filament:Prusament PLA] inherits = *PLA* +filament_vendor = Prusa Polymers temperature = 215 filament_cost = 24.99 filament_density = 1.24 filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa" -filament_vendor = Prusa [filament:*PLA MMU2*] inherits = Prusa PLA @@ -1591,25 +1904,29 @@ filament_unloading_speed_start = 100 [filament:Generic PLA MMU2] inherits = *PLA MMU2* +alias = Generic PLA filament_vendor = Generic [filament:Prusa PLA MMU2] inherits = *PLA MMU2* +alias = Prusa PLA filament_vendor = Prusa [filament:Prusament PLA MMU2] inherits = *PLA MMU2* -filament_vendor = Prusa +alias = Prusament PLA +filament_vendor = Prusa Polymers [filament:SemiFlex or Flexfill 98A] inherits = *FLEX* +filament_vendor = Generic filament_cost = 82 filament_density = 1.22 filament_max_volumetric_speed = 1.35 -filament_vendor = Flexfill [filament:Taulman Bridge] inherits = *common* +filament_vendor = Taulman filament_cost = 40 filament_density = 1.13 bed_temperature = 90 @@ -1626,12 +1943,12 @@ first_layer_bed_temperature = 60 first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 250 -filament_vendor = Taulman [filament:Taulman T-Glase] inherits = *PET* +filament_vendor = Taulman filament_cost = 40 filament_density = 1.27 bridge_fan_speed = 40 @@ -1642,10 +1959,16 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" -filament_vendor = Taulman + +[filament:Verbatim PLA] +inherits = *PLA* +filament_vendor = Verbatim +filament_cost = 42.99 +filament_density = 1.24 [filament:Verbatim BVOH] inherits = *common* +filament_vendor = Verbatim filament_cost = 218 filament_density = 1.23 bed_temperature = 60 @@ -1664,12 +1987,13 @@ first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 min_fan_speed = 100 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 210 -filament_vendor = Verbatim [filament:Verbatim BVOH MMU2] inherits = Verbatim BVOH +alias = Verbatim BVOH +filament_vendor = Verbatim compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material temperature = 195 fan_always_on = 1 @@ -1686,10 +2010,11 @@ filament_unload_time = 12 filament_unloading_speed = 20 filament_unloading_speed_start = 100 filament_loading_speed_start = 19 -filament_vendor = Verbatim [filament:PrimaSelect PVA+ MMU2] inherits = *common* +alias = PrimaSelect PVA+ +filament_vendor = PrimaSelect compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material bed_temperature = 60 bridge_fan_speed = 100 @@ -1725,10 +2050,10 @@ min_print_speed = 15 slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 195 -filament_vendor = PrimaSelect [filament:Verbatim PP] inherits = *common* +filament_vendor = Verbatim filament_cost = 72 filament_density = 0.89 bed_temperature = 100 @@ -1746,14 +2071,15 @@ first_layer_bed_temperature = 100 first_layer_temperature = 220 max_fan_speed = 100 min_fan_speed = 100 -start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/}0{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}0{else}10{endif}; Filament gcode" temperature = 220 -filament_vendor = Verbatim ## Filaments MMU1 [filament:ColorFabb HT MMU1] inherits = *PETMMU1* +alias = ColorFabb HT +filament_vendor = ColorFabb bed_temperature = 110 bridge_fan_speed = 30 cooling = 1 @@ -1771,7 +2097,9 @@ temperature = 270 [filament:ColorFabb XT MMU1] inherits = *PETMMU1* -filament_type = PET +alias = ColorFabb XT +filament_vendor = ColorFabb +filament_type = PETG filament_cost = 62.9 filament_density = 1.27 first_layer_bed_temperature = 90 @@ -1780,6 +2108,8 @@ temperature = 270 [filament:ColorFabb XT-CF20 MMU1] inherits = *PETMMU1* +alias = ColorFabb XT-CF20 +filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model=="MK2SMM" extrusion_multiplier = 1.2 filament_cost = 80.65 @@ -1793,6 +2123,8 @@ temperature = 260 [filament:ColorFabb nGen MMU1] inherits = *PETMMU1* +alias = ColorFabb nGen +filament_vendor = ColorFabb filament_cost = 21.2 filament_density = 1.2 bridge_fan_speed = 40 @@ -1805,6 +2137,8 @@ min_fan_speed = 20 [filament:E3D Edge MMU1] inherits = *PETMMU1* +alias = E3D Edge +filament_vendor = E3D filament_cost = 56.9 filament_density = 1.26 filament_type = EDGE @@ -1812,6 +2146,8 @@ filament_notes = "List of manufacturers tested with standard PET print settings: [filament:Fillamentum CPE MMU1] inherits = *PETMMU1* +alias = Fillamentum CPE +filament_vendor = Fillamentum filament_cost = 54.1 filament_density = 1.25 filament_type = CPE @@ -1823,18 +2159,24 @@ temperature = 275 [filament:Generic PET MMU1] inherits = *PETMMU1* +alias = Generic PET +filament_vendor = Generic filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladec PETG" [filament:Prusa PET MMU1] inherits = *PETMMU1* +alias = Prusa PET +filament_vendor = Prusa filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG" [filament:Prusament PETG MMU1] inherits = *PETMMU1* +alias = Prusament PETG +filament_vendor = Prusa Polymers first_layer_temperature = 240 temperature = 250 filament_cost = 24.99 @@ -1843,6 +2185,8 @@ filament_type = PETG [filament:Taulman T-Glase MMU1] inherits = *PETMMU1* +alias = Taulman T-Glase +filament_vendor = Taulman filament_cost = 40 filament_density = 1.27 bridge_fan_speed = 40 @@ -1856,6 +2200,8 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el [filament:SemiFlex or Flexfill 98A MMU1] inherits = *FLEX* +alias = SemiFlex or Flexfill 98A +filament_vendor = Generic filament_cost = 82 filament_density = 1.22 filament_max_volumetric_speed = 1.35 @@ -1866,6 +2212,8 @@ compatible_printers_condition = printer_model=="MK2SMM" [filament:Generic FLEX MMU1] inherits = *FLEX* +alias = Generic FLEX +filament_vendor = Generic filament_cost = 82 filament_density = 1.22 filament_max_volumetric_speed = 1.2 @@ -1874,6 +2222,195 @@ filament_retract_speed = nil filament_retract_lift = nil compatible_printers_condition = printer_model=="MK2SMM" +## Filaments MINI + +[filament:Generic PET MINI] +inherits = Generic PET; *PETMINI* +alias = Generic PET + +[filament:Generic ABS MINI] +inherits = Generic ABS; *ABSMINI* +alias = Generic ABS + +[filament:Prusament PETG MINI] +inherits = Prusament PETG; *PETMINI* +alias = Prusament PETG + +[filament:Prusament ASA MINI] +inherits = Prusament ASA; *ABSMINI* +alias = Prusament ASA +first_layer_temperature = 260 +first_layer_bed_temperature = 100 +temperature = 260 +bed_temperature = 100 +fan_always_on = 1 +cooling = 1 +min_fan_speed = 20 +max_fan_speed = 20 +min_print_speed = 15 +slowdown_below_layer_time = 15 +disable_fan_first_layers = 4 +filament_type = ASA +filament_colour = #FFF2EC + +[filament:Fillamentum Flexfill 98A MINI] +inherits = SemiFlex or Flexfill 98A; *FLEXMINI* +alias = Fillamentum Flexfill 98A +filament_vendor = Fillamentum +filament_max_volumetric_speed = 1.6 + +[filament:Fillamentum CPE MINI] +inherits = Fillamentum CPE; *PETMINI* +alias = Fillamentum CPE +first_layer_temperature = 265 +first_layer_bed_temperature = 90 +temperature = 265 + +[filament:ColorFabb nGen MINI] +inherits = ColorFabb nGen; *PETMINI* +alias = ColorFabb nGen + +[filament:ColorFabb nGen flex MINI] +inherits = ColorFabb nGen flex; *FLEXMINI* +alias = ColorFabb nGen flex +filament_max_volumetric_speed = 4 + +[filament:E3D PC-ABS MINI] +inherits = E3D PC-ABS; *ABSMINI* +alias = E3D PC-ABS + +[filament:Fillamentum ABS MINI] +inherits = Fillamentum ABS; *ABSMINI* +alias = Fillamentum ABS + +[filament:Fillamentum ASA MINI] +inherits = Fillamentum ASA; *ABSMINI* +alias = Fillamentum ASA +first_layer_temperature = 255 +first_layer_bed_temperature = 100 +temperature = 255 +bed_temperature = 100 +fan_always_on = 1 +cooling = 1 +min_fan_speed = 20 +max_fan_speed = 20 +min_print_speed = 15 +slowdown_below_layer_time = 15 +disable_fan_first_layers = 4 +filament_type = ASA +filament_colour = #FFF2EC + +[filament:Polymaker PC-Max MINI] +inherits = Polymaker PC-Max; *ABSMINI* +alias = Polymaker PC-Max +filament_type = PC +bed_temperature = 100 +filament_colour = #3A80CA +first_layer_bed_temperature = 100 +first_layer_temperature = 270 +temperature = 270 +bridge_fan_speed = 0 + +[filament:Prusa ABS MINI] +inherits = *ABSMINI* +alias = Prusa ABS +filament_vendor = Prusa + +[filament:Generic HIPS MINI] +inherits = *ABSMINI* +alias = Generic HIPS +filament_vendor = Generic +filament_cost = 27.3 +filament_density = 1.04 +bridge_fan_speed = 50 +cooling = 1 +extrusion_multiplier = 0.9 +fan_always_on = 1 +fan_below_layer_time = 10 +filament_colour = #FFFFD7 +filament_soluble = 1 +filament_type = HIPS +first_layer_temperature = 230 +max_fan_speed = 20 +min_fan_speed = 20 +start_filament_gcode = "M900 K0.2 ; Filament gcode" +temperature = 230 + +[filament:ColorFabb HT MINI] +inherits = *PETMINI* +alias = ColorFabb HT +filament_vendor = ColorFabb +bed_temperature = 100 +bridge_fan_speed = 30 +cooling = 1 +disable_fan_first_layers = 3 +fan_always_on = 0 +fan_below_layer_time = 10 +filament_cost = 58.66 +filament_density = 1.18 +first_layer_bed_temperature = 100 +first_layer_temperature = 270 +max_fan_speed = 20 +min_fan_speed = 10 +start_filament_gcode = "M900 K0.2 ; Filament gcode" +temperature = 270 + +[filament:ColorFabb XT MINI] +inherits = *PETMINI* +alias = ColorFabb XT +filament_vendor = ColorFabb +filament_type = PETG +filament_cost = 62.9 +filament_density = 1.27 +first_layer_bed_temperature = 90 +first_layer_temperature = 260 +temperature = 270 + +[filament:ColorFabb XT-CF20 MINI] +inherits = *PETMINI* +alias = ColorFabb XT-CF20 +filament_vendor = ColorFabb +compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model=="MINI" +extrusion_multiplier = 1.2 +filament_cost = 80.65 +filament_density = 1.35 +filament_colour = #804040 +filament_max_volumetric_speed = 1 +first_layer_bed_temperature = 90 +first_layer_temperature = 260 +start_filament_gcode = "M900 K0.2 ; Filament gcode" +temperature = 260 + +[filament:Taulman T-Glase MINI] +inherits = *PETMINI* +alias = Taulman T-Glase +filament_vendor = Taulman +filament_cost = 40 +filament_density = 1.27 +bridge_fan_speed = 40 +cooling = 0 +fan_always_on = 0 +first_layer_bed_temperature = 90 +first_layer_temperature = 240 +max_fan_speed = 5 +min_fan_speed = 0 +start_filament_gcode = "M900 K0.2 ; Filament gcode" + +[filament:E3D Edge MINI] +inherits = *PETMINI* +alias = E3D Edge +filament_vendor = E3D +filament_cost = 56.9 +filament_density = 1.26 +filament_type = EDGE + +[filament:Prusa PET MINI] +inherits = *PETMINI* +alias = Prusa PET +filament_vendor = Prusa +filament_cost = 27.82 +filament_density = 1.27 + [sla_print:*common*] compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_SL1.*/ layer_height = 0.05 @@ -1921,7 +2458,7 @@ support_head_front_diameter = 0.5 support_head_penetration = 0.5 support_pillar_diameter = 1.3 -########### Materials 0.025 +########### Materials [sla_material:*common 0.05*] compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_SL1.*/ @@ -1955,209 +2492,421 @@ initial_layer_height = 0.1 ########### Materials 0.025 +[sla_material:3DM-ABS 0.025] +inherits = *common 0.025* +exposure_time = 12 +initial_exposure_time = 35 +material_type = Tough +material_vendor = 3DM + +[sla_material:3DM-Vulcan Gold 0.025] +inherits = *common 0.025* +exposure_time = 12 +initial_exposure_time = 30 +material_type = Tough +material_vendor = 3DM + [sla_material:BlueCast Phrozen Wax 0.025] inherits = *common 0.025* exposure_time = 15 initial_exposure_time = 50 +material_type = Tough +material_vendor = BlueCast [sla_material:BlueCast EcoGray 0.025] inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 40 +material_type = Tough +material_vendor = BlueCast -[sla_material:BlueCast Keramaster Dental 0.025] -material_type = Dental +[sla_material:BlueCast Kera Master Dental 0.025] inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 45 -material_vendor = Bluecast +material_type = Dental +material_vendor = BlueCast [sla_material:BlueCast X10 0.025] inherits = *common 0.025* exposure_time = 4 initial_exposure_time = 100 +material_type = Tough +material_vendor = BlueCast +[sla_material:Esun Bio-Photopolymer Resin White 0.025] +inherits = *common 0.025* +exposure_time = 5 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Esun + +[sla_material:Esun Standard Resin Black 0.025] +inherits = *common 0.025* +exposure_time = 6 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Esun + +[sla_material:Photocentric Ash Grey 0.025] +inherits = *common 0.025* +exposure_time = 9 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Photocentric + +[sla_material:Resinworks 3D Violet 0.025] +inherits = *common 0.025* +exposure_time = 15 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Resinworks 3D + +[sla_material:Resinworks 3D Green 0.025] +inherits = *common 0.025* +exposure_time = 17 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Resinworks 3D + +## Prusa [sla_material:Prusa Orange Tough 0.025] inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa [sla_material:Prusa Grey Tough 0.025] inherits = *common 0.025* exposure_time = 7 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Azure Blue Tough 0.025] inherits = *common 0.025* exposure_time = 7 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa + [sla_material:Prusa Maroon Tough 0.025] inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Beige Tough 0.025] inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Pink Tough 0.025] inherits = *common 0.025* exposure_time = 7 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa White Tough 0.025] inherits = *common 0.025* exposure_time = 6.5 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Transparent Tough 0.025] inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 15 +material_type = Tough +material_vendor = Prusa -[sla_material:Prusa Green Casting 0.025] +[sla_material:Prusa Green Dental Casting 0.025] inherits = *common 0.025* exposure_time = 12 -initial_exposure_time = 35 +initial_exposure_time = 40 +material_type = Casting +material_vendor = Prusa -## [sla_material:Prusa Transparent Green Tough 0.025] +[sla_material:Prusa Transparent Green Tough 0.025] +inherits = *common 0.025* +exposure_time = 5 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Clear ABS like 0.025] +inherits = *common 0.025* +exposure_time = 6 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa + +## [sla_material:Prusa ABS like White 0.025] ## inherits = *common 0.025* -## exposure_time = 5 -## initial_exposure_time = 35 +## exposure_time = 6 +## initial_exposure_time = 30 + +[sla_material:Prusa Grey High Tenacity 0.025] +inherits = *common 0.025* +exposure_time = 5 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Cyan Super Low Odor 0.025] +inherits = *common 0.025* +exposure_time = 5 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Magenta Super Low Odor 0.025] +inherits = *common 0.025* +exposure_time = 5 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Yellow Super Low Odor 0.025] +inherits = *common 0.025* +exposure_time = 5 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Orange-Yellow Teeth Model 0.025] +inherits = *common 0.025* +exposure_time = 5 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa + ########### Materials 0.05 +[sla_material:Asiga Denta Model 0.05] +inherits = *common 0.05* +exposure_time = 15 +initial_exposure_time = 30 +material_type = Dental +material_vendor = Asiga + +[sla_material:Ameralabs AMD 3 LED 0.05] +inherits = *common 0.05* +exposure_time = 5 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Ameralabs + [sla_material:BlueCast EcoGray 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 35 -material_vendor = Bluecast +material_type = Tough +material_vendor = BlueCast -[sla_material:BlueCast Keramaster 0.05] -inherits = *common 0.05* -exposure_time = 8 -initial_exposure_time = 45 -material_vendor = Bluecast - -[sla_material:BlueCast Keramaster Dental 0.05] -material_type = Dental +[sla_material:BlueCast Kera Master Dental 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 50 -material_vendor = Bluecast +material_type = Dental +material_vendor = BlueCast [sla_material:BlueCast LCD-DLP Original 0.05] inherits = *common 0.05* exposure_time = 10 initial_exposure_time = 60 -material_vendor = Bluecast +material_type = Tough +material_vendor = BlueCast [sla_material:BlueCast Phrozen Wax 0.05] inherits = *common 0.05* exposure_time = 16 initial_exposure_time = 50 -material_vendor = Bluecast +material_type = Tough +material_vendor = BlueCast [sla_material:BlueCast S+ 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 45 -material_vendor = Bluecast +material_type = Tough +material_vendor = BlueCast + +[sla_material:BlueCast X5 0.05] +inherits = *common 0.05* +exposure_time = 9 +initial_exposure_time = 100 +material_type = Tough +material_vendor = BlueCast [sla_material:BlueCast X10 0.05] inherits = *common 0.05* exposure_time = 6 initial_exposure_time = 100 +material_type = Tough +material_vendor = BlueCast + +[sla_material:BlueCast 23LS 0.05] +inherits = *common 0.05* +exposure_time = 8 +initial_exposure_time = 50 +material_type = Tough +material_vendor = BlueCast [sla_material:Monocure 3D Black Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 6 initial_exposure_time = 40 +material_type = Tough material_vendor = Monocure [sla_material:Monocure 3D Blue Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 40 +material_type = Tough material_vendor = Monocure [sla_material:Monocure 3D Clear Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 40 +material_type = Tough material_vendor = Monocure [sla_material:Monocure 3D Grey Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 10 initial_exposure_time = 30 +material_type = Tough material_vendor = Monocure [sla_material:Monocure 3D White Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 40 +material_type = Tough material_vendor = Monocure [sla_material:3DM-HTR140 (high temperature) 0.05] inherits = *common 0.05* exposure_time = 12 initial_exposure_time = 45 +material_type = Tough +material_vendor = Monocure + +[sla_material:Esun Bio-Photopolymer Resin White 0.05] +inherits = *common 0.05* +exposure_time = 8 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Esun + +[sla_material:Esun Standard Resin Black 0.05] +inherits = *common 0.05* +exposure_time = 7 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Esun [sla_material:3DM-ABS 0.05] inherits = *common 0.05* exposure_time = 13 initial_exposure_time = 25 +material_type = Tough +material_vendor = 3DM [sla_material:3DM-BLACK 0.05] inherits = *common 0.05* exposure_time = 20 initial_exposure_time = 40 +material_type = Tough material_vendor = 3DM [sla_material:3DM-DENT 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 45 +material_type = Dental material_vendor = 3DM [sla_material:3DM-HR Green 0.05] inherits = *common 0.05* exposure_time = 15 initial_exposure_time = 40 +material_type = Tough material_vendor = 3DM [sla_material:3DM-HR Red Wine 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 35 +material_type = Tough material_vendor = 3DM [sla_material:3DM-XPRO White 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 35 +material_type = Tough +material_vendor = 3DM + +[sla_material:3DM-Vulcan Gold 0.05] +inherits = *common 0.05* +exposure_time = 15 +initial_exposure_time = 30 +material_type = Tough material_vendor = 3DM [sla_material:FTD Ash Grey 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 40 +material_type = Tough material_vendor = FTD [sla_material:Harz Labs Model Resin Cherry 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 45 +material_type = Tough material_vendor = Harz Labs +[sla_material:Resinworks 3D Violet 0.05] +inherits = *common 0.05* +exposure_time = 17 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Resinworks 3D + +[sla_material:Resinworks 3D Green 0.05] +inherits = *common 0.05* +exposure_time = 21 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Resinworks 3D + [sla_material:Photocentric Hard Grey 0.05] inherits = *common 0.05* exposure_time = 15 initial_exposure_time = 30 +material_type = Tough +material_vendor = Photocentric + +[sla_material:Photocentric Ash Grey 0.05] +inherits = *common 0.05* +exposure_time = 10 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Photocentric ## Prusa @@ -2165,46 +2914,91 @@ initial_exposure_time = 30 inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Orange Tough 0.05] inherits = *common 0.05* exposure_time = 7.5 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Grey Tough 0.05] inherits = *common 0.05* exposure_time = 8.5 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Black Tough 0.05] inherits = *common 0.05* exposure_time = 6 initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa ## [sla_material:Prusa Beige Super Low Odor 0.05] ## inherits = *common 0.05* ## exposure_time = 7.5 ## initial_exposure_time = 35 +## material_type = Tough +## material_vendor = Prusa ## [sla_material:Prusa White Super Low Odor 0.05] ## inherits = *common 0.05* ## exposure_time = 6.5 ## initial_exposure_time = 35 +## material_type = Tough +## material_vendor = Prusa ## [sla_material:Prusa Grey Super Low Odor 0.05] ## inherits = *common 0.05* ## exposure_time = 6.5 ## initial_exposure_time = 35 +## material_type = Tough +## material_vendor = Prusa + +[sla_material:Prusa Cyan Super Low Odor 0.05] +inherits = *common 0.05* +exposure_time = 6 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Magenta Super Low Odor 0.05] +inherits = *common 0.05* +exposure_time = 6 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Yellow Super Low Odor 0.05] +inherits = *common 0.05* +exposure_time = 6 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa ## [sla_material:Prusa Black High Tenacity 0.05] ## inherits = *common 0.05* ## exposure_time = 7 ## initial_exposure_time = 35 +## material_type = Tough +## material_vendor = Prusa -[sla_material:Prusa Green Casting 0.05] +[sla_material:Prusa Orange-Yellow Teeth Model 0.05] +inherits = *common 0.05* +exposure_time = 7 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa + +[sla_material:Prusa Green Dental Casting 0.05] inherits = *common 0.05* exposure_time = 13 -initial_exposure_time = 40 +initial_exposure_time = 50 +material_type = Casting material_vendor = Prusa ## [sla_material:Prusa Yellow Solid 0.05] @@ -2216,61 +3010,74 @@ material_vendor = Prusa inherits = *common 0.05* exposure_time = 7.5 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa -## [sla_material:Prusa Transparent Green Tough 0.05] -## inherits = *common 0.05* -## exposure_time = 6 -## initial_exposure_time = 35 +[sla_material:Prusa Transparent Green Tough 0.05] +inherits = *common 0.05* +exposure_time = 6 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Transparent Red Tough 0.05] inherits = *common 0.05* exposure_time = 6 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa [sla_material:Prusa Maroon Tough 0.05] inherits = *common 0.05* exposure_time = 7.5 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa [sla_material:Prusa Pink Tough 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa [sla_material:Prusa Azure Blue Tough 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa [sla_material:Prusa Transparent Tough 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 15 +material_type = Tough +material_vendor = Prusa ## [sla_material:Prusa Yellow Flexible 0.05] ## inherits = *common 0.05* ## exposure_time = 9 ## initial_exposure_time = 35 -## [sla_material:Prusa Clear Flexible 0.05] -## inherits = *common 0.05* -## exposure_time = 5 -## initial_exposure_time = 15 +[sla_material:Prusa Clear Flexible 0.05] +inherits = *common 0.05* +exposure_time = 5 +initial_exposure_time = 15 +material_type = Flexible +material_vendor = Prusa ## [sla_material:Prusa White Flexible 0.05] ## inherits = *common 0.05* ## exposure_time = 9 ## initial_exposure_time = 35 -## [sla_material:Prusa Blue Flexible 0.05] -## inherits = *common 0.05* -## exposure_time = 9 -## initial_exposure_time = 35 +[sla_material:Prusa Blue Flexible 0.05] +inherits = *common 0.05* +exposure_time = 5 +initial_exposure_time = 15 +material_type = Flexible +material_vendor = Prusa ## [sla_material:Prusa Black Flexible 0.05] ## inherits = *common 0.05* @@ -2282,61 +3089,128 @@ initial_exposure_time = 15 ## exposure_time = 9 ## initial_exposure_time = 35 +[sla_material:Prusa Clear ABS like 0.05] +inherits = *common 0.05* +exposure_time = 8 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa + +## [sla_material:Prusa ABS like White 0.05] +## inherits = *common 0.05* +## exposure_time = 8 +## initial_exposure_time = 30 + +[sla_material:Prusa Yellow Jewelry Casting 0.05] +inherits = *common 0.05* +exposure_time = 13 +initial_exposure_time = 45 +material_type = Casting +material_vendor = Prusa + +[sla_material:Prusa Grey High Tenacity 0.05] +inherits = *common 0.05* +exposure_time = 7 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa + ########### Materials 0.035 [sla_material:Prusa Orange Tough 0.035] inherits = *common 0.035* exposure_time = 6 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa ########### Materials 0.1 +[sla_material:BlueCast EcoGray 0.1] +inherits = *common 0.1* +exposure_time = 10 +initial_exposure_time = 35 +material_type = Tough +material_vendor = BlueCast + +[sla_material:BlueCast Kera Master Dental 0.1] +inherits = *common 0.1* +exposure_time = 13 +initial_exposure_time = 50 +material_type = Tough +material_vendor = BlueCast + +## Prusa + [sla_material:Prusa Orange Tough 0.1] inherits = *common 0.1* exposure_time = 13 initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Beige Tough 0.1] inherits = *common 0.1* exposure_time = 13 initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Pink Tough 0.1] inherits = *common 0.1* exposure_time = 13 initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Azure Blue Tough 0.1] inherits = *common 0.1* exposure_time = 13 initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Maroon Tough 0.1] inherits = *common 0.1* exposure_time = 13 initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa White Tough 0.1] inherits = *common 0.1* exposure_time = 13 initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Black Tough 0.1] inherits = *common 0.1* exposure_time = 13 initial_exposure_time = 55 +material_type = Tough +material_vendor = Prusa [sla_material:Prusa Transparent Tough 0.1] inherits = *common 0.1* exposure_time = 8 initial_exposure_time = 35 +material_type = Tough material_vendor = Prusa -[sla_material:Prusa Green Casting 0.1] +[sla_material:Prusa Green Dental Casting 0.1] inherits = *common 0.1* exposure_time = 15 initial_exposure_time = 50 +material_type = Casting +material_vendor = Prusa + +[sla_material:Prusa Transparent Green Tough 0.1] +inherits = *common 0.1* +exposure_time = 7 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa [printer:*common*] printer_technology = FFF @@ -2454,6 +3328,7 @@ retract_length = 1 retract_speed = 50 variable_layer_height = 1 printer_variant = 0.25 +retract_lift = 0.15 default_print_profile = 0.10mm DETAIL 0.25 nozzle [printer:Original Prusa i3 MK2S 0.6 nozzle] @@ -2503,19 +3378,19 @@ min_layer_height = 0.1 inherits = Original Prusa i3 MK2S printer_model = MK2.5 remaining_times = 1 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 0.25 nozzle] inherits = Original Prusa i3 MK2S 0.25 nozzle printer_model = MK2.5 remaining_times = 1 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 0.6 nozzle] inherits = Original Prusa i3 MK2S 0.6 nozzle printer_model = MK2.5 remaining_times = 1 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 MMU2 Single] inherits = Original Prusa i3 MK2.5; *mm2* @@ -2544,7 +3419,7 @@ machine_min_travel_rate = 0 default_print_profile = 0.15mm OPTIMAL MK2.5 default_filament_profile = Prusament PLA printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2.5\n -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; load to nozzle\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; load to nozzle\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors [printer:Original Prusa i3 MK2.5 MMU2 Single 0.6 nozzle] @@ -2586,23 +3461,23 @@ single_extruder_multi_material = 1 # to be defined explicitely. nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n [printer:Original Prusa i3 MK2.5S] inherits = Original Prusa i3 MK2.5 printer_model = MK2.5S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5S 0.25 nozzle] inherits = Original Prusa i3 MK2.5 0.25 nozzle printer_model = MK2.5S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5S 0.6 nozzle] inherits = Original Prusa i3 MK2.5 0.6 nozzle printer_model = MK2.5S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5S MMU2S Single] inherits = Original Prusa i3 MK2.5; *mm2s* @@ -2631,7 +3506,7 @@ machine_min_travel_rate = 0 default_print_profile = 0.15mm OPTIMAL MK2.5 default_filament_profile = Prusament PLA printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2.5\n -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors [printer:Original Prusa i3 MK2.5S MMU2S Single 0.6 nozzle] @@ -2650,8 +3525,9 @@ max_layer_height = 0.15 min_layer_height = 0.05 nozzle_diameter = 0.25 printer_variant = 0.25 +retract_lift = 0.15 default_print_profile = 0.10mm DETAIL 0.25 nozzle -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n [printer:Original Prusa i3 MK2.5S MMU2S] inherits = Original Prusa i3 MK2.5; *mm2s* @@ -2684,7 +3560,7 @@ single_extruder_multi_material = 1 # to be defined explicitely. nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n [printer:Original Prusa i3 MK2.5S MMU2S 0.6 nozzle] @@ -2731,7 +3607,7 @@ remaining_times = 1 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n retract_lift_below = 209 max_print_height = 210 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} printer_model = MK3 default_print_profile = 0.15mm QUALITY MK3 @@ -2741,7 +3617,8 @@ nozzle_diameter = 0.25 max_layer_height = 0.15 min_layer_height = 0.05 printer_variant = 0.25 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} +retract_lift = 0.15 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3 [printer:Original Prusa i3 MK3 0.6 nozzle] @@ -2755,17 +3632,17 @@ default_print_profile = 0.30mm QUALITY 0.6 nozzle MK3 [printer:Original Prusa i3 MK3S] inherits = Original Prusa i3 MK3 printer_model = MK3S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} [printer:Original Prusa i3 MK3S 0.25 nozzle] inherits = Original Prusa i3 MK3 0.25 nozzle printer_model = MK3S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} [printer:Original Prusa i3 MK3S 0.6 nozzle] inherits = Original Prusa i3 MK3 0.6 nozzle printer_model = MK3S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} [printer:*mm2*] inherits = Original Prusa i3 MK3 @@ -2795,7 +3672,7 @@ default_filament_profile = Prusament PLA MMU2 inherits = *mm2* single_extruder_multi_material = 0 default_filament_profile = Prusament PLA -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors [printer:Original Prusa i3 MK3 MMU2 Single 0.6 nozzle] @@ -2814,7 +3691,8 @@ nozzle_diameter = 0.25 max_layer_height = 0.15 min_layer_height = 0.05 printer_variant = 0.25 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F1000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n +retract_lift = 0.15 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F1000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3 [printer:Original Prusa i3 MK3 MMU2] @@ -2825,14 +3703,14 @@ inherits = *mm2* machine_max_acceleration_e = 8000,8000 nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n [printer:Original Prusa i3 MK3S MMU2S Single] inherits = *mm2s* single_extruder_multi_material = 0 default_filament_profile = Prusament PLA -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n end_gcode = G1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors [printer:Original Prusa i3 MK3S MMU2S Single 0.6 nozzle] @@ -2851,7 +3729,8 @@ nozzle_diameter = 0.25 max_layer_height = 0.15 min_layer_height = 0.05 printer_variant = 0.25 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n +retract_lift = 0.15 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\nG21 ; set units to millimeters\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3 [printer:Original Prusa i3 MK3S MMU2S] @@ -2859,7 +3738,7 @@ inherits = *mm2s* machine_max_acceleration_e = 8000,8000 nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.8.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG21 ; set units to millimeters\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n ## 0.6mm nozzle MMU2/S printer profiles @@ -2880,12 +3759,76 @@ min_layer_height = 0.15 printer_variant = 0.6 default_print_profile = 0.30mm QUALITY 0.6 nozzle MK3 +## MINI + +[printer:Original Prusa MINI] +inherits = *common* +printer_model = MINI +printer_technology = FFF +printer_variant = 0.4 +printer_vendor = +thumbnails = 240x320,220x165,16x16 +bed_shape = 0x0,180x0,180x180,0x180 +default_filament_profile = "Prusament PLA MINI" +default_print_profile = 0.15mm QUALITY MINI +gcode_flavor = marlin +machine_max_acceleration_e = 5000 +machine_max_acceleration_extruding = 1250 +machine_max_acceleration_retracting = 1250 +machine_max_acceleration_x = 1250 +machine_max_acceleration_y = 1250 +machine_max_acceleration_z = 400 +machine_max_feedrate_e = 80 +machine_max_feedrate_x = 180 +machine_max_feedrate_y = 180 +machine_max_feedrate_z = 12 +machine_max_jerk_e = 10 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 2 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +max_layer_height = 0.25 +max_print_height = 180 +min_layer_height = 0.07 +nozzle_diameter = 0.4 +retract_length = 3.2 +retract_lift = 0.2 +retract_speed = 70 +deretract_speed = 40 +wipe = 1 +retract_before_wipe = 70% +retract_before_travel = 1.5 +retract_lift_above = 0 +retract_lift_below = 179 +retract_layer_change = 0 +silent_mode = 0 +remaining_times = 1 +start_gcode = M569 S0 E \nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM92 E317 ; set steps/unit for extruder\nM104 S170 ; set extruder temp for bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 R170 ; wait for bed leveling temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG28 ; home all without mesh bed level\nG29 ; mesh bed leveling \nM104 S[first_layer_temperature] ; set extruder temp\nG92 E0.0\nG1 Y-2.0 X179 F2400\nG1 Z3 F720\nM109 S[first_layer_temperature] ; wait for extruder temp\n\n; intro line\nG1 X170 F1000\nG1 Z0.2 F720\nG1 X110.0 E8.0 F900\nG1 X40.0 E10.0 F700\nG92 E0.0\n\nM221 S95 ; set flow +end_gcode = G1 E-1 F2100 ; retract\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+5, max_print_height)}{endif} F720 ; Move print head up\nG1 X0 Y180 F4200 ; park print head\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM221 S100 ; reset flow\nM84 ; disable motors +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MINI\n +extruder_colour = + +[printer:Original Prusa MINI 0.25 nozzle] +inherits = Original Prusa MINI +printer_variant = 0.25 +nozzle_diameter = 0.25 +retract_length = 3 +retract_lift = 0.15 +retract_speed = 70 +deretract_speed = 40 +wipe = 1 +retract_before_wipe = 70% +retract_before_travel = 1 +start_gcode = M569 S0 E \nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM92 E317 ; set steps/unit for extruder\nM104 S170 ; set extruder temp for bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 R170 ; wait for bed leveling temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG28 ; home all without mesh bed level\nG29 ; mesh bed leveling \nM104 S[first_layer_temperature] ; set extruder temp\nG92 E0.0\nG1 Y-2.0 X179 F2400\nG1 Z3 F720\nM109 S[first_layer_temperature] ; wait for extruder temp\n\n; intro line\nG1 X170 F1000\nG1 Z0.2 F720\nG1 X110.0 E8.0 F600\nG1 X40.0 E10.0 F400\nG92 E0.0\n\nM221 S95 ; set flow + [printer:Original Prusa SL1] printer_technology = SLA printer_model = SL1 printer_variant = default default_sla_material_profile = Prusa Orange Tough 0.05 default_sla_print_profile = 0.05 Normal +thumbnails = 400x400,800x480 bed_shape = 1.48x1.02,119.48x1.02,119.48x67.02,1.48x67.02 display_height = 68.04 display_orientation = portrait diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index 25100b22fe..f053aea296 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -1205,7 +1205,7 @@ ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector& ds : deltas) + for (const std::vector& ds : deltas) for (float delta : ds) assert(delta <= 0.); assert(expoly.holes.size() + 1 == deltas.size()); diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp index 52ac4a0aa6..065a69ba36 100644 --- a/src/libslic3r/EdgeGrid.cpp +++ b/src/libslic3r/EdgeGrid.cpp @@ -46,11 +46,29 @@ void EdgeGrid::Grid::create(const Polygons &polygons, coord_t resolution) ++ ncontours; // Collect the contours. - m_contours.assign(ncontours, NULL); + m_contours.assign(ncontours, nullptr); ncontours = 0; for (size_t j = 0; j < polygons.size(); ++ j) if (! polygons[j].points.empty()) - m_contours[ncontours++] = &polygons[j].points; + m_contours[ncontours ++] = &polygons[j].points; + + create_from_m_contours(resolution); +} + +void EdgeGrid::Grid::create(const std::vector &polygons, coord_t resolution) +{ + // Count the contours. + size_t ncontours = 0; + for (size_t j = 0; j < polygons.size(); ++ j) + if (! polygons[j].empty()) + ++ ncontours; + + // Collect the contours. + m_contours.assign(ncontours, nullptr); + ncontours = 0; + for (size_t j = 0; j < polygons.size(); ++ j) + if (! polygons[j].empty()) + m_contours[ncontours ++] = &polygons[j]; create_from_m_contours(resolution); } @@ -66,7 +84,7 @@ void EdgeGrid::Grid::create(const ExPolygon &expoly, coord_t resolution) ++ ncontours; // Collect the contours. - m_contours.assign(ncontours, NULL); + m_contours.assign(ncontours, nullptr); ncontours = 0; if (! expoly.contour.points.empty()) m_contours[ncontours++] = &expoly.contour.points; @@ -91,7 +109,7 @@ void EdgeGrid::Grid::create(const ExPolygons &expolygons, coord_t resolution) } // Collect the contours. - m_contours.assign(ncontours, NULL); + m_contours.assign(ncontours, nullptr); ncontours = 0; for (size_t i = 0; i < expolygons.size(); ++ i) { const ExPolygon &expoly = expolygons[i]; @@ -1122,7 +1140,7 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt Vec2d vfoot = foot - pt.cast(); double dist_foot = vfoot.norm(); double dist_foot_err = dist_foot - d_min; - assert(std::abs(dist_foot_err) < 1e-7 * d_min); + assert(std::abs(dist_foot_err) < 1e-7 || std::abs(dist_foot_err) < 1e-7 * d_min); #endif /* NDEBUG */ } } @@ -1145,7 +1163,7 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt vfoot = p1.cast() * (1. - result.t) + p2.cast() * result.t - pt.cast(); double dist_foot = vfoot.norm(); double dist_foot_err = dist_foot - std::abs(result.distance); - assert(std::abs(dist_foot_err) < 1e-7 * std::abs(result.distance)); + assert(std::abs(dist_foot_err) < 1e-7 || std::abs(dist_foot_err) < 1e-7 * std::abs(result.distance)); } #endif /* NDEBUG */ } else diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp index 92cee83629..81517a5c4b 100644 --- a/src/libslic3r/EdgeGrid.hpp +++ b/src/libslic3r/EdgeGrid.hpp @@ -21,6 +21,7 @@ public: void set_bbox(const BoundingBox &bbox) { m_bbox = bbox; } void create(const Polygons &polygons, coord_t resolution); + void create(const std::vector &polygons, coord_t resolution); void create(const ExPolygon &expoly, coord_t resolution); void create(const ExPolygons &expolygons, coord_t resolution); void create(const ExPolygonCollection &expolygons, coord_t resolution); @@ -208,6 +209,25 @@ public: } } + template void visit_cells_intersecting_box(BoundingBox bbox, VISITOR &visitor) const + { + // End points of the line segment. + bbox.min -= m_bbox.min; + bbox.max -= m_bbox.min + Point(1, 1); + // Get the cells of the end points. + bbox.min /= m_resolution; + bbox.max /= m_resolution; + // Trim with the cells. + bbox.min.x() = std::max(bbox.min.x(), 0); + bbox.min.y() = std::max(bbox.min.y(), 0); + bbox.max.x() = std::min(bbox.max.x(), (coord_t)m_cols - 1); + bbox.max.y() = std::min(bbox.max.y(), (coord_t)m_rows - 1); + for (coord_t iy = bbox.min.y(); iy <= bbox.max.y(); ++ iy) + for (coord_t ix = bbox.min.x(); ix <= bbox.max.x(); ++ ix) + if (! visitor(iy, ix)) + return; + } + std::pair>::const_iterator, std::vector>::const_iterator> cell_data_range(coord_t row, coord_t col) const { const EdgeGrid::Grid::Cell &cell = m_cells[row * m_cols + col]; diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 0f4eb01350..69a20b5ece 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -8,6 +8,7 @@ #include "Flow.hpp" #include "Geometry.hpp" #include "SVG.hpp" +#include "Utils.hpp" #include #include @@ -26,6 +27,10 @@ struct ResampledPoint { double curve_parameter; }; +// Distance calculated using SDF (Shape Diameter Function). +// The distance is calculated by casting a fan of rays and measuring the intersection distance. +// Thus the calculation is relatively slow. For the Elephant foot compensation purpose, this distance metric does not avoid +// pinching off small pieces of a contour, thus this function has been superseded by contour_distance2(). std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx_contour, const Slic3r::Points &contour, const std::vector &resampled_point_parameters, double search_radius) { assert(! contour.empty()); @@ -60,9 +65,9 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx for (size_t axis = 0; axis < 2; ++ axis) { double dx = std::abs(dir(axis)); if (dx >= EPSILON) { - double tedge = (dir(axis) > 0) ? (double(bbox.max(axis)) - EPSILON - this->pt(axis)) : (this->pt(axis) - double(bbox.min(axis)) - EPSILON); + double tedge = (dir(axis) > 0) ? (double(bbox.max(axis)) - SCALED_EPSILON - this->pt(axis)) : (this->pt(axis) - double(bbox.min(axis)) - SCALED_EPSILON); if (tedge < dx) - t = tedge / dx; + t = std::min(t, tedge / dx); } } this->dir = dir; @@ -70,6 +75,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx dir *= t; this->pt_end = (this->pt + dir).cast(); this->t_min = 1.; + assert(this->grid.bbox().contains(this->pt_start) && this->grid.bbox().contains(this->pt_end)); } bool operator()(coord_t iy, coord_t ix) { @@ -166,7 +172,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx SVG svg(debug_out_path("contour_distance_raycasted-%d-%d.svg", iRun, &pt_next - contour.data()).c_str(), bbox); svg.draw(expoly_grid); svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); - svg.draw(*pt_this, "red", scale_(0.1)); + svg.draw(*pt_this, "red", coord_t(scale_(0.1))); #endif /* CONTOUR_DISTANCE_DEBUG_SVG */ for (int i = - num_rays + 1; i < num_rays; ++ i) { @@ -181,7 +187,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx svg.draw(Line(visitor.pt_start, visitor.pt_end), "yellow", scale_(0.01)); if (visitor.t_min < 1.) { Vec2d pt = visitor.pt + visitor.dir * visitor.t_min; - svg.draw(Point(pt), "red", scale_(0.1)); + svg.draw(Point(pt), "red", coord_t(scale_(0.1))); } #endif /* CONTOUR_DISTANCE_DEBUG_SVG */ } @@ -208,7 +214,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx out.emplace_back(float(distances.front() * search_radius)); #endif #ifdef CONTOUR_DISTANCE_DEBUG_SVG - printf("contour_distance_raycasted-%d-%d.svg - distance %lf\n", iRun, &pt_next - contour.data(), unscale(out.back())); + printf("contour_distance_raycasted-%d-%d.svg - distance %lf\n", iRun, int(&pt_next - contour.data()), unscale(out.back())); #endif /* CONTOUR_DISTANCE_DEBUG_SVG */ pt_this = &pt_next; idx_pt_this = &pt_next - contour.data(); @@ -222,6 +228,188 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx return out; } +// Contour distance by measuring the closest point of an ExPolygon stored inside the EdgeGrid, while filtering out points of the same contour +// at concave regions, or convex regions with low curvature (curvature is estimated as a ratio between contour length and chordal distance crossing the contour ends). +std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t idx_contour, const Slic3r::Points &contour, const std::vector &resampled_point_parameters, double compensation, double search_radius) +{ + assert(! contour.empty()); + assert(contour.size() >= 2); + + std::vector out; + + if (contour.size() > 2) + { +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + static int iRun = 0; + ++ iRun; + BoundingBox bbox = get_extents(contour); + bbox.merge(grid.bbox()); + ExPolygon expoly_grid; + expoly_grid.contour = Polygon(*grid.contours().front()); + for (size_t i = 1; i < grid.contours().size(); ++ i) + expoly_grid.holes.emplace_back(Polygon(*grid.contours()[i])); +#endif + struct Visitor { + Visitor(const EdgeGrid::Grid &grid, const size_t idx_contour, const std::vector &resampled_point_parameters, double dist_same_contour_accept, double dist_same_contour_reject) : + grid(grid), idx_contour(idx_contour), contour(*grid.contours()[idx_contour]), resampled_point_parameters(resampled_point_parameters), dist_same_contour_accept(dist_same_contour_accept), dist_same_contour_reject(dist_same_contour_reject) {} + + void init(const Points &contour, const Point &apoint) { + this->idx_point = &apoint - contour.data(); + this->point = apoint; + this->found = false; + this->dir_inside = this->dir_inside_at_point(contour, this->idx_point); + } + + bool operator()(coord_t iy, coord_t ix) { + // Called with a row and colum of the grid cell, which is intersected by a line. + auto cell_data_range = this->grid.cell_data_range(iy, ix); + for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++ it_contour_and_segment) { + // End points of the line segment and their vector. + std::pair segment = this->grid.segment(*it_contour_and_segment); + const Vec2d v = (segment.second - segment.first).cast(); + const Vec2d va = (this->point - segment.first).cast(); + const double l2 = v.squaredNorm(); // avoid a sqrt + const double t = (l2 == 0.0) ? 0. : clamp(0., 1., va.dot(v) / l2); + // Closest point from this->point to the segment. + const Vec2d foot = segment.first.cast() + t * v; + const Vec2d bisector = foot - this->point.cast(); + const double dist = bisector.norm(); + if ((! this->found || dist < this->distance) && this->dir_inside.dot(bisector) > 0) { + bool accept = true; + if (it_contour_and_segment->first == idx_contour) { + // Complex case: The closest segment originates from the same contour as the starting point. + // Reject the closest point if its distance along the contour is reasonable compared to the current contour bisector (this->pt, foot). + double param_lo = resampled_point_parameters[this->idx_point].curve_parameter; + double param_hi; + double param_end = resampled_point_parameters.back().curve_parameter; + const Slic3r::Points &ipts = *grid.contours()[it_contour_and_segment->first]; + const size_t ipt = it_contour_and_segment->second; + { + ResampledPoint key(ipt, false, 0.); + auto lower = [](const ResampledPoint& l, const ResampledPoint r) { return l.idx_src < r.idx_src || (l.idx_src == r.idx_src && int(l.interpolated) > int(r.interpolated)); }; + auto it = std::lower_bound(resampled_point_parameters.begin(), resampled_point_parameters.end(), key, lower); + assert(it != resampled_point_parameters.end() && it->idx_src == ipt && ! it->interpolated); + param_hi = t * sqrt(l2); + if (ipt + 1 < ipts.size()) + param_hi += it->curve_parameter; + } + if (param_lo > param_hi) + std::swap(param_lo, param_hi); + assert(param_lo > - SCALED_EPSILON && param_lo <= param_end + SCALED_EPSILON); + assert(param_hi > - SCALED_EPSILON && param_hi <= param_end + SCALED_EPSILON); + double dist_along_contour = std::min(param_hi - param_lo, param_lo + param_end - param_hi); + if (dist_along_contour < dist_same_contour_accept) + accept = false; + else if (dist < dist_same_contour_reject + SCALED_EPSILON) { + // this->point is close to foot. This point will only be accepted if the path along the contour is significantly + // longer than the bisector. That is, the path shall not bulge away from the bisector too much. + // Bulge is estimated by 0.6 of the circle circumference drawn around the bisector. + // Test whether the contour is convex or concave. + bool inside = + (t == 0.) ? this->inside_corner(ipts, ipt, this->point) : + (t == 1.) ? this->inside_corner(ipts, ipt + 1 == ipts.size() ? 0 : ipt + 1, this->point) : + this->left_of_segment(ipts, ipt, this->point); + accept = inside && dist_along_contour > 0.6 * M_PI * dist; + } + } + if (accept && (! this->found || dist < this->distance)) { + // Simple case: Just measure the shortest distance. + this->distance = dist; +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + this->closest_point = foot.cast(); +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + this->found = true; + } + } + } + // Continue traversing the grid. + return true; + } + + const EdgeGrid::Grid &grid; + const size_t idx_contour; + const Points &contour; + const std::vector &resampled_point_parameters; + const double dist_same_contour_accept; + const double dist_same_contour_reject; + + size_t idx_point; + Point point; + // Direction inside the contour from idx_point, not normalized. + Vec2d dir_inside; + bool found; + double distance; +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + Point closest_point; +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + + private: + static Vec2d dir_inside_at_point(const Points &contour, size_t i) { + size_t iprev = prev_idx_modulo(i, contour); + size_t inext = next_idx_modulo(i, contour); + Vec2d v1 = (contour[i] - contour[iprev]).cast(); + Vec2d v2 = (contour[inext] - contour[i]).cast(); + return Vec2d(- v1.y() - v2.y(), v1.x() + v2.x()); + } + static Vec2d dir_inside_at_segment(const Points& contour, size_t i) { + size_t inext = next_idx_modulo(i, contour); + Vec2d v = (contour[inext] - contour[i]).cast(); + return Vec2d(- v.y(), v.x()); + } + + static bool inside_corner(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) { + const Vec2d pt = pt_oposite.cast(); + size_t iprev = prev_idx_modulo(i, contour); + size_t inext = next_idx_modulo(i, contour); + Vec2d v1 = (contour[i] - contour[iprev]).cast(); + Vec2d v2 = (contour[inext] - contour[i]).cast(); + bool left_of_v1 = cross2(v1, pt - contour[iprev].cast()) > 0.; + bool left_of_v2 = cross2(v2, pt - contour[i ].cast()) > 0.; + return cross2(v1, v2) > 0 ? + left_of_v1 && left_of_v2 : // convex corner + left_of_v1 || left_of_v2; // concave corner + } + static bool left_of_segment(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) { + const Vec2d pt = pt_oposite.cast(); + size_t inext = next_idx_modulo(i, contour); + Vec2d v = (contour[inext] - contour[i]).cast(); + return cross2(v, pt - contour[i].cast()) > 0.; + } + } visitor(grid, idx_contour, resampled_point_parameters, 0.5 * compensation * M_PI, search_radius); + + out.reserve(contour.size()); + Point radius_vector(search_radius, search_radius); + for (const Point &pt : contour) { + visitor.init(contour, pt); + grid.visit_cells_intersecting_box(BoundingBox(pt - radius_vector, pt + radius_vector), visitor); + out.emplace_back(float(visitor.found ? std::min(visitor.distance, search_radius) : search_radius)); + +#if 0 +//#ifdef CONTOUR_DISTANCE_DEBUG_SVG + if (out.back() < search_radius) { + SVG svg(debug_out_path("contour_distance_filtered-%d-%d.svg", iRun, int(&pt - contour.data())).c_str(), bbox); + svg.draw(expoly_grid); + svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); + svg.draw(pt, "green", coord_t(scale_(0.1))); + svg.draw(visitor.closest_point, "red", coord_t(scale_(0.1))); + printf("contour_distance_filtered-%d-%d.svg - distance %lf\n", iRun, int(&pt - contour.data()), unscale(out.back())); + } +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + } +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + if (out.back() < search_radius) { + SVG svg(debug_out_path("contour_distance_filtered-final-%d.svg", iRun).c_str(), bbox); + svg.draw(expoly_grid); + svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); + for (size_t i = 0; i < contour.size(); ++ i) + svg.draw(contour[i], out[i] < float(search_radius - SCALED_EPSILON) ? "red" : "green", coord_t(scale_(0.1))); + } +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + } + + return out; +} + Points resample_polygon(const Points &contour, double dist, std::vector &resampled_point_parameters) { Points out; @@ -257,8 +445,8 @@ static inline void smooth_compensation(std::vector &compensation, float s std::vector out(compensation); for (size_t iter = 0; iter < num_iterations; ++ iter) { for (size_t i = 0; i < compensation.size(); ++ i) { - float prev = (i == 0) ? compensation.back() : compensation[i - 1]; - float next = (i + 1 == compensation.size()) ? compensation.front() : compensation[i + 1]; + float prev = prev_value_modulo(i, compensation); + float next = next_value_modulo(i, compensation); float laplacian = compensation[i] * (1.f - strength) + 0.5f * strength * (prev + next); // Compensations are negative. Only apply the laplacian if it leads to lower compensation. out[i] = std::max(laplacian, compensation[i]); @@ -267,30 +455,6 @@ static inline void smooth_compensation(std::vector &compensation, float s } } -template -static inline INDEX_TYPE prev_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container) -{ - if (idx == 0) - idx = INDEX_TYPE(container.size()); - return -- idx; -} - -template -static inline INDEX_TYPE next_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container) -{ - if (++ idx == INDEX_TYPE(container.size())) - idx = 0; - return idx; -} - -template -static inline T exchange(T& obj, U&& new_value) -{ - T old_value = std::move(obj); - obj = std::forward(new_value); - return old_value; -} - static inline void smooth_compensation_banded(const Points &contour, float band, std::vector &compensation, float strength, size_t num_iterations) { assert(contour.size() == compensation.size()); @@ -302,13 +466,13 @@ static inline void smooth_compensation_banded(const Points &contour, float band, for (int i = 0; i < int(compensation.size()); ++ i) { const Vec2f pthis = contour[i].cast(); - int j = prev_idx_cyclic(i, contour); + int j = prev_idx_modulo(i, contour); Vec2f pprev = contour[j].cast(); float prev = compensation[j]; float l2 = (pthis - pprev).squaredNorm(); if (l2 < dist_min2) { float l = sqrt(l2); - int jprev = exchange(j, prev_idx_cyclic(j, contour)); + int jprev = exchange(j, prev_idx_modulo(j, contour)); while (j != i) { const Vec2f pp = contour[j].cast(); const float lthis = (pp - pprev).norm(); @@ -323,17 +487,17 @@ static inline void smooth_compensation_banded(const Points &contour, float band, prev = use_min ? std::min(prev, compensation[j]) : compensation[j]; pprev = pp; l = lnext; - jprev = exchange(j, prev_idx_cyclic(j, contour)); + jprev = exchange(j, prev_idx_modulo(j, contour)); } } - j = next_idx_cyclic(i, contour); + j = next_idx_modulo(i, contour); pprev = contour[j].cast(); float next = compensation[j]; l2 = (pprev - pthis).squaredNorm(); if (l2 < dist_min2) { float l = sqrt(l2); - int jprev = exchange(j, next_idx_cyclic(j, contour)); + int jprev = exchange(j, next_idx_modulo(j, contour)); while (j != i) { const Vec2f pp = contour[j].cast(); const float lthis = (pp - pprev).norm(); @@ -348,7 +512,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, next = use_min ? std::min(next, compensation[j]) : compensation[j]; pprev = pp; l = lnext; - jprev = exchange(j, next_idx_cyclic(j, contour)); + jprev = exchange(j, next_idx_modulo(j, contour)); } } @@ -361,7 +525,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, } ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow &external_perimeter_flow, const double compensation) -{ +{ // The contour shall be wide enough to apply the external perimeter plus compensation on both sides. double min_contour_width = double(external_perimeter_flow.scaled_width() + external_perimeter_flow.scaled_spacing()); double scaled_compensation = scale_(compensation); @@ -369,39 +533,68 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow & // Make the search radius a bit larger for the averaging in contour_distance over a fan of rays to work. double search_radius = min_contour_width_compensated + min_contour_width * 0.5; - EdgeGrid::Grid grid; - ExPolygon simplified = input_expoly.simplify(SCALED_EPSILON).front(); - BoundingBox bbox = get_extents(simplified.contour); - bbox.offset(SCALED_EPSILON); - grid.set_bbox(bbox); - grid.create(simplified, coord_t(0.7 * search_radius)); - std::vector> deltas; - deltas.reserve(simplified.holes.size() + 1); - ExPolygon resampled(simplified); - double resample_interval = scale_(0.5); - for (size_t idx_contour = 0; idx_contour <= simplified.holes.size(); ++ idx_contour) { - Polygon &poly = (idx_contour == 0) ? resampled.contour : resampled.holes[idx_contour - 1]; - std::vector resampled_point_parameters; - poly.points = resample_polygon(poly.points, resample_interval, resampled_point_parameters); - std::vector dists = contour_distance(grid, idx_contour, poly.points, resampled_point_parameters, search_radius); - for (float &d : dists) { -// printf("Point %d, Distance: %lf\n", int(&d - dists.data()), unscale(d)); - // Convert contour width to available compensation distance. - if (d < min_contour_width) - d = 0.f; - else if (d > min_contour_width_compensated) - d = - float(scaled_compensation); - else - d = - (d - float(min_contour_width)) / 2.f; - assert(d >= - float(scaled_compensation) && d <= 0.f); + BoundingBox bbox = get_extents(input_expoly.contour); + Point bbox_size = bbox.size(); + ExPolygon out; + if (bbox_size.x() < min_contour_width_compensated + SCALED_EPSILON || + bbox_size.y() < min_contour_width_compensated + SCALED_EPSILON || + input_expoly.area() < min_contour_width_compensated * min_contour_width_compensated * 5.) + { + // The contour is tiny. Don't correct it. + out = input_expoly; + } + else + { + EdgeGrid::Grid grid; + ExPolygon simplified = input_expoly.simplify(SCALED_EPSILON).front(); + BoundingBox bbox = get_extents(simplified.contour); + bbox.offset(SCALED_EPSILON); + grid.set_bbox(bbox); + grid.create(simplified, coord_t(0.7 * search_radius)); + std::vector> deltas; + deltas.reserve(simplified.holes.size() + 1); + ExPolygon resampled(simplified); + double resample_interval = scale_(0.5); + for (size_t idx_contour = 0; idx_contour <= simplified.holes.size(); ++ idx_contour) { + Polygon &poly = (idx_contour == 0) ? resampled.contour : resampled.holes[idx_contour - 1]; + std::vector resampled_point_parameters; + poly.points = resample_polygon(poly.points, resample_interval, resampled_point_parameters); + std::vector dists = contour_distance2(grid, idx_contour, poly.points, resampled_point_parameters, scaled_compensation, search_radius); + for (float &d : dists) { + // printf("Point %d, Distance: %lf\n", int(&d - dists.data()), unscale(d)); + // Convert contour width to available compensation distance. + if (d < min_contour_width) + d = 0.f; + else if (d > min_contour_width_compensated) + d = - float(scaled_compensation); + else + d = - (d - float(min_contour_width)) / 2.f; + assert(d >= - float(scaled_compensation) && d <= 0.f); + } + // smooth_compensation(dists, 0.4f, 10); + smooth_compensation_banded(poly.points, float(0.8 * resample_interval), dists, 0.3f, 3); + deltas.emplace_back(dists); + } + + ExPolygons out_vec = variable_offset_inner_ex(resampled, deltas, 2.); + if (out_vec.size() == 1) + out = std::move(out_vec.front()); + else { + // Something went wrong, don't compensate. + out = input_expoly; +#ifdef TESTS_EXPORT_SVGS + if (out_vec.size() > 1) { + static int iRun = 0; + SVG::export_expolygons(debug_out_path("elephant_foot_compensation-many_contours-%d.svg", iRun ++).c_str(), + { { { input_expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { out_vec }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); + } +#endif /* TESTS_EXPORT_SVGS */ + assert(out_vec.size() == 1); } -// smooth_compensation(dists, 0.4f, 10); - smooth_compensation_banded(poly.points, float(0.8 * resample_interval), dists, 0.3f, 3); - deltas.emplace_back(dists); } - ExPolygons out = variable_offset_inner_ex(resampled, deltas, 2.); - return out.front(); + return out; } ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &external_perimeter_flow, const double compensation) diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index 7833c9c913..4ee8974f47 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -77,6 +77,11 @@ public: void triangulate_pp(Points *triangles) const; void triangulate_p2t(Polygons* polygons) const; Lines lines() const; + + // Number of contours (outer contour with holes). + size_t num_contours() const { return this->holes.size() + 1; } + Polygon& contour_or_hole(size_t idx) { return (idx == 0) ? this->contour : this->holes[idx - 1]; } + const Polygon& contour_or_hole(size_t idx) const { return (idx == 0) ? this->contour : this->holes[idx - 1]; } }; inline bool operator==(const ExPolygon &lhs, const ExPolygon &rhs) { return lhs.contour == rhs.contour && lhs.holes == rhs.holes; } diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index b22d85b657..b76991f1cc 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -267,6 +267,15 @@ public: //static inline std::string role_to_string(ExtrusionLoopRole role); +#ifndef NDEBUG + bool validate() const { + assert(this->first_point() == this->paths.back().polyline.points.back()); + for (size_t i = 1; i < paths.size(); ++ i) + assert(this->paths[i - 1].polyline.points.back() == this->paths[i].polyline.points.front()); + return true; + } +#endif /* NDEBUG */ + private: ExtrusionLoopRole m_loop_role; }; diff --git a/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/src/libslic3r/Fill/Fill3DHoneycomb.cpp index 820f0008bf..6c4b4d9036 100644 --- a/src/libslic3r/Fill/Fill3DHoneycomb.cpp +++ b/src/libslic3r/Fill/Fill3DHoneycomb.cpp @@ -158,43 +158,18 @@ void Fill3DHoneycomb::_fill_surface_single( ((this->layer_id/thickness_layers) % 2) + 1); // move pattern in place - for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it) - it->translate(bb.min(0), bb.min(1)); + for (Polyline &pl : polylines) + pl.translate(bb.min); - // clip pattern to boundaries - polylines = intersection_pl(polylines, (Polygons)expolygon); + // clip pattern to boundaries, chain the clipped polylines + Polylines polylines_chained = chain_polylines(intersection_pl(polylines, to_polygons(expolygon))); - // connect lines - if (! params.dont_connect && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections - ExPolygon expolygon_off; - { - ExPolygons expolygons_off = offset_ex(expolygon, SCALED_EPSILON); - if (! expolygons_off.empty()) { - // When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island. - assert(expolygons_off.size() == 1); - std::swap(expolygon_off, expolygons_off.front()); - } - } - bool first = true; - for (Polyline &polyline : chain_polylines(std::move(polylines))) { - if (! first) { - // Try to connect the lines. - Points &pts_end = polylines_out.back().points; - const Point &first_point = polyline.points.front(); - const Point &last_point = pts_end.back(); - // TODO: we should also check that both points are on a fill_boundary to avoid - // connecting paths on the boundaries of internal regions - if ((last_point - first_point).cast().norm() <= 1.5 * distance && - expolygon_off.contains(Line(last_point, first_point))) { - // Append the polyline. - pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end()); - continue; - } - } - // The lines cannot be connected. - polylines_out.emplace_back(std::move(polyline)); - first = false; - } + // connect lines if needed + if (! polylines_chained.empty()) { + if (params.dont_connect) + append(polylines_out, std::move(polylines_chained)); + else + this->connect_infill(std::move(polylines_chained), expolygon, polylines_out, params); } } diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index c16d764152..88eba9a51f 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -1,8 +1,10 @@ #include #include "../ClipperUtils.hpp" +#include "../EdgeGrid.hpp" #include "../Surface.hpp" #include "../PrintConfig.hpp" +#include "../libslic3r.h" #include "FillBase.hpp" #include "FillConcentric.hpp" @@ -148,4 +150,838 @@ std::pair Fill::_infill_direction(const Surface *surface) const return std::pair(out_angle, out_shift); } +#if 0 +// From pull request "Gyroid improvements" #2730 by @supermerill + +/// cut poly between poly.point[idx_1] & poly.point[idx_1+1] +/// add p1+-width to one part and p2+-width to the other one. +/// add the "new" polyline to polylines (to part cut from poly) +/// p1 & p2 have to be between poly.point[idx_1] & poly.point[idx_1+1] +/// if idx_1 is ==0 or == size-1, then we don't need to create a new polyline. +static void cut_polyline(Polyline &poly, Polylines &polylines, size_t idx_1, Point p1, Point p2) { + //reorder points + if (p1.distance_to_square(poly.points[idx_1]) > p2.distance_to_square(poly.points[idx_1])) { + Point temp = p2; + p2 = p1; + p1 = temp; + } + if (idx_1 == poly.points.size() - 1) { + //shouldn't be possible. + poly.points.erase(poly.points.end() - 1); + } else { + // create new polyline + Polyline new_poly; + //put points in new_poly + new_poly.points.push_back(p2); + new_poly.points.insert(new_poly.points.end(), poly.points.begin() + idx_1 + 1, poly.points.end()); + //erase&put points in poly + poly.points.erase(poly.points.begin() + idx_1 + 1, poly.points.end()); + poly.points.push_back(p1); + //safe test + if (poly.length() == 0) + poly.points = new_poly.points; + else + polylines.emplace_back(new_poly); + } +} + +/// the poly is like a polygon but with first_point != last_point (already removed) +static void cut_polygon(Polyline &poly, size_t idx_1, Point p1, Point p2) { + //reorder points + if (p1.distance_to_square(poly.points[idx_1]) > p2.distance_to_square(poly.points[idx_1])) { + Point temp = p2; + p2 = p1; + p1 = temp; + } + //check if we need to rotate before cutting + if (idx_1 != poly.size() - 1) { + //put points in new_poly + poly.points.insert(poly.points.end(), poly.points.begin(), poly.points.begin() + idx_1 + 1); + poly.points.erase(poly.points.begin(), poly.points.begin() + idx_1 + 1); + } + //put points in poly + poly.points.push_back(p1); + poly.points.insert(poly.points.begin(), p2); +} + +/// check if the polyline from pts_to_check may be at 'width' distance of a point in polylines_blocker +/// it use equally_spaced_points with width/2 precision, so don't worry with pts_to_check number of points. +/// it use the given polylines_blocker points, be sure to put enough of them to be reliable. +/// complexity : N(pts_to_check.equally_spaced_points(width / 2)) x N(polylines_blocker.points) +static bool collision(const Points &pts_to_check, const Polylines &polylines_blocker, const coordf_t width) { + //check if it's not too close to a polyline + coordf_t min_dist_square = width * width * 0.9 - SCALED_EPSILON; + Polyline better_polylines(pts_to_check); + Points better_pts = better_polylines.equally_spaced_points(width / 2); + for (const Point &p : better_pts) { + for (const Polyline &poly2 : polylines_blocker) { + for (const Point &p2 : poly2.points) { + if (p.distance_to_square(p2) < min_dist_square) { + return true; + } + } + } + } + return false; +} + +/// Try to find a path inside polylines that allow to go from p1 to p2. +/// width if the width of the extrusion +/// polylines_blockers are the array of polylines to check if the path isn't blocked by something. +/// complexity: N(polylines.points) + a collision check after that if we finded a path: N(2(p2-p1)/width) x N(polylines_blocker.points) +static Points get_frontier(Polylines &polylines, const Point& p1, const Point& p2, const coord_t width, const Polylines &polylines_blockers, coord_t max_size = -1) { + for (size_t idx_poly = 0; idx_poly < polylines.size(); ++idx_poly) { + Polyline &poly = polylines[idx_poly]; + if (poly.size() <= 1) continue; + + //loop? + if (poly.first_point() == poly.last_point()) { + //polygon : try to find a line for p1 & p2. + size_t idx_11, idx_12, idx_21, idx_22; + idx_11 = poly.closest_point_index(p1); + idx_12 = idx_11; + if (Line(poly.points[idx_11], poly.points[(idx_11 + 1) % (poly.points.size() - 1)]).distance_to(p1) < SCALED_EPSILON) { + idx_12 = (idx_11 + 1) % (poly.points.size() - 1); + } else if (Line(poly.points[(idx_11 > 0) ? (idx_11 - 1) : (poly.points.size() - 2)], poly.points[idx_11]).distance_to(p1) < SCALED_EPSILON) { + idx_11 = (idx_11 > 0) ? (idx_11 - 1) : (poly.points.size() - 2); + } else { + continue; + } + idx_21 = poly.closest_point_index(p2); + idx_22 = idx_21; + if (Line(poly.points[idx_21], poly.points[(idx_21 + 1) % (poly.points.size() - 1)]).distance_to(p2) < SCALED_EPSILON) { + idx_22 = (idx_21 + 1) % (poly.points.size() - 1); + } else if (Line(poly.points[(idx_21 > 0) ? (idx_21 - 1) : (poly.points.size() - 2)], poly.points[idx_21]).distance_to(p2) < SCALED_EPSILON) { + idx_21 = (idx_21 > 0) ? (idx_21 - 1) : (poly.points.size() - 2); + } else { + continue; + } + + + //edge case: on the same line + if (idx_11 == idx_21 && idx_12 == idx_22) { + if (collision(Points() = { p1, p2 }, polylines_blockers, width)) return Points(); + //break loop + poly.points.erase(poly.points.end() - 1); + cut_polygon(poly, idx_11, p1, p2); + return Points() = { Line(p1, p2).midpoint() }; + } + + //compute distance & array for the ++ path + Points ret_1_to_2; + double dist_1_to_2 = p1.distance_to(poly.points[idx_12]); + ret_1_to_2.push_back(poly.points[idx_12]); + size_t max = idx_12 <= idx_21 ? idx_21+1 : poly.points.size(); + for (size_t i = idx_12 + 1; i < max; i++) { + dist_1_to_2 += poly.points[i - 1].distance_to(poly.points[i]); + ret_1_to_2.push_back(poly.points[i]); + } + if (idx_12 > idx_21) { + dist_1_to_2 += poly.points.back().distance_to(poly.points.front()); + ret_1_to_2.push_back(poly.points[0]); + for (size_t i = 1; i <= idx_21; i++) { + dist_1_to_2 += poly.points[i - 1].distance_to(poly.points[i]); + ret_1_to_2.push_back(poly.points[i]); + } + } + dist_1_to_2 += p2.distance_to(poly.points[idx_21]); + + //compute distance & array for the -- path + Points ret_2_to_1; + double dist_2_to_1 = p1.distance_to(poly.points[idx_11]); + ret_2_to_1.push_back(poly.points[idx_11]); + size_t min = idx_22 <= idx_11 ? idx_22 : 0; + for (size_t i = idx_11; i > min; i--) { + dist_2_to_1 += poly.points[i - 1].distance_to(poly.points[i]); + ret_2_to_1.push_back(poly.points[i - 1]); + } + if (idx_22 > idx_11) { + dist_2_to_1 += poly.points.back().distance_to(poly.points.front()); + ret_2_to_1.push_back(poly.points[poly.points.size() - 1]); + for (size_t i = poly.points.size() - 1; i > idx_22; i--) { + dist_2_to_1 += poly.points[i - 1].distance_to(poly.points[i]); + ret_2_to_1.push_back(poly.points[i - 1]); + } + } + dist_2_to_1 += p2.distance_to(poly.points[idx_22]); + + if (max_size < dist_2_to_1 && max_size < dist_1_to_2) { + return Points(); + } + + //choose between the two direction (keep the short one) + if (dist_1_to_2 < dist_2_to_1) { + if (collision(ret_1_to_2, polylines_blockers, width)) return Points(); + //break loop + poly.points.erase(poly.points.end() - 1); + //remove points + if (idx_12 <= idx_21) { + poly.points.erase(poly.points.begin() + idx_12, poly.points.begin() + idx_21 + 1); + if (idx_12 != 0) { + cut_polygon(poly, idx_11, p1, p2); + } //else : already cut at the good place + } else { + poly.points.erase(poly.points.begin() + idx_12, poly.points.end()); + poly.points.erase(poly.points.begin(), poly.points.begin() + idx_21); + cut_polygon(poly, poly.points.size() - 1, p1, p2); + } + return ret_1_to_2; + } else { + if (collision(ret_2_to_1, polylines_blockers, width)) return Points(); + //break loop + poly.points.erase(poly.points.end() - 1); + //remove points + if (idx_22 <= idx_11) { + poly.points.erase(poly.points.begin() + idx_22, poly.points.begin() + idx_11 + 1); + if (idx_22 != 0) { + cut_polygon(poly, idx_21, p1, p2); + } //else : already cut at the good place + } else { + poly.points.erase(poly.points.begin() + idx_22, poly.points.end()); + poly.points.erase(poly.points.begin(), poly.points.begin() + idx_11); + cut_polygon(poly, poly.points.size() - 1, p1, p2); + } + return ret_2_to_1; + } + } else { + //polyline : try to find a line for p1 & p2. + size_t idx_1, idx_2; + idx_1 = poly.closest_point_index(p1); + if (idx_1 < poly.points.size() - 1 && Line(poly.points[idx_1], poly.points[idx_1 + 1]).distance_to(p1) < SCALED_EPSILON) { + } else if (idx_1 > 0 && Line(poly.points[idx_1 - 1], poly.points[idx_1]).distance_to(p1) < SCALED_EPSILON) { + idx_1 = idx_1 - 1; + } else { + continue; + } + idx_2 = poly.closest_point_index(p2); + if (idx_2 < poly.points.size() - 1 && Line(poly.points[idx_2], poly.points[idx_2 + 1]).distance_to(p2) < SCALED_EPSILON) { + } else if (idx_2 > 0 && Line(poly.points[idx_2 - 1], poly.points[idx_2]).distance_to(p2) < SCALED_EPSILON) { + idx_2 = idx_2 - 1; + } else { + continue; + } + + //edge case: on the same line + if (idx_1 == idx_2) { + if (collision(Points() = { p1, p2 }, polylines_blockers, width)) return Points(); + cut_polyline(poly, polylines, idx_1, p1, p2); + return Points() = { Line(p1, p2).midpoint() }; + } + + //create ret array + size_t first_idx = idx_1; + size_t last_idx = idx_2 + 1; + if (idx_1 > idx_2) { + first_idx = idx_2; + last_idx = idx_1 + 1; + } + Points p_ret; + p_ret.insert(p_ret.end(), poly.points.begin() + first_idx + 1, poly.points.begin() + last_idx); + + coordf_t length = 0; + for (size_t i = 1; i < p_ret.size(); i++) length += p_ret[i - 1].distance_to(p_ret[i]); + + if (max_size < length) { + return Points(); + } + + if (collision(p_ret, polylines_blockers, width)) return Points(); + //cut polyline + poly.points.erase(poly.points.begin() + first_idx + 1, poly.points.begin() + last_idx); + cut_polyline(poly, polylines, first_idx, p1, p2); + //order the returned array to be p1->p2 + if (idx_1 > idx_2) { + std::reverse(p_ret.begin(), p_ret.end()); + } + return p_ret; + } + + } + + return Points(); +} + +/// Connect the infill_ordered polylines, in this order, from the back point to the next front point. +/// It uses only the boundary polygons to do so, and can't pass two times at the same place. +/// It avoid passing over the infill_ordered's polylines (preventing local over-extrusion). +/// return the connected polylines in polylines_out. Can output polygons (stored as polylines with first_point = last_point). +/// complexity: worst: N(infill_ordered.points) x N(boundary.points) +/// typical: N(infill_ordered) x ( N(boundary.points) + N(infill_ordered.points) ) +void Fill::connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const FillParams ¶ms) { + + //TODO: fallback to the quick & dirty old algorithm when n(points) is too high. + Polylines polylines_frontier = to_polylines(((Polygons)boundary)); + + Polylines polylines_blocker; + coord_t clip_size = scale_(this->spacing) * 2; + for (const Polyline &polyline : infill_ordered) { + if (polyline.length() > 2.01 * clip_size) { + polylines_blocker.push_back(polyline); + polylines_blocker.back().clip_end(clip_size); + polylines_blocker.back().clip_start(clip_size); + } + } + + //length between two lines + coordf_t ideal_length = (1 / params.density) * this->spacing; + + Polylines polylines_connected_first; + bool first = true; + for (const Polyline &polyline : infill_ordered) { + if (!first) { + // Try to connect the lines. + Points &pts_end = polylines_connected_first.back().points; + const Point &last_point = pts_end.back(); + const Point &first_point = polyline.points.front(); + if (last_point.distance_to(first_point) < scale_(this->spacing) * 10) { + Points pts_frontier = get_frontier(polylines_frontier, last_point, first_point, scale_(this->spacing), polylines_blocker, (coord_t)scale_(ideal_length) * 2); + if (!pts_frontier.empty()) { + // The lines can be connected. + pts_end.insert(pts_end.end(), pts_frontier.begin(), pts_frontier.end()); + pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end()); + continue; + } + } + } + // The lines cannot be connected. + polylines_connected_first.emplace_back(std::move(polyline)); + + first = false; + } + + Polylines polylines_connected; + first = true; + for (const Polyline &polyline : polylines_connected_first) { + if (!first) { + // Try to connect the lines. + Points &pts_end = polylines_connected.back().points; + const Point &last_point = pts_end.back(); + const Point &first_point = polyline.points.front(); + + Polylines before = polylines_frontier; + Points pts_frontier = get_frontier(polylines_frontier, last_point, first_point, scale_(this->spacing), polylines_blocker); + if (!pts_frontier.empty()) { + // The lines can be connected. + pts_end.insert(pts_end.end(), pts_frontier.begin(), pts_frontier.end()); + pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end()); + continue; + } + } + // The lines cannot be connected. + polylines_connected.emplace_back(std::move(polyline)); + + first = false; + } + + //try to link to nearest point if possible + for (size_t idx1 = 0; idx1 < polylines_connected.size(); idx1++) { + size_t min_idx = 0; + coordf_t min_length = 0; + bool switch_id1 = false; + bool switch_id2 = false; + for (size_t idx2 = idx1 + 1; idx2 < polylines_connected.size(); idx2++) { + double last_first = polylines_connected[idx1].last_point().distance_to_square(polylines_connected[idx2].first_point()); + double first_first = polylines_connected[idx1].first_point().distance_to_square(polylines_connected[idx2].first_point()); + double first_last = polylines_connected[idx1].first_point().distance_to_square(polylines_connected[idx2].last_point()); + double last_last = polylines_connected[idx1].last_point().distance_to_square(polylines_connected[idx2].last_point()); + double min = std::min(std::min(last_first, last_last), std::min(first_first, first_last)); + if (min < min_length || min_length == 0) { + min_idx = idx2; + switch_id1 = (std::min(last_first, last_last) > std::min(first_first, first_last)); + switch_id2 = (std::min(last_first, first_first) > std::min(last_last, first_last)); + min_length = min; + } + } + if (min_idx > idx1 && min_idx < polylines_connected.size()){ + Points pts_frontier = get_frontier(polylines_frontier, + switch_id1 ? polylines_connected[idx1].first_point() : polylines_connected[idx1].last_point(), + switch_id2 ? polylines_connected[min_idx].last_point() : polylines_connected[min_idx].first_point(), + scale_(this->spacing), polylines_blocker); + if (!pts_frontier.empty()) { + if (switch_id1) polylines_connected[idx1].reverse(); + if (switch_id2) polylines_connected[min_idx].reverse(); + Points &pts_end = polylines_connected[idx1].points; + pts_end.insert(pts_end.end(), pts_frontier.begin(), pts_frontier.end()); + pts_end.insert(pts_end.end(), polylines_connected[min_idx].points.begin(), polylines_connected[min_idx].points.end()); + polylines_connected.erase(polylines_connected.begin() + min_idx); + } + } + } + + //try to create some loops if possible + for (Polyline &polyline : polylines_connected) { + Points pts_frontier = get_frontier(polylines_frontier, polyline.last_point(), polyline.first_point(), scale_(this->spacing), polylines_blocker); + if (!pts_frontier.empty()) { + polyline.points.insert(polyline.points.end(), pts_frontier.begin(), pts_frontier.end()); + polyline.points.insert(polyline.points.begin(), polyline.points.back()); + } + polylines_out.emplace_back(polyline); + } +} + +#else + +struct ContourPointData { + ContourPointData(float param) : param(param) {} + // Eucleidean position of the contour point along the contour. + float param = 0.f; + // Was the segment starting with this contour point extruded? + bool segment_consumed = false; + // Was this point extruded over? + bool point_consumed = false; +}; + +// Verify whether the contour from point idx_start to point idx_end could be taken (whether all segments along the contour were not yet extruded). +static bool could_take(const std::vector &contour_data, size_t idx_start, size_t idx_end) +{ + assert(idx_start != idx_end); + for (size_t i = idx_start; i != idx_end; ) { + if (contour_data[i].segment_consumed || contour_data[i].point_consumed) + return false; + if (++ i == contour_data.size()) + i = 0; + } + return ! contour_data[idx_end].point_consumed; +} + +// Connect end of pl1 to the start of pl2 using the perimeter contour. +// The idx_start and idx_end are ordered so that the connecting polyline points will be taken with increasing indices. +static void take(Polyline &pl1, Polyline &&pl2, const Points &contour, std::vector &contour_data, size_t idx_start, size_t idx_end, bool reversed) +{ +#ifndef NDEBUG + size_t num_points_initial = pl1.points.size(); + assert(idx_start != idx_end); +#endif /* NDEBUG */ + + { + // Reserve memory at pl1 for the connecting contour and pl2. + int new_points = int(idx_end) - int(idx_start) - 1; + if (new_points < 0) + new_points += int(contour.size()); + pl1.points.reserve(pl1.points.size() + size_t(new_points) + pl2.points.size()); + } + + contour_data[idx_start].point_consumed = true; + contour_data[idx_start].segment_consumed = true; + contour_data[idx_end ].point_consumed = true; + + if (reversed) { + size_t i = (idx_end == 0) ? contour_data.size() - 1 : idx_end - 1; + while (i != idx_start) { + contour_data[i].point_consumed = true; + contour_data[i].segment_consumed = true; + pl1.points.emplace_back(contour[i]); + if (i == 0) + i = contour_data.size(); + -- i; + } + } else { + size_t i = idx_start; + if (++ i == contour_data.size()) + i = 0; + while (i != idx_end) { + contour_data[i].point_consumed = true; + contour_data[i].segment_consumed = true; + pl1.points.emplace_back(contour[i]); + if (++ i == contour_data.size()) + i = 0; + } + } + + append(pl1.points, std::move(pl2.points)); +} + +// Return an index of start of a segment and a point of the clipping point at distance from the end of polyline. +struct SegmentPoint { + // Segment index, defining a line ::max(); + // Parameter of point in <0, 1) along the line ::max(); } +}; + +static inline SegmentPoint clip_start_segment_and_point(const Points &polyline, double distance) +{ + assert(polyline.size() >= 2); + assert(distance > 0.); + // Initialized to "invalid". + SegmentPoint out; + if (polyline.size() >= 2) { + const double d2 = distance * distance; + Vec2d pt_prev = polyline.front().cast(); + for (int i = 1; i < polyline.size(); ++ i) { + Vec2d pt = polyline[i].cast(); + Vec2d v = pt - pt_prev; + double l2 = v.squaredNorm(); + if (l2 > d2) { + out.idx_segment = i; + out.t = distance / sqrt(l2); + out.point = pt + out.t * v; + break; + } + distance -= sqrt(l2); + pt_prev = pt; + } + } + return out; +} + +static inline SegmentPoint clip_end_segment_and_point(const Points &polyline, double distance) +{ + assert(polyline.size() >= 2); + assert(distance > 0.); + // Initialized to "invalid". + SegmentPoint out; + if (polyline.size() >= 2) { + const double d2 = distance * distance; + Vec2d pt_next = polyline.back().cast(); + for (int i = int(polyline.size()) - 2; i >= 0; -- i) { + Vec2d pt = polyline[i].cast(); + Vec2d v = pt - pt_next; + double l2 = v.squaredNorm(); + if (l2 > d2) { + out.idx_segment = i; + out.t = distance / sqrt(l2); + out.point = pt + out.t * v; + break; + } + distance -= sqrt(l2); + pt_next = pt; + } + } + return out; +} + +static inline double segment_point_distance_squared(const Vec2d &p1a, const Vec2d &p1b, const Vec2d &p2) +{ + const Vec2d v = p1b - p1a; + const Vec2d va = p2 - p1a; + const double l2 = v.squaredNorm(); + if (l2 < EPSILON) + // p1a == p1b + return va.squaredNorm(); + // Project p2 onto the (p1a, p1b) segment. + const double t = va.dot(v); + if (t < 0.) + return va.squaredNorm(); + else if (t > l2) + return (p2 - p1b).squaredNorm(); + return ((t / l2) * v - va).squaredNorm(); +} + +// Distance to the closest point of line. +static inline double min_distance_of_segments(const Vec2d &p1a, const Vec2d &p1b, const Vec2d &p2a, const Vec2d &p2b) +{ + Vec2d v1 = p1b - p1a; + double l1_2 = v1.squaredNorm(); + if (l1_2 < EPSILON) + // p1a == p1b: Return distance of p1a from the (p2a, p2b) segment. + return segment_point_distance_squared(p2a, p2b, p1a); + + Vec2d v2 = p2b - p2a; + double l2_2 = v2.squaredNorm(); + if (l2_2 < EPSILON) + // p2a == p2b: Return distance of p2a from the (p1a, p1b) segment. + return segment_point_distance_squared(p1a, p1b, p2a); + + // Project p2a, p2b onto the (p1a, p1b) segment. + auto project_p2a_p2b_onto_seg_p1a_p1b = [](const Vec2d& p1a, const Vec2d& p1b, const Vec2d& p2a, const Vec2d& p2b, const Vec2d& v1, const double l1_2) { + Vec2d v1a2a = p2a - p1a; + Vec2d v1a2b = p2b - p1a; + double t1 = v1a2a.dot(v1); + double t2 = v1a2b.dot(v1); + if (t1 <= 0.) { + if (t2 <= 0.) + // Both p2a and p2b are left of v1. + return (((t1 < t2) ? p2b : p2a) - p1a).squaredNorm(); + else if (t2 < l1_2) + // Project p2b onto the (p1a, p1b) segment. + return ((t2 / l1_2) * v1 - v1a2b).squaredNorm(); + } + else if (t1 >= l1_2) { + if (t2 >= l1_2) + // Both p2a and p2b are right of v1. + return (((t1 < t2) ? p2a : p2b) - p1b).squaredNorm(); + else if (t2 < l1_2) + // Project p2b onto the (p1a, p1b) segment. + return ((t2 / l1_2) * v1 - v1a2b).squaredNorm(); + } + else { + // Project p1b onto the (p1a, p1b) segment. + double dist_min = ((t2 / l1_2) * v1 - v1a2a).squaredNorm(); + if (t2 > 0. && t2 < l1_2) + dist_min = std::min(dist_min, ((t2 / l1_2) * v1 - v1a2b).squaredNorm()); + return dist_min; + } + return std::numeric_limits::max(); + }; + + return std::min( + project_p2a_p2b_onto_seg_p1a_p1b(p1a, p1b, p2a, p2b, v1, l1_2), + project_p2a_p2b_onto_seg_p1a_p1b(p2a, p2b, p1a, p1b, v2, l2_2)); +} + +// Mark the segments of split boundary as consumed if they are very close to some of the infill line. +void mark_boundary_segments_touching_infill( + const std::vector &boundary, + std::vector> &boundary_data, + const BoundingBox &boundary_bbox, + const Polylines &infill, + const double clip_distance, + const double distance_colliding) +{ + EdgeGrid::Grid grid; + grid.set_bbox(boundary_bbox); + // Inflate the bounding box by a thick line width. + grid.create(boundary, clip_distance + scale_(10.)); + + struct Visitor { + Visitor(const EdgeGrid::Grid &grid, const std::vector &boundary, std::vector> &boundary_data, const double dist2_max) : + grid(grid), boundary(boundary), boundary_data(boundary_data), dist2_max(dist2_max) {} + + void init(const Vec2d &pt1, const Vec2d &pt2) { + this->pt1 = &pt1; + this->pt2 = &pt2; + } + + bool operator()(coord_t iy, coord_t ix) { + // Called with a row and colum of the grid cell, which is intersected by a line. + auto cell_data_range = this->grid.cell_data_range(iy, ix); + for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++ it_contour_and_segment) { + // End points of the line segment and their vector. + auto segment = this->grid.segment(*it_contour_and_segment); + const Vec2d seg_pt1 = segment.first.cast(); + const Vec2d seg_pt2 = segment.second.cast(); + if (min_distance_of_segments(seg_pt1, seg_pt2, *this->pt1, *this->pt2) < this->dist2_max) { + // Mark this boundary segment as touching the infill line. + ContourPointData&bdp = boundary_data[it_contour_and_segment->first][it_contour_and_segment->second]; + bdp.segment_consumed = true; + // There is no need for checking seg_pt2 as it will be checked the next time. + if (segment_point_distance_squared(*this->pt1, *this->pt2, seg_pt1) < this->dist2_max) + bdp.point_consumed = true; + } + } + // Continue traversing the grid along the edge. + return true; + } + + const EdgeGrid::Grid &grid; + const std::vector &boundary; + std::vector> &boundary_data; + // Maximum distance between the boundary and the infill line allowed to consider the boundary not touching the infill line. + const double dist2_max; + + const Vec2d *pt1; + const Vec2d *pt2; + } visitor(grid, boundary, boundary_data, distance_colliding * distance_colliding); + + for (const Polyline &polyline : infill) { + // Clip the infill polyline by the Eucledian distance along the polyline. + SegmentPoint start_point = clip_start_segment_and_point(polyline.points, clip_distance); + SegmentPoint end_point = clip_end_segment_and_point(polyline.points, clip_distance); + if (start_point.valid() && end_point.valid() && + (start_point.idx_segment < end_point.idx_segment || (start_point.idx_segment == end_point.idx_segment && start_point.t < end_point.t))) { + // The clipped polyline is non-empty. + for (size_t point_idx = start_point.idx_segment; point_idx <= end_point.idx_segment; ++ point_idx) { +//FIXME extend the EdgeGrid to suport tracing a thick line. +#if 0 + Point pt1, pt2; + Vec2d pt1d, pt2d; + if (point_idx == start_point.idx_segment) { + pt1d = start_point.point; + pt1 = pt1d.cast(); + } else { + pt1 = polyline.points[point_idx]; + pt1d = pt1.cast(); + } + if (point_idx == start_point.idx_segment) { + pt2d = end_point.point; + pt2 = pt1d.cast(); + } else { + pt2 = polyline.points[point_idx]; + pt2d = pt2.cast(); + } + visitor.init(pt1d, pt2d); + grid.visit_cells_intersecting_thick_line(pt1, pt2, distance_colliding, visitor); +#else + Vec2d pt1 = (point_idx == start_point.idx_segment) ? start_point.point : polyline.points[point_idx].cast(); + Vec2d pt2 = (point_idx == end_point .idx_segment) ? end_point .point : polyline.points[point_idx].cast(); + visitor.init(pt1, pt2); + // Simulate tracing of a thick line. This only works reliably if distance_colliding <= grid cell size. + Vec2d v = (pt2 - pt1).normalized() * distance_colliding; + Vec2d vperp(-v.y(), v.x()); + Vec2d a = pt1 - v - vperp; + Vec2d b = pt1 + v - vperp; + grid.visit_cells_intersecting_line(a.cast(), b.cast(), visitor); + a = pt1 - v + vperp; + b = pt1 + v + vperp; + grid.visit_cells_intersecting_line(a.cast(), b.cast(), visitor); +#endif + } + } + } +} + +void Fill::connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary_src, Polylines &polylines_out, const FillParams ¶ms) +{ + assert(! infill_ordered.empty()); + assert(! boundary_src.contour.points.empty()); + + BoundingBox bbox = get_extents(boundary_src.contour); + bbox.offset(SCALED_EPSILON); + + // 1) Add the end points of infill_ordered to boundary_src. + std::vector boundary; + std::vector> boundary_data; + boundary.assign(boundary_src.holes.size() + 1, Points()); + boundary_data.assign(boundary_src.holes.size() + 1, std::vector()); + // Mapping the infill_ordered end point to a (contour, point) of boundary. + std::vector> map_infill_end_point_to_boundary; + map_infill_end_point_to_boundary.assign(infill_ordered.size() * 2, std::pair(std::numeric_limits::max(), std::numeric_limits::max())); + { + // Project the infill_ordered end points onto boundary_src. + std::vector> intersection_points; + { + EdgeGrid::Grid grid; + grid.set_bbox(bbox); + grid.create(boundary_src, scale_(10.)); + intersection_points.reserve(infill_ordered.size() * 2); + for (const Polyline &pl : infill_ordered) + for (const Point *pt : { &pl.points.front(), &pl.points.back() }) { + EdgeGrid::Grid::ClosestPointResult cp = grid.closest_point(*pt, SCALED_EPSILON); + if (cp.valid()) { + // The infill end point shall lie on the contour. + assert(cp.distance < 2.); + intersection_points.emplace_back(cp, (&pl - infill_ordered.data()) * 2 + (pt == &pl.points.front() ? 0 : 1)); + } + } + std::sort(intersection_points.begin(), intersection_points.end(), [](const std::pair &cp1, const std::pair &cp2) { + return cp1.first.contour_idx < cp2.first.contour_idx || + (cp1.first.contour_idx == cp2.first.contour_idx && + (cp1.first.start_point_idx < cp2.first.start_point_idx || + (cp1.first.start_point_idx == cp2.first.start_point_idx && cp1.first.t < cp2.first.t))); + }); + } + auto it = intersection_points.begin(); + auto it_end = intersection_points.end(); + for (size_t idx_contour = 0; idx_contour <= boundary_src.holes.size(); ++ idx_contour) { + const Polygon &contour_src = (idx_contour == 0) ? boundary_src.contour : boundary_src.holes[idx_contour - 1]; + Points &contour_dst = boundary[idx_contour]; + for (size_t idx_point = 0; idx_point < contour_src.points.size(); ++ idx_point) { + contour_dst.emplace_back(contour_src.points[idx_point]); + for (; it != it_end && it->first.contour_idx == idx_contour && it->first.start_point_idx == idx_point; ++ it) { + // Add these points to the destination contour. + const Vec2d pt1 = contour_src[idx_point].cast(); + const Vec2d pt2 = (idx_point + 1 == contour_src.size() ? contour_src.points.front() : contour_src.points[idx_point + 1]).cast(); + const Vec2d pt = lerp(pt1, pt2, it->first.t); + map_infill_end_point_to_boundary[it->second] = std::make_pair(idx_contour, contour_dst.size()); + contour_dst.emplace_back(pt.cast()); + } + } + // Parametrize the curve. + std::vector &contour_data = boundary_data[idx_contour]; + contour_data.reserve(contour_dst.size()); + contour_data.emplace_back(ContourPointData(0.f)); + for (size_t i = 1; i < contour_dst.size(); ++ i) + contour_data.emplace_back(contour_data.back().param + (contour_dst[i].cast() - contour_dst[i - 1].cast()).norm()); + contour_data.front().param = contour_data.back().param + (contour_dst.back().cast() - contour_dst.front().cast()).norm(); + } + +#ifndef NDEBUG + assert(boundary.size() == boundary_src.num_contours()); + assert(std::all_of(map_infill_end_point_to_boundary.begin(), map_infill_end_point_to_boundary.end(), + [&boundary](const std::pair &contour_point) { + return contour_point.first < boundary.size() && contour_point.second < boundary[contour_point.first].size(); + })); +#endif /* NDEBUG */ + } + + // Mark the points and segments of split boundary as consumed if they are very close to some of the infill line. + { + //const double clip_distance = scale_(this->spacing); + const double clip_distance = 3. * scale_(this->spacing); + const double distance_colliding = scale_(this->spacing); + mark_boundary_segments_touching_infill(boundary, boundary_data, bbox, infill_ordered, clip_distance, distance_colliding); + } + + // Connection from end of one infill line to the start of another infill line. + //const float length_max = scale_(this->spacing); +// const float length_max = scale_((2. / params.density) * this->spacing); + const float length_max = scale_((1000. / params.density) * this->spacing); + std::vector merged_with(infill_ordered.size()); + for (size_t i = 0; i < merged_with.size(); ++ i) + merged_with[i] = i; + struct ConnectionCost { + ConnectionCost(size_t idx_first, double cost, bool reversed) : idx_first(idx_first), cost(cost), reversed(reversed) {} + size_t idx_first; + double cost; + bool reversed; + }; + std::vector connections_sorted; + connections_sorted.reserve(infill_ordered.size() * 2 - 2); + for (size_t idx_chain = 1; idx_chain < infill_ordered.size(); ++ idx_chain) { + const Polyline &pl1 = infill_ordered[idx_chain - 1]; + const Polyline &pl2 = infill_ordered[idx_chain]; + const std::pair *cp1 = &map_infill_end_point_to_boundary[(idx_chain - 1) * 2 + 1]; + const std::pair *cp2 = &map_infill_end_point_to_boundary[idx_chain * 2]; + const std::vector &contour_data = boundary_data[cp1->first]; + if (cp1->first == cp2->first) { + // End points on the same contour. Try to connect them. + float param_lo = (cp1->second == 0) ? 0.f : contour_data[cp1->second].param; + float param_hi = (cp2->second == 0) ? 0.f : contour_data[cp2->second].param; + float param_end = contour_data.front().param; + bool reversed = false; + if (param_lo > param_hi) { + std::swap(param_lo, param_hi); + reversed = true; + } + assert(param_lo >= 0.f && param_lo <= param_end); + assert(param_hi >= 0.f && param_hi <= param_end); + double len = param_hi - param_lo; + if (len < length_max) + connections_sorted.emplace_back(idx_chain - 1, len, reversed); + len = param_lo + param_end - param_hi; + if (len < length_max) + connections_sorted.emplace_back(idx_chain - 1, len, ! reversed); + } + } + std::sort(connections_sorted.begin(), connections_sorted.end(), [](const ConnectionCost& l, const ConnectionCost& r) { return l.cost < r.cost; }); + + size_t idx_chain_last = 0; + for (ConnectionCost &connection_cost : connections_sorted) { + const std::pair *cp1 = &map_infill_end_point_to_boundary[connection_cost.idx_first * 2 + 1]; + const std::pair *cp2 = &map_infill_end_point_to_boundary[(connection_cost.idx_first + 1) * 2]; + assert(cp1->first == cp2->first); + std::vector &contour_data = boundary_data[cp1->first]; + if (connection_cost.reversed) + std::swap(cp1, cp2); + if (could_take(contour_data, cp1->second, cp2->second)) { + // Indices of the polygons to be connected. + size_t idx_first = connection_cost.idx_first; + size_t idx_second = idx_first + 1; + for (size_t last = idx_first;;) { + size_t lower = merged_with[last]; + if (lower == last) { + merged_with[idx_first] = lower; + idx_first = lower; + break; + } + last = lower; + } + // Connect the two polygons using the boundary contour. + take(infill_ordered[idx_first], std::move(infill_ordered[idx_second]), boundary[cp1->first], contour_data, cp1->second, cp2->second, connection_cost.reversed); + // Mark the second polygon as merged with the first one. + merged_with[idx_second] = merged_with[idx_first]; + } + } + polylines_out.reserve(polylines_out.size() + std::count_if(infill_ordered.begin(), infill_ordered.end(), [](const Polyline &pl) { return ! pl.empty(); })); + for (Polyline &pl : infill_ordered) + if (! pl.empty()) + polylines_out.emplace_back(std::move(pl)); +} + +#endif + } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 3b834dede3..d005f6e4ad 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -111,6 +111,8 @@ protected: virtual std::pair _infill_direction(const Surface *surface) const; + void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const FillParams ¶ms); + public: static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance); diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp index 7cd9558923..ed0586edfe 100644 --- a/src/libslic3r/Fill/FillGyroid.cpp +++ b/src/libslic3r/Fill/FillGyroid.cpp @@ -31,19 +31,26 @@ static inline double f(double x, double z_sin, double z_cos, bool vertical, bool static inline Polyline make_wave( const std::vector& one_period, double width, double height, double offset, double scaleFactor, - double z_cos, double z_sin, bool vertical) + double z_cos, double z_sin, bool vertical, bool flip) { std::vector points = one_period; double period = points.back()(0); - points.pop_back(); - int n = points.size(); - do { - points.emplace_back(Vec2d(points[points.size()-n](0) + period, points[points.size()-n](1))); - } while (points.back()(0) < width); - points.back()(0) = width; + if (width != period) // do not extend if already truncated + { + points.reserve(one_period.size() * floor(width / period)); + points.pop_back(); + + int n = points.size(); + do { + points.emplace_back(Vec2d(points[points.size()-n](0) + period, points[points.size()-n](1))); + } while (points.back()(0) < width - EPSILON); + + points.emplace_back(Vec2d(width, f(width, z_sin, z_cos, vertical, flip))); + } // and construct the final polyline to return: Polyline polyline; + polyline.points.reserve(points.size()); for (auto& point : points) { point(1) += offset; point(1) = clamp(0., height, double(point(1))); @@ -55,45 +62,56 @@ static inline Polyline make_wave( return polyline; } -static std::vector make_one_period(double width, double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip) +static std::vector make_one_period(double width, double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip, double tolerance) { std::vector points; - double dx = M_PI_4; // very coarse spacing to begin with + double dx = M_PI_2; // exact coordinates on main inflexion lobes double limit = std::min(2*M_PI, width); - for (double x = 0.; x < limit + EPSILON; x += dx) { // so the last point is there too - x = std::min(x, limit); - points.emplace_back(Vec2d(x,f(x, z_sin,z_cos, vertical, flip))); - } + points.reserve(ceil(limit / tolerance / 3)); - // now we will check all internal points and in case some are too far from the line connecting its neighbours, - // we will add one more point on each side: - const double tolerance = .1; - for (unsigned int i=1;i(scaleFactor) * std::abs(cross2(rp, lp) - cross2(rp - lp, tp)) / lrv.norm(); - if (dist_mm > tolerance) { // if the difference from straight line is more than this - double x = 0.5f * (points[i-1](0) + points[i](0)); - points.emplace_back(Vec2d(x, f(x, z_sin, z_cos, vertical, flip))); - x = 0.5f * (points[i+1](0) + points[i](0)); - points.emplace_back(Vec2d(x, f(x, z_sin, z_cos, vertical, flip))); - // we added the points to the end, but need them all in order - std::sort(points.begin(), points.end(), [](const Vec2d &lhs, const Vec2d &rhs){ return lhs < rhs; }); - // decrement i so we also check the first newly added point - --i; + for (double x = 0.; x < limit - EPSILON; x += dx) { + points.emplace_back(Vec2d(x, f(x, z_sin, z_cos, vertical, flip))); + } + points.emplace_back(Vec2d(limit, f(limit, z_sin, z_cos, vertical, flip))); + + // piecewise increase in resolution up to requested tolerance + for(;;) + { + size_t size = points.size(); + for (unsigned int i = 1;i < size; ++i) { + auto& lp = points[i-1]; // left point + auto& rp = points[i]; // right point + double x = lp(0) + (rp(0) - lp(0)) / 2; + double y = f(x, z_sin, z_cos, vertical, flip); + Vec2d ip = {x, y}; + if (std::abs(cross2(Vec2d(ip - lp), Vec2d(ip - rp))) > sqr(tolerance)) { + points.emplace_back(std::move(ip)); + } + } + + if (size == points.size()) + break; + else + { + // insert new points in order + std::sort(points.begin(), points.end(), + [](const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0); }); } } + return points; } static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double line_spacing, double width, double height) { const double scaleFactor = scale_(line_spacing) / density_adjusted; - //scale factor for 5% : 8 712 388 - // 1z = 10^-6 mm ? + + // tolerance in scaled units. clamp the maximum tolerance as there's + // no processing-speed benefit to do so beyond a certain point + const double tolerance = std::min(line_spacing / 2, FillGyroid::PatternTolerance) / unscale(scaleFactor); + + //scale factor for 5% : 8 712 388 + // 1z = 10^-6 mm ? const double z = gridZ / scaleFactor; const double z_sin = sin(z); const double z_cos = cos(z); @@ -109,20 +127,27 @@ static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double std::swap(width,height); } - std::vector one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // creates one period of the waves, so it doesn't have to be recalculated all the time + std::vector one_period_odd = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip, tolerance); // creates one period of the waves, so it doesn't have to be recalculated all the time + flip = !flip; // even polylines are a bit shifted + std::vector one_period_even = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip, tolerance); Polylines result; - for (double y0 = lower_bound; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates odd polylines - result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical)); - - flip = !flip; // even polylines are a bit shifted - one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // updates the one period sample - for (double y0 = lower_bound + M_PI; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates even polylines - result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical)); + for (double y0 = lower_bound; y0 < upper_bound + EPSILON; y0 += M_PI) { + // creates odd polylines + result.emplace_back(make_wave(one_period_odd, width, height, y0, scaleFactor, z_cos, z_sin, vertical, flip)); + // creates even polylines + y0 += M_PI; + if (y0 < upper_bound + EPSILON) { + result.emplace_back(make_wave(one_period_even, width, height, y0, scaleFactor, z_cos, z_sin, vertical, flip)); + } + } return result; } +// FIXME: needed to fix build on Mac on buildserver +constexpr double FillGyroid::PatternTolerance; + void FillGyroid::_fill_surface_single( const FillParams ¶ms, unsigned int thickness_layers, @@ -130,63 +155,52 @@ void FillGyroid::_fill_surface_single( ExPolygon &expolygon, Polylines &polylines_out) { - // no rotation is supported for this infill pattern (yet) + float infill_angle = this->angle + (CorrectionAngle * 2*M_PI) / 360.; + if(abs(infill_angle) >= EPSILON) + expolygon.rotate(-infill_angle); + BoundingBox bb = expolygon.contour.bounding_box(); // Density adjusted to have a good %of weight. - double density_adjusted = std::max(0., params.density * 2.44); + double density_adjusted = std::max(0., params.density * DensityAdjust); // Distance between the gyroid waves in scaled coordinates. coord_t distance = coord_t(scale_(this->spacing) / density_adjusted); // align bounding box to a multiple of our grid module - bb.merge(_align_to_grid(bb.min, Point(2.*M_PI*distance, 2.*M_PI*distance))); + bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance))); // generate pattern - Polylines polylines = make_gyroid_waves( + Polylines polylines = make_gyroid_waves( scale_(this->z), density_adjusted, this->spacing, ceil(bb.size()(0) / distance) + 1., ceil(bb.size()(1) / distance) + 1.); - - // move pattern in place - for (Polyline &polyline : polylines) - polyline.translate(bb.min(0), bb.min(1)); - // clip pattern to boundaries - polylines = intersection_pl(polylines, (Polygons)expolygon); + // shift the polyline to the grid origin + for (Polyline &pl : polylines) + pl.translate(bb.min); - // connect lines - if (! params.dont_connect && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections - ExPolygon expolygon_off; - { - ExPolygons expolygons_off = offset_ex(expolygon, (float)SCALED_EPSILON); - if (! expolygons_off.empty()) { - // When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island. - assert(expolygons_off.size() == 1); - std::swap(expolygon_off, expolygons_off.front()); - } - } - bool first = true; - for (Polyline &polyline : chain_polylines(std::move(polylines))) { - if (! first) { - // Try to connect the lines. - Points &pts_end = polylines_out.back().points; - const Point &first_point = polyline.points.front(); - const Point &last_point = pts_end.back(); - // TODO: we should also check that both points are on a fill_boundary to avoid - // connecting paths on the boundaries of internal regions - // TODO: avoid crossing current infill path - if ((last_point - first_point).cast().norm() <= 5 * distance && - expolygon_off.contains(Line(last_point, first_point))) { - // Append the polyline. - pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end()); - continue; - } - } - // The lines cannot be connected. - polylines_out.emplace_back(std::move(polyline)); - first = false; - } + polylines = intersection_pl(polylines, to_polygons(expolygon)); + + if (! polylines.empty()) + // remove too small bits (larger than longer) + polylines.erase( + std::remove_if(polylines.begin(), polylines.end(), [this](const Polyline &pl) { return pl.length() < scale_(this->spacing * 3); }), + polylines.end()); + + if (! polylines.empty()) { + polylines = chain_polylines(polylines); + // connect lines + size_t polylines_out_first_idx = polylines_out.size(); + if (params.dont_connect) + append(polylines_out, std::move(polylines)); + else + this->connect_infill(std::move(polylines), expolygon, polylines_out, params); + // new paths must be rotated back + if (abs(infill_angle) >= EPSILON) { + for (auto it = polylines_out.begin() + polylines_out_first_idx; it != polylines_out.end(); ++ it) + it->rotate(infill_angle); + } } } diff --git a/src/libslic3r/Fill/FillGyroid.hpp b/src/libslic3r/Fill/FillGyroid.hpp index 9c3cef940b..37babb25e3 100644 --- a/src/libslic3r/Fill/FillGyroid.hpp +++ b/src/libslic3r/Fill/FillGyroid.hpp @@ -16,6 +16,17 @@ public: // require bridge flow since most of this pattern hangs in air virtual bool use_bridge_flow() const { return false; } + // Correction applied to regular infill angle to maximize printing + // speed in default configuration (degrees) + static constexpr float CorrectionAngle = -45.; + + // Density adjustment to have a good %of weight. + static constexpr double DensityAdjust = 2.44; + + // Gyroid upper resolution tolerance (mm^-2) + static constexpr double PatternTolerance = 0.2; + + protected: virtual void _fill_surface_single( const FillParams ¶ms, diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 63658e817f..56a94b28c2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -285,7 +285,7 @@ static inline Point wipe_tower_point_to_object_point(GCode &gcodegen, const Vec2 return Point(scale_(wipe_tower_pt.x() - gcodegen.origin()(0)), scale_(wipe_tower_pt.y() - gcodegen.origin()(1))); } -std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const +std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id, double z) const { if (new_extruder_id != -1 && new_extruder_id != tcr.new_tool) throw std::invalid_argument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect."); @@ -321,6 +321,15 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T gcode += gcodegen.unretract(); } + double current_z = gcodegen.writer().get_position().z(); + if (z == -1.) // in case no specific z was provided, print at current_z pos + z = current_z; + if (! is_approx(z, current_z)) { + gcode += gcodegen.writer().retract(); + gcode += gcodegen.writer().travel_to_z(z, "Travel down to the last wipe tower layer."); + gcode += gcodegen.writer().unretract(); + } + // Process the end filament gcode. std::string end_filament_gcode_str; @@ -387,16 +396,23 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T // A phony move to the end position at the wipe tower. gcodegen.writer().travel_to_xy(end_pos.cast()); gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos)); + if (! is_approx(z, current_z)) { + gcode += gcodegen.writer().retract(); + gcode += gcodegen.writer().travel_to_z(current_z, "Travel back up to the topmost object layer."); + gcode += gcodegen.writer().unretract(); + } - // Prepare a future wipe. - gcodegen.m_wipe.path.points.clear(); - if (new_extruder_id >= 0) { - // Start the wipe at the current position. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos)); - // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, - Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left, - end_pos.y()))); + else { + // Prepare a future wipe. + gcodegen.m_wipe.path.points.clear(); + if (new_extruder_id >= 0) { + // Start the wipe at the current position. + gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos)); + // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. + gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, + Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left, + end_pos.y()))); + } } // Let the planner know we are traveling between objects. @@ -522,7 +538,23 @@ std::string WipeTowerIntegration::tool_change(GCode &gcodegen, int extruder_id, if (m_layer_idx < (int)m_tool_changes.size()) { if (! (size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size())) throw std::runtime_error("Wipe tower generation failed, possibly due to empty first layer."); - gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id); + + + // Calculate where the wipe tower layer will be printed. -1 means that print z will not change, + // resulting in a wipe tower with sparse layers. + double wipe_tower_z = -1; + bool ignore_sparse = false; + if (gcodegen.config().wipe_tower_no_sparse_layers.value) { + wipe_tower_z = m_last_wipe_tower_print_z; + ignore_sparse = (m_brim_done && m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool); + if (m_tool_change_idx == 0 && ! ignore_sparse) + wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height; + } + + if (! ignore_sparse) { + gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z); + m_last_wipe_tower_print_z = wipe_tower_z; + } } m_brim_done = true; } @@ -961,7 +993,7 @@ void GCode::_do_export(Print &print, FILE *file) // Write thumbnails using base64 encoding if (thumbnail_data != nullptr) { - const unsigned int max_row_length = 78; + const size_t max_row_length = 78; for (const ThumbnailData& data : *thumbnail_data) { @@ -972,19 +1004,21 @@ void GCode::_do_export(Print &print, FILE *file) void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)data.pixels.data(), data.width, data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1); if (png_data != nullptr) { - _write_format(file, "\n;\n; thumbnail begin %dx%d\n", data.width, data.height); + std::string encoded; + encoded.resize(boost::beast::detail::base64::encoded_size(png_size)); + encoded.resize(boost::beast::detail::base64::encode((void*)&encoded[0], (const void*)png_data, png_size)); - std::string encoded = boost::beast::detail::base64_encode((const std::uint8_t*)png_data, png_size); + _write_format(file, "\n;\n; thumbnail begin %dx%d %d\n", data.width, data.height, encoded.size()); unsigned int row_count = 0; - while (encoded.length() > max_row_length) + while (encoded.size() > max_row_length) { _write_format(file, "; %s\n", encoded.substr(0, max_row_length).c_str()); encoded = encoded.substr(max_row_length); ++row_count; } - if (encoded.length() > 0) + if (encoded.size() > 0) _write_format(file, "; %s\n", encoded.c_str()); _write(file, "; thumbnail end\n;\n"); @@ -997,9 +1031,12 @@ void GCode::_do_export(Print &print, FILE *file) size_t row_size = 4 * data.width; for (int r = (int)data.height - 1; r >= 0; --r) { - std::string encoded = boost::beast::detail::base64_encode((const std::uint8_t*)(data.pixels.data() + r * row_size), row_size); + std::string encoded; + encoded.resize(boost::beast::detail::base64::encoded_size(row_size)); + encoded.resize(boost::beast::detail::base64::encode((void*)&encoded[0], (const void*)(data.pixels.data() + r * row_size), row_size)); + unsigned int row_count = 0; - while (encoded.length() > max_row_length) + while (encoded.size() > max_row_length) { if (row_count == 0) _write_format(file, "; %s\n", encoded.substr(0, max_row_length).c_str()); @@ -1010,7 +1047,7 @@ void GCode::_do_export(Print &print, FILE *file) ++row_count; } - if (encoded.length() > 0) + if (encoded.size() > 0) { if (row_count == 0) _write_format(file, "; %s\n", encoded.c_str()); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 3183e8883e..19ec5be3c2 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -113,7 +113,7 @@ public: private: WipeTowerIntegration& operator=(const WipeTowerIntegration&); - std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const; + std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id, double z = -1.) const; // Postprocesses gcode: rotates and moves G1 extrusions and returns result std::string post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const; @@ -134,6 +134,7 @@ private: int m_tool_change_idx; bool m_brim_done; bool i_have_brim = false; + double m_last_wipe_tower_print_z = 0.f; }; class GCode { diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 73dc91c405..cd326b9a0d 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -474,6 +474,7 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vectortoolchanges_depth() > WT_EPSILON; box_coordinates box = fill_box; for (int i=0;i<2;++i) { - if (m_layer_info->toolchanges_depth() < WT_EPSILON) { // there were no toolchanges on this layer + if (! toolchanges_on_layer) { if (i==0) box.expand(m_perimeter_width); else box.expand(-m_perimeter_width); } @@ -1201,9 +1203,12 @@ WipeTower::ToolChangeResult WipeTower::finish_layer() m_depth_traversed = m_wipe_tower_depth-m_perimeter_width; - // Ask our writer about how much material was consumed: - if (m_current_tool < m_used_filament_length.size()) - m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); + + // Ask our writer about how much material was consumed. + // Skip this in case the layer is sparse and config option to not print sparse layers is enabled. + if (! m_no_sparse_layers || toolchanges_on_layer) + if (m_current_tool < m_used_filament_length.size()) + m_used_filament_length[m_current_tool] += writer.get_and_reset_used_filament_length(); ToolChangeResult result; result.priming = false; diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index c1ea3f2b56..3114900559 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -220,6 +220,7 @@ private: float m_parking_pos_retraction = 0.f; float m_extra_loading_move = 0.f; float m_bridging = 0.f; + bool m_no_sparse_layers = false; bool m_set_extruder_trimpot = false; bool m_adhesion = true; GCodeFlavor m_gcode_flavor; diff --git a/src/libslic3r/KDTreeIndirect.hpp b/src/libslic3r/KDTreeIndirect.hpp index 3cccfdafac..239008559c 100644 --- a/src/libslic3r/KDTreeIndirect.hpp +++ b/src/libslic3r/KDTreeIndirect.hpp @@ -46,9 +46,9 @@ public: if (indices.empty()) clear(); else { - // Allocate a next highest power of 2 nodes, because the incomplete binary tree will not have the leaves filled strictly from the left. + // Allocate enough memory for a full binary tree. m_nodes.assign(next_highest_power_of_2(indices.size() + 1), npos); - build_recursive(indices, 0, 0, 0, (int)(indices.size() - 1)); + build_recursive(indices, 0, 0, 0, indices.size() - 1); } indices.clear(); } @@ -81,7 +81,7 @@ public: private: // Build a balanced tree by splitting the input sequence by an axis aligned plane at a dimension. - void build_recursive(std::vector &input, size_t node, int dimension, int left, int right) + void build_recursive(std::vector &input, size_t node, const size_t dimension, const size_t left, const size_t right) { if (left > right) return; @@ -94,54 +94,56 @@ private: return; } - // Partition the input sequence to two equal halves. - int center = (left + right) >> 1; + // Partition the input to left / right pieces of the same length to produce a balanced tree. + size_t center = (left + right) / 2; partition_input(input, dimension, left, right, center); // Insert a node into the tree. m_nodes[node] = input[center]; - // Partition the left and right subtrees. - size_t next_dimension = (++ dimension == NumDimensions) ? 0 : dimension; - build_recursive(input, (node << 1) + 1, next_dimension, left, center - 1); - build_recursive(input, (node << 1) + 2, next_dimension, center + 1, right); + // Build up the left / right subtrees. + size_t next_dimension = dimension; + if (++ next_dimension == NumDimensions) + next_dimension = 0; + if (center > left) + build_recursive(input, node * 2 + 1, next_dimension, left, center - 1); + build_recursive(input, node * 2 + 2, next_dimension, center + 1, right); } - // Partition the input m_nodes at k using QuickSelect method. + // Partition the input m_nodes at "k" and "dimension" using the QuickSelect method: // https://en.wikipedia.org/wiki/Quickselect - void partition_input(std::vector &input, int dimension, int left, int right, int k) const + // Items left of the k'th item are lower than the k'th item in the "dimension", + // items right of the k'th item are higher than the k'th item in the "dimension", + void partition_input(std::vector &input, const size_t dimension, size_t left, size_t right, const size_t k) const { while (left < right) { - // Guess the k'th element. - // Pick the pivot as a median of first, center and last value. - // Sort first, center and last values. - int center = (left + right) >> 1; - auto left_value = this->coordinate(input[left], dimension); - auto center_value = this->coordinate(input[center], dimension); - auto right_value = this->coordinate(input[right], dimension); - if (center_value < left_value) { - std::swap(input[left], input[center]); - std::swap(left_value, center_value); + size_t center = (left + right) / 2; + CoordType pivot; + { + // Bubble sort the input[left], input[center], input[right], so that a median of the three values + // will end up in input[center]. + CoordType left_value = this->coordinate(input[left], dimension); + CoordType center_value = this->coordinate(input[center], dimension); + CoordType right_value = this->coordinate(input[right], dimension); + if (left_value > center_value) { + std::swap(input[left], input[center]); + std::swap(left_value, center_value); + } + if (left_value > right_value) { + std::swap(input[left], input[right]); + right_value = left_value; + } + if (center_value > right_value) { + std::swap(input[center], input[right]); + center_value = right_value; + } + pivot = center_value; } - if (right_value < left_value) { - std::swap(input[left], input[right]); - std::swap(left_value, right_value); - } - if (right_value < center_value) { - std::swap(input[center], input[right]); - // No need to do that, result is not used. - // std::swap(center_value, right_value); - } - // Only two or three values are left and those are sorted already. - if (left + 3 > right) + if (right <= left + 2) + // The interval is already sorted. break; - // left and right items are already at their correct positions. - // input[left].point[dimension] <= input[center].point[dimension] <= input[right].point[dimension] - // Move the pivot to the (right - 1) position. - std::swap(input[center], input[right - 1]); - // Pivot value. - double pivot = this->coordinate(input[right - 1], dimension); + size_t i = left; + size_t j = right - 1; + std::swap(input[center], input[j]); // Partition the set based on the pivot. - int i = left; - int j = right - 1; for (;;) { // Skip left points that are already at correct positions. // Search will certainly stop at position (right - 1), which stores the pivot. @@ -153,7 +155,7 @@ private: std::swap(input[i], input[j]); } // Restore pivot to the center of the sequence. - std::swap(input[i], input[right]); + std::swap(input[i], input[right - 1]); // Which side the kth element is in? if (k < i) right = i - 1; @@ -173,7 +175,7 @@ private: return; // Left / right child node index. - size_t left = (node << 1) + 1; + size_t left = node * 2 + 1; size_t right = left + 1; unsigned int mask = visitor(m_nodes[node], dimension); if ((mask & (unsigned int)VisitorReturnMask::STOP) == 0) { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index e044bdf5c2..78a09c5113 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -201,6 +201,7 @@ bool Print::invalidate_state_by_config_options(const std::vectormode = comAdvanced; def->set_default_value(new ConfigOptionString("")); + def = this->add("thumbnails", coPoints); + def->label = L("Picture sizes to be stored into a .gcode and .sl1 files"); + def->mode = comExpert; + def->set_default_value(new ConfigOptionPoints()); + def = this->add("layer_height", coFloat); def->label = L("Layer height"); def->category = L("Layers and Perimeters"); @@ -1837,6 +1842,14 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); + def = this->add("wipe_tower_no_sparse_layers", coBool); + def->label = L("No sparse layers (EXPERIMENTAL)"); + def->tooltip = L("If enabled, the wipe tower will not be printed on layers with no toolchanges. " + "On layers with a toolchange, extruder will travel downward to print the wipe tower. " + "User is responsible for ensuring there is no collision with the print."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("support_material", coBool); def->label = L("Generate support material"); def->category = L("Support material"); @@ -2440,6 +2453,34 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->set_default_value(new ConfigOptionFloat(0.3)); + def = this->add("bottle_volume", coFloat); + def->label = L("Bottle volume"); + def->tooltip = L("Bottle volume"); + def->sidetext = L("ml"); + def->min = 50; + def->set_default_value(new ConfigOptionFloat(1000.0)); + + def = this->add("bottle_weight", coFloat); + def->label = L("Bottle weight"); + def->tooltip = L("Bottle weight"); + def->sidetext = L("kg"); + def->min = 0; + def->set_default_value(new ConfigOptionFloat(1.0)); + + def = this->add("material_density", coFloat); + def->label = L("Density"); + def->tooltip = L("Density"); + def->sidetext = L("g/ml"); + def->min = 0; + def->set_default_value(new ConfigOptionFloat(1.0)); + + def = this->add("bottle_cost", coFloat); + def->label = L("Cost"); + def->tooltip = L("Cost"); + def->sidetext = L("money/bottle"); + def->min = 0; + def->set_default_value(new ConfigOptionFloat(0.0)); + def = this->add("faded_layers", coInt); def->label = L("Faded layers"); def->tooltip = L("Number of the layers needed for the exposure time fade from initial exposure time to the exposure time"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 4b007fc51c..5f5a861da3 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -669,6 +669,7 @@ public: ConfigOptionStrings start_filament_gcode; ConfigOptionBool single_extruder_multi_material; ConfigOptionBool single_extruder_multi_material_priming; + ConfigOptionBool wipe_tower_no_sparse_layers; ConfigOptionString toolchange_gcode; ConfigOptionFloat travel_speed; ConfigOptionBool use_firmware_retraction; @@ -739,6 +740,7 @@ protected: OPT_PTR(retract_speed); OPT_PTR(single_extruder_multi_material); OPT_PTR(single_extruder_multi_material_priming); + OPT_PTR(wipe_tower_no_sparse_layers); OPT_PTR(start_gcode); OPT_PTR(start_filament_gcode); OPT_PTR(toolchange_gcode); @@ -1126,6 +1128,10 @@ class SLAMaterialConfig : public StaticPrintConfig STATIC_PRINT_CONFIG_CACHE(SLAMaterialConfig) public: ConfigOptionFloat initial_layer_height; + ConfigOptionFloat bottle_cost; + ConfigOptionFloat bottle_volume; + ConfigOptionFloat bottle_weight; + ConfigOptionFloat material_density; ConfigOptionFloat exposure_time; ConfigOptionFloat initial_exposure_time; ConfigOptionFloats material_correction; @@ -1133,6 +1139,10 @@ protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { OPT_PTR(initial_layer_height); + OPT_PTR(bottle_cost); + OPT_PTR(bottle_volume); + OPT_PTR(bottle_weight); + OPT_PTR(material_density); OPT_PTR(exposure_time); OPT_PTR(initial_exposure_time); OPT_PTR(material_correction); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 2c080ec3d4..d9f8b7b6db 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1607,7 +1607,11 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector steps; diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index a0fb050057..b38655e68a 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -237,11 +237,19 @@ std::vector> chain_segments_greedy_constrained_reversals // Chain the end points: find (num_segments - 1) shortest links not forming bifurcations or loops. assert(num_segments >= 2); +#ifndef NDEBUG + double distance_taken_last = 0.; +#endif /* NDEBUG */ for (int iter = int(num_segments) - 2;; -- iter) { assert(validate_graph_and_queue()); // Take the first end point, for which the link points to the currently closest valid neighbor. EndPoint &end_point1 = *queue.top(); - assert(end_point1.edge_out != nullptr); +#ifndef NDEBUG + // Each edge added shall be longer than the previous one taken. + assert(end_point1.distance_out > distance_taken_last - SCALED_EPSILON); + distance_taken_last = end_point1.distance_out; +#endif /* NDEBUG */ + assert(end_point1.edge_out != nullptr); // No point on the queue may be connected yet. assert(end_point1.chain_id == 0); // Take the closest end point to the first end point, @@ -313,6 +321,10 @@ std::vector> chain_segments_greedy_constrained_reversals assert(next_idx < end_points.size()); end_point1.edge_out = &end_points[next_idx]; end_point1.distance_out = (end_points[next_idx].pos - end_point1.pos).squaredNorm(); +#ifndef NDEBUG + // Each edge shall be longer than the last one removed from the queue. + assert(end_point1.distance_out > distance_taken_last - SCALED_EPSILON); +#endif /* NDEBUG */ // Update position of this end point in the queue based on the distance calculated at the line above. queue.update(end_point1.heap_idx); //FIXME Remove the other end point from the KD tree. @@ -460,18 +472,206 @@ std::vector chain_points(const Points &points, Point *start_near) return out; } +// Flip the sequences of polylines to lower the total length of connecting lines. +// #define DEBUG_SVG_OUTPUT +static inline void improve_ordering_by_segment_flipping(Polylines &polylines, bool fixed_start) +{ +#ifndef NDEBUG + auto cost = [&polylines]() { + double sum = 0.; + for (size_t i = 1; i < polylines.size(); ++i) + sum += (polylines[i].first_point() - polylines[i - 1].last_point()).cast().norm(); + return sum; + }; + double cost_initial = cost(); + + static int iRun = 0; + ++ iRun; + BoundingBox bbox = get_extents(polylines); +#ifdef DEBUG_SVG_OUTPUT + { + SVG svg(debug_out_path("improve_ordering_by_segment_flipping-initial-%d.svg", iRun).c_str(), bbox); + svg.draw(polylines); + for (size_t i = 1; i < polylines.size(); ++ i) + svg.draw(Line(polylines[i - 1].last_point(), polylines[i].first_point()), "red"); + } +#endif /* DEBUG_SVG_OUTPUT */ +#endif /* NDEBUG */ + + struct Connection { + Connection(size_t heap_idx = std::numeric_limits::max(), bool flipped = false) : heap_idx(heap_idx), flipped(flipped) {} + // Position of this object on MutablePriorityHeap. + size_t heap_idx; + // Is segment_idx flipped? + bool flipped; + + double squaredNorm(const Polylines &polylines, const std::vector &connections) const + { return ((this + 1)->start_point(polylines, connections) - this->end_point(polylines, connections)).squaredNorm(); } + double norm(const Polylines &polylines, const std::vector &connections) const + { return sqrt(this->squaredNorm(polylines, connections)); } + double squaredNorm(const Polylines &polylines, const std::vector &connections, bool try_flip1, bool try_flip2) const + { return ((this + 1)->start_point(polylines, connections, try_flip2) - this->end_point(polylines, connections, try_flip1)).squaredNorm(); } + double norm(const Polylines &polylines, const std::vector &connections, bool try_flip1, bool try_flip2) const + { return sqrt(this->squaredNorm(polylines, connections, try_flip1, try_flip2)); } + Vec2d start_point(const Polylines &polylines, const std::vector &connections, bool flip = false) const + { const Polyline &pl = polylines[this - connections.data()]; return ((this->flipped == flip) ? pl.points.front() : pl.points.back()).cast(); } + Vec2d end_point(const Polylines &polylines, const std::vector &connections, bool flip = false) const + { const Polyline &pl = polylines[this - connections.data()]; return ((this->flipped == flip) ? pl.points.back() : pl.points.front()).cast(); } + + bool in_queue() const { return this->heap_idx != std::numeric_limits::max(); } + void flip() { this->flipped = ! this->flipped; } + }; + std::vector connections(polylines.size()); + +#ifndef NDEBUG + auto cost_flipped = [fixed_start, &polylines, &connections]() { + assert(! fixed_start || ! connections.front().flipped); + double sum = 0.; + for (size_t i = 1; i < polylines.size(); ++ i) + sum += connections[i - 1].norm(polylines, connections); + return sum; + }; + double cost_prev = cost_flipped(); + assert(std::abs(cost_initial - cost_prev) < SCALED_EPSILON); + + auto print_statistics = [&polylines, &connections]() { +#if 0 + for (size_t i = 1; i < polylines.size(); ++ i) + printf("Connecting %d with %d: Current length %lf flip(%d, %d), left flipped: %lf, right flipped: %lf, both flipped: %lf, \n", + int(i - 1), int(i), + unscale(connections[i - 1].norm(polylines, connections)), + int(connections[i - 1].flipped), int(connections[i].flipped), + unscale(connections[i - 1].norm(polylines, connections, true, false)), + unscale(connections[i - 1].norm(polylines, connections, false, true)), + unscale(connections[i - 1].norm(polylines, connections, true, true))); +#endif + }; + print_statistics(); +#endif /* NDEBUG */ + + // Initialize a MutablePriorityHeap of connections between polylines. + auto queue = make_mutable_priority_queue( + [](Connection *connection, size_t idx){ connection->heap_idx = idx; }, + // Sort by decreasing connection distance. + [&polylines, &connections](Connection *l, Connection *r){ return l->squaredNorm(polylines, connections) > r->squaredNorm(polylines, connections); }); + queue.reserve(polylines.size() - 1); + for (size_t i = 0; i + 1 < polylines.size(); ++ i) + queue.push(&connections[i]); + + static constexpr size_t itercnt = 100; + size_t iter = 0; + for (; ! queue.empty() && iter < itercnt; ++ iter) { + Connection &connection = *queue.top(); + queue.pop(); + connection.heap_idx = std::numeric_limits::max(); + size_t idx_first = &connection - connections.data(); + // Try to flip segments starting with idx_first + 1 to the end. + // Calculate the last segment to be flipped to improve the total path length. + double length_current = connection.norm(polylines, connections); + double length_flipped = connection.norm(polylines, connections, false, true); + int best_idx_forward = int(idx_first); + double best_improvement_forward = 0.; + for (size_t i = idx_first + 1; i + 1 < connections.size(); ++ i) { + length_current += connections[i].norm(polylines, connections); + double this_improvement = length_current - length_flipped - connections[i].norm(polylines, connections, true, false); + length_flipped += connections[i].norm(polylines, connections, true, true); + if (this_improvement > best_improvement_forward) { + best_improvement_forward = this_improvement; + best_idx_forward = int(i); + } +// if (length_flipped > 1.5 * length_current) +// break; + } + if (length_current - length_flipped > best_improvement_forward) + // Best improvement by flipping up to the end. + best_idx_forward = int(connections.size()) - 1; + // Try to flip segments starting with idx_first - 1 to the start. + // Calculate the last segment to be flipped to improve the total path length. + length_current = connection.norm(polylines, connections); + length_flipped = connection.norm(polylines, connections, true, false); + int best_idx_backwards = int(idx_first); + double best_improvement_backwards = 0.; + for (int i = int(idx_first) - 1; i >= 0; -- i) { + length_current += connections[i].norm(polylines, connections); + double this_improvement = length_current - length_flipped - connections[i].norm(polylines, connections, false, true); + length_flipped += connections[i].norm(polylines, connections, true, true); + if (this_improvement > best_improvement_backwards) { + best_improvement_backwards = this_improvement; + best_idx_backwards = int(i); + } +// if (length_flipped > 1.5 * length_current) +// break; + } + if (! fixed_start && length_current - length_flipped > best_improvement_backwards) + // Best improvement by flipping up to the start including the first polyline. + best_idx_backwards = -1; + int update_begin = int(idx_first); + int update_end = best_idx_forward; + if (best_improvement_backwards > 0. && best_improvement_backwards > best_improvement_forward) { + // Flip the sequence of polylines from idx_first to best_improvement_forward + 1. + update_begin = best_idx_backwards; + update_end = int(idx_first); + } + assert(update_begin <= update_end); + if (update_begin == update_end) + continue; + for (int i = update_begin + 1; i <= update_end; ++ i) + connections[i].flip(); + +#ifndef NDEBUG + double cost = cost_flipped(); + assert(cost < cost_prev); + cost_prev = cost; + print_statistics(); +#endif /* NDEBUG */ + + update_end = std::min(update_end + 1, int(connections.size()) - 1); + for (int i = std::max(0, update_begin); i < update_end; ++ i) { + Connection &c = connections[i]; + if (c.in_queue()) + queue.update(c.heap_idx); + else + queue.push(&c); + } + } + + // Flip the segments based on the flip flag. + for (Polyline &pl : polylines) + if (connections[&pl - polylines.data()].flipped) + pl.reverse(); + +#ifndef NDEBUG + double cost_final = cost(); +#ifdef DEBUG_SVG_OUTPUT + { + SVG svg(debug_out_path("improve_ordering_by_segment_flipping-final-%d.svg", iRun).c_str(), bbox); + svg.draw(polylines); + for (size_t i = 1; i < polylines.size(); ++ i) + svg.draw(Line(polylines[i - 1].last_point(), polylines[i].first_point()), "red"); + } +#endif /* DEBUG_SVG_OUTPUT */ +#endif /* NDEBUG */ + + assert(cost_final <= cost_prev); + assert(cost_final <= cost_initial); +} + Polylines chain_polylines(Polylines &&polylines, const Point *start_near) { - auto segment_end_point = [&polylines](size_t idx, bool first_point) -> const Point& { return first_point ? polylines[idx].first_point() : polylines[idx].last_point(); }; - std::vector> ordered = chain_segments_greedy(segment_end_point, polylines.size(), start_near); Polylines out; - out.reserve(polylines.size()); - for (auto &segment_and_reversal : ordered) { - out.emplace_back(std::move(polylines[segment_and_reversal.first])); - if (segment_and_reversal.second) - out.back().reverse(); + if (! polylines.empty()) { + auto segment_end_point = [&polylines](size_t idx, bool first_point) -> const Point& { return first_point ? polylines[idx].first_point() : polylines[idx].last_point(); }; + std::vector> ordered = chain_segments_greedy(segment_end_point, polylines.size(), start_near); + out.reserve(polylines.size()); + for (auto &segment_and_reversal : ordered) { + out.emplace_back(std::move(polylines[segment_and_reversal.first])); + if (segment_and_reversal.second) + out.back().reverse(); + } + if (out.size() > 1) + improve_ordering_by_segment_flipping(out, start_near != nullptr); } - return out; + return out; } template static inline T chain_path_items(const Points &points, const T &items) diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 9af2adcc62..e5fae485a7 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -165,6 +165,65 @@ template size_t next_highest_power_of_2(T v, return next_highest_power_of_2(uint32_t(v)); } +template +inline INDEX_TYPE prev_idx_modulo(INDEX_TYPE idx, const INDEX_TYPE count) +{ + if (idx == 0) + idx = count; + return -- idx; +} + +template +inline INDEX_TYPE next_idx_modulo(INDEX_TYPE idx, const INDEX_TYPE count) +{ + if (++ idx == count) + idx = 0; + return idx; +} + +template +inline typename CONTAINER_TYPE::size_type prev_idx_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return prev_idx_modulo(idx, container.size()); +} + +template +inline typename CONTAINER_TYPE::size_type next_idx_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return next_idx_modulo(idx, container.size()); +} + +template +inline const typename CONTAINER_TYPE::value_type& prev_value_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return container[prev_idx_modulo(idx, container.size())]; +} + +template +inline typename CONTAINER_TYPE::value_type& prev_value_modulo(typename CONTAINER_TYPE::size_type idx, CONTAINER_TYPE &container) +{ + return container[prev_idx_modulo(idx, container.size())]; +} + +template +inline const typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) +{ + return container[next_idx_modulo(idx, container.size())]; +} + +template +inline typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER_TYPE::size_type idx, CONTAINER_TYPE &container) +{ + return container[next_idx_modulo(idx, container.size())]; +} + +template +inline T exchange(T& obj, U&& new_value) +{ + T old_value = std::move(obj); + obj = std::forward(new_value); + return old_value; +} extern std::string xml_escape(std::string text); diff --git a/src/platform/osx/Info.plist.in b/src/platform/osx/Info.plist.in index f4e298180b..d09f015b9c 100644 --- a/src/platform/osx/Info.plist.in +++ b/src/platform/osx/Info.plist.in @@ -116,5 +116,7 @@ NSApplication NSHighResolutionCapable + NSRequiresAquaSystemAppearance + diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index f77cd9ccc5..6dcbc60b71 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -158,6 +158,7 @@ set(SLIC3R_GUI_SOURCES Utils/UndoRedo.hpp Utils/HexFile.cpp Utils/HexFile.hpp + Utils/Thread.hpp ) if (APPLE) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 4185b66646..d0bab50c6c 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -204,6 +204,7 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c std::string cst_texture(custom_texture); if (!cst_texture.empty()) { + std::replace(cst_texture.begin(), cst_texture.end(), '\\', '/'); if ((!boost::algorithm::iends_with(custom_texture, ".png") && !boost::algorithm::iends_with(custom_texture, ".svg")) || !boost::filesystem::exists(custom_texture)) cst_texture = ""; } @@ -212,6 +213,7 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c std::string cst_model(custom_model); if (!cst_model.empty()) { + std::replace(cst_model.begin(), cst_model.end(), '\\', '/'); if (!boost::algorithm::iends_with(custom_model, ".stl") || !boost::filesystem::exists(custom_model)) cst_model = ""; } @@ -270,27 +272,13 @@ void Bed3D::render(GLCanvas3D& canvas, float theta, float scale_factor) const switch (m_type) { - case MK2: - { - render_prusa(canvas, "mk2", theta > 90.0f); - break; - } - case MK3: - { - render_prusa(canvas, "mk3", theta > 90.0f); - break; - } - case SL1: - { - render_prusa(canvas, "sl1", theta > 90.0f); - break; - } + case MK2: { render_prusa(canvas, "mk2", theta > 90.0f); break; } + case MK3: { render_prusa(canvas, "mk3", theta > 90.0f); break; } + case SL1: { render_prusa(canvas, "sl1", theta > 90.0f); break; } + case MINI: { render_prusa(canvas, "mini", theta > 90.0f); break; } + case ENDER3: { render_prusa(canvas, "ender3", theta > 90.0f); break; } default: - case Custom: - { - render_custom(canvas, theta > 90.0f); - break; - } + case Custom: { render_custom(canvas, theta > 90.0f); break; } } } @@ -362,22 +350,38 @@ Bed3D::EType Bed3D::detect_type(const Pointfs& shape) const { if (curr->config.has("bed_shape")) { - if ((curr->vendor != nullptr) && (curr->vendor->name == "Prusa Research") && (shape == dynamic_cast(curr->config.option("bed_shape"))->values)) + if (curr->vendor != nullptr) { - if (boost::contains(curr->name, "SL1")) + if ((curr->vendor->name == "Prusa Research") && (shape == dynamic_cast(curr->config.option("bed_shape"))->values)) { - type = SL1; - break; + if (boost::contains(curr->name, "SL1")) + { + type = SL1; + break; + } + else if (boost::contains(curr->name, "MK3") || boost::contains(curr->name, "MK2.5")) + { + type = MK3; + break; + } + else if (boost::contains(curr->name, "MK2")) + { + type = MK2; + break; + } + else if (boost::contains(curr->name, "MINI")) + { + type = MINI; + break; + } } - else if (boost::contains(curr->name, "MK3") || boost::contains(curr->name, "MK2.5")) + else if ((curr->vendor->name == "Creality") && (shape == dynamic_cast(curr->config.option("bed_shape"))->values)) { - type = MK3; - break; - } - else if (boost::contains(curr->name, "MK2")) - { - type = MK2; - break; + if (boost::contains(curr->name, "ENDER-3")) + { + type = ENDER3; + break; + } } } } diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index c9a30e6ec2..132836711e 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -67,6 +67,8 @@ public: MK2, MK3, SL1, + MINI, + ENDER3, Custom, Num_Types }; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 086ba7a74a..bbfcabd36f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -707,24 +707,24 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M print_volume.min(2) = -1e10; ModelInstance::EPrintVolumeState state = ModelInstance::PVS_Inside; - bool all_contained = true; bool contained_min_one = false; for (GLVolume* volume : this->volumes) { - if ((volume == nullptr) || !volume->printable || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || ((volume->composite_id.volume_id < 0) && !volume->shader_outside_printer_detection_enabled)) + if ((volume == nullptr) || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || ((volume->composite_id.volume_id < 0) && !volume->shader_outside_printer_detection_enabled)) continue; const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box(); bool contained = print_volume.contains(bb); - all_contained &= contained; + + volume->is_outside = !contained; + if (!volume->printable) + continue; if (contained) contained_min_one = true; - volume->is_outside = !contained; - if ((state == ModelInstance::PVS_Inside) && volume->is_outside) state = ModelInstance::PVS_Fully_Outside; @@ -735,7 +735,7 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M if (out_state != nullptr) *out_state = state; - return /*all_contained*/ contained_min_one; // #ys_FIXME_delete_after_testing + return contained_min_one; } void GLVolumeCollection::reset_outside_state() diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 3f0d87c355..5ab65f340b 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -261,11 +261,7 @@ bool BackgroundSlicingProcess::start() if (m_state == STATE_INITIAL) { // The worker thread is not running yet. Start it. assert(! m_thread.joinable()); - boost::thread::attributes attrs; - // Duplicating the stack allocation size of Thread Building Block worker threads of the thread pool: - // allocate 4MB on a 64bit system, allocate 2MB on a 32bit system by default. - attrs.set_stack_size((sizeof(void*) == 4) ? (2048 * 1024) : (4096 * 1024)); - m_thread = boost::thread(attrs, [this]{this->thread_proc_safe();}); + m_thread = create_thread([this]{this->thread_proc_safe();}); // Wait until the worker thread is ready to execute the background processing task. m_condition.wait(lck, [this](){ return m_state == STATE_IDLE; }); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index bf8cbc2359..a603d52acc 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -6,12 +6,12 @@ #include #include -#include #include #include "libslic3r/Print.hpp" #include "slic3r/Utils/PrintHost.hpp" +#include "slic3r/Utils/Thread.hpp" namespace Slic3r { diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 5624ada9d2..96a0a59cd5 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -12,6 +12,7 @@ #include "boost/nowide/iostream.hpp" #include +#include #include @@ -60,7 +61,9 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf { m_shape = default_pt.values; m_custom_texture = custom_texture.value.empty() ? NONE : custom_texture.value; + std::replace(m_custom_texture.begin(), m_custom_texture.end(), '\\', '/'); m_custom_model = custom_model.value.empty() ? NONE : custom_model.value; + std::replace(m_custom_model.begin(), m_custom_model.end(), '\\', '/'); auto sbsizer = new wxStaticBoxSizer(wxVERTICAL, this, _(L("Shape"))); sbsizer->GetStaticBox()->SetFont(wxGetApp().bold_font()); @@ -212,7 +215,18 @@ wxPanel* BedShapePanel::init_texture_panel() wxStaticText* lbl = dynamic_cast(e.GetEventObject()); if (lbl != nullptr) { - wxString tooltip_text = (m_custom_texture == NONE) ? "" : _(m_custom_texture); + bool exists = (m_custom_texture == NONE) || boost::filesystem::exists(m_custom_texture); + lbl->SetForegroundColour(exists ? wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) : wxColor(*wxRED)); + + wxString tooltip_text = ""; + if (m_custom_texture != NONE) + { + if (!exists) + tooltip_text += _(L("Not found: ")); + + tooltip_text += _(m_custom_texture); + } + wxToolTip* tooltip = lbl->GetToolTip(); if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text)) lbl->SetToolTip(tooltip_text); @@ -280,7 +294,18 @@ wxPanel* BedShapePanel::init_model_panel() wxStaticText* lbl = dynamic_cast(e.GetEventObject()); if (lbl != nullptr) { - wxString tooltip_text = (m_custom_model == NONE) ? "" : _(m_custom_model); + bool exists = (m_custom_model == NONE) || boost::filesystem::exists(m_custom_model); + lbl->SetForegroundColour(exists ? wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) : wxColor(*wxRED)); + + wxString tooltip_text = ""; + if (m_custom_model != NONE) + { + if (!exists) + tooltip_text += _(L("Not found: ")); + + tooltip_text += _(m_custom_model); + } + wxToolTip* tooltip = lbl->GetToolTip(); if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text)) lbl->SetToolTip(tooltip_text); @@ -521,6 +546,8 @@ void BedShapePanel::load_texture() return; } + std::replace(file_name.begin(), file_name.end(), '\\', '/'); + wxBusyCursor wait; m_custom_texture = file_name; @@ -544,6 +571,8 @@ void BedShapePanel::load_model() return; } + std::replace(file_name.begin(), file_name.end(), '\\', '/'); + wxBusyCursor wait; m_custom_model = file_name; diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index bc73e32625..393d973b7e 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -166,6 +166,8 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt int max_row_width = 0; int current_row_width = 0; + bool is_variants = false; + for (const auto &model : models) { if (! filter(model)) { continue; } @@ -220,6 +222,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt auto *alt_label = new wxStaticText(variants_panel, wxID_ANY, _(L("Alternate nozzles:"))); alt_label->SetFont(font_alt_nozzle); variants_sizer->Add(alt_label, 0, wxBOTTOM, 3); + is_variants = true; } auto *cbox = new Checkbox(variants_panel, label, model_id, variant.name); @@ -280,10 +283,10 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt } title_sizer->AddStretchSpacer(); - if (titles.size() > 1) { + if (/*titles.size() > 1*/is_variants) { // It only makes sense to add the All / None buttons if there's multiple printers - auto *sel_all_std = new wxButton(this, wxID_ANY, _(L("All standard"))); + auto *sel_all_std = new wxButton(this, wxID_ANY, titles.size() > 1 ? _(L("All standard")) : _(L("Standard"))); auto *sel_all = new wxButton(this, wxID_ANY, _(L("All"))); auto *sel_none = new wxButton(this, wxID_ANY, _(L("None"))); sel_all_std->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true, false); }); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 42e3448fc1..a8953f166e 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -11,6 +11,12 @@ #include #include +#ifdef __WXOSX__ +#define wxOSX true +#else +#define wxOSX false +#endif + namespace Slic3r { namespace GUI { wxString double_to_string(double const value, const int max_precision /*= 4*/) @@ -304,7 +310,7 @@ void TextCtrl::BUILD() { auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - if (! m_opt.multiline) + if (! m_opt.multiline && !wxOSX) // Only disable background refresh for single line input fields, as they are completely painted over by the edit control. // This does not apply to the multi-line edit field, where the last line and a narrow frame around the text is not cleared. temp->SetBackgroundStyle(wxBG_STYLE_PAINT); @@ -491,7 +497,7 @@ void CheckBox::BUILD() { // Set Label as a string of at least one space simbol to correct system scaling of a CheckBox auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetValue(check_value); if (m_opt.readonly) temp->Disable(); @@ -601,7 +607,7 @@ void SpinCtrl::BUILD() { auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, 0|wxTE_PROCESS_ENTER, min_val, max_val, default_value); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // XXX: On OS X the wxSpinCtrl widget is made up of two subwidgets, unfortunatelly // the kill focus event is not propagated to the encompassing widget, @@ -717,7 +723,7 @@ void Choice::BUILD() { } temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); @@ -1072,7 +1078,7 @@ void ColourPicker::BUILD() auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 76990fb89c..6c940ac708 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2094,20 +2094,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, contained_min_one && !m_model->objects.empty() && state != ModelInstance::PVS_Partly_Outside)); - -// #ys_FIXME_delete_after_testing -// bool contained = m_volumes.check_outside_state(m_config, &state); -// if (!contained) -// { -// _set_warning_texture(WarningTexture::ObjectOutside, true); -// post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, state == ModelInstance::PVS_Fully_Outside)); -// } -// else -// { -// m_volumes.reset_outside_state(); -// _set_warning_texture(WarningTexture::ObjectOutside, false); -// post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, !m_model->objects.empty())); -// } } else { @@ -2917,6 +2903,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) volume_bbox.offset(1.0); if (volume_bbox.contains(m_mouse.scene_position)) { + m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None; // The dragging operation is initiated. m_mouse.drag.move_volume_idx = volume_idx; m_selection.start_dragging(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 0b24e22157..7d37baa665 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -105,7 +105,7 @@ static void register_dpi_event() const auto rect = reinterpret_cast(lParam); const wxRect wxrect(wxPoint(rect->top, rect->left), wxPoint(rect->bottom, rect->right)); - DpiChangedEvent evt(EVT_DPI_CHANGED, dpi, wxrect); + DpiChangedEvent evt(EVT_DPI_CHANGED_SLICER, dpi, wxrect); win->GetEventHandler()->AddPendingEvent(evt); return true; @@ -1131,8 +1131,11 @@ void GUI_App::gcode_thumbnails_debug() boost::nowide::ofstream out_file(out_filename.c_str(), std::ios::binary); if (out_file.good()) { - std::string decoded = boost::beast::detail::base64_decode(row); - out_file.write(decoded.c_str(), decoded.length()); + std::string decoded; + decoded.resize(boost::beast::detail::base64::decoded_size(row.size())); + decoded.resize(boost::beast::detail::base64::decode((void*)&decoded[0], row.data(), row.size()).first); + + out_file.write(decoded.c_str(), decoded.size()); out_file.close(); } #else @@ -1147,8 +1150,11 @@ void GUI_App::gcode_thumbnails_debug() std::vector thumbnail(4 * width * height, 0); for (unsigned int r = 0; r < (unsigned int)rows.size(); ++r) { - std::string decoded_row = boost::beast::detail::base64_decode(rows[r]); - if ((unsigned int)decoded_row.length() == width * 4) + std::string decoded_row; + decoded_row.resize(boost::beast::detail::base64::decoded_size(rows[r].size())); + decoded_row.resize(boost::beast::detail::base64::decode((void*)&decoded_row[0], rows[r].data(), rows[r].size()).first); + + if ((unsigned int)decoded_row.size() == width * 4) { void* image_ptr = (void*)(thumbnail.data() + r * width * 4); ::memcpy(image_ptr, (const void*)decoded_row.c_str(), width * 4); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 4ecab8a0f1..937e3dbdc8 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -57,7 +57,7 @@ static wxBitmapComboBox* create_word_local_combo(wxWindow *parent) #endif //__WXOSX__ temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->Append(_(L("World coordinates"))); temp->Append(_(L("Local coordinates"))); diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index d5753f2ccf..5090382cef 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -55,7 +55,7 @@ void on_window_geometry(wxTopLevelWindow *tlw, std::function callback) #endif } -wxDEFINE_EVENT(EVT_DPI_CHANGED, DpiChangedEvent); +wxDEFINE_EVENT(EVT_DPI_CHANGED_SLICER, DpiChangedEvent); #ifdef _WIN32 template typename F::FN winapi_get_function(const wchar_t *dll, const char *fn_name) { diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index c47714e464..f7bebd5778 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -50,7 +50,7 @@ struct DpiChangedEvent : public wxEvent { } }; -wxDECLARE_EVENT(EVT_DPI_CHANGED, DpiChangedEvent); +wxDECLARE_EVENT(EVT_DPI_CHANGED_SLICER, DpiChangedEvent); template class DPIAware : public P { @@ -75,7 +75,7 @@ public: // recalc_font(); - this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) { + this->Bind(EVT_DPI_CHANGED_SLICER, [this](const DpiChangedEvent &evt) { m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT; m_new_font_point_size = get_default_font_for_dpi(evt.dpi).GetPointSize(); diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index cc3d89b1fa..6089e18f50 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -175,7 +175,7 @@ public: staticbox(title!=""), extra_column(extra_clmn) { if (staticbox) { stb = new wxStaticBox(_parent, wxID_ANY, title); - stb->SetBackgroundStyle(wxBG_STYLE_PAINT); + if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT); stb->SetFont(wxGetApp().bold_font()); } else stb = nullptr; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8491a22aa7..94319927da 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -76,6 +76,7 @@ #include "../Utils/PrintHost.hpp" #include "../Utils/FixModelByWin10.hpp" #include "../Utils/UndoRedo.hpp" +#include "../Utils/Thread.hpp" #include // Needs to be last because reasons :-/ #include "WipeTowerDialog.hpp" @@ -87,8 +88,6 @@ using Slic3r::Preset; using Slic3r::PrintHostJob; #if ENABLE_THUMBNAIL_GENERATOR -static const std::vector < std::pair> THUMBNAIL_SIZE_FFF = { { 240, 320 }, { 220, 165 }, { 16, 16 } }; -static const std::vector> THUMBNAIL_SIZE_SLA = { { 800, 480 } }; static const std::pair THUMBNAIL_SIZE_3MF = { 256, 256 }; #endif // ENABLE_THUMBNAIL_GENERATOR @@ -231,7 +230,7 @@ SlicedInfo::SlicedInfo(wxWindow *parent) : init_info_label(_(L("Used Filament (mm³)"))); init_info_label(_(L("Used Filament (g)"))); init_info_label(_(L("Used Material (unit)"))); - init_info_label(_(L("Cost"))); + init_info_label(_(L("Cost (money)"))); init_info_label(_(L("Estimated printing time"))); init_info_label(_(L("Number of tool changes"))); @@ -1129,12 +1128,10 @@ void Sidebar::show_info_sizer() } } -void Sidebar::show_sliced_info_sizer(const bool show) +void Sidebar::update_sliced_info_sizer() { - wxWindowUpdateLocker freeze_guard(this); - - p->sliced_info->Show(show); - if (show) { + if (p->sliced_info->IsShown(size_t(0))) + { if (p->plater->printer_technology() == ptSLA) { const SLAPrintStatistics& ps = p->plater->sla_print().print_statistics(); @@ -1150,7 +1147,18 @@ void Sidebar::show_sliced_info_sizer(const bool show) wxString::Format("%.2f", (ps.objects_used_material + ps.support_used_material) / 1000); p->sliced_info->SetTextAndShow(siMateril_unit, info_text, new_label); - p->sliced_info->SetTextAndShow(siCost, "N/A"/*wxString::Format("%.2f", ps.total_cost)*/); + wxString str_total_cost = "N/A"; + + DynamicPrintConfig* cfg = wxGetApp().get_tab(Preset::TYPE_SLA_MATERIAL)->get_config(); + if (cfg->option("bottle_cost")->getFloat() > 0.0 && + cfg->option("bottle_volume")->getFloat() > 0.0) + { + double material_cost = cfg->option("bottle_cost")->getFloat() / + cfg->option("bottle_volume")->getFloat(); + str_total_cost = wxString::Format("%.2f", material_cost*(ps.objects_used_material + ps.support_used_material) / 1000); + } + p->sliced_info->SetTextAndShow(siCost, str_total_cost); + wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : get_time_dhms(float(ps.estimated_print_time)); p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _(L("Estimated printing time")) + " :"); @@ -1224,6 +1232,15 @@ void Sidebar::show_sliced_info_sizer(const bool show) p->sliced_info->SetTextAndShow(siMateril_unit, "N/A"); } } +} + +void Sidebar::show_sliced_info_sizer(const bool show) +{ + wxWindowUpdateLocker freeze_guard(this); + + p->sliced_info->Show(show); + if (show) + update_sliced_info_sizer(); Layout(); p->scrolled->Refresh(); @@ -1441,7 +1458,7 @@ struct Plater::priv class Job : public wxEvtHandler { int m_range = 100; - std::future m_ftr; + boost::thread m_thread; priv * m_plater = nullptr; std::atomic m_running{false}, m_canceled{false}; bool m_finalized = false; @@ -1482,7 +1499,8 @@ struct Plater::priv // Do a full refresh of scene tree, including regenerating // all the GLVolumes. FIXME The update function shall just // reload the modified matrices. - if (!was_canceled()) plater().update((unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH); + if (!was_canceled()) + plater().update(unsigned(UpdateParams::FORCE_FULL_SCREEN_REFRESH)); } public: @@ -1511,9 +1529,9 @@ struct Plater::priv } Job(const Job &) = delete; - Job(Job &&) = default; + Job(Job &&) = delete; Job &operator=(const Job &) = delete; - Job &operator=(Job &&) = default; + Job &operator=(Job &&) = delete; virtual void process() = 0; @@ -1537,7 +1555,7 @@ struct Plater::priv wxBeginBusyCursor(); try { // Execute the job - m_ftr = std::async(std::launch::async, &Job::run, this); + m_thread = create_thread([this] { this->run(); }); } catch (std::exception &) { update_status(status_range(), _(L("ERROR: not enough resources to " @@ -1553,16 +1571,15 @@ struct Plater::priv // returned if the timeout has been reached and the job is still // running. Call cancel() before this fn if you want to explicitly // end the job. - bool join(int timeout_ms = 0) const + bool join(int timeout_ms = 0) { - if (!m_ftr.valid()) return true; - + if (!m_thread.joinable()) return true; + if (timeout_ms <= 0) - m_ftr.wait(); - else if (m_ftr.wait_for(std::chrono::milliseconds( - timeout_ms)) == std::future_status::timeout) + m_thread.join(); + else if (!m_thread.try_join_for(boost::chrono::milliseconds(timeout_ms))) return false; - + return true; } @@ -3056,14 +3073,16 @@ bool Plater::priv::restart_background_process(unsigned int state) (this->background_process.state() != BackgroundSlicingProcess::STATE_RUNNING)) { // update thumbnail data + const std::vector &thumbnail_sizes = this->background_process.current_print()->full_print_config().option("thumbnails")->values; if (this->printer_technology == ptFFF) { // for ptFFF we need to generate the thumbnails before the export of gcode starts this->thumbnail_data.clear(); - for (const std::pair& size : THUMBNAIL_SIZE_FFF) + for (const Vec2d &sized : thumbnail_sizes) { this->thumbnail_data.push_back(ThumbnailData()); - generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true, false); + Point size(sized); // round to ints + generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false); } } else if (this->printer_technology == ptSLA) @@ -3071,10 +3090,11 @@ bool Plater::priv::restart_background_process(unsigned int state) // for ptSLA generate thumbnails without supports and pad (not yet calculated) // to render also supports and pad see on_slicing_update() this->thumbnail_data.clear(); - for (const std::pair& size : THUMBNAIL_SIZE_SLA) + for (const Vec2d &sized : thumbnail_sizes) { this->thumbnail_data.push_back(ThumbnailData()); - generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true, false); + Point size(sized); // round to ints + generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false); } } } @@ -3426,11 +3446,13 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) // for ptSLA generate the thumbnail after supports and pad have been calculated to have them rendered if ((this->printer_technology == ptSLA) && (evt.status.percent == -3)) { + const std::vector& thumbnail_sizes = this->background_process.current_print()->full_print_config().option("thumbnails")->values; this->thumbnail_data.clear(); - for (const std::pair& size : THUMBNAIL_SIZE_SLA) + for (const Vec2d &sized : thumbnail_sizes) { this->thumbnail_data.push_back(ThumbnailData()); - generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, false, false); + Point size(sized); // round to ints + generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, false, false); } } #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index c327b4d91e..2f7ff30024 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -113,6 +113,7 @@ public: void update_objects_list_extruder_column(size_t extruders_count); void show_info_sizer(); void show_sliced_info_sizer(const bool show); + void update_sliced_info_sizer(); void enable_buttons(bool enable); void set_btn_label(const ActionButtonType btn_type, const wxString& label) const; bool show_reslice(bool show) const; diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index a360aaf1a0..32a03b6b2f 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -403,7 +403,7 @@ const std::vector& Preset::print_options() "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects", "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "single_extruder_multi_material_priming", - "compatible_printers", "compatible_printers_condition", "inherits" + "wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits" }; return s_opts; } @@ -444,7 +444,8 @@ const std::vector& Preset::printer_options() "machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e", "machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e", "machine_min_extruding_rate", "machine_min_travel_rate", - "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e" + "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e", + "thumbnails" }; s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end()); } @@ -513,6 +514,10 @@ const std::vector& Preset::sla_material_options() s_opts = { "material_type", "initial_layer_height", + "bottle_cost", + "bottle_volume", + "bottle_weight", + "material_density", "exposure_time", "initial_exposure_time", "material_correction", diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 92db623f02..01c42d3dec 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -96,6 +96,7 @@ PresetBundle::PresetBundle() : preset.config.optptr("printer_vendor", true); preset.config.optptr("printer_model", true); preset.config.optptr("printer_variant", true); + preset.config.optptr("thumbnails", true); if (i == 0) { preset.config.optptr("default_print_profile", true); preset.config.option("default_filament_profile", true)->values = { "" }; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index c2a258e69b..8f95e00e57 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1170,6 +1170,7 @@ void TabPrint::build() optgroup->append_single_option_line("wipe_tower_width"); optgroup->append_single_option_line("wipe_tower_rotation_angle"); optgroup->append_single_option_line("wipe_tower_bridging"); + optgroup->append_single_option_line("wipe_tower_no_sparse_layers"); optgroup->append_single_option_line("single_extruder_multi_material_priming"); optgroup = page->new_optgroup(_(L("Advanced"))); @@ -3419,8 +3420,41 @@ void TabSLAMaterial::build() auto page = add_options_page(_(L("Material")), "resin"); - auto optgroup = page->new_optgroup(_(L("Layers"))); -// optgroup->append_single_option_line("layer_height"); + auto optgroup = page->new_optgroup(_(L("Material"))); + optgroup->append_single_option_line("bottle_cost"); + optgroup->append_single_option_line("bottle_volume"); + optgroup->append_single_option_line("bottle_weight"); + optgroup->append_single_option_line("material_density"); + + optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) + { + DynamicPrintConfig new_conf = *m_config; + + if (opt_key == "bottle_volume") { + double new_bottle_weight = boost::any_cast(value)/(new_conf.option("material_density")->getFloat() * 1000); + new_conf.set_key_value("bottle_weight", new ConfigOptionFloat(new_bottle_weight)); + } + if (opt_key == "bottle_weight") { + double new_bottle_volume = boost::any_cast(value)*(new_conf.option("material_density")->getFloat() * 1000); + new_conf.set_key_value("bottle_volume", new ConfigOptionFloat(new_bottle_volume)); + } + if (opt_key == "material_density") { + double new_bottle_volume = new_conf.option("bottle_weight")->getFloat() * boost::any_cast(value) * 1000; + new_conf.set_key_value("bottle_volume", new ConfigOptionFloat(new_bottle_volume)); + } + + load_config(new_conf); + + update_dirty(); + on_value_change(opt_key, value); + + if (opt_key == "bottle_volume" || opt_key == "bottle_cost") { + wxGetApp().sidebar().update_sliced_info_sizer(); + wxGetApp().sidebar().Layout(); + } + }; + + optgroup = page->new_optgroup(_(L("Layers"))); optgroup->append_single_option_line("initial_layer_height"); optgroup = page->new_optgroup(_(L("Exposure"))); diff --git a/src/slic3r/Utils/Thread.hpp b/src/slic3r/Utils/Thread.hpp new file mode 100644 index 0000000000..e9c76d2aba --- /dev/null +++ b/src/slic3r/Utils/Thread.hpp @@ -0,0 +1,28 @@ +#ifndef THREAD_HPP +#define THREAD_HPP + +#include +#include + +namespace Slic3r { + +template +inline boost::thread create_thread(boost::thread::attributes &attrs, Fn &&fn) +{ + // Duplicating the stack allocation size of Thread Building Block worker + // threads of the thread pool: allocate 4MB on a 64bit system, allocate 2MB + // on a 32bit system by default. + + attrs.set_stack_size((sizeof(void*) == 4) ? (2048 * 1024) : (4096 * 1024)); + return boost::thread{attrs, std::forward(fn)}; +} + +template inline boost::thread create_thread(Fn &&fn) +{ + boost::thread::attributes attrs; + return create_thread(attrs, std::forward(fn)); +} + +} + +#endif // THREAD_HPP diff --git a/tests/libslic3r/test_elephant_foot_compensation.cpp b/tests/libslic3r/test_elephant_foot_compensation.cpp index 9a7e652648..98ec5df528 100644 --- a/tests/libslic3r/test_elephant_foot_compensation.cpp +++ b/tests/libslic3r/test_elephant_foot_compensation.cpp @@ -220,8 +220,232 @@ static ExPolygon vase_with_fins() return out; } +static ExPolygon contour_with_hole() +{ + ExPolygon out; + out.contour.points = { + { 23302819, 108248}, { 23410179, 157624}, { 23451825, 176777}, { 24106418, 478750}, { 24704172, 811512}, { 24883849, 911534}, { 25980045, 1530217}, { 26591038, 1897423}, { 26829981, 2041022}, { 27158523, 2249848}, { 27618921, 2584465}, + { 27896903, 2786507}, { 28144524, 2978990}, { 28815685, 3551061}, { 28909975, 3628821}, { 29371498, 4009409}, { 29402087, 4037084}, { 29493584, 4119861}, { 29765627, 4382947}, { 30607836, 5197449}, { 30934687, 5508413}, { 31019374, 5593546}, + { 31075807, 5655861}, { 31235879, 5823254}, { 31667505, 6274618}, { 31976596, 6656087}, { 32328364, 7055603}, { 32440973, 7183484}, { 32491346, 7249288}, { 33179667, 8148478}, { 33575401, 8717521}, { 33835875, 9075811}, { 34010014, 9315332}, + { 34304500, 9781688}, { 34369165, 9898535}, { 34397842, 9950359}, { 34494651, 10316439}, { 34501993, 10344190}, { 34385828, 10617514}, { 34331252, 10651174}, { 34084812, 10803186}, { 33894353, 10899665}, { 33398927, 11326583}, + { 33183121, 11494200}, { 32195826, 12261037}, { 31686925, 12719913}, { 31571718, 12807396}, { 31250995, 13050935}, { 31207108, 13086856}, { 31130381, 13149671}, { 31070741, 13206732}, { 30967095, 13305896}, { 30228082, 14071658}, + { 30116771, 14212337}, { 30044101, 14304176}, { 29567520, 14906137}, { 29043350, 15664879}, { 28911161, 15871189}, { 28855871, 15957479}, { 28714334, 16227582}, { 28650159, 16350050}, { 28364584, 16899765}, { 28240857, 17235607}, + { 28151371, 17509658}, { 28114198, 17623503}, { 28309361, 17730441}, { 28370394, 17763884}, { 28488974, 17847025}, { 28525745, 17872806}, { 29082248, 18281292}, { 29152930, 18376480}, { 29168058, 18396855}, { 29173722, 18656366}, + { 29176206, 18770149}, { 29167406, 18857292}, { 29104337, 19029141}, { 29049428, 19178752}, { 28907061, 19434701}, { 28857790, 19523283}, { 28715480, 19775043}, { 28630622, 20043684}, { 28609342, 20111052}, { 28573760, 20267045}, + { 28403454, 21103762}, { 28370165, 21230085}, { 28332310, 21373746}, { 28315057, 21418891}, { 28294569, 21472487}, { 28334157, 21579715}, { 28561468, 21814880}, { 28854906, 22118451}, { 29225599, 22499341}, { 29285205, 22617454}, + { 29324833, 22695983}, { 29313473, 22800767}, { 29312583, 22808982}, { 29272380, 22876835}, { 28829469, 23460472}, { 28817999, 23488286}, { 28796393, 23540675}, { 28775618, 23627381}, { 28732328, 23808034}, { 28661140, 24177335}, + { 28645731, 24834289}, { 28625222, 25202417}, { 28579034, 26031478}, { 28586310, 26420529}, { 28633240, 26560504}, { 28664456, 26653603}, { 28740916, 26788014}, { 28797005, 26886614}, { 28812464, 26950783}, { 28858428, 27009579}, + { 28975940, 26859631}, { 29022419, 26805440}, { 29115451, 26696972}, { 29135739, 26685915}, { 29155135, 26675346}, { 29408332, 26616458}, { 29592642, 26573591}, { 29614928, 26568091}, { 29711634, 26559197}, { 30723503, 26466299}, + { 31183646, 26470661}, { 31550568, 26550771}, { 31777556, 26600329}, { 32014697, 26671604}, { 32334931, 26854665}, { 32449353, 26920987}, { 32657873, 27041843}, { 32701539, 27084927}, { 32750872, 27133602}, { 33434549, 27790306}, + { 33487600, 27817659}, { 33548673, 27849142}, { 33793150, 28109624}, { 33877574, 28164293}, { 33965395, 28221161}, { 33999067, 28249986}, { 34024398, 28271673}, { 34059690, 28329572}, { 34087359, 28374972}, { 34181544, 28710471}, + { 34170186, 28732578}, { 34134947, 28801161}, { 34092867, 29064916}, { 33950784, 29233310}, { 33878646, 29318804}, { 33721956, 29672399}, { 33660358, 29727949}, { 33620108, 29764243}, { 33393624, 30270577}, { 33094597, 30771032}, + { 33063116, 30812704}, { 32973928, 30930779}, { 32608081, 31341847}, { 32393317, 31544017}, { 32206520, 31719862}, { 31997581, 31894374}, { 31972538, 31942583}, { 32059002, 32025240}, { 32171917, 32133182}, { 32501317, 32311025}, + { 32715593, 32426714}, { 32802065, 32479231}, { 32956210, 32574312}, { 33249042, 32770899}, { 33946833, 33239350}, { 34445301, 33680139}, { 34778020, 33974357}, { 35230994, 34391224}, { 35341113, 34460366}, { 35450459, 34529022}, + { 35625170, 34673345}, { 35764733, 34757179}, { 35775747, 34633947}, { 35846476, 34564107}, { 35965365, 34446723}, { 36038088, 34379954}, { 36151170, 34276133}, { 36426218, 34106680}, { 36531666, 34187969}, { 36695885, 34314565}, + { 37011093, 34586835}, { 37067557, 34150814}, { 37052506, 33989541}, { 37037043, 33823855}, { 37069574, 33661923}, { 37083653, 33591851}, { 37186706, 33497192}, { 37521634, 33288703}, { 37617140, 33275082}, { 37684699, 33219614}, + { 37821418, 33228393}, { 37938489, 33235910}, { 38091617, 33138918}, { 38155158, 33060873}, { 38213556, 32989142}, { 38727086, 32659362}, { 38746459, 32654507}, { 38809135, 32638806}, { 38820634, 32624462}, { 38855007, 32581573}, + { 39134002, 32235481}, { 39392850, 32163442}, { 39569189, 32115608}, { 39686862, 32083692}, { 39744314, 32146839}, { 39840707, 31963655}, { 39973169, 31711932}, { 40025735, 31592644}, { 40157184, 31465080}, { 40313010, 31313863}, + { 40390192, 31223588}, { 40418596, 31230809}, { 40594404, 31186692}, { 40732045, 31068306}, { 40746151, 30846139}, { 40761255, 30608300}, { 40853394, 30223426}, { 40876768, 30095588}, { 40895496, 29993166}, { 40968240, 29949606}, + { 41197066, 29989787}, { 41412367, 30027591}, { 41472384, 29977101}, { 41695297, 29659954}, { 41890516, 29382211}, { 42157410, 28987811}, { 42408947, 28616097}, { 42669462, 28292349}, { 42683144, 28275345}, { 42919982, 27924149}, + { 43162781, 27628506}, { 43527344, 27260325}, { 43847191, 27036250}, { 44057061, 26922424}, { 44231096, 26828037}, { 44301999, 26795490}, { 44327421, 26804561}, { 44319287, 26913761}, { 44143507, 27648484}, { 44107324, 27729499}, + { 44074236, 27803580}, { 44025541, 27932083}, { 43944121, 28146941}, { 43877811, 28710269}, { 43895199, 28764671}, { 43933238, 28883702}, { 43919165, 29004140}, { 43888109, 29269841}, { 43825852, 29576752}, { 43811824, 29609468}, + { 43748820, 29756420}, { 43763658, 29837769}, { 43832567, 30215488}, { 44075125, 29807258}, { 44209233, 29804204}, { 44310228, 29813855}, { 44365586, 29958259}, { 43873534, 30271247}, { 44003187, 30330249}, { 44617279, 30687869}, + { 44694113, 31070182}, { 44941015, 31257544}, { 45130334, 31171398}, { 45147836, 31132029}, { 45242053, 31070592}, { 45345637, 31033061}, { 45565937, 30953238}, { 45609517, 30857448}, { 45651888, 30764320}, { 45660681, 30754094}, + { 45822750, 30772646}, { 45944979, 30753042}, { 45964326, 30749938}, { 46054945, 30795588}, { 46577640, 31130668}, { 46870296, 31313313}, { 46976414, 31379541}, { 46998128, 31406087}, { 47008874, 31439291}, { 47031018, 31569281}, + { 47031214, 31576854}, { 47036334, 31774677}, { 47193705, 31889293}, { 47353245, 32029772}, { 47484683, 32145510}, { 47534251, 32233847}, { 47538509, 32241438}, { 47602626, 32453825}, { 47622648, 32465115}, { 47701707, 32575250}, + { 47776955, 33122018}, { 47677092, 33345574}, { 47630772, 33380015}, { 47572757, 33423150}, { 47328653, 33537512}, { 47343826, 33612940}, { 47462219, 33617810}, { 47578431, 33622591}, { 47808035, 33604884}, { 47842258, 33885890}, + { 47847000, 34154765}, { 47852298, 34455418}, { 47806556, 34798342}, { 47804979, 34803470}, { 47795265, 34835122}, { 47811501, 34879922}, { 47843100, 35247684}, { 47839663, 35481904}, { 47833503, 35902474}, { 47803910, 36044010}, + { 47819598, 36077879}, { 47841934, 36100587}, { 47854870, 36165755}, { 47911856, 36452861}, { 47927332, 36616382}, { 47936929, 36717785}, { 47770423, 36987292}, { 47699764, 37101659}, { 47671115, 37157488}, { 47423375, 37424772}, + { 47616349, 37518717}, { 47680621, 37550006}, { 47836151, 37632587}, { 47811936, 37777743}, { 47716954, 38113916}, { 47654340, 38250491}, { 47533407, 38514290}, { 47431515, 38674036}, { 47367427, 38987733}, { 47348164, 39043625}, + { 47298533, 39187606}, { 47279676, 39231940}, { 47252411, 39296047}, { 47246894, 39304927}, { 47238746, 39318037}, { 47232029, 39335258}, { 47220194, 39365593}, { 47196053, 39429922}, { 47159408, 39527585}, { 47041654, 39691835}, + { 47002148, 39908798}, { 46964248, 39997937}, { 46895728, 40159083}, { 46826610, 40301043}, { 46763479, 40430710}, { 46514929, 40884923}, { 46474179, 40918994}, { 46440818, 40946888}, { 46433233, 40992821}, { 46426528, 41033401}, + { 46108271, 41626808}, { 46056215, 41723876}, { 45997871, 41855066}, { 45755987, 42227269}, { 45653183, 42385466}, { 45444848, 42652871}, { 45380966, 42654262}, { 45336326, 42655238}, { 45326382, 42763461}, { 45318953, 42844333}, + { 45175146, 43086382}, { 45086585, 43235443}, { 45055897, 43281060}, { 44968051, 43418247}, { 44470500, 44195272}, { 44413430, 44364401}, { 44390221, 44433179}, { 44309502, 44528273}, { 44199667, 44604532}, { 43887229, 44833256}, + { 43815081, 44886070}, { 43726552, 44932547}, { 43689058, 44928887}, { 43686137, 44927822}, { 43280111, 44871367}, { 43249704, 44937548}, { 43324977, 45004000}, { 43046101, 45224515}, { 42898716, 45341059}, { 42838343, 45382240}, + { 42721108, 45493632}, { 42470119, 45669357}, { 42359756, 45746630}, { 42073412, 45910212}, { 42022050, 45926905}, { 41907133, 46027394}, { 41144940, 46559849}, { 40902566, 46683907}, { 40884989, 46688481}, { 40811763, 46707548}, + { 40768612, 46786655}, { 40675645, 46871372}, { 40548269, 46985681}, { 40382460, 47085920}, { 40082094, 47267510}, { 39768380, 47413990}, { 39734614, 47420931}, { 39586801, 47437916}, { 39408498, 47458403}, { 39355630, 47574767}, + { 39281498, 47737937}, { 39251009, 47783502}, { 39152882, 47890727}, { 39013408, 48043132}, { 38921577, 48100514}, { 38896008, 48108330}, { 38727116, 48102492}, { 38692428, 48101294}, { 38425261, 48075982}, { 38342344, 48047392}, + { 38336010, 48154957}, { 38151978, 48395628}, { 37811687, 48488990}, { 37804084, 48490379}, { 37674998, 48513979}, { 37674196, 48513196}, { 37658712, 48498074}, { 37592273, 48482371}, { 37336907, 48659173}, { 37140701, 48741338}, + { 37129466, 48764064}, { 37075599, 48873013}, { 36739574, 48838715}, { 36721697, 48864552}, { 36456161, 49171298}, { 36442740, 49184060}, { 36436660, 49212679}, { 36300951, 49585030}, { 36223897, 49727927}, { 36150156, 49864671}, + { 35924446, 50245885}, { 35769083, 50508275}, { 35750118, 50514284}, { 35323137, 50653609}, { 34050908, 50703703}, { 33864494, 50706292}, { 33666152, 50709051}, { 33813201, 50839130}, { 33884905, 50893350}, { 33912037, 50913867}, + { 34282238, 51132740}, { 35016181, 51605972}, { 35027459, 51615787}, { 35030754, 51618656}, { 35108803, 51693454}, { 35137469, 51720927}, { 34948522, 51872654}, { 34658613, 52064227}, { 34464997, 52192175}, { 34289189, 52285353}, + { 34219119, 52312637}, { 33847969, 52428212}, { 33681538, 52480036}, { 33407178, 52510887}, { 33421683, 52685666}, { 33428342, 52765908}, { 33392094, 53146294}, { 33371466, 53362761}, { 33253040, 54291767}, { 33196142, 54612534}, + { 33128154, 54815569}, { 33095559, 54912904}, { 32570427, 55111061}, { 32525706, 55125923}, { 32458612, 55148214}, { 32385063, 55163161}, { 32282016, 55184108}, { 32241393, 55188603}, { 32190544, 55194226}, { 32027959, 55217259}, + { 32011561, 56072729}, { 32003567, 57064095}, { 31997637, 57799631}, { 32015577, 60287161}, { 32014290, 61201940}, { 32012996, 62120667}, { 32007630, 62197246}, { 32002828, 62265761}, { 32003310, 62373952}, { 32003630, 62444825}, + { 31951202, 63100419}, { 31935103, 63301732}, { 31937490, 63354807}, { 31968533, 64124669}, { 32071989, 64767136}, { 32091323, 64947492}, { 32101518, 65042609}, { 32140486, 65216353}, { 32159835, 65302616}, { 32422071, 66001036}, + { 32441049, 66056128}, { 32463003, 66119864}, { 32483582, 66164217}, { 32504016, 66208251}, { 32702117, 66557895}, { 32734168, 66611648}, { 32759723, 66654509}, { 32985249, 66546464}, { 33208649, 66439436}, { 33424955, 66330151}, + { 33554797, 66263457}, { 33891385, 66090564}, { 34622897, 65616004}, { 34819546, 65471063}, { 34988926, 65346218}, { 35739513, 64794843}, { 36421629, 64150515}, { 36944662, 63656452}, { 36959929, 63643292}, { 36964174, 63639854}, + { 36973615, 63630686}, { 37023366, 63597643}, { 37652255, 63172287}, { 37804320, 63100590}, { 37939211, 63174238}, { 37949998, 63178562}, { 38147664, 63257792}, { 38147652, 63269386}, { 38147521, 63403665}, { 38150429, 63418056}, + { 38177182, 63550576}, { 38159827, 64298859}, { 38153585, 64520174}, { 38146482, 64771937}, { 38142126, 64820836}, { 38138239, 64839298}, { 38115242, 65010431}, { 38113231, 65025393}, { 37912271, 66372984}, { 37841830, 66687479}, + { 37674277, 67228175}, { 37551047, 67593509}, { 37497098, 67727333}, { 37392268, 67951311}, { 36986640, 68817980}, { 36604483, 69575518}, { 36479686, 69769345}, { 36265058, 70102690}, { 36332308, 70163400}, { 36398395, 70223058}, + { 36718105, 70645723}, { 36714573, 70708131}, { 36707947, 70825274}, { 36665865, 71083146}, { 36295751, 71910509}, { 36243731, 72020144}, { 36010145, 72512434}, { 35364761, 74115820}, { 35327445, 74206370}, { 35287332, 74303707}, + { 35262905, 74370595}, { 35235816, 74444782}, { 35006275, 75142899}, { 34758612, 75896141}, { 34609479, 76324076}, { 34534936, 76598593}, { 34419529, 77019735}, { 34125782, 78091675}, { 34270135, 78023153}, { 34366481, 77977415}, + { 34669421, 77827427}, { 35532698, 77282412}, { 35875762, 77065829}, { 35924952, 77041288}, { 35981906, 77004141}, { 36227708, 76899428}, { 36700108, 76693284}, { 36835857, 76657801}, { 36942059, 76731654}, { 36959107, 76741135}, + { 37155031, 76850094}, { 37152161, 76868751}, { 37133420, 76990662}, { 37135224, 77014721}, { 37144331, 77136260}, { 37029215, 77783623}, { 36994547, 77984972}, { 36957442, 78200506}, { 36949745, 78231593}, { 36945059, 78243379}, + { 36909925, 78358183}, { 36908693, 78362210}, { 36517584, 79569608}, { 36400200, 79852238}, { 36160758, 80317591}, { 36001388, 80606724}, { 35929263, 80720331}, { 35803937, 80894237}, { 35313741, 81574455}, { 34810829, 82211118}, + { 34636165, 82398130}, { 34424143, 82625140}, { 34177218, 82875584}, { 34001320, 83053991}, { 33330876, 83686990}, { 33313615, 83940131}, { 33257889, 84757318}, { 33154596, 86125618}, { 33050414, 87930914}, { 33037323, 88157771}, + { 32996151, 88791902}, { 33122354, 88720953}, { 34042644, 88195810}, { 34854618, 87571171}, { 35217422, 87292077}, { 35240201, 87279017}, { 35256654, 87268145}, { 35304044, 87230648}, { 35465557, 87154377}, { 35979874, 86886707}, + { 36162994, 86833255}, { 36213131, 86859811}, { 36328089, 86920714}, { 36446386, 87103899}, { 36444792, 87129675}, { 36435583, 87278561}, { 36439166, 87306042}, { 36455346, 87430153}, { 36439626, 87577638}, { 36363937, 88287781}, + { 36334385, 88516418}, { 36324472, 88550288}, { 36266923, 88831775}, { 36258817, 88871412}, { 36009099, 90001153}, { 35925390, 90278389}, { 35742522, 90743063}, { 35584494, 91114154}, { 35511233, 91260521}, { 35378328, 91493626}, + { 34896978, 92337857}, { 34592698, 92829175}, { 34534101, 92906355}, { 34379904, 93109443}, { 34292029, 93224277}, { 34181322, 93368951}, { 33996695, 93594059}, { 33791238, 93844563}, { 33350304, 94350448}, { 32679061, 95059135}, + { 32663276, 95383974}, { 32630835, 96051559}, { 32623715, 96162432}, { 32625261, 96184173}, { 32631760, 96253789}, { 32637940, 96319986}, { 32671334, 96831435}, { 32555999, 97073603}, { 32552956, 97110111}, { 32549772, 97148299}, + { 32339278, 100576678}, { 32333722, 100685777}, { 32330348, 100752035}, { 32315766, 101012907}, { 32604225, 100816839}, { 32833219, 100661190}, { 33690734, 100037568}, { 33947721, 99810841}, { 34263306, 99532414}, { 34709871, 99161136}, + { 35458100, 98470566}, { 35535202, 98409290}, { 35673889, 98299068}, { 35825183, 98230993}, { 36031300, 98138241}, { 36364183, 98058757}, { 36389853, 98099020}, { 36443213, 98182736}, { 36495776, 98421334}, { 36464592, 98534766}, + { 36403262, 98757832}, { 36433188, 98786253}, { 36468201, 98819516}, { 36427877, 99135414}, { 36380139, 99509425}, { 36367327, 99566653}, { 36130997, 100458902}, { 36092849, 100736616}, { 35993189, 101207413}, { 35961980, 101354843}, + { 35901824, 101565944}, { 35599001, 102436249}, { 35598486, 102437494}, { 35525627, 102612717}, { 35498238, 102672427}, { 35179093, 103368204}, { 34902420, 103873765}, { 34074371, 105280790}, { 33796945, 105666257}, { 33430747, 106175067}, + { 32757675, 107021332}, { 32288404, 107611357}, { 32147333, 107782229}, { 32045181, 107903768}, { 32013865, 108446053}, { 32004365, 108597331}, { 31933356, 109727991}, { 31929556, 109801743}, { 31921205, 109963885}, { 31919950, 109998202}, + { 31917378, 110068478}, { 31935487, 110174763}, { 31962352, 110332410}, { 31868759, 110776536}, { 31779274, 112901692}, { 31772558, 113008639}, { 31763520, 113152580}, { 31760914, 113226796}, { 31757613, 113320828}, { 31878079, 113245898}, + { 32056600, 113134847}, { 32205325, 113028281}, { 32417383, 112876331}, { 32791706, 112611586}, { 33374891, 112199137}, { 34043729, 111739447}, { 34299836, 111533282}, { 34686259, 111194925}, { 35041202, 110899316}, { 36153161, 109973245}, + { 36489565, 109732139}, { 36935134, 109547251}, { 36998142, 109523782}, { 37285208, 109416845}, { 37303575, 109443686}, { 37380657, 109556352}, { 37429339, 109768662}, { 37389406, 109896075}, { 37312708, 110140778}, { 37330397, 110173101}, + { 37358669, 110224762}, { 37347970, 110508588}, { 37343682, 110622428}, { 37233824, 111039422}, { 36974286, 111866215}, { 36941457, 112104350}, { 36810462, 112600390}, { 36763361, 112778757}, { 36685333, 113003686}, { 36304140, 113929965}, + { 36303227, 113931942}, { 36219925, 114112998}, { 36185254, 114177524}, { 35766113, 114957538}, { 35699185, 115058398}, { 35271549, 115739102}, { 34529522, 116832154}, { 34230604, 117226448}, { 34152175, 117323267}, { 33753453, 117815498}, + { 33688745, 117896887}, { 33515149, 118115220}, { 33167360, 118505862}, { 32252839, 119533076}, { 31951224, 119865885}, { 31856676, 119967574}, { 31811772, 120013039}, { 31820788, 120150853}, { 31837447, 120637820}, { 31884548, 122014628}, + { 31884879, 122025348}, { 31884889, 122025915}, { 31884859, 122030715}, { 31853727, 124752378}, { 31852710, 125798379}, { 32040109, 125687330}, { 32336721, 125511560}, { 33050838, 125039566}, { 33741293, 124531865}, { 34004877, 124347492}, + { 34706008, 123857040}, { 34900746, 123695124}, { 35248769, 123405773}, { 35958009, 122839178}, { 36752647, 122139217}, { 36794698, 122103853}, { 36926183, 121993279}, { 37041929, 121900209}, { 37364281, 121641009}, { 37506782, 121535931}, + { 37599623, 121475276}, { 37805210, 121390600}, { 38274450, 121197339}, { 38429386, 121137935}, { 38611951, 121409191}, { 38647554, 121490884}, { 38558179, 121763354}, { 38544345, 121816126}, { 38504735, 121967178}, { 38540287, 122025777}, + { 38533522, 122225637}, { 38527834, 122393821}, { 38490015, 122574939}, { 38335371, 123023448}, { 38226910, 123422167}, { 38128017, 123785706}, { 38110062, 123913558}, { 38039445, 124196782}, { 37811751, 125109983}, { 37795287, 125159401}, + { 37789856, 125175267}, { 37747302, 125281671}, { 37678378, 125454008}, { 37326009, 126304036}, { 37280379, 126403545}, { 36723741, 127438116}, { 36607591, 127622339}, { 35307172, 129556108}, { 34960577, 130042788}, { 34625146, 130457962}, + { 34244496, 130929114}, { 33616736, 131638592}, { 33126427, 132192717}, { 32289044, 133098400}, { 32128210, 133254928}, { 32114672, 133265860}, { 32051379, 133303244}, { 31973610, 133349175}, { 32021296, 134019482}, { 32078232, 134927829}, + { 32192915, 136757391}, { 32250210, 137342897}, { 32301584, 137908848}, { 32406571, 139065434}, { 32456488, 139422175}, { 32511513, 139855909}, { 32587723, 140456611}, { 33065481, 140191593}, { 33323332, 140063408}, { 33766028, 139843340}, + { 33978698, 139717429}, { 34224999, 139571601}, { 35090288, 139002456}, { 36098536, 138270161}, { 36204726, 138196467}, { 36870073, 137734734}, { 36937868, 137678015}, { 37269439, 137400662}, { 38224552, 136636721}, { 39248462, 135736109}, + { 39262231, 135724978}, { 39431206, 135588270}, { 39558286, 135491389}, { 40066663, 135103831}, { 40597978, 134876486}, { 40913397, 134752602}, { 41009750, 134730971}, { 41033440, 134769160}, { 41137853, 134937472}, { 41236776, 135135656}, + { 41185372, 135392011}, { 41170368, 135466840}, { 41117848, 135629223}, { 41128977, 135726643}, { 41112112, 135925316}, { 41028443, 136275112}, { 40892177, 136737346}, { 40715316, 137337282}, { 40625973, 137862286}, { 40571054, 138077826}, + { 40413004, 138698127}, { 40307787, 139028628}, { 40280705, 139108396}, { 40108570, 139542037}, { 39781168, 140366808}, { 39776747, 140377453}, { 39771298, 140388940}, { 39694209, 140532631}, { 39126953, 141589960}, { 39112976, 141613526}, + { 38864787, 141998169}, { 38780359, 142124163}, { 37534211, 143983846}, { 36837998, 144898691}, { 36749607, 145008489}, { 36437049, 145396720}, { 36308895, 145540735}, { 35926199, 145970826}, { 35104551, 146848709}, { 34756762, 147234955}, + { 34428436, 147599589}, { 34120556, 147908106}, { 34059694, 147944671}, { 33992021, 147971830}, { 33888925, 148013197}, { 33994002, 148234139}, { 34102871, 148463060}, { 34260406, 148815390}, { 34505558, 149252538}, { 34649150, 149539737}, + { 34875213, 149991894}, { 34913367, 150060689}, { 34939834, 150108425}, { 35009188, 150222655}, { 35057146, 150301638}, { 35531716, 151039155}, { 35961908, 151607166}, { 36198106, 151919026}, { 37112008, 151466356}, { 37122527, 151461129}, + { 37143274, 151448455}, { 37793852, 151104327}, { 38753278, 150462096}, { 39057095, 150265965}, { 39387132, 150052914}, { 39992757, 149578233}, { 40209373, 149410006}, { 40448656, 149224173}, { 41648972, 148150708}, { 41827582, 147994189}, + { 42089284, 147764870}, { 42281920, 147557241}, { 42535672, 147283737}, { 43211137, 146606344}, { 43969650, 145734949}, { 44008274, 145690567}, { 44434382, 145256367}, { 44673165, 145036231}, { 44753304, 144976343}, { 44941707, 144886575}, + { 45449136, 144644796}, { 45533221, 144617860}, { 45594657, 144672684}, { 45686988, 144755077}, { 45821054, 144894151}, { 45845698, 144928928}, { 45802394, 145256827}, { 45801968, 145263145}, { 45793099, 145396327}, { 45826083, 145436911}, + { 45827387, 145448733}, { 45852550, 145676686}, { 45846396, 146183080}, { 45801072, 146729105}, { 45751200, 147329993}, { 45765306, 147565974}, { 45765766, 147690105}, { 45758629, 147823920}, { 45717918, 148587045}, { 45669293, 148998256}, + { 45657164, 149090109}, { 45565455, 149517107}, { 45390903, 150329829}, { 45380310, 150370709}, { 45303883, 150599765}, { 45049477, 151362234}, { 45041081, 151384892}, { 44988127, 151512567}, { 44899898, 151709940}, { 44188361, 153301702}, + { 43960091, 153807492}, { 43687530, 154326968}, { 43680264, 154339888}, { 43428400, 154787836}, { 43418419, 154804941}, { 43222756, 155140257}, { 43211901, 155157187}, { 43019606, 155457042}, { 42439201, 156284412}, { 42742998, 156320854}, + { 42946786, 156345296}, { 43218356, 156408139}, { 43490220, 156548626}, { 43600789, 156605776}, { 43616758, 156616967}, { 43638494, 156675797}, { 43689725, 156874320}, { 43697411, 156939181}, { 43667792, 157194800}, { 43663112, 157219786}, + { 43589483, 157612846}, { 43578259, 157650201}, { 43503908, 157897703}, { 43271842, 158586008}, { 43026656, 159112379}, { 42680049, 159768278}, { 42229097, 160621619}, { 41614538, 161818913}, { 41602009, 161838594}, { 41549009, 161921905}, + { 41366702, 162195210}, { 41089703, 162610457}, { 41051349, 162661598}, { 40028827, 163938879}, { 39981539, 163995316}, { 39859709, 164140726}, { 39557928, 164489623}, { 38840108, 165319487}, { 38817977, 165343409}, { 36508721, 167822791}, + { 35803734, 168527171}, { 35265129, 169065323}, { 35217638, 169111343}, { 35182142, 169143335}, { 34143283, 170051242}, { 34091092, 170092305}, { 33992346, 170169987}, { 32820222, 171015261}, { 32596277, 171172367}, { 32366414, 171333625}, + { 30949741, 172256683}, { 30776429, 172369214}, { 30685231, 172428426}, { 29784929, 172978028}, { 29711510, 173022900}, { 29649347, 173060901}, { 29626880, 173084470}, { 29607989, 173104288}, { 29476620, 173372906}, { 29166644, 173374167}, + { 29105869, 173396269}, { 29066168, 173410694}, { 28480959, 173773359}, { 28318456, 173874074}, { 28236958, 173920336}, { 28053468, 174015451}, { 27663961, 174212865}, { 26444009, 174781179}, { 25128636, 175292014}, { 24833691, 175404475}, + { 24567873, 175499255}, { 23673660, 175815148}, { 23263816, 175959931}, { 22989484, 175996217}, { 22919277, 176005507}, { 22821755, 176011321}, { 22593369, 175931875}, { 22197778, 175796707}, { 20895444, 175329856}, { 20562493, 175210506}, + { 20357518, 175131409}, { 19431901, 174778687}, { 19227774, 174700914}, { 17432818, 173805114}, { 17355249, 173765680}, { 17340552, 173757060}, { 17293649, 173727963}, { 15176003, 172414266}, { 14987901, 172296594}, { 14897452, 172240019}, + { 14730104, 172123866}, { 14649567, 172067971}, { 12604451, 170685425}, { 12582065, 170669040}, { 12501564, 170610143}, { 12483411, 170595498}, { 12418519, 170543227}, { 11146256, 169546467}, { 11131285, 169533173}, { 10973608, 169393198}, + { 10963368, 169383375}, { 10855356, 169279681}, { 9350332, 167783891}, { 9237755, 167663880}, { 9038028, 167450975}, { 7554140, 165846157}, { 6510331, 164717307}, { 6450301, 164645790}, { 4792198, 162599032}, { 4711896, 162499401}, + { 4702892, 162486484}, { 4689884, 162466018}, { 4689721, 162465748}, { 4111625, 161512044}, { 3262811, 159825639}, { 3085907, 159501392}, { 2964224, 159278374}, { 2880198, 159123098}, { 2827825, 159026309}, { 2730830, 158798250}, + { 2662597, 158637824}, { 2461794, 158144454}, { 2258655, 157377436}, { 2232776, 156966420}, { 2227381, 156880727}, { 2229842, 156800001}, { 2404803, 156571898}, { 2502593, 156512353}, { 2571069, 156470646}, { 3012355, 156329121}, + { 3172690, 156317433}, { 3263007, 156310852}, { 3448807, 156270050}, { 2933268, 155537448}, { 2932334, 155536119}, { 2690506, 155171633}, { 2473838, 154800417}, { 2214521, 154335871}, { 1956160, 153843466}, { 1643404, 153150964}, + { 936422, 151585583}, { 886715, 151471650}, { 881872, 151459055}, { 835673, 151315362}, { 420381, 150023686}, { 415543, 150006511}, { 411493, 149986474}, { 371105, 149740432}, { 184472, 148603483}, { 176976, 148544106}, { 143829, 148268525}, + { 141423, 148213179}, { 118798, 147692447}, { 141994, 147109270}, { 96664, 146619882}, { 46940, 146083025}, { 34028, 145778412}, { 32148, 145734124}, { 50580, 145571914}, { 79797, 145477573}, { 59893, 144996644}, { 53607, 144916874}, + { 75632, 144881102}, { 170230, 144783356}, { 367047, 144609349}, { 495089, 144649841}, { 696206, 144748339}, { 861062, 144829070}, { 1202743, 145013350}, { 1665932, 145467720}, { 1738044, 145542186}, { 1871110, 145679584}, { 2233705, 146073631}, + { 2875888, 146771504}, { 2976802, 146887761}, { 3008358, 146918708}, { 3105019, 147016992}, { 3562844, 147482514}, { 3900940, 147829488}, { 3926192, 147851556}, { 5456634, 149216502}, { 5473415, 149229592}, { 5678115, 149389248}, + { 6416516, 149979537}, { 6693887, 150160404}, { 7011978, 150367823}, { 8034093, 151060650}, { 8245822, 151174920}, { 8663509, 151400371}, { 8734568, 151444233}, { 9700825, 151913516}, { 10314440, 151101573}, { 10876143, 150241580}, + { 10937084, 150142918}, { 10989872, 150057455}, { 11012110, 150016058}, { 11029139, 149984364}, { 11202330, 149640866}, { 11331097, 149385460}, { 11601540, 148893595}, { 11801542, 148453984}, { 11867898, 148312015}, { 12006182, 148016156}, + { 11936334, 147987685}, { 11846756, 147951181}, { 11775937, 147908929}, { 11448318, 147578728}, { 10005162, 146006655}, { 9941330, 145934468}, { 9420742, 145345782}, { 9364739, 145276533}, { 9005053, 144831776}, { 8354706, 143947082}, + { 7741954, 143034251}, { 7046776, 141998616}, { 6866979, 141726486}, { 6759755, 141551328}, { 6581042, 141228382}, { 6214827, 140566592}, { 6160332, 140464737}, { 6154984, 140452943}, { 6118667, 140365627}, { 5608006, 139066930}, + { 5576877, 138974353}, { 5449821, 138579522}, { 5423448, 138473840}, { 5269717, 137857830}, { 5183256, 137323221}, { 5051763, 136885377}, { 4900390, 136381329}, { 4788716, 135926420}, { 4778542, 135832434}, { 4751278, 135580592}, + { 4759133, 135551850}, { 4772567, 135502722}, { 4750760, 135428400}, { 4689711, 135220325}, { 4720284, 134950229}, { 4772938, 134876983}, { 4872059, 134739100}, { 4907041, 134734799}, { 4988166, 134747911}, { 5187996, 134827143}, + { 5324282, 134881173}, { 5823633, 135095262}, { 6457261, 135576778}, { 6468046, 135585394}, { 6645027, 135726930}, { 7665807, 136625984}, { 8014871, 136908364}, { 8760642, 137511681}, { 9070115, 137764153}, { 9505207, 138067027}, + { 9692018, 138199840}, { 10866067, 139034528}, { 10974854, 139102654}, { 11199174, 139243162}, { 11980766, 139757269}, { 12820102, 140204762}, { 13013724, 140301821}, { 13307713, 140449197}, { 13339465, 140204984}, { 13387908, 139832384}, + { 13476326, 139229254}, { 13545245, 138464294}, { 13637934, 137435521}, { 13704650, 136750183}, { 13756310, 135946981}, { 13854009, 134427968}, { 13931781, 133352665}, { 13880515, 133326641}, { 13806176, 133288914}, { 13608773, 133095964}, + { 13229938, 132676064}, { 12917088, 132329299}, { 12475540, 131854762}, { 12234438, 131582242}, { 11645945, 130917061}, { 11435343, 130656410}, { 11256705, 130435328}, { 11087956, 130227341}, { 10943531, 130049329}, { 10660547, 129658000}, + { 9884836, 128504691}, { 9363495, 127729593}, { 9183437, 127445707}, { 8613352, 126392173}, { 8569664, 126295529}, { 8233135, 125484892}, { 8100143, 125150567}, { 8091324, 125125230}, { 8068370, 125055541}, { 8047369, 124966573}, + { 7827878, 124036734}, { 7815999, 123941440}, { 7743138, 123689990}, { 7467916, 122740178}, { 7381012, 122383130}, { 7365871, 122250909}, { 7330956, 121946008}, { 7347071, 121910652}, { 7366239, 121868607}, { 7337555, 121775565}, + { 7275180, 121573218}, { 7357784, 121255913}, { 7363162, 121248563}, { 7433561, 121152362}, { 7492882, 121172887}, { 8152120, 121400901}, { 8296078, 121458859}, { 8337642, 121483827}, { 8428744, 121552386}, { 8461373, 121578560}, + { 9113408, 122101612}, { 9968838, 122858025}, { 10418874, 123221408}, { 11203964, 123855334}, { 11236475, 123882487}, { 11264272, 123901717}, { 12869603, 125041315}, { 13619004, 125547677}, { 13833945, 125671552}, { 14049136, 125795572}, + { 14042979, 124631730}, { 14031124, 123791039}, { 14029618, 123425913}, { 14024871, 122275773}, { 14024680, 122240909}, { 14024300, 122172017}, { 14024368, 122132419}, { 14024494, 122058437}, { 14025750, 122003675}, { 14028093, 121901540}, + { 14053706, 121051621}, { 14084937, 120015176}, { 13976495, 119893307}, { 12808105, 118596333}, { 12632795, 118395530}, { 12332420, 118051483}, { 12010936, 117651678}, { 11662489, 117218341}, { 11286185, 116695820}, { 10542401, 115590915}, + { 10484664, 115505145}, { 10085127, 114875400}, { 9677465, 114107097}, { 9676038, 114103997}, { 9587011, 113910478}, { 9572058, 113874387}, { 9221672, 113028545}, { 9132465, 112762183}, { 8929936, 112011523}, { 8896027, 111773355}, + { 8763540, 111338847}, { 8591711, 110775312}, { 8585822, 110750616}, { 8583286, 110726469}, { 8532504, 110242770}, { 8561517, 110201837}, { 8589689, 110162093}, { 8539283, 109999835}, { 8459773, 109743891}, { 8476274, 109635698}, + { 8539247, 109532026}, { 8559299, 109499015}, { 8639538, 109407427}, { 8837219, 109481673}, { 9374636, 109713713}, { 9614985, 109884378}, { 9895885, 110108176}, { 10150796, 110311272}, { 10647433, 110745796}, { 11163900, 111149653}, + { 11435641, 111378216}, { 11952173, 111812662}, { 12063358, 111892355}, { 12195941, 111987389}, { 13754894, 113077948}, { 13965930, 113207021}, { 14143358, 113315534}, { 14095680, 112195851}, { 14075275, 111736247}, { 14031684, 110754424}, + { 13949266, 109698295}, { 13931155, 109374956}, { 13907232, 108947887}, { 13903305, 108820557}, { 13899752, 108705317}, { 13898286, 108692370}, { 13896892, 108680054}, { 13882077, 108455610}, { 13866991, 108227067}, { 13852378, 107897586}, + { 13627196, 107630194}, { 13249326, 107173733}, { 13128837, 107021896}, { 12504668, 106235327}, { 12449045, 106156712}, { 12301165, 105947708}, { 12240927, 105864439}, { 12071292, 105629917}, { 11741182, 105140360}, { 11102902, 104050785}, + { 11009874, 103891983}, { 10724262, 103375048}, { 10370561, 102607103}, { 10302463, 102446702}, { 9995869, 101563023}, { 9933827, 101340326}, { 9788639, 100674614}, { 9761576, 100425516}, { 9620310, 99895785}, { 9572074, 99714909}, + { 9473316, 99261511}, { 9457110, 98860065}, { 9475422, 98813097}, { 9491516, 98771818}, { 9454445, 98628574}, { 9395112, 98399301}, { 9430018, 98201406}, { 9448015, 98172416}, { 9519385, 98057456}, { 9858391, 98155219}, { 10045563, 98209192}, + { 10217386, 98274096}, { 10328458, 98365757}, { 11168922, 99136589}, { 11517095, 99428522}, { 11782963, 99664460}, { 12152171, 99992110}, { 12543518, 100270019}, { 12914813, 100533689}, { 13199749, 100744460}, { 13324020, 100835567}, + { 13585579, 101027330}, { 13575682, 100826649}, { 13569447, 100700201}, { 13562345, 100567361}, { 13559065, 100506021}, { 13429751, 98521010}, { 13371150, 97621467}, { 13343156, 97180710}, { 13333987, 97039073}, { 13207473, 95084673}, + { 13138184, 95005008}, { 13017680, 94866468}, { 12083312, 93848129}, { 12022705, 93771797}, { 11862461, 93569995}, { 11784430, 93470508}, { 11589381, 93221813}, { 11309567, 92840780}, { 10844778, 92098029}, { 10775191, 91976786}, + { 10496881, 91491862}, { 10185086, 90849349}, { 10144137, 90764963}, { 10074833, 90600171}, { 9828579, 89857830}, { 9703614, 89075796}, { 9674971, 88969502}, { 9495272, 88102892}, { 9475468, 87916753}, { 9440640, 87589408}, { 9465676, 87528619}, + { 9487914, 87474617}, { 9465041, 87357340}, { 9428525, 87170118}, { 9490390, 86904119}, { 9512256, 86883153}, { 9574632, 86823334}, { 9727402, 86841642}, { 10166330, 86894255}, { 10190151, 86899193}, { 10198409, 86903284}, { 10249971, 86942095}, + { 10299758, 86980568}, { 11788945, 88131376}, { 11901024, 88196968}, { 12050012, 88284161}, { 12770268, 88697024}, { 12893258, 88767518}, { 12865978, 88340499}, { 12755514, 86383203}, { 12590001, 84209400}, { 12584956, 84143148}, + { 12549052, 83666692}, { 11929877, 83107725}, { 11390770, 82556851}, { 11083660, 82243035}, { 10537284, 81546957}, { 10424674, 81403496}, { 10079867, 80926984}, { 9689286, 80270083}, { 9687616, 80267071}, { 9615613, 80136762}, + { 9601056, 80104215}, { 9309849, 79453353}, { 9259598, 79312241}, { 9118888, 78788995}, { 9088297, 78585733}, { 8994447, 78301695}, { 8881493, 77959840}, { 8828452, 77771748}, { 8812025, 77688113}, { 8733303, 77287329}, { 8744431, 77274990}, + { 8786674, 77228142}, { 8770800, 77179143}, { 8746495, 77100409}, { 8709758, 76981397}, { 8765710, 76725562}, { 8780763, 76703647}, { 8821796, 76643902}, { 9050198, 76667553}, { 9430163, 76706910}, { 9505621, 76721216}, { 9535183, 76740071}, + { 9561982, 76753134}, { 11021709, 77681521}, { 11271938, 77809531}, { 11740477, 78049225}, { 11713323, 77940287}, { 11500961, 77088300}, { 11491445, 77055518}, { 11468672, 76977103}, { 11007894, 75454998}, { 10625858, 74342820}, + { 10581531, 74223613}, { 10547931, 74133250}, { 9872558, 72487409}, { 9785055, 72279833}, { 9735127, 72161397}, { 9661531, 72007947}, { 9614591, 71910070}, { 9234200, 71112437}, { 9147114, 70727104}, { 9142261, 70702843}, { 9138267, 70682891}, + { 9286224, 70443224}, { 9461343, 70247284}, { 9556416, 70162672}, { 9625168, 70101485}, { 9435737, 69811425}, { 9287394, 69584273}, { 8757085, 68530695}, { 8673850, 68365333}, { 8445942, 67877601}, { 8187617, 67187177}, { 8139627, 67039434}, + { 7937861, 66234567}, { 7892565, 65909655}, { 7845288, 65439718}, { 7844011, 65310767}, { 7823103, 65136343}, { 7778117, 64761067}, { 7716333, 64313964}, { 7705694, 64124356}, { 7687717, 63803945}, { 7701643, 63790152}, { 7718011, 63773943}, + { 7758186, 63752036}, { 7729172, 63586572}, { 7697769, 63407488}, { 7779619, 63146399}, { 7790119, 63132497}, { 7857734, 63042993}, { 7899799, 63053366}, { 8115923, 63106666}, { 8464711, 63240292}, { 8677072, 63398904}, { 8767176, 63477143}, + { 8977927, 63660143}, { 9421383, 64100703}, { 9785048, 64413088}, { 9975436, 64589567}, { 10286420, 64877827}, { 11014721, 65410888}, { 11115862, 65482249}, { 11327524, 65631599}, { 11395991, 65675856}, { 11535890, 65766274}, { 12026448, 66109919}, + { 12502690, 66343355}, { 12786634, 66472769}, { 13164960, 66645193}, { 13207596, 66564001}, { 13256756, 66470394}, { 13640736, 65570500}, { 13683003, 65454507}, { 13718537, 65356988}, { 13735231, 65270567}, { 13747424, 65207437}, + { 13863686, 64629409}, { 13875328, 64496043}, { 13887975, 64351165}, { 13957488, 63607260}, { 13950883, 63386188}, { 13943973, 63154947}, { 13895952, 62476120}, { 13876483, 62262044}, { 13859838, 62079009}, { 13859584, 62074662}, + { 13859582, 62065658}, { 13859483, 61971042}, { 13862761, 55222623}, { 13815791, 55212684}, { 13617475, 55174296}, { 13379849, 55128299}, { 13200660, 55067043}, { 13117648, 55038667}, { 12798922, 54907256}, { 12743350, 54730557}, + { 12719703, 54655364}, { 12656225, 54324243}, { 12632418, 53676660}, { 12625539, 53489551}, { 12652785, 53052852}, { 12782795, 52820186}, { 12846930, 52705411}, { 13041220, 52491209}, { 13143647, 52409064}, { 13187810, 52373646}, + { 13354789, 52319639}, { 13381838, 52313108}, { 13407786, 52306845}, { 13609096, 52308186}, { 13798532, 52309451}, { 14794521, 52294618}, { 15549961, 52336594}, { 16050147, 52311338}, { 16209513, 52303295}, { 16312325, 52297439}, + { 16369590, 51869307}, { 16340473, 51576398}, { 16331091, 51482008}, { 16316170, 51377054}, { 16241360, 51186578}, { 16186688, 51047373}, { 16076915, 50725256}, { 16093629, 50461603}, { 16098435, 50385771}, { 16109774, 50333994}, + { 16208639, 50141731}, { 16271132, 50020206}, { 16284775, 49997056}, { 16295310, 49985147}, { 16360397, 49947770}, { 16432796, 49916484}, { 16999910, 49671395}, { 17079341, 49631019}, { 17221011, 49559013}, { 17356128, 49546264}, + { 17369996, 49528116}, { 17426993, 49502498}, { 17530282, 49456075}, { 17342293, 49148088}, { 17284381, 49008875}, { 17254026, 48935905}, { 17357436, 48625105}, { 17422365, 48429965}, { 17423796, 48426977}, { 17601162, 48056939}, + { 17599241, 47980228}, { 17595410, 47827198}, { 17579402, 47751708}, { 17538195, 47557388}, { 17400788, 46598168}, { 17023471, 46464319}, { 16973301, 46446494}, { 16812540, 46389386}, { 16673736, 46329440}, { 16319654, 46176525}, + { 15950663, 46003440}, { 15838028, 45939836}, { 15697899, 45836427}, { 15289766, 45502367}, { 15260072, 45476441}, { 14999104, 45248614}, { 14962927, 45210840}, { 14722491, 44959778}, { 14678301, 44921783}, { 14404868, 44686698}, + { 14020130, 44298671}, { 13905758, 44155324}, { 13566066, 43648328}, { 13163266, 43047144}, { 13102631, 42937239}, { 13070977, 42862998}, { 12945977, 42560557}, { 12902489, 42448510}, { 12696099, 41916758}, { 12684650, 41857975}, + { 12656516, 41713516}, { 12557005, 40938961}, { 12554067, 40837978}, { 12550435, 40713161}, { 12562692, 40535359}, { 12575839, 40344643}, { 12609216, 40034504}, { 12660395, 39915667}, { 12708691, 39803526}, { 12798899, 39599814}, + { 12938906, 39372986}, { 12995589, 39281154}, { 13232289, 39007147}, { 13498241, 38725717}, { 13591444, 38550048}, { 13628611, 38480001}, { 13631794, 38446522}, { 13586786, 38388985}, { 13507530, 38236091}, { 13096257, 38028857}, + { 12821362, 37838492}, { 12551686, 37651741}, { 12445887, 37503612}, { 12369283, 37396362}, { 12264258, 37242462}, { 12195026, 37044172}, { 12148552, 36863589}, { 12101329, 36680088}, { 12142095, 35348959}, { 12144651, 35291418}, + { 12162788, 34883134}, { 12163706, 34850506}, { 12168637, 34675334}, { 12163420, 34644423}, { 12134883, 34475307}, { 12106311, 33932082}, { 12095021, 33476333}, { 12094122, 33057779}, { 12092211, 32168031}, { 12100800, 31962352}, + { 12107580, 31800023}, { 12116077, 31640101}, { 12122543, 31518406}, { 12193613, 31111725}, { 12255946, 30755035}, { 12655685, 28642673}, { 12654000, 28322388}, { 12689137, 28120452}, { 12708722, 28007885}, { 12692342, 27740702}, + { 12770201, 27316837}, { 12810004, 27100162}, { 12822406, 26990057}, { 12840969, 26876333}, { 12930142, 26507364}, { 13006294, 26192274}, { 13140275, 25812749}, { 13171909, 25737294}, { 13213594, 25637871}, { 13513395, 24982223}, + { 13564918, 24904642}, { 13614340, 24830229}, { 13673478, 24765245}, { 13723561, 24710211}, { 13790283, 24595233}, { 13857122, 24480057}, { 14153860, 24116007}, { 14231993, 24020147}, { 14248273, 23981550}, { 14451243, 23786195}, + { 14602942, 23651634}, { 14684407, 23579375}, { 15221344, 23339532}, { 15255414, 23324310}, { 15480802, 23178412}, { 15646843, 23091400}, { 16018697, 22744059}, { 16456749, 22567685}, { 16708674, 22466255}, { 16837697, 22410158}, + { 17154392, 22190832}, { 17069931, 22106918}, { 17007737, 21985244}, { 16978925, 21928875}, { 17036320, 21826992}, { 17212750, 21670157}, { 17298093, 21594293}, { 17451145, 21457485}, { 17530883, 21256458}, { 17541075, 21230767}, + { 17549886, 21207629}, { 17244063, 20372250}, { 17209346, 20248411}, { 17092010, 20089995}, { 17023648, 19955801}, { 16984483, 19912896}, { 16834254, 19784836}, { 16625524, 19606905}, { 16620983, 19603024}, { 16616582, 19597241}, + { 16614255, 19589014}, { 16578856, 19463898}, { 16588025, 19439937}, { 16595650, 19420015}, { 16602627, 19365704}, { 16608518, 19319848}, { 16694764, 19210381}, { 16784442, 19096556}, { 16461235, 17851161}, { 16421291, 17669728}, + { 16359955, 17616552}, { 16304854, 17528237}, { 16266671, 17467038}, { 16001330, 17343372}, { 15927109, 17308781}, { 15828509, 17248124}, { 15766385, 17190011}, { 15678175, 17097940}, { 15629868, 17047518}, { 15678592, 16534350}, + { 15695434, 16356965}, { 15704034, 16303332}, { 15705308, 16269732}, { 15725443, 15743784}, { 15808595, 15332260}, { 15821377, 15312568}, { 15838901, 15285580}, { 15993537, 15201723}, { 16119571, 15175593}, { 16189683, 15163592}, + { 16237347, 15155438}, { 16508759, 15159065}, { 16375757, 14977910}, { 16282021, 14850635}, { 15510709, 13877187}, { 15342882, 13710959}, { 15237532, 13606608}, { 14831965, 13239743}, { 14581428, 13013122}, { 14293147, 12740902}, + { 14190984, 12660109}, { 13669460, 12247703}, { 12564414, 11331695}, { 12487187, 11271158}, { 12046686, 10925925}, { 11871179, 10835479}, { 11582487, 10686699}, { 11523291, 10654160}, { 11396348, 10324251}, { 11575096, 9791088}, + { 11656410, 9657529}, { 11694903, 9594301}, { 12154341, 8957487}, { 12327404, 8717611}, { 12920992, 7861977}, { 13163209, 7541046}, { 13299428, 7360558}, { 13534727, 7094968}, { 13607608, 7012705}, { 14344532, 6120949}, { 15087045, 5393680}, + { 15307430, 5177820}, { 15930737, 4553097}, { 16730116, 3841678}, { 17107544, 3505773}, { 17287251, 3346015}, { 17407773, 3251557}, { 17762201, 2970942}, { 18238970, 2593464}, { 18584923, 2367852}, { 18697829, 2294226}, { 18997703, 2084694}, + { 19253265, 1922140}, { 19413044, 1820512}, { 20082389, 1425058}, { 21018405, 914454}, { 21306702, 757182}, { 21909855, 426548}, { 22232009, 276063}, { 22432844, 180461}, { 22572399, 114027}, { 22900298, 67093} + }; + out.holes.emplace_back(Slic3r::Points( { + { 28812659, 51882256}, { 28813904, 51895244}, { 28807002, 51890550}, { 28850702, 52059657}, { 28856299, 52123368}, { 29045593, 52135332}, { 29004080, 52024610}, { 28932623, 51976002}, { 29332407, 51880142}, { 29334099, 51804647}, + { 29252306, 51781113}, { 29155613, 51753292}, { 28890648, 51728889}, { 28797131, 51720277} + } )); + return out; +} + SCENARIO("Elephant foot compensation", "[ElephantFoot]") { + GIVEN("Contour with hole") { + ExPolygon expoly = contour_with_hole(); + WHEN("Compensated") { + // Elephant foot compensation shall not pinch off bits from this contour. + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.419999987f, 0.2f, 0.4f, false), 0.2f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_with_hole.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } + + GIVEN("Tiny contour") { + ExPolygon expoly({ { 133382606, 94912473 }, { 134232493, 95001115 }, { 133783926, 95159440 }, { 133441897, 95180666 }, { 133408242, 95191984 }, { 133339012, 95166830 }, { 132991642, 95011087 }, { 133206549, 94908304 } }); + WHEN("Compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.419999987f, 0.2f, 0.4f, false), 0.2f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_tiny.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("Tiny contour is not compensated") { + REQUIRE(expoly_compensated == expoly); + } + } + } + GIVEN("Large box") { ExPolygon expoly( { {50000000, 50000000 }, { 0, 50000000 }, { 0, 0 }, { 50000000, 0 } } ); WHEN("Compensated") { diff --git a/tests/libslic3r/test_geometry.cpp b/tests/libslic3r/test_geometry.cpp index 22755c2622..4a800b3d3f 100644 --- a/tests/libslic3r/test_geometry.cpp +++ b/tests/libslic3r/test_geometry.cpp @@ -252,15 +252,39 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method", "[Geometry]") { } } -TEST_CASE("Chained path working correctly", "[Geometry]"){ - // if chained_path() works correctly, these points should be joined with no diagonal paths - // (thus 26 units long) - std::vector points = {Point(26,26),Point(52,26),Point(0,26),Point(26,52),Point(26,0),Point(0,52),Point(52,52),Point(52,0)}; - std::vector indices = chain_points(points); - for (Points::size_type i = 0; i + 1 < indices.size(); ++ i) { - double dist = (points.at(indices.at(i)).cast() - points.at(indices.at(i+1)).cast()).norm(); - REQUIRE(std::abs(dist-26) <= EPSILON); - } +SCENARIO("Path chaining", "[Geometry]") { + GIVEN("A path") { + std::vector points = { Point(26,26),Point(52,26),Point(0,26),Point(26,52),Point(26,0),Point(0,52),Point(52,52),Point(52,0) }; + THEN("Chained with no diagonals (thus 26 units long)") { + std::vector indices = chain_points(points); + for (Points::size_type i = 0; i + 1 < indices.size(); ++ i) { + double dist = (points.at(indices.at(i)).cast() - points.at(indices.at(i+1)).cast()).norm(); + REQUIRE(std::abs(dist-26) <= EPSILON); + } + } + } + GIVEN("Loop pieces") { + Point a { 2185796, 19058485 }; + Point b { 3957902, 18149382 }; + Point c { 2912841, 18790564 }; + Point d { 2831848, 18832390 }; + Point e { 3179601, 18627769 }; + Point f { 3137952, 18653370 }; + Polylines polylines = { { a, b }, + { c, d }, + { e, f }, + { d, a }, + { f, c }, + { b, e } }; + Polylines chained = chain_polylines(polylines, &a); + THEN("Connected without a gap") { + for (size_t i = 0; i < chained.size(); ++i) { + const Polyline &pl1 = (i == 0) ? chained.back() : chained[i - 1]; + const Polyline &pl2 = chained[i]; + REQUIRE(pl1.points.back() == pl2.points.front()); + } + } + } } SCENARIO("Line distances", "[Geometry]"){