Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_project_dirty_state
|
@ -268,8 +268,6 @@ set(LIBDIR_BIN ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||||
include_directories(${LIBDIR})
|
include_directories(${LIBDIR})
|
||||||
# For generated header files
|
# For generated header files
|
||||||
include_directories(${LIBDIR_BIN}/platform)
|
include_directories(${LIBDIR_BIN}/platform)
|
||||||
# For libslic3r.h
|
|
||||||
include_directories(${LIBDIR}/clipper)
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
|
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
|
||||||
|
|
4
deps/deps-linux.cmake
vendored
|
@ -13,7 +13,7 @@ include("deps-unix-common.cmake")
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND ./bootstrap.sh
|
CONFIGURE_COMMAND ./bootstrap.sh
|
||||||
|
@ -100,5 +100,5 @@ ExternalProject_Add(dep_libcurl
|
||||||
BUILD_COMMAND make "-j${NPROC}"
|
BUILD_COMMAND make "-j${NPROC}"
|
||||||
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies(dep_openvdb dep_boost)
|
add_dependencies(dep_openvdb dep_boost)
|
||||||
|
|
||||||
|
|
4
deps/deps-macos.cmake
vendored
|
@ -18,7 +18,7 @@ include("deps-unix-common.cmake")
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND ./bootstrap.sh
|
CONFIGURE_COMMAND ./bootstrap.sh
|
||||||
|
@ -87,5 +87,5 @@ ExternalProject_Add(dep_libcurl
|
||||||
BUILD_COMMAND make "-j${NPROC}"
|
BUILD_COMMAND make "-j${NPROC}"
|
||||||
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
||||||
)
|
)
|
||||||
|
add_dependencies(dep_openvdb dep_boost)
|
||||||
|
|
||||||
add_dependencies(dep_openvdb dep_boost)
|
|
5
deps/deps-mingw.cmake
vendored
|
@ -9,7 +9,7 @@ include("deps-unix-common.cmake")
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND bootstrap.bat
|
CONFIGURE_COMMAND bootstrap.bat
|
||||||
|
@ -58,4 +58,5 @@ ExternalProject_Add(dep_libcurl
|
||||||
-DCURL_DISABLE_GOPHER=ON
|
-DCURL_DISABLE_GOPHER=ON
|
||||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||||
${DEP_CMAKE_OPTS}
|
${DEP_CMAKE_OPTS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
5
deps/deps-windows.cmake
vendored
|
@ -55,7 +55,7 @@ endmacro()
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND bootstrap.bat
|
CONFIGURE_COMMAND bootstrap.bat
|
||||||
|
@ -295,4 +295,5 @@ if (${DEP_DEBUG})
|
||||||
COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
|
COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
|
||||||
WORKING_DIRECTORY "${BINARY_DIR}"
|
WORKING_DIRECTORY "${BINARY_DIR}"
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
BIN
resources/icons/info.png
Normal file
After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 232 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 221 KiB |
|
@ -1,11 +1,14 @@
|
||||||
min_slic3r_version = 2.3.0-beta2
|
min_slic3r_version = 2.3.1-beta
|
||||||
0.0.8 Updated start and end g-code for Anycubic Mega.
|
0.0.10 Various updates for Anycubic Mega. Added filament profiles.
|
||||||
0.0.7 Updated start g-code for Anycubic Mega.
|
0.0.9 Updated bed textures
|
||||||
0.0.6 Reduced max print height for Predator. Updated end g-code, before layer change g-code and output filename format for Kossel.
|
min_slic3r_version = 2.3.0-beta2
|
||||||
0.0.5 Updated end g-code.
|
0.0.8 Updated start and end g-code for Anycubic Mega.
|
||||||
min_slic3r_version = 2.3.0-alpha2
|
0.0.7 Updated start g-code for Anycubic Mega.
|
||||||
0.0.4 Fixed predator output filename format, infill overlap, start gcode adjustments.
|
0.0.6 Reduced max print height for Predator. Updated end g-code, before layer change g-code and output filename format for Kossel.
|
||||||
0.0.3 Fixed infill_overlap, start_gcode, end_gcode for Anycubic Predator
|
0.0.5 Updated end g-code.
|
||||||
0.0.2 Added Anycubic Predator
|
min_slic3r_version = 2.3.0-alpha2
|
||||||
min_slic3r_version = 2.3.0-alpha0
|
0.0.4 Fixed predator output filename format, infill overlap, start gcode adjustments.
|
||||||
0.0.1 Initial Version
|
0.0.3 Fixed infill_overlap, start_gcode, end_gcode for Anycubic Predator
|
||||||
|
0.0.2 Added Anycubic Predator
|
||||||
|
min_slic3r_version = 2.3.0-alpha0
|
||||||
|
0.0.1 Initial Version
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
name = Anycubic
|
name = Anycubic
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# 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.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.0.8
|
config_version = 0.0.10
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
@ -76,7 +76,7 @@ bridge_flow_ratio = 0.8
|
||||||
bridge_speed = 30
|
bridge_speed = 30
|
||||||
brim_width = 0
|
brim_width = 0
|
||||||
clip_multipart_objects = 1
|
clip_multipart_objects = 1
|
||||||
compatible_printers =
|
compatible_printers =
|
||||||
complete_objects = 0
|
complete_objects = 0
|
||||||
dont_support_bridges = 1
|
dont_support_bridges = 1
|
||||||
elefant_foot_compensation = 0
|
elefant_foot_compensation = 0
|
||||||
|
@ -108,7 +108,7 @@ max_volumetric_extrusion_rate_slope_negative = 0
|
||||||
max_volumetric_extrusion_rate_slope_positive = 0
|
max_volumetric_extrusion_rate_slope_positive = 0
|
||||||
max_volumetric_speed = 0
|
max_volumetric_speed = 0
|
||||||
min_skirt_length = 4
|
min_skirt_length = 4
|
||||||
notes =
|
notes =
|
||||||
overhangs = 0
|
overhangs = 0
|
||||||
only_retract_when_crossing_perimeters = 0
|
only_retract_when_crossing_perimeters = 0
|
||||||
ooze_prevention = 0
|
ooze_prevention = 0
|
||||||
|
@ -117,8 +117,8 @@ perimeters = 2
|
||||||
perimeter_extruder = 1
|
perimeter_extruder = 1
|
||||||
perimeter_extrusion_width = 0.45
|
perimeter_extrusion_width = 0.45
|
||||||
perimeter_speed = 45
|
perimeter_speed = 45
|
||||||
post_process =
|
post_process =
|
||||||
print_settings_id =
|
print_settings_id =
|
||||||
raft_layers = 0
|
raft_layers = 0
|
||||||
resolution = 0
|
resolution = 0
|
||||||
seam_position = nearest
|
seam_position = nearest
|
||||||
|
@ -290,7 +290,7 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_MODEL_AK(|LP).*/ and n
|
||||||
# Common filament preset
|
# Common filament preset
|
||||||
[filament:*common_akossel*]
|
[filament:*common_akossel*]
|
||||||
cooling = 0
|
cooling = 0
|
||||||
compatible_printers =
|
compatible_printers =
|
||||||
extrusion_multiplier = 1
|
extrusion_multiplier = 1
|
||||||
filament_cost = 0
|
filament_cost = 0
|
||||||
filament_density = 0
|
filament_density = 0
|
||||||
|
@ -375,9 +375,9 @@ filament_vendor = Generic
|
||||||
# Common printer preset
|
# Common printer preset
|
||||||
[printer:*common_akossel*]
|
[printer:*common_akossel*]
|
||||||
printer_technology = FFF
|
printer_technology = FFF
|
||||||
bed_shape =
|
bed_shape =
|
||||||
before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]
|
before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]
|
||||||
between_objects_gcode =
|
between_objects_gcode =
|
||||||
deretract_speed = 40
|
deretract_speed = 40
|
||||||
extruder_colour = #FFFF00
|
extruder_colour = #FFFF00
|
||||||
extruder_offset = 0x0
|
extruder_offset = 0x0
|
||||||
|
@ -405,8 +405,8 @@ max_layer_height = 0.3
|
||||||
min_layer_height = 0.08
|
min_layer_height = 0.08
|
||||||
max_print_height = 300
|
max_print_height = 300
|
||||||
nozzle_diameter = 0.4
|
nozzle_diameter = 0.4
|
||||||
printer_notes =
|
printer_notes =
|
||||||
printer_settings_id =
|
printer_settings_id =
|
||||||
retract_before_travel = 2
|
retract_before_travel = 2
|
||||||
retract_before_wipe = 70%
|
retract_before_wipe = 70%
|
||||||
retract_layer_change = 1
|
retract_layer_change = 1
|
||||||
|
@ -419,9 +419,9 @@ retract_restart_extra = 0
|
||||||
retract_restart_extra_toolchange = 0
|
retract_restart_extra_toolchange = 0
|
||||||
retract_speed = 60
|
retract_speed = 60
|
||||||
single_extruder_multi_material = 0
|
single_extruder_multi_material = 0
|
||||||
start_gcode =
|
start_gcode =
|
||||||
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG28 ; home\nM84 ; disable motors
|
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG28 ; home\nM84 ; disable motors
|
||||||
toolchange_gcode =
|
toolchange_gcode =
|
||||||
use_firmware_retraction = 0
|
use_firmware_retraction = 0
|
||||||
use_relative_e_distances = 1
|
use_relative_e_distances = 1
|
||||||
use_volumetric_e = 0
|
use_volumetric_e = 0
|
||||||
|
@ -435,7 +435,7 @@ default_filament_profile = Generic PLA @AKOSSEL
|
||||||
inherits = *common_akossel*
|
inherits = *common_akossel*
|
||||||
printer_model = AKLP
|
printer_model = AKLP
|
||||||
printer_variant = 0.4
|
printer_variant = 0.4
|
||||||
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_Anycubic\nPRINTER_MODEL_AKLP\nPRINTER_HAS_BOWDEN\n
|
printer_notes = Do not 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_Anycubic\nPRINTER_MODEL_AKLP\nPRINTER_HAS_BOWDEN\n
|
||||||
bed_shape = 114.562x10.0229,113.253x19.9695,111.081x29.7642,108.065x39.3323,104.225x48.6011,99.5929x57.5,94.2025x65.9613,88.0951x73.9206,81.3173x81.3173,73.9206x88.0951,65.9613x94.2025,57.5x99.5929,48.6011x104.225,39.3323x108.065,29.7642x111.081,19.9695x113.253,10.0229x114.562,7.04172e-15x115,-10.0229x114.562,-19.9695x113.253,-29.7642x111.081,-39.3323x108.065,-48.6011x104.225,-57.5x99.5929,-65.9613x94.2025,-73.9206x88.0951,-81.3173x81.3173,-88.0951x73.9206,-94.2025x65.9613,-99.5929x57.5,-104.225x48.6011,-108.065x39.3323,-111.081x29.7642,-113.253x19.9695,-114.562x10.0229,-115x1.40834e-14,-114.562x-10.0229,-113.253x-19.9695,-111.081x-29.7642,-108.065x-39.3323,-104.225x-48.6011,-99.5929x-57.5,-94.2025x-65.9613,-88.0951x-73.9206,-81.3173x-81.3173,-73.9206x-88.0951,-65.9613x-94.2025,-57.5x-99.5929,-48.6011x-104.225,-39.3323x-108.065,-29.7642x-111.081,-19.9695x-113.253,-10.0229x-114.562,-2.11252e-14x-115,10.0229x-114.562,19.9695x-113.253,29.7642x-111.081,39.3323x-108.065,48.6011x-104.225,57.5x-99.5929,65.9613x-94.2025,73.9206x-88.0951,81.3173x-81.3173,88.0951x-73.9206,94.2025x-65.9613,99.5929x-57.5,104.225x-48.6011,108.065x-39.3323,111.081x-29.7642,113.253x-19.9695,114.562x-10.0229,115x-2.81669e-14
|
bed_shape = 114.562x10.0229,113.253x19.9695,111.081x29.7642,108.065x39.3323,104.225x48.6011,99.5929x57.5,94.2025x65.9613,88.0951x73.9206,81.3173x81.3173,73.9206x88.0951,65.9613x94.2025,57.5x99.5929,48.6011x104.225,39.3323x108.065,29.7642x111.081,19.9695x113.253,10.0229x114.562,7.04172e-15x115,-10.0229x114.562,-19.9695x113.253,-29.7642x111.081,-39.3323x108.065,-48.6011x104.225,-57.5x99.5929,-65.9613x94.2025,-73.9206x88.0951,-81.3173x81.3173,-88.0951x73.9206,-94.2025x65.9613,-99.5929x57.5,-104.225x48.6011,-108.065x39.3323,-111.081x29.7642,-113.253x19.9695,-114.562x10.0229,-115x1.40834e-14,-114.562x-10.0229,-113.253x-19.9695,-111.081x-29.7642,-108.065x-39.3323,-104.225x-48.6011,-99.5929x-57.5,-94.2025x-65.9613,-88.0951x-73.9206,-81.3173x-81.3173,-73.9206x-88.0951,-65.9613x-94.2025,-57.5x-99.5929,-48.6011x-104.225,-39.3323x-108.065,-29.7642x-111.081,-19.9695x-113.253,-10.0229x-114.562,-2.11252e-14x-115,10.0229x-114.562,19.9695x-113.253,29.7642x-111.081,39.3323x-108.065,48.6011x-104.225,57.5x-99.5929,65.9613x-94.2025,73.9206x-88.0951,81.3173x-81.3173,88.0951x-73.9206,94.2025x-65.9613,99.5929x-57.5,104.225x-48.6011,108.065x-39.3323,111.081x-29.7642,113.253x-19.9695,114.562x-10.0229,115x-2.81669e-14
|
||||||
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\nG1 X-54.672 Y95.203 Z0.3 F9000\nG92 E0.0\nG1 F1000\nG1 X-52.931 Y96.185 E0.300\nG1 X-50.985 Y97.231 E0.331\nG1 X-49.018 Y98.238 E0.331\nG1 X-47.032 Y99.205 E0.331\nG1 X-45.026 Y100.132 E0.331\nG1 X-43.003 Y101.019 E0.331\nG1 X-40.961 Y101.864 E0.331\nG1 X-38.904 Y102.668 E0.331\nG1 X-36.83 Y103.431 E0.331\nG1 X-34.742 Y104.152 E0.331\nG1 X-32.639 Y104.83 E0.331\nG1 X-30.523 Y105.466 E0.331\nG1 X-28.395 Y106.06 E0.331\nG1 X-26.255 Y106.61 E0.331\nG1 X-24.105 Y107.117 E0.331\nG1 X-21.945 Y107.581 E0.331\nG1 X-19.776 Y108.001 E0.331\nG1 X-17.599 Y108.377 E0.331\nG1 X-15.415 Y108.71 E0.331\nG1 X-13.224 Y108.998 E0.331\nG1 X-11.028 Y109.242 E0.331\nG1 X-8.828 Y109.442 E0.331\nG1 X-6.624 Y109.598 E0.331\nG1 X-4.418 Y109.709 E0.331\nG1 X-2.209 Y109.776 E0.332\nG1 X0 Y109.798 E0.331\nG1 X2.209 Y109.776 E0.690\nG1 X4.418 Y109.709 E0.691\nG1 X6.624 Y109.598 E0.690\nG1 X8.828 Y109.442 E0.690\nG1 X11.028 Y109.242 E0.690\nG1 X13.224 Y108.998 E0.690\nG1 X15.415 Y108.71 E0.691\nG1 X17.599 Y108.377 E0.690\nG1 X19.776 Y108.001 E0.690\nG1 X21.945 Y107.581 E0.690\nG1 X24.105 Y107.117 E0.690\nG1 X26.255 Y106.61 E0.690\nG1 X28.395 Y106.06 E0.690\nG1 X30.523 Y105.466 E0.690\nG1 X32.639 Y104.83 E0.690\nG1 X34.742 Y104.152 E0.690\nG1 X36.83 Y103.431 E0.690\nG1 X38.904 Y102.668 E0.691\nG1 X40.961 Y101.864 E0.690\nG1 X43.003 Y101.019 E0.691\nG1 X45.026 Y100.132 E0.690\nG1 X47.032 Y99.205 E0.691\nG1 X49.018 Y98.238 E0.690\nG1 X50.985 Y97.231 E0.691\nG1 X52.931 Y96.185 E0.690\nG1 X54.672 Y95.203 E0.625\nG92 E0.0\nG1 E-5 F3000 ; retract 5mm\nG1 X52.931 Y96.185 F1000 ; wipe\nG1 X50.985 Y97.231 F1000 ; wipe\nG1 X49.018 Y98.238 F1000 ; wipe\nG1 X0 Y109.798 F1000\nG1 E4.8 F1500; de-retract\nG92 E0.0 ; reset extrusion distance\nM221 S{if layer_height<0.075}100{else}95{endif}
|
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\nG1 X-54.672 Y95.203 Z0.3 F9000\nG92 E0.0\nG1 F1000\nG1 X-52.931 Y96.185 E0.300\nG1 X-50.985 Y97.231 E0.331\nG1 X-49.018 Y98.238 E0.331\nG1 X-47.032 Y99.205 E0.331\nG1 X-45.026 Y100.132 E0.331\nG1 X-43.003 Y101.019 E0.331\nG1 X-40.961 Y101.864 E0.331\nG1 X-38.904 Y102.668 E0.331\nG1 X-36.83 Y103.431 E0.331\nG1 X-34.742 Y104.152 E0.331\nG1 X-32.639 Y104.83 E0.331\nG1 X-30.523 Y105.466 E0.331\nG1 X-28.395 Y106.06 E0.331\nG1 X-26.255 Y106.61 E0.331\nG1 X-24.105 Y107.117 E0.331\nG1 X-21.945 Y107.581 E0.331\nG1 X-19.776 Y108.001 E0.331\nG1 X-17.599 Y108.377 E0.331\nG1 X-15.415 Y108.71 E0.331\nG1 X-13.224 Y108.998 E0.331\nG1 X-11.028 Y109.242 E0.331\nG1 X-8.828 Y109.442 E0.331\nG1 X-6.624 Y109.598 E0.331\nG1 X-4.418 Y109.709 E0.331\nG1 X-2.209 Y109.776 E0.332\nG1 X0 Y109.798 E0.331\nG1 X2.209 Y109.776 E0.690\nG1 X4.418 Y109.709 E0.691\nG1 X6.624 Y109.598 E0.690\nG1 X8.828 Y109.442 E0.690\nG1 X11.028 Y109.242 E0.690\nG1 X13.224 Y108.998 E0.690\nG1 X15.415 Y108.71 E0.691\nG1 X17.599 Y108.377 E0.690\nG1 X19.776 Y108.001 E0.690\nG1 X21.945 Y107.581 E0.690\nG1 X24.105 Y107.117 E0.690\nG1 X26.255 Y106.61 E0.690\nG1 X28.395 Y106.06 E0.690\nG1 X30.523 Y105.466 E0.690\nG1 X32.639 Y104.83 E0.690\nG1 X34.742 Y104.152 E0.690\nG1 X36.83 Y103.431 E0.690\nG1 X38.904 Y102.668 E0.691\nG1 X40.961 Y101.864 E0.690\nG1 X43.003 Y101.019 E0.691\nG1 X45.026 Y100.132 E0.690\nG1 X47.032 Y99.205 E0.691\nG1 X49.018 Y98.238 E0.690\nG1 X50.985 Y97.231 E0.691\nG1 X52.931 Y96.185 E0.690\nG1 X54.672 Y95.203 E0.625\nG92 E0.0\nG1 E-5 F3000 ; retract 5mm\nG1 X52.931 Y96.185 F1000 ; wipe\nG1 X50.985 Y97.231 F1000 ; wipe\nG1 X49.018 Y98.238 F1000 ; wipe\nG1 X0 Y109.798 F1000\nG1 E4.8 F1500; de-retract\nG92 E0.0 ; reset extrusion distance\nM221 S{if layer_height<0.075}100{else}95{endif}
|
||||||
|
|
||||||
|
@ -443,7 +443,7 @@ start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104
|
||||||
inherits = *common_akossel*
|
inherits = *common_akossel*
|
||||||
printer_model = AK
|
printer_model = AK
|
||||||
printer_variant = 0.4
|
printer_variant = 0.4
|
||||||
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_Anycubic\nPRINTER_MODEL_AK\nPRINTER_HAS_BOWDEN\n
|
printer_notes = Do not 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_Anycubic\nPRINTER_MODEL_AK\nPRINTER_HAS_BOWDEN\n
|
||||||
bed_shape = 89.6575x7.84402,88.6327x15.6283,86.9333x23.2937,84.5723x30.7818,81.5677x38.0356,77.9423x45,73.7237x51.6219,68.944x57.8509,63.6396x63.6396,57.8509x68.944,51.6219x73.7237,45x77.9423,38.0356x81.5677,30.7818x84.5723,23.2937x86.9333,15.6283x88.6327,7.84402x89.6575,5.51091e-15x90,-7.84402x89.6575,-15.6283x88.6327,-23.2937x86.9333,-30.7818x84.5723,-38.0356x81.5677,-45x77.9423,-51.6219x73.7237,-57.8509x68.944,-63.6396x63.6396,-68.944x57.8509,-73.7237x51.6219,-77.9423x45,-81.5677x38.0356,-84.5723x30.7818,-86.9333x23.2937,-88.6327x15.6283,-89.6575x7.84402,-90x1.10218e-14,-89.6575x-7.84402,-88.6327x-15.6283,-86.9333x-23.2937,-84.5723x-30.7818,-81.5677x-38.0356,-77.9423x-45,-73.7237x-51.6219,-68.944x-57.8509,-63.6396x-63.6396,-57.8509x-68.944,-51.6219x-73.7237,-45x-77.9423,-38.0356x-81.5677,-30.7818x-84.5723,-23.2937x-86.9333,-15.6283x-88.6327,-7.84402x-89.6575,-1.65327e-14x-90,7.84402x-89.6575,15.6283x-88.6327,23.2937x-86.9333,30.7818x-84.5723,38.0356x-81.5677,45x-77.9423,51.6219x-73.7237,57.8509x-68.944,63.6396x-63.6396,68.944x-57.8509,73.7237x-51.6219,77.9423x-45,81.5677x-38.0356,84.5723x-30.7818,86.9333x-23.2937,88.6327x-15.6283,89.6575x-7.84402,90x-2.20436e-14
|
bed_shape = 89.6575x7.84402,88.6327x15.6283,86.9333x23.2937,84.5723x30.7818,81.5677x38.0356,77.9423x45,73.7237x51.6219,68.944x57.8509,63.6396x63.6396,57.8509x68.944,51.6219x73.7237,45x77.9423,38.0356x81.5677,30.7818x84.5723,23.2937x86.9333,15.6283x88.6327,7.84402x89.6575,5.51091e-15x90,-7.84402x89.6575,-15.6283x88.6327,-23.2937x86.9333,-30.7818x84.5723,-38.0356x81.5677,-45x77.9423,-51.6219x73.7237,-57.8509x68.944,-63.6396x63.6396,-68.944x57.8509,-73.7237x51.6219,-77.9423x45,-81.5677x38.0356,-84.5723x30.7818,-86.9333x23.2937,-88.6327x15.6283,-89.6575x7.84402,-90x1.10218e-14,-89.6575x-7.84402,-88.6327x-15.6283,-86.9333x-23.2937,-84.5723x-30.7818,-81.5677x-38.0356,-77.9423x-45,-73.7237x-51.6219,-68.944x-57.8509,-63.6396x-63.6396,-57.8509x-68.944,-51.6219x-73.7237,-45x-77.9423,-38.0356x-81.5677,-30.7818x-84.5723,-23.2937x-86.9333,-15.6283x-88.6327,-7.84402x-89.6575,-1.65327e-14x-90,7.84402x-89.6575,15.6283x-88.6327,23.2937x-86.9333,30.7818x-84.5723,38.0356x-81.5677,45x-77.9423,51.6219x-73.7237,57.8509x-68.944,63.6396x-63.6396,68.944x-57.8509,73.7237x-51.6219,77.9423x-45,81.5677x-38.0356,84.5723x-30.7818,86.9333x-23.2937,88.6327x-15.6283,89.6575x-7.84402,90x-2.20436e-14
|
||||||
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\nG1 X-39.672 Y69.712 Z0.3 F9000\nG92 E0.0\nG1 F1000\nG1 X-38.457 Y70.397 E0.209\nG1 X-37.043 Y71.157 E0.241\nG1 X-35.614 Y71.889 E0.241\nG1 X-34.171 Y72.591 E0.241\nG1 X-32.714 Y73.265 E0.241\nG1 X-31.244 Y73.909 E0.241\nG1 X-29.761 Y74.523 E0.241\nG1 X-28.266 Y75.108 E0.241\nG1 X-26.759 Y75.662 E0.241\nG1 X-25.242 Y76.185 E0.241\nG1 X-23.714 Y76.678 E0.241\nG1 X-22.177 Y77.14 E0.241\nG1 X-20.63 Y77.571 E0.241\nG1 X-19.076 Y77.971 E0.241\nG1 X-17.514 Y78.34 E0.241\nG1 X-15.944 Y78.677 E0.241\nG1 X-14.368 Y78.982 E0.241\nG1 X-12.786 Y79.255 E0.241\nG1 X-11.199 Y79.497 E0.241\nG1 X-9.608 Y79.706 E0.241\nG1 X-8.013 Y79.884 E0.241\nG1 X-6.414 Y80.029 E0.241\nG1 X-4.813 Y80.142 E0.241\nG1 X-3.21 Y80.223 E0.241\nG1 X-1.605 Y80.271 E0.241\nG1 X0 Y80.287 E0.241\nG1 X1.605 Y80.271 E0.502\nG1 X3.21 Y80.223 E0.502\nG1 X4.813 Y80.142 E0.502\nG1 X6.414 Y80.029 E0.502\nG1 X8.013 Y79.884 E0.502\nG1 X9.608 Y79.706 E0.502\nG1 X11.199 Y79.497 E0.501\nG1 X12.786 Y79.255 E0.502\nG1 X14.368 Y78.982 E0.502\nG1 X15.944 Y78.677 E0.502\nG1 X17.514 Y78.34 E0.502\nG1 X19.076 Y77.971 E0.502\nG1 X20.63 Y77.571 E0.501\nG1 X22.177 Y77.14 E0.502\nG1 X23.714 Y76.678 E0.502\nG1 X25.242 Y76.185 E0.502\nG1 X26.759 Y75.662 E0.501\nG1 X28.266 Y75.108 E0.502\nG1 X29.761 Y74.523 E0.502\nG1 X31.244 Y73.909 E0.502\nG1 X32.714 Y73.265 E0.502\nG1 X34.171 Y72.591 E0.502\nG1 X35.614 Y71.889 E0.501\nG1 X37.043 Y71.157 E0.502\nG1 X38.457 Y70.397 E0.502\nG1 X39.672 Y69.712 E0.436\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
|
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\nG1 X-39.672 Y69.712 Z0.3 F9000\nG92 E0.0\nG1 F1000\nG1 X-38.457 Y70.397 E0.209\nG1 X-37.043 Y71.157 E0.241\nG1 X-35.614 Y71.889 E0.241\nG1 X-34.171 Y72.591 E0.241\nG1 X-32.714 Y73.265 E0.241\nG1 X-31.244 Y73.909 E0.241\nG1 X-29.761 Y74.523 E0.241\nG1 X-28.266 Y75.108 E0.241\nG1 X-26.759 Y75.662 E0.241\nG1 X-25.242 Y76.185 E0.241\nG1 X-23.714 Y76.678 E0.241\nG1 X-22.177 Y77.14 E0.241\nG1 X-20.63 Y77.571 E0.241\nG1 X-19.076 Y77.971 E0.241\nG1 X-17.514 Y78.34 E0.241\nG1 X-15.944 Y78.677 E0.241\nG1 X-14.368 Y78.982 E0.241\nG1 X-12.786 Y79.255 E0.241\nG1 X-11.199 Y79.497 E0.241\nG1 X-9.608 Y79.706 E0.241\nG1 X-8.013 Y79.884 E0.241\nG1 X-6.414 Y80.029 E0.241\nG1 X-4.813 Y80.142 E0.241\nG1 X-3.21 Y80.223 E0.241\nG1 X-1.605 Y80.271 E0.241\nG1 X0 Y80.287 E0.241\nG1 X1.605 Y80.271 E0.502\nG1 X3.21 Y80.223 E0.502\nG1 X4.813 Y80.142 E0.502\nG1 X6.414 Y80.029 E0.502\nG1 X8.013 Y79.884 E0.502\nG1 X9.608 Y79.706 E0.502\nG1 X11.199 Y79.497 E0.501\nG1 X12.786 Y79.255 E0.502\nG1 X14.368 Y78.982 E0.502\nG1 X15.944 Y78.677 E0.502\nG1 X17.514 Y78.34 E0.502\nG1 X19.076 Y77.971 E0.502\nG1 X20.63 Y77.571 E0.501\nG1 X22.177 Y77.14 E0.502\nG1 X23.714 Y76.678 E0.502\nG1 X25.242 Y76.185 E0.502\nG1 X26.759 Y75.662 E0.501\nG1 X28.266 Y75.108 E0.502\nG1 X29.761 Y74.523 E0.502\nG1 X31.244 Y73.909 E0.502\nG1 X32.714 Y73.265 E0.502\nG1 X34.171 Y72.591 E0.502\nG1 X35.614 Y71.889 E0.501\nG1 X37.043 Y71.157 E0.502\nG1 X38.457 Y70.397 E0.502\nG1 X39.672 Y69.712 E0.436\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}
|
||||||
|
|
||||||
|
@ -784,7 +784,7 @@ printer_model = MEGA0
|
||||||
printer_variant = 0.4
|
printer_variant = 0.4
|
||||||
max_layer_height = 0.3
|
max_layer_height = 0.3
|
||||||
min_layer_height = 0.1
|
min_layer_height = 0.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_ANYCUBIC\nPRINTER_MODEL_MEGA0
|
printer_notes = Do not 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_ANYCUBIC\nPRINTER_MODEL_MEGA0
|
||||||
bed_shape = 0x0,220x0,220x220,0x220
|
bed_shape = 0x0,220x0,220x220,0x220
|
||||||
max_print_height = 250
|
max_print_height = 250
|
||||||
machine_max_acceleration_e = 5000
|
machine_max_acceleration_e = 5000
|
||||||
|
@ -822,54 +822,61 @@ end_gcode = M117 Cooling down...\nM104 S0 ; turn off extruder\nM107 ; Fan off\nM
|
||||||
|
|
||||||
[print:*common_mega*]
|
[print:*common_mega*]
|
||||||
bottom_solid_min_thickness = 0.5
|
bottom_solid_min_thickness = 0.5
|
||||||
bridge_acceleration = 1800
|
bridge_acceleration = 1000
|
||||||
bridge_flow_ratio = 0.8
|
bridge_flow_ratio = 0.95
|
||||||
bridge_speed = 30
|
bridge_speed = 30
|
||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and printer_notes=~/.*PRINTER_MODEL_I3_MEGA.*/ and nozzle_diameter[0]==0.4
|
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and printer_notes=~/.*PRINTER_MODEL_I3_MEGA.*/ and nozzle_diameter[0]==0.4
|
||||||
default_acceleration = 1800
|
default_acceleration = 1000
|
||||||
ensure_vertical_shell_thickness = 1
|
ensure_vertical_shell_thickness = 1
|
||||||
external_perimeter_extrusion_width = 0.6
|
external_perimeter_extrusion_width = 0.45
|
||||||
external_perimeter_speed = 40
|
external_perimeter_speed = 25
|
||||||
extruder_clearance_height = 35
|
extruder_clearance_height = 35
|
||||||
extruder_clearance_radius = 60
|
extruder_clearance_radius = 60
|
||||||
extrusion_width = 0.45
|
extrusion_width = 0.45
|
||||||
fill_density = 15%
|
fill_density = 15%
|
||||||
fill_pattern = gyroid
|
fill_pattern = gyroid
|
||||||
first_layer_acceleration = 1800
|
first_layer_acceleration = 1000
|
||||||
first_layer_extrusion_width = 0.42
|
first_layer_extrusion_width = 0.42
|
||||||
first_layer_height = 0.2
|
first_layer_height = 0.2
|
||||||
|
first_layer_speed = 20
|
||||||
gap_fill_speed = 40
|
gap_fill_speed = 40
|
||||||
gcode_comments = 1
|
gcode_comments = 1
|
||||||
infill_acceleration = 1800
|
infill_acceleration = 1000
|
||||||
|
infill_anchor = 2.5
|
||||||
|
infill_anchor_max = 12
|
||||||
infill_extrusion_width = 0.45
|
infill_extrusion_width = 0.45
|
||||||
infill_speed = 60
|
max_print_speed = 200
|
||||||
|
min_skirt_length = 4
|
||||||
only_retract_when_crossing_perimeters = 0
|
only_retract_when_crossing_perimeters = 0
|
||||||
output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
|
output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
|
||||||
perimeter_acceleration = 1800
|
perimeter_acceleration = 800
|
||||||
perimeter_extrusion_width = 0.45
|
perimeter_extrusion_width = 0.45
|
||||||
|
perimeter_speed = 45
|
||||||
perimeters = 2
|
perimeters = 2
|
||||||
seam_position = nearest
|
seam_position = nearest
|
||||||
skirts = 0
|
skirt_distance = 2
|
||||||
slice_closing_radius = 0.05
|
skirt_height = 3
|
||||||
small_perimeter_speed = 30
|
skirts = 1
|
||||||
|
small_perimeter_speed = 25
|
||||||
solid_infill_below_area = 0
|
solid_infill_below_area = 0
|
||||||
solid_infill_speed = 60
|
solid_infill_extrusion_width = 0.45
|
||||||
|
solid_infill_speed = 80
|
||||||
support_material_buildplate_only = 1
|
support_material_buildplate_only = 1
|
||||||
support_material_contact_distance = 0.1
|
support_material_contact_distance = 0.1
|
||||||
support_material_extrusion_width = 0.35
|
support_material_extrusion_width = 0.35
|
||||||
support_material_interface_layers = 2
|
support_material_interface_layers = 2
|
||||||
support_material_interface_spacing = 0.2
|
support_material_interface_spacing = 0.2
|
||||||
support_material_spacing = 2
|
support_material_spacing = 2
|
||||||
|
support_material_speed = 50
|
||||||
support_material_threshold = 55
|
support_material_threshold = 55
|
||||||
support_material_with_sheath = 0
|
|
||||||
thin_walls = 0
|
thin_walls = 0
|
||||||
top_infill_extrusion_width = 0.4
|
top_infill_extrusion_width = 0.4
|
||||||
top_solid_infill_speed = 40
|
top_solid_infill_speed = 40
|
||||||
|
top_solid_layers = 5
|
||||||
top_solid_min_thickness = 0.6
|
top_solid_min_thickness = 0.6
|
||||||
travel_speed = 180
|
travel_speed = 180
|
||||||
|
|
||||||
[print:*supported_mega*]
|
[print:*supported_mega*]
|
||||||
raft_layers = 2
|
|
||||||
support_material = 1
|
support_material = 1
|
||||||
|
|
||||||
# XXXXXXXXXXXXXXXXXXXX
|
# XXXXXXXXXXXXXXXXXXXX
|
||||||
|
@ -911,7 +918,19 @@ inherits = *0.20mm_mega*;*supported_mega*
|
||||||
[print:*0.30mm_mega*]
|
[print:*0.30mm_mega*]
|
||||||
inherits = *common_mega*
|
inherits = *common_mega*
|
||||||
bottom_solid_layers = 4
|
bottom_solid_layers = 4
|
||||||
bridge_flow_ratio = 0.95
|
external_perimeter_extrusion_width = 0.6
|
||||||
|
external_perimeter_speed = 35
|
||||||
|
extrusion_width = 0.5
|
||||||
|
fill_pattern = grid
|
||||||
|
infill_extrusion_width = 0.5
|
||||||
|
infill_speed = 85
|
||||||
|
layer_height = 0.3
|
||||||
|
perimeter_extrusion_width = 0.5
|
||||||
|
perimeter_speed = 50
|
||||||
|
small_perimeter_speed = 30
|
||||||
|
solid_infill_extrusion_width = 0.5
|
||||||
|
support_material_extrusion_width = 0.38
|
||||||
|
support_material_speed = 45
|
||||||
top_solid_layers = 4
|
top_solid_layers = 4
|
||||||
|
|
||||||
[print:0.30mm DRAFT @MEGA]
|
[print:0.30mm DRAFT @MEGA]
|
||||||
|
@ -929,7 +948,6 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and
|
||||||
end_filament_gcode = "; Filament-specific end gcode"
|
end_filament_gcode = "; Filament-specific end gcode"
|
||||||
fan_always_on = 1
|
fan_always_on = 1
|
||||||
fan_below_layer_time = 100
|
fan_below_layer_time = 100
|
||||||
filament_colour = #FF8000
|
|
||||||
filament_vendor = Generic
|
filament_vendor = Generic
|
||||||
min_print_speed = 15
|
min_print_speed = 15
|
||||||
slowdown_below_layer_time = 20
|
slowdown_below_layer_time = 20
|
||||||
|
@ -941,13 +959,13 @@ slowdown_below_layer_time = 20
|
||||||
cooling = 0
|
cooling = 0
|
||||||
fan_always_on = 0
|
fan_always_on = 0
|
||||||
fan_below_layer_time = 20
|
fan_below_layer_time = 20
|
||||||
filament_colour = #FFF2EC
|
filament_colour = #3A80CA
|
||||||
filament_cost = 27.82
|
filament_cost = 27.82
|
||||||
filament_density = 1.04
|
filament_density = 1.04
|
||||||
filament_max_volumetric_speed = 11
|
filament_max_volumetric_speed = 11
|
||||||
filament_ramming_parameters = "120 100 5.70968 6.03226 7 8.25806 9 9.19355 9.3871 9.77419 10.129 10.3226 10.4516 10.5161| 0.05 5.69677 0.45 6.15484 0.95 8.76774 1.45 9.20323 1.95 9.95806 2.45 10.3871 2.95 10.5677 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
|
filament_ramming_parameters = "120 100 5.70968 6.03226 7 8.25806 9 9.19355 9.3871 9.77419 10.129 10.3226 10.4516 10.5161| 0.05 5.69677 0.45 6.15484 0.95 8.76774 1.45 9.20323 1.95 9.95806 2.45 10.3871 2.95 10.5677 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
|
||||||
filament_type = ABS
|
filament_type = ABS
|
||||||
first_layer_bed_temperature = 100
|
first_layer_bed_temperature = 105
|
||||||
first_layer_temperature = 255
|
first_layer_temperature = 255
|
||||||
max_fan_speed = 30
|
max_fan_speed = 30
|
||||||
min_fan_speed = 20
|
min_fan_speed = 20
|
||||||
|
@ -955,14 +973,14 @@ slowdown_below_layer_time = 20
|
||||||
|
|
||||||
[filament:Generic ABS @MEGA]
|
[filament:Generic ABS @MEGA]
|
||||||
inherits = *ABS_mega*
|
inherits = *ABS_mega*
|
||||||
|
|
||||||
[filament:*FLEX_mega*]
|
[filament:*FLEX_mega*]
|
||||||
inherits = *common_mega*
|
inherits = *common_mega*
|
||||||
bed_temperature = 50
|
bed_temperature = 50
|
||||||
bridge_fan_speed = 80
|
bridge_fan_speed = 80
|
||||||
cooling = 0
|
cooling = 0
|
||||||
extrusion_multiplier = 1.15
|
extrusion_multiplier = 1.15
|
||||||
fan_always_on = 0
|
fan_always_on = 0
|
||||||
filament_colour = #008000
|
filament_colour = #008000
|
||||||
filament_cost = 82.00
|
filament_cost = 82.00
|
||||||
filament_density = 1.22
|
filament_density = 1.22
|
||||||
|
@ -970,7 +988,7 @@ filament_deretract_speed = 25
|
||||||
filament_max_volumetric_speed = 1.2
|
filament_max_volumetric_speed = 1.2
|
||||||
filament_retract_length = 0.8
|
filament_retract_length = 0.8
|
||||||
filament_type = FLEX
|
filament_type = FLEX
|
||||||
first_layer_bed_temperature = 50
|
first_layer_bed_temperature = 55
|
||||||
first_layer_temperature = 240
|
first_layer_temperature = 240
|
||||||
max_fan_speed = 90
|
max_fan_speed = 90
|
||||||
min_fan_speed = 70
|
min_fan_speed = 70
|
||||||
|
@ -979,16 +997,41 @@ temperature = 240
|
||||||
[filament:Generic FLEX @MEGA]
|
[filament:Generic FLEX @MEGA]
|
||||||
inherits = *FLEX_mega*
|
inherits = *FLEX_mega*
|
||||||
|
|
||||||
|
[filament:SainSmart TPU @MEGA]
|
||||||
|
inherits = *FLEX_mega*
|
||||||
|
filament_vendor = SainSmart
|
||||||
|
bed_temperature = 50
|
||||||
|
bridge_fan_speed = 100
|
||||||
|
cooling = 1
|
||||||
|
disable_fan_first_layers = 4
|
||||||
|
filament_cost = 39.99
|
||||||
|
filament_density = 1.21
|
||||||
|
filament_deretract_speed = 15
|
||||||
|
filament_max_volumetric_speed = 1.8
|
||||||
|
filament_notes = "SainSmart TPU gains popularity among 3D Printing community for its balance of rigidity and flexibility. In addition, with a 95A Shore Hardness and improved bed adhesion, it is easier to print even with a stock elementary 3D Printer like the Creality Ender 3. SainSmart TPU will not disappoint if you are looking for flexible filament. From drone parts, phone cases, to small toys, all can be printed with ease.\n\nhttps://www.sainsmart.com/collections/tpu-filament/products/all-colors-tpu-flexible-filament-1-75mm-0-8kg-1-76lb"
|
||||||
|
filament_retract_before_travel = 5
|
||||||
|
filament_retract_length = 4
|
||||||
|
filament_retract_speed = 40
|
||||||
|
filament_unloading_speed = 90
|
||||||
|
first_layer_bed_temperature = 55
|
||||||
|
first_layer_temperature = 235
|
||||||
|
full_fan_speed_layer = 6
|
||||||
|
max_fan_speed = 80
|
||||||
|
min_fan_speed = 80
|
||||||
|
slowdown_below_layer_time = 10
|
||||||
|
temperature = 235
|
||||||
|
|
||||||
[filament:*PETG_mega*]
|
[filament:*PETG_mega*]
|
||||||
inherits = *common_mega*
|
inherits = *common_mega*
|
||||||
bed_temperature = 90
|
bed_temperature = 90
|
||||||
bridge_fan_speed = 50
|
bridge_fan_speed = 50
|
||||||
fan_below_layer_time = 20
|
fan_below_layer_time = 20
|
||||||
|
filament_colour = #FF8000
|
||||||
filament_cost = 27.82
|
filament_cost = 27.82
|
||||||
filament_density = 1.27
|
filament_density = 1.27
|
||||||
filament_max_volumetric_speed = 8
|
filament_max_volumetric_speed = 8
|
||||||
filament_type = PETG
|
filament_type = PETG
|
||||||
first_layer_bed_temperature = 85
|
first_layer_bed_temperature = 90
|
||||||
first_layer_temperature = 230
|
first_layer_temperature = 230
|
||||||
max_fan_speed = 50
|
max_fan_speed = 50
|
||||||
min_fan_speed = 30
|
min_fan_speed = 30
|
||||||
|
@ -997,14 +1040,63 @@ temperature = 240
|
||||||
[filament:Generic PETG @MEGA]
|
[filament:Generic PETG @MEGA]
|
||||||
inherits = *PETG_mega*
|
inherits = *PETG_mega*
|
||||||
|
|
||||||
|
[filament:ColorFabb XT-CF20 @MEGA]
|
||||||
|
inherits = *PETG_mega*
|
||||||
|
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and printer_notes=~/.*PRINTER_MODEL_I3_MEGA.*/
|
||||||
|
extrusion_multiplier = 1.05
|
||||||
|
filament_colour = #804040
|
||||||
|
filament_cost = 66.60
|
||||||
|
filament_density = 1.35
|
||||||
|
filament_deretract_speed = 25
|
||||||
|
filament_max_volumetric_speed = 2
|
||||||
|
filament_notes = "Based on colorFabb_XT, XT-CF20 is a carbon fiber composite material. Loaded with no less than 20% specially sourced carbon fibers we have developed a very stiff and tough 3D printing filament made for functional parts. It is truly a professional printers go-to material, especially for users looking for high melt strength, high melt viscosity and good dimensional accuracy and stability.\n\nhttps://colorfabb.com/xt-cf20"
|
||||||
|
filament_retract_before_travel = 1
|
||||||
|
filament_retract_length = 1.4
|
||||||
|
filament_retract_speed = 40
|
||||||
|
filament_spool_weight = 236
|
||||||
|
filament_vendor = ColorFabb
|
||||||
|
first_layer_temperature = 260
|
||||||
|
full_fan_speed_layer = 5
|
||||||
|
slowdown_below_layer_time = 15
|
||||||
|
temperature = 260
|
||||||
|
|
||||||
|
[filament:ERYONE PETG @MEGA]
|
||||||
|
inherits = *PETG_mega*
|
||||||
|
filament_vendor = ERYONE
|
||||||
|
filament_cost = 20.99
|
||||||
|
filament_notes = "https://eryone.com/petg/show/10.html"
|
||||||
|
|
||||||
|
[filament:FormFutura HDglass @MEGA]
|
||||||
|
inherits = *PETG_mega*
|
||||||
|
filament_vendor = FormFutura
|
||||||
|
filament_cost = 46.65
|
||||||
|
filament_notes = "HDglass is a high performance PETG type of 3D printer with unsurpassed 3D printing properties and improved mechanical strength, flexibility, toughness and heat resistance.\n\nhttps://www.formfutura.com/shop/product/hdglass-2812"
|
||||||
|
|
||||||
|
[filament:FormFutura ReForm rPET @MEGA]
|
||||||
|
inherits = *PETG_mega*
|
||||||
|
filament_vendor = FormFutura
|
||||||
|
filament_cost = 26.65
|
||||||
|
filament_notes = "ReForm rPET is a recycled PETG type of 3D printer filament that is made from post-industrial waste streams of a nearby located plastic bottle manufacturer.\n\nhttps://www.formfutura.com/shop/product/reform-rpet-2836"
|
||||||
|
filament_spool_weight = 176
|
||||||
|
|
||||||
|
[filament:Janbex transparent PETG @MEGA]
|
||||||
|
inherits = *PETG_mega*
|
||||||
|
filament_vendor = Janbex
|
||||||
|
filament_cost = 31.99
|
||||||
|
filament_spool_weight = 222
|
||||||
|
first_layer_temperature = 215
|
||||||
|
min_fan_speed = 100
|
||||||
|
temperature = 210
|
||||||
|
|
||||||
[filament:*PLA_mega*]
|
[filament:*PLA_mega*]
|
||||||
inherits = *common_mega*
|
inherits = *common_mega*
|
||||||
bed_temperature = 60
|
bed_temperature = 60
|
||||||
disable_fan_first_layers = 1
|
disable_fan_first_layers = 1
|
||||||
|
filament_colour = #FF3232
|
||||||
filament_cost = 25.40
|
filament_cost = 25.40
|
||||||
filament_density = 1.24
|
filament_density = 1.24
|
||||||
filament_max_volumetric_speed = 10
|
filament_max_volumetric_speed = 10
|
||||||
first_layer_bed_temperature = 60
|
first_layer_bed_temperature = 65
|
||||||
first_layer_temperature = 215
|
first_layer_temperature = 215
|
||||||
min_fan_speed = 100
|
min_fan_speed = 100
|
||||||
temperature = 210
|
temperature = 210
|
||||||
|
@ -1012,73 +1104,97 @@ temperature = 210
|
||||||
[filament:Generic PLA @MEGA]
|
[filament:Generic PLA @MEGA]
|
||||||
inherits = *PLA_mega*
|
inherits = *PLA_mega*
|
||||||
|
|
||||||
[filament:*3Dmensionals PLA_mega*]
|
[filament:3Dmensionals PLA @MEGA]
|
||||||
inherits = *PLA_mega*
|
inherits = *PLA_mega*
|
||||||
filament_vendor = 3Dmensionals
|
filament_vendor = 3Dmensionals
|
||||||
filament_cost = 23.35
|
filament_cost = 22.90
|
||||||
|
filament_notes = "Das 3DFilaments - PLA von 3Dmensionals ist ein sehr leicht zu druckendes 3D-Drucker Filament. Dabei handelt es sich um ein etwas härteres PLA mit einer exzellenten thermischen Stabilität. Das Filament zeichnet sich vor allem durch verzugfreies 3D-Drucken aus und weist minimale bis keine Verformung nach dem Abkühlen auf. Daher ist es besonders gut für den Druck größerer Objekte geeignet. Zudem bietet 3DFilaments - PLA über die gesamte Fadenläge eine hervorragende Durchmesser- und Rundheitstoleranz.\n\nhttps://www.3dmensionals.de/3dfilaments?number=PSU3DM001V"
|
||||||
|
|
||||||
[filament:3Dmensionals PLA @MEGA]
|
[filament:3D Warhorse PLA @MEGA]
|
||||||
inherits = *3Dmensionals PLA_mega*
|
inherits = *PLA_mega*
|
||||||
|
filament_vendor = 3D Warhorse
|
||||||
|
filament_cost = 19.99
|
||||||
|
|
||||||
[filament:3Dmensionals PLA blue @MEGA]
|
[filament:AMOLEN wood PLA]
|
||||||
inherits = *3Dmensionals PLA_mega*
|
inherits = *PLA_mega*
|
||||||
filament_colour = #4155FB
|
filament_vendor = AMOLEN
|
||||||
|
compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and printer_notes=~/.*PRINTER_MODEL_I3_MEGA.*/
|
||||||
|
extrusion_multiplier = 1.1
|
||||||
|
filament_colour = #DFC287
|
||||||
|
filament_cost = 33.99
|
||||||
|
filament_density = 1.23
|
||||||
|
filament_max_volumetric_speed = 9
|
||||||
|
filament_notes = "https://amolen.com/collections/wood/products/amolen-pla-filament-1-75mm-wood-color-3d-printer-filament-1kg2-2lb"
|
||||||
|
|
||||||
[filament:3Dmensionals PLA silver @MEGA]
|
[filament:FormFutura EasyFil PLA @MEGA]
|
||||||
inherits = *3Dmensionals PLA_mega*
|
inherits = *PLA_mega*
|
||||||
filament_colour = #B9B5B4
|
filament_vendor = FormFutura
|
||||||
|
filament_cost = 39.93
|
||||||
|
filament_notes = "EasyFil PLA is an easy to print PLA type of 3D printer filament that is available in a wide variety of colors. Its improved flowing behavior make 3D printed layers flow more into each other.\n\nhttps://www.formfutura.com/shop/product/easyfil-pla-2801"
|
||||||
|
|
||||||
[filament:3Dmensionals PLA white @MEGA]
|
[filament:FormFutura ReForm rPLA @MEGA]
|
||||||
inherits = *3Dmensionals PLA_mega*
|
inherits = *PLA_mega*
|
||||||
filament_colour = #FEFEFD
|
filament_vendor = FormFutura
|
||||||
|
filament_cost = 26.65
|
||||||
|
filament_notes = "ReForm is a sustainable initiative within Formfutura to efficiently manage residual extrusion waste streams and re-use them into high-end upcycled filaments. The ideology behind ReForm is to a make 3D printing more sustainable – without having to make compromises on material properties – and yet keep it affordable.\n\nhttps://www.formfutura.com/shop/product/reform-rpla-2838"
|
||||||
|
|
||||||
[filament:*Verbatim PLA_mega*]
|
[filament:GIANTARM PLA @MEGA]
|
||||||
|
inherits = *PLA_mega*
|
||||||
|
filament_vendor = GIANTARM
|
||||||
|
filament_cost = 24.99
|
||||||
|
|
||||||
|
[filament:Prusament PLA @MEGA]
|
||||||
|
inherits = *PLA_mega*
|
||||||
|
filament_vendor = Prusa Polymers
|
||||||
|
filament_cost = 30.24
|
||||||
|
filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa"
|
||||||
|
filament_spool_weight = 201
|
||||||
|
temperature = 215
|
||||||
|
|
||||||
|
[filament:Verbatim PLA @MEGA]
|
||||||
inherits = *PLA_mega*
|
inherits = *PLA_mega*
|
||||||
filament_vendor = Verbatim
|
filament_vendor = Verbatim
|
||||||
filament_cost = 23.88
|
filament_cost = 23.88
|
||||||
|
|
||||||
[filament:Verbatim PLA @MEGA]
|
|
||||||
inherits = *Verbatim PLA_mega*
|
|
||||||
|
|
||||||
[filament:Verbatim PLA black @MEGA]
|
|
||||||
inherits = *Verbatim PLA_mega*
|
|
||||||
filament_colour = #333333
|
|
||||||
|
|
||||||
[printer:*common_mega*]
|
[printer:*common_mega*]
|
||||||
printer_technology = FFF
|
printer_technology = FFF
|
||||||
bed_shape = 0x0,210x0,210x210,0x210
|
bed_shape = 0x0,210x0,210x210,0x210
|
||||||
before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]
|
before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]
|
||||||
default_filament_profile = Generic PLA @MEGA
|
default_filament_profile = Generic PLA @MEGA
|
||||||
default_print_profile = 0.15mm QUALITY @MEGA
|
default_print_profile = 0.15mm QUALITY @MEGA
|
||||||
deretract_speed = 50
|
deretract_speed = 40
|
||||||
end_gcode = G4 ; wait\nG92 E0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; move print head up\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors
|
end_gcode = G1 E-1.0 F2100 ; retract\nG92 E0.0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; move print head up\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y105 F3000 ; park print head\nM84 ; disable motors
|
||||||
extruder_colour = #808080
|
extruder_colour = #808080
|
||||||
gcode_flavor = marlin
|
gcode_flavor = marlin
|
||||||
layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
|
layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
|
||||||
max_layer_height = 0.36
|
max_layer_height = 0.36
|
||||||
max_print_height = 205
|
max_print_height = 205
|
||||||
|
remaining_times = 1
|
||||||
|
retract_before_travel = 1.5
|
||||||
retract_before_wipe = 60%
|
retract_before_wipe = 60%
|
||||||
retract_layer_change = 1
|
retract_layer_change = 1
|
||||||
retract_length = 6
|
retract_length = 3.2
|
||||||
retract_lift = 0.075
|
retract_lift = 0.2
|
||||||
retract_lift_below = 204
|
retract_lift_below = 204
|
||||||
|
retract_speed = 70
|
||||||
silent_mode = 0
|
silent_mode = 0
|
||||||
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG1 Y0 Z1 F100 ; move print head up\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG92 E0\nG1 Z0.2 F360\nG1 X60 E9 F700 ; intro line\nG1 X100 E12.5 F700 ; intro line\nG92 E0
|
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG1 Y2.0 Z0.2 F1000 ; move print head up\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG92 E0.0\nG1 X60.0 E9.0 F1000 ; intro line\nG1 X100.0 E12.5 F1000 ; intro line\nG92 E0.0
|
||||||
|
thumbnails = 16x16,220x124
|
||||||
use_relative_e_distances = 1
|
use_relative_e_distances = 1
|
||||||
wipe = 1
|
wipe = 1
|
||||||
machine_max_acceleration_e = 5000
|
machine_max_acceleration_e = 10000
|
||||||
machine_max_acceleration_extruding = 1250
|
machine_max_acceleration_extruding = 1250
|
||||||
machine_max_acceleration_retracting = 1250
|
machine_max_acceleration_retracting = 1250
|
||||||
machine_max_acceleration_x = 1000
|
machine_max_acceleration_x = 3000
|
||||||
machine_max_acceleration_y = 1000
|
machine_max_acceleration_y = 2000
|
||||||
machine_max_acceleration_z = 200
|
machine_max_acceleration_z = 60
|
||||||
machine_max_feedrate_e = 60
|
machine_max_feedrate_e = 60
|
||||||
machine_max_feedrate_x = 200
|
machine_max_feedrate_x = 500
|
||||||
machine_max_feedrate_y = 200
|
machine_max_feedrate_y = 500
|
||||||
machine_max_feedrate_z = 6
|
machine_max_feedrate_z = 6
|
||||||
machine_max_jerk_e = 5
|
machine_max_jerk_e = 5
|
||||||
machine_max_jerk_x = 8
|
machine_max_jerk_x = 10
|
||||||
machine_max_jerk_y = 8
|
machine_max_jerk_y = 10
|
||||||
machine_max_jerk_z = 0.4
|
machine_max_jerk_z = 0.4
|
||||||
|
|
||||||
[printer:Anycubic i3 Mega]
|
[printer:Anycubic i3 Mega]
|
||||||
|
@ -1092,6 +1208,7 @@ inherits = *common_mega*
|
||||||
printer_model = I3MEGAS
|
printer_model = I3MEGAS
|
||||||
printer_variant = 0.4
|
printer_variant = 0.4
|
||||||
printer_notes = Do not 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_ANYCUBIC\nPRINTER_MODEL_I3_MEGA_S\nPRINTER_HAS_BOWDEN
|
printer_notes = Do not 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_ANYCUBIC\nPRINTER_MODEL_I3_MEGA_S\nPRINTER_HAS_BOWDEN
|
||||||
|
machine_max_feedrate_e = 30
|
||||||
machine_max_feedrate_z = 8
|
machine_max_feedrate_z = 8
|
||||||
|
|
||||||
|
|
||||||
|
@ -1743,7 +1860,7 @@ machine_max_jerk_z = 5
|
||||||
machine_min_extruding_rate = 0
|
machine_min_extruding_rate = 0
|
||||||
machine_min_travel_rate = 0
|
machine_min_travel_rate = 0
|
||||||
printer_settings_id =
|
printer_settings_id =
|
||||||
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_ANYCUBIC\nPRINTER_MODEL_PREDATOR\nPRINTER_HAS_BOWDEN\n
|
printer_notes = Do not 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_ANYCUBIC\nPRINTER_MODEL_PREDATOR\nPRINTER_HAS_BOWDEN\n
|
||||||
default_filament_profile = Generic PLA @PREDATOR
|
default_filament_profile = Generic PLA @PREDATOR
|
||||||
|
|
||||||
[printer:Anycubic Predator 0.4 nozzle]
|
[printer:Anycubic Predator 0.4 nozzle]
|
||||||
|
@ -1775,4 +1892,4 @@ default_print_profile = 0.24mm 0.8 nozzle DETAILED QUALITY @PREDATOR
|
||||||
|
|
||||||
#########################################
|
#########################################
|
||||||
########## end printer presets ##########
|
########## end printer presets ##########
|
||||||
#########################################
|
#########################################"do not" cause ' is bad for syntax highlighting
|
||||||
|
|
561
resources/profiles/Anycubic/i3megas.svg
Normal file
|
@ -0,0 +1,561 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="210.5mm"
|
||||||
|
height="210.5mm"
|
||||||
|
viewBox="0 0 210.5 210.5"
|
||||||
|
version="1.1"
|
||||||
|
id="svg886"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||||
|
sodipodi:docname="ai3m.svg">
|
||||||
|
<defs
|
||||||
|
id="defs880" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#7670ff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.70710678"
|
||||||
|
inkscape:cx="466.73093"
|
||||||
|
inkscape:cy="380.93745"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:lockguides="false"
|
||||||
|
showguides="false"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="1912"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata883">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer3"
|
||||||
|
inkscape:label="Layer 2"
|
||||||
|
transform="translate(0,-86.5)"
|
||||||
|
style="display:inline"
|
||||||
|
sodipodi:insensitive="true">
|
||||||
|
<path
|
||||||
|
id="path869"
|
||||||
|
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.04216461;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 167.32704,288.75984 v -3.83255 h 1.45715 v 7.07119 l -6.06232,-5.36476 v -1.94915 z m -9.42165,-2.52278 1.54352,2.96287 h -0.60107 l -0.76147,1.4617 h 2.12401 l 0.6004,1.1525 h 1.65752 l -3.73414,-7.16792 z m 44.62362,4.25408 v 1.50745 c 0.98166,-0.11796 1.8734,-0.62934 2.47099,-1.41702 l -1.14996,-0.94952 c -0.31636,0.44259 -0.78818,0.74942 -1.32103,0.85909 z m -40.17486,-27.16603 11.53897,-20.77294 18.70747,18.05526 -17.35981,21.92818 z m -5.69662,28.48902 1.6624,-3.19108 -0.82877,-1.59087 L 155,291.81413 Z m 22.56867,-7.05936 c 0.97028,0.11659 1.8532,0.61761 2.4509,1.39077 l -1.16155,0.93258 c -0.31614,-0.41985 -0.77457,-0.70996 -1.28935,-0.81591 z m 3.41542,0.17252 h 1.46761 v 4.19716 c 0,0.59031 0.3725,1.11637 0.92932,1.3124 v 1.50898 c -1.38222,-0.22635 -2.39693,-1.42074 -2.39693,-2.82138 z m 8.44048,6.88684 v -6.88684 h -1.43359 v 6.88684 z m 1.73019,-4.18512 c 0.35459,0 0.64204,-0.28746 0.64204,-0.64204 0,-0.35459 -0.28745,-0.64204 -0.64204,-0.64204 h -0.8869 v -1.41764 h 0.8869 c 1.13753,0 2.05968,0.92215 2.05968,2.05968 0,1.13753 -0.92215,2.05968 -2.05968,2.05968 h -0.8869 l -0.004,-1.41764 z m -30.09042,4.18512 h 1.49929 v -2.7357 l -1.49929,-1.32677 z m 33.23702,0 h 1.43359 v -6.88684 h -1.43359 z m -6.61958,-43.20436 -15.24232,-6.09042 18.63476,17.98509 11.51531,1.11097 z m -18.15413,43.20436 v -3.62964 l 2.39506,-3.2572 h 1.87519 l -2.78508,3.78762 v 3.09922 z m 0.39556,-5.55407 -0.92997,1.26472 -1.81565,-2.59749 h 1.814 z m 21.17859,-25.58701 11.46398,1.10603 -13.7034,15.36187 -15.13578,5.47973 z m 7.21757,28.12689 c 0.17089,0.85467 0.83896,1.52274 1.69364,1.69363 v 1.50644 c -1.6794,-0.19619 -3.0039,-1.52068 -3.20008,-3.20007 -0.23374,-2.00112 1.19897,-3.81283 3.20008,-4.04658 v 1.50643 c -1.16914,0.23375 -1.92739,1.37102 -1.69364,2.54015 z m -5.04526,0.93674 c 0,-0.30809 -0.0685,-0.61233 -0.20062,-0.89067 -0.35104,0.36232 -0.79749,0.61783 -1.28769,0.73699 0.0131,0.0502 0.0197,0.10183 0.0197,0.15368 0,0.33625 -0.2726,0.60885 -0.60885,0.60885 h -0.92882 v 1.4686 l 0.92882,-10e-6 c 1.14733,0 2.07744,-0.9301 2.07744,-2.07744 z m -14.38439,-0.10463 1.14995,0.94952 c -0.5976,0.78768 -1.48934,1.29906 -2.471,1.41702 v -1.50745 c 0.53286,-0.10967 1.00468,-0.4165 1.32105,-0.85909 z m -2.17951,0.86152 c -0.85468,-0.17089 -1.52275,-0.83896 -1.69364,-1.69363 -0.23376,-1.16913 0.52451,-2.3064 1.69364,-2.54015 v -1.50643 c -2.00111,0.23375 -3.43383,2.04546 -3.20007,4.04658 0.19617,1.67939 1.52067,3.00388 3.20007,3.20007 z m 9.99181,-1.36912 v -4.19716 h -1.46761 v 4.19716 c 0,0.62159 -0.41231,1.16778 -1.01011,1.3381 v 1.49533 c 1.41883,-0.19091 2.47772,-1.40182 2.47772,-2.83343 z m 14.16946,-2.86224 v -1.50744 c 0.97027,0.11659 1.85319,0.61761 2.45089,1.39077 l -1.16154,0.93258 c -0.31614,-0.41985 -0.77458,-0.70996 -1.28935,-0.81591 z"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccsccccscccccccccccccccccccccccccccccccccccccccccccsccsccccscccccccccccccccccccccccc" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
transform="translate(0,-86.5)"
|
||||||
|
style="display:none">
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.68079633,77.180801 H 219.81921"
|
||||||
|
id="path1596"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,77.180801 V 296.31918"
|
||||||
|
id="path1594"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,296.31918 H 0.68079633"
|
||||||
|
id="path1592"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.68079633,296.31918 V 77.180801"
|
||||||
|
id="rect1544"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
id="path5301"
|
||||||
|
d="M 9.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 19.681,296.31918 V 77.180801"
|
||||||
|
id="path5303" />
|
||||||
|
<path
|
||||||
|
id="path5305"
|
||||||
|
d="M 29.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 39.681,296.31918 V 77.180801"
|
||||||
|
id="path5307" />
|
||||||
|
<path
|
||||||
|
id="path5309"
|
||||||
|
d="M 49.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 59.681,296.31918 V 77.180801"
|
||||||
|
id="path5311" />
|
||||||
|
<path
|
||||||
|
id="path5313"
|
||||||
|
d="M 69.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 79.681,296.31918 V 77.180801"
|
||||||
|
id="path5315" />
|
||||||
|
<path
|
||||||
|
id="path5317"
|
||||||
|
d="M 89.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 99.681,296.31918 V 77.180801"
|
||||||
|
id="path5319" />
|
||||||
|
<path
|
||||||
|
id="path5321"
|
||||||
|
d="M 109.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 119.681,296.31918 V 77.180801"
|
||||||
|
id="path5323" />
|
||||||
|
<path
|
||||||
|
id="path5325"
|
||||||
|
d="M 129.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 139.681,296.31918 V 77.180801"
|
||||||
|
id="path5327" />
|
||||||
|
<path
|
||||||
|
id="path5329"
|
||||||
|
d="M 149.681,296.31918 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 159.681,296.31918 V 77.180801"
|
||||||
|
id="path5331" />
|
||||||
|
<path
|
||||||
|
id="path5333"
|
||||||
|
d="m 169.681,296.31918 v -3.0895 m 0,-10.12031 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 179.681,296.31918 v -2.82492 m 0,-10.18645 v -6.87917 m 0,-28.50885 V 77.180801"
|
||||||
|
id="path5335"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
id="path5337"
|
||||||
|
d="m 189.681,296.31918 v -2.95721 m 0,-50.37005 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 199.681,296.31918 v -3.15564 m 0,-9.72344 v -4.69636 m 0,-30.8901 V 77.180801"
|
||||||
|
id="path5339"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
id="path5341"
|
||||||
|
d="m 209.681,296.31918 v -2.89106 m 0,-10.25261 v -14.61822 m 0,-12.76615 V 77.180801"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
id="path5343"
|
||||||
|
d="m 219.81921,287.319 h -3.39004 m -51.52761,0 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 219.81921,277.319 h -18.00827 m -21.36511,0 H 0.68079633"
|
||||||
|
id="path5345"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
id="path5347"
|
||||||
|
d="m 219.81921,267.319 h -8.94629 m -36.90938,0 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 219.81921,257.319 h -8.74786 m -36.90937,0 H 0.68079633"
|
||||||
|
id="path5349"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
id="path5351"
|
||||||
|
d="m 219.81921,247.319 h -21.44786 m -18.12395,0 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,237.319 H 0.68079633"
|
||||||
|
id="path5353" />
|
||||||
|
<path
|
||||||
|
id="path5355"
|
||||||
|
d="M 219.81921,227.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,217.319 H 0.68079633"
|
||||||
|
id="path5357" />
|
||||||
|
<path
|
||||||
|
id="path5359"
|
||||||
|
d="M 219.81921,207.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,197.319 H 0.68079633"
|
||||||
|
id="path5361" />
|
||||||
|
<path
|
||||||
|
id="path5363"
|
||||||
|
d="M 219.81921,187.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,177.319 H 0.68079633"
|
||||||
|
id="path5365" />
|
||||||
|
<path
|
||||||
|
id="path5367"
|
||||||
|
d="M 219.81921,167.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,157.319 H 0.68079633"
|
||||||
|
id="path5369" />
|
||||||
|
<path
|
||||||
|
id="path5371"
|
||||||
|
d="M 219.81921,147.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,137.319 H 0.68079633"
|
||||||
|
id="path5373" />
|
||||||
|
<path
|
||||||
|
id="path5375"
|
||||||
|
d="M 219.81921,127.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,117.319 H 0.68079633"
|
||||||
|
id="path5377" />
|
||||||
|
<path
|
||||||
|
id="path5379"
|
||||||
|
d="M 219.81921,107.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 219.81921,97.319 H 0.68079633"
|
||||||
|
id="path5381" />
|
||||||
|
<path
|
||||||
|
id="path5383"
|
||||||
|
d="M 219.81921,87.319 H 0.68079633"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 3"
|
||||||
|
style="display:inline">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 0.25,205.25001 h 152.88208 m 53.78799,0 h 3.32996"
|
||||||
|
id="path973"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 145.25002,210.25 V 0.25000128"
|
||||||
|
id="path971"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 205.25001,210.25 v -2.79018 m 0,-10.89792 V 0.25000128"
|
||||||
|
id="path969"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,15.250006 H 210.25003"
|
||||||
|
id="path967"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,155.25001 H 210.25003"
|
||||||
|
id="path965"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 55.249995,210.25 V 0.25000128"
|
||||||
|
id="path963"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 0.25,175.25 h 160.97366 m 43.87229,0 h 5.15408"
|
||||||
|
id="path961"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 125.25003,210.25 V 0.25000128"
|
||||||
|
id="path959"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,35.250001 H 210.25003"
|
||||||
|
id="path957"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 195.25003,210.25 v -3.02405 m 0,-10.68744 0,-10.52373 m 0,-19.79114 0,-165.97363872"
|
||||||
|
id="path955"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 35.25,210.25 V 0.25000128"
|
||||||
|
id="path953"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 5.2500251,210.25 V 0.25000128"
|
||||||
|
id="path951"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,25.249986 H 210.25003"
|
||||||
|
id="path949"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,105.25 H 210.25003"
|
||||||
|
id="path947"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 105.25004,210.25 V 0.25000128"
|
||||||
|
id="path945"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,55.249996 H 210.25003"
|
||||||
|
id="path943"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 185.25001,210.25 v -3.02405 m 0,-10.73421 v -2.8531 m 0,-34.30738 V 0.25000128"
|
||||||
|
id="path941"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 175.25,210.25 v -3.11759 m 0,-51.39092 V 0.25000128"
|
||||||
|
id="path939"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 15.250005,210.25 V 0.25000128"
|
||||||
|
id="path937"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,125.25 H 210.25003"
|
||||||
|
id="path935"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 85.250005,210.25 V 0.25000128"
|
||||||
|
id="path933"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,75.249991 H 210.25003"
|
||||||
|
id="path931"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 155.25,210.25 v -3.02405 m 0,-7.39 V 0.25000128"
|
||||||
|
id="path929"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,0.25000128 V 210.25"
|
||||||
|
id="path927"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,5.2499912 H 210.25003"
|
||||||
|
id="path925"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,145.24999 H 210.25003"
|
||||||
|
id="path923"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 65.25001,210.25 V 0.25000128"
|
||||||
|
id="path921"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,95.250021 H 210.25003"
|
||||||
|
id="path919"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 165.25002,210.25 v -2.79018 m 0,-10.4302 v -13.18975 m 0,-14.82678 V 0.25000128"
|
||||||
|
id="path917"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 135.25001,210.25 V 0.25000128"
|
||||||
|
id="path915"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 210.25003,0.25000128 H 0.25"
|
||||||
|
id="path913"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 0.25,165.25002 h 166.9605 m 26.98754,0 h 16.05199"
|
||||||
|
id="path911"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 45.250015,210.25 V 0.25000128"
|
||||||
|
id="path909"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 115.25001,210.25 V 0.25000128"
|
||||||
|
id="path907"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,45.249981 H 210.25003"
|
||||||
|
id="path905"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 210.25003,210.25 V 0.25000128"
|
||||||
|
id="path903"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 25.25002,210.25 V 0.25000128"
|
||||||
|
id="path901"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 0.25,185.25002 h 166.25892 m 30.26159,0 h 13.47952"
|
||||||
|
id="path899"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,115.25002 H 210.25003"
|
||||||
|
id="path897"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 95.25002,210.25 V 0.25000128"
|
||||||
|
id="path895"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,65.250011 H 210.25003"
|
||||||
|
id="path893"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,210.25 H 210.25003"
|
||||||
|
id="path891"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,85.250006 H 210.25003"
|
||||||
|
id="path889"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 0.25,195.25 h 172.9694 m 6.46576,0 h 30.56487"
|
||||||
|
id="path887"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.25,135.25001 H 210.25003"
|
||||||
|
id="path885"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 75.250025,210.25 V 0.25000128"
|
||||||
|
id="path875"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 30 KiB |
BIN
resources/profiles/Anycubic/i3megas_bed.stl
Normal file
|
@ -1,2 +1,2 @@
|
||||||
min_slic3r_version = 2.4.0-alpha0
|
min_slic3r_version = 2.3.1-beta
|
||||||
0.0.1 Initial Artillery bundle
|
0.0.1 Initial Artillery bundle
|
||||||
|
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
@ -1,3 +1,6 @@
|
||||||
|
min_slic3r_version = 2.3.1-beta
|
||||||
|
0.0.16 Updated CR6-SE start g-code. Added and updated filament profiles.
|
||||||
|
0.0.15 Added new printer models, filament profiles. Various improvements.
|
||||||
min_slic3r_version = 2.3.0-rc2
|
min_slic3r_version = 2.3.0-rc2
|
||||||
0.0.14 Optimized start g-code. Added filament profile. Various improvements.
|
0.0.14 Optimized start g-code. Added filament profile. Various improvements.
|
||||||
0.0.13 Optimized start and end g-code. General improvements.
|
0.0.13 Optimized start and end g-code. General improvements.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
name = Creality
|
name = Creality
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# 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.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.0.14
|
config_version = 0.0.16
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
@ -21,7 +21,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = ender3.svg
|
bed_texture = ender3.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER3BLTOUCH]
|
[printer_model:ENDER3BLTOUCH]
|
||||||
name = Creality Ender-3 BLTouch
|
name = Creality Ender-3 BLTouch
|
||||||
|
@ -30,7 +30,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = ender3.svg
|
bed_texture = ender3.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER3V2]
|
[printer_model:ENDER3V2]
|
||||||
name = Creality Ender-3 V2
|
name = Creality Ender-3 V2
|
||||||
|
@ -39,7 +39,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3v2_bed.stl
|
bed_model = ender3v2_bed.stl
|
||||||
bed_texture = ender3v2.svg
|
bed_texture = ender3v2.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER3MAX]
|
[printer_model:ENDER3MAX]
|
||||||
name = Creality Ender-3 Max
|
name = Creality Ender-3 Max
|
||||||
|
@ -48,7 +48,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10spro.svg
|
bed_texture = cr10spro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER4]
|
[printer_model:ENDER4]
|
||||||
name = Creality Ender-4
|
name = Creality Ender-4
|
||||||
|
@ -57,7 +57,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3v2_bed.stl
|
bed_model = ender3v2_bed.stl
|
||||||
bed_texture = ender3v2.svg
|
bed_texture = ender3v2.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER5]
|
[printer_model:ENDER5]
|
||||||
name = Creality Ender-5
|
name = Creality Ender-5
|
||||||
|
@ -66,7 +66,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = ender3.svg
|
bed_texture = ender3.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER5PLUS]
|
[printer_model:ENDER5PLUS]
|
||||||
name = Creality Ender-5 Plus
|
name = Creality Ender-5 Plus
|
||||||
|
@ -75,7 +75,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender5plus_bed.stl
|
bed_model = ender5plus_bed.stl
|
||||||
bed_texture = ender5plus.svg
|
bed_texture = ender5plus.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER6]
|
[printer_model:ENDER6]
|
||||||
name = Creality Ender-6
|
name = Creality Ender-6
|
||||||
|
@ -84,7 +84,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender6_bed.stl
|
bed_model = ender6_bed.stl
|
||||||
bed_texture = ender6.svg
|
bed_texture = ender6.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER2]
|
[printer_model:ENDER2]
|
||||||
name = Creality Ender-2
|
name = Creality Ender-2
|
||||||
|
@ -93,7 +93,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender2_bed.stl
|
bed_model = ender2_bed.stl
|
||||||
bed_texture = ender2.svg
|
bed_texture = ender2.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR5PRO]
|
[printer_model:CR5PRO]
|
||||||
name = Creality CR-5 Pro
|
name = Creality CR-5 Pro
|
||||||
|
@ -102,7 +102,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr5pro_bed.stl
|
bed_model = cr5pro_bed.stl
|
||||||
bed_texture = cr5pro.svg
|
bed_texture = cr5pro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR5PROH]
|
[printer_model:CR5PROH]
|
||||||
name = Creality CR-5 Pro H
|
name = Creality CR-5 Pro H
|
||||||
|
@ -111,7 +111,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr5pro_bed.stl
|
bed_model = cr5pro_bed.stl
|
||||||
bed_texture = cr5pro.svg
|
bed_texture = cr5pro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR6SE]
|
[printer_model:CR6SE]
|
||||||
name = Creality CR-6 SE
|
name = Creality CR-6 SE
|
||||||
|
@ -120,7 +120,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr6se_bed.stl
|
bed_model = cr6se_bed.stl
|
||||||
bed_texture = cr6se.svg
|
bed_texture = cr6se.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR6MAX]
|
[printer_model:CR6MAX]
|
||||||
name = Creality CR-6 Max
|
name = Creality CR-6 Max
|
||||||
|
@ -129,7 +129,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10s4_bed.stl
|
bed_model = cr10s4_bed.stl
|
||||||
bed_texture = cr10s4.svg
|
bed_texture = cr10s4.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10MINI]
|
[printer_model:CR10MINI]
|
||||||
name = Creality CR-10 Mini
|
name = Creality CR-10 Mini
|
||||||
|
@ -138,7 +138,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10mini_bed.stl
|
bed_model = cr10mini_bed.stl
|
||||||
bed_texture = cr10mini.svg
|
bed_texture = cr10mini.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10MAX]
|
[printer_model:CR10MAX]
|
||||||
name = Creality CR-10 Max
|
name = Creality CR-10 Max
|
||||||
|
@ -147,7 +147,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10max_bed.stl
|
bed_model = cr10max_bed.stl
|
||||||
bed_texture = cr10max.svg
|
bed_texture = cr10max.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10]
|
[printer_model:CR10]
|
||||||
name = Creality CR-10
|
name = Creality CR-10
|
||||||
|
@ -156,7 +156,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10_bed.stl
|
bed_model = cr10_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10V2]
|
[printer_model:CR10V2]
|
||||||
name = Creality CR-10 V2
|
name = Creality CR-10 V2
|
||||||
|
@ -165,7 +165,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10V3]
|
[printer_model:CR10V3]
|
||||||
name = Creality CR-10 V3
|
name = Creality CR-10 V3
|
||||||
|
@ -174,7 +174,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10S]
|
[printer_model:CR10S]
|
||||||
name = Creality CR-10 S
|
name = Creality CR-10 S
|
||||||
|
@ -183,7 +183,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10_bed.stl
|
bed_model = cr10_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10SPRO]
|
[printer_model:CR10SPRO]
|
||||||
name = Creality CR-10 S Pro
|
name = Creality CR-10 S Pro
|
||||||
|
@ -192,7 +192,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10spro.svg
|
bed_texture = cr10spro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10SPROV2]
|
[printer_model:CR10SPROV2]
|
||||||
name = Creality CR-10 S Pro V2
|
name = Creality CR-10 S Pro V2
|
||||||
|
@ -201,7 +201,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10S4]
|
[printer_model:CR10S4]
|
||||||
name = Creality CR-10 S4
|
name = Creality CR-10 S4
|
||||||
|
@ -210,7 +210,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10s4_bed.stl
|
bed_model = cr10s4_bed.stl
|
||||||
bed_texture = cr10s4.svg
|
bed_texture = cr10s4.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10S5]
|
[printer_model:CR10S5]
|
||||||
name = Creality CR-10 S5
|
name = Creality CR-10 S5
|
||||||
|
@ -219,7 +219,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10s5_bed.stl
|
bed_model = cr10s5_bed.stl
|
||||||
bed_texture = cr10s5.svg
|
bed_texture = cr10s5.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR20]
|
[printer_model:CR20]
|
||||||
name = Creality CR-20
|
name = Creality CR-20
|
||||||
|
@ -228,7 +228,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = cr20.svg
|
bed_texture = cr20.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR20PRO]
|
[printer_model:CR20PRO]
|
||||||
name = Creality CR-20 Pro
|
name = Creality CR-20 Pro
|
||||||
|
@ -237,7 +237,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = cr20.svg
|
bed_texture = cr20.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR200B]
|
[printer_model:CR200B]
|
||||||
name = Creality CR-200B
|
name = Creality CR-200B
|
||||||
|
@ -246,7 +246,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr200b_bed.stl
|
bed_model = cr200b_bed.stl
|
||||||
bed_texture = cr200b.svg
|
bed_texture = cr200b.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR8]
|
[printer_model:CR8]
|
||||||
name = Creality CR-8
|
name = Creality CR-8
|
||||||
|
@ -255,7 +255,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr8_bed.stl
|
bed_model = cr8_bed.stl
|
||||||
bed_texture = cr8.svg
|
bed_texture = cr8.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
#[printer_model:CRX]
|
#[printer_model:CRX]
|
||||||
#name = Creality CR-X
|
#name = Creality CR-X
|
||||||
|
@ -264,7 +264,7 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
|
||||||
#family = CR-X
|
#family = CR-X
|
||||||
#bed_model = cr10v2_bed.stl
|
#bed_model = cr10v2_bed.stl
|
||||||
#bed_texture = cr10spro.svg
|
#bed_texture = cr10spro.svg
|
||||||
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
#[printer_model:CRXPRO]
|
#[printer_model:CRXPRO]
|
||||||
#name = Creality CR-X Pro
|
#name = Creality CR-X Pro
|
||||||
|
@ -273,7 +273,7 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
|
||||||
#family = CR-X
|
#family = CR-X
|
||||||
#bed_model = cr10v2_bed.stl
|
#bed_model = cr10v2_bed.stl
|
||||||
#bed_texture = cr10spro.svg
|
#bed_texture = cr10spro.svg
|
||||||
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
|
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
||||||
# not make it into the user interface.
|
# not make it into the user interface.
|
||||||
|
@ -281,6 +281,7 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
|
||||||
# Common print preset
|
# Common print preset
|
||||||
[print:*common*]
|
[print:*common*]
|
||||||
avoid_crossing_perimeters = 0
|
avoid_crossing_perimeters = 0
|
||||||
|
bridge_acceleration = 250
|
||||||
bridge_angle = 0
|
bridge_angle = 0
|
||||||
bridge_flow_ratio = 0.95
|
bridge_flow_ratio = 0.95
|
||||||
bridge_speed = 25
|
bridge_speed = 25
|
||||||
|
@ -288,6 +289,7 @@ brim_width = 0
|
||||||
clip_multipart_objects = 1
|
clip_multipart_objects = 1
|
||||||
compatible_printers =
|
compatible_printers =
|
||||||
complete_objects = 0
|
complete_objects = 0
|
||||||
|
default_acceleration = 500
|
||||||
dont_support_bridges = 1
|
dont_support_bridges = 1
|
||||||
elefant_foot_compensation = 0.1
|
elefant_foot_compensation = 0.1
|
||||||
ensure_vertical_shell_thickness = 1
|
ensure_vertical_shell_thickness = 1
|
||||||
|
@ -383,6 +385,7 @@ layer_height = 0.08
|
||||||
perimeters = 3
|
perimeters = 3
|
||||||
bottom_solid_layers = 9
|
bottom_solid_layers = 9
|
||||||
top_solid_layers = 11
|
top_solid_layers = 11
|
||||||
|
bridge_flow_ratio = 0.70
|
||||||
|
|
||||||
[print:*0.10mm*]
|
[print:*0.10mm*]
|
||||||
inherits = *common*
|
inherits = *common*
|
||||||
|
@ -390,6 +393,7 @@ layer_height = 0.10
|
||||||
perimeters = 3
|
perimeters = 3
|
||||||
bottom_solid_layers = 7
|
bottom_solid_layers = 7
|
||||||
top_solid_layers = 9
|
top_solid_layers = 9
|
||||||
|
bridge_flow_ratio = 0.70
|
||||||
|
|
||||||
[print:*0.12mm*]
|
[print:*0.12mm*]
|
||||||
inherits = *common*
|
inherits = *common*
|
||||||
|
@ -397,12 +401,14 @@ layer_height = 0.12
|
||||||
perimeters = 3
|
perimeters = 3
|
||||||
bottom_solid_layers = 6
|
bottom_solid_layers = 6
|
||||||
top_solid_layers = 7
|
top_solid_layers = 7
|
||||||
|
bridge_flow_ratio = 0.70
|
||||||
|
|
||||||
[print:*0.16mm*]
|
[print:*0.16mm*]
|
||||||
inherits = *common*
|
inherits = *common*
|
||||||
layer_height = 0.16
|
layer_height = 0.16
|
||||||
bottom_solid_layers = 5
|
bottom_solid_layers = 5
|
||||||
top_solid_layers = 7
|
top_solid_layers = 7
|
||||||
|
bridge_flow_ratio = 0.85
|
||||||
|
|
||||||
[print:*0.20mm*]
|
[print:*0.20mm*]
|
||||||
inherits = *common*
|
inherits = *common*
|
||||||
|
@ -631,9 +637,11 @@ first_layer_bed_temperature = 60
|
||||||
filament_cost = 19.00
|
filament_cost = 19.00
|
||||||
filament_density = 1.24
|
filament_density = 1.24
|
||||||
filament_colour = #FF0000
|
filament_colour = #FF0000
|
||||||
|
filament_spool_weight = 256
|
||||||
|
|
||||||
[filament:Devil Design PLA (Galaxy) @CREALITY]
|
[filament:Devil Design PLA Galaxy @CREALITY]
|
||||||
inherits = *PLA*
|
inherits = *PLA*
|
||||||
|
renamed_from = "Devil Design PLA (Galaxy) @CREALITY"
|
||||||
filament_vendor = Devil Design
|
filament_vendor = Devil Design
|
||||||
temperature = 225
|
temperature = 225
|
||||||
bed_temperature = 65
|
bed_temperature = 65
|
||||||
|
@ -642,6 +650,7 @@ first_layer_bed_temperature = 65
|
||||||
filament_cost = 19.00
|
filament_cost = 19.00
|
||||||
filament_density = 1.24
|
filament_density = 1.24
|
||||||
filament_colour = #FF0000
|
filament_colour = #FF0000
|
||||||
|
filament_spool_weight = 256
|
||||||
|
|
||||||
[filament:Extrudr PLA NX2 @CREALITY]
|
[filament:Extrudr PLA NX2 @CREALITY]
|
||||||
inherits = *PLA*
|
inherits = *PLA*
|
||||||
|
@ -700,6 +709,40 @@ filament_density = 1.24
|
||||||
filament_colour = #125467
|
filament_colour = #125467
|
||||||
filament_spool_weight = 238
|
filament_spool_weight = 238
|
||||||
|
|
||||||
|
[filament:3DJAKE ecoPLA Matt @CREALITY]
|
||||||
|
inherits = *PLA*
|
||||||
|
filament_vendor = 3DJAKE
|
||||||
|
temperature = 195
|
||||||
|
bed_temperature = 60
|
||||||
|
first_layer_temperature = 195
|
||||||
|
first_layer_bed_temperature = 60
|
||||||
|
filament_cost = 24.99
|
||||||
|
filament_density = 1.38
|
||||||
|
filament_colour = #125467
|
||||||
|
filament_spool_weight = 238
|
||||||
|
|
||||||
|
[filament:3DJAKE ecoPLA Tough @CREALITY]
|
||||||
|
inherits = *PLA*
|
||||||
|
filament_vendor = 3DJAKE
|
||||||
|
temperature = 215
|
||||||
|
bed_temperature = 60
|
||||||
|
first_layer_temperature = 215
|
||||||
|
first_layer_bed_temperature = 60
|
||||||
|
filament_cost = 29.99
|
||||||
|
filament_density = 1.21
|
||||||
|
filament_colour = #125467
|
||||||
|
|
||||||
|
[filament:FormFutura Tough PLA @CREALITY]
|
||||||
|
inherits = *PLA*
|
||||||
|
filament_vendor = FormFutura
|
||||||
|
temperature = 215
|
||||||
|
bed_temperature = 60
|
||||||
|
first_layer_temperature = 215
|
||||||
|
first_layer_bed_temperature = 60
|
||||||
|
filament_cost = 46.65
|
||||||
|
filament_density = 1.21
|
||||||
|
filament_colour = #ed000e
|
||||||
|
|
||||||
[filament:123-3D Jupiter PLA @CREALITY]
|
[filament:123-3D Jupiter PLA @CREALITY]
|
||||||
inherits = *PLA*
|
inherits = *PLA*
|
||||||
filament_vendor = 123-3D
|
filament_vendor = 123-3D
|
||||||
|
@ -926,7 +969,7 @@ printer_model = CR5PROH
|
||||||
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_CREALITY\nPRINTER_MODEL_CR5PROH\nPRINTER_HAS_BOWDEN
|
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_CREALITY\nPRINTER_MODEL_CR5PROH\nPRINTER_HAS_BOWDEN
|
||||||
|
|
||||||
[printer:Creality CR-6 SE]
|
[printer:Creality CR-6 SE]
|
||||||
inherits = *common*; *fastabl*; *pauseprint*
|
inherits = *common*; *pauseprint*
|
||||||
bed_shape = 5x0,230x0,230x235,5x235
|
bed_shape = 5x0,230x0,230x235,5x235
|
||||||
printer_model = CR6SE
|
printer_model = CR6SE
|
||||||
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_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN
|
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_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
min_slic3r_version = 2.4.0-alpha0
|
min_slic3r_version = 2.3.1-beta
|
||||||
0.0.1 Initial version
|
0.0.1 Initial version
|
||||||
|
0.0.2 Improved start gcode, changed filename format
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
[vendor]
|
[vendor]
|
||||||
# Vendor name will be shown by the Config Wizard.
|
# Vendor name will be shown by the Config Wizard.
|
||||||
name = INAT
|
name = INAT
|
||||||
config_version = 0.0.1
|
config_version = 0.0.2
|
||||||
config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/INAT/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/INAT/
|
||||||
|
|
||||||
###
|
###
|
||||||
### PRINTER LIST
|
### PRINTER LIST
|
||||||
|
@ -133,7 +133,7 @@ extruder_clearance_radius = 85
|
||||||
extruder_clearance_height = 34
|
extruder_clearance_height = 34
|
||||||
gcode_comments = 0
|
gcode_comments = 0
|
||||||
gcode_label_objects = 0
|
gcode_label_objects = 0
|
||||||
output_filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gcode
|
output_filename_format = {input_filename_base}_{filament_type[0]}.gcode
|
||||||
|
|
||||||
|
|
||||||
[print:0.2mm Standard @PROTON_X]
|
[print:0.2mm Standard @PROTON_X]
|
||||||
|
@ -193,7 +193,7 @@ use_firmware_retraction = 0
|
||||||
use_volumetric_e = 0
|
use_volumetric_e = 0
|
||||||
variable_layer_height = 1
|
variable_layer_height = 1
|
||||||
#gcodes
|
#gcodes
|
||||||
start_gcode = G28 ;Home\nG0 Z0.3 F200 ;Move nozzle down\nM192 S50 ; Wait for probe temperature to settle\nG29\nG0 X0 Y0 Z30 F6000\nM84 E\nM0\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0\n
|
start_gcode = G28 ;Home\nG0 X-2 Y150 F6000 ;Move to the side\nG0 Z0.3 F200 ;Move nozzle down\nM192 ; Wait for probe temperature to settle\nG28 Z\nG29\nG0 X0 Y0 Z30 F6000\nM84 E\nM0\nG1 Z15.0 F6000 ;Move the platform down 15mm\n
|
||||||
end_gcode = M400\nM104 S0\nM140 S0\nM107\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X R5\nG0 Y300 F2000\nM84\n
|
end_gcode = M400\nM104 S0\nM140 S0\nM107\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X R5\nG0 Y300 F2000\nM84\n
|
||||||
color_change_gcode = M600
|
color_change_gcode = M600
|
||||||
#limits
|
#limits
|
||||||
|
|
|
@ -1,159 +1,161 @@
|
||||||
min_slic3r_version = 2.3.0-rc1
|
min_slic3r_version = 2.4.0-alpha0
|
||||||
1.2.4 Updated cost/density values in filament settings. Various changes in print settings.
|
1.3.0-alpha0 Disabled thick bridges, updated support settings.
|
||||||
1.2.3 Updated firmware version. Updated end g-code in MMU2 printer profiles.
|
min_slic3r_version = 2.3.0-rc1
|
||||||
1.2.2 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles.
|
1.2.4 Updated cost/density values in filament settings. Various changes in print settings.
|
||||||
1.2.1 Updated FW version for MK2.5 family printers.
|
1.2.3 Updated firmware version. Updated end g-code in MMU2 printer profiles.
|
||||||
1.2.0 Added full_fan_speed_layer value for PETG. Increased support interface spacing for 0.6mm nozzle profiles. Updated firmware version.
|
1.2.2 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles.
|
||||||
min_slic3r_version = 2.3.0-beta2
|
1.2.1 Updated FW version for MK2.5 family printers.
|
||||||
1.2.0-beta1 Updated end g-code. Added full_fan_speed_layer values.
|
1.2.0 Added full_fan_speed_layer value for PETG. Increased support interface spacing for 0.6mm nozzle profiles. Updated firmware version.
|
||||||
min_slic3r_version = 2.3.0-beta0
|
min_slic3r_version = 2.3.0-beta2
|
||||||
1.2.0-beta0 Adjusted infill anchor limits. Added filament spool weights.
|
1.2.0-beta1 Updated end g-code. Added full_fan_speed_layer values.
|
||||||
min_slic3r_version = 2.3.0-alpha4
|
min_slic3r_version = 2.3.0-beta0
|
||||||
1.2.0-alpha1 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles.
|
1.2.0-beta0 Adjusted infill anchor limits. Added filament spool weights.
|
||||||
1.2.0-alpha0 Added filament spool weights
|
min_slic3r_version = 2.3.0-alpha4
|
||||||
min_slic3r_version = 2.2.0-alpha3
|
1.2.0-alpha1 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles.
|
||||||
1.1.13 Updated firmware version. Updated end g-code in MMU2 printer profiles.
|
1.2.0-alpha0 Added filament spool weights
|
||||||
1.1.12 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles.
|
min_slic3r_version = 2.2.0-alpha3
|
||||||
1.1.11 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles.
|
1.1.13 Updated firmware version. Updated end g-code in MMU2 printer profiles.
|
||||||
1.1.10 Updated firmware version.
|
1.1.12 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles.
|
||||||
1.1.9 Updated K values in filament profiles (linear advance). Added new filament profiles and SLA materials.
|
1.1.11 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles.
|
||||||
1.1.8 Updated start/end g-code scripts for MK3 family printer profiles (reduced extruder motor current for some print profiles). Added new filament and SLA material profiles.
|
1.1.10 Updated firmware version.
|
||||||
1.1.7 Updated end g-code for MMU2 Single printer profiles. Added/updated filament and SLA material profiles.
|
1.1.9 Updated K values in filament profiles (linear advance). Added new filament profiles and SLA materials.
|
||||||
1.1.6 Updated firmware version for MK2.5/S and MK3/S.
|
1.1.8 Updated start/end g-code scripts for MK3 family printer profiles (reduced extruder motor current for some print profiles). Added new filament and SLA material profiles.
|
||||||
1.1.5 Updated MMU1 specific retraction settings for Prusament PC Blend
|
1.1.7 Updated end g-code for MMU2 Single printer profiles. Added/updated filament and SLA material profiles.
|
||||||
1.1.4 Added Prusament PC Blend filament profile.
|
1.1.6 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
1.1.3 Added SLA material and filament profile
|
1.1.5 Updated MMU1 specific retraction settings for Prusament PC Blend
|
||||||
1.1.2 Added renamed_from fields for PETG filaments to indicate that they were renamed from PET.
|
1.1.4 Added Prusament PC Blend filament profile.
|
||||||
1.1.1 Added Verbatim and Fiberlogy PETG filament profiles. Updated auto cooling settings for ABS.
|
1.1.3 Added SLA material and filament profile
|
||||||
1.1.1-beta Updated for PrusaSlicer 2.2.0-beta
|
1.1.2 Added renamed_from fields for PETG filaments to indicate that they were renamed from PET.
|
||||||
1.1.1-alpha4 Extended list of default filaments to be installed, top/bottom_solid_min_thickness defined, infill_acceleration changed etc
|
1.1.1 Added Verbatim and Fiberlogy PETG filament profiles. Updated auto cooling settings for ABS.
|
||||||
1.1.1-alpha3 Print bed textures are now configurable from the Preset Bundle. Requires PrusaSlicer 2.2.0-alpha3 and newer.
|
1.1.1-beta Updated for PrusaSlicer 2.2.0-beta
|
||||||
# The following line (max_slic3r_version) forces the users of PrusaSlicer 2.2.0-alpha3 and newer to update the profiles to 1.1.1-alpha3 and newer,
|
1.1.1-alpha4 Extended list of default filaments to be installed, top/bottom_solid_min_thickness defined, infill_acceleration changed etc
|
||||||
# so they will see the print bed.
|
1.1.1-alpha3 Print bed textures are now configurable from the Preset Bundle. Requires PrusaSlicer 2.2.0-alpha3 and newer.
|
||||||
max_slic3r_version = 2.2.0-alpha2
|
# The following line (max_slic3r_version) forces the users of PrusaSlicer 2.2.0-alpha3 and newer to update the profiles to 1.1.1-alpha3 and newer,
|
||||||
min_slic3r_version = 2.2.0-alpha0
|
# so they will see the print bed.
|
||||||
1.1.1-alpha2 Bumped up config version, so our in house customer will get updated profiles.
|
max_slic3r_version = 2.2.0-alpha2
|
||||||
1.1.0 Filament aliases, Creality profiles and other goodies for PrusaSlicer 2.2.0-alpha0
|
min_slic3r_version = 2.2.0-alpha0
|
||||||
min_slic3r_version = 2.1.1-beta0
|
1.1.1-alpha2 Bumped up config version, so our in house customer will get updated profiles.
|
||||||
1.0.11 Updated firmware version.
|
1.1.0 Filament aliases, Creality profiles and other goodies for PrusaSlicer 2.2.0-alpha0
|
||||||
1.0.10 Updated firmware version for MK2.5/S and MK3/S.
|
min_slic3r_version = 2.1.1-beta0
|
||||||
1.0.9 Updated firmware version for MK2.5/S and MK3/S.
|
1.0.11 Updated firmware version.
|
||||||
1.0.8 Various changes in FFF profiles, new filaments/materials added. See changelog.
|
1.0.10 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
1.0.7 Updated layer height limits for MINI
|
1.0.9 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
1.0.6 Added Prusa MINI profiles
|
1.0.8 Various changes in FFF profiles, new filaments/materials added. See changelog.
|
||||||
min_slic3r_version = 2.1.0-alpha0
|
1.0.7 Updated layer height limits for MINI
|
||||||
1.0.5 Added SLA materials
|
1.0.6 Added Prusa MINI profiles
|
||||||
1.0.4 Updated firmware version and 0.25mm nozzle profiles
|
min_slic3r_version = 2.1.0-alpha0
|
||||||
1.0.3 Added filament profiles
|
1.0.5 Added SLA materials
|
||||||
1.0.2 Added SLA materials
|
1.0.4 Updated firmware version and 0.25mm nozzle profiles
|
||||||
1.0.1 Updated MK3 firmware version check to 3.8.0, new soluble support profiles for 0.6mm nozzle diameter MMU2S printers.
|
1.0.3 Added filament profiles
|
||||||
1.0.0 Updated end G-code for the MMU2 profiles to lift the extruder at the end of print. Wipe tower bridging distance was made smaller for soluble supports.
|
1.0.2 Added SLA materials
|
||||||
1.0.0-beta1 Updated color for the ASA filaments to differ from the other filaments. Single extruder printers now have no extruder color assigned, obects and toolpaths will be colored with the color of the active filament.
|
1.0.1 Updated MK3 firmware version check to 3.8.0, new soluble support profiles for 0.6mm nozzle diameter MMU2S printers.
|
||||||
1.0.0-beta0 Printer model checks in start G-codes, ASA filament profiles, limits on min / max SL1 exposition times
|
1.0.0 Updated end G-code for the MMU2 profiles to lift the extruder at the end of print. Wipe tower bridging distance was made smaller for soluble supports.
|
||||||
1.0.0-alpha2 Printer model and nozzle diameter check
|
1.0.0-beta1 Updated color for the ASA filaments to differ from the other filaments. Single extruder printers now have no extruder color assigned, obects and toolpaths will be colored with the color of the active filament.
|
||||||
1.0.0-alpha1 Added Prusament ASA profile
|
1.0.0-beta0 Printer model checks in start G-codes, ASA filament profiles, limits on min / max SL1 exposition times
|
||||||
1.0.0-alpha0 Filament specific retract for PET and similar copolymers, and for FLEX
|
1.0.0-alpha2 Printer model and nozzle diameter check
|
||||||
min_slic3r_version = 1.42.0-alpha6
|
1.0.0-alpha1 Added Prusament ASA profile
|
||||||
0.8.10 Updated firmware version.
|
1.0.0-alpha0 Filament specific retract for PET and similar copolymers, and for FLEX
|
||||||
0.8.9 Updated firmware version for MK2.5/S and MK3/S.
|
min_slic3r_version = 1.42.0-alpha6
|
||||||
0.8.8 Updated firmware version for MK2.5/S and MK3/S.
|
0.8.10 Updated firmware version.
|
||||||
0.8.7 Updated firmware version
|
0.8.9 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
0.8.6 Updated firmware version for MK2.5/S and MK3/S
|
0.8.8 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
0.8.5 Updated SL1 printer and material settings
|
0.8.7 Updated firmware version
|
||||||
0.8.4 Added Prusament ASA profile
|
0.8.6 Updated firmware version for MK2.5/S and MK3/S
|
||||||
0.8.3 FW version and SL1 materials update
|
0.8.5 Updated SL1 printer and material settings
|
||||||
0.8.2 FFF and SL1 settings update
|
0.8.4 Added Prusament ASA profile
|
||||||
0.8.1 Output settings and SLA materials update
|
0.8.3 FW version and SL1 materials update
|
||||||
0.8.0 Updated for the PrusaSlicer 2.0.0 final release
|
0.8.2 FFF and SL1 settings update
|
||||||
0.8.0-rc2 Updated firmware versions for MK2.5/S and MK3/S
|
0.8.1 Output settings and SLA materials update
|
||||||
0.8.0-rc1 Updated SLA profiles
|
0.8.0 Updated for the PrusaSlicer 2.0.0 final release
|
||||||
0.8.0-rc Updated for the PrusaSlicer 2.0.0-rc release
|
0.8.0-rc2 Updated firmware versions for MK2.5/S and MK3/S
|
||||||
0.8.0-beta4 Updated SLA profiles
|
0.8.0-rc1 Updated SLA profiles
|
||||||
0.8.0-beta3 Updated SLA profiles
|
0.8.0-rc Updated for the PrusaSlicer 2.0.0-rc release
|
||||||
0.8.0-beta2 Updated SLA profiles
|
0.8.0-beta4 Updated SLA profiles
|
||||||
0.8.0-beta1 Updated SLA profiles
|
0.8.0-beta3 Updated SLA profiles
|
||||||
0.8.0-beta Updated SLA profiles
|
0.8.0-beta2 Updated SLA profiles
|
||||||
0.8.0-alpha9 Updated SLA and FFF profiles
|
0.8.0-beta1 Updated SLA profiles
|
||||||
0.8.0-alpha8 Updated SLA profiles
|
0.8.0-beta Updated SLA profiles
|
||||||
0.8.0-alpha7 Updated SLA profiles
|
0.8.0-alpha9 Updated SLA and FFF profiles
|
||||||
0.8.0-alpha6 Updated SLA profiles
|
0.8.0-alpha8 Updated SLA profiles
|
||||||
min_slic3r_version = 1.42.0-alpha
|
0.8.0-alpha7 Updated SLA profiles
|
||||||
0.8.0-alpha Updated SLA profiles
|
0.8.0-alpha6 Updated SLA profiles
|
||||||
0.4.0-alpha4 Updated SLA profiles
|
min_slic3r_version = 1.42.0-alpha
|
||||||
0.4.0-alpha3 Update of SLA profiles
|
0.8.0-alpha Updated SLA profiles
|
||||||
0.4.0-alpha2 First SLA profiles
|
0.4.0-alpha4 Updated SLA profiles
|
||||||
min_slic3r_version = 1.41.3-alpha
|
0.4.0-alpha3 Update of SLA profiles
|
||||||
0.4.12 Updated firmware version for MK2.5/S and MK3/S.
|
0.4.0-alpha2 First SLA profiles
|
||||||
0.4.11 Updated firmware version for MK2.5/S and MK3/S.
|
min_slic3r_version = 1.41.3-alpha
|
||||||
0.4.10 Updated firmware version
|
0.4.12 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
0.4.9 Updated firmware version for MK2.5/S and MK3/S
|
0.4.11 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
0.4.8 MK2.5/3/S FW update
|
0.4.10 Updated firmware version
|
||||||
0.4.7 MK2/S/MMU FW update
|
0.4.9 Updated firmware version for MK2.5/S and MK3/S
|
||||||
0.4.6 Updated firmware versions for MK2.5/S and MK3/S
|
0.4.8 MK2.5/3/S FW update
|
||||||
0.4.5 Enabled remaining time support for MK2/S/MMU1
|
0.4.7 MK2/S/MMU FW update
|
||||||
0.4.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
0.4.6 Updated firmware versions for MK2.5/S and MK3/S
|
||||||
0.4.3 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
0.4.5 Enabled remaining time support for MK2/S/MMU1
|
||||||
0.4.2 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
0.4.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||||
0.4.1 New MK2.5S and MK3S FW versions
|
0.4.3 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||||
0.4.0 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
0.4.2 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||||
min_slic3r_version = 1.41.1
|
0.4.1 New MK2.5S and MK3S FW versions
|
||||||
0.3.11 Updated firmware version for MK2.5/S and MK3/S.
|
0.4.0 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||||
0.3.10 Updated firmware version
|
min_slic3r_version = 1.41.1
|
||||||
0.3.9 Updated firmware version for MK2.5/S and MK3/S
|
0.3.11 Updated firmware version for MK2.5/S and MK3/S.
|
||||||
0.3.8 MK2.5/3/S FW update
|
0.3.10 Updated firmware version
|
||||||
0.3.7 MK2/S/MMU FW update
|
0.3.9 Updated firmware version for MK2.5/S and MK3/S
|
||||||
0.3.6 Updated firmware versions for MK2.5 and MK3
|
0.3.8 MK2.5/3/S FW update
|
||||||
0.3.5 New MK2.5 and MK3 FW versions
|
0.3.7 MK2/S/MMU FW update
|
||||||
0.3.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
0.3.6 Updated firmware versions for MK2.5 and MK3
|
||||||
0.3.3 Prusament PETG released
|
0.3.5 New MK2.5 and MK3 FW versions
|
||||||
0.3.2 New MK2.5 and MK3 FW versions
|
0.3.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||||
0.3.1 New MK2.5 and MK3 FW versions
|
0.3.3 Prusament PETG released
|
||||||
0.3.0 New MK2.5 and MK3 FW version
|
0.3.2 New MK2.5 and MK3 FW versions
|
||||||
min_slic3r_version = 1.41.0-alpha
|
0.3.1 New MK2.5 and MK3 FW versions
|
||||||
0.2.9 New MK2.5 and MK3 FW versions
|
0.3.0 New MK2.5 and MK3 FW version
|
||||||
0.2.8 New MK2.5 and MK3 FW version
|
min_slic3r_version = 1.41.0-alpha
|
||||||
min_slic3r_version = 1.41.1
|
0.2.9 New MK2.5 and MK3 FW versions
|
||||||
0.2.7 New MK2.5 and MK3 FW version
|
0.2.8 New MK2.5 and MK3 FW version
|
||||||
0.2.6 Added MMU2 MK2.5 settings
|
min_slic3r_version = 1.41.1
|
||||||
min_slic3r_version = 1.41.0-alpha
|
0.2.7 New MK2.5 and MK3 FW version
|
||||||
0.2.5 Prusament is out - added prusament settings
|
0.2.6 Added MMU2 MK2.5 settings
|
||||||
0.2.4 Added soluble support profiles for MMU2
|
min_slic3r_version = 1.41.0-alpha
|
||||||
0.2.3 Added materials for MMU2 single mode, edited MK3 xy stealth feedrate limit
|
0.2.5 Prusament is out - added prusament settings
|
||||||
0.2.2 Edited MMU2 Single mode purge line
|
0.2.4 Added soluble support profiles for MMU2
|
||||||
0.2.1 Added PET and BVOH settings for MMU2
|
0.2.3 Added materials for MMU2 single mode, edited MK3 xy stealth feedrate limit
|
||||||
0.2.0-beta5 Fixed MMU1 ramming parameters
|
0.2.2 Edited MMU2 Single mode purge line
|
||||||
0.2.0-beta4 Added filament loading speed at start, increased minimal purge on wipe tower
|
0.2.1 Added PET and BVOH settings for MMU2
|
||||||
0.2.0-beta3 Edited ramming parameters and filament cooling moves for MMU2
|
0.2.0-beta5 Fixed MMU1 ramming parameters
|
||||||
0.2.0-beta2 Edited first layer speed and wipe tower position
|
0.2.0-beta4 Added filament loading speed at start, increased minimal purge on wipe tower
|
||||||
0.2.0-beta Removed limit on the MK3MMU2 height, added legacy M204 S T format to the MK2 profiles
|
0.2.0-beta3 Edited ramming parameters and filament cooling moves for MMU2
|
||||||
0.2.0-alpha8 Added filament_load/unload_time for the PLA/ABS MMU2 filament presets.
|
0.2.0-beta2 Edited first layer speed and wipe tower position
|
||||||
0.2.0-alpha7 Vojtech's fix the incorrect *MK3* references
|
0.2.0-beta Removed limit on the MK3MMU2 height, added legacy M204 S T format to the MK2 profiles
|
||||||
0.2.0-alpha6 Jindra's way to fix the 0.2.0-alpha5 version
|
0.2.0-alpha8 Added filament_load/unload_time for the PLA/ABS MMU2 filament presets.
|
||||||
0.2.0-alpha5 Bumped up firmware versions for MK2.5/MK3 to 3.3.1, disabled priming areas for MK3MMU2
|
0.2.0-alpha7 Vojtech's fix the incorrect *MK3* references
|
||||||
0.2.0-alpha4 Extended the custom start/end G-codes of the MMU2.0 printers for no priming towers.
|
0.2.0-alpha6 Jindra's way to fix the 0.2.0-alpha5 version
|
||||||
0.2.0-alpha3 Adjusted machine limits for time estimates, added filament density and cost
|
0.2.0-alpha5 Bumped up firmware versions for MK2.5/MK3 to 3.3.1, disabled priming areas for MK3MMU2
|
||||||
0.2.0-alpha2 Renamed the key MK3SMMU to MK3MMU2, added a generic PLA MMU2 material
|
0.2.0-alpha4 Extended the custom start/end G-codes of the MMU2.0 printers for no priming towers.
|
||||||
0.2.0-alpha1 added initial profiles for the i3 MK3 Multi Material Upgrade 2.0
|
0.2.0-alpha3 Adjusted machine limits for time estimates, added filament density and cost
|
||||||
0.2.0-alpha moved machine limits from the start G-code to the new print profile parameters
|
0.2.0-alpha2 Renamed the key MK3SMMU to MK3MMU2, added a generic PLA MMU2 material
|
||||||
min_slic3r_version = 1.40.0
|
0.2.0-alpha1 added initial profiles for the i3 MK3 Multi Material Upgrade 2.0
|
||||||
0.1.18 Updated firmware version
|
0.2.0-alpha moved machine limits from the start G-code to the new print profile parameters
|
||||||
0.1.17 Updated firmware version for MK2.5/S and MK3/S
|
min_slic3r_version = 1.40.0
|
||||||
0.1.16 MK2.5/3/S FW update
|
0.1.18 Updated firmware version
|
||||||
0.1.15 MK2/S/MMU FW update
|
0.1.17 Updated firmware version for MK2.5/S and MK3/S
|
||||||
0.1.14 Updated firmware versions for MK2.5 and MK3
|
0.1.16 MK2.5/3/S FW update
|
||||||
0.1.13 New MK2.5 and MK3 FW versions
|
0.1.15 MK2/S/MMU FW update
|
||||||
0.1.12 New MK2.5 and MK3 FW versions
|
0.1.14 Updated firmware versions for MK2.5 and MK3
|
||||||
0.1.11 fw version changed to 3.3.1
|
0.1.13 New MK2.5 and MK3 FW versions
|
||||||
0.1.10 MK3 jerk and acceleration update
|
0.1.12 New MK2.5 and MK3 FW versions
|
||||||
0.1.9 edited support extrusion width for 0.25 and 0.6 nozzles
|
0.1.11 fw version changed to 3.3.1
|
||||||
0.1.8 extrusion width for 0,25, 0.6 and variable layer height fixes
|
0.1.10 MK3 jerk and acceleration update
|
||||||
0.1.7 Fixed errors in 0.25mm and 0.6mm profiles
|
0.1.9 edited support extrusion width for 0.25 and 0.6 nozzles
|
||||||
0.1.6 Split the MK2.5 profile from the MK2S
|
0.1.8 extrusion width for 0,25, 0.6 and variable layer height fixes
|
||||||
min_slic3r_version = 1.40.0-beta
|
0.1.7 Fixed errors in 0.25mm and 0.6mm profiles
|
||||||
0.1.5 fixed printer_variant fields for the i3 MK3 0.25 and 0.6mm nozzles
|
0.1.6 Split the MK2.5 profile from the MK2S
|
||||||
0.1.4 edited fw version, added z-raise after print
|
min_slic3r_version = 1.40.0-beta
|
||||||
min_slic3r_version = 1.40.0-alpha
|
0.1.5 fixed printer_variant fields for the i3 MK3 0.25 and 0.6mm nozzles
|
||||||
0.1.3 Fixed an incorrect position of the max_print_height parameter
|
0.1.4 edited fw version, added z-raise after print
|
||||||
0.1.2 Wipe tower changes
|
min_slic3r_version = 1.40.0-alpha
|
||||||
0.1.1 Minor print speed adjustments
|
0.1.3 Fixed an incorrect position of the max_print_height parameter
|
||||||
0.1.0 Initial
|
0.1.2 Wipe tower changes
|
||||||
|
0.1.1 Minor print speed adjustments
|
||||||
|
0.1.0 Initial
|
||||||
|
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 31 KiB |
|
@ -1,8 +1,9 @@
|
||||||
min_slic3r_version = 2.3.0-alpha3
|
min_slic3r_version = 2.3.0-alpha3
|
||||||
|
0.0.7 Added PLA, PETG profiles for 0.25 nozzle, fixed supports on 0.8 nozzle profile, fixed max volumetric speed, disabled elefant foot compensation
|
||||||
0.0.6 Added material TPU 93A (SMARTFIL)
|
0.0.6 Added material TPU 93A (SMARTFIL)
|
||||||
0.0.5 Removed obsolete host keys.
|
0.0.5 Removed obsolete host keys.
|
||||||
0.0.4 Added PLA, PETG profiles for 0.8 nozzle, update print materials
|
0.0.4 Added PLA, PETG profiles for 0.8 nozzle, update print materials
|
||||||
0.0.3 Added DeltiQ 2, DeltiQ 2 Plus printers, 0.10mm, 0.20mm FLEX print profiles, updated print materials, flexprint extension support
|
0.0.3 Added DeltiQ 2, DeltiQ 2 Plus printers, 0.10mm, 0.20mm FLEX print profiles, updated print materials, flexprint extension support
|
||||||
min_slic3r_version = 2.3.0-alpha0
|
min_slic3r_version = 2.3.0-alpha0
|
||||||
0.0.2 Added 0.15mm print profile
|
0.0.2 Added 0.15mm print profile
|
||||||
0.0.1 Initial TriLAB bundle
|
0.0.1 Initial TriLAB bundle
|
|
@ -6,7 +6,7 @@
|
||||||
name = TriLAB
|
name = TriLAB
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# 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.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.0.6
|
config_version = 0.0.7
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/TriLAB/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/TriLAB/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
@ -17,16 +17,16 @@ config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/Prus
|
||||||
|
|
||||||
[printer_model:DQ2]
|
[printer_model:DQ2]
|
||||||
name = DeltiQ 2
|
name = DeltiQ 2
|
||||||
variants = 0.4; 0.8
|
variants = 0.4; 0.25; 0.8
|
||||||
technology = FFF
|
technology = FFF
|
||||||
family = DeltiQ 2
|
family = DeltiQ 2
|
||||||
bed_model = dq2_bed.stl
|
bed_model = dq2_bed.stl
|
||||||
bed_texture = dq2_bed_texture.svg
|
bed_texture = dq2_bed_texture.svg
|
||||||
default_materials = DeltiQ - PLA - Generic; DeltiQ - PETG - Generic; DeltiQ - ABS - Generic; DeltiQ - PLA - ExtraFill (Fillamentum); DeltiQ - PETG (Devil Design); DeltiQ - ABS - ExtraFill (Fillamentum); DeltiQ - ASA - ExtraFill (Fillamentum); DeltiQ - CPE - HG100 (Fillamentum); DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 93A (SMARTFIL); DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle
|
default_materials = DeltiQ - PLA - Generic; DeltiQ - PETG - Generic; DeltiQ - ABS - Generic; DeltiQ - PLA - ExtraFill (Fillamentum); DeltiQ - PETG (Devil Design); DeltiQ - ABS - ExtraFill (Fillamentum); DeltiQ - ASA - ExtraFill (Fillamentum); DeltiQ - CPE - HG100 (Fillamentum); DeltiQ FP2 - PLA - Generic; DeltiQ FP2 - PETG - Generic; DeltiQ FP2 - ABS - Generic; DeltiQ FP2 - PLA - ExtraFill (Fillamentum); DeltiQ FP2 - PETG (Devil Design); DeltiQ FP2 - ABS - ExtraFill (Fillamentum); DeltiQ FP2 - ASA - ExtraFill (Fillamentum); DeltiQ FP2 - CPE - HG100 (Fillamentum); DeltiQ FP2 - FLEX - Generic; DeltiQ FP2 - TPU 92A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 98A - FlexFill (Fillamentum); DeltiQ FP2 - TPU 93A (SMARTFIL); DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle; DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle
|
||||||
|
|
||||||
[printer_model:DQ2P]
|
[printer_model:DQ2P]
|
||||||
name = DeltiQ 2 Plus
|
name = DeltiQ 2 Plus
|
||||||
variants = 0.4; 0.8
|
variants = 0.4; 0.25; 0.8
|
||||||
technology = FFF
|
technology = FFF
|
||||||
family = DeltiQ 2
|
family = DeltiQ 2
|
||||||
bed_model = dq2_bed.stl
|
bed_model = dq2_bed.stl
|
||||||
|
@ -110,7 +110,7 @@ complete_objects = 0
|
||||||
default_acceleration = 2000
|
default_acceleration = 2000
|
||||||
dont_support_bridges = 0
|
dont_support_bridges = 0
|
||||||
draft_shield = 0
|
draft_shield = 0
|
||||||
elefant_foot_compensation = 0.2
|
elefant_foot_compensation = 0.0
|
||||||
ensure_vertical_shell_thickness = 0
|
ensure_vertical_shell_thickness = 0
|
||||||
external_perimeter_extrusion_width = 0.45
|
external_perimeter_extrusion_width = 0.45
|
||||||
external_perimeter_speed = 30
|
external_perimeter_speed = 30
|
||||||
|
@ -150,7 +150,7 @@ min_skirt_length = 4
|
||||||
notes =
|
notes =
|
||||||
only_retract_when_crossing_perimeters = 1
|
only_retract_when_crossing_perimeters = 1
|
||||||
ooze_prevention = 0
|
ooze_prevention = 0
|
||||||
output_filename_format = {input_filename_base}_{printer_model}_{filament_type[0]}_{layer_height}mm_{print_time}.gcode
|
output_filename_format = {input_filename_base}_{printer_model}_{filament_type[0]}_{layer_height}mm_{print_time}_{timestamp}.gcode
|
||||||
overhangs = 1
|
overhangs = 1
|
||||||
perimeter_acceleration = 1500
|
perimeter_acceleration = 1500
|
||||||
perimeter_extruder = 1
|
perimeter_extruder = 1
|
||||||
|
@ -283,6 +283,37 @@ travel_speed = 200
|
||||||
max_print_speed = 40
|
max_print_speed = 40
|
||||||
complete_objects = 1
|
complete_objects = 1
|
||||||
|
|
||||||
|
[print:DeltiQ 0.07mm Quality @0.25 nozzle]
|
||||||
|
inherits = DeltiQ 0.20mm Normal
|
||||||
|
bottom_solid_layers = 6
|
||||||
|
bottom_solid_min_thickness = 0.5
|
||||||
|
bridge_speed = 60
|
||||||
|
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and nozzle_diameter[0]==0.25
|
||||||
|
elefant_foot_compensation = 0.0
|
||||||
|
external_perimeter_extrusion_width = 0.27
|
||||||
|
extrusion_width = 0.25
|
||||||
|
first_layer_extrusion_width = 0.26
|
||||||
|
first_layer_height = 0.1
|
||||||
|
infill_extrusion_width = 0.27
|
||||||
|
infill_overlap = 50%
|
||||||
|
layer_height = 0.07
|
||||||
|
overhangs = 1
|
||||||
|
perimeter_extrusion_width = 0.27
|
||||||
|
perimeters = 5
|
||||||
|
solid_infill_extrusion_width = 0.27
|
||||||
|
skirts = 2
|
||||||
|
support_material_extrusion_width = 0.27
|
||||||
|
support_material_contact_distance = 0.1
|
||||||
|
top_infill_extrusion_width = 0.27
|
||||||
|
top_solid_layers = 6
|
||||||
|
top_solid_min_thickness = 0.5
|
||||||
|
thin_walls = 1
|
||||||
|
|
||||||
|
[print:DeltiQ 0.20mm Normal @0.25 nozzle]
|
||||||
|
inherits = DeltiQ 0.07mm Quality @0.25 nozzle
|
||||||
|
first_layer_height = 0.2
|
||||||
|
layer_height = 0.2
|
||||||
|
|
||||||
[print:DeltiQ 0.40mm Normal @0.8 nozzle]
|
[print:DeltiQ 0.40mm Normal @0.8 nozzle]
|
||||||
inherits = DeltiQ 0.20mm Normal
|
inherits = DeltiQ 0.20mm Normal
|
||||||
bottom_solid_layers = 3
|
bottom_solid_layers = 3
|
||||||
|
@ -290,7 +321,7 @@ bottom_solid_min_thickness = 1.2
|
||||||
bridge_flow_ratio = 0.90
|
bridge_flow_ratio = 0.90
|
||||||
bridge_speed = 20
|
bridge_speed = 20
|
||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and nozzle_diameter[0]==0.8
|
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and nozzle_diameter[0]==0.8
|
||||||
elefant_foot_compensation = 0.2
|
elefant_foot_compensation = 0.0
|
||||||
external_perimeter_extrusion_width = 0.80
|
external_perimeter_extrusion_width = 0.80
|
||||||
external_perimeter_speed = 30
|
external_perimeter_speed = 30
|
||||||
extrusion_width = 0.80
|
extrusion_width = 0.80
|
||||||
|
@ -311,6 +342,8 @@ perimeters = 2
|
||||||
small_perimeter_speed = 20
|
small_perimeter_speed = 20
|
||||||
solid_infill_extrusion_width = 0.8
|
solid_infill_extrusion_width = 0.8
|
||||||
solid_infill_speed = 60
|
solid_infill_speed = 60
|
||||||
|
support_material_extrusion_width = 0.8
|
||||||
|
support_material_contact_distance = 0.2
|
||||||
top_infill_extrusion_width = 0.8
|
top_infill_extrusion_width = 0.8
|
||||||
top_solid_infill_speed = 40
|
top_solid_infill_speed = 40
|
||||||
top_solid_layers = 4
|
top_solid_layers = 4
|
||||||
|
@ -412,7 +445,7 @@ fan_below_layer_time = 20
|
||||||
filament_vendor = Fillamentum
|
filament_vendor = Fillamentum
|
||||||
filament_cost = 774
|
filament_cost = 774
|
||||||
filament_density = 1.08
|
filament_density = 1.08
|
||||||
filament_max_volumetric_speed = 4
|
filament_max_volumetric_speed = 8
|
||||||
filament_retract_before_travel = 3
|
filament_retract_before_travel = 3
|
||||||
filament_retract_before_wipe = 70%
|
filament_retract_before_wipe = 70%
|
||||||
filament_retract_layer_change = 1
|
filament_retract_layer_change = 1
|
||||||
|
@ -474,6 +507,19 @@ min_print_speed = 10
|
||||||
slowdown_below_layer_time = 5
|
slowdown_below_layer_time = 5
|
||||||
temperature = 260
|
temperature = 260
|
||||||
|
|
||||||
|
[filament:DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle]
|
||||||
|
inherits = DeltiQ - PLA - ExtraFill (Fillamentum)
|
||||||
|
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.25
|
||||||
|
|
||||||
|
[filament:DeltiQ - PETG (Devil Design) @0.25 nozzle]
|
||||||
|
inherits = DeltiQ - PETG (Devil Design)
|
||||||
|
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.25
|
||||||
|
first_layer_temperature = 225
|
||||||
|
temperature = 220
|
||||||
|
max_fan_speed = 65
|
||||||
|
min_fan_speed = 40
|
||||||
|
bridge_fan_speed = 100
|
||||||
|
|
||||||
[filament:DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle]
|
[filament:DeltiQ - PLA - ExtraFill (Fillamentum) @0.8 nozzle]
|
||||||
inherits = DeltiQ - PLA - ExtraFill (Fillamentum)
|
inherits = DeltiQ - PLA - ExtraFill (Fillamentum)
|
||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.8
|
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes=~/.*PRINTER_FAMILY_DQ.*/ and !(printer_notes=~/.*FLEXPRINT.*/) and nozzle_diameter[0]==0.8
|
||||||
|
@ -536,7 +582,7 @@ filament_vendor = Generic
|
||||||
filament_cost = 1870
|
filament_cost = 1870
|
||||||
filament_density = 1.22
|
filament_density = 1.22
|
||||||
filament_deretract_speed = nil
|
filament_deretract_speed = nil
|
||||||
filament_max_volumetric_speed = 0.7
|
filament_max_volumetric_speed = 3.0
|
||||||
filament_retract_before_travel = 2
|
filament_retract_before_travel = 2
|
||||||
filament_retract_before_wipe = 70%
|
filament_retract_before_wipe = 70%
|
||||||
filament_retract_layer_change = 0
|
filament_retract_layer_change = 0
|
||||||
|
@ -634,7 +680,7 @@ filament_vendor = Fillamentum
|
||||||
filament_cost = 1870
|
filament_cost = 1870
|
||||||
filament_density = 1.22
|
filament_density = 1.22
|
||||||
filament_deretract_speed = nil
|
filament_deretract_speed = nil
|
||||||
filament_max_volumetric_speed = 2.9
|
filament_max_volumetric_speed = 3.0
|
||||||
filament_retract_before_travel = 2
|
filament_retract_before_travel = 2
|
||||||
filament_retract_before_wipe = 70%
|
filament_retract_before_wipe = 70%
|
||||||
filament_retract_layer_change = 0
|
filament_retract_layer_change = 0
|
||||||
|
@ -665,7 +711,7 @@ filament_vendor = Fillamentum
|
||||||
filament_cost = 1870
|
filament_cost = 1870
|
||||||
filament_density = 1.22
|
filament_density = 1.22
|
||||||
filament_deretract_speed = nil
|
filament_deretract_speed = nil
|
||||||
filament_max_volumetric_speed = 2.9
|
filament_max_volumetric_speed = 3.0
|
||||||
filament_retract_before_travel = 2
|
filament_retract_before_travel = 2
|
||||||
filament_retract_before_wipe = 70%
|
filament_retract_before_wipe = 70%
|
||||||
filament_retract_layer_change = 0
|
filament_retract_layer_change = 0
|
||||||
|
@ -689,7 +735,7 @@ extrusion_multiplier = 1.10
|
||||||
filament_cost = 1870
|
filament_cost = 1870
|
||||||
filament_density = 1.23
|
filament_density = 1.23
|
||||||
filament_deretract_speed = nil
|
filament_deretract_speed = nil
|
||||||
filament_max_volumetric_speed = 2.9
|
filament_max_volumetric_speed = 3.0
|
||||||
filament_retract_before_wipe = 70%
|
filament_retract_before_wipe = 70%
|
||||||
filament_retract_length = 2.5
|
filament_retract_length = 2.5
|
||||||
filament_retract_speed = 20
|
filament_retract_speed = 20
|
||||||
|
@ -822,6 +868,15 @@ printer_model = DQ2
|
||||||
printer_variant = 0.4
|
printer_variant = 0.4
|
||||||
max_print_height = 320
|
max_print_height = 320
|
||||||
|
|
||||||
|
[printer:DeltiQ 2 - 0.25 nozzle]
|
||||||
|
inherits = DeltiQ 2
|
||||||
|
printer_variant = 0.25
|
||||||
|
max_layer_height = 0.15
|
||||||
|
min_layer_height = 0.07
|
||||||
|
nozzle_diameter = 0.25
|
||||||
|
default_filament_profile = "DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle"
|
||||||
|
default_print_profile = DeltiQ 0.07mm Quality @0.25 nozzle
|
||||||
|
|
||||||
[printer:DeltiQ 2 - 0.8 nozzle]
|
[printer:DeltiQ 2 - 0.8 nozzle]
|
||||||
inherits = DeltiQ 2
|
inherits = DeltiQ 2
|
||||||
printer_variant = 0.8
|
printer_variant = 0.8
|
||||||
|
@ -837,6 +892,15 @@ printer_model = DQ2P
|
||||||
printer_variant = 0.4
|
printer_variant = 0.4
|
||||||
max_print_height = 500
|
max_print_height = 500
|
||||||
|
|
||||||
|
[printer:DeltiQ 2 Plus - 0.25 nozzle]
|
||||||
|
inherits = DeltiQ 2 Plus
|
||||||
|
printer_variant = 0.25
|
||||||
|
max_layer_height = 0.15
|
||||||
|
min_layer_height = 0.07
|
||||||
|
nozzle_diameter = 0.25
|
||||||
|
default_filament_profile = "DeltiQ - PLA - ExtraFill (Fillamentum) @0.25 nozzle"
|
||||||
|
default_print_profile = DeltiQ 0.07mm Quality @0.25 nozzle
|
||||||
|
|
||||||
[printer:DeltiQ 2 Plus - 0.8 nozzle]
|
[printer:DeltiQ 2 Plus - 0.8 nozzle]
|
||||||
inherits = DeltiQ 2 Plus
|
inherits = DeltiQ 2 Plus
|
||||||
printer_variant = 0.8
|
printer_variant = 0.8
|
||||||
|
|
|
@ -217,6 +217,11 @@ int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */,
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
// Allow the asserts to open message box, such message box allows to ignore the assert and continue with the application.
|
||||||
|
// Without this call, the seemingly same message box is being opened by the abort() function, but that is too late and
|
||||||
|
// the application will be killed even if "Ignore" button is pressed.
|
||||||
|
_set_error_mode(_OUT_TO_MSGBOX);
|
||||||
|
|
||||||
std::vector<wchar_t*> argv_extended;
|
std::vector<wchar_t*> argv_extended;
|
||||||
argv_extended.emplace_back(argv[0]);
|
argv_extended.emplace_back(argv[0]);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@ project(clipper)
|
||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
add_library(clipper STATIC
|
add_library(clipper STATIC
|
||||||
clipper.cpp
|
# We are using ClipperLib compiled as part of the libslic3r project using Slic3r::Point as its base type.
|
||||||
clipper.hpp
|
# clipper.cpp
|
||||||
|
# clipper.hpp
|
||||||
clipper_z.cpp
|
clipper_z.cpp
|
||||||
clipper_z.hpp
|
clipper_z.hpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,10 +37,12 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include <Eigen/Geometry>
|
||||||
|
|
||||||
#define CLIPPER_VERSION "6.2.6"
|
#define CLIPPER_VERSION "6.2.6"
|
||||||
|
|
||||||
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
|
//CLIPPERLIB_USE_XYZ: adds a Z member to IntPoint. Adds a minor cost to perfomance.
|
||||||
//#define use_xyz
|
//#define CLIPPERLIB_USE_XYZ
|
||||||
|
|
||||||
//use_lines: Enables line clipping. Adds a very minor cost to performance.
|
//use_lines: Enables line clipping. Adds a very minor cost to performance.
|
||||||
#define use_lines
|
#define use_lines
|
||||||
|
@ -57,11 +59,15 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#ifdef use_xyz
|
#ifdef CLIPPERLIB_NAMESPACE_PREFIX
|
||||||
namespace ClipperLib_Z {
|
namespace CLIPPERLIB_NAMESPACE_PREFIX {
|
||||||
#else /* use_xyz */
|
#endif // CLIPPERLIB_NAMESPACE_PREFIX
|
||||||
namespace ClipperLib {
|
|
||||||
#endif /* use_xyz */
|
#ifdef CLIPPERLIB_USE_XYZ
|
||||||
|
namespace ClipperLib_Z {
|
||||||
|
#else
|
||||||
|
namespace ClipperLib {
|
||||||
|
#endif
|
||||||
|
|
||||||
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
|
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
|
||||||
enum PolyType { ptSubject, ptClip };
|
enum PolyType { ptSubject, ptClip };
|
||||||
|
@ -71,36 +77,41 @@ enum PolyType { ptSubject, ptClip };
|
||||||
//see http://glprogramming.com/red/chapter11.html
|
//see http://glprogramming.com/red/chapter11.html
|
||||||
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
||||||
|
|
||||||
|
// If defined, Clipper will work with 32bit signed int coordinates to reduce memory
|
||||||
|
// consumption and to speed up exact orientation predicate calculation.
|
||||||
|
// In that case, coordinates and their differences (vectors of the coordinates) have to fit int32_t.
|
||||||
|
#define CLIPPERLIB_INT32
|
||||||
|
|
||||||
// Point coordinate type
|
// Point coordinate type
|
||||||
typedef int64_t cInt;
|
#ifdef CLIPPERLIB_INT32
|
||||||
// Maximum cInt value to allow a cross product calculation using 32bit expressions.
|
// Coordinates and their differences (vectors of the coordinates) have to fit int32_t.
|
||||||
static cInt const loRange = 0x3FFFFFFF;
|
typedef int32_t cInt;
|
||||||
// Maximum allowed cInt value.
|
|
||||||
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
|
|
||||||
|
|
||||||
struct IntPoint {
|
|
||||||
cInt X;
|
|
||||||
cInt Y;
|
|
||||||
#ifdef use_xyz
|
|
||||||
cInt Z;
|
|
||||||
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
|
|
||||||
#else
|
#else
|
||||||
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
|
typedef int64_t cInt;
|
||||||
#endif
|
// Maximum cInt value to allow a cross product calculation using 32bit expressions.
|
||||||
|
static constexpr cInt const loRange = 0x3FFFFFFF; // 0x3FFFFFFF = 1 073 741 823
|
||||||
|
// Maximum allowed cInt value.
|
||||||
|
static constexpr cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
|
||||||
|
#ifdef CLIPPERLIB_INTPOINT_TYPE
|
||||||
|
using IntPoint = CLIPPERLIB_INTPOINT_TYPE;
|
||||||
|
#else // CLIPPERLIB_INTPOINT_TYPE
|
||||||
|
using IntPoint = Eigen::Matrix<cInt,
|
||||||
|
#ifdef CLIPPERLIB_USE_XYZ
|
||||||
|
3
|
||||||
|
#else // CLIPPERLIB_USE_XYZ
|
||||||
|
2
|
||||||
|
#endif // CLIPPERLIB_USE_XYZ
|
||||||
|
, 1, Eigen::DontAlign>;
|
||||||
|
#endif // CLIPPERLIB_INTPOINT_TYPE
|
||||||
|
|
||||||
|
using DoublePoint = Eigen::Matrix<double, 2, 1, Eigen::DontAlign>;
|
||||||
|
|
||||||
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
|
|
||||||
{
|
|
||||||
return a.X == b.X && a.Y == b.Y;
|
|
||||||
}
|
|
||||||
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
|
|
||||||
{
|
|
||||||
return a.X != b.X || a.Y != b.Y;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef std::vector< IntPoint > Path;
|
typedef std::vector<IntPoint> Path;
|
||||||
typedef std::vector< Path > Paths;
|
typedef std::vector<Path> Paths;
|
||||||
|
|
||||||
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
|
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
|
||||||
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
|
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
|
||||||
|
@ -109,16 +120,9 @@ std::ostream& operator <<(std::ostream &s, const IntPoint &p);
|
||||||
std::ostream& operator <<(std::ostream &s, const Path &p);
|
std::ostream& operator <<(std::ostream &s, const Path &p);
|
||||||
std::ostream& operator <<(std::ostream &s, const Paths &p);
|
std::ostream& operator <<(std::ostream &s, const Paths &p);
|
||||||
|
|
||||||
struct DoublePoint
|
|
||||||
{
|
|
||||||
double X;
|
|
||||||
double Y;
|
|
||||||
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
|
|
||||||
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef use_xyz
|
#ifdef CLIPPERLIB_USE_XYZ
|
||||||
typedef std::function<void(const IntPoint& e1bot, const IntPoint& e1top, const IntPoint& e2bot, const IntPoint& e2top, IntPoint& pt)> ZFillCallback;
|
typedef std::function<void(const IntPoint& e1bot, const IntPoint& e1top, const IntPoint& e2bot, const IntPoint& e2top, IntPoint& pt)> ZFillCallback;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -187,9 +191,7 @@ double Area(const Path &poly);
|
||||||
inline bool Orientation(const Path &poly) { return Area(poly) >= 0; }
|
inline bool Orientation(const Path &poly) { return Area(poly) >= 0; }
|
||||||
int PointInPolygon(const IntPoint &pt, const Path &path);
|
int PointInPolygon(const IntPoint &pt, const Path &path);
|
||||||
|
|
||||||
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
Paths SimplifyPolygon(const Path &in_poly, PolyFillType fillType = pftEvenOdd);
|
||||||
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
|
||||||
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
|
|
||||||
|
|
||||||
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
|
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
|
||||||
void CleanPolygon(Path& poly, double distance = 1.415);
|
void CleanPolygon(Path& poly, double distance = 1.415);
|
||||||
|
@ -259,11 +261,11 @@ enum EdgeSide { esLeft = 1, esRight = 2};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Point of an output polygon.
|
// Point of an output polygon.
|
||||||
// 36B on 64bit system without use_xyz.
|
// 36B on 64bit system without CLIPPERLIB_USE_XYZ.
|
||||||
struct OutPt {
|
struct OutPt {
|
||||||
// 4B
|
// 4B
|
||||||
int Idx;
|
int Idx;
|
||||||
// 16B without use_xyz / 24B with use_xyz
|
// 16B without CLIPPERLIB_USE_XYZ / 24B with CLIPPERLIB_USE_XYZ
|
||||||
IntPoint Pt;
|
IntPoint Pt;
|
||||||
// 4B on 32bit system, 8B on 64bit system
|
// 4B on 32bit system, 8B on 64bit system
|
||||||
OutPt *Next;
|
OutPt *Next;
|
||||||
|
@ -289,10 +291,65 @@ enum EdgeSide { esLeft = 1, esRight = 2};
|
||||||
class ClipperBase
|
class ClipperBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClipperBase() : m_UseFullRange(false), m_HasOpenPaths(false) {}
|
ClipperBase() :
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
|
m_UseFullRange(false),
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
m_HasOpenPaths(false) {}
|
||||||
~ClipperBase() { Clear(); }
|
~ClipperBase() { Clear(); }
|
||||||
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
||||||
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
|
|
||||||
|
template<typename PathsProvider>
|
||||||
|
bool AddPaths(PathsProvider &&paths_provider, PolyType PolyTyp, bool Closed)
|
||||||
|
{
|
||||||
|
size_t num_paths = paths_provider.size();
|
||||||
|
if (num_paths == 0)
|
||||||
|
return false;
|
||||||
|
if (num_paths == 1)
|
||||||
|
return AddPath(*paths_provider.begin(), PolyTyp, Closed);
|
||||||
|
|
||||||
|
std::vector<int> num_edges(num_paths, 0);
|
||||||
|
int num_edges_total = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
for (const Path &pg : paths_provider) {
|
||||||
|
// Remove duplicate end point from a closed input path.
|
||||||
|
// Remove duplicate points from the end of the input path.
|
||||||
|
int highI = (int)pg.size() -1;
|
||||||
|
if (Closed)
|
||||||
|
while (highI > 0 && (pg[highI] == pg[0]))
|
||||||
|
--highI;
|
||||||
|
while (highI > 0 && (pg[highI] == pg[highI -1]))
|
||||||
|
--highI;
|
||||||
|
if ((Closed && highI < 2) || (!Closed && highI < 1))
|
||||||
|
highI = -1;
|
||||||
|
num_edges[i ++] = highI + 1;
|
||||||
|
num_edges_total += highI + 1;
|
||||||
|
}
|
||||||
|
if (num_edges_total == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Allocate a new edge array.
|
||||||
|
std::vector<TEdge> edges(num_edges_total);
|
||||||
|
// Fill in the edge array.
|
||||||
|
bool result = false;
|
||||||
|
TEdge *p_edge = edges.data();
|
||||||
|
i = 0;
|
||||||
|
for (const Path &pg : paths_provider) {
|
||||||
|
if (num_edges[i]) {
|
||||||
|
bool res = AddPathInternal(pg, num_edges[i] - 1, PolyTyp, Closed, p_edge);
|
||||||
|
if (res) {
|
||||||
|
p_edge += num_edges[i];
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++ i;
|
||||||
|
}
|
||||||
|
if (result)
|
||||||
|
// At least some edges were generated. Remember the edge array.
|
||||||
|
m_edges.emplace_back(std::move(edges));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
IntRect GetBounds();
|
IntRect GetBounds();
|
||||||
// By default, when three or more vertices are collinear in input polygons (subject or clip), the Clipper object removes the 'inner' vertices before clipping.
|
// By default, when three or more vertices are collinear in input polygons (subject or clip), the Clipper object removes the 'inner' vertices before clipping.
|
||||||
|
@ -310,9 +367,14 @@ protected:
|
||||||
// Local minima (Y, left edge, right edge) sorted by ascending Y.
|
// Local minima (Y, left edge, right edge) sorted by ascending Y.
|
||||||
std::vector<LocalMinimum> m_MinimaList;
|
std::vector<LocalMinimum> m_MinimaList;
|
||||||
|
|
||||||
|
#ifdef CLIPPERLIB_INT32
|
||||||
|
static constexpr const bool m_UseFullRange = false;
|
||||||
|
#else // CLIPPERLIB_INT32
|
||||||
// True if the input polygons have abs values higher than loRange, but lower than hiRange.
|
// True if the input polygons have abs values higher than loRange, but lower than hiRange.
|
||||||
// False if the input polygons have abs values lower or equal to loRange.
|
// False if the input polygons have abs values lower or equal to loRange.
|
||||||
bool m_UseFullRange;
|
bool m_UseFullRange;
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
|
||||||
// A vector of edges per each input path.
|
// A vector of edges per each input path.
|
||||||
std::vector<std::vector<TEdge>> m_edges;
|
std::vector<std::vector<TEdge>> m_edges;
|
||||||
// Don't remove intermediate vertices of a collinear sequence of points.
|
// Don't remove intermediate vertices of a collinear sequence of points.
|
||||||
|
@ -349,7 +411,7 @@ public:
|
||||||
bool StrictlySimple() const {return m_StrictSimple;};
|
bool StrictlySimple() const {return m_StrictSimple;};
|
||||||
void StrictlySimple(bool value) {m_StrictSimple = value;};
|
void StrictlySimple(bool value) {m_StrictSimple = value;};
|
||||||
//set the callback function for z value filling on intersections (otherwise Z is 0)
|
//set the callback function for z value filling on intersections (otherwise Z is 0)
|
||||||
#ifdef use_xyz
|
#ifdef CLIPPERLIB_USE_XYZ
|
||||||
void ZFillFunction(ZFillCallback zFillFunc) { m_ZFill = zFillFunc; }
|
void ZFillFunction(ZFillCallback zFillFunc) { m_ZFill = zFillFunc; }
|
||||||
#endif
|
#endif
|
||||||
protected:
|
protected:
|
||||||
|
@ -382,7 +444,7 @@ private:
|
||||||
// Does the result go to a PolyTree or Paths?
|
// Does the result go to a PolyTree or Paths?
|
||||||
bool m_UsingPolyTree;
|
bool m_UsingPolyTree;
|
||||||
bool m_StrictSimple;
|
bool m_StrictSimple;
|
||||||
#ifdef use_xyz
|
#ifdef CLIPPERLIB_USE_XYZ
|
||||||
ZFillCallback m_ZFill; //custom callback
|
ZFillCallback m_ZFill; //custom callback
|
||||||
#endif
|
#endif
|
||||||
void SetWindingCount(TEdge& edge) const;
|
void SetWindingCount(TEdge& edge) const;
|
||||||
|
@ -435,7 +497,7 @@ private:
|
||||||
void DoSimplePolygons();
|
void DoSimplePolygons();
|
||||||
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const;
|
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const;
|
||||||
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const;
|
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const;
|
||||||
#ifdef use_xyz
|
#ifdef CLIPPERLIB_USE_XYZ
|
||||||
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
|
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -448,7 +510,11 @@ public:
|
||||||
MiterLimit(miterLimit), ArcTolerance(roundPrecision), ShortestEdgeLength(shortestEdgeLength), m_lowest(-1, 0) {}
|
MiterLimit(miterLimit), ArcTolerance(roundPrecision), ShortestEdgeLength(shortestEdgeLength), m_lowest(-1, 0) {}
|
||||||
~ClipperOffset() { Clear(); }
|
~ClipperOffset() { Clear(); }
|
||||||
void AddPath(const Path& path, JoinType joinType, EndType endType);
|
void AddPath(const Path& path, JoinType joinType, EndType endType);
|
||||||
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
|
template<typename PathsProvider>
|
||||||
|
void AddPaths(PathsProvider &&paths, JoinType joinType, EndType endType) {
|
||||||
|
for (const Path &path : paths)
|
||||||
|
AddPath(path, joinType, endType);
|
||||||
|
}
|
||||||
void Execute(Paths& solution, double delta);
|
void Execute(Paths& solution, double delta);
|
||||||
void Execute(PolyTree& solution, double delta);
|
void Execute(PolyTree& solution, double delta);
|
||||||
void Clear();
|
void Clear();
|
||||||
|
@ -485,8 +551,20 @@ class clipperException : public std::exception
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename PathsProvider>
|
||||||
|
inline Paths SimplifyPolygons(PathsProvider &&in_polys, PolyFillType fillType = pftEvenOdd) {
|
||||||
|
Clipper c;
|
||||||
|
c.StrictlySimple(true);
|
||||||
|
c.AddPaths(std::forward<PathsProvider>(in_polys), ptSubject, true);
|
||||||
|
Paths out;
|
||||||
|
c.Execute(ctUnion, out, fillType, fillType);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
} //ClipperLib namespace
|
} //ClipperLib namespace
|
||||||
|
|
||||||
|
#ifdef CLIPPERLIB_NAMESPACE_PREFIX
|
||||||
|
} // namespace CLIPPERLIB_NAMESPACE_PREFIX
|
||||||
|
#endif // CLIPPERLIB_NAMESPACE_PREFIX
|
||||||
|
|
||||||
#endif //clipper_hpp
|
#endif //clipper_hpp
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Hackish wrapper around the ClipperLib library to compile the Clipper library with the Z support.
|
// Hackish wrapper around the ClipperLib library to compile the Clipper library with the Z support.
|
||||||
|
|
||||||
// Enable the Z coordinate support.
|
// Enable the Z coordinate support.
|
||||||
#define use_xyz
|
#define CLIPPERLIB_USE_XYZ
|
||||||
|
|
||||||
// and let it compile
|
// and let it compile
|
||||||
#include "clipper.cpp"
|
#include "clipper.cpp"
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
#ifndef clipper_z_hpp
|
#ifndef clipper_z_hpp
|
||||||
#ifdef clipper_hpp
|
#ifdef clipper_hpp
|
||||||
#error "You should include the clipper_z.hpp first"
|
#error "You should include clipper_z.hpp before clipper.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define clipper_z_hpp
|
#define clipper_z_hpp
|
||||||
|
|
||||||
// Enable the Z coordinate support.
|
// Enable the Z coordinate support.
|
||||||
#define use_xyz
|
#define CLIPPERLIB_USE_XYZ
|
||||||
|
|
||||||
#include "clipper.hpp"
|
#include "clipper.hpp"
|
||||||
|
|
||||||
#undef clipper_hpp
|
#undef clipper_hpp
|
||||||
#undef use_xyz
|
#undef CLIPPERLIB_USE_XYZ
|
||||||
|
|
||||||
#endif // clipper_z_hpp
|
#endif // clipper_z_hpp
|
||||||
|
|
|
@ -12,11 +12,8 @@ set(LIBNEST2D_SRCFILES
|
||||||
include/libnest2d/placers/bottomleftplacer.hpp
|
include/libnest2d/placers/bottomleftplacer.hpp
|
||||||
include/libnest2d/placers/nfpplacer.hpp
|
include/libnest2d/placers/nfpplacer.hpp
|
||||||
include/libnest2d/selections/selection_boilerplate.hpp
|
include/libnest2d/selections/selection_boilerplate.hpp
|
||||||
#include/libnest2d/selections/filler.hpp
|
|
||||||
include/libnest2d/selections/firstfit.hpp
|
include/libnest2d/selections/firstfit.hpp
|
||||||
#include/libnest2d/selections/djd_heuristic.hpp
|
include/libnest2d/backends/libslic3r/geometries.hpp
|
||||||
include/libnest2d/backends/clipper/geometries.hpp
|
|
||||||
include/libnest2d/backends/clipper/clipper_polygon.hpp
|
|
||||||
include/libnest2d/optimizers/nlopt/nlopt_boilerplate.hpp
|
include/libnest2d/optimizers/nlopt/nlopt_boilerplate.hpp
|
||||||
include/libnest2d/optimizers/nlopt/simplex.hpp
|
include/libnest2d/optimizers/nlopt/simplex.hpp
|
||||||
include/libnest2d/optimizers/nlopt/subplex.hpp
|
include/libnest2d/optimizers/nlopt/subplex.hpp
|
||||||
|
@ -27,5 +24,5 @@ set(LIBNEST2D_SRCFILES
|
||||||
add_library(libnest2d STATIC ${LIBNEST2D_SRCFILES})
|
add_library(libnest2d STATIC ${LIBNEST2D_SRCFILES})
|
||||||
|
|
||||||
target_include_directories(libnest2d PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
target_include_directories(libnest2d PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||||
target_link_libraries(libnest2d PUBLIC clipper NLopt::nlopt TBB::tbb Boost::boost)
|
target_link_libraries(libnest2d PUBLIC NLopt::nlopt TBB::tbb Boost::boost libslic3r)
|
||||||
target_compile_definitions(libnest2d PUBLIC LIBNEST2D_THREADING_tbb LIBNEST2D_STATIC LIBNEST2D_OPTIMIZER_nlopt LIBNEST2D_GEOMETRIES_clipper)
|
target_compile_definitions(libnest2d PUBLIC LIBNEST2D_THREADING_tbb LIBNEST2D_STATIC LIBNEST2D_OPTIMIZER_nlopt LIBNEST2D_GEOMETRIES_libslic3r)
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
#ifndef CLIPPER_POLYGON_HPP
|
|
||||||
#define CLIPPER_POLYGON_HPP
|
|
||||||
|
|
||||||
#include <clipper.hpp>
|
|
||||||
|
|
||||||
namespace ClipperLib {
|
|
||||||
|
|
||||||
struct Polygon {
|
|
||||||
Path Contour;
|
|
||||||
Paths Holes;
|
|
||||||
|
|
||||||
inline Polygon() = default;
|
|
||||||
|
|
||||||
inline explicit Polygon(const Path& cont): Contour(cont) {}
|
|
||||||
// inline explicit Polygon(const Paths& holes):
|
|
||||||
// Holes(holes) {}
|
|
||||||
inline Polygon(const Path& cont, const Paths& holes):
|
|
||||||
Contour(cont), Holes(holes) {}
|
|
||||||
|
|
||||||
inline explicit Polygon(Path&& cont): Contour(std::move(cont)) {}
|
|
||||||
// inline explicit Polygon(Paths&& holes): Holes(std::move(holes)) {}
|
|
||||||
inline Polygon(Path&& cont, Paths&& holes):
|
|
||||||
Contour(std::move(cont)), Holes(std::move(holes)) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline IntPoint& operator +=(IntPoint& p, const IntPoint& pa ) {
|
|
||||||
// This could be done with SIMD
|
|
||||||
p.X += pa.X;
|
|
||||||
p.Y += pa.Y;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline IntPoint operator+(const IntPoint& p1, const IntPoint& p2) {
|
|
||||||
IntPoint ret = p1;
|
|
||||||
ret += p2;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline IntPoint& operator -=(IntPoint& p, const IntPoint& pa ) {
|
|
||||||
p.X -= pa.X;
|
|
||||||
p.Y -= pa.Y;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline IntPoint operator -(const IntPoint& p ) {
|
|
||||||
IntPoint ret = p;
|
|
||||||
ret.X = -ret.X;
|
|
||||||
ret.Y = -ret.Y;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline IntPoint operator-(const IntPoint& p1, const IntPoint& p2) {
|
|
||||||
IntPoint ret = p1;
|
|
||||||
ret -= p2;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline IntPoint& operator *=(IntPoint& p, const IntPoint& pa ) {
|
|
||||||
p.X *= pa.X;
|
|
||||||
p.Y *= pa.Y;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline IntPoint operator*(const IntPoint& p1, const IntPoint& p2) {
|
|
||||||
IntPoint ret = p1;
|
|
||||||
ret *= p2;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CLIPPER_POLYGON_HPP
|
|
|
@ -1,356 +0,0 @@
|
||||||
#ifndef CLIPPER_BACKEND_HPP
|
|
||||||
#define CLIPPER_BACKEND_HPP
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <cassert>
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <libnest2d/geometry_traits.hpp>
|
|
||||||
#include <libnest2d/geometry_traits_nfp.hpp>
|
|
||||||
|
|
||||||
#include "clipper_polygon.hpp"
|
|
||||||
|
|
||||||
namespace libnest2d {
|
|
||||||
|
|
||||||
// Aliases for convinience
|
|
||||||
using PointImpl = ClipperLib::IntPoint;
|
|
||||||
using PathImpl = ClipperLib::Path;
|
|
||||||
using HoleStore = ClipperLib::Paths;
|
|
||||||
using PolygonImpl = ClipperLib::Polygon;
|
|
||||||
|
|
||||||
template<> struct ShapeTag<PolygonImpl> { using Type = PolygonTag; };
|
|
||||||
template<> struct ShapeTag<PathImpl> { using Type = PathTag; };
|
|
||||||
template<> struct ShapeTag<PointImpl> { using Type = PointTag; };
|
|
||||||
|
|
||||||
// Type of coordinate units used by Clipper. Enough to specialize for point,
|
|
||||||
// the rest of the types will work (Path, Polygon)
|
|
||||||
template<> struct CoordType<PointImpl> {
|
|
||||||
using Type = ClipperLib::cInt;
|
|
||||||
static const constexpr ClipperLib::cInt MM_IN_COORDS = 1000000;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Enough to specialize for path, it will work for multishape and Polygon
|
|
||||||
template<> struct PointType<PathImpl> { using Type = PointImpl; };
|
|
||||||
|
|
||||||
// This is crucial. CountourType refers to itself by default, so we don't have
|
|
||||||
// to secialize for clipper Path. ContourType<PathImpl>::Type is PathImpl.
|
|
||||||
template<> struct ContourType<PolygonImpl> { using Type = PathImpl; };
|
|
||||||
|
|
||||||
// The holes are contained in Clipper::Paths
|
|
||||||
template<> struct HolesContainer<PolygonImpl> { using Type = ClipperLib::Paths; };
|
|
||||||
|
|
||||||
namespace pointlike {
|
|
||||||
|
|
||||||
// Tell libnest2d how to extract the X coord from a ClipperPoint object
|
|
||||||
template<> inline ClipperLib::cInt x(const PointImpl& p)
|
|
||||||
{
|
|
||||||
return p.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tell libnest2d how to extract the Y coord from a ClipperPoint object
|
|
||||||
template<> inline ClipperLib::cInt y(const PointImpl& p)
|
|
||||||
{
|
|
||||||
return p.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tell libnest2d how to extract the X coord from a ClipperPoint object
|
|
||||||
template<> inline ClipperLib::cInt& x(PointImpl& p)
|
|
||||||
{
|
|
||||||
return p.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tell libnest2d how to extract the Y coord from a ClipperPoint object
|
|
||||||
template<> inline ClipperLib::cInt& y(PointImpl& p)
|
|
||||||
{
|
|
||||||
return p.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Using the libnest2d default area implementation
|
|
||||||
#define DISABLE_BOOST_AREA
|
|
||||||
|
|
||||||
namespace shapelike {
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance, const PolygonTag&)
|
|
||||||
{
|
|
||||||
#define DISABLE_BOOST_OFFSET
|
|
||||||
|
|
||||||
using ClipperLib::ClipperOffset;
|
|
||||||
using ClipperLib::jtSquare;
|
|
||||||
using ClipperLib::etClosedPolygon;
|
|
||||||
using ClipperLib::Paths;
|
|
||||||
|
|
||||||
Paths result;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ClipperOffset offs;
|
|
||||||
offs.AddPath(sh.Contour, jtSquare, etClosedPolygon);
|
|
||||||
offs.AddPaths(sh.Holes, jtSquare, etClosedPolygon);
|
|
||||||
offs.Execute(result, static_cast<double>(distance));
|
|
||||||
} catch (ClipperLib::clipperException &) {
|
|
||||||
throw GeometryException(GeomErr::OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offsetting reverts the orientation and also removes the last vertex
|
|
||||||
// so boost will not have a closed polygon.
|
|
||||||
|
|
||||||
// we plan to replace contours
|
|
||||||
sh.Holes.clear();
|
|
||||||
|
|
||||||
bool found_the_contour = false;
|
|
||||||
for(auto& r : result) {
|
|
||||||
if(ClipperLib::Orientation(r)) {
|
|
||||||
// We don't like if the offsetting generates more than one contour
|
|
||||||
// but throwing would be an overkill. Instead, we should warn the
|
|
||||||
// caller about the inability to create correct geometries
|
|
||||||
if(!found_the_contour) {
|
|
||||||
sh.Contour = std::move(r);
|
|
||||||
ClipperLib::ReversePath(sh.Contour);
|
|
||||||
auto front_p = sh.Contour.front();
|
|
||||||
sh.Contour.emplace_back(std::move(front_p));
|
|
||||||
found_the_contour = true;
|
|
||||||
} else {
|
|
||||||
dout() << "Warning: offsetting result is invalid!";
|
|
||||||
/* TODO warning */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO If there are multiple contours we can't be sure which hole
|
|
||||||
// belongs to the first contour. (But in this case the situation is
|
|
||||||
// bad enough to let it go...)
|
|
||||||
sh.Holes.emplace_back(std::move(r));
|
|
||||||
ClipperLib::ReversePath(sh.Holes.back());
|
|
||||||
auto front_p = sh.Holes.back().front();
|
|
||||||
sh.Holes.back().emplace_back(std::move(front_p));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline void offset(PathImpl& sh, TCoord<PointImpl> distance, const PathTag&)
|
|
||||||
{
|
|
||||||
PolygonImpl p(std::move(sh));
|
|
||||||
offset(p, distance, PolygonTag());
|
|
||||||
sh = p.Contour;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tell libnest2d how to make string out of a ClipperPolygon object
|
|
||||||
template<> inline std::string toString(const PolygonImpl& sh)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
ss << "Contour {\n";
|
|
||||||
for(auto p : sh.Contour) {
|
|
||||||
ss << "\t" << p.X << " " << p.Y << "\n";
|
|
||||||
}
|
|
||||||
ss << "}\n";
|
|
||||||
|
|
||||||
for(auto& h : sh.Holes) {
|
|
||||||
ss << "Holes {\n";
|
|
||||||
for(auto p : h) {
|
|
||||||
ss << "\t{\n";
|
|
||||||
ss << "\t\t" << p.X << " " << p.Y << "\n";
|
|
||||||
ss << "\t}\n";
|
|
||||||
}
|
|
||||||
ss << "}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline PolygonImpl create(const PathImpl& path, const HoleStore& holes)
|
|
||||||
{
|
|
||||||
PolygonImpl p;
|
|
||||||
p.Contour = path;
|
|
||||||
p.Holes = holes;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline PolygonImpl create( PathImpl&& path, HoleStore&& holes) {
|
|
||||||
PolygonImpl p;
|
|
||||||
p.Contour.swap(path);
|
|
||||||
p.Holes.swap(holes);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline const THolesContainer<PolygonImpl>& holes(const PolygonImpl& sh)
|
|
||||||
{
|
|
||||||
return sh.Holes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline THolesContainer<PolygonImpl>& holes(PolygonImpl& sh)
|
|
||||||
{
|
|
||||||
return sh.Holes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline TContour<PolygonImpl>& hole(PolygonImpl& sh, unsigned long idx)
|
|
||||||
{
|
|
||||||
return sh.Holes[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline const TContour<PolygonImpl>& hole(const PolygonImpl& sh,
|
|
||||||
unsigned long idx)
|
|
||||||
{
|
|
||||||
return sh.Holes[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline size_t holeCount(const PolygonImpl& sh)
|
|
||||||
{
|
|
||||||
return sh.Holes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline PathImpl& contour(PolygonImpl& sh)
|
|
||||||
{
|
|
||||||
return sh.Contour;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline const PathImpl& contour(const PolygonImpl& sh)
|
|
||||||
{
|
|
||||||
return sh.Contour;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DISABLE_BOOST_TRANSLATE
|
|
||||||
template<>
|
|
||||||
inline void translate(PolygonImpl& sh, const PointImpl& offs)
|
|
||||||
{
|
|
||||||
for(auto& p : sh.Contour) { p += offs; }
|
|
||||||
for(auto& hole : sh.Holes) for(auto& p : hole) { p += offs; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DISABLE_BOOST_ROTATE
|
|
||||||
template<>
|
|
||||||
inline void rotate(PolygonImpl& sh, const Radians& rads)
|
|
||||||
{
|
|
||||||
using Coord = TCoord<PointImpl>;
|
|
||||||
|
|
||||||
auto cosa = rads.cos();
|
|
||||||
auto sina = rads.sin();
|
|
||||||
|
|
||||||
for(auto& p : sh.Contour) {
|
|
||||||
p = {
|
|
||||||
static_cast<Coord>(p.X * cosa - p.Y * sina),
|
|
||||||
static_cast<Coord>(p.X * sina + p.Y * cosa)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
for(auto& hole : sh.Holes) for(auto& p : hole) {
|
|
||||||
p = {
|
|
||||||
static_cast<Coord>(p.X * cosa - p.Y * sina),
|
|
||||||
static_cast<Coord>(p.X * sina + p.Y * cosa)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace shapelike
|
|
||||||
|
|
||||||
#define DISABLE_BOOST_NFP_MERGE
|
|
||||||
inline TMultiShape<PolygonImpl> clipper_execute(
|
|
||||||
ClipperLib::Clipper& clipper,
|
|
||||||
ClipperLib::ClipType clipType,
|
|
||||||
ClipperLib::PolyFillType subjFillType = ClipperLib::pftEvenOdd,
|
|
||||||
ClipperLib::PolyFillType clipFillType = ClipperLib::pftEvenOdd)
|
|
||||||
{
|
|
||||||
TMultiShape<PolygonImpl> retv;
|
|
||||||
|
|
||||||
ClipperLib::PolyTree result;
|
|
||||||
clipper.Execute(clipType, result, subjFillType, clipFillType);
|
|
||||||
|
|
||||||
retv.reserve(static_cast<size_t>(result.Total()));
|
|
||||||
|
|
||||||
std::function<void(ClipperLib::PolyNode*, PolygonImpl&)> processHole;
|
|
||||||
|
|
||||||
auto processPoly = [&retv, &processHole](ClipperLib::PolyNode *pptr) {
|
|
||||||
PolygonImpl poly;
|
|
||||||
poly.Contour.swap(pptr->Contour);
|
|
||||||
|
|
||||||
assert(!pptr->IsHole());
|
|
||||||
|
|
||||||
if(!poly.Contour.empty() ) {
|
|
||||||
auto front_p = poly.Contour.front();
|
|
||||||
auto &back_p = poly.Contour.back();
|
|
||||||
if(front_p.X != back_p.X || front_p.Y != back_p.X)
|
|
||||||
poly.Contour.emplace_back(front_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto h : pptr->Childs) { processHole(h, poly); }
|
|
||||||
retv.push_back(poly);
|
|
||||||
};
|
|
||||||
|
|
||||||
processHole = [&processPoly](ClipperLib::PolyNode *pptr, PolygonImpl& poly)
|
|
||||||
{
|
|
||||||
poly.Holes.emplace_back(std::move(pptr->Contour));
|
|
||||||
|
|
||||||
assert(pptr->IsHole());
|
|
||||||
|
|
||||||
if(!poly.Contour.empty() ) {
|
|
||||||
auto front_p = poly.Contour.front();
|
|
||||||
auto &back_p = poly.Contour.back();
|
|
||||||
if(front_p.X != back_p.X || front_p.Y != back_p.X)
|
|
||||||
poly.Contour.emplace_back(front_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto c : pptr->Childs) processPoly(c);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto traverse = [&processPoly] (ClipperLib::PolyNode *node)
|
|
||||||
{
|
|
||||||
for(auto ch : node->Childs) processPoly(ch);
|
|
||||||
};
|
|
||||||
|
|
||||||
traverse(&result);
|
|
||||||
|
|
||||||
return retv;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace nfp {
|
|
||||||
|
|
||||||
template<> inline TMultiShape<PolygonImpl>
|
|
||||||
merge(const TMultiShape<PolygonImpl>& shapes)
|
|
||||||
{
|
|
||||||
ClipperLib::Clipper clipper(ClipperLib::ioReverseSolution);
|
|
||||||
|
|
||||||
bool closed = true;
|
|
||||||
bool valid = true;
|
|
||||||
|
|
||||||
for(auto& path : shapes) {
|
|
||||||
valid &= clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
|
|
||||||
|
|
||||||
for(auto& h : path.Holes)
|
|
||||||
valid &= clipper.AddPath(h, ClipperLib::ptSubject, closed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!valid) throw GeometryException(GeomErr::MERGE);
|
|
||||||
|
|
||||||
return clipper_execute(clipper, ClipperLib::ctUnion, ClipperLib::pftNegative);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DISABLE_BOOST_CONVEX_HULL
|
|
||||||
|
|
||||||
//#define DISABLE_BOOST_SERIALIZE
|
|
||||||
//#define DISABLE_BOOST_UNSERIALIZE
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable: 4244)
|
|
||||||
#pragma warning(disable: 4267)
|
|
||||||
#endif
|
|
||||||
// All other operators and algorithms are implemented with boost
|
|
||||||
#include <libnest2d/utils/boost_alg.hpp>
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // CLIPPER_BACKEND_HPP
|
|
|
@ -0,0 +1,283 @@
|
||||||
|
#ifndef CLIPPER_BACKEND_HPP
|
||||||
|
#define CLIPPER_BACKEND_HPP
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <libnest2d/geometry_traits.hpp>
|
||||||
|
#include <libnest2d/geometry_traits_nfp.hpp>
|
||||||
|
|
||||||
|
#include <libslic3r/ExPolygon.hpp>
|
||||||
|
#include <libslic3r/ClipperUtils.hpp>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
template<class T, class En = void> struct IsVec_ : public std::false_type {};
|
||||||
|
|
||||||
|
template<class T> struct IsVec_< Vec<2, T> >: public std::true_type {};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static constexpr const bool IsVec = IsVec_<libnest2d::remove_cvref_t<T>>::value;
|
||||||
|
|
||||||
|
template<class T, class O> using VecOnly = std::enable_if_t<IsVec<T>, O>;
|
||||||
|
|
||||||
|
inline Point operator+(const Point& p1, const Point& p2) {
|
||||||
|
Point ret = p1;
|
||||||
|
ret += p2;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Point operator -(const Point& p ) {
|
||||||
|
Point ret = p;
|
||||||
|
ret.x() = -ret.x();
|
||||||
|
ret.y() = -ret.y();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Point operator-(const Point& p1, const Point& p2) {
|
||||||
|
Point ret = p1;
|
||||||
|
ret -= p2;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Point& operator *=(Point& p, const Point& pa ) {
|
||||||
|
p.x() *= pa.x();
|
||||||
|
p.y() *= pa.y();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Point operator*(const Point& p1, const Point& p2) {
|
||||||
|
Point ret = p1;
|
||||||
|
ret *= p2;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
namespace libnest2d {
|
||||||
|
|
||||||
|
template<class T> using Vec = Slic3r::Vec<2, T>;
|
||||||
|
|
||||||
|
// Aliases for convinience
|
||||||
|
using PointImpl = Slic3r::Point;
|
||||||
|
using PathImpl = Slic3r::Polygon;
|
||||||
|
using HoleStore = Slic3r::Polygons;
|
||||||
|
using PolygonImpl = Slic3r::ExPolygon;
|
||||||
|
|
||||||
|
template<> struct ShapeTag<Slic3r::Vec2crd> { using Type = PointTag; };
|
||||||
|
template<> struct ShapeTag<Slic3r::Point> { using Type = PointTag; };
|
||||||
|
|
||||||
|
template<> struct ShapeTag<std::vector<Slic3r::Vec2crd>> { using Type = PathTag; };
|
||||||
|
template<> struct ShapeTag<Slic3r::Polygon> { using Type = PathTag; };
|
||||||
|
template<> struct ShapeTag<Slic3r::Points> { using Type = PathTag; };
|
||||||
|
template<> struct ShapeTag<Slic3r::ExPolygon> { using Type = PolygonTag; };
|
||||||
|
template<> struct ShapeTag<Slic3r::ExPolygons> { using Type = MultiPolygonTag; };
|
||||||
|
|
||||||
|
// Type of coordinate units used by Clipper. Enough to specialize for point,
|
||||||
|
// the rest of the types will work (Path, Polygon)
|
||||||
|
template<> struct CoordType<Slic3r::Point> {
|
||||||
|
using Type = coord_t;
|
||||||
|
static const constexpr coord_t MM_IN_COORDS = 1000000;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct CoordType<Slic3r::Vec2crd> {
|
||||||
|
using Type = coord_t;
|
||||||
|
static const constexpr coord_t MM_IN_COORDS = 1000000;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enough to specialize for path, it will work for multishape and Polygon
|
||||||
|
template<> struct PointType<std::vector<Slic3r::Vec2crd>> { using Type = Slic3r::Vec2crd; };
|
||||||
|
template<> struct PointType<Slic3r::Polygon> { using Type = Slic3r::Point; };
|
||||||
|
template<> struct PointType<Slic3r::Points> { using Type = Slic3r::Point; };
|
||||||
|
|
||||||
|
// This is crucial. CountourType refers to itself by default, so we don't have
|
||||||
|
// to secialize for clipper Path. ContourType<PathImpl>::Type is PathImpl.
|
||||||
|
template<> struct ContourType<Slic3r::ExPolygon> { using Type = Slic3r::Polygon; };
|
||||||
|
|
||||||
|
// The holes are contained in Clipper::Paths
|
||||||
|
template<> struct HolesContainer<Slic3r::ExPolygon> { using Type = Slic3r::Polygons; };
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct OrientationType<Slic3r::Polygon> {
|
||||||
|
static const constexpr Orientation Value = Orientation::COUNTER_CLOCKWISE;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct OrientationType<Slic3r::Points> {
|
||||||
|
static const constexpr Orientation Value = Orientation::COUNTER_CLOCKWISE;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ClosureType<Slic3r::Polygon> {
|
||||||
|
static const constexpr Closure Value = Closure::OPEN;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ClosureType<Slic3r::Points> {
|
||||||
|
static const constexpr Closure Value = Closure::OPEN;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct MultiShape<Slic3r::ExPolygon> { using Type = Slic3r::ExPolygons; };
|
||||||
|
template<> struct ContourType<Slic3r::ExPolygons> { using Type = Slic3r::Polygon; };
|
||||||
|
|
||||||
|
// Using the libnest2d default area implementation
|
||||||
|
#define DISABLE_BOOST_AREA
|
||||||
|
|
||||||
|
namespace shapelike {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void offset(Slic3r::ExPolygon& sh, coord_t distance, const PolygonTag&)
|
||||||
|
{
|
||||||
|
#define DISABLE_BOOST_OFFSET
|
||||||
|
auto res = Slic3r::offset_ex(sh, distance, Slic3r::ClipperLib::jtSquare);
|
||||||
|
if (!res.empty()) sh = res.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void offset(Slic3r::Polygon& sh, coord_t distance, const PathTag&)
|
||||||
|
{
|
||||||
|
auto res = Slic3r::offset(sh, distance, Slic3r::ClipperLib::jtSquare);
|
||||||
|
if (!res.empty()) sh = res.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell libnest2d how to make string out of a ClipperPolygon object
|
||||||
|
template<> inline std::string toString(const Slic3r::ExPolygon& sh)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << "Contour {\n";
|
||||||
|
for(auto &p : sh.contour.points) {
|
||||||
|
ss << "\t" << p.x() << " " << p.y() << "\n";
|
||||||
|
}
|
||||||
|
ss << "}\n";
|
||||||
|
|
||||||
|
for(auto& h : sh.holes) {
|
||||||
|
ss << "Holes {\n";
|
||||||
|
for(auto p : h.points) {
|
||||||
|
ss << "\t{\n";
|
||||||
|
ss << "\t\t" << p.x() << " " << p.y() << "\n";
|
||||||
|
ss << "\t}\n";
|
||||||
|
}
|
||||||
|
ss << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline Slic3r::ExPolygon create(const Slic3r::Polygon& path, const Slic3r::Polygons& holes)
|
||||||
|
{
|
||||||
|
Slic3r::ExPolygon p;
|
||||||
|
p.contour = path;
|
||||||
|
p.holes = holes;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline Slic3r::ExPolygon create(Slic3r::Polygon&& path, Slic3r::Polygons&& holes) {
|
||||||
|
Slic3r::ExPolygon p;
|
||||||
|
p.contour.points.swap(path.points);
|
||||||
|
p.holes.swap(holes);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const THolesContainer<PolygonImpl>& holes(const Slic3r::ExPolygon& sh)
|
||||||
|
{
|
||||||
|
return sh.holes;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline THolesContainer<PolygonImpl>& holes(Slic3r::ExPolygon& sh)
|
||||||
|
{
|
||||||
|
return sh.holes;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline Slic3r::Polygon& hole(Slic3r::ExPolygon& sh, unsigned long idx)
|
||||||
|
{
|
||||||
|
return sh.holes[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const Slic3r::Polygon& hole(const Slic3r::ExPolygon& sh, unsigned long idx)
|
||||||
|
{
|
||||||
|
return sh.holes[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline size_t holeCount(const Slic3r::ExPolygon& sh)
|
||||||
|
{
|
||||||
|
return sh.holes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline Slic3r::Polygon& contour(Slic3r::ExPolygon& sh)
|
||||||
|
{
|
||||||
|
return sh.contour;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const Slic3r::Polygon& contour(const Slic3r::ExPolygon& sh)
|
||||||
|
{
|
||||||
|
return sh.contour;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void reserve(Slic3r::Polygon& p, size_t vertex_capacity, const PathTag&)
|
||||||
|
{
|
||||||
|
p.points.reserve(vertex_capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void addVertex(Slic3r::Polygon& sh, const PathTag&, const Slic3r::Point &p)
|
||||||
|
{
|
||||||
|
sh.points.emplace_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DISABLE_BOOST_TRANSLATE
|
||||||
|
template<>
|
||||||
|
inline void translate(Slic3r::ExPolygon& sh, const Slic3r::Point& offs)
|
||||||
|
{
|
||||||
|
sh.translate(offs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DISABLE_BOOST_ROTATE
|
||||||
|
template<>
|
||||||
|
inline void rotate(Slic3r::ExPolygon& sh, const Radians& rads)
|
||||||
|
{
|
||||||
|
sh.rotate(rads);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace shapelike
|
||||||
|
|
||||||
|
namespace nfp {
|
||||||
|
|
||||||
|
#define DISABLE_BOOST_NFP_MERGE
|
||||||
|
template<>
|
||||||
|
inline TMultiShape<PolygonImpl> merge(const TMultiShape<PolygonImpl>& shapes)
|
||||||
|
{
|
||||||
|
return Slic3r::union_ex(shapes);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nfp
|
||||||
|
} // namespace libnest2d
|
||||||
|
|
||||||
|
#define DISABLE_BOOST_CONVEX_HULL
|
||||||
|
|
||||||
|
//#define DISABLE_BOOST_SERIALIZE
|
||||||
|
//#define DISABLE_BOOST_UNSERIALIZE
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4244)
|
||||||
|
#pragma warning(disable: 4267)
|
||||||
|
#endif
|
||||||
|
// All other operators and algorithms are implemented with boost
|
||||||
|
#include <libnest2d/utils/boost_alg.hpp>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CLIPPER_BACKEND_HPP
|
|
@ -128,22 +128,32 @@ template<class S> struct ContourType<DefaultMultiShape<S>> {
|
||||||
using Type = typename ContourType<S>::Type;
|
using Type = typename ContourType<S>::Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Orientation {
|
enum class Orientation { CLOCKWISE, COUNTER_CLOCKWISE };
|
||||||
CLOCKWISE,
|
|
||||||
COUNTER_CLOCKWISE
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class S>
|
template<class S>
|
||||||
struct OrientationType {
|
struct OrientationType {
|
||||||
|
|
||||||
// Default Polygon orientation that the library expects
|
// Default Polygon orientation that the library expects
|
||||||
static const Orientation Value = Orientation::CLOCKWISE;
|
static const constexpr Orientation Value = Orientation::CLOCKWISE;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> inline /*constexpr*/ bool is_clockwise() {
|
template<class T> inline constexpr bool is_clockwise() {
|
||||||
return OrientationType<TContour<T>>::Value == Orientation::CLOCKWISE;
|
return OrientationType<TContour<T>>::Value == Orientation::CLOCKWISE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline const constexpr Orientation OrientationTypeV =
|
||||||
|
OrientationType<TContour<T>>::Value;
|
||||||
|
|
||||||
|
enum class Closure { OPEN, CLOSED };
|
||||||
|
|
||||||
|
template<class S> struct ClosureType {
|
||||||
|
static const constexpr Closure Value = Closure::CLOSED;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline const constexpr Closure ClosureTypeV =
|
||||||
|
ClosureType<TContour<T>>::Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief A point pair base class for other point pairs (segment, box, ...).
|
* \brief A point pair base class for other point pairs (segment, box, ...).
|
||||||
|
@ -474,8 +484,8 @@ inline _Box<P> _Box<P>::infinite(const P& center) {
|
||||||
|
|
||||||
// It is important for Mx and My to be strictly less than half of the
|
// It is important for Mx and My to be strictly less than half of the
|
||||||
// range of type C. width(), height() and area() will not overflow this way.
|
// range of type C. width(), height() and area() will not overflow this way.
|
||||||
C Mx = C((std::numeric_limits<C>::lowest() + 2 * getX(center)) / 2.01);
|
C Mx = C((std::numeric_limits<C>::lowest() + 2 * getX(center)) / 4.01);
|
||||||
C My = C((std::numeric_limits<C>::lowest() + 2 * getY(center)) / 2.01);
|
C My = C((std::numeric_limits<C>::lowest() + 2 * getY(center)) / 4.01);
|
||||||
|
|
||||||
ret.maxCorner() = center - P{Mx, My};
|
ret.maxCorner() = center - P{Mx, My};
|
||||||
ret.minCorner() = center + P{Mx, My};
|
ret.minCorner() = center + P{Mx, My};
|
||||||
|
@ -587,9 +597,9 @@ inline void reserve(RawPath& p, size_t vertex_capacity, const PathTag&)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class S, class...Args>
|
template<class S, class...Args>
|
||||||
inline void addVertex(S& sh, const PathTag&, Args...args)
|
inline void addVertex(S& sh, const PathTag&, const TPoint<S> &p)
|
||||||
{
|
{
|
||||||
sh.emplace_back(std::forward<Args>(args)...);
|
sh.emplace_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class S, class Fn>
|
template<class S, class Fn>
|
||||||
|
@ -841,9 +851,9 @@ template<class P> auto rbegin(P& p) -> decltype(_backward(end(p)))
|
||||||
return _backward(end(p));
|
return _backward(end(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class P> auto rcbegin(const P& p) -> decltype(_backward(end(p)))
|
template<class P> auto rcbegin(const P& p) -> decltype(_backward(cend(p)))
|
||||||
{
|
{
|
||||||
return _backward(end(p));
|
return _backward(cend(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class P> auto rend(P& p) -> decltype(_backward(begin(p)))
|
template<class P> auto rend(P& p) -> decltype(_backward(begin(p)))
|
||||||
|
@ -873,16 +883,16 @@ inline void reserve(T& sh, size_t vertex_capacity) {
|
||||||
reserve(sh, vertex_capacity, Tag<T>());
|
reserve(sh, vertex_capacity, Tag<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class S, class...Args>
|
template<class S>
|
||||||
inline void addVertex(S& sh, const PolygonTag&, Args...args)
|
inline void addVertex(S& sh, const PolygonTag&, const TPoint<S> &p)
|
||||||
{
|
{
|
||||||
addVertex(contour(sh), PathTag(), std::forward<Args>(args)...);
|
addVertex(contour(sh), PathTag(), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class S, class...Args> // Tag dispatcher
|
template<class S> // Tag dispatcher
|
||||||
inline void addVertex(S& sh, Args...args)
|
inline void addVertex(S& sh, const TPoint<S> &p)
|
||||||
{
|
{
|
||||||
addVertex(sh, Tag<S>(), std::forward<Args>(args)...);
|
addVertex(sh, Tag<S>(), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class S>
|
template<class S>
|
||||||
|
|
|
@ -28,7 +28,7 @@ inline void buildPolygon(const EdgeList& edgelist,
|
||||||
|
|
||||||
auto& rsh = sl::contour(rpoly);
|
auto& rsh = sl::contour(rpoly);
|
||||||
|
|
||||||
sl::reserve(rsh, 2*edgelist.size());
|
sl::reserve(rsh, 2 * edgelist.size());
|
||||||
|
|
||||||
// Add the two vertices from the first edge into the final polygon.
|
// Add the two vertices from the first edge into the final polygon.
|
||||||
sl::addVertex(rsh, edgelist.front().first());
|
sl::addVertex(rsh, edgelist.front().first());
|
||||||
|
@ -57,7 +57,6 @@ inline void buildPolygon(const EdgeList& edgelist,
|
||||||
|
|
||||||
tmp = std::next(tmp);
|
tmp = std::next(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Container, class Iterator = typename Container::iterator>
|
template<class Container, class Iterator = typename Container::iterator>
|
||||||
|
@ -214,15 +213,24 @@ inline NfpResult<RawShape> nfpConvexOnly(const RawShape& sh,
|
||||||
// Reserve the needed memory
|
// Reserve the needed memory
|
||||||
edgelist.reserve(cap);
|
edgelist.reserve(cap);
|
||||||
sl::reserve(rsh, static_cast<unsigned long>(cap));
|
sl::reserve(rsh, static_cast<unsigned long>(cap));
|
||||||
|
auto add_edge = [&edgelist](const Vertex &v1, const Vertex &v2) {
|
||||||
|
Edge e{v1, v2};
|
||||||
|
if (e.sqlength() > 0)
|
||||||
|
edgelist.emplace_back(e);
|
||||||
|
};
|
||||||
|
|
||||||
{ // place all edges from sh into edgelist
|
{ // place all edges from sh into edgelist
|
||||||
auto first = sl::cbegin(sh);
|
auto first = sl::cbegin(sh);
|
||||||
auto next = std::next(first);
|
auto next = std::next(first);
|
||||||
|
|
||||||
while(next != sl::cend(sh)) {
|
while(next != sl::cend(sh)) {
|
||||||
edgelist.emplace_back(*(first), *(next));
|
add_edge(*(first), *(next));
|
||||||
|
|
||||||
++first; ++next;
|
++first; ++next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constexpr (ClosureTypeV<RawShape> == Closure::OPEN)
|
||||||
|
add_edge(*sl::rcbegin(sh), *sl::cbegin(sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // place all edges from other into edgelist
|
{ // place all edges from other into edgelist
|
||||||
|
@ -230,15 +238,19 @@ inline NfpResult<RawShape> nfpConvexOnly(const RawShape& sh,
|
||||||
auto next = std::next(first);
|
auto next = std::next(first);
|
||||||
|
|
||||||
while(next != sl::cend(other)) {
|
while(next != sl::cend(other)) {
|
||||||
edgelist.emplace_back(*(next), *(first));
|
add_edge(*(next), *(first));
|
||||||
|
|
||||||
++first; ++next;
|
++first; ++next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constexpr (ClosureTypeV<RawShape> == Closure::OPEN)
|
||||||
|
add_edge(*sl::cbegin(other), *sl::rcbegin(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(edgelist.begin(), edgelist.end(),
|
std::sort(edgelist.begin(), edgelist.end(),
|
||||||
[](const Edge& e1, const Edge& e2)
|
[](const Edge& e1, const Edge& e2)
|
||||||
{
|
{
|
||||||
Vertex ax(1, 0); // Unit vector for the X axis
|
const Vertex ax(1, 0); // Unit vector for the X axis
|
||||||
|
|
||||||
// get cectors from the edges
|
// get cectors from the edges
|
||||||
Vertex p1 = e1.second() - e1.first();
|
Vertex p1 = e1.second() - e1.first();
|
||||||
|
@ -284,12 +296,18 @@ inline NfpResult<RawShape> nfpConvexOnly(const RawShape& sh,
|
||||||
// If Ratio is an actual rational type, there is no precision loss
|
// If Ratio is an actual rational type, there is no precision loss
|
||||||
auto pcos1 = Ratio(lcos[0]) / lsq1 * sign * lcos[0];
|
auto pcos1 = Ratio(lcos[0]) / lsq1 * sign * lcos[0];
|
||||||
auto pcos2 = Ratio(lcos[1]) / lsq2 * sign * lcos[1];
|
auto pcos2 = Ratio(lcos[1]) / lsq2 * sign * lcos[1];
|
||||||
|
|
||||||
return q[0] < 2 ? pcos1 < pcos2 : pcos1 > pcos2;
|
if constexpr (is_clockwise<RawShape>())
|
||||||
|
return q[0] < 2 ? pcos1 < pcos2 : pcos1 > pcos2;
|
||||||
|
else
|
||||||
|
return q[0] < 2 ? pcos1 > pcos2 : pcos1 < pcos2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If in different quadrants, compare the quadrant indices only.
|
// If in different quadrants, compare the quadrant indices only.
|
||||||
return q[0] > q[1];
|
if constexpr (is_clockwise<RawShape>())
|
||||||
|
return q[0] > q[1];
|
||||||
|
else
|
||||||
|
return q[0] < q[1];
|
||||||
});
|
});
|
||||||
|
|
||||||
__nfp::buildPolygon(edgelist, rsh, top_nfp);
|
__nfp::buildPolygon(edgelist, rsh, top_nfp);
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#include <libnest2d/backends/clipper/geometries.hpp>
|
#include <libnest2d/backends/clipper/geometries.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBNEST2D_GEOMETRIES_libslic3r
|
||||||
|
#include <libnest2d/backends/libslic3r/geometries.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBNEST2D_OPTIMIZER_nlopt
|
#ifdef LIBNEST2D_OPTIMIZER_nlopt
|
||||||
// We include the stock optimizers for local and global optimization
|
// We include the stock optimizers for local and global optimization
|
||||||
#include <libnest2d/optimizers/nlopt/subplex.hpp> // Local subplex for NfpPlacer
|
#include <libnest2d/optimizers/nlopt/subplex.hpp> // Local subplex for NfpPlacer
|
||||||
|
|
|
@ -96,7 +96,7 @@ public:
|
||||||
* @return The orientation type identifier for the _Item type.
|
* @return The orientation type identifier for the _Item type.
|
||||||
*/
|
*/
|
||||||
static BP2D_CONSTEXPR Orientation orientation() {
|
static BP2D_CONSTEXPR Orientation orientation() {
|
||||||
return OrientationType<RawShape>::Value;
|
return OrientationType<TContour<RawShape>>::Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -446,44 +446,32 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Sh> Sh create_rect(TCoord<Sh> width, TCoord<Sh> height)
|
||||||
|
{
|
||||||
|
auto sh = sl::create<Sh>(
|
||||||
|
{{0, 0}, {0, height}, {width, height}, {width, 0}});
|
||||||
|
|
||||||
|
if constexpr (ClosureTypeV<Sh> == Closure::CLOSED)
|
||||||
|
sl::addVertex(sh, {0, 0});
|
||||||
|
|
||||||
|
if constexpr (OrientationTypeV<Sh> == Orientation::COUNTER_CLOCKWISE)
|
||||||
|
std::reverse(sl::begin(sh), sl::end(sh));
|
||||||
|
|
||||||
|
return sh;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Subclass of _Item for regular rectangle items.
|
* \brief Subclass of _Item for regular rectangle items.
|
||||||
*/
|
*/
|
||||||
template<class RawShape>
|
template<class Sh>
|
||||||
class _Rectangle: public _Item<RawShape> {
|
class _Rectangle: public _Item<Sh> {
|
||||||
using _Item<RawShape>::vertex;
|
using _Item<Sh>::vertex;
|
||||||
using TO = Orientation;
|
using TO = Orientation;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Unit = TCoord<TPoint<RawShape>>;
|
using Unit = TCoord<Sh>;
|
||||||
|
|
||||||
template<TO o = OrientationType<RawShape>::Value>
|
inline _Rectangle(Unit w, Unit h): _Item<Sh>{create_rect<Sh>(w, h)} {}
|
||||||
inline _Rectangle(Unit width, Unit height,
|
|
||||||
// disable this ctor if o != CLOCKWISE
|
|
||||||
enable_if_t< o == TO::CLOCKWISE, int> = 0 ):
|
|
||||||
_Item<RawShape>( sl::create<RawShape>( {
|
|
||||||
{0, 0},
|
|
||||||
{0, height},
|
|
||||||
{width, height},
|
|
||||||
{width, 0},
|
|
||||||
{0, 0}
|
|
||||||
} ))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<TO o = OrientationType<RawShape>::Value>
|
|
||||||
inline _Rectangle(Unit width, Unit height,
|
|
||||||
// disable this ctor if o != COUNTER_CLOCKWISE
|
|
||||||
enable_if_t< o == TO::COUNTER_CLOCKWISE, int> = 0 ):
|
|
||||||
_Item<RawShape>( sl::create<RawShape>( {
|
|
||||||
{0, 0},
|
|
||||||
{width, 0},
|
|
||||||
{width, height},
|
|
||||||
{0, height},
|
|
||||||
{0, 0}
|
|
||||||
} ))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Unit width() const BP2D_NOEXCEPT {
|
inline Unit width() const BP2D_NOEXCEPT {
|
||||||
return getX(vertex(2));
|
return getX(vertex(2));
|
||||||
|
|
|
@ -365,44 +365,50 @@ protected:
|
||||||
// the additional vertices for maintaning min object distance
|
// the additional vertices for maintaning min object distance
|
||||||
sl::reserve(rsh, finish-start+4);
|
sl::reserve(rsh, finish-start+4);
|
||||||
|
|
||||||
/*auto addOthers = [&rsh, finish, start, &item](){
|
auto addOthers_ = [&rsh, finish, start, &item](){
|
||||||
for(size_t i = start+1; i < finish; i++)
|
for(size_t i = start+1; i < finish; i++)
|
||||||
sl::addVertex(rsh, item.vertex(i));
|
sl::addVertex(rsh, item.vertex(i));
|
||||||
};*/
|
};
|
||||||
|
|
||||||
auto reverseAddOthers = [&rsh, finish, start, &item](){
|
auto reverseAddOthers_ = [&rsh, finish, start, &item](){
|
||||||
for(auto i = finish-1; i > start; i--)
|
for(auto i = finish-1; i > start; i--)
|
||||||
sl::addVertex(rsh, item.vertex(
|
sl::addVertex(rsh, item.vertex(static_cast<unsigned long>(i)));
|
||||||
static_cast<unsigned long>(i)));
|
};
|
||||||
|
|
||||||
|
auto addOthers = [&addOthers_, &reverseAddOthers_]() {
|
||||||
|
if constexpr (!is_clockwise<RawShape>())
|
||||||
|
addOthers_();
|
||||||
|
else
|
||||||
|
reverseAddOthers_();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Final polygon construction...
|
// Final polygon construction...
|
||||||
|
|
||||||
static_assert(OrientationType<RawShape>::Value ==
|
|
||||||
Orientation::CLOCKWISE,
|
|
||||||
"Counter clockwise toWallPoly() Unimplemented!");
|
|
||||||
|
|
||||||
// Clockwise polygon construction
|
// Clockwise polygon construction
|
||||||
|
|
||||||
sl::addVertex(rsh, topleft_vertex);
|
sl::addVertex(rsh, topleft_vertex);
|
||||||
|
|
||||||
if(dir == Dir::LEFT) reverseAddOthers();
|
if(dir == Dir::LEFT) addOthers();
|
||||||
else {
|
else {
|
||||||
sl::addVertex(rsh, getX(topleft_vertex), 0);
|
sl::addVertex(rsh, {getX(topleft_vertex), 0});
|
||||||
sl::addVertex(rsh, getX(bottomleft_vertex), 0);
|
sl::addVertex(rsh, {getX(bottomleft_vertex), 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
sl::addVertex(rsh, bottomleft_vertex);
|
sl::addVertex(rsh, bottomleft_vertex);
|
||||||
|
|
||||||
if(dir == Dir::LEFT) {
|
if(dir == Dir::LEFT) {
|
||||||
sl::addVertex(rsh, 0, getY(bottomleft_vertex));
|
sl::addVertex(rsh, {0, getY(bottomleft_vertex)});
|
||||||
sl::addVertex(rsh, 0, getY(topleft_vertex));
|
sl::addVertex(rsh, {0, getY(topleft_vertex)});
|
||||||
}
|
}
|
||||||
else reverseAddOthers();
|
else addOthers();
|
||||||
|
|
||||||
|
|
||||||
// Close the polygon
|
// Close the polygon
|
||||||
sl::addVertex(rsh, topleft_vertex);
|
if constexpr (ClosureTypeV<RawShape> == Closure::CLOSED)
|
||||||
|
sl::addVertex(rsh, topleft_vertex);
|
||||||
|
|
||||||
|
if constexpr (!is_clockwise<RawShape>())
|
||||||
|
std::reverse(rsh.begin(), rsh.end());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,8 +250,8 @@ template<class RawShape> class EdgeCache {
|
||||||
Vertex ret = edge.first();
|
Vertex ret = edge.first();
|
||||||
|
|
||||||
// Get the point on the edge which lies in ed distance from the start
|
// Get the point on the edge which lies in ed distance from the start
|
||||||
ret += { static_cast<Coord>(std::round(ed*std::cos(angle))),
|
ret += Vertex(static_cast<Coord>(std::round(ed*std::cos(angle))),
|
||||||
static_cast<Coord>(std::round(ed*std::sin(angle))) };
|
static_cast<Coord>(std::round(ed*std::sin(angle))));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -724,8 +724,7 @@ private:
|
||||||
auto rawobjfunc = [_objfunc, iv, startpos]
|
auto rawobjfunc = [_objfunc, iv, startpos]
|
||||||
(Vertex v, Item& itm)
|
(Vertex v, Item& itm)
|
||||||
{
|
{
|
||||||
auto d = v - iv;
|
auto d = (v - iv) + startpos;
|
||||||
d += startpos;
|
|
||||||
itm.translation(d);
|
itm.translation(d);
|
||||||
return _objfunc(itm);
|
return _objfunc(itm);
|
||||||
};
|
};
|
||||||
|
@ -742,8 +741,7 @@ private:
|
||||||
&item, &bin, &iv, &startpos] (const Optimum& o)
|
&item, &bin, &iv, &startpos] (const Optimum& o)
|
||||||
{
|
{
|
||||||
auto v = getNfpPoint(o);
|
auto v = getNfpPoint(o);
|
||||||
auto d = v - iv;
|
auto d = (v - iv) + startpos;
|
||||||
d += startpos;
|
|
||||||
item.translation(d);
|
item.translation(d);
|
||||||
|
|
||||||
merged_pile.emplace_back(item.transformedShape());
|
merged_pile.emplace_back(item.transformedShape());
|
||||||
|
@ -877,8 +875,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
if( best_score < global_score ) {
|
if( best_score < global_score ) {
|
||||||
auto d = getNfpPoint(optimum) - iv;
|
auto d = (getNfpPoint(optimum) - iv) + startpos;
|
||||||
d += startpos;
|
|
||||||
final_tr = d;
|
final_tr = d;
|
||||||
final_rot = initial_rot + rot;
|
final_rot = initial_rot + rot;
|
||||||
can_pack = true;
|
can_pack = true;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
// this should be removed to not confuse the compiler
|
// this should be removed to not confuse the compiler
|
||||||
// #include <libnest2d.h>
|
// #include "../libnest2d.hpp"
|
||||||
|
|
||||||
namespace bp2d {
|
namespace bp2d {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@ using libnest2d::PolygonImpl;
|
||||||
using libnest2d::PathImpl;
|
using libnest2d::PathImpl;
|
||||||
using libnest2d::Orientation;
|
using libnest2d::Orientation;
|
||||||
using libnest2d::OrientationType;
|
using libnest2d::OrientationType;
|
||||||
|
using libnest2d::OrientationTypeV;
|
||||||
|
using libnest2d::ClosureType;
|
||||||
|
using libnest2d::Closure;
|
||||||
|
using libnest2d::ClosureTypeV;
|
||||||
using libnest2d::getX;
|
using libnest2d::getX;
|
||||||
using libnest2d::getY;
|
using libnest2d::getY;
|
||||||
using libnest2d::setX;
|
using libnest2d::setX;
|
||||||
|
@ -213,8 +217,15 @@ struct ToBoostOrienation<bp2d::Orientation::COUNTER_CLOCKWISE> {
|
||||||
static const order_selector Value = counterclockwise;
|
static const order_selector Value = counterclockwise;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const bp2d::Orientation RealOrientation =
|
template<bp2d::Closure> struct ToBoostClosure {};
|
||||||
bp2d::OrientationType<bp2d::PolygonImpl>::Value;
|
|
||||||
|
template<> struct ToBoostClosure<bp2d::Closure::OPEN> {
|
||||||
|
static const constexpr closure_selector Value = closure_selector::open;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct ToBoostClosure<bp2d::Closure::CLOSED> {
|
||||||
|
static const constexpr closure_selector Value = closure_selector::closed;
|
||||||
|
};
|
||||||
|
|
||||||
// Ring implementation /////////////////////////////////////////////////////////
|
// Ring implementation /////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -225,12 +236,13 @@ template<> struct tag<bp2d::PathImpl> {
|
||||||
|
|
||||||
template<> struct point_order<bp2d::PathImpl> {
|
template<> struct point_order<bp2d::PathImpl> {
|
||||||
static const order_selector value =
|
static const order_selector value =
|
||||||
ToBoostOrienation<RealOrientation>::Value;
|
ToBoostOrienation<bp2d::OrientationTypeV<bp2d::PathImpl>>::Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// All our Paths should be closed for the bin packing application
|
// All our Paths should be closed for the bin packing application
|
||||||
template<> struct closure<bp2d::PathImpl> {
|
template<> struct closure<bp2d::PathImpl> {
|
||||||
static const closure_selector value = closed;
|
static const constexpr closure_selector value =
|
||||||
|
ToBoostClosure< bp2d::ClosureTypeV<bp2d::PathImpl> >::Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Polygon implementation //////////////////////////////////////////////////////
|
// Polygon implementation //////////////////////////////////////////////////////
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "BoundingBox.hpp"
|
#include "BoundingBox.hpp"
|
||||||
|
|
||||||
#include <libnest2d/backends/clipper/geometries.hpp>
|
#include <libnest2d/backends/libslic3r/geometries.hpp>
|
||||||
#include <libnest2d/optimizers/nlopt/subplex.hpp>
|
#include <libnest2d/optimizers/nlopt/subplex.hpp>
|
||||||
#include <libnest2d/placers/nfpplacer.hpp>
|
#include <libnest2d/placers/nfpplacer.hpp>
|
||||||
#include <libnest2d/selections/firstfit.hpp>
|
#include <libnest2d/selections/firstfit.hpp>
|
||||||
|
@ -54,23 +54,22 @@ namespace Slic3r {
|
||||||
|
|
||||||
template<class Tout = double, class = FloatingOnly<Tout>, int...EigenArgs>
|
template<class Tout = double, class = FloatingOnly<Tout>, int...EigenArgs>
|
||||||
inline constexpr Eigen::Matrix<Tout, 2, EigenArgs...> unscaled(
|
inline constexpr Eigen::Matrix<Tout, 2, EigenArgs...> unscaled(
|
||||||
const ClipperLib::IntPoint &v) noexcept
|
const Slic3r::ClipperLib::IntPoint &v) noexcept
|
||||||
{
|
{
|
||||||
return Eigen::Matrix<Tout, 2, EigenArgs...>{unscaled<Tout>(v.X),
|
return Eigen::Matrix<Tout, 2, EigenArgs...>{unscaled<Tout>(v.x()),
|
||||||
unscaled<Tout>(v.Y)};
|
unscaled<Tout>(v.y())};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace arrangement {
|
namespace arrangement {
|
||||||
|
|
||||||
using namespace libnest2d;
|
using namespace libnest2d;
|
||||||
namespace clppr = ClipperLib;
|
|
||||||
|
|
||||||
// Get the libnest2d types for clipper backend
|
// Get the libnest2d types for clipper backend
|
||||||
using Item = _Item<clppr::Polygon>;
|
using Item = _Item<ExPolygon>;
|
||||||
using Box = _Box<clppr::IntPoint>;
|
using Box = _Box<Point>;
|
||||||
using Circle = _Circle<clppr::IntPoint>;
|
using Circle = _Circle<Point>;
|
||||||
using Segment = _Segment<clppr::IntPoint>;
|
using Segment = _Segment<Point>;
|
||||||
using MultiPolygon = TMultiShape<clppr::Polygon>;
|
using MultiPolygon = ExPolygons;
|
||||||
|
|
||||||
// Summon the spatial indexing facilities from boost
|
// Summon the spatial indexing facilities from boost
|
||||||
namespace bgi = boost::geometry::index;
|
namespace bgi = boost::geometry::index;
|
||||||
|
@ -127,8 +126,8 @@ template<class TBin>
|
||||||
class AutoArranger {
|
class AutoArranger {
|
||||||
public:
|
public:
|
||||||
// Useful type shortcuts...
|
// Useful type shortcuts...
|
||||||
using Placer = typename placers::_NofitPolyPlacer<clppr::Polygon, TBin>;
|
using Placer = typename placers::_NofitPolyPlacer<ExPolygon, TBin>;
|
||||||
using Selector = selections::_FirstFitSelection<clppr::Polygon>;
|
using Selector = selections::_FirstFitSelection<ExPolygon>;
|
||||||
using Packer = _Nester<Placer, Selector>;
|
using Packer = _Nester<Placer, Selector>;
|
||||||
using PConfig = typename Packer::PlacementConfig;
|
using PConfig = typename Packer::PlacementConfig;
|
||||||
using Distance = TCoord<PointImpl>;
|
using Distance = TCoord<PointImpl>;
|
||||||
|
@ -168,7 +167,7 @@ protected:
|
||||||
// as it possibly can be but at the same time, it has to provide
|
// as it possibly can be but at the same time, it has to provide
|
||||||
// reasonable results.
|
// reasonable results.
|
||||||
std::tuple<double /*score*/, Box /*farthest point from bin center*/>
|
std::tuple<double /*score*/, Box /*farthest point from bin center*/>
|
||||||
objfunc(const Item &item, const clppr::IntPoint &bincenter)
|
objfunc(const Item &item, const Point &bincenter)
|
||||||
{
|
{
|
||||||
const double bin_area = m_bin_area;
|
const double bin_area = m_bin_area;
|
||||||
const SpatIndex& spatindex = m_rtree;
|
const SpatIndex& spatindex = m_rtree;
|
||||||
|
@ -220,12 +219,12 @@ protected:
|
||||||
|
|
||||||
switch (compute_case) {
|
switch (compute_case) {
|
||||||
case BIG_ITEM: {
|
case BIG_ITEM: {
|
||||||
const clppr::IntPoint& minc = ibb.minCorner(); // bottom left corner
|
const Point& minc = ibb.minCorner(); // bottom left corner
|
||||||
const clppr::IntPoint& maxc = ibb.maxCorner(); // top right corner
|
const Point& maxc = ibb.maxCorner(); // top right corner
|
||||||
|
|
||||||
// top left and bottom right corners
|
// top left and bottom right corners
|
||||||
clppr::IntPoint top_left{getX(minc), getY(maxc)};
|
Point top_left{getX(minc), getY(maxc)};
|
||||||
clppr::IntPoint bottom_right{getX(maxc), getY(minc)};
|
Point bottom_right{getX(maxc), getY(minc)};
|
||||||
|
|
||||||
// Now the distance of the gravity center will be calculated to the
|
// Now the distance of the gravity center will be calculated to the
|
||||||
// five anchor points and the smallest will be chosen.
|
// five anchor points and the smallest will be chosen.
|
||||||
|
@ -452,7 +451,7 @@ template<> std::function<double(const Item&)> AutoArranger<Circle>::get_objfn()
|
||||||
// Specialization for a generalized polygon.
|
// Specialization for a generalized polygon.
|
||||||
// Warning: this is unfinished business. It may or may not work.
|
// Warning: this is unfinished business. It may or may not work.
|
||||||
template<>
|
template<>
|
||||||
std::function<double(const Item &)> AutoArranger<clppr::Polygon>::get_objfn()
|
std::function<double(const Item &)> AutoArranger<ExPolygon>::get_objfn()
|
||||||
{
|
{
|
||||||
auto bincenter = sl::boundingBox(m_bin).center();
|
auto bincenter = sl::boundingBox(m_bin).center();
|
||||||
return [this, bincenter](const Item &item) {
|
return [this, bincenter](const Item &item) {
|
||||||
|
@ -521,7 +520,7 @@ void _arrange(
|
||||||
|
|
||||||
inline Box to_nestbin(const BoundingBox &bb) { return Box{{bb.min(X), bb.min(Y)}, {bb.max(X), bb.max(Y)}};}
|
inline Box to_nestbin(const BoundingBox &bb) { return Box{{bb.min(X), bb.min(Y)}, {bb.max(X), bb.max(Y)}};}
|
||||||
inline Circle to_nestbin(const CircleBed &c) { return Circle({c.center()(0), c.center()(1)}, c.radius()); }
|
inline Circle to_nestbin(const CircleBed &c) { return Circle({c.center()(0), c.center()(1)}, c.radius()); }
|
||||||
inline clppr::Polygon to_nestbin(const Polygon &p) { return sl::create<clppr::Polygon>(Slic3rMultiPoint_to_ClipperPath(p)); }
|
inline ExPolygon to_nestbin(const Polygon &p) { return ExPolygon{p}; }
|
||||||
inline Box to_nestbin(const InfiniteBed &bed) { return Box::infinite({bed.center.x(), bed.center.y()}); }
|
inline Box to_nestbin(const InfiniteBed &bed) { return Box::infinite({bed.center.x(), bed.center.y()}); }
|
||||||
|
|
||||||
inline coord_t width(const BoundingBox& box) { return box.max.x() - box.min.x(); }
|
inline coord_t width(const BoundingBox& box) { return box.max.x() - box.min.x(); }
|
||||||
|
@ -568,19 +567,12 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
|
||||||
const Vec2crd &offs = arrpoly.translation;
|
const Vec2crd &offs = arrpoly.translation;
|
||||||
double rotation = arrpoly.rotation;
|
double rotation = arrpoly.rotation;
|
||||||
|
|
||||||
if (p.is_counter_clockwise()) p.reverse();
|
|
||||||
|
|
||||||
clppr::Polygon clpath(Slic3rMultiPoint_to_ClipperPath(p));
|
|
||||||
|
|
||||||
// This fixes:
|
// This fixes:
|
||||||
// https://github.com/prusa3d/PrusaSlicer/issues/2209
|
// https://github.com/prusa3d/PrusaSlicer/issues/2209
|
||||||
if (clpath.Contour.size() < 3)
|
if (p.points.size() < 3)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto firstp = clpath.Contour.front();
|
outp.emplace_back(std::move(p));
|
||||||
clpath.Contour.emplace_back(firstp);
|
|
||||||
|
|
||||||
outp.emplace_back(std::move(clpath));
|
|
||||||
outp.back().rotation(rotation);
|
outp.back().rotation(rotation);
|
||||||
outp.back().translation({offs.x(), offs.y()});
|
outp.back().translation({offs.x(), offs.y()});
|
||||||
outp.back().binId(arrpoly.bed_idx);
|
outp.back().binId(arrpoly.bed_idx);
|
||||||
|
@ -624,7 +616,7 @@ void arrange(ArrangePolygons & arrangables,
|
||||||
const BedT & bed,
|
const BedT & bed,
|
||||||
const ArrangeParams & params)
|
const ArrangeParams & params)
|
||||||
{
|
{
|
||||||
namespace clppr = ClipperLib;
|
namespace clppr = Slic3r::ClipperLib;
|
||||||
|
|
||||||
std::vector<Item> items, fixeditems;
|
std::vector<Item> items, fixeditems;
|
||||||
items.reserve(arrangables.size());
|
items.reserve(arrangables.size());
|
||||||
|
@ -643,8 +635,8 @@ void arrange(ArrangePolygons & arrangables,
|
||||||
_arrange(items, fixeditems, to_nestbin(bed), params, pri, cfn);
|
_arrange(items, fixeditems, to_nestbin(bed), params, pri, cfn);
|
||||||
|
|
||||||
for(size_t i = 0; i < items.size(); ++i) {
|
for(size_t i = 0; i < items.size(); ++i) {
|
||||||
clppr::IntPoint tr = items[i].translation();
|
Point tr = items[i].translation();
|
||||||
arrangables[i].translation = {coord_t(tr.X), coord_t(tr.Y)};
|
arrangables[i].translation = {coord_t(tr.x()), coord_t(tr.y())};
|
||||||
arrangables[i].rotation = items[i].rotation();
|
arrangables[i].rotation = items[i].rotation();
|
||||||
arrangables[i].bed_idx = items[i].binId();
|
arrangables[i].bed_idx = items[i].binId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,24 +225,11 @@ BoundingBox3Base<PointClass>::max_size() const
|
||||||
template coordf_t BoundingBox3Base<Vec3f>::max_size() const;
|
template coordf_t BoundingBox3Base<Vec3f>::max_size() const;
|
||||||
template coordf_t BoundingBox3Base<Vec3d>::max_size() const;
|
template coordf_t BoundingBox3Base<Vec3d>::max_size() const;
|
||||||
|
|
||||||
// Align a coordinate to a grid. The coordinate may be negative,
|
|
||||||
// the aligned value will never be bigger than the original one.
|
|
||||||
static inline coord_t _align_to_grid(const coord_t coord, const coord_t spacing) {
|
|
||||||
// Current C++ standard defines the result of integer division to be rounded to zero,
|
|
||||||
// for both positive and negative numbers. Here we want to round down for negative
|
|
||||||
// numbers as well.
|
|
||||||
coord_t aligned = (coord < 0) ?
|
|
||||||
((coord - spacing + 1) / spacing) * spacing :
|
|
||||||
(coord / spacing) * spacing;
|
|
||||||
assert(aligned <= coord);
|
|
||||||
return aligned;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoundingBox::align_to_grid(const coord_t cell_size)
|
void BoundingBox::align_to_grid(const coord_t cell_size)
|
||||||
{
|
{
|
||||||
if (this->defined) {
|
if (this->defined) {
|
||||||
min(0) = _align_to_grid(min(0), cell_size);
|
min(0) = Slic3r::align_to_grid(min(0), cell_size);
|
||||||
min(1) = _align_to_grid(min(1), cell_size);
|
min(1) = Slic3r::align_to_grid(min(1), cell_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ void BridgeDetector::initialize()
|
||||||
this->angle = -1.;
|
this->angle = -1.;
|
||||||
|
|
||||||
// Outset our bridge by an arbitrary amout; we'll use this outer margin for detecting anchors.
|
// Outset our bridge by an arbitrary amout; we'll use this outer margin for detecting anchors.
|
||||||
Polygons grown = offset(to_polygons(this->expolygons), float(this->spacing));
|
Polygons grown = offset(this->expolygons, float(this->spacing));
|
||||||
|
|
||||||
// Detect possible anchoring edges of this bridging region.
|
// Detect possible anchoring edges of this bridging region.
|
||||||
// Detect what edges lie on lower slices by turning bridge contour and holes
|
// Detect what edges lie on lower slices by turning bridge contour and holes
|
||||||
|
@ -227,29 +227,33 @@ void ExPolygon::get_trapezoids(ExPolygon clone, Polygons* polygons, double angle
|
||||||
// This algorithm may return more trapezoids than necessary
|
// This algorithm may return more trapezoids than necessary
|
||||||
// (i.e. it may break a single trapezoid in several because
|
// (i.e. it may break a single trapezoid in several because
|
||||||
// other parts of the object have x coordinates in the middle)
|
// other parts of the object have x coordinates in the middle)
|
||||||
static void get_trapezoids2(const ExPolygon &expoly, Polygons* polygons)
|
static void get_trapezoids2(const ExPolygon& expoly, Polygons* polygons)
|
||||||
{
|
{
|
||||||
Polygons src_polygons = to_polygons(expoly);
|
Polygons src_polygons = to_polygons(expoly);
|
||||||
// get all points of this ExPolygon
|
// get all points of this ExPolygon
|
||||||
const Points pp = to_points(src_polygons);
|
const Points pp = to_points(src_polygons);
|
||||||
|
|
||||||
// build our bounding box
|
// build our bounding box
|
||||||
BoundingBox bb(pp);
|
BoundingBox bb(pp);
|
||||||
|
|
||||||
// get all x coordinates
|
// get all x coordinates
|
||||||
std::vector<coord_t> xx;
|
std::vector<coord_t> xx;
|
||||||
xx.reserve(pp.size());
|
xx.reserve(pp.size());
|
||||||
for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p)
|
for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p)
|
||||||
xx.push_back(p->x());
|
xx.push_back(p->x());
|
||||||
std::sort(xx.begin(), xx.end());
|
std::sort(xx.begin(), xx.end());
|
||||||
|
|
||||||
// find trapezoids by looping from first to next-to-last coordinate
|
// find trapezoids by looping from first to next-to-last coordinate
|
||||||
|
Polygons rectangle;
|
||||||
|
rectangle.emplace_back(Polygon());
|
||||||
for (std::vector<coord_t>::const_iterator x = xx.begin(); x != xx.end()-1; ++x) {
|
for (std::vector<coord_t>::const_iterator x = xx.begin(); x != xx.end()-1; ++x) {
|
||||||
coord_t next_x = *(x + 1);
|
coord_t next_x = *(x + 1);
|
||||||
if (*x != next_x)
|
if (*x != next_x) {
|
||||||
// intersect with rectangle
|
// intersect with rectangle
|
||||||
// append results to return value
|
// append results to return value
|
||||||
polygons_append(*polygons, intersection({ { { *x, bb.min.y() }, { next_x, bb.min.y() }, { next_x, bb.max.y() }, { *x, bb.max.y() } } }, src_polygons));
|
rectangle.front() = { { *x, bb.min.y() }, { next_x, bb.min.y() }, { next_x, bb.max.y() }, { *x, bb.max.y() } };
|
||||||
|
polygons_append(*polygons, intersection(rectangle, src_polygons));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +306,7 @@ Polygons BridgeDetector::coverage(double angle) const
|
||||||
covered = union_(covered);
|
covered = union_(covered);
|
||||||
// Intersect trapezoids with actual bridge area to remove extra margins and append it to result.
|
// Intersect trapezoids with actual bridge area to remove extra margins and append it to result.
|
||||||
polygons_rotate(covered, -(PI/2.0 - angle));
|
polygons_rotate(covered, -(PI/2.0 - angle));
|
||||||
covered = intersection(covered, to_polygons(this->expolygons));
|
covered = intersection(this->expolygons, covered);
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
my @lines = map @{$_->lines}, @$trapezoids;
|
my @lines = map @{$_->lines}, @$trapezoids;
|
||||||
|
|
|
@ -78,7 +78,7 @@ static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print)
|
||||||
// Assign the maximum Z from four points. This values is valid index of the island
|
// Assign the maximum Z from four points. This values is valid index of the island
|
||||||
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot,
|
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot,
|
||||||
const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) {
|
const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) {
|
||||||
pt.Z = std::max(std::max(e1bot.Z, e1top.Z), std::max(e2bot.Z, e2top.Z));
|
pt.z() = std::max(std::max(e1bot.z(), e1top.z()), std::max(e2bot.z(), e2top.z()));
|
||||||
});
|
});
|
||||||
// Add islands
|
// Add islands
|
||||||
clipper.AddPaths(islands_clip, ClipperLib_Z::ptSubject, true);
|
clipper.AddPaths(islands_clip, ClipperLib_Z::ptSubject, true);
|
||||||
|
@ -90,9 +90,9 @@ static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print)
|
||||||
ConstPrintObjectPtrs top_level_objects_with_brim;
|
ConstPrintObjectPtrs top_level_objects_with_brim;
|
||||||
for (int i = 0; i < islands_polytree.ChildCount(); ++i) {
|
for (int i = 0; i < islands_polytree.ChildCount(); ++i) {
|
||||||
for (const ClipperLib_Z::IntPoint &point : islands_polytree.Childs[i]->Contour) {
|
for (const ClipperLib_Z::IntPoint &point : islands_polytree.Childs[i]->Contour) {
|
||||||
if (point.Z != 0 && processed_objects_idx.find(island_to_object[point.Z - 1]->id().id) == processed_objects_idx.end()) {
|
if (point.z() != 0 && processed_objects_idx.find(island_to_object[point.z() - 1]->id().id) == processed_objects_idx.end()) {
|
||||||
top_level_objects_with_brim.emplace_back(island_to_object[point.Z - 1]);
|
top_level_objects_with_brim.emplace_back(island_to_object[point.z() - 1]);
|
||||||
processed_objects_idx.insert(island_to_object[point.Z - 1]->id().id);
|
processed_objects_idx.insert(island_to_object[point.z() - 1]->id().id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ static ExPolygons top_level_outer_brim_area(const Print &print, const ConstPrint
|
||||||
Polygons no_brim_area_object;
|
Polygons no_brim_area_object;
|
||||||
for (const ExPolygon &ex_poly : object->layers().front()->lslices) {
|
for (const ExPolygon &ex_poly : object->layers().front()->lslices) {
|
||||||
if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner) && is_top_outer_brim)
|
if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner) && is_top_outer_brim)
|
||||||
append(brim_area_object, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset), offset_ex(ex_poly.contour, brim_offset)));
|
append(brim_area_object, diff_ex(offset(ex_poly.contour, brim_width + brim_offset), offset(ex_poly.contour, brim_offset)));
|
||||||
|
|
||||||
if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
|
if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
|
||||||
append(no_brim_area_object, offset(ex_poly.holes, -no_brim_offset));
|
append(no_brim_area_object, offset(ex_poly.holes, -no_brim_offset));
|
||||||
|
@ -156,7 +156,7 @@ static ExPolygons top_level_outer_brim_area(const Print &print, const ConstPrint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff_ex(to_polygons(std::move(brim_area)), no_brim_area);
|
return diff_ex(brim_area, no_brim_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ExPolygons inner_brim_area(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, const float no_brim_offset)
|
static ExPolygons inner_brim_area(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, const float no_brim_offset)
|
||||||
|
@ -183,14 +183,14 @@ static ExPolygons inner_brim_area(const Print &print, const ConstPrintObjectPtrs
|
||||||
if (top_outer_brim)
|
if (top_outer_brim)
|
||||||
no_brim_area_object.emplace_back(ex_poly);
|
no_brim_area_object.emplace_back(ex_poly);
|
||||||
else
|
else
|
||||||
append(brim_area_object, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset), offset_ex(ex_poly.contour, brim_offset)));
|
append(brim_area_object, diff_ex(offset(ex_poly.contour, brim_width + brim_offset), offset(ex_poly.contour, brim_offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner)
|
if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner)
|
||||||
append(brim_area_object, diff_ex(offset_ex(ex_poly.holes, -brim_offset), offset_ex(ex_poly.holes, -brim_width - brim_offset)));
|
append(brim_area_object, diff_ex(offset_ex(ex_poly.holes, -brim_offset), offset_ex(ex_poly.holes, -brim_width - brim_offset)));
|
||||||
|
|
||||||
if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim)
|
if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim)
|
||||||
append(no_brim_area_object, offset_ex(ex_poly.contour, no_brim_offset));
|
append(no_brim_area_object, to_expolygons(offset(ex_poly.contour, no_brim_offset)));
|
||||||
|
|
||||||
if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
|
if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
|
||||||
append(no_brim_area_object, offset_ex(ex_poly.holes, -no_brim_offset));
|
append(no_brim_area_object, offset_ex(ex_poly.holes, -no_brim_offset));
|
||||||
|
@ -317,7 +317,7 @@ static void make_inner_brim(const Print &print, const ConstPrintObjectPtrs &top_
|
||||||
islands_ex = offset_ex(islands_ex, -float(flow.scaled_spacing()), jtSquare);
|
islands_ex = offset_ex(islands_ex, -float(flow.scaled_spacing()), jtSquare);
|
||||||
}
|
}
|
||||||
|
|
||||||
loops = union_pt_chained_outside_in(loops, false);
|
loops = union_pt_chained_outside_in(loops);
|
||||||
std::reverse(loops.begin(), loops.end());
|
std::reverse(loops.begin(), loops.end());
|
||||||
extrusion_entities_append_loops(brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()),
|
extrusion_entities_append_loops(brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()),
|
||||||
float(flow.width()), float(print.skirt_first_layer_height()));
|
float(flow.width()), float(print.skirt_first_layer_height()));
|
||||||
|
@ -342,7 +342,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
||||||
poly.douglas_peucker(SCALED_RESOLUTION);
|
poly.douglas_peucker(SCALED_RESOLUTION);
|
||||||
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
|
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
|
||||||
}
|
}
|
||||||
loops = union_pt_chained_outside_in(loops, false);
|
loops = union_pt_chained_outside_in(loops);
|
||||||
|
|
||||||
std::vector<Polylines> loops_pl_by_levels;
|
std::vector<Polylines> loops_pl_by_levels;
|
||||||
{
|
{
|
||||||
|
@ -456,7 +456,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
||||||
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint& e1bot, const ClipperLib_Z::IntPoint& e1top, const ClipperLib_Z::IntPoint& e2bot, const ClipperLib_Z::IntPoint& e2top, ClipperLib_Z::IntPoint& pt) {
|
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint& e1bot, const ClipperLib_Z::IntPoint& e1top, const ClipperLib_Z::IntPoint& e2bot, const ClipperLib_Z::IntPoint& e2top, ClipperLib_Z::IntPoint& pt) {
|
||||||
// Assign a valid input loop identifier. Such an identifier is strictly positive, the next line is safe even in case one side of a segment
|
// Assign a valid input loop identifier. Such an identifier is strictly positive, the next line is safe even in case one side of a segment
|
||||||
// hat the Z coordinate not set to the contour coordinate.
|
// hat the Z coordinate not set to the contour coordinate.
|
||||||
pt.Z = std::max(std::max(e1bot.Z, e1top.Z), std::max(e2bot.Z, e2top.Z));
|
pt.z() = std::max(std::max(e1bot.z(), e1top.z()), std::max(e2bot.z(), e2top.z()));
|
||||||
});
|
});
|
||||||
// add polygons
|
// add polygons
|
||||||
clipper.AddPaths(input_clip, ClipperLib_Z::ptSubject, false);
|
clipper.AddPaths(input_clip, ClipperLib_Z::ptSubject, false);
|
||||||
|
@ -474,8 +474,8 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
||||||
for (const ClipperLib_Z::Path &path : loops_trimmed) {
|
for (const ClipperLib_Z::Path &path : loops_trimmed) {
|
||||||
size_t input_idx = 0;
|
size_t input_idx = 0;
|
||||||
for (const ClipperLib_Z::IntPoint &pt : path)
|
for (const ClipperLib_Z::IntPoint &pt : path)
|
||||||
if (pt.Z > 0) {
|
if (pt.z() > 0) {
|
||||||
input_idx = (size_t)pt.Z;
|
input_idx = (size_t)pt.z();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert(input_idx != 0);
|
assert(input_idx != 0);
|
||||||
|
@ -492,14 +492,14 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
||||||
size_t j = i + 1;
|
size_t j = i + 1;
|
||||||
for (; j < loops_trimmed_order.size() && loops_trimmed_order[i].second == loops_trimmed_order[j].second; ++ j) ;
|
for (; j < loops_trimmed_order.size() && loops_trimmed_order[i].second == loops_trimmed_order[j].second; ++ j) ;
|
||||||
const ClipperLib_Z::Path &first_path = *loops_trimmed_order[i].first;
|
const ClipperLib_Z::Path &first_path = *loops_trimmed_order[i].first;
|
||||||
if (i + 1 == j && first_path.size() > 3 && first_path.front().X == first_path.back().X && first_path.front().Y == first_path.back().Y) {
|
if (i + 1 == j && first_path.size() > 3 && first_path.front().x() == first_path.back().x() && first_path.front().y() == first_path.back().y()) {
|
||||||
auto *loop = new ExtrusionLoop();
|
auto *loop = new ExtrusionLoop();
|
||||||
brim.entities.emplace_back(loop);
|
brim.entities.emplace_back(loop);
|
||||||
loop->paths.emplace_back(erSkirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height()));
|
loop->paths.emplace_back(erSkirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height()));
|
||||||
Points &points = loop->paths.front().polyline.points;
|
Points &points = loop->paths.front().polyline.points;
|
||||||
points.reserve(first_path.size());
|
points.reserve(first_path.size());
|
||||||
for (const ClipperLib_Z::IntPoint &pt : first_path)
|
for (const ClipperLib_Z::IntPoint &pt : first_path)
|
||||||
points.emplace_back(coord_t(pt.X), coord_t(pt.Y));
|
points.emplace_back(coord_t(pt.x()), coord_t(pt.y()));
|
||||||
i = j;
|
i = j;
|
||||||
} else {
|
} else {
|
||||||
//FIXME The path chaining here may not be optimal.
|
//FIXME The path chaining here may not be optimal.
|
||||||
|
@ -511,7 +511,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
||||||
Points &points = static_cast<ExtrusionPath*>(this_loop_trimmed.entities.back())->polyline.points;
|
Points &points = static_cast<ExtrusionPath*>(this_loop_trimmed.entities.back())->polyline.points;
|
||||||
points.reserve(path.size());
|
points.reserve(path.size());
|
||||||
for (const ClipperLib_Z::IntPoint &pt : path)
|
for (const ClipperLib_Z::IntPoint &pt : path)
|
||||||
points.emplace_back(coord_t(pt.X), coord_t(pt.Y));
|
points.emplace_back(coord_t(pt.x()), coord_t(pt.y()));
|
||||||
}
|
}
|
||||||
chain_and_reorder_extrusion_entities(this_loop_trimmed.entities, &last_pt);
|
chain_and_reorder_extrusion_entities(this_loop_trimmed.entities, &last_pt);
|
||||||
brim.entities.reserve(brim.entities.size() + this_loop_trimmed.entities.size());
|
brim.entities.reserve(brim.entities.size() + this_loop_trimmed.entities.size());
|
||||||
|
|
|
@ -23,6 +23,8 @@ add_library(libslic3r STATIC
|
||||||
BridgeDetector.hpp
|
BridgeDetector.hpp
|
||||||
Brim.cpp
|
Brim.cpp
|
||||||
Brim.hpp
|
Brim.hpp
|
||||||
|
clipper.cpp
|
||||||
|
clipper.hpp
|
||||||
ClipperUtils.cpp
|
ClipperUtils.cpp
|
||||||
ClipperUtils.hpp
|
ClipperUtils.hpp
|
||||||
Config.cpp
|
Config.cpp
|
||||||
|
@ -219,6 +221,9 @@ add_library(libslic3r STATIC
|
||||||
SimplifyMeshImpl.hpp
|
SimplifyMeshImpl.hpp
|
||||||
SimplifyMesh.cpp
|
SimplifyMesh.cpp
|
||||||
MarchingSquares.hpp
|
MarchingSquares.hpp
|
||||||
|
Execution/Execution.hpp
|
||||||
|
Execution/ExecutionSeq.hpp
|
||||||
|
Execution/ExecutionTBB.hpp
|
||||||
Optimize/Optimizer.hpp
|
Optimize/Optimizer.hpp
|
||||||
Optimize/NLoptOptimizer.hpp
|
Optimize/NLoptOptimizer.hpp
|
||||||
Optimize/BruteforceOptimizer.hpp
|
Optimize/BruteforceOptimizer.hpp
|
||||||
|
|
|
@ -8,218 +8,354 @@
|
||||||
#include "Surface.hpp"
|
#include "Surface.hpp"
|
||||||
|
|
||||||
// import these wherever we're included
|
// import these wherever we're included
|
||||||
using ClipperLib::jtMiter;
|
using Slic3r::ClipperLib::jtMiter;
|
||||||
using ClipperLib::jtRound;
|
using Slic3r::ClipperLib::jtRound;
|
||||||
using ClipperLib::jtSquare;
|
using Slic3r::ClipperLib::jtSquare;
|
||||||
|
|
||||||
// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library
|
static constexpr const float ClipperSafetyOffset = 10.f;
|
||||||
// for general offsetting (the offset(), offset2(), offset_ex() functions) and for the safety offset,
|
|
||||||
// which is optionally executed by other functions (union, intersection, diff).
|
#define CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
// This scaling (cca 130t) is applied over the usual SCALING_FACTOR.
|
|
||||||
// By the way, is the scalling for offset needed at all?
|
|
||||||
// The reason to apply this scaling may be to match the resolution of the double mantissa.
|
|
||||||
#define CLIPPER_OFFSET_POWER_OF_2 17
|
|
||||||
// 2^17=131072
|
|
||||||
#define CLIPPER_OFFSET_SCALE (1 << CLIPPER_OFFSET_POWER_OF_2)
|
|
||||||
#define CLIPPER_OFFSET_SCALE_ROUNDING_DELTA ((1 << (CLIPPER_OFFSET_POWER_OF_2 - 1)) - 1)
|
|
||||||
#define CLIPPER_MAX_COORD_UNSCALED (ClipperLib::hiRange / CLIPPER_OFFSET_SCALE)
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
//-----------------------------------------------------------
|
namespace ClipperUtils {
|
||||||
// legacy code from Clipper documentation
|
class PathsProviderIteratorBase {
|
||||||
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons *expolygons);
|
public:
|
||||||
Slic3r::ExPolygons PolyTreeToExPolygons(ClipperLib::PolyTree& polytree);
|
using value_type = Points;
|
||||||
//-----------------------------------------------------------
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = const Points*;
|
||||||
|
using reference = const Points&;
|
||||||
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
};
|
||||||
|
|
||||||
ClipperLib::Path Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input);
|
class EmptyPathsProvider {
|
||||||
ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const Polygons &input);
|
public:
|
||||||
ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const ExPolygons &input);
|
struct iterator : public PathsProviderIteratorBase {
|
||||||
ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const Polylines &input);
|
public:
|
||||||
Slic3r::Polygon ClipperPath_to_Slic3rPolygon(const ClipperLib::Path &input);
|
const Points& operator*() { assert(false); return s_empty_points; }
|
||||||
Slic3r::Polyline ClipperPath_to_Slic3rPolyline(const ClipperLib::Path &input);
|
// all iterators point to end.
|
||||||
Slic3r::Polygons ClipperPaths_to_Slic3rPolygons(const ClipperLib::Paths &input);
|
constexpr bool operator==(const iterator &rhs) const { return true; }
|
||||||
Slic3r::Polylines ClipperPaths_to_Slic3rPolylines(const ClipperLib::Paths &input);
|
constexpr bool operator!=(const iterator &rhs) const { return false; }
|
||||||
Slic3r::ExPolygons ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input);
|
const Points& operator++(int) { assert(false); return s_empty_points; }
|
||||||
|
constexpr iterator& operator++() { assert(false); return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr EmptyPathsProvider() {}
|
||||||
|
static constexpr iterator cend() throw() { return iterator{}; }
|
||||||
|
static constexpr iterator end() throw() { return cend(); }
|
||||||
|
static constexpr iterator cbegin() throw() { return cend(); }
|
||||||
|
static constexpr iterator begin() throw() { return cend(); }
|
||||||
|
static constexpr size_t size() throw() { return 0; }
|
||||||
|
|
||||||
|
static Points s_empty_points;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SinglePathProvider {
|
||||||
|
public:
|
||||||
|
SinglePathProvider(const Points &points) : m_points(points) {}
|
||||||
|
|
||||||
|
struct iterator : public PathsProviderIteratorBase {
|
||||||
|
public:
|
||||||
|
explicit iterator(const Points &points) : m_ptr(&points) {}
|
||||||
|
const Points& operator*() const { return *m_ptr; }
|
||||||
|
bool operator==(const iterator &rhs) const { return m_ptr == rhs.m_ptr; }
|
||||||
|
bool operator!=(const iterator &rhs) const { return !(*this == rhs); }
|
||||||
|
const Points& operator++(int) { auto out = m_ptr; m_ptr = &s_end; return *out; }
|
||||||
|
iterator& operator++() { m_ptr = &s_end; return *this; }
|
||||||
|
private:
|
||||||
|
const Points *m_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator cbegin() const { return iterator(m_points); }
|
||||||
|
iterator begin() const { return this->cbegin(); }
|
||||||
|
iterator cend() const { return iterator(s_end); }
|
||||||
|
iterator end() const { return this->cend(); }
|
||||||
|
size_t size() const { return 1; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Points &m_points;
|
||||||
|
static Points s_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename MultiPointType>
|
||||||
|
class MultiPointsProvider {
|
||||||
|
public:
|
||||||
|
MultiPointsProvider(const std::vector<MultiPointType> &multipoints) : m_multipoints(multipoints) {}
|
||||||
|
|
||||||
|
struct iterator : public PathsProviderIteratorBase {
|
||||||
|
public:
|
||||||
|
explicit iterator(typename std::vector<MultiPointType>::const_iterator it) : m_it(it) {}
|
||||||
|
const Points& operator*() const { return m_it->points; }
|
||||||
|
bool operator==(const iterator &rhs) const { return m_it == rhs.m_it; }
|
||||||
|
bool operator!=(const iterator &rhs) const { return !(*this == rhs); }
|
||||||
|
const Points& operator++(int) { return (m_it ++)->points; }
|
||||||
|
iterator& operator++() { ++ m_it; return *this; }
|
||||||
|
private:
|
||||||
|
typename std::vector<MultiPointType>::const_iterator m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator cbegin() const { return iterator(m_multipoints.begin()); }
|
||||||
|
iterator begin() const { return this->cbegin(); }
|
||||||
|
iterator cend() const { return iterator(m_multipoints.end()); }
|
||||||
|
iterator end() const { return this->cend(); }
|
||||||
|
size_t size() const { return m_multipoints.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::vector<MultiPointType> &m_multipoints;
|
||||||
|
};
|
||||||
|
|
||||||
|
using PolygonsProvider = MultiPointsProvider<Polygon>;
|
||||||
|
using PolylinesProvider = MultiPointsProvider<Polyline>;
|
||||||
|
|
||||||
|
struct ExPolygonProvider {
|
||||||
|
ExPolygonProvider(const ExPolygon &expoly) : m_expoly(expoly) {}
|
||||||
|
|
||||||
|
struct iterator : public PathsProviderIteratorBase {
|
||||||
|
public:
|
||||||
|
explicit iterator(const ExPolygon &expoly, int idx) : m_expoly(expoly), m_idx(idx) {}
|
||||||
|
const Points& operator*() const { return (m_idx == 0) ? m_expoly.contour.points : m_expoly.holes[m_idx - 1].points; }
|
||||||
|
bool operator==(const iterator &rhs) const { assert(m_expoly == rhs.m_expoly); return m_idx == rhs.m_idx; }
|
||||||
|
bool operator!=(const iterator &rhs) const { return !(*this == rhs); }
|
||||||
|
const Points& operator++(int) { const Points &out = **this; ++ m_idx; return out; }
|
||||||
|
iterator& operator++() { ++ m_idx; return *this; }
|
||||||
|
private:
|
||||||
|
const ExPolygon &m_expoly;
|
||||||
|
int m_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator cbegin() const { return iterator(m_expoly, 0); }
|
||||||
|
iterator begin() const { return this->cbegin(); }
|
||||||
|
iterator cend() const { return iterator(m_expoly, m_expoly.holes.size() + 1); }
|
||||||
|
iterator end() const { return this->cend(); }
|
||||||
|
size_t size() const { return m_expoly.holes.size() + 1; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ExPolygon &m_expoly;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExPolygonsProvider {
|
||||||
|
ExPolygonsProvider(const ExPolygons &expolygons) : m_expolygons(expolygons) {
|
||||||
|
m_size = 0;
|
||||||
|
for (const ExPolygon &expoly : expolygons)
|
||||||
|
m_size += expoly.holes.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct iterator : public PathsProviderIteratorBase {
|
||||||
|
public:
|
||||||
|
explicit iterator(ExPolygons::const_iterator it) : m_it_expolygon(it), m_idx_contour(0) {}
|
||||||
|
const Points& operator*() const { return (m_idx_contour == 0) ? m_it_expolygon->contour.points : m_it_expolygon->holes[m_idx_contour - 1].points; }
|
||||||
|
bool operator==(const iterator &rhs) const { return m_it_expolygon == rhs.m_it_expolygon && m_idx_contour == rhs.m_idx_contour; }
|
||||||
|
bool operator!=(const iterator &rhs) const { return !(*this == rhs); }
|
||||||
|
iterator& operator++() {
|
||||||
|
if (++ m_idx_contour == m_it_expolygon->holes.size() + 1) {
|
||||||
|
++ m_it_expolygon;
|
||||||
|
m_idx_contour = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Points& operator++(int) {
|
||||||
|
const Points &out = **this;
|
||||||
|
++ (*this);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ExPolygons::const_iterator m_it_expolygon;
|
||||||
|
size_t m_idx_contour;
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator cbegin() const { return iterator(m_expolygons.cbegin()); }
|
||||||
|
iterator begin() const { return this->cbegin(); }
|
||||||
|
iterator cend() const { return iterator(m_expolygons.cend()); }
|
||||||
|
iterator end() const { return this->cend(); }
|
||||||
|
size_t size() const { return m_size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ExPolygons &m_expolygons;
|
||||||
|
size_t m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SurfacesProvider {
|
||||||
|
SurfacesProvider(const Surfaces &surfaces) : m_surfaces(surfaces) {
|
||||||
|
m_size = 0;
|
||||||
|
for (const Surface &surface : surfaces)
|
||||||
|
m_size += surface.expolygon.holes.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct iterator : public PathsProviderIteratorBase {
|
||||||
|
public:
|
||||||
|
explicit iterator(Surfaces::const_iterator it) : m_it_surface(it), m_idx_contour(0) {}
|
||||||
|
const Points& operator*() const { return (m_idx_contour == 0) ? m_it_surface->expolygon.contour.points : m_it_surface->expolygon.holes[m_idx_contour - 1].points; }
|
||||||
|
bool operator==(const iterator &rhs) const { return m_it_surface == rhs.m_it_surface && m_idx_contour == rhs.m_idx_contour; }
|
||||||
|
bool operator!=(const iterator &rhs) const { return !(*this == rhs); }
|
||||||
|
iterator& operator++() {
|
||||||
|
if (++ m_idx_contour == m_it_surface->expolygon.holes.size() + 1) {
|
||||||
|
++ m_it_surface;
|
||||||
|
m_idx_contour = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Points& operator++(int) {
|
||||||
|
const Points &out = **this;
|
||||||
|
++ (*this);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Surfaces::const_iterator m_it_surface;
|
||||||
|
size_t m_idx_contour;
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator cbegin() const { return iterator(m_surfaces.cbegin()); }
|
||||||
|
iterator begin() const { return this->cbegin(); }
|
||||||
|
iterator cend() const { return iterator(m_surfaces.cend()); }
|
||||||
|
iterator end() const { return this->cend(); }
|
||||||
|
size_t size() const { return m_size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Surfaces &m_surfaces;
|
||||||
|
size_t m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SurfacesPtrProvider {
|
||||||
|
SurfacesPtrProvider(const SurfacesPtr &surfaces) : m_surfaces(surfaces) {
|
||||||
|
m_size = 0;
|
||||||
|
for (const Surface *surface : surfaces)
|
||||||
|
m_size += surface->expolygon.holes.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct iterator : public PathsProviderIteratorBase {
|
||||||
|
public:
|
||||||
|
explicit iterator(SurfacesPtr::const_iterator it) : m_it_surface(it), m_idx_contour(0) {}
|
||||||
|
const Points& operator*() const { return (m_idx_contour == 0) ? (*m_it_surface)->expolygon.contour.points : (*m_it_surface)->expolygon.holes[m_idx_contour - 1].points; }
|
||||||
|
bool operator==(const iterator &rhs) const { return m_it_surface == rhs.m_it_surface && m_idx_contour == rhs.m_idx_contour; }
|
||||||
|
bool operator!=(const iterator &rhs) const { return !(*this == rhs); }
|
||||||
|
iterator& operator++() {
|
||||||
|
if (++ m_idx_contour == (*m_it_surface)->expolygon.holes.size() + 1) {
|
||||||
|
++ m_it_surface;
|
||||||
|
m_idx_contour = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Points& operator++(int) {
|
||||||
|
const Points &out = **this;
|
||||||
|
++ (*this);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SurfacesPtr::const_iterator m_it_surface;
|
||||||
|
size_t m_idx_contour;
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator cbegin() const { return iterator(m_surfaces.cbegin()); }
|
||||||
|
iterator begin() const { return this->cbegin(); }
|
||||||
|
iterator cend() const { return iterator(m_surfaces.cend()); }
|
||||||
|
iterator end() const { return this->cend(); }
|
||||||
|
size_t size() const { return m_size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const SurfacesPtr &m_surfaces;
|
||||||
|
size_t m_size;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ExPolygons ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input);
|
||||||
|
|
||||||
// offset Polygons
|
// offset Polygons
|
||||||
ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit);
|
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit);
|
|
||||||
inline Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
inline Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
|
||||||
|
|
||||||
// offset Polylines
|
// offset Polylines
|
||||||
inline Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3)
|
Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3);
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polyline), ClipperLib::etOpenButt, delta, joinType, miterLimit)); }
|
Slic3r::Polygons offset(const Slic3r::Polylines &polylines, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3);
|
||||||
inline Slic3r::Polygons offset(const Slic3r::Polylines &polylines, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3)
|
Slic3r::Polygons offset(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polylines), ClipperLib::etOpenButt, delta, joinType, miterLimit)); }
|
Slic3r::Polygons offset(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
|
Slic3r::Polygons offset(const Slic3r::Surfaces &surfaces, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
|
Slic3r::Polygons offset(const Slic3r::SurfacesPtr &surfaces, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
|
Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
|
Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
|
Slic3r::ExPolygons offset_ex(const Slic3r::Surfaces &surfaces, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
|
|
||||||
// offset expolygons and surfaces
|
Slic3r::Polygons offset2(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType, double miterLimit);
|
Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType, double miterLimit);
|
|
||||||
inline Slic3r::Polygons offset(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(expolygon, delta, joinType, miterLimit)); }
|
|
||||||
inline Slic3r::Polygons offset(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
|
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygon, delta, joinType, miterLimit)); }
|
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
|
|
||||||
|
|
||||||
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1,
|
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
double miterLimit = 3);
|
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1,
|
Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||||
double miterLimit = 3);
|
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1,
|
|
||||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
|
||||||
double miterLimit = 3);
|
|
||||||
Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1,
|
|
||||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
|
||||||
double miterLimit = 3);
|
|
||||||
|
|
||||||
Slic3r::Polygons _clipper(ClipperLib::ClipType clipType,
|
Slic3r::Lines _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
|
||||||
Slic3r::ExPolygons _clipper_ex(ClipperLib::ClipType clipType,
|
|
||||||
const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
|
||||||
Slic3r::Polylines _clipper_pl(ClipperLib::ClipType clipType,
|
|
||||||
const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
|
||||||
Slic3r::Polylines _clipper_pl(ClipperLib::ClipType clipType,
|
|
||||||
const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
|
||||||
Slic3r::Lines _clipper_ln(ClipperLib::ClipType clipType,
|
|
||||||
const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
|
||||||
|
|
||||||
// diff
|
Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
inline Slic3r::Polygons
|
Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::Polygon &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons diff_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygon &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polylines diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
|
||||||
|
inline Slic3r::Lines diff_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false)
|
||||||
{
|
{
|
||||||
return _clipper(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
return _clipper_ln(ClipperLib::ctDifference, subject, clip, do_safety_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Slic3r::ExPolygons
|
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
Slic3r::Polygons intersection(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygon &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polygons intersection(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::ExPolygons intersection_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip, bool do_safety_offset = false);
|
||||||
|
Slic3r::Polylines intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false);
|
||||||
|
|
||||||
|
inline Slic3r::Lines intersection_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false)
|
||||||
{
|
{
|
||||||
return _clipper_ex(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
return _clipper_ln(ClipperLib::ctIntersection, subject, clip, do_safety_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Slic3r::ExPolygons
|
inline Slic3r::Lines intersection_ln(const Slic3r::Line &subject, const Slic3r::Polygons &clip, bool do_safety_offset = false)
|
||||||
diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_ex(ClipperLib::ctDifference, to_polygons(subject), to_polygons(clip), safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Polygons
|
|
||||||
diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper(ClipperLib::ctDifference, to_polygons(subject), to_polygons(clip), safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Polylines
|
|
||||||
diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_pl(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Polylines
|
|
||||||
diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_pl(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Lines
|
|
||||||
diff_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_ln(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// intersection
|
|
||||||
inline Slic3r::Polygons
|
|
||||||
intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::ExPolygons
|
|
||||||
intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_ex(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::ExPolygons
|
|
||||||
intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_ex(ClipperLib::ctIntersection, to_polygons(subject), to_polygons(clip), safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Polygons
|
|
||||||
intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper(ClipperLib::ctIntersection, to_polygons(subject), to_polygons(clip), safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Polylines
|
|
||||||
intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_pl(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Polylines
|
|
||||||
intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_pl(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Lines intersection_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_ln(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::Lines intersection_ln(const Slic3r::Line &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
|
||||||
{
|
{
|
||||||
Slic3r::Lines lines;
|
Slic3r::Lines lines;
|
||||||
lines.emplace_back(subject);
|
lines.emplace_back(subject);
|
||||||
return _clipper_ln(ClipperLib::ctIntersection, lines, clip, safety_offset_);
|
return _clipper_ln(ClipperLib::ctIntersection, lines, clip, do_safety_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// union
|
Slic3r::Polygons union_(const Slic3r::Polygons &subject, bool do_safety_offset = false);
|
||||||
inline Slic3r::Polygons union_(const Slic3r::Polygons &subject, bool safety_offset_ = false)
|
Slic3r::Polygons union_(const Slic3r::ExPolygons &subject, bool do_safety_offset = false);
|
||||||
{
|
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2, bool do_safety_offset = false);
|
||||||
return _clipper(ClipperLib::ctUnion, subject, Slic3r::Polygons(), safety_offset_);
|
Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, bool do_safety_offset = false);
|
||||||
}
|
Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons &subject);
|
||||||
|
Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject);
|
||||||
|
|
||||||
inline Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2, bool safety_offset_ = false)
|
ClipperLib::PolyTree union_pt(const Slic3r::Polygons &subject);
|
||||||
{
|
ClipperLib::PolyTree union_pt(const Slic3r::ExPolygons &subject);
|
||||||
return _clipper(ClipperLib::ctUnion, subject, subject2, safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, bool safety_offset_ = false)
|
Slic3r::Polygons union_pt_chained_outside_in(const Slic3r::Polygons &subject);
|
||||||
{
|
|
||||||
return _clipper_ex(ClipperLib::ctUnion, subject, Slic3r::Polygons(), safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons &subject, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_ex(ClipperLib::ctUnion, to_polygons(subject), Slic3r::Polygons(), safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject, bool safety_offset_ = false)
|
|
||||||
{
|
|
||||||
return _clipper_ex(ClipperLib::ctUnion, to_polygons(subject), Slic3r::Polygons(), safety_offset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClipperLib::PolyTree union_pt(const Slic3r::Polygons &subject, bool safety_offset_ = false);
|
|
||||||
ClipperLib::PolyTree union_pt(const Slic3r::ExPolygons &subject, bool safety_offset_ = false);
|
|
||||||
ClipperLib::PolyTree union_pt(Slic3r::Polygons &&subject, bool safety_offset_ = false);
|
|
||||||
ClipperLib::PolyTree union_pt(Slic3r::ExPolygons &&subject, bool safety_offset_ = false);
|
|
||||||
|
|
||||||
Slic3r::Polygons union_pt_chained_outside_in(const Slic3r::Polygons &subject, bool safety_offset_ = false);
|
|
||||||
|
|
||||||
ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes);
|
ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes);
|
||||||
|
|
||||||
|
@ -267,7 +403,7 @@ void traverse_pt(const ClipperLib::PolyNode *tree, Polygons *out)
|
||||||
if (!tree) return; // terminates recursion
|
if (!tree) return; // terminates recursion
|
||||||
|
|
||||||
// Push the contour of the current level
|
// Push the contour of the current level
|
||||||
out->emplace_back(ClipperPath_to_Slic3rPolygon(tree->Contour));
|
out->emplace_back(tree->Contour);
|
||||||
|
|
||||||
// Do the recursion for all the children.
|
// Do the recursion for all the children.
|
||||||
traverse_pt<ordering>(tree->Childs, out);
|
traverse_pt<ordering>(tree->Childs, out);
|
||||||
|
@ -286,13 +422,13 @@ void traverse_pt(const ClipperLib::PolyNode *tree, ExPolygons *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
ExPolygon level;
|
ExPolygon level;
|
||||||
level.contour = ClipperPath_to_Slic3rPolygon(tree->Contour);
|
level.contour.points = tree->Contour;
|
||||||
|
|
||||||
foreach_node<ordering>(tree->Childs,
|
foreach_node<ordering>(tree->Childs,
|
||||||
[out, &level] (const ClipperLib::PolyNode *node) {
|
[out, &level] (const ClipperLib::PolyNode *node) {
|
||||||
|
|
||||||
// Holes are collected here.
|
// Holes are collected here.
|
||||||
level.holes.emplace_back(ClipperPath_to_Slic3rPolygon(node->Contour));
|
level.holes.emplace_back(node->Contour);
|
||||||
|
|
||||||
// By doing a recursion, a new level expoly is created with the contour
|
// By doing a recursion, a new level expoly is created with the contour
|
||||||
// and holes of the lower level. Doing this for all the childs.
|
// and holes of the lower level. Doing this for all the childs.
|
||||||
|
@ -315,10 +451,9 @@ void traverse_pt(const ClipperLib::PolyNodes &nodes, ExOrJustPolygons *retval)
|
||||||
Slic3r::Polygons simplify_polygons(const Slic3r::Polygons &subject, bool preserve_collinear = false);
|
Slic3r::Polygons simplify_polygons(const Slic3r::Polygons &subject, bool preserve_collinear = false);
|
||||||
Slic3r::ExPolygons simplify_polygons_ex(const Slic3r::Polygons &subject, bool preserve_collinear = false);
|
Slic3r::ExPolygons simplify_polygons_ex(const Slic3r::Polygons &subject, bool preserve_collinear = false);
|
||||||
|
|
||||||
void safety_offset(ClipperLib::Paths* paths);
|
|
||||||
|
|
||||||
Polygons top_level_islands(const Slic3r::Polygons &polygons);
|
Polygons top_level_islands(const Slic3r::Polygons &polygons);
|
||||||
|
|
||||||
|
ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::vector<float> &deltas, double miter_limit);
|
||||||
Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||||
Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||||
ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||||
|
|
|
@ -471,8 +471,8 @@ bool ConfigBase::set_deserialize_nothrow(const t_config_option_key &opt_key_src,
|
||||||
{
|
{
|
||||||
t_config_option_key opt_key = opt_key_src;
|
t_config_option_key opt_key = opt_key_src;
|
||||||
std::string value = value_src;
|
std::string value = value_src;
|
||||||
// Both opt_key and value may be modified by _handle_legacy().
|
// Both opt_key and value may be modified by handle_legacy().
|
||||||
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by _handle_legacy().
|
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
|
||||||
this->handle_legacy(opt_key, value);
|
this->handle_legacy(opt_key, value);
|
||||||
if (opt_key.empty())
|
if (opt_key.empty())
|
||||||
// Ignore the option.
|
// Ignore the option.
|
||||||
|
|
|
@ -18,11 +18,53 @@
|
||||||
|
|
||||||
#include <boost/algorithm/string/trim.hpp>
|
#include <boost/algorithm/string/trim.hpp>
|
||||||
#include <boost/format/format_fwd.hpp>
|
#include <boost/format/format_fwd.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/property_tree/ptree_fwd.hpp>
|
#include <boost/property_tree/ptree_fwd.hpp>
|
||||||
|
|
||||||
#include <cereal/access.hpp>
|
#include <cereal/access.hpp>
|
||||||
#include <cereal/types/base_class.hpp>
|
#include <cereal/types/base_class.hpp>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
struct FloatOrPercent
|
||||||
|
{
|
||||||
|
double value;
|
||||||
|
bool percent;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class cereal::access;
|
||||||
|
template<class Archive> void serialize(Archive& ar) { ar(this->value); ar(this->percent); }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const FloatOrPercent& l, const FloatOrPercent& r) throw() { return l.value == r.value && l.percent == r.percent; }
|
||||||
|
inline bool operator!=(const FloatOrPercent& l, const FloatOrPercent& r) throw() { return !(l == r); }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template<> struct hash<Slic3r::FloatOrPercent> {
|
||||||
|
std::size_t operator()(const Slic3r::FloatOrPercent& v) const noexcept {
|
||||||
|
std::size_t seed = std::hash<double>{}(v.value);
|
||||||
|
return v.percent ? seed ^ 0x9e3779b9 : seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct hash<Slic3r::Vec2d> {
|
||||||
|
std::size_t operator()(const Slic3r::Vec2d& v) const noexcept {
|
||||||
|
std::size_t seed = std::hash<double>{}(v.x());
|
||||||
|
boost::hash_combine(seed, std::hash<double>{}(v.y()));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct hash<Slic3r::Vec3d> {
|
||||||
|
std::size_t operator()(const Slic3r::Vec3d& v) const noexcept {
|
||||||
|
std::size_t seed = std::hash<double>{}(v.x());
|
||||||
|
boost::hash_combine(seed, std::hash<double>{}(v.y()));
|
||||||
|
boost::hash_combine(seed, std::hash<double>{}(v.z()));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
// Name of the configuration option.
|
// Name of the configuration option.
|
||||||
|
@ -137,6 +179,7 @@ public:
|
||||||
virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
||||||
virtual bool operator==(const ConfigOption &rhs) const = 0;
|
virtual bool operator==(const ConfigOption &rhs) const = 0;
|
||||||
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
|
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
|
||||||
|
virtual size_t hash() const throw() = 0;
|
||||||
bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; }
|
bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; }
|
||||||
bool is_vector() const { return ! this->is_scalar(); }
|
bool is_vector() const { return ! this->is_scalar(); }
|
||||||
// If this option is nullable, then it may have its value or values set to nil.
|
// If this option is nullable, then it may have its value or values set to nil.
|
||||||
|
@ -185,8 +228,10 @@ public:
|
||||||
return this->value == static_cast<const ConfigOptionSingle<T>*>(&rhs)->value;
|
return this->value == static_cast<const ConfigOptionSingle<T>*>(&rhs)->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const T &rhs) const { return this->value == rhs; }
|
bool operator==(const T &rhs) const throw() { return this->value == rhs; }
|
||||||
bool operator!=(const T &rhs) const { return this->value != rhs; }
|
bool operator!=(const T &rhs) const throw() { return this->value != rhs; }
|
||||||
|
|
||||||
|
size_t hash() const throw() override { return std::hash<T>{}(this->value); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class cereal::access;
|
friend class cereal::access;
|
||||||
|
@ -339,8 +384,16 @@ public:
|
||||||
return this->values == static_cast<const ConfigOptionVector<T>*>(&rhs)->values;
|
return this->values == static_cast<const ConfigOptionVector<T>*>(&rhs)->values;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const std::vector<T> &rhs) const { return this->values == rhs; }
|
bool operator==(const std::vector<T> &rhs) const throw() { return this->values == rhs; }
|
||||||
bool operator!=(const std::vector<T> &rhs) const { return this->values != rhs; }
|
bool operator!=(const std::vector<T> &rhs) const throw() { return this->values != rhs; }
|
||||||
|
|
||||||
|
size_t hash() const throw() override {
|
||||||
|
std::hash<T> hasher;
|
||||||
|
size_t seed = 0;
|
||||||
|
for (const auto &v : this->values)
|
||||||
|
boost::hash_combine(seed, hasher(v));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
// Is this option overridden by another option?
|
// Is this option overridden by another option?
|
||||||
// An option overrides another option if it is not nil and not equal.
|
// An option overrides another option if it is not nil and not equal.
|
||||||
|
@ -413,7 +466,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
double getFloat() const override { return this->value; }
|
double getFloat() const override { return this->value; }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionFloat(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionFloat(*this); }
|
||||||
bool operator==(const ConfigOptionFloat &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionFloat &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
|
@ -454,7 +507,7 @@ public:
|
||||||
static ConfigOptionType static_type() { return coFloats; }
|
static ConfigOptionType static_type() { return coFloats; }
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionFloatsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionFloatsTempl(*this); }
|
||||||
bool operator==(const ConfigOptionFloatsTempl &rhs) const { return vectors_equal(this->values, rhs.values); }
|
bool operator==(const ConfigOptionFloatsTempl &rhs) const throw() { return vectors_equal(this->values, rhs.values); }
|
||||||
bool operator==(const ConfigOption &rhs) const override {
|
bool operator==(const ConfigOption &rhs) const override {
|
||||||
if (rhs.type() != this->type())
|
if (rhs.type() != this->type())
|
||||||
throw Slic3r::RuntimeError("ConfigOptionFloatsTempl: Comparing incompatible types");
|
throw Slic3r::RuntimeError("ConfigOptionFloatsTempl: Comparing incompatible types");
|
||||||
|
@ -566,7 +619,7 @@ public:
|
||||||
int getInt() const override { return this->value; }
|
int getInt() const override { return this->value; }
|
||||||
void setInt(int val) override { this->value = val; }
|
void setInt(int val) override { this->value = val; }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionInt(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionInt(*this); }
|
||||||
bool operator==(const ConfigOptionInt &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionInt &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
|
@ -606,7 +659,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionIntsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionIntsTempl(*this); }
|
||||||
ConfigOptionIntsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionIntsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionIntsTempl &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionIntsTempl &rhs) const throw() { return this->values == rhs.values; }
|
||||||
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
||||||
bool nullable() const override { return NULLABLE; }
|
bool nullable() const override { return NULLABLE; }
|
||||||
// Special "nil" value to be stored into the vector if this->supports_nil().
|
// Special "nil" value to be stored into the vector if this->supports_nil().
|
||||||
|
@ -689,7 +742,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionString(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionString(*this); }
|
||||||
ConfigOptionString& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionString& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionString &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionString &rhs) const throw() { return this->value == rhs.value; }
|
||||||
bool empty() const { return this->value.empty(); }
|
bool empty() const { return this->value.empty(); }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
|
@ -722,7 +775,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionStrings(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionStrings(*this); }
|
||||||
ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionStrings &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionStrings &rhs) const throw() { return this->values == rhs.values; }
|
||||||
bool is_nil(size_t) const override { return false; }
|
bool is_nil(size_t) const override { return false; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
|
@ -757,7 +810,8 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPercent(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPercent(*this); }
|
||||||
ConfigOptionPercent& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPercent& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPercent &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionPercent &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
double get_abs_value(double ratio_over) const { return ratio_over * this->value / 100; }
|
double get_abs_value(double ratio_over) const { return ratio_over * this->value / 100; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
|
@ -796,8 +850,8 @@ public:
|
||||||
static ConfigOptionType static_type() { return coPercents; }
|
static ConfigOptionType static_type() { return coPercents; }
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPercentsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPercentsTempl(*this); }
|
||||||
ConfigOptionPercentsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPercentsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPercentsTempl &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionPercentsTempl &rhs) const throw() { return this->values == rhs.values; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
|
@ -856,8 +910,12 @@ public:
|
||||||
assert(dynamic_cast<const ConfigOptionFloatOrPercent*>(&rhs));
|
assert(dynamic_cast<const ConfigOptionFloatOrPercent*>(&rhs));
|
||||||
return *this == *static_cast<const ConfigOptionFloatOrPercent*>(&rhs);
|
return *this == *static_cast<const ConfigOptionFloatOrPercent*>(&rhs);
|
||||||
}
|
}
|
||||||
bool operator==(const ConfigOptionFloatOrPercent &rhs) const
|
bool operator==(const ConfigOptionFloatOrPercent &rhs) const throw()
|
||||||
{ return this->value == rhs.value && this->percent == rhs.percent; }
|
{ return this->value == rhs.value && this->percent == rhs.percent; }
|
||||||
|
size_t hash() const throw() override {
|
||||||
|
size_t seed = std::hash<double>{}(this->value);
|
||||||
|
return this->percent ? seed ^ 0x9e3779b9 : seed;
|
||||||
|
}
|
||||||
double get_abs_value(double ratio_over) const
|
double get_abs_value(double ratio_over) const
|
||||||
{ return this->percent ? (ratio_over * this->value / 100) : this->value; }
|
{ return this->percent ? (ratio_over * this->value / 100) : this->value; }
|
||||||
|
|
||||||
|
@ -891,27 +949,6 @@ private:
|
||||||
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionPercent>(this), percent); }
|
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionPercent>(this), percent); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FloatOrPercent
|
|
||||||
{
|
|
||||||
double value;
|
|
||||||
bool percent;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class cereal::access;
|
|
||||||
template<class Archive> void serialize(Archive & ar) { ar(this->value); ar(this->percent); }
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(const FloatOrPercent &l, const FloatOrPercent &r)
|
|
||||||
{
|
|
||||||
return l.value == r.value && l.percent == r.percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const FloatOrPercent& l, const FloatOrPercent& r)
|
|
||||||
{
|
|
||||||
return !(l == r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool NULLABLE>
|
template<bool NULLABLE>
|
||||||
class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector<FloatOrPercent>
|
class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector<FloatOrPercent>
|
||||||
{
|
{
|
||||||
|
@ -925,13 +962,14 @@ public:
|
||||||
static ConfigOptionType static_type() { return coFloatsOrPercents; }
|
static ConfigOptionType static_type() { return coFloatsOrPercents; }
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionFloatsOrPercentsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionFloatsOrPercentsTempl(*this); }
|
||||||
bool operator==(const ConfigOptionFloatsOrPercentsTempl &rhs) const { return vectors_equal(this->values, rhs.values); }
|
bool operator==(const ConfigOptionFloatsOrPercentsTempl &rhs) const throw() { return vectors_equal(this->values, rhs.values); }
|
||||||
bool operator==(const ConfigOption &rhs) const override {
|
bool operator==(const ConfigOption &rhs) const override {
|
||||||
if (rhs.type() != this->type())
|
if (rhs.type() != this->type())
|
||||||
throw Slic3r::RuntimeError("ConfigOptionFloatsOrPercentsTempl: Comparing incompatible types");
|
throw Slic3r::RuntimeError("ConfigOptionFloatsOrPercentsTempl: Comparing incompatible types");
|
||||||
assert(dynamic_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs));
|
assert(dynamic_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs));
|
||||||
return vectors_equal(this->values, static_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs)->values);
|
return vectors_equal(this->values, static_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs)->values);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
||||||
bool nullable() const override { return NULLABLE; }
|
bool nullable() const override { return NULLABLE; }
|
||||||
// Special "nil" value to be stored into the vector if this->supports_nil().
|
// Special "nil" value to be stored into the vector if this->supports_nil().
|
||||||
|
@ -1038,7 +1076,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPoint(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPoint(*this); }
|
||||||
ConfigOptionPoint& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPoint& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPoint &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionPoint &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
|
@ -1074,7 +1112,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPoints(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPoints(*this); }
|
||||||
ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPoints &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionPoints &rhs) const throw() { return this->values == rhs.values; }
|
||||||
bool is_nil(size_t) const override { return false; }
|
bool is_nil(size_t) const override { return false; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
|
@ -1146,7 +1184,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPoint3(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPoint3(*this); }
|
||||||
ConfigOptionPoint3& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPoint3& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPoint3 &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionPoint3 &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
|
@ -1183,7 +1221,7 @@ public:
|
||||||
bool getBool() const override { return this->value; }
|
bool getBool() const override { return this->value; }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionBool(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionBool(*this); }
|
||||||
ConfigOptionBool& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionBool& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionBool &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionBool &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
|
@ -1217,7 +1255,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionBoolsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionBoolsTempl(*this); }
|
||||||
ConfigOptionBoolsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionBoolsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionBoolsTempl &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionBoolsTempl &rhs) const throw() { return this->values == rhs.values; }
|
||||||
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
||||||
bool nullable() const override { return NULLABLE; }
|
bool nullable() const override { return NULLABLE; }
|
||||||
// Special "nil" value to be stored into the vector if this->supports_nil().
|
// Special "nil" value to be stored into the vector if this->supports_nil().
|
||||||
|
@ -1311,7 +1349,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionEnum<T>(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionEnum<T>(*this); }
|
||||||
ConfigOptionEnum<T>& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionEnum<T>& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionEnum<T> &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionEnum<T> &rhs) const throw() { return this->value == rhs.value; }
|
||||||
int getInt() const override { return (int)this->value; }
|
int getInt() const override { return (int)this->value; }
|
||||||
void setInt(int val) override { this->value = T(val); }
|
void setInt(int val) override { this->value = T(val); }
|
||||||
|
|
||||||
|
@ -1397,7 +1435,7 @@ public:
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionEnumGeneric(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionEnumGeneric(*this); }
|
||||||
ConfigOptionEnumGeneric& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionEnumGeneric& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionEnumGeneric &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionEnumGeneric &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
bool operator==(const ConfigOption &rhs) const override
|
bool operator==(const ConfigOption &rhs) const override
|
||||||
{
|
{
|
||||||
|
@ -1967,8 +2005,9 @@ public:
|
||||||
int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
||||||
|
|
||||||
// In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*.
|
// In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*.
|
||||||
|
// Thus the virtual method getInt() is used to retrieve the enum value.
|
||||||
template<typename ENUM>
|
template<typename ENUM>
|
||||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return this->option<ConfigOptionEnum<ENUM>>(opt_key)->value; }
|
ENUM opt_enum(const t_config_option_key &opt_key) const { return static_cast<ENUM>(this->option(opt_key)->getInt()); }
|
||||||
|
|
||||||
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
||||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||||
|
|
|
@ -83,8 +83,8 @@ inline bool operator!=(const ExPolygon &lhs, const ExPolygon &rhs) { return lhs.
|
||||||
inline size_t number_polygons(const ExPolygons &expolys)
|
inline size_t number_polygons(const ExPolygons &expolys)
|
||||||
{
|
{
|
||||||
size_t n_polygons = 0;
|
size_t n_polygons = 0;
|
||||||
for (ExPolygons::const_iterator it = expolys.begin(); it != expolys.end(); ++ it)
|
for (const ExPolygon &ex : expolys)
|
||||||
n_polygons += it->holes.size() + 1;
|
n_polygons += ex.holes.size() + 1;
|
||||||
return n_polygons;
|
return n_polygons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +217,28 @@ inline Polygons to_polygons(const ExPolygons &src)
|
||||||
return polygons;
|
return polygons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygon &src)
|
||||||
|
{
|
||||||
|
ConstPolygonPtrs polygons;
|
||||||
|
polygons.reserve(src.holes.size() + 1);
|
||||||
|
polygons.emplace_back(&src.contour);
|
||||||
|
for (const Polygon &hole : src.holes)
|
||||||
|
polygons.emplace_back(&hole);
|
||||||
|
return polygons;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygons &src)
|
||||||
|
{
|
||||||
|
ConstPolygonPtrs polygons;
|
||||||
|
polygons.reserve(number_polygons(src));
|
||||||
|
for (const ExPolygon &expoly : src) {
|
||||||
|
polygons.emplace_back(&expoly.contour);
|
||||||
|
for (const Polygon &hole : expoly.holes)
|
||||||
|
polygons.emplace_back(&hole);
|
||||||
|
}
|
||||||
|
return polygons;
|
||||||
|
}
|
||||||
|
|
||||||
inline Polygons to_polygons(ExPolygon &&src)
|
inline Polygons to_polygons(ExPolygon &&src)
|
||||||
{
|
{
|
||||||
Polygons polygons;
|
Polygons polygons;
|
||||||
|
@ -338,6 +360,8 @@ extern std::vector<BoundingBox> get_extents_vector(const ExPolygons &polygons);
|
||||||
extern bool remove_sticks(ExPolygon &poly);
|
extern bool remove_sticks(ExPolygon &poly);
|
||||||
extern void keep_largest_contour_only(ExPolygons &polygons);
|
extern void keep_largest_contour_only(ExPolygons &polygons);
|
||||||
|
|
||||||
|
inline double area(const ExPolygon &poly) { return poly.area(); }
|
||||||
|
|
||||||
inline double area(const ExPolygons &polys)
|
inline double area(const ExPolygons &polys)
|
||||||
{
|
{
|
||||||
double s = 0.;
|
double s = 0.;
|
||||||
|
|
128
src/libslic3r/Execution/Execution.hpp
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
#ifndef EXECUTION_HPP
|
||||||
|
#define EXECUTION_HPP
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include "libslic3r/libslic3r.h"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Override for valid execution policies
|
||||||
|
template<class EP> struct IsExecutionPolicy_ : public std::false_type {};
|
||||||
|
|
||||||
|
template<class EP> constexpr bool IsExecutionPolicy =
|
||||||
|
IsExecutionPolicy_<remove_cvref_t<EP>>::value;
|
||||||
|
|
||||||
|
template<class EP, class T = void>
|
||||||
|
using ExecutionPolicyOnly = std::enable_if_t<IsExecutionPolicy<EP>, T>;
|
||||||
|
|
||||||
|
namespace execution {
|
||||||
|
|
||||||
|
// This struct needs to be specialized for each execution policy.
|
||||||
|
// See ExecutionSeq.hpp and ExecutionTBB.hpp for example.
|
||||||
|
template<class EP, class En = void> struct Traits {};
|
||||||
|
|
||||||
|
template<class EP> using AsTraits = Traits<remove_cvref_t<EP>>;
|
||||||
|
|
||||||
|
// Each execution policy should declare two types of mutexes. A a spin lock and
|
||||||
|
// a blocking mutex. These types should satisfy the BasicLockable concept.
|
||||||
|
template<class EP> using SpinningMutex = typename Traits<EP>::SpinningMutex;
|
||||||
|
template<class EP> using BlockingMutex = typename Traits<EP>::BlockingMutex;
|
||||||
|
|
||||||
|
// Query the available threads for concurrency.
|
||||||
|
template<class EP, class = ExecutionPolicyOnly<EP> >
|
||||||
|
size_t max_concurrency(const EP &ep)
|
||||||
|
{
|
||||||
|
return AsTraits<EP>::max_concurrency(ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
// foreach loop with the execution policy passed as argument. Granularity can
|
||||||
|
// be specified explicitly. max_concurrency() can be used for optimal results.
|
||||||
|
template<class EP, class It, class Fn, class = ExecutionPolicyOnly<EP>>
|
||||||
|
void for_each(const EP &ep, It from, It to, Fn &&fn, size_t granularity = 1)
|
||||||
|
{
|
||||||
|
AsTraits<EP>::for_each(ep, from, to, std::forward<Fn>(fn), granularity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A reduce operation with the execution policy passed as argument.
|
||||||
|
// mergefn has T(const T&, const T&) signature
|
||||||
|
// accessfn has T(I) signature if I is an integral type and
|
||||||
|
// T(const I::value_type &) if I is an iterator type.
|
||||||
|
template<class EP,
|
||||||
|
class I,
|
||||||
|
class MergeFn,
|
||||||
|
class T,
|
||||||
|
class AccessFn,
|
||||||
|
class = ExecutionPolicyOnly<EP> >
|
||||||
|
T reduce(const EP & ep,
|
||||||
|
I from,
|
||||||
|
I to,
|
||||||
|
const T & init,
|
||||||
|
MergeFn && mergefn,
|
||||||
|
AccessFn &&accessfn,
|
||||||
|
size_t granularity = 1)
|
||||||
|
{
|
||||||
|
return AsTraits<EP>::reduce(ep, from, to, init,
|
||||||
|
std::forward<MergeFn>(mergefn),
|
||||||
|
std::forward<AccessFn>(accessfn),
|
||||||
|
granularity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// An overload of reduce method to be used with iterators as 'from' and 'to'
|
||||||
|
// arguments. Access functor is omitted here.
|
||||||
|
template<class EP,
|
||||||
|
class I,
|
||||||
|
class MergeFn,
|
||||||
|
class T,
|
||||||
|
class = ExecutionPolicyOnly<EP> >
|
||||||
|
T reduce(const EP &ep,
|
||||||
|
I from,
|
||||||
|
I to,
|
||||||
|
const T & init,
|
||||||
|
MergeFn &&mergefn,
|
||||||
|
size_t granularity = 1)
|
||||||
|
{
|
||||||
|
return reduce(
|
||||||
|
ep, from, to, init, std::forward<MergeFn>(mergefn),
|
||||||
|
[](const auto &i) { return i; }, granularity);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EP,
|
||||||
|
class I,
|
||||||
|
class T,
|
||||||
|
class AccessFn,
|
||||||
|
class = ExecutionPolicyOnly<EP>>
|
||||||
|
T accumulate(const EP & ep,
|
||||||
|
I from,
|
||||||
|
I to,
|
||||||
|
const T & init,
|
||||||
|
AccessFn &&accessfn,
|
||||||
|
size_t granularity = 1)
|
||||||
|
{
|
||||||
|
return reduce(ep, from, to, init, std::plus<T>{},
|
||||||
|
std::forward<AccessFn>(accessfn), granularity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class EP,
|
||||||
|
class I,
|
||||||
|
class T,
|
||||||
|
class = ExecutionPolicyOnly<EP> >
|
||||||
|
T accumulate(const EP &ep,
|
||||||
|
I from,
|
||||||
|
I to,
|
||||||
|
const T & init,
|
||||||
|
size_t granularity = 1)
|
||||||
|
{
|
||||||
|
return reduce(
|
||||||
|
ep, from, to, init, std::plus<T>{}, [](const auto &i) { return i; },
|
||||||
|
granularity);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace execution_policy
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // EXECUTION_HPP
|
84
src/libslic3r/Execution/ExecutionSeq.hpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#ifndef EXECUTIONSEQ_HPP
|
||||||
|
#define EXECUTIONSEQ_HPP
|
||||||
|
|
||||||
|
#ifdef PRUSASLICER_USE_EXECUTION_STD // Conflicts with our version of TBB
|
||||||
|
#include <execution>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Execution.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Execution policy implementing dummy sequential algorithms
|
||||||
|
struct ExecutionSeq {};
|
||||||
|
|
||||||
|
template<> struct IsExecutionPolicy_<ExecutionSeq> : public std::true_type {};
|
||||||
|
|
||||||
|
static constexpr ExecutionSeq ex_seq = {};
|
||||||
|
|
||||||
|
template<class EP> struct IsSequentialEP_ { static constexpr bool value = false; };
|
||||||
|
|
||||||
|
template<> struct IsSequentialEP_<ExecutionSeq>: public std::true_type {};
|
||||||
|
#ifdef PRUSASLICER_USE_EXECUTION_STD
|
||||||
|
template<> struct IsExecutionPolicy_<std::execution::sequenced_policy>: public std::true_type {};
|
||||||
|
template<> struct IsSequentialEP_<std::execution::sequenced_policy>: public std::true_type {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class EP>
|
||||||
|
constexpr bool IsSequentialEP = IsSequentialEP_<remove_cvref_t<EP>>::value;
|
||||||
|
|
||||||
|
template<class EP, class R = EP>
|
||||||
|
using SequentialEPOnly = std::enable_if_t<IsSequentialEP<EP>, R>;
|
||||||
|
|
||||||
|
template<class EP>
|
||||||
|
struct execution::Traits<EP, SequentialEPOnly<EP, void>> {
|
||||||
|
private:
|
||||||
|
struct _Mtx { inline void lock() {} inline void unlock() {} };
|
||||||
|
|
||||||
|
template<class Fn, class It>
|
||||||
|
static IteratorOnly<It, void> loop_(It from, It to, Fn &&fn)
|
||||||
|
{
|
||||||
|
for (auto it = from; it != to; ++it) fn(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Fn, class I>
|
||||||
|
static IntegerOnly<I, void> loop_(I from, I to, Fn &&fn)
|
||||||
|
{
|
||||||
|
for (I i = from; i < to; ++i) fn(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
using SpinningMutex = _Mtx;
|
||||||
|
using BlockingMutex = _Mtx;
|
||||||
|
|
||||||
|
template<class It, class Fn>
|
||||||
|
static void for_each(const EP &,
|
||||||
|
It from,
|
||||||
|
It to,
|
||||||
|
Fn &&fn,
|
||||||
|
size_t /* ignore granularity */ = 1)
|
||||||
|
{
|
||||||
|
loop_(from, to, std::forward<Fn>(fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class I, class MergeFn, class T, class AccessFn>
|
||||||
|
static T reduce(const EP &,
|
||||||
|
I from,
|
||||||
|
I to,
|
||||||
|
const T & init,
|
||||||
|
MergeFn &&mergefn,
|
||||||
|
AccessFn &&access,
|
||||||
|
size_t /*granularity*/ = 1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
T acc = init;
|
||||||
|
loop_(from, to, [&](auto &i) { acc = mergefn(acc, access(i)); });
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t max_concurrency(const EP &) { return 1; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // EXECUTIONSEQ_HPP
|
77
src/libslic3r/Execution/ExecutionTBB.hpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#ifndef EXECUTIONTBB_HPP
|
||||||
|
#define EXECUTIONTBB_HPP
|
||||||
|
|
||||||
|
#include <tbb/spin_mutex.h>
|
||||||
|
#include <tbb/mutex.h>
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
#include <tbb/parallel_reduce.h>
|
||||||
|
#include <tbb/task_arena.h>
|
||||||
|
|
||||||
|
#include "Execution.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
struct ExecutionTBB {};
|
||||||
|
template<> struct IsExecutionPolicy_<ExecutionTBB> : public std::true_type {};
|
||||||
|
|
||||||
|
// Execution policy using Intel TBB library under the hood.
|
||||||
|
static constexpr ExecutionTBB ex_tbb = {};
|
||||||
|
|
||||||
|
template<> struct execution::Traits<ExecutionTBB> {
|
||||||
|
private:
|
||||||
|
|
||||||
|
template<class Fn, class It>
|
||||||
|
static IteratorOnly<It, void> loop_(const tbb::blocked_range<It> &range, Fn &&fn)
|
||||||
|
{
|
||||||
|
for (auto &el : range) fn(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Fn, class I>
|
||||||
|
static IntegerOnly<I, void> loop_(const tbb::blocked_range<I> &range, Fn &&fn)
|
||||||
|
{
|
||||||
|
for (I i = range.begin(); i < range.end(); ++i) fn(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
using SpinningMutex = tbb::spin_mutex;
|
||||||
|
using BlockingMutex = tbb::mutex;
|
||||||
|
|
||||||
|
template<class It, class Fn>
|
||||||
|
static void for_each(const ExecutionTBB &,
|
||||||
|
It from, It to, Fn &&fn, size_t granularity)
|
||||||
|
{
|
||||||
|
tbb::parallel_for(tbb::blocked_range{from, to, granularity},
|
||||||
|
[&fn](const auto &range) {
|
||||||
|
loop_(range, std::forward<Fn>(fn));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class I, class MergeFn, class T, class AccessFn>
|
||||||
|
static T reduce(const ExecutionTBB &,
|
||||||
|
I from,
|
||||||
|
I to,
|
||||||
|
const T &init,
|
||||||
|
MergeFn &&mergefn,
|
||||||
|
AccessFn &&access,
|
||||||
|
size_t granularity = 1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return tbb::parallel_reduce(
|
||||||
|
tbb::blocked_range{from, to, granularity}, init,
|
||||||
|
[&](const auto &range, T subinit) {
|
||||||
|
T acc = subinit;
|
||||||
|
loop_(range, [&](auto &i) { acc = mergefn(acc, access(i)); });
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
std::forward<MergeFn>(mergefn));
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t max_concurrency(const ExecutionTBB &)
|
||||||
|
{
|
||||||
|
return tbb::this_task_arena::max_concurrency();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EXECUTIONTBB_HPP
|
|
@ -14,12 +14,12 @@ namespace Slic3r {
|
||||||
|
|
||||||
void ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
|
void ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
|
||||||
{
|
{
|
||||||
this->_inflate_collection(intersection_pl((Polylines)polyline, to_polygons(collection.expolygons)), retval);
|
this->_inflate_collection(intersection_pl(Polylines{ polyline }, collection.expolygons), retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtrusionPath::subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
|
void ExtrusionPath::subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
|
||||||
{
|
{
|
||||||
this->_inflate_collection(diff_pl((Polylines)this->polyline, to_polygons(collection.expolygons)), retval);
|
this->_inflate_collection(diff_pl(Polylines{ this->polyline }, collection.expolygons), retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtrusionPath::clip_end(double distance)
|
void ExtrusionPath::clip_end(double distance)
|
||||||
|
@ -318,7 +318,7 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
||||||
case erIroning : return L("Ironing");
|
case erIroning : return L("Ironing");
|
||||||
case erBridgeInfill : return L("Bridge infill");
|
case erBridgeInfill : return L("Bridge infill");
|
||||||
case erGapFill : return L("Gap fill");
|
case erGapFill : return L("Gap fill");
|
||||||
case erSkirt : return L("Skirt");
|
case erSkirt : return L("Skirt/Brim");
|
||||||
case erSupportMaterial : return L("Support material");
|
case erSupportMaterial : return L("Support material");
|
||||||
case erSupportMaterialInterface : return L("Support material interface");
|
case erSupportMaterialInterface : return L("Support material interface");
|
||||||
case erWipeTower : return L("Wipe tower");
|
case erWipeTower : return L("Wipe tower");
|
||||||
|
@ -349,7 +349,7 @@ ExtrusionRole ExtrusionEntity::string_to_role(const std::string_view role)
|
||||||
return erBridgeInfill;
|
return erBridgeInfill;
|
||||||
else if (role == L("Gap fill"))
|
else if (role == L("Gap fill"))
|
||||||
return erGapFill;
|
return erGapFill;
|
||||||
else if (role == L("Skirt"))
|
else if (role == L("Skirt") || role == L("Skirt/Brim")) // "Skirt" is for backward compatibility with 2.3.1 and earlier
|
||||||
return erSkirt;
|
return erSkirt;
|
||||||
else if (role == L("Support material"))
|
else if (role == L("Support material"))
|
||||||
return erSupportMaterial;
|
return erSupportMaterial;
|
||||||
|
|
|
@ -203,6 +203,8 @@ public:
|
||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
||||||
const Point& last_point() const override { return this->paths.back().polyline.points.back(); }
|
const Point& last_point() const override { return this->paths.back().polyline.points.back(); }
|
||||||
|
size_t size() const { return this->paths.size(); }
|
||||||
|
bool empty() const { return this->paths.empty(); }
|
||||||
double length() const override;
|
double length() const override;
|
||||||
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
|
|
|
@ -147,7 +147,7 @@ void Fill3DHoneycomb::_fill_surface_single(
|
||||||
// align bounding box to a multiple of our honeycomb grid module
|
// align bounding box to a multiple of our honeycomb grid module
|
||||||
// (a module is 2*$distance since one $distance half-module is
|
// (a module is 2*$distance since one $distance half-module is
|
||||||
// growing while the other $distance half-module is shrinking)
|
// growing while the other $distance half-module is shrinking)
|
||||||
bb.merge(_align_to_grid(bb.min, Point(2*distance, 2*distance)));
|
bb.merge(align_to_grid(bb.min, Point(2*distance, 2*distance)));
|
||||||
|
|
||||||
// generate pattern
|
// generate pattern
|
||||||
Polylines polylines = makeGrid(
|
Polylines polylines = makeGrid(
|
||||||
|
@ -162,7 +162,7 @@ void Fill3DHoneycomb::_fill_surface_single(
|
||||||
pl.translate(bb.min);
|
pl.translate(bb.min);
|
||||||
|
|
||||||
// clip pattern to boundaries, chain the clipped polylines
|
// clip pattern to boundaries, chain the clipped polylines
|
||||||
polylines = intersection_pl(polylines, to_polygons(expolygon));
|
polylines = intersection_pl(polylines, expolygon);
|
||||||
|
|
||||||
// connect lines if needed
|
// connect lines if needed
|
||||||
if (params.dont_connect() || polylines.size() <= 1)
|
if (params.dont_connect() || polylines.size() <= 1)
|
||||||
|
|
|
@ -1368,7 +1368,7 @@ void Filler::_fill_surface_single(
|
||||||
all_polylines.reserve(lines.size());
|
all_polylines.reserve(lines.size());
|
||||||
std::transform(lines.begin(), lines.end(), std::back_inserter(all_polylines), [](const Line& l) { return Polyline{ l.a, l.b }; });
|
std::transform(lines.begin(), lines.end(), std::back_inserter(all_polylines), [](const Line& l) { return Polyline{ l.a, l.b }; });
|
||||||
// Crop all polylines
|
// Crop all polylines
|
||||||
all_polylines = intersection_pl(std::move(all_polylines), to_polygons(expolygon));
|
all_polylines = intersection_pl(std::move(all_polylines), expolygon);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,26 +133,10 @@ public:
|
||||||
static void connect_infill(Polylines &&infill_ordered, const Polygons &boundary, const BoundingBox& bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms);
|
static void connect_infill(Polylines &&infill_ordered, const Polygons &boundary, const BoundingBox& bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms);
|
||||||
static void connect_infill(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary, const BoundingBox &bbox, Polylines &polylines_out, double spacing, const FillParams ¶ms);
|
static void connect_infill(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary, const BoundingBox &bbox, Polylines &polylines_out, double spacing, const FillParams ¶ms);
|
||||||
|
|
||||||
static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);
|
static void connect_base_support(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms);
|
||||||
|
static void connect_base_support(Polylines &&infill_ordered, const Polygons &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms);
|
||||||
|
|
||||||
// Align a coordinate to a grid. The coordinate may be negative,
|
static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);
|
||||||
// the aligned value will never be bigger than the original one.
|
|
||||||
static coord_t _align_to_grid(const coord_t coord, const coord_t spacing) {
|
|
||||||
// Current C++ standard defines the result of integer division to be rounded to zero,
|
|
||||||
// for both positive and negative numbers. Here we want to round down for negative
|
|
||||||
// numbers as well.
|
|
||||||
coord_t aligned = (coord < 0) ?
|
|
||||||
((coord - spacing + 1) / spacing) * spacing :
|
|
||||||
(coord / spacing) * spacing;
|
|
||||||
assert(aligned <= coord);
|
|
||||||
return aligned;
|
|
||||||
}
|
|
||||||
static Point _align_to_grid(Point coord, Point spacing)
|
|
||||||
{ return Point(_align_to_grid(coord(0), spacing(0)), _align_to_grid(coord(1), spacing(1))); }
|
|
||||||
static coord_t _align_to_grid(coord_t coord, coord_t spacing, coord_t base)
|
|
||||||
{ return base + _align_to_grid(coord - base, spacing); }
|
|
||||||
static Point _align_to_grid(Point coord, Point spacing, Point base)
|
|
||||||
{ return Point(_align_to_grid(coord(0), spacing(0), base(0)), _align_to_grid(coord(1), spacing(1), base(1))); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -24,16 +24,16 @@ void FillConcentric::_fill_surface_single(
|
||||||
this->spacing = unscale<double>(distance);
|
this->spacing = unscale<double>(distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons loops = to_polygons(std::move(expolygon));
|
Polygons loops = to_polygons(expolygon);
|
||||||
Polygons last = loops;
|
ExPolygons last { std::move(expolygon) };
|
||||||
while (! last.empty()) {
|
while (! last.empty()) {
|
||||||
last = offset2(last, -(distance + min_spacing/2), +min_spacing/2);
|
last = offset2_ex(last, -(distance + min_spacing/2), +min_spacing/2);
|
||||||
append(loops, last);
|
append(loops, to_polygons(last));
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate paths from the outermost to the innermost, to avoid
|
// generate paths from the outermost to the innermost, to avoid
|
||||||
// adhesion problems of the first central tiny loops
|
// adhesion problems of the first central tiny loops
|
||||||
loops = union_pt_chained_outside_in(loops, false);
|
loops = union_pt_chained_outside_in(loops);
|
||||||
|
|
||||||
// split paths using a nearest neighbor search
|
// split paths using a nearest neighbor search
|
||||||
size_t iPathFirst = polylines_out.size();
|
size_t iPathFirst = polylines_out.size();
|
||||||
|
|
|
@ -166,7 +166,7 @@ void FillGyroid::_fill_surface_single(
|
||||||
coord_t distance = coord_t(scale_(this->spacing) / density_adjusted);
|
coord_t distance = coord_t(scale_(this->spacing) / density_adjusted);
|
||||||
|
|
||||||
// align bounding box to a multiple of our grid module
|
// 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
|
// generate pattern
|
||||||
Polylines polylines = make_gyroid_waves(
|
Polylines polylines = make_gyroid_waves(
|
||||||
|
@ -180,7 +180,7 @@ void FillGyroid::_fill_surface_single(
|
||||||
for (Polyline &pl : polylines)
|
for (Polyline &pl : polylines)
|
||||||
pl.translate(bb.min);
|
pl.translate(bb.min);
|
||||||
|
|
||||||
polylines = intersection_pl(polylines, to_polygons(expolygon));
|
polylines = intersection_pl(polylines, expolygon);
|
||||||
|
|
||||||
if (! polylines.empty()) {
|
if (! polylines.empty()) {
|
||||||
// Remove very small bits, but be careful to not remove infill lines connecting thin walls!
|
// Remove very small bits, but be careful to not remove infill lines connecting thin walls!
|
||||||
|
|
|
@ -47,7 +47,7 @@ void FillHoneycomb::_fill_surface_single(
|
||||||
// extend bounding box so that our pattern will be aligned with other layers
|
// extend bounding box so that our pattern will be aligned with other layers
|
||||||
// $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
|
// $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
|
||||||
// The infill is not aligned to the object bounding box, but to a world coordinate system. Supposedly good enough.
|
// The infill is not aligned to the object bounding box, but to a world coordinate system. Supposedly good enough.
|
||||||
bounding_box.merge(_align_to_grid(bounding_box.min, Point(m.hex_width, m.pattern_height)));
|
bounding_box.merge(align_to_grid(bounding_box.min, Point(m.hex_width, m.pattern_height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
coord_t x = bounding_box.min(0);
|
coord_t x = bounding_box.min(0);
|
||||||
|
@ -73,7 +73,7 @@ void FillHoneycomb::_fill_surface_single(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
all_polylines = intersection_pl(std::move(all_polylines), to_polygons(expolygon));
|
all_polylines = intersection_pl(std::move(all_polylines), expolygon);
|
||||||
if (params.dont_connect() || all_polylines.size() <= 1)
|
if (params.dont_connect() || all_polylines.size() <= 1)
|
||||||
append(polylines_out, chain_polylines(std::move(all_polylines)));
|
append(polylines_out, chain_polylines(std::move(all_polylines)));
|
||||||
else
|
else
|
||||||
|
|
|
@ -31,7 +31,7 @@ void FillLine::_fill_surface_single(
|
||||||
} else {
|
} else {
|
||||||
// extend bounding box so that our pattern will be aligned with other layers
|
// extend bounding box so that our pattern will be aligned with other layers
|
||||||
// Transform the reference point to the rotated coordinate system.
|
// Transform the reference point to the rotated coordinate system.
|
||||||
bounding_box.merge(_align_to_grid(
|
bounding_box.merge(align_to_grid(
|
||||||
bounding_box.min,
|
bounding_box.min,
|
||||||
Point(this->_line_spacing, this->_line_spacing),
|
Point(this->_line_spacing, this->_line_spacing),
|
||||||
direction.second.rotated(- direction.first)));
|
direction.second.rotated(- direction.first)));
|
||||||
|
@ -58,7 +58,7 @@ void FillLine::_fill_surface_single(
|
||||||
pts.push_back(it->a);
|
pts.push_back(it->a);
|
||||||
pts.push_back(it->b);
|
pts.push_back(it->b);
|
||||||
}
|
}
|
||||||
Polylines polylines = intersection_pl(polylines_src, offset(to_polygons(expolygon), scale_(0.02)), false);
|
Polylines polylines = intersection_pl(polylines_src, offset(expolygon, scale_(0.02)), false);
|
||||||
|
|
||||||
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
|
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
|
||||||
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
|
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
|
||||||
|
|
|
@ -44,7 +44,7 @@ void FillPlanePath::_fill_surface_single(
|
||||||
coord_t(floor(pt.x() * distance_between_lines + 0.5)),
|
coord_t(floor(pt.x() * distance_between_lines + 0.5)),
|
||||||
coord_t(floor(pt.y() * distance_between_lines + 0.5))));
|
coord_t(floor(pt.y() * distance_between_lines + 0.5))));
|
||||||
// intersection(polylines_src, offset((Polygons)expolygon, scale_(0.02)), &polylines);
|
// intersection(polylines_src, offset((Polygons)expolygon, scale_(0.02)), &polylines);
|
||||||
polylines = intersection_pl(std::move(polylines), to_polygons(expolygon));
|
polylines = intersection_pl(std::move(polylines), expolygon);
|
||||||
Polylines chained;
|
Polylines chained;
|
||||||
if (params.dont_connect() || params.density > 0.5 || polylines.size() <= 1)
|
if (params.dont_connect() || params.density > 0.5 || polylines.size() <= 1)
|
||||||
chained = chain_polylines(std::move(polylines));
|
chained = chain_polylines(std::move(polylines));
|
||||||
|
|
|
@ -798,33 +798,44 @@ static std::vector<SegmentedIntersectionLine> slice_region_by_vertical_lines(con
|
||||||
assert(l <= this_x);
|
assert(l <= this_x);
|
||||||
assert(r >= this_x);
|
assert(r >= this_x);
|
||||||
// Calculate the intersection position in y axis. x is known.
|
// Calculate the intersection position in y axis. x is known.
|
||||||
if (p1(0) == this_x) {
|
if (p1.x() == this_x) {
|
||||||
if (p2(0) == this_x) {
|
if (p2.x() == this_x) {
|
||||||
// Ignore strictly vertical segments.
|
// Ignore strictly vertical segments.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
is.pos_p = p1(1);
|
const Point &p0 = prev_value_modulo(iPrev, contour);
|
||||||
|
if (int64_t(p0.x() - p1.x()) * int64_t(p2.x() - p1.x()) > 0) {
|
||||||
|
// Ignore points of a contour touching the infill line from one side.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
is.pos_p = p1.y();
|
||||||
is.pos_q = 1;
|
is.pos_q = 1;
|
||||||
} else if (p2(0) == this_x) {
|
} else if (p2.x() == this_x) {
|
||||||
is.pos_p = p2(1);
|
const Point &p3 = next_value_modulo(iSegment, contour);
|
||||||
|
if (int64_t(p3.x() - p2.x()) * int64_t(p1.x() - p2.x()) > 0) {
|
||||||
|
// Ignore points of a contour touching the infill line from one side.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
is.pos_p = p2.y();
|
||||||
is.pos_q = 1;
|
is.pos_q = 1;
|
||||||
} else {
|
} else {
|
||||||
// First calculate the intersection parameter 't' as a rational number with non negative denominator.
|
// First calculate the intersection parameter 't' as a rational number with non negative denominator.
|
||||||
if (p2(0) > p1(0)) {
|
if (p2.x() > p1.x()) {
|
||||||
is.pos_p = this_x - p1(0);
|
is.pos_p = this_x - p1.x();
|
||||||
is.pos_q = p2(0) - p1(0);
|
is.pos_q = p2.x() - p1.x();
|
||||||
} else {
|
} else {
|
||||||
is.pos_p = p1(0) - this_x;
|
is.pos_p = p1.x() - this_x;
|
||||||
is.pos_q = p1(0) - p2(0);
|
is.pos_q = p1.x() - p2.x();
|
||||||
}
|
}
|
||||||
assert(is.pos_p >= 0 && is.pos_p <= is.pos_q);
|
assert(is.pos_q > 1);
|
||||||
|
assert(is.pos_p > 0 && is.pos_p < is.pos_q);
|
||||||
// Make an intersection point from the 't'.
|
// Make an intersection point from the 't'.
|
||||||
is.pos_p *= int64_t(p2(1) - p1(1));
|
is.pos_p *= int64_t(p2.y() - p1.y());
|
||||||
is.pos_p += p1(1) * int64_t(is.pos_q);
|
is.pos_p += p1.y() * int64_t(is.pos_q);
|
||||||
}
|
}
|
||||||
// +-1 to take rounding into account.
|
// +-1 to take rounding into account.
|
||||||
assert(is.pos() + 1 >= std::min(p1(1), p2(1)));
|
assert(is.pos() + 1 >= std::min(p1.y(), p2.y()));
|
||||||
assert(is.pos() <= std::max(p1(1), p2(1)) + 1);
|
assert(is.pos() <= std::max(p1.y(), p2.y()) + 1);
|
||||||
segs[i].intersections.push_back(is);
|
segs[i].intersections.push_back(is);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -844,55 +855,46 @@ static std::vector<SegmentedIntersectionLine> slice_region_by_vertical_lines(con
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
for (size_t i = 0; i < sil.intersections.size(); ++ i) {
|
for (size_t i = 0; i < sil.intersections.size(); ++ i) {
|
||||||
// What is the orientation of the segment at the intersection point?
|
// What is the orientation of the segment at the intersection point?
|
||||||
size_t iContour = sil.intersections[i].iContour;
|
SegmentIntersection &is = sil.intersections[i];
|
||||||
const Points &contour = poly_with_offset.contour(iContour).points;
|
const size_t iContour = is.iContour;
|
||||||
size_t iSegment = sil.intersections[i].iSegment;
|
const Points &contour = poly_with_offset.contour(iContour).points;
|
||||||
size_t iPrev = ((iSegment == 0) ? contour.size() : iSegment) - 1;
|
const size_t iSegment = is.iSegment;
|
||||||
coord_t dir = contour[iSegment](0) - contour[iPrev](0);
|
const size_t iPrev = prev_idx_modulo(iSegment, contour);
|
||||||
bool low = dir > 0;
|
const coord_t dir = contour[iSegment].x() - contour[iPrev].x();
|
||||||
sil.intersections[i].type = poly_with_offset.is_contour_outer(iContour) ?
|
const bool low = dir > 0;
|
||||||
|
is.type = poly_with_offset.is_contour_outer(iContour) ?
|
||||||
(low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) :
|
(low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) :
|
||||||
(low ? SegmentIntersection::INNER_LOW : SegmentIntersection::INNER_HIGH);
|
(low ? SegmentIntersection::INNER_LOW : SegmentIntersection::INNER_HIGH);
|
||||||
if (j > 0 && sil.intersections[i].iContour == sil.intersections[j-1].iContour) {
|
bool take_next = true;
|
||||||
// Two successive intersection points on a vertical line with the same contour. This may be a special case.
|
if (j > 0) {
|
||||||
if (sil.intersections[i].pos() == sil.intersections[j-1].pos()) {
|
SegmentIntersection &is2 = sil.intersections[j - 1];
|
||||||
// Two successive segments meet exactly at the vertical line.
|
if (iContour == is2.iContour && is.pos_q == 1 && is2.pos_q == 1) {
|
||||||
#ifdef SLIC3R_DEBUG
|
// Two successive intersection points on a vertical line with the same contour, both points are end points of their respective contour segments.
|
||||||
// Verify that the segments of sil.intersections[i] and sil.intersections[j-1] are adjoint.
|
if (is.pos_p == is2.pos_p) {
|
||||||
size_t iSegment2 = sil.intersections[j-1].iSegment;
|
// Two successive segments meet exactly at the vertical line.
|
||||||
size_t iPrev2 = ((iSegment2 == 0) ? contour.size() : iSegment2) - 1;
|
// Verify that the segments of sil.intersections[i] and sil.intersections[j-1] are adjoint.
|
||||||
assert(iSegment == iPrev2 || iSegment2 == iPrev);
|
assert(iSegment == prev_idx_modulo(is2.iSegment, contour) || is2.iSegment == iPrev);
|
||||||
#endif /* SLIC3R_DEBUG */
|
assert(is.type == is2.type);
|
||||||
if (sil.intersections[i].type == sil.intersections[j-1].type) {
|
|
||||||
// Two successive segments of the same direction (both to the right or both to the left)
|
// Two successive segments of the same direction (both to the right or both to the left)
|
||||||
// meet exactly at the vertical line.
|
// meet exactly at the vertical line.
|
||||||
// Remove the second intersection point.
|
// Remove the second intersection point.
|
||||||
} else {
|
take_next = false;
|
||||||
// This is a loop returning to the same point.
|
} else if (is.type == is2.type) {
|
||||||
// It may as well be a vertex of a loop touching this vertical line.
|
// Two non successive segments of the same direction (both to the right or both to the left)
|
||||||
// Remove both the lines.
|
// meet exactly at the vertical line. That means there is a Z shaped path, where the center segment
|
||||||
-- j;
|
// of the Z shaped path is aligned with this vertical line.
|
||||||
|
// Remove one of the intersection points while maximizing the vertical segment length.
|
||||||
|
if (low) {
|
||||||
|
// Remove the second intersection point, keep the first intersection point.
|
||||||
|
} else {
|
||||||
|
// Remove the first intersection point, keep the second intersection point.
|
||||||
|
sil.intersections[j-1] = sil.intersections[i];
|
||||||
|
}
|
||||||
|
take_next = false;
|
||||||
}
|
}
|
||||||
} else if (sil.intersections[i].type == sil.intersections[j-1].type) {
|
|
||||||
// Two non successive segments of the same direction (both to the right or both to the left)
|
|
||||||
// meet exactly at the vertical line. That means there is a Z shaped path, where the center segment
|
|
||||||
// of the Z shaped path is aligned with this vertical line.
|
|
||||||
// Remove one of the intersection points while maximizing the vertical segment length.
|
|
||||||
if (low) {
|
|
||||||
// Remove the second intersection point, keep the first intersection point.
|
|
||||||
} else {
|
|
||||||
// Remove the first intersection point, keep the second intersection point.
|
|
||||||
sil.intersections[j-1] = sil.intersections[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Vertical line intersects a contour segment at a general position (not at one of its end points).
|
|
||||||
// or the contour just touches this vertical line with a vertical segment or a sequence of vertical segments.
|
|
||||||
// Keep both intersection points.
|
|
||||||
if (j < i)
|
|
||||||
sil.intersections[j] = sil.intersections[i];
|
|
||||||
++ j;
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (take_next) {
|
||||||
// Vertical line intersects a contour segment at a general position (not at one of its end points).
|
// Vertical line intersects a contour segment at a general position (not at one of its end points).
|
||||||
if (j < i)
|
if (j < i)
|
||||||
sil.intersections[j] = sil.intersections[i];
|
sil.intersections[j] = sil.intersections[i];
|
||||||
|
@ -905,7 +907,13 @@ static std::vector<SegmentedIntersectionLine> slice_region_by_vertical_lines(con
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the segments. If something is wrong, give up.
|
// Verify the segments. If something is wrong, give up.
|
||||||
#define ASSERT_THROW(CONDITION) do { assert(CONDITION); if (! (CONDITION)) throw InfillFailedException(); } while (0)
|
#ifdef INFILL_DEBUG_OUTPUT
|
||||||
|
#define INFILL_DEBUG_ASSERT(CONDITION)
|
||||||
|
try {
|
||||||
|
#else // INFILL_DEBUG_OUTPUT
|
||||||
|
#define INFILL_DEBUG_ASSERT(CONDITION) assert(CONDITION)
|
||||||
|
#endif // INFILL_DEBUG_OUTPUT
|
||||||
|
#define ASSERT_THROW(CONDITION) do { INFILL_DEBUG_ASSERT(CONDITION); if (! (CONDITION)) throw InfillFailedException(); } while (0)
|
||||||
for (size_t i_seg = 0; i_seg < segs.size(); ++ i_seg) {
|
for (size_t i_seg = 0; i_seg < segs.size(); ++ i_seg) {
|
||||||
SegmentedIntersectionLine &sil = segs[i_seg];
|
SegmentedIntersectionLine &sil = segs[i_seg];
|
||||||
// The intersection points have to be even.
|
// The intersection points have to be even.
|
||||||
|
@ -925,6 +933,56 @@ static std::vector<SegmentedIntersectionLine> slice_region_by_vertical_lines(con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef ASSERT_THROW
|
#undef ASSERT_THROW
|
||||||
|
#undef INFILL_DEBUG_ASSERT
|
||||||
|
#ifdef INFILL_DEBUG_OUTPUT
|
||||||
|
} catch (const InfillFailedException & /* ex */) {
|
||||||
|
// Export the buggy result into an SVG file.
|
||||||
|
static int iRun = 0;
|
||||||
|
BoundingBox bbox = get_extents(poly_with_offset.polygons_src);
|
||||||
|
bbox.offset(scale_(3.));
|
||||||
|
::Slic3r::SVG svg(debug_out_path("slice_region_by_vertical_lines-failed-%d.svg", iRun ++), bbox);
|
||||||
|
svg.draw(poly_with_offset.polygons_src);
|
||||||
|
svg.draw_outline(poly_with_offset.polygons_src, "green");
|
||||||
|
svg.draw_outline(poly_with_offset.polygons_outer, "green");
|
||||||
|
svg.draw_outline(poly_with_offset.polygons_inner, "green");
|
||||||
|
for (size_t i_seg = 0; i_seg < segs.size(); ++i_seg) {
|
||||||
|
SegmentedIntersectionLine &sil = segs[i_seg];
|
||||||
|
for (size_t i = 0; i < sil.intersections.size();) {
|
||||||
|
// An intersection segment crossing the bigger contour may cross the inner offsetted contour even number of times.
|
||||||
|
if (sil.intersections[i].type != SegmentIntersection::OUTER_LOW) {
|
||||||
|
svg.draw(Point(sil.pos, sil.intersections[i].pos()), "red");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size_t j = i + 1;
|
||||||
|
if (j == sil.intersections.size()) {
|
||||||
|
svg.draw(Point(sil.pos, sil.intersections[i].pos()), "magenta");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! (sil.intersections[j].type == SegmentIntersection::INNER_LOW || sil.intersections[j].type == SegmentIntersection::OUTER_HIGH)) {
|
||||||
|
svg.draw(Point(sil.pos, sil.intersections[j].pos()), "blue");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (; j < sil.intersections.size() && sil.intersections[j].is_inner(); ++j);
|
||||||
|
if (j == sil.intersections.size()) {
|
||||||
|
svg.draw(Point(sil.pos, sil.intersections[j - 1].pos()), "magenta");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((j & 1) != 1 || sil.intersections[j].type != SegmentIntersection::OUTER_HIGH) {
|
||||||
|
svg.draw(Point(sil.pos, sil.intersections[j].pos()), "red");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! (i + 1 == j || sil.intersections[j - 1].type == SegmentIntersection::INNER_HIGH)) {
|
||||||
|
svg.draw(Point(sil.pos, sil.intersections[j].pos()), "red");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
svg.draw(Line(Point(sil.pos, sil.intersections[i].pos()), Point(sil.pos, sil.intersections[j].pos())), "black");
|
||||||
|
i = j + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#endif //INFILL_DEBUG_OUTPUT
|
||||||
|
|
||||||
return segs;
|
return segs;
|
||||||
}
|
}
|
||||||
|
@ -2714,10 +2772,10 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
|
||||||
// extend bounding box so that our pattern will be aligned with other layers
|
// extend bounding box so that our pattern will be aligned with other layers
|
||||||
// Transform the reference point to the rotated coordinate system.
|
// Transform the reference point to the rotated coordinate system.
|
||||||
Point refpt = rotate_vector.second.rotated(- rotate_vector.first);
|
Point refpt = rotate_vector.second.rotated(- rotate_vector.first);
|
||||||
// _align_to_grid will not work correctly with positive pattern_shift.
|
// align_to_grid will not work correctly with positive pattern_shift.
|
||||||
coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
|
coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
|
||||||
refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
|
refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
|
||||||
bounding_box.merge(_align_to_grid(
|
bounding_box.merge(align_to_grid(
|
||||||
bounding_box.min,
|
bounding_box.min,
|
||||||
Point(line_spacing, line_spacing),
|
Point(line_spacing, line_spacing),
|
||||||
refpt));
|
refpt));
|
||||||
|
@ -2825,6 +2883,45 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void make_fill_lines(const ExPolygonWithOffset &poly_with_offset, Point refpt, double angle, coord_t x_margin, coord_t line_spacing, coord_t pattern_shift, Polylines &fill_lines)
|
||||||
|
{
|
||||||
|
BoundingBox bounding_box = poly_with_offset.bounding_box_src();
|
||||||
|
// Don't produce infill lines, which fully overlap with the infill perimeter.
|
||||||
|
coord_t x_min = bounding_box.min.x() + x_margin;
|
||||||
|
coord_t x_max = bounding_box.max.x() - x_margin;
|
||||||
|
// extend bounding box so that our pattern will be aligned with other layers
|
||||||
|
// align_to_grid will not work correctly with positive pattern_shift.
|
||||||
|
coord_t pattern_shift_scaled = pattern_shift % line_spacing;
|
||||||
|
refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
|
||||||
|
bounding_box.merge(Slic3r::align_to_grid(bounding_box.min, Point(line_spacing, line_spacing), refpt));
|
||||||
|
|
||||||
|
// Intersect a set of euqally spaced vertical lines wiht expolygon.
|
||||||
|
// n_vlines = ceil(bbox_width / line_spacing)
|
||||||
|
const size_t n_vlines = (bounding_box.max.x() - bounding_box.min.x() + line_spacing - 1) / line_spacing;
|
||||||
|
const double cos_a = cos(angle);
|
||||||
|
const double sin_a = sin(angle);
|
||||||
|
for (const SegmentedIntersectionLine &vline : slice_region_by_vertical_lines(poly_with_offset, n_vlines, bounding_box.min.x(), line_spacing))
|
||||||
|
if (vline.pos >= x_min) {
|
||||||
|
if (vline.pos > x_max)
|
||||||
|
break;
|
||||||
|
for (auto it = vline.intersections.begin(); it != vline.intersections.end();) {
|
||||||
|
auto it_low = it ++;
|
||||||
|
assert(it_low->type == SegmentIntersection::OUTER_LOW);
|
||||||
|
if (it_low->type != SegmentIntersection::OUTER_LOW)
|
||||||
|
continue;
|
||||||
|
auto it_high = it;
|
||||||
|
assert(it_high->type == SegmentIntersection::OUTER_HIGH);
|
||||||
|
if (it_high->type == SegmentIntersection::OUTER_HIGH) {
|
||||||
|
if (angle == 0.)
|
||||||
|
fill_lines.emplace_back(Point(vline.pos, it_low->pos()), Point(vline.pos, it_high->pos()));
|
||||||
|
else
|
||||||
|
fill_lines.emplace_back(Point(vline.pos, it_low->pos()).rotated(cos_a, sin_a), Point(vline.pos, it_high->pos()).rotated(cos_a, sin_a));
|
||||||
|
++ it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillParams params, const std::initializer_list<SweepParams> &sweep_params, Polylines &polylines_out)
|
bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillParams params, const std::initializer_list<SweepParams> &sweep_params, Polylines &polylines_out)
|
||||||
{
|
{
|
||||||
assert(sweep_params.size() > 1);
|
assert(sweep_params.size() > 1);
|
||||||
|
@ -2843,42 +2940,8 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar
|
||||||
std::pair<float, Point> rotate_vector = this->_infill_direction(surface);
|
std::pair<float, Point> rotate_vector = this->_infill_direction(surface);
|
||||||
for (const SweepParams &sweep : sweep_params) {
|
for (const SweepParams &sweep : sweep_params) {
|
||||||
// Rotate polygons so that we can work with vertical lines here
|
// Rotate polygons so that we can work with vertical lines here
|
||||||
double angle = rotate_vector.first + sweep.angle_base;
|
float angle = rotate_vector.first + sweep.angle_base;
|
||||||
ExPolygonWithOffset poly_with_offset(poly_with_offset_base, - angle);
|
make_fill_lines(ExPolygonWithOffset(poly_with_offset_base, - angle), rotate_vector.second.rotated(-angle), angle, line_width + coord_t(SCALED_EPSILON), line_spacing, coord_t(scale_(sweep.pattern_shift)), fill_lines);
|
||||||
BoundingBox bounding_box = poly_with_offset.bounding_box_src();
|
|
||||||
// Don't produce infill lines, which fully overlap with the infill perimeter.
|
|
||||||
coord_t x_min = bounding_box.min.x() + line_width + coord_t(SCALED_EPSILON);
|
|
||||||
coord_t x_max = bounding_box.max.x() - line_width - coord_t(SCALED_EPSILON);
|
|
||||||
// extend bounding box so that our pattern will be aligned with other layers
|
|
||||||
// Transform the reference point to the rotated coordinate system.
|
|
||||||
Point refpt = rotate_vector.second.rotated(- angle);
|
|
||||||
// _align_to_grid will not work correctly with positive pattern_shift.
|
|
||||||
coord_t pattern_shift_scaled = coord_t(scale_(sweep.pattern_shift)) % line_spacing;
|
|
||||||
refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
|
|
||||||
bounding_box.merge(_align_to_grid(bounding_box.min, Point(line_spacing, line_spacing), refpt));
|
|
||||||
|
|
||||||
// Intersect a set of euqally spaced vertical lines wiht expolygon.
|
|
||||||
// n_vlines = ceil(bbox_width / line_spacing)
|
|
||||||
const size_t n_vlines = (bounding_box.max.x() - bounding_box.min.x() + line_spacing - 1) / line_spacing;
|
|
||||||
const double cos_a = cos(angle);
|
|
||||||
const double sin_a = sin(angle);
|
|
||||||
for (const SegmentedIntersectionLine &vline : slice_region_by_vertical_lines(poly_with_offset, n_vlines, bounding_box.min.x(), line_spacing))
|
|
||||||
if (vline.pos > x_min) {
|
|
||||||
if (vline.pos >= x_max)
|
|
||||||
break;
|
|
||||||
for (auto it = vline.intersections.begin(); it != vline.intersections.end();) {
|
|
||||||
auto it_low = it ++;
|
|
||||||
assert(it_low->type == SegmentIntersection::OUTER_LOW);
|
|
||||||
if (it_low->type != SegmentIntersection::OUTER_LOW)
|
|
||||||
continue;
|
|
||||||
auto it_high = it;
|
|
||||||
assert(it_high->type == SegmentIntersection::OUTER_HIGH);
|
|
||||||
if (it_high->type == SegmentIntersection::OUTER_HIGH) {
|
|
||||||
fill_lines.emplace_back(Point(vline.pos, it_low->pos()).rotated(cos_a, sin_a), Point(vline.pos, it_high->pos()).rotated(cos_a, sin_a));
|
|
||||||
++ it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.dont_connect() || fill_lines.size() <= 1) {
|
if (params.dont_connect() || fill_lines.size() <= 1) {
|
||||||
|
@ -2954,4 +3017,29 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams ¶
|
||||||
return polylines_out;
|
return polylines_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Polylines FillSupportBase::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||||
|
{
|
||||||
|
assert(! params.full_infill());
|
||||||
|
|
||||||
|
Polylines polylines_out;
|
||||||
|
std::pair<float, Point> rotate_vector = this->_infill_direction(surface);
|
||||||
|
ExPolygonWithOffset poly_with_offset(surface->expolygon, - rotate_vector.first, float(scale_(this->overlap - 0.5 * this->spacing)));
|
||||||
|
if (poly_with_offset.n_contours > 0) {
|
||||||
|
Polylines fill_lines;
|
||||||
|
coord_t line_spacing = coord_t(scale_(this->spacing) / params.density);
|
||||||
|
// Create infill lines, keep them vertical.
|
||||||
|
make_fill_lines(poly_with_offset, rotate_vector.second.rotated(- rotate_vector.first), 0, 0, line_spacing, 0, fill_lines);
|
||||||
|
// Both the poly_with_offset and polylines_out are rotated, so the infill lines are strictly vertical.
|
||||||
|
connect_base_support(std::move(fill_lines), poly_with_offset.polygons_outer, poly_with_offset.bounding_box_outer(), polylines_out, this->spacing, params);
|
||||||
|
// Rotate back by rotate_vector.first
|
||||||
|
const double cos_a = cos(rotate_vector.first);
|
||||||
|
const double sin_a = sin(rotate_vector.first);
|
||||||
|
for (Polyline &pl : polylines_out)
|
||||||
|
for (Point &pt : pl.points)
|
||||||
|
pt.rotate(cos_a, sin_a);
|
||||||
|
}
|
||||||
|
return polylines_out;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,17 @@ protected:
|
||||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FillSupportBase : public FillRectilinear
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Fill* clone() const override { return new FillSupportBase(*this); }
|
||||||
|
~FillSupportBase() override = default;
|
||||||
|
Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
|
||||||
|
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
|
|
@ -89,18 +89,11 @@ double Flow::extrusion_width(const std::string& opt_key, const ConfigOptionFloat
|
||||||
|
|
||||||
if (opt->percent) {
|
if (opt->percent) {
|
||||||
auto opt_key_layer_height = first_layer ? "first_layer_height" : "layer_height";
|
auto opt_key_layer_height = first_layer ? "first_layer_height" : "layer_height";
|
||||||
auto opt_layer_height = config.option(opt_key_layer_height);
|
auto opt_layer_height = config.option(opt_key_layer_height);
|
||||||
if (opt_layer_height == nullptr)
|
if (opt_layer_height == nullptr)
|
||||||
throw_on_missing_variable(opt_key, opt_key_layer_height);
|
throw_on_missing_variable(opt_key, opt_key_layer_height);
|
||||||
double layer_height = opt_layer_height->getFloat();
|
assert(! first_layer || ! static_cast<const ConfigOptionFloatOrPercent*>(opt_layer_height)->percent);
|
||||||
if (first_layer && static_cast<const ConfigOptionFloatOrPercent*>(opt_layer_height)->percent) {
|
return opt->get_abs_value(opt_layer_height->getFloat());
|
||||||
// first_layer_height depends on layer_height.
|
|
||||||
opt_layer_height = config.option("layer_height");
|
|
||||||
if (opt_layer_height == nullptr)
|
|
||||||
throw_on_missing_variable(opt_key, "layer_height");
|
|
||||||
layer_height *= 0.01 * opt_layer_height->getFloat();
|
|
||||||
}
|
|
||||||
return opt->get_abs_value(layer_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->value == 0.) {
|
if (opt->value == 0.) {
|
||||||
|
@ -238,13 +231,14 @@ Flow support_material_flow(const PrintObject *object, float layer_height)
|
||||||
|
|
||||||
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
|
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
|
||||||
{
|
{
|
||||||
const auto &width = (object->print()->config().first_layer_extrusion_width.value > 0) ? object->print()->config().first_layer_extrusion_width : object->config().support_material_extrusion_width;
|
const PrintConfig &print_config = object->print()->config();
|
||||||
|
const auto &width = (print_config.first_layer_extrusion_width.value > 0) ? print_config.first_layer_extrusion_width : object->config().support_material_extrusion_width;
|
||||||
return Flow::new_from_config_width(
|
return Flow::new_from_config_width(
|
||||||
frSupportMaterial,
|
frSupportMaterial,
|
||||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||||
(width.value > 0) ? width : object->config().extrusion_width,
|
(width.value > 0) ? width : object->config().extrusion_width,
|
||||||
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
|
float(print_config.nozzle_diameter.get_at(object->config().support_material_extruder-1)),
|
||||||
(layer_height > 0.f) ? layer_height : float(object->config().first_layer_height.get_abs_value(object->config().layer_height.value)));
|
(layer_height > 0.f) ? layer_height : float(print_config.first_layer_height.get_abs_value(object->config().layer_height.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
|
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
|
||||||
|
|
|
@ -87,7 +87,7 @@ PNGBuffer read_png(const mz_zip_archive_file_stat &entry,
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiveData extract_sla_archive(const std::string &zipfname,
|
ArchiveData extract_sla_archive(const std::string &zipfname,
|
||||||
const std::string &exclude)
|
const std::string &exclude)
|
||||||
{
|
{
|
||||||
ArchiveData arch;
|
ArchiveData arch;
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ std::vector<ExPolygons> extract_slices_from_sla_archive(
|
||||||
{
|
{
|
||||||
double incr, val, prev;
|
double incr, val, prev;
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
tbb::spin_mutex mutex;
|
tbb::spin_mutex mutex = {};
|
||||||
} st {100. / slices.size(), 0., 0.};
|
} st {100. / slices.size(), 0., 0.};
|
||||||
|
|
||||||
tbb::parallel_for(size_t(0), arch.images.size(),
|
tbb::parallel_for(size_t(0), arch.images.size(),
|
||||||
|
@ -371,6 +371,13 @@ void fill_iniconf(ConfMap &m, const SLAPrint &print)
|
||||||
m["numSlow"] = std::to_string(stats.slow_layers_count);
|
m["numSlow"] = std::to_string(stats.slow_layers_count);
|
||||||
m["numFast"] = std::to_string(stats.fast_layers_count);
|
m["numFast"] = std::to_string(stats.fast_layers_count);
|
||||||
m["printTime"] = std::to_string(stats.estimated_print_time);
|
m["printTime"] = std::to_string(stats.estimated_print_time);
|
||||||
|
|
||||||
|
bool hollow_en = false;
|
||||||
|
auto it = print.objects().begin();
|
||||||
|
while (!hollow_en && it != print.objects().end())
|
||||||
|
hollow_en = (*it++)->config().hollowing_enable;
|
||||||
|
|
||||||
|
m["hollow"] = hollow_en ? "1" : "0";
|
||||||
|
|
||||||
m["action"] = "print";
|
m["action"] = "print";
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,19 +435,18 @@ namespace Slic3r {
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
assert(m_layer_idx >= 0);
|
assert(m_layer_idx >= 0);
|
||||||
if (!m_brim_done || gcodegen.writer().need_toolchange(extruder_id) || finish_layer) {
|
if (gcodegen.writer().need_toolchange(extruder_id) || finish_layer) {
|
||||||
if (m_layer_idx < (int)m_tool_changes.size()) {
|
if (m_layer_idx < (int)m_tool_changes.size()) {
|
||||||
if (!(size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size()))
|
if (!(size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size()))
|
||||||
throw Slic3r::RuntimeError("Wipe tower generation failed, possibly due to empty first layer.");
|
throw Slic3r::RuntimeError("Wipe tower generation failed, possibly due to empty first layer.");
|
||||||
|
|
||||||
|
|
||||||
// Calculate where the wipe tower layer will be printed. -1 means that print z will not change,
|
// 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.
|
// resulting in a wipe tower with sparse layers.
|
||||||
double wipe_tower_z = -1;
|
double wipe_tower_z = -1;
|
||||||
bool ignore_sparse = false;
|
bool ignore_sparse = false;
|
||||||
if (gcodegen.config().wipe_tower_no_sparse_layers.value) {
|
if (gcodegen.config().wipe_tower_no_sparse_layers.value) {
|
||||||
wipe_tower_z = m_last_wipe_tower_print_z;
|
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);
|
ignore_sparse = (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)
|
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;
|
wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +456,6 @@ namespace Slic3r {
|
||||||
m_last_wipe_tower_print_z = wipe_tower_z;
|
m_last_wipe_tower_print_z = wipe_tower_z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_brim_done = true;
|
|
||||||
}
|
}
|
||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
@ -786,7 +784,8 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re
|
||||||
namespace DoExport {
|
namespace DoExport {
|
||||||
static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool& silent_time_estimator_enabled)
|
static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool& silent_time_estimator_enabled)
|
||||||
{
|
{
|
||||||
silent_time_estimator_enabled = (config.gcode_flavor == gcfMarlin) && config.silent_mode;
|
silent_time_estimator_enabled = (config.gcode_flavor == gcfMarlinLegacy || config.gcode_flavor == gcfMarlinFirmware)
|
||||||
|
&& config.silent_mode;
|
||||||
processor.reset();
|
processor.reset();
|
||||||
processor.apply_config(config);
|
processor.apply_config(config);
|
||||||
processor.enable_stealth_time_estimator(silent_time_estimator_enabled);
|
processor.enable_stealth_time_estimator(silent_time_estimator_enabled);
|
||||||
|
@ -1112,7 +1111,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
||||||
// Write some terse information on the slicing parameters.
|
// Write some terse information on the slicing parameters.
|
||||||
const PrintObject *first_object = print.objects().front();
|
const PrintObject *first_object = print.objects().front();
|
||||||
const double layer_height = first_object->config().layer_height.value;
|
const double layer_height = first_object->config().layer_height.value;
|
||||||
const double first_layer_height = first_object->config().first_layer_height.get_abs_value(layer_height);
|
assert(! print.config().first_layer_height.percent);
|
||||||
|
const double first_layer_height = print.config().first_layer_height.value;
|
||||||
for (const PrintRegion* region : print.regions()) {
|
for (const PrintRegion* region : print.regions()) {
|
||||||
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width());
|
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width());
|
||||||
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width());
|
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width());
|
||||||
|
@ -1357,7 +1357,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
||||||
bbox_prime.offset(0.5f);
|
bbox_prime.offset(0.5f);
|
||||||
bool overlap = bbox_prime.overlap(bbox_print);
|
bool overlap = bbox_prime.overlap(bbox_print);
|
||||||
|
|
||||||
if (print.config().gcode_flavor == gcfMarlin) {
|
if (print.config().gcode_flavor == gcfMarlinLegacy || print.config().gcode_flavor == gcfMarlinFirmware) {
|
||||||
_write(file, this->retract());
|
_write(file, this->retract());
|
||||||
_write(file, "M300 S800 P500\n"); // Beep for 500ms, tone 800Hz.
|
_write(file, "M300 S800 P500\n"); // Beep for 500ms, tone 800Hz.
|
||||||
if (overlap) {
|
if (overlap) {
|
||||||
|
@ -1560,7 +1560,8 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc
|
||||||
// Do not process this piece of G-code by the time estimator, it already knows the values through another sources.
|
// Do not process this piece of G-code by the time estimator, it already knows the values through another sources.
|
||||||
void GCode::print_machine_envelope(FILE *file, Print &print)
|
void GCode::print_machine_envelope(FILE *file, Print &print)
|
||||||
{
|
{
|
||||||
if (print.config().gcode_flavor.value == gcfMarlin && print.config().machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) {
|
if ((print.config().gcode_flavor.value == gcfMarlinLegacy || print.config().gcode_flavor.value == gcfMarlinFirmware)
|
||||||
|
&& print.config().machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) {
|
||||||
fprintf(file, "M201 X%d Y%d Z%d E%d ; sets maximum accelerations, mm/sec^2\n",
|
fprintf(file, "M201 X%d Y%d Z%d E%d ; sets maximum accelerations, mm/sec^2\n",
|
||||||
int(print.config().machine_max_acceleration_x.values.front() + 0.5),
|
int(print.config().machine_max_acceleration_x.values.front() + 0.5),
|
||||||
int(print.config().machine_max_acceleration_y.values.front() + 0.5),
|
int(print.config().machine_max_acceleration_y.values.front() + 0.5),
|
||||||
|
@ -1571,10 +1572,20 @@ void GCode::print_machine_envelope(FILE *file, Print &print)
|
||||||
int(print.config().machine_max_feedrate_y.values.front() + 0.5),
|
int(print.config().machine_max_feedrate_y.values.front() + 0.5),
|
||||||
int(print.config().machine_max_feedrate_z.values.front() + 0.5),
|
int(print.config().machine_max_feedrate_z.values.front() + 0.5),
|
||||||
int(print.config().machine_max_feedrate_e.values.front() + 0.5));
|
int(print.config().machine_max_feedrate_e.values.front() + 0.5));
|
||||||
|
|
||||||
|
// Now M204 - acceleration. This one is quite hairy thanks to how Marlin guys care about
|
||||||
|
// backwards compatibility: https://github.com/prusa3d/PrusaSlicer/issues/1089
|
||||||
|
// Legacy Marlin should export travel acceleration the same as printing acceleration.
|
||||||
|
// MarlinFirmware has the two separated.
|
||||||
|
int travel_acc = print.config().gcode_flavor == gcfMarlinLegacy
|
||||||
|
? int(print.config().machine_max_acceleration_extruding.values.front() + 0.5)
|
||||||
|
: int(print.config().machine_max_acceleration_travel.values.front() + 0.5);
|
||||||
fprintf(file, "M204 P%d R%d T%d ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2\n",
|
fprintf(file, "M204 P%d R%d T%d ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2\n",
|
||||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
||||||
int(print.config().machine_max_acceleration_retracting.values.front() + 0.5),
|
int(print.config().machine_max_acceleration_retracting.values.front() + 0.5),
|
||||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5));
|
travel_acc);
|
||||||
|
|
||||||
|
|
||||||
fprintf(file, "M205 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/sec\n",
|
fprintf(file, "M205 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/sec\n",
|
||||||
print.config().machine_max_jerk_x.values.front(),
|
print.config().machine_max_jerk_x.values.front(),
|
||||||
print.config().machine_max_jerk_y.values.front(),
|
print.config().machine_max_jerk_y.values.front(),
|
||||||
|
@ -1768,6 +1779,10 @@ namespace ProcessLayer
|
||||||
else {
|
else {
|
||||||
gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id);
|
gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id);
|
||||||
gcode += "\n";
|
gcode += "\n";
|
||||||
|
//FIXME Tell G-code writer that M600 filled the extruder, thus the G-code writer shall reset the extruder to unretracted state after
|
||||||
|
// return from M600. Thus the G-code generated by the following line is ignored.
|
||||||
|
// see GH issue #6362
|
||||||
|
gcodegen.writer().unretract();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -75,8 +75,8 @@ public:
|
||||||
m_tool_changes(tool_changes),
|
m_tool_changes(tool_changes),
|
||||||
m_final_purge(final_purge),
|
m_final_purge(final_purge),
|
||||||
m_layer_idx(-1),
|
m_layer_idx(-1),
|
||||||
m_tool_change_idx(0),
|
m_tool_change_idx(0)
|
||||||
m_brim_done(false) {}
|
{}
|
||||||
|
|
||||||
std::string prime(GCode &gcodegen);
|
std::string prime(GCode &gcodegen);
|
||||||
void next_layer() { ++ m_layer_idx; m_tool_change_idx = 0; }
|
void next_layer() { ++ m_layer_idx; m_tool_change_idx = 0; }
|
||||||
|
@ -105,8 +105,6 @@ private:
|
||||||
// Current layer index.
|
// Current layer index.
|
||||||
int m_layer_idx;
|
int m_layer_idx;
|
||||||
int m_tool_change_idx;
|
int m_tool_change_idx;
|
||||||
bool m_brim_done;
|
|
||||||
bool i_have_brim = false;
|
|
||||||
double m_last_wipe_tower_print_z = 0.f;
|
double m_last_wipe_tower_print_z = 0.f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -326,7 +326,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||||
PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
|
PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
|
||||||
const char *line_start = gcode.c_str();
|
const char *line_start = gcode.c_str();
|
||||||
const char *line_end = line_start;
|
const char *line_end = line_start;
|
||||||
const char extrusion_axis = config.get_extrusion_axis()[0];
|
const char extrusion_axis = get_extrusion_axis(config)[0];
|
||||||
// Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command
|
// Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command
|
||||||
// for a sequence of extrusion moves.
|
// for a sequence of extrusion moves.
|
||||||
size_t active_speed_modifier = size_t(-1);
|
size_t active_speed_modifier = size_t(-1);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
static const float INCHES_TO_MM = 25.4f;
|
static const float INCHES_TO_MM = 25.4f;
|
||||||
static const float MMMIN_TO_MMSEC = 1.0f / 60.0f;
|
static const float MMMIN_TO_MMSEC = 1.0f / 60.0f;
|
||||||
static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
|
static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
|
||||||
|
static const float DEFAULT_TRAVEL_ACCELERATION = 1250.0f;
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
@ -190,6 +191,8 @@ void GCodeProcessor::TimeMachine::reset()
|
||||||
enabled = false;
|
enabled = false;
|
||||||
acceleration = 0.0f;
|
acceleration = 0.0f;
|
||||||
max_acceleration = 0.0f;
|
max_acceleration = 0.0f;
|
||||||
|
travel_acceleration = 0.0f;
|
||||||
|
max_travel_acceleration = 0.0f;
|
||||||
extrude_factor_override_percentage = 1.0f;
|
extrude_factor_override_percentage = 1.0f;
|
||||||
time = 0.0f;
|
time = 0.0f;
|
||||||
#if ENABLE_EXTENDED_M73_LINES
|
#if ENABLE_EXTENDED_M73_LINES
|
||||||
|
@ -823,8 +826,13 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||||
m_filament_diameters[i] = static_cast<float>(config.filament_diameter.values[i]);
|
m_filament_diameters[i] = static_cast<float>(config.filament_diameter.values[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_flavor == gcfMarlin && config.machine_limits_usage.value != MachineLimitsUsage::Ignore)
|
if ((m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware) && config.machine_limits_usage.value != MachineLimitsUsage::Ignore) {
|
||||||
m_time_processor.machine_limits = reinterpret_cast<const MachineEnvelopeConfig&>(config);
|
m_time_processor.machine_limits = reinterpret_cast<const MachineEnvelopeConfig&>(config);
|
||||||
|
if (m_flavor == gcfMarlinLegacy) {
|
||||||
|
// Legacy Marlin does not have separate travel acceleration, it uses the 'extruding' value instead.
|
||||||
|
m_time_processor.machine_limits.machine_max_acceleration_travel = m_time_processor.machine_limits.machine_max_acceleration_extruding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful.
|
// Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful.
|
||||||
// As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they
|
// As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they
|
||||||
|
@ -842,10 +850,19 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||||
float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i);
|
float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i);
|
||||||
m_time_processor.machines[i].max_acceleration = max_acceleration;
|
m_time_processor.machines[i].max_acceleration = max_acceleration;
|
||||||
m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION;
|
m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION;
|
||||||
|
float max_travel_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_travel, i);
|
||||||
|
m_time_processor.machines[i].max_travel_acceleration = max_travel_acceleration;
|
||||||
|
m_time_processor.machines[i].travel_acceleration = (max_travel_acceleration > 0.0f) ? max_travel_acceleration : DEFAULT_TRAVEL_ACCELERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_time_processor.export_remaining_time_enabled = config.remaining_times.value;
|
m_time_processor.export_remaining_time_enabled = config.remaining_times.value;
|
||||||
m_use_volumetric_e = config.use_volumetric_e;
|
m_use_volumetric_e = config.use_volumetric_e;
|
||||||
|
|
||||||
|
#if ENABLE_START_GCODE_VISUALIZATION
|
||||||
|
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||||
|
if (first_layer_height != nullptr)
|
||||||
|
m_first_layer_height = std::abs(first_layer_height->value);
|
||||||
|
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||||
|
@ -934,7 +951,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_flavor == gcfMarlin) {
|
if (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware) {
|
||||||
const ConfigOptionFloats* machine_max_acceleration_x = config.option<ConfigOptionFloats>("machine_max_acceleration_x");
|
const ConfigOptionFloats* machine_max_acceleration_x = config.option<ConfigOptionFloats>("machine_max_acceleration_x");
|
||||||
if (machine_max_acceleration_x != nullptr)
|
if (machine_max_acceleration_x != nullptr)
|
||||||
m_time_processor.machine_limits.machine_max_acceleration_x.values = machine_max_acceleration_x->values;
|
m_time_processor.machine_limits.machine_max_acceleration_x.values = machine_max_acceleration_x->values;
|
||||||
|
@ -991,6 +1008,15 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||||
if (machine_max_acceleration_retracting != nullptr)
|
if (machine_max_acceleration_retracting != nullptr)
|
||||||
m_time_processor.machine_limits.machine_max_acceleration_retracting.values = machine_max_acceleration_retracting->values;
|
m_time_processor.machine_limits.machine_max_acceleration_retracting.values = machine_max_acceleration_retracting->values;
|
||||||
|
|
||||||
|
|
||||||
|
// Legacy Marlin does not have separate travel acceleration, it uses the 'extruding' value instead.
|
||||||
|
const ConfigOptionFloats* machine_max_acceleration_travel = config.option<ConfigOptionFloats>(m_flavor == gcfMarlinLegacy
|
||||||
|
? "machine_max_acceleration_extruding"
|
||||||
|
: "machine_max_acceleration_travel");
|
||||||
|
if (machine_max_acceleration_travel != nullptr)
|
||||||
|
m_time_processor.machine_limits.machine_max_acceleration_travel.values = machine_max_acceleration_travel->values;
|
||||||
|
|
||||||
|
|
||||||
const ConfigOptionFloats* machine_min_extruding_rate = config.option<ConfigOptionFloats>("machine_min_extruding_rate");
|
const ConfigOptionFloats* machine_min_extruding_rate = config.option<ConfigOptionFloats>("machine_min_extruding_rate");
|
||||||
if (machine_min_extruding_rate != nullptr)
|
if (machine_min_extruding_rate != nullptr)
|
||||||
m_time_processor.machine_limits.machine_min_extruding_rate.values = machine_min_extruding_rate->values;
|
m_time_processor.machine_limits.machine_min_extruding_rate.values = machine_min_extruding_rate->values;
|
||||||
|
@ -1004,6 +1030,9 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||||
float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i);
|
float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i);
|
||||||
m_time_processor.machines[i].max_acceleration = max_acceleration;
|
m_time_processor.machines[i].max_acceleration = max_acceleration;
|
||||||
m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION;
|
m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION;
|
||||||
|
float max_travel_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_travel, i);
|
||||||
|
m_time_processor.machines[i].max_travel_acceleration = max_travel_acceleration;
|
||||||
|
m_time_processor.machines[i].travel_acceleration = (max_travel_acceleration > 0.0f) ? max_travel_acceleration : DEFAULT_TRAVEL_ACCELERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_time_processor.machine_limits.machine_max_acceleration_x.values.size() > 1)
|
if (m_time_processor.machine_limits.machine_max_acceleration_x.values.size() > 1)
|
||||||
|
@ -1012,6 +1041,12 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||||
const ConfigOptionBool* use_volumetric_e = config.option<ConfigOptionBool>("use_volumetric_e");
|
const ConfigOptionBool* use_volumetric_e = config.option<ConfigOptionBool>("use_volumetric_e");
|
||||||
if (use_volumetric_e != nullptr)
|
if (use_volumetric_e != nullptr)
|
||||||
m_use_volumetric_e = use_volumetric_e->value;
|
m_use_volumetric_e = use_volumetric_e->value;
|
||||||
|
|
||||||
|
#if ENABLE_START_GCODE_VISUALIZATION
|
||||||
|
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||||
|
if (first_layer_height != nullptr)
|
||||||
|
m_first_layer_height = std::abs(first_layer_height->value);
|
||||||
|
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
||||||
|
@ -1037,6 +1072,9 @@ void GCodeProcessor::reset()
|
||||||
|
|
||||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
m_line_id = 0;
|
m_line_id = 0;
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
m_last_line_id = 0;
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
m_feedrate = 0.0f;
|
m_feedrate = 0.0f;
|
||||||
m_width = 0.0f;
|
m_width = 0.0f;
|
||||||
|
@ -1059,6 +1097,10 @@ void GCodeProcessor::reset()
|
||||||
|
|
||||||
m_filament_diameters = std::vector<float>(Min_Extruder_Count, 1.75f);
|
m_filament_diameters = std::vector<float>(Min_Extruder_Count, 1.75f);
|
||||||
m_extruded_last_z = 0.0f;
|
m_extruded_last_z = 0.0f;
|
||||||
|
#if ENABLE_START_GCODE_VISUALIZATION
|
||||||
|
m_first_layer_height = 0.0f;
|
||||||
|
m_processing_start_custom_gcode = false;
|
||||||
|
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||||
m_g1_line_id = 0;
|
m_g1_line_id = 0;
|
||||||
m_layer_id = 0;
|
m_layer_id = 0;
|
||||||
m_cp_color.reset();
|
m_cp_color.reset();
|
||||||
|
@ -1420,6 +1462,13 @@ void GCodeProcessor::process_tags(const std::string_view comment)
|
||||||
// extrusion role tag
|
// extrusion role tag
|
||||||
if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
|
if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
|
||||||
m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length()));
|
m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length()));
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
if (m_extrusion_role == erExternalPerimeter)
|
||||||
|
m_seams_detector.activate(true);
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
|
#if ENABLE_START_GCODE_VISUALIZATION
|
||||||
|
m_processing_start_custom_gcode = (m_extrusion_role == erCustom && m_g1_line_id == 0);
|
||||||
|
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1646,23 +1695,23 @@ bool GCodeProcessor::process_cura_tags(const std::string_view comment)
|
||||||
if (pos != comment.npos) {
|
if (pos != comment.npos) {
|
||||||
const std::string_view flavor = comment.substr(pos + tag.length());
|
const std::string_view flavor = comment.substr(pos + tag.length());
|
||||||
if (flavor == "BFB")
|
if (flavor == "BFB")
|
||||||
m_flavor = gcfMarlin; // << ???????????????????????
|
m_flavor = gcfMarlinLegacy; // is this correct ?
|
||||||
else if (flavor == "Mach3")
|
else if (flavor == "Mach3")
|
||||||
m_flavor = gcfMach3;
|
m_flavor = gcfMach3;
|
||||||
else if (flavor == "Makerbot")
|
else if (flavor == "Makerbot")
|
||||||
m_flavor = gcfMakerWare;
|
m_flavor = gcfMakerWare;
|
||||||
else if (flavor == "UltiGCode")
|
else if (flavor == "UltiGCode")
|
||||||
m_flavor = gcfMarlin; // << ???????????????????????
|
m_flavor = gcfMarlinLegacy; // is this correct ?
|
||||||
else if (flavor == "Marlin(Volumetric)")
|
else if (flavor == "Marlin(Volumetric)")
|
||||||
m_flavor = gcfMarlin; // << ???????????????????????
|
m_flavor = gcfMarlinLegacy; // is this correct ?
|
||||||
else if (flavor == "Griffin")
|
else if (flavor == "Griffin")
|
||||||
m_flavor = gcfMarlin; // << ???????????????????????
|
m_flavor = gcfMarlinLegacy; // is this correct ?
|
||||||
else if (flavor == "Repetier")
|
else if (flavor == "Repetier")
|
||||||
m_flavor = gcfRepetier;
|
m_flavor = gcfRepetier;
|
||||||
else if (flavor == "RepRap")
|
else if (flavor == "RepRap")
|
||||||
m_flavor = gcfRepRapFirmware;
|
m_flavor = gcfRepRapFirmware;
|
||||||
else if (flavor == "Marlin")
|
else if (flavor == "Marlin")
|
||||||
m_flavor = gcfMarlin;
|
m_flavor = gcfMarlinLegacy;
|
||||||
else
|
else
|
||||||
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown flavor: " << flavor;
|
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown flavor: " << flavor;
|
||||||
|
|
||||||
|
@ -2164,7 +2213,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
||||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_START_GCODE_VISUALIZATION
|
||||||
|
if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f))
|
||||||
|
#else
|
||||||
if (type == EMoveType::Extrude && (m_extrusion_role == erCustom || m_width == 0.0f || m_height == 0.0f))
|
if (type == EMoveType::Extrude && (m_extrusion_role == erCustom || m_width == 0.0f || m_height == 0.0f))
|
||||||
|
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||||
type = EMoveType::Travel;
|
type = EMoveType::Travel;
|
||||||
|
|
||||||
// time estimate section
|
// time estimate section
|
||||||
|
@ -2226,9 +2279,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculates block acceleration
|
// calculates block acceleration
|
||||||
float acceleration = is_extrusion_only_move(delta_pos) ?
|
float acceleration =
|
||||||
get_retract_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i)) :
|
(type == EMoveType::Travel) ? get_travel_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i)) :
|
||||||
get_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i));
|
(is_extrusion_only_move(delta_pos) ?
|
||||||
|
get_retract_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i)) :
|
||||||
|
get_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i)));
|
||||||
|
|
||||||
for (unsigned char a = X; a <= E; ++a) {
|
for (unsigned char a = X; a <= E; ++a) {
|
||||||
float axis_max_acceleration = get_axis_max_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), static_cast<Axis>(a));
|
float axis_max_acceleration = get_axis_max_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), static_cast<Axis>(a));
|
||||||
|
@ -2278,13 +2333,13 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
||||||
// Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction.
|
// Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction.
|
||||||
float jerk =
|
float jerk =
|
||||||
(v_exit > v_entry) ?
|
(v_exit > v_entry) ?
|
||||||
(((v_entry > 0.0f) || (v_exit < 0.0f)) ?
|
((v_entry > 0.0f || v_exit < 0.0f) ?
|
||||||
// coasting
|
// coasting
|
||||||
(v_exit - v_entry) :
|
(v_exit - v_entry) :
|
||||||
// axis reversal
|
// axis reversal
|
||||||
std::max(v_exit, -v_entry)) :
|
std::max(v_exit, -v_entry)) :
|
||||||
// v_exit <= v_entry
|
// v_exit <= v_entry
|
||||||
(((v_entry < 0.0f) || (v_exit > 0.0f)) ?
|
((v_entry < 0.0f || v_exit > 0.0f) ?
|
||||||
// coasting
|
// coasting
|
||||||
(v_entry - v_exit) :
|
(v_entry - v_exit) :
|
||||||
// axis reversal
|
// axis reversal
|
||||||
|
@ -2305,7 +2360,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
||||||
float vmax_junction_threshold = vmax_junction * 0.99f;
|
float vmax_junction_threshold = vmax_junction * 0.99f;
|
||||||
|
|
||||||
// Not coasting. The machine will stop and start the movements anyway, better to start the segment from start.
|
// Not coasting. The machine will stop and start the movements anyway, better to start the segment from start.
|
||||||
if ((prev.safe_feedrate > vmax_junction_threshold) && (curr.safe_feedrate > vmax_junction_threshold))
|
if (prev.safe_feedrate > vmax_junction_threshold && curr.safe_feedrate > vmax_junction_threshold)
|
||||||
vmax_junction = curr.safe_feedrate;
|
vmax_junction = curr.safe_feedrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2329,6 +2384,31 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
||||||
machine.calculate_time(TimeProcessor::Planner::queue_size);
|
machine.calculate_time(TimeProcessor::Planner::queue_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
// check for seam starting vertex
|
||||||
|
if (type == EMoveType::Extrude && m_extrusion_role == erExternalPerimeter && m_seams_detector.is_active() && !m_seams_detector.has_first_vertex())
|
||||||
|
m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[m_extruder_id]);
|
||||||
|
// check for seam ending vertex and store the resulting move
|
||||||
|
else if ((type != EMoveType::Extrude || m_extrusion_role != erExternalPerimeter) && m_seams_detector.is_active()) {
|
||||||
|
auto set_end_position = [this](const Vec3f& pos) {
|
||||||
|
m_end_position[X] = pos.x(); m_end_position[Y] = pos.y(); m_end_position[Z] = pos.z();
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(m_seams_detector.has_first_vertex());
|
||||||
|
const Vec3f curr_pos(m_end_position[X], m_end_position[Y], m_end_position[Z]);
|
||||||
|
const Vec3f new_pos = m_result.moves.back().position - m_extruder_offsets[m_extruder_id];
|
||||||
|
const std::optional<Vec3f> first_vertex = m_seams_detector.get_first_vertex();
|
||||||
|
// the threshold value = 0.25 is arbitrary, we may find some smarter condition later
|
||||||
|
if ((new_pos - *first_vertex).norm() < 0.25f) {
|
||||||
|
set_end_position(0.5f * (new_pos + *first_vertex));
|
||||||
|
store_move_vertex(EMoveType::Seam);
|
||||||
|
set_end_position(curr_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_seams_detector.activate(false);
|
||||||
|
}
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
|
|
||||||
// store move
|
// store move
|
||||||
store_move_vertex(type);
|
store_move_vertex(type);
|
||||||
}
|
}
|
||||||
|
@ -2575,7 +2655,7 @@ void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line)
|
||||||
|
|
||||||
// see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate
|
// see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate
|
||||||
// http://smoothieware.org/supported-g-codes
|
// http://smoothieware.org/supported-g-codes
|
||||||
float factor = (m_flavor == gcfMarlin || m_flavor == gcfSmoothie) ? 1.0f : MMMIN_TO_MMSEC;
|
float factor = (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware || m_flavor == gcfSmoothie) ? 1.0f : MMMIN_TO_MMSEC;
|
||||||
|
|
||||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
|
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
|
||||||
if (static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
|
if (static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
|
||||||
|
@ -2602,10 +2682,11 @@ void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line)
|
||||||
if (static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
|
if (static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal ||
|
||||||
m_time_processor.machine_envelope_processing_enabled) {
|
m_time_processor.machine_envelope_processing_enabled) {
|
||||||
if (line.has_value('S', value)) {
|
if (line.has_value('S', value)) {
|
||||||
// Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware,
|
// Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware
|
||||||
// and it is also generated by Slic3r to control acceleration per extrusion type
|
// It is also generated by PrusaSlicer to control acceleration per extrusion type
|
||||||
// (there is a separate acceleration settings in Slicer for perimeter, first layer etc).
|
// (perimeters, first layer etc) when 'Marlin (legacy)' flavor is used.
|
||||||
set_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), value);
|
set_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), value);
|
||||||
|
set_travel_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), value);
|
||||||
if (line.has_value('T', value))
|
if (line.has_value('T', value))
|
||||||
set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value);
|
set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value);
|
||||||
}
|
}
|
||||||
|
@ -2615,11 +2696,9 @@ void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line)
|
||||||
set_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), value);
|
set_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), value);
|
||||||
if (line.has_value('R', value))
|
if (line.has_value('R', value))
|
||||||
set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value);
|
set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value);
|
||||||
if (line.has_value('T', value)) {
|
if (line.has_value('T', value))
|
||||||
// Interpret the T value as the travel acceleration in the new Marlin format.
|
// Interpret the T value as the travel acceleration in the new Marlin format.
|
||||||
//FIXME Prusa3D firmware currently does not support travel acceleration value independent from the extruding acceleration value.
|
set_travel_acceleration(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i), value);
|
||||||
// set_travel_acceleration(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2749,7 +2828,7 @@ void GCodeProcessor::process_T(const std::string_view command)
|
||||||
int eid = 0;
|
int eid = 0;
|
||||||
if (! parse_number(command.substr(1), eid) || eid < 0 || eid > 255) {
|
if (! parse_number(command.substr(1), eid) || eid < 0 || eid > 255) {
|
||||||
// Specific to the MMU2 V2 (see https://www.help.prusa3d.com/en/article/prusa-specific-g-codes_112173):
|
// Specific to the MMU2 V2 (see https://www.help.prusa3d.com/en/article/prusa-specific-g-codes_112173):
|
||||||
if (m_flavor == gcfMarlin && (command == "Tx" || command == "Tc" || command == "T?"))
|
if ((m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware) && (command == "Tx" || command == "Tc" || command == "T?"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// T-1 is a valid gcode line for RepRap Firmwares (used to deselects all tools) see https://github.com/prusa3d/PrusaSlicer/issues/5677
|
// T-1 is a valid gcode line for RepRap Firmwares (used to deselects all tools) see https://github.com/prusa3d/PrusaSlicer/issues/5677
|
||||||
|
@ -2783,15 +2862,29 @@ void GCodeProcessor::process_T(const std::string_view command)
|
||||||
|
|
||||||
void GCodeProcessor::store_move_vertex(EMoveType type)
|
void GCodeProcessor::store_move_vertex(EMoveType type)
|
||||||
{
|
{
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
m_last_line_id = (type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ?
|
||||||
|
m_line_id + 1 :
|
||||||
|
((type == EMoveType::Seam) ? m_last_line_id : m_line_id);
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
|
|
||||||
MoveVertex vertex = {
|
MoveVertex vertex = {
|
||||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
m_last_line_id,
|
||||||
|
#else
|
||||||
(type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ? m_line_id + 1 : m_line_id,
|
(type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ? m_line_id + 1 : m_line_id,
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
type,
|
type,
|
||||||
m_extrusion_role,
|
m_extrusion_role,
|
||||||
m_extruder_id,
|
m_extruder_id,
|
||||||
m_cp_color.current,
|
m_cp_color.current,
|
||||||
|
#if ENABLE_START_GCODE_VISUALIZATION
|
||||||
|
Vec3f(m_end_position[X], m_end_position[Y], m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
|
||||||
|
#else
|
||||||
Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
|
Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
|
||||||
|
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||||
m_end_position[E] - m_start_position[E],
|
m_end_position[E] - m_start_position[E],
|
||||||
m_feedrate,
|
m_feedrate,
|
||||||
m_width,
|
m_width,
|
||||||
|
@ -2890,6 +2983,22 @@ void GCodeProcessor::set_acceleration(PrintEstimatedTimeStatistics::ETimeMode mo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GCodeProcessor::get_travel_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const
|
||||||
|
{
|
||||||
|
size_t id = static_cast<size_t>(mode);
|
||||||
|
return (id < m_time_processor.machines.size()) ? m_time_processor.machines[id].travel_acceleration : DEFAULT_TRAVEL_ACCELERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeProcessor::set_travel_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value)
|
||||||
|
{
|
||||||
|
size_t id = static_cast<size_t>(mode);
|
||||||
|
if (id < m_time_processor.machines.size()) {
|
||||||
|
m_time_processor.machines[id].travel_acceleration = (m_time_processor.machines[id].max_travel_acceleration == 0.0f) ? value :
|
||||||
|
// Clamp the acceleration with the maximum.
|
||||||
|
std::min(value, m_time_processor.machines[id].max_travel_acceleration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float GCodeProcessor::get_filament_load_time(size_t extruder_id)
|
float GCodeProcessor::get_filament_load_time(size_t extruder_id)
|
||||||
{
|
{
|
||||||
return (m_time_processor.filament_load_times.empty() || m_time_processor.extruder_unloaded) ?
|
return (m_time_processor.filament_load_times.empty() || m_time_processor.extruder_unloaded) ?
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
#include <optional>
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
@ -20,6 +23,9 @@ namespace Slic3r {
|
||||||
Noop,
|
Noop,
|
||||||
Retract,
|
Retract,
|
||||||
Unretract,
|
Unretract,
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
Seam,
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
Tool_change,
|
Tool_change,
|
||||||
Color_change,
|
Color_change,
|
||||||
Pause_Print,
|
Pause_Print,
|
||||||
|
@ -251,6 +257,9 @@ namespace Slic3r {
|
||||||
float acceleration; // mm/s^2
|
float acceleration; // mm/s^2
|
||||||
// hard limit for the acceleration, to which the firmware will clamp.
|
// hard limit for the acceleration, to which the firmware will clamp.
|
||||||
float max_acceleration; // mm/s^2
|
float max_acceleration; // mm/s^2
|
||||||
|
float travel_acceleration; // mm/s^2
|
||||||
|
// hard limit for the travel acceleration, to which the firmware will clamp.
|
||||||
|
float max_travel_acceleration; // mm/s^2
|
||||||
float extrude_factor_override_percentage;
|
float extrude_factor_override_percentage;
|
||||||
float time; // s
|
float time; // s
|
||||||
#if ENABLE_EXTENDED_M73_LINES
|
#if ENABLE_EXTENDED_M73_LINES
|
||||||
|
@ -367,8 +376,7 @@ namespace Slic3r {
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
int64_t time{ 0 };
|
int64_t time{ 0 };
|
||||||
void reset()
|
void reset() {
|
||||||
{
|
|
||||||
time = 0;
|
time = 0;
|
||||||
moves = std::vector<MoveVertex>();
|
moves = std::vector<MoveVertex>();
|
||||||
bed_shape = Pointfs();
|
bed_shape = Pointfs();
|
||||||
|
@ -377,8 +385,7 @@ namespace Slic3r {
|
||||||
settings_ids.reset();
|
settings_ids.reset();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void reset()
|
void reset() {
|
||||||
{
|
|
||||||
moves = std::vector<MoveVertex>();
|
moves = std::vector<MoveVertex>();
|
||||||
bed_shape = Pointfs();
|
bed_shape = Pointfs();
|
||||||
extruder_colors = std::vector<std::string>();
|
extruder_colors = std::vector<std::string>();
|
||||||
|
@ -388,6 +395,29 @@ namespace Slic3r {
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
class SeamsDetector
|
||||||
|
{
|
||||||
|
bool m_active{ false };
|
||||||
|
std::optional<Vec3f> m_first_vertex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void activate(bool active) {
|
||||||
|
if (m_active != active) {
|
||||||
|
m_active = active;
|
||||||
|
if (m_active)
|
||||||
|
m_first_vertex.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Vec3f> get_first_vertex() const { return m_first_vertex; }
|
||||||
|
void set_first_vertex(const Vec3f& vertex) { m_first_vertex = vertex; }
|
||||||
|
|
||||||
|
bool is_active() const { return m_active; }
|
||||||
|
bool has_first_vertex() const { return m_first_vertex.has_value(); }
|
||||||
|
};
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||||
struct DataChecker
|
struct DataChecker
|
||||||
{
|
{
|
||||||
|
@ -473,6 +503,9 @@ namespace Slic3r {
|
||||||
|
|
||||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
unsigned int m_line_id;
|
unsigned int m_line_id;
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
unsigned int m_last_line_id;
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
float m_feedrate; // mm/s
|
float m_feedrate; // mm/s
|
||||||
float m_width; // mm
|
float m_width; // mm
|
||||||
|
@ -487,10 +520,17 @@ namespace Slic3r {
|
||||||
ExtruderTemps m_extruder_temps;
|
ExtruderTemps m_extruder_temps;
|
||||||
std::vector<float> m_filament_diameters;
|
std::vector<float> m_filament_diameters;
|
||||||
float m_extruded_last_z;
|
float m_extruded_last_z;
|
||||||
|
#if ENABLE_START_GCODE_VISUALIZATION
|
||||||
|
float m_first_layer_height; // mm
|
||||||
|
bool m_processing_start_custom_gcode;
|
||||||
|
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||||
unsigned int m_g1_line_id;
|
unsigned int m_g1_line_id;
|
||||||
unsigned int m_layer_id;
|
unsigned int m_layer_id;
|
||||||
CpColor m_cp_color;
|
CpColor m_cp_color;
|
||||||
bool m_use_volumetric_e;
|
bool m_use_volumetric_e;
|
||||||
|
#if ENABLE_SEAMS_VISUALIZATION
|
||||||
|
SeamsDetector m_seams_detector;
|
||||||
|
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||||
|
|
||||||
enum class EProducer
|
enum class EProducer
|
||||||
{
|
{
|
||||||
|
@ -668,7 +708,9 @@ namespace Slic3r {
|
||||||
float get_axis_max_jerk(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const;
|
float get_axis_max_jerk(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const;
|
||||||
float get_retract_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const;
|
float get_retract_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const;
|
||||||
float get_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const;
|
float get_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const;
|
||||||
void set_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value);
|
void set_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value);
|
||||||
|
float get_travel_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const;
|
||||||
|
void set_travel_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value);
|
||||||
float get_filament_load_time(size_t extruder_id);
|
float get_filament_load_time(size_t extruder_id);
|
||||||
float get_filament_unload_time(size_t extruder_id);
|
float get_filament_unload_time(size_t extruder_id);
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,16 @@ void ToolOrdering::reorder_extruders(unsigned int last_extruder_id)
|
||||||
lt.extruders.front() = last_extruder_id;
|
lt.extruders.front() = last_extruder_id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On first layer with wipe tower, prefer a soluble extruder
|
||||||
|
// at the beginning, so it is not wiped on the first layer.
|
||||||
|
if (lt == m_layer_tools[0] && m_print_config_ptr && m_print_config_ptr->wipe_tower) {
|
||||||
|
for (size_t i = 0; i<lt.extruders.size(); ++i)
|
||||||
|
if (m_print_config_ptr->filament_soluble.get_at(lt.extruders[i]-1)) { // 1-based...
|
||||||
|
std::swap(lt.extruders[i], lt.extruders.front());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
last_extruder_id = lt.extruders.back();
|
last_extruder_id = lt.extruders.back();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,6 @@
|
||||||
#include "BoundingBox.hpp"
|
#include "BoundingBox.hpp"
|
||||||
|
|
||||||
|
|
||||||
// Experimental "Peter's wipe tower" feature was partially implemented, inspired by
|
|
||||||
// PJR's idea of alternating two perpendicular wiping directions on a square tower.
|
|
||||||
// It is probably never going to be finished, there are multiple remaining issues
|
|
||||||
// and there is probably no need to go down this way. m_peters_wipe_tower variable
|
|
||||||
// turns this on, maybe it should just be removed. Anyway, the issues are
|
|
||||||
// - layer's are not exactly square
|
|
||||||
// - variable width for higher levels
|
|
||||||
// - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer)
|
|
||||||
// - enable enhanced first layer adhesion
|
|
||||||
|
|
||||||
|
|
||||||
namespace Slic3r
|
namespace Slic3r
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -122,8 +111,10 @@ public:
|
||||||
|
|
||||||
WipeTowerWriter& feedrate(float f)
|
WipeTowerWriter& feedrate(float f)
|
||||||
{
|
{
|
||||||
if (f != m_current_feedrate)
|
if (f != m_current_feedrate) {
|
||||||
m_gcode += "G1" + set_format_F(f) + "\n";
|
m_gcode += "G1" + set_format_F(f) + "\n";
|
||||||
|
m_current_feedrate = f;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +207,7 @@ public:
|
||||||
|
|
||||||
WipeTowerWriter& extrude(const Vec2f &dest, const float f = 0.f)
|
WipeTowerWriter& extrude(const Vec2f &dest, const float f = 0.f)
|
||||||
{ return extrude(dest.x(), dest.y(), f); }
|
{ return extrude(dest.x(), dest.y(), f); }
|
||||||
|
|
||||||
WipeTowerWriter& rectangle(const Vec2f& ld,float width,float height,const float f = 0.f)
|
WipeTowerWriter& rectangle(const Vec2f& ld,float width,float height,const float f = 0.f)
|
||||||
{
|
{
|
||||||
Vec2f corners[4];
|
Vec2f corners[4];
|
||||||
|
@ -242,6 +233,14 @@ public:
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WipeTowerWriter& rectangle(const WipeTower::box_coordinates& box, const float f = 0.f)
|
||||||
|
{
|
||||||
|
rectangle(Vec2f(box.ld.x(), box.ld.y()),
|
||||||
|
box.ru.x() - box.lu.x(),
|
||||||
|
box.ru.y() - box.rd.y(), f);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
WipeTowerWriter& load(float e, float f = 0.f)
|
WipeTowerWriter& load(float e, float f = 0.f)
|
||||||
{
|
{
|
||||||
if (e == 0.f && (f == 0.f || f == m_current_feedrate))
|
if (e == 0.f && (f == 0.f || f == m_current_feedrate))
|
||||||
|
@ -343,7 +342,7 @@ public:
|
||||||
WipeTowerWriter& speed_override_backup()
|
WipeTowerWriter& speed_override_backup()
|
||||||
{
|
{
|
||||||
// This is only supported by Prusa at this point (https://github.com/prusa3d/PrusaSlicer/issues/3114)
|
// This is only supported by Prusa at this point (https://github.com/prusa3d/PrusaSlicer/issues/3114)
|
||||||
if (m_gcode_flavor == gcfMarlin)
|
if (m_gcode_flavor == gcfMarlinLegacy || m_gcode_flavor == gcfMarlinFirmware)
|
||||||
m_gcode += "M220 B\n";
|
m_gcode += "M220 B\n";
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +350,7 @@ public:
|
||||||
// Let the firmware restore the active speed override value.
|
// Let the firmware restore the active speed override value.
|
||||||
WipeTowerWriter& speed_override_restore()
|
WipeTowerWriter& speed_override_restore()
|
||||||
{
|
{
|
||||||
if (m_gcode_flavor == gcfMarlin)
|
if (m_gcode_flavor == gcfMarlinLegacy || m_gcode_flavor == gcfMarlinFirmware)
|
||||||
m_gcode += "M220 R\n";
|
m_gcode += "M220 R\n";
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -523,13 +522,21 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
|
||||||
m_wipe_tower_brim_width(float(config.wipe_tower_brim_width)),
|
m_wipe_tower_brim_width(float(config.wipe_tower_brim_width)),
|
||||||
m_y_shift(0.f),
|
m_y_shift(0.f),
|
||||||
m_z_pos(0.f),
|
m_z_pos(0.f),
|
||||||
m_is_first_layer(false),
|
|
||||||
m_bridging(float(config.wipe_tower_bridging)),
|
m_bridging(float(config.wipe_tower_bridging)),
|
||||||
m_no_sparse_layers(config.wipe_tower_no_sparse_layers),
|
m_no_sparse_layers(config.wipe_tower_no_sparse_layers),
|
||||||
m_gcode_flavor(config.gcode_flavor),
|
m_gcode_flavor(config.gcode_flavor),
|
||||||
|
m_travel_speed(config.travel_speed),
|
||||||
m_current_tool(initial_tool),
|
m_current_tool(initial_tool),
|
||||||
wipe_volumes(wiping_matrix)
|
wipe_volumes(wiping_matrix)
|
||||||
{
|
{
|
||||||
|
// Read absolute value of first layer speed, if given as percentage,
|
||||||
|
// it is taken over following default. Speeds from config are not
|
||||||
|
// easily accessible here.
|
||||||
|
const float default_speed = 60.f;
|
||||||
|
m_first_layer_speed = config.get_abs_value("first_layer_speed", default_speed);
|
||||||
|
if (m_first_layer_speed == 0.f) // just to make sure autospeed doesn't break it.
|
||||||
|
m_first_layer_speed = default_speed / 2.f;
|
||||||
|
|
||||||
// If this is a single extruder MM printer, we will use all the SE-specific config values.
|
// If this is a single extruder MM printer, we will use all the SE-specific config values.
|
||||||
// Otherwise, the defaults will be used to turn off the SE stuff.
|
// Otherwise, the defaults will be used to turn off the SE stuff.
|
||||||
if (m_semm) {
|
if (m_semm) {
|
||||||
|
@ -539,10 +546,24 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
|
||||||
m_extra_loading_move = float(config.extra_loading_move);
|
m_extra_loading_move = float(config.extra_loading_move);
|
||||||
m_set_extruder_trimpot = config.high_current_on_filament_swap;
|
m_set_extruder_trimpot = config.high_current_on_filament_swap;
|
||||||
}
|
}
|
||||||
// Calculate where the priming lines should be - very naive test not detecting parallelograms or custom shapes
|
// Calculate where the priming lines should be - very naive test not detecting parallelograms etc.
|
||||||
const std::vector<Vec2d>& bed_points = config.bed_shape.values;
|
const std::vector<Vec2d>& bed_points = config.bed_shape.values;
|
||||||
|
BoundingBoxf bb(bed_points);
|
||||||
|
m_bed_width = float(bb.size().x());
|
||||||
m_bed_shape = (bed_points.size() == 4 ? RectangularBed : CircularBed);
|
m_bed_shape = (bed_points.size() == 4 ? RectangularBed : CircularBed);
|
||||||
m_bed_width = float(BoundingBoxf(bed_points).size().x());
|
|
||||||
|
if (m_bed_shape == CircularBed) {
|
||||||
|
// this may still be a custom bed, check that the points are roughly on a circle
|
||||||
|
double r2 = std::pow(m_bed_width/2., 2.);
|
||||||
|
double lim2 = std::pow(m_bed_width/10., 2.);
|
||||||
|
Vec2d center = bb.center();
|
||||||
|
for (const Vec2d& pt : bed_points)
|
||||||
|
if (std::abs(std::pow(pt.x()-center.x(), 2.) + std::pow(pt.y()-center.y(), 2.) - r2) > lim2) {
|
||||||
|
m_bed_shape = CustomBed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_bed_bottom_left = m_bed_shape == RectangularBed
|
m_bed_bottom_left = m_bed_shape == RectangularBed
|
||||||
? Vec2f(bed_points.front().x(), bed_points.front().y())
|
? Vec2f(bed_points.front().x(), bed_points.front().y())
|
||||||
: Vec2f::Zero();
|
: Vec2f::Zero();
|
||||||
|
@ -556,6 +577,7 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
|
||||||
m_filpar.push_back(FilamentParameters());
|
m_filpar.push_back(FilamentParameters());
|
||||||
|
|
||||||
m_filpar[idx].material = config.filament_type.get_at(idx);
|
m_filpar[idx].material = config.filament_type.get_at(idx);
|
||||||
|
m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
|
||||||
m_filpar[idx].temperature = config.temperature.get_at(idx);
|
m_filpar[idx].temperature = config.temperature.get_at(idx);
|
||||||
m_filpar[idx].first_layer_temperature = config.first_layer_temperature.get_at(idx);
|
m_filpar[idx].first_layer_temperature = config.first_layer_temperature.get_at(idx);
|
||||||
|
|
||||||
|
@ -617,10 +639,12 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
||||||
|
|
||||||
float prime_section_width = std::min(0.9f * m_bed_width / tools.size(), 60.f);
|
float prime_section_width = std::min(0.9f * m_bed_width / tools.size(), 60.f);
|
||||||
box_coordinates cleaning_box(Vec2f(0.02f * m_bed_width, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f);
|
box_coordinates cleaning_box(Vec2f(0.02f * m_bed_width, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f);
|
||||||
// In case of a circular bed, place it so it goes across the diameter and hope it will fit
|
if (m_bed_shape == CircularBed) {
|
||||||
if (m_bed_shape == CircularBed)
|
cleaning_box = box_coordinates(Vec2f(0.f, 0.f), prime_section_width, 100.f);
|
||||||
cleaning_box.translate(-m_bed_width/2 + m_bed_width * 0.03f, -m_bed_width * 0.12f);
|
float total_width_half = tools.size() * prime_section_width / 2.f;
|
||||||
if (m_bed_shape == RectangularBed)
|
cleaning_box.translate(-total_width_half, -std::sqrt(std::max(0.f, std::pow(m_bed_width/2, 2.f) - std::pow(1.05f * total_width_half, 2.f))));
|
||||||
|
}
|
||||||
|
else
|
||||||
cleaning_box.translate(m_bed_bottom_left);
|
cleaning_box.translate(m_bed_bottom_left);
|
||||||
|
|
||||||
std::vector<ToolChangeResult> results;
|
std::vector<ToolChangeResult> results;
|
||||||
|
@ -680,7 +704,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
||||||
if (m_set_extruder_trimpot)
|
if (m_set_extruder_trimpot)
|
||||||
writer.set_extruder_trimpot(550);
|
writer.set_extruder_trimpot(550);
|
||||||
writer.speed_override_restore()
|
writer.speed_override_restore()
|
||||||
.feedrate(6000)
|
.feedrate(m_travel_speed * 60.f)
|
||||||
.flush_planner_queue()
|
.flush_planner_queue()
|
||||||
.reset_extruder()
|
.reset_extruder()
|
||||||
.append("; CP PRIMING END\n"
|
.append("; CP PRIMING END\n"
|
||||||
|
@ -694,21 +718,14 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
||||||
m_old_temperature = -1; // If the priming is turned off in config, the temperature changing commands will not actually appear
|
m_old_temperature = -1; // If the priming is turned off in config, the temperature changing commands will not actually appear
|
||||||
// in the output gcode - we should not remember emitting them (we will output them twice in the worst case)
|
// in the output gcode - we should not remember emitting them (we will output them twice in the worst case)
|
||||||
|
|
||||||
// so that tool_change() will know to extrude the wipe tower brim:
|
|
||||||
m_print_brim = true;
|
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
|
WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
|
||||||
{
|
{
|
||||||
if ( m_print_brim )
|
|
||||||
return toolchange_Brim();
|
|
||||||
|
|
||||||
size_t old_tool = m_current_tool;
|
size_t old_tool = m_current_tool;
|
||||||
|
|
||||||
float wipe_area = 0.f;
|
float wipe_area = 0.f;
|
||||||
bool last_change_in_layer = false;
|
|
||||||
float wipe_volume = 0.f;
|
float wipe_volume = 0.f;
|
||||||
|
|
||||||
// Finds this toolchange info
|
// Finds this toolchange info
|
||||||
|
@ -716,9 +733,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
|
||||||
{
|
{
|
||||||
for (const auto &b : m_layer_info->tool_changes)
|
for (const auto &b : m_layer_info->tool_changes)
|
||||||
if ( b.new_tool == tool ) {
|
if ( b.new_tool == tool ) {
|
||||||
wipe_volume = b.wipe_volume;
|
wipe_volume = b.wipe_volume;
|
||||||
if (tool == m_layer_info->tool_changes.back().new_tool)
|
|
||||||
last_change_in_layer = true;
|
|
||||||
wipe_area = b.required_depth * m_layer_info->extra_spacing;
|
wipe_area = b.required_depth * m_layer_info->extra_spacing;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -727,17 +742,17 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
|
||||||
// Otherwise we are going to Unload only. And m_layer_info would be invalid.
|
// Otherwise we are going to Unload only. And m_layer_info would be invalid.
|
||||||
}
|
}
|
||||||
|
|
||||||
box_coordinates cleaning_box(
|
box_coordinates cleaning_box(
|
||||||
Vec2f(m_perimeter_width / 2.f, m_perimeter_width / 2.f),
|
Vec2f(m_perimeter_width / 2.f, m_perimeter_width / 2.f),
|
||||||
m_wipe_tower_width - m_perimeter_width,
|
m_wipe_tower_width - m_perimeter_width,
|
||||||
(tool != (unsigned int)(-1) ? /*m_layer_info->depth*/wipe_area+m_depth_traversed-0.5f*m_perimeter_width
|
(tool != (unsigned int)(-1) ? wipe_area+m_depth_traversed-0.5f*m_perimeter_width
|
||||||
: m_wipe_tower_depth-m_perimeter_width));
|
: m_wipe_tower_depth-m_perimeter_width));
|
||||||
|
|
||||||
WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
|
WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
|
||||||
writer.set_extrusion_flow(m_extrusion_flow)
|
writer.set_extrusion_flow(m_extrusion_flow)
|
||||||
.set_z(m_z_pos)
|
.set_z(m_z_pos)
|
||||||
.set_initial_tool(m_current_tool)
|
.set_initial_tool(m_current_tool)
|
||||||
.set_y_shift(m_y_shift + (tool!=(unsigned int)(-1) && (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower) ? m_layer_info->depth - m_layer_info->toolchanges_depth(): 0.f))
|
.set_y_shift(m_y_shift + (tool!=(unsigned int)(-1) && (m_current_shape == SHAPE_REVERSED) ? m_layer_info->depth - m_layer_info->toolchanges_depth(): 0.f))
|
||||||
.append(";--------------------\n"
|
.append(";--------------------\n"
|
||||||
"; CP TOOLCHANGE START\n")
|
"; CP TOOLCHANGE START\n")
|
||||||
.comment_with_value(" toolchange #", m_num_tool_changes + 1); // the number is zero-based
|
.comment_with_value(" toolchange #", m_num_tool_changes + 1); // the number is zero-based
|
||||||
|
@ -759,7 +774,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
|
||||||
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
||||||
if (tool != (unsigned int)-1){ // This is not the last change.
|
if (tool != (unsigned int)-1){ // This is not the last change.
|
||||||
toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material,
|
toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material,
|
||||||
m_is_first_layer ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature);
|
is_first_layer() ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature);
|
||||||
toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials.
|
toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials.
|
||||||
toolchange_Load(writer, cleaning_box);
|
toolchange_Load(writer, cleaning_box);
|
||||||
writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
|
writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
|
||||||
|
@ -770,24 +785,10 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
|
||||||
|
|
||||||
m_depth_traversed += wipe_area;
|
m_depth_traversed += wipe_area;
|
||||||
|
|
||||||
if (last_change_in_layer) {// draw perimeter line
|
|
||||||
writer.set_y_shift(m_y_shift);
|
|
||||||
if (m_peters_wipe_tower)
|
|
||||||
writer.rectangle(Vec2f::Zero(), m_layer_info->depth + 3*m_perimeter_width, m_wipe_tower_depth);
|
|
||||||
else {
|
|
||||||
writer.rectangle(Vec2f::Zero(), m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
|
|
||||||
if (layer_finished()) { // no finish_layer will be called, we must wipe the nozzle
|
|
||||||
writer.add_wipe_point(writer.x(), writer.y())
|
|
||||||
.add_wipe_point(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_set_extruder_trimpot)
|
if (m_set_extruder_trimpot)
|
||||||
writer.set_extruder_trimpot(550); // Reset the extruder current to a normal value.
|
writer.set_extruder_trimpot(550); // Reset the extruder current to a normal value.
|
||||||
writer.speed_override_restore();
|
writer.speed_override_restore();
|
||||||
writer.feedrate(6000)
|
writer.feedrate(m_travel_speed * 60.f)
|
||||||
.flush_planner_queue()
|
.flush_planner_queue()
|
||||||
.reset_extruder()
|
.reset_extruder()
|
||||||
.append("; CP TOOLCHANGE END\n"
|
.append("; CP TOOLCHANGE END\n"
|
||||||
|
@ -801,66 +802,6 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
|
||||||
return construct_tcr(writer, false, old_tool);
|
return construct_tcr(writer, false, old_tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_offset)
|
|
||||||
{
|
|
||||||
size_t old_tool = m_current_tool;
|
|
||||||
|
|
||||||
const box_coordinates wipeTower_box(
|
|
||||||
Vec2f::Zero(),
|
|
||||||
m_wipe_tower_width,
|
|
||||||
m_wipe_tower_depth);
|
|
||||||
|
|
||||||
WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
|
|
||||||
writer.set_extrusion_flow(m_extrusion_flow * 1.1f)
|
|
||||||
.set_z(m_z_pos) // Let the writer know the current Z position as a base for Z-hop.
|
|
||||||
.set_initial_tool(m_current_tool)
|
|
||||||
.append(";-------------------------------------\n"
|
|
||||||
"; CP WIPE TOWER FIRST LAYER BRIM START\n");
|
|
||||||
|
|
||||||
Vec2f initial_position = wipeTower_box.lu - Vec2f(m_wipe_tower_brim_width + 2*m_perimeter_width, 0);
|
|
||||||
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
|
||||||
|
|
||||||
// Prime the extruder left of the wipe tower.
|
|
||||||
writer.extrude_explicit(wipeTower_box.ld - Vec2f(m_wipe_tower_brim_width + 2*m_perimeter_width, 0),
|
|
||||||
1.5f * m_extrusion_flow * (wipeTower_box.lu.y() - wipeTower_box.ld.y()), 2400);
|
|
||||||
|
|
||||||
// The tool is supposed to be active and primed at the time when the wipe tower brim is extruded.
|
|
||||||
// Extrude brim around the future wipe tower ('normal' spacing with no extra void space).
|
|
||||||
box_coordinates box(wipeTower_box);
|
|
||||||
float spacing = m_perimeter_width - m_layer_height*float(1.-M_PI_4);
|
|
||||||
|
|
||||||
// How many perimeters shall the brim have?
|
|
||||||
size_t loops_num = (m_wipe_tower_brim_width + spacing/2.f) / spacing;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < loops_num; ++ i) {
|
|
||||||
box.expand(spacing);
|
|
||||||
writer.travel (box.ld, 7000)
|
|
||||||
.extrude(box.lu, 2100).extrude(box.ru)
|
|
||||||
.extrude(box.rd ).extrude(box.ld);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save actual brim width to be later passed to the Print object, which will use it
|
|
||||||
// for skirt calculation and pass it to GLCanvas for precise preview box
|
|
||||||
m_wipe_tower_brim_width_real = wipeTower_box.ld.x() - box.ld.x() + spacing/2.f;
|
|
||||||
|
|
||||||
box.expand(-spacing);
|
|
||||||
writer.add_wipe_point(writer.x(), writer.y())
|
|
||||||
.add_wipe_point(box.ld)
|
|
||||||
.add_wipe_point(box.rd);
|
|
||||||
|
|
||||||
writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n"
|
|
||||||
";-----------------------------------\n");
|
|
||||||
|
|
||||||
m_print_brim = false; // Mark the brim as extruded
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
return construct_tcr(writer, false, old_tool);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
||||||
void WipeTower::toolchange_Unload(
|
void WipeTower::toolchange_Unload(
|
||||||
|
@ -957,7 +898,7 @@ void WipeTower::toolchange_Unload(
|
||||||
// be already set and there is no need to change anything. Also, the temperature could be changed
|
// be already set and there is no need to change anything. Also, the temperature could be changed
|
||||||
// for wrong extruder.
|
// for wrong extruder.
|
||||||
if (m_semm) {
|
if (m_semm) {
|
||||||
if (new_temperature != 0 && (new_temperature != m_old_temperature || m_is_first_layer) ) { // Set the extruder temperature, but don't wait.
|
if (new_temperature != 0 && (new_temperature != m_old_temperature || is_first_layer()) ) { // Set the extruder temperature, but don't wait.
|
||||||
// If the required temperature is the same as last time, don't emit the M104 again (if user adjusted the value, it would be reset)
|
// If the required temperature is the same as last time, don't emit the M104 again (if user adjusted the value, it would be reset)
|
||||||
// However, always change temperatures on the first layer (this is to avoid issues with priming lines turned off).
|
// However, always change temperatures on the first layer (this is to avoid issues with priming lines turned off).
|
||||||
writer.set_extruder_temp(new_temperature, false);
|
writer.set_extruder_temp(new_temperature, false);
|
||||||
|
@ -1017,7 +958,10 @@ void WipeTower::toolchange_Change(
|
||||||
// gcode could have left the extruder somewhere, we cannot just start extruding. We should also inform the
|
// gcode could have left the extruder somewhere, we cannot just start extruding. We should also inform the
|
||||||
// postprocessor that we absolutely want to have this in the gcode, even if it thought it is the same as before.
|
// postprocessor that we absolutely want to have this in the gcode, even if it thought it is the same as before.
|
||||||
Vec2f current_pos = writer.pos_rotated();
|
Vec2f current_pos = writer.pos_rotated();
|
||||||
writer.append(std::string("G1 X") + std::to_string(current_pos.x()) + " Y" + std::to_string(current_pos.y()) + never_skip_tag() + "\n");
|
writer.feedrate(m_travel_speed * 60.f) // see https://github.com/prusa3d/PrusaSlicer/issues/5483
|
||||||
|
.append(std::string("G1 X") + std::to_string(current_pos.x())
|
||||||
|
+ " Y" + std::to_string(current_pos.y())
|
||||||
|
+ never_skip_tag() + "\n");
|
||||||
|
|
||||||
// The toolchange Tn command will be inserted later, only in case that the user does
|
// The toolchange Tn command will be inserted later, only in case that the user does
|
||||||
// not provide a custom toolchange gcode.
|
// not provide a custom toolchange gcode.
|
||||||
|
@ -1063,9 +1007,8 @@ void WipeTower::toolchange_Wipe(
|
||||||
float wipe_volume)
|
float wipe_volume)
|
||||||
{
|
{
|
||||||
// Increase flow on first layer, slow down print.
|
// Increase flow on first layer, slow down print.
|
||||||
writer.set_extrusion_flow(m_extrusion_flow * (m_is_first_layer ? 1.18f : 1.f))
|
writer.set_extrusion_flow(m_extrusion_flow * (is_first_layer() ? 1.18f : 1.f))
|
||||||
.append("; CP TOOLCHANGE WIPE\n");
|
.append("; CP TOOLCHANGE WIPE\n");
|
||||||
float wipe_coeff = m_is_first_layer ? 0.5f : 1.f;
|
|
||||||
const float& xl = cleaning_box.ld.x();
|
const float& xl = cleaning_box.ld.x();
|
||||||
const float& xr = cleaning_box.rd.x();
|
const float& xr = cleaning_box.rd.x();
|
||||||
|
|
||||||
|
@ -1075,7 +1018,9 @@ void WipeTower::toolchange_Wipe(
|
||||||
|
|
||||||
float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height);
|
float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height);
|
||||||
float dy = m_extra_spacing*m_perimeter_width;
|
float dy = m_extra_spacing*m_perimeter_width;
|
||||||
float wipe_speed = 1600.f;
|
|
||||||
|
const float target_speed = is_first_layer() ? m_first_layer_speed * 60.f : 4800.f;
|
||||||
|
float wipe_speed = 0.33f * target_speed;
|
||||||
|
|
||||||
// if there is less than 2.5*m_perimeter_width to the edge, advance straightaway (there is likely a blob anyway)
|
// if there is less than 2.5*m_perimeter_width to the edge, advance straightaway (there is likely a blob anyway)
|
||||||
if ((m_left_to_right ? xr-writer.x() : writer.x()-xl) < 2.5f*m_perimeter_width) {
|
if ((m_left_to_right ? xr-writer.x() : writer.x()-xl) < 2.5f*m_perimeter_width) {
|
||||||
|
@ -1086,17 +1031,17 @@ void WipeTower::toolchange_Wipe(
|
||||||
// now the wiping itself:
|
// now the wiping itself:
|
||||||
for (int i = 0; true; ++i) {
|
for (int i = 0; true; ++i) {
|
||||||
if (i!=0) {
|
if (i!=0) {
|
||||||
if (wipe_speed < 1610.f) wipe_speed = 1800.f;
|
if (wipe_speed < 0.34f * target_speed) wipe_speed = 0.375f * target_speed;
|
||||||
else if (wipe_speed < 1810.f) wipe_speed = 2200.f;
|
else if (wipe_speed < 0.377 * target_speed) wipe_speed = 0.458f * target_speed;
|
||||||
else if (wipe_speed < 2210.f) wipe_speed = 4200.f;
|
else if (wipe_speed < 0.46f * target_speed) wipe_speed = 0.875f * target_speed;
|
||||||
else wipe_speed = std::min(4800.f, wipe_speed + 50.f);
|
else wipe_speed = std::min(target_speed, wipe_speed + 50.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float traversed_x = writer.x();
|
float traversed_x = writer.x();
|
||||||
if (m_left_to_right)
|
if (m_left_to_right)
|
||||||
writer.extrude(xr - (i % 4 == 0 ? 0 : 1.5f*m_perimeter_width), writer.y(), wipe_speed * wipe_coeff);
|
writer.extrude(xr - (i % 4 == 0 ? 0 : 1.5f*m_perimeter_width), writer.y(), wipe_speed);
|
||||||
else
|
else
|
||||||
writer.extrude(xl + (i % 4 == 1 ? 0 : 1.5f*m_perimeter_width), writer.y(), wipe_speed * wipe_coeff);
|
writer.extrude(xl + (i % 4 == 1 ? 0 : 1.5f*m_perimeter_width), writer.y(), wipe_speed);
|
||||||
|
|
||||||
if (writer.y()+float(EPSILON) > cleaning_box.lu.y()-0.5f*m_perimeter_width)
|
if (writer.y()+float(EPSILON) > cleaning_box.lu.y()-0.5f*m_perimeter_width)
|
||||||
break; // in case next line would not fit
|
break; // in case next line would not fit
|
||||||
|
@ -1112,17 +1057,16 @@ void WipeTower::toolchange_Wipe(
|
||||||
m_left_to_right = !m_left_to_right;
|
m_left_to_right = !m_left_to_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is neither priming nor not the last toolchange on this layer - we are
|
// We may be going back to the model - wipe the nozzle. If this is followed
|
||||||
// going back to the model - wipe the nozzle.
|
// by finish_layer, this wipe path will be overwritten.
|
||||||
if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool) {
|
writer.add_wipe_point(writer.x(), writer.y())
|
||||||
|
.add_wipe_point(writer.x(), writer.y() - dy)
|
||||||
|
.add_wipe_point(! m_left_to_right ? m_wipe_tower_width : 0.f, writer.y() - dy);
|
||||||
|
|
||||||
|
if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool)
|
||||||
m_left_to_right = !m_left_to_right;
|
m_left_to_right = !m_left_to_right;
|
||||||
writer.add_wipe_point(writer.x(), writer.y())
|
|
||||||
.add_wipe_point(writer.x(), writer.y() - dy)
|
|
||||||
.add_wipe_point(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y() - dy);
|
|
||||||
|
|
||||||
}
|
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
|
||||||
|
|
||||||
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1130,9 +1074,8 @@ void WipeTower::toolchange_Wipe(
|
||||||
|
|
||||||
WipeTower::ToolChangeResult WipeTower::finish_layer()
|
WipeTower::ToolChangeResult WipeTower::finish_layer()
|
||||||
{
|
{
|
||||||
// This should only be called if the layer is not finished yet.
|
|
||||||
// Otherwise the caller would likely travel to the wipe tower in vain.
|
|
||||||
assert(! this->layer_finished());
|
assert(! this->layer_finished());
|
||||||
|
m_current_layer_finished = true;
|
||||||
|
|
||||||
size_t old_tool = m_current_tool;
|
size_t old_tool = m_current_tool;
|
||||||
|
|
||||||
|
@ -1140,61 +1083,75 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
|
||||||
writer.set_extrusion_flow(m_extrusion_flow)
|
writer.set_extrusion_flow(m_extrusion_flow)
|
||||||
.set_z(m_z_pos)
|
.set_z(m_z_pos)
|
||||||
.set_initial_tool(m_current_tool)
|
.set_initial_tool(m_current_tool)
|
||||||
.set_y_shift(m_y_shift - (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower ? m_layer_info->toolchanges_depth() : 0.f))
|
.set_y_shift(m_y_shift - (m_current_shape == SHAPE_REVERSED ? m_layer_info->toolchanges_depth() : 0.f));
|
||||||
.append(";--------------------\n"
|
|
||||||
"; CP EMPTY GRID START\n")
|
|
||||||
.comment_with_value(" layer #", m_num_layer_changes + 1);
|
|
||||||
|
|
||||||
// Slow down on the 1st layer.
|
// Slow down on the 1st layer.
|
||||||
float speed_factor = m_is_first_layer ? 0.5f : 1.f;
|
bool first_layer = is_first_layer();
|
||||||
|
float feedrate = first_layer ? m_first_layer_speed * 60.f : 2900.f;
|
||||||
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
||||||
box_coordinates fill_box(Vec2f(m_perimeter_width, m_depth_traversed + m_perimeter_width),
|
box_coordinates fill_box(Vec2f(m_perimeter_width, m_layer_info->depth-(current_depth-m_perimeter_width)),
|
||||||
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
|
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
|
||||||
|
|
||||||
|
|
||||||
writer.set_initial_position((m_left_to_right ? fill_box.ru : fill_box.lu), // so there is never a diagonal travel
|
writer.set_initial_position((m_left_to_right ? fill_box.ru : fill_box.lu), // so there is never a diagonal travel
|
||||||
m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
||||||
|
|
||||||
bool toolchanges_on_layer = m_layer_info->toolchanges_depth() > WT_EPSILON;
|
bool toolchanges_on_layer = m_layer_info->toolchanges_depth() > WT_EPSILON;
|
||||||
box_coordinates box = fill_box;
|
box_coordinates wt_box(Vec2f(0.f, (m_current_shape == SHAPE_REVERSED ? m_layer_info->toolchanges_depth() : 0.f)),
|
||||||
for (int i=0;i<2;++i) {
|
m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
|
||||||
if (! toolchanges_on_layer) {
|
|
||||||
if (i==0) box.expand(m_perimeter_width);
|
// inner perimeter of the sparse section, if there is space for it:
|
||||||
else box.expand(-m_perimeter_width);
|
if (fill_box.ru.y() - fill_box.rd.y() > m_perimeter_width - WT_EPSILON)
|
||||||
}
|
writer.rectangle(fill_box.ld, fill_box.rd.x()-fill_box.ld.x(), fill_box.ru.y()-fill_box.rd.y(), feedrate);
|
||||||
else i=2; // only draw the inner perimeter, outer has been already drawn by tool_change(...)
|
|
||||||
writer.rectangle(box.ld, box.rd.x()-box.ld.x(), box.ru.y()-box.rd.y(), 2900*speed_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we are in one of the corners, travel to ld along the perimeter:
|
// we are in one of the corners, travel to ld along the perimeter:
|
||||||
if (writer.x() > fill_box.ld.x()+EPSILON) writer.travel(fill_box.ld.x(),writer.y());
|
if (writer.x() > fill_box.ld.x()+EPSILON) writer.travel(fill_box.ld.x(),writer.y());
|
||||||
if (writer.y() > fill_box.ld.y()+EPSILON) writer.travel(writer.x(),fill_box.ld.y());
|
if (writer.y() > fill_box.ld.y()+EPSILON) writer.travel(writer.x(),fill_box.ld.y());
|
||||||
|
|
||||||
if (m_is_first_layer && m_adhesion) {
|
// Extrude infill to support the material to be printed above.
|
||||||
// Extrude a dense infill at the 1st layer to improve 1st layer adhesion of the wipe tower.
|
const float dy = (fill_box.lu.y() - fill_box.ld.y() - m_perimeter_width);
|
||||||
box.expand(-m_perimeter_width/2.f);
|
float left = fill_box.lu.x() + 2*m_perimeter_width;
|
||||||
int nsteps = int(floor((box.lu.y() - box.ld.y()) / (2*m_perimeter_width)));
|
float right = fill_box.ru.x() - 2 * m_perimeter_width;
|
||||||
float step = (box.lu.y() - box.ld.y()) / nsteps;
|
if (dy > m_perimeter_width)
|
||||||
writer.travel(box.ld - Vec2f(m_perimeter_width/2.f, m_perimeter_width/2.f));
|
{
|
||||||
if (nsteps >= 0)
|
writer.travel(fill_box.ld + Vec2f(m_perimeter_width * 2, 0.f))
|
||||||
for (int i = 0; i < nsteps; ++i) {
|
.append(";--------------------\n"
|
||||||
writer.extrude(box.ld.x()+m_perimeter_width/2.f, writer.y() + 0.5f * step);
|
"; CP EMPTY GRID START\n")
|
||||||
writer.extrude(box.rd.x() - m_perimeter_width / 2.f, writer.y());
|
.comment_with_value(" layer #", m_num_layer_changes + 1);
|
||||||
writer.extrude(box.rd.x() - m_perimeter_width / 2.f, writer.y() + 0.5f * step);
|
|
||||||
writer.extrude(box.ld.x() + m_perimeter_width / 2.f, writer.y());
|
// Is there a soluble filament wiped/rammed at the next layer?
|
||||||
|
// If so, the infill should not be sparse.
|
||||||
|
bool solid_infill = m_layer_info+1 == m_plan.end()
|
||||||
|
? false
|
||||||
|
: std::any_of((m_layer_info+1)->tool_changes.begin(),
|
||||||
|
(m_layer_info+1)->tool_changes.end(),
|
||||||
|
[this](const WipeTowerInfo::ToolChange& tch) {
|
||||||
|
return m_filpar[tch.new_tool].is_soluble
|
||||||
|
|| m_filpar[tch.old_tool].is_soluble;
|
||||||
|
});
|
||||||
|
solid_infill |= first_layer && m_adhesion;
|
||||||
|
|
||||||
|
if (solid_infill) {
|
||||||
|
float sparse_factor = 1.5f; // 1=solid, 2=every other line, etc.
|
||||||
|
if (first_layer) { // the infill should touch perimeters
|
||||||
|
left -= m_perimeter_width;
|
||||||
|
right += m_perimeter_width;
|
||||||
|
sparse_factor = 1.f;
|
||||||
}
|
}
|
||||||
writer.add_wipe_point(writer.x(), writer.y())
|
float y = fill_box.ld.y() + m_perimeter_width;
|
||||||
.add_wipe_point(box.rd.x()-m_perimeter_width/2.f,writer.y());
|
int n = dy / (m_perimeter_width * sparse_factor);
|
||||||
}
|
float spacing = (dy-m_perimeter_width)/(n-1);
|
||||||
else { // Extrude a sparse infill to support the material to be printed above.
|
int i=0;
|
||||||
const float dy = (fill_box.lu.y() - fill_box.ld.y() - m_perimeter_width);
|
for (i=0; i<n; ++i) {
|
||||||
const float left = fill_box.lu.x() + 2*m_perimeter_width;
|
writer.extrude(writer.x(), y, feedrate)
|
||||||
const float right = fill_box.ru.x() - 2 * m_perimeter_width;
|
.extrude(i%2 ? left : right, y);
|
||||||
if (dy > m_perimeter_width)
|
y = y + spacing;
|
||||||
{
|
}
|
||||||
// Extrude an inverse U at the left of the region.
|
writer.extrude(writer.x(), fill_box.lu.y());
|
||||||
writer.travel(fill_box.ld + Vec2f(m_perimeter_width * 2, 0.f))
|
} else {
|
||||||
.extrude(fill_box.lu + Vec2f(m_perimeter_width * 2, 0.f), 2900 * speed_factor);
|
// Extrude an inverse U at the left of the region and the sparse infill.
|
||||||
|
writer.extrude(fill_box.lu + Vec2f(m_perimeter_width * 2, 0.f), feedrate);
|
||||||
|
|
||||||
const int n = 1+int((right-left)/m_bridging);
|
const int n = 1+int((right-left)/m_bridging);
|
||||||
const float dx = (right-left)/n;
|
const float dx = (right-left)/n;
|
||||||
|
@ -1203,18 +1160,40 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
|
||||||
writer.travel(x,writer.y());
|
writer.travel(x,writer.y());
|
||||||
writer.extrude(x,i%2 ? fill_box.rd.y() : fill_box.ru.y());
|
writer.extrude(x,i%2 ? fill_box.rd.y() : fill_box.ru.y());
|
||||||
}
|
}
|
||||||
writer.add_wipe_point(Vec2f(writer.x(), writer.y()))
|
|
||||||
.add_wipe_point(Vec2f(left, writer.y()));
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
writer.add_wipe_point(Vec2f(writer.x(), writer.y()))
|
|
||||||
.add_wipe_point(Vec2f(right, writer.y()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.append("; CP EMPTY GRID END\n"
|
|
||||||
";------------------\n\n\n\n\n\n\n");
|
|
||||||
|
|
||||||
m_depth_traversed = m_wipe_tower_depth-m_perimeter_width;
|
writer.append("; CP EMPTY GRID END\n"
|
||||||
|
";------------------\n\n\n\n\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// outer perimeter (always):
|
||||||
|
writer.rectangle(wt_box, feedrate);
|
||||||
|
|
||||||
|
// brim (first layer only)
|
||||||
|
if (first_layer) {
|
||||||
|
box_coordinates box = wt_box;
|
||||||
|
float spacing = m_perimeter_width - m_layer_height*float(1.-M_PI_4);
|
||||||
|
// How many perimeters shall the brim have?
|
||||||
|
size_t loops_num = (m_wipe_tower_brim_width + spacing/2.f) / spacing;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < loops_num; ++ i) {
|
||||||
|
box.expand(spacing);
|
||||||
|
writer.rectangle(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save actual brim width to be later passed to the Print object, which will use it
|
||||||
|
// for skirt calculation and pass it to GLCanvas for precise preview box
|
||||||
|
m_wipe_tower_brim_width_real = wt_box.ld.x() - box.ld.x() + spacing/2.f;
|
||||||
|
wt_box = box;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now prepare future wipe. box contains rectangle that was extruded last (ccw).
|
||||||
|
Vec2f target = (writer.pos() == wt_box.ld ? wt_box.rd :
|
||||||
|
(writer.pos() == wt_box.rd ? wt_box.ru :
|
||||||
|
(writer.pos() == wt_box.ru ? wt_box.lu :
|
||||||
|
wt_box.ld)));
|
||||||
|
writer.add_wipe_point(writer.pos())
|
||||||
|
.add_wipe_point(target);
|
||||||
|
|
||||||
|
|
||||||
// Ask our writer about how much material was consumed.
|
// Ask our writer about how much material was consumed.
|
||||||
|
@ -1227,23 +1206,22 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box
|
// Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box
|
||||||
void WipeTower::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wipe_volume)
|
void WipeTower::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool,
|
||||||
|
unsigned int new_tool, float wipe_volume)
|
||||||
{
|
{
|
||||||
assert(m_plan.empty() || m_plan.back().z <= z_par + WT_EPSILON); // refuses to add a layer below the last one
|
assert(m_plan.empty() || m_plan.back().z <= z_par + WT_EPSILON); // refuses to add a layer below the last one
|
||||||
|
|
||||||
if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) // if we moved to a new layer, we'll add it to m_plan first
|
if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) // if we moved to a new layer, we'll add it to m_plan first
|
||||||
m_plan.push_back(WipeTowerInfo(z_par, layer_height_par));
|
m_plan.push_back(WipeTowerInfo(z_par, layer_height_par));
|
||||||
|
|
||||||
if (brim) { // this toolchange prints brim - we must add it to m_plan, but not to count its depth
|
if (m_first_layer_idx == size_t(-1) && (! m_no_sparse_layers || old_tool != new_tool))
|
||||||
m_plan.back().tool_changes.push_back(WipeTowerInfo::ToolChange(old_tool, new_tool));
|
m_first_layer_idx = m_plan.size() - 1;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (old_tool==new_tool) // new layer without toolchanges - we are done
|
if (old_tool == new_tool) // new layer without toolchanges - we are done
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// this is an actual toolchange - let's calculate depth to reserve on the wipe tower
|
// this is an actual toolchange - let's calculate depth to reserve on the wipe tower
|
||||||
float depth = 0.f;
|
float depth = 0.f;
|
||||||
float width = m_wipe_tower_width - 3*m_perimeter_width;
|
float width = m_wipe_tower_width - 3*m_perimeter_width;
|
||||||
float length_to_extrude = volume_to_length(0.25f * std::accumulate(m_filpar[old_tool].ramming_speed.begin(), m_filpar[old_tool].ramming_speed.end(), 0.f),
|
float length_to_extrude = volume_to_length(0.25f * std::accumulate(m_filpar[old_tool].ramming_speed.begin(), m_filpar[old_tool].ramming_speed.end(), 0.f),
|
||||||
m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator,
|
m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator,
|
||||||
|
@ -1293,28 +1271,65 @@ void WipeTower::save_on_last_wipe()
|
||||||
if (m_layer_info->tool_changes.size()==0) // we have no way to save anything on an empty layer
|
if (m_layer_info->tool_changes.size()==0) // we have no way to save anything on an empty layer
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const auto &toolchange : m_layer_info->tool_changes)
|
// Which toolchange will finish_layer extrusions be subtracted from?
|
||||||
|
int idx = first_toolchange_to_nonsoluble(m_layer_info->tool_changes);
|
||||||
|
|
||||||
|
for (int i=0; i<int(m_layer_info->tool_changes.size()); ++i) {
|
||||||
|
auto& toolchange = m_layer_info->tool_changes[i];
|
||||||
tool_change(toolchange.new_tool);
|
tool_change(toolchange.new_tool);
|
||||||
|
|
||||||
float width = m_wipe_tower_width - 3*m_perimeter_width; // width we draw into
|
if (i == idx) {
|
||||||
float length_to_save = 2*(m_wipe_tower_width+m_wipe_tower_depth) + (!layer_finished() ? finish_layer().total_extrusion_length_in_plane() : 0.f);
|
float width = m_wipe_tower_width - 3*m_perimeter_width; // width we draw into
|
||||||
float length_to_wipe = volume_to_length(m_layer_info->tool_changes.back().wipe_volume,
|
float length_to_save = finish_layer().total_extrusion_length_in_plane();
|
||||||
m_perimeter_width,m_layer_info->height) - m_layer_info->tool_changes.back().first_wipe_line - length_to_save;
|
float length_to_wipe = volume_to_length(toolchange.wipe_volume,
|
||||||
|
m_perimeter_width, m_layer_info->height) - toolchange.first_wipe_line - length_to_save;
|
||||||
|
|
||||||
length_to_wipe = std::max(length_to_wipe,0.f);
|
length_to_wipe = std::max(length_to_wipe,0.f);
|
||||||
float depth_to_wipe = m_perimeter_width * (std::floor(length_to_wipe/width) + ( length_to_wipe > 0.f ? 1.f : 0.f ) ) * m_extra_spacing;
|
float depth_to_wipe = m_perimeter_width * (std::floor(length_to_wipe/width) + ( length_to_wipe > 0.f ? 1.f : 0.f ) ) * m_extra_spacing;
|
||||||
|
|
||||||
//depth += (int(length_to_extrude / width) + 1) * m_perimeter_width;
|
toolchange.required_depth = toolchange.ramming_depth + depth_to_wipe;
|
||||||
m_layer_info->tool_changes.back().required_depth = m_layer_info->tool_changes.back().ramming_depth + depth_to_wipe;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return index of first toolchange that switches to non-soluble extruder
|
||||||
|
// ot -1 if there is no such toolchange.
|
||||||
|
int WipeTower::first_toolchange_to_nonsoluble(
|
||||||
|
const std::vector<WipeTowerInfo::ToolChange>& tool_changes) const
|
||||||
|
{
|
||||||
|
for (size_t idx=0; idx<tool_changes.size(); ++idx)
|
||||||
|
if (! m_filpar[tool_changes[idx].new_tool].is_soluble)
|
||||||
|
return idx;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WipeTower::ToolChangeResult merge_tcr(WipeTower::ToolChangeResult& first,
|
||||||
|
WipeTower::ToolChangeResult& second)
|
||||||
|
{
|
||||||
|
assert(first.new_tool == second.initial_tool);
|
||||||
|
WipeTower::ToolChangeResult out = first;
|
||||||
|
if (first.end_pos != second.start_pos) {
|
||||||
|
char buf[2048]; // Add a travel move from tc1.end_pos to tc2.start_pos.
|
||||||
|
sprintf(buf, "G1 X%.3f Y%.3f F7200\n", second.start_pos.x(), second.start_pos.y());
|
||||||
|
out.gcode += buf;
|
||||||
|
}
|
||||||
|
out.gcode += second.gcode;
|
||||||
|
out.extrusions.insert(out.extrusions.end(), second.extrusions.begin(), second.extrusions.end());
|
||||||
|
out.end_pos = second.end_pos;
|
||||||
|
out.wipe_path = second.wipe_path;
|
||||||
|
out.initial_tool = first.initial_tool;
|
||||||
|
out.new_tool = second.new_tool;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Processes vector m_plan and calls respective functions to generate G-code for the wipe tower
|
// Processes vector m_plan and calls respective functions to generate G-code for the wipe tower
|
||||||
// Resulting ToolChangeResults are appended into vector "result"
|
// Resulting ToolChangeResults are appended into vector "result"
|
||||||
void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result)
|
void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result)
|
||||||
{
|
{
|
||||||
if (m_plan.empty())
|
if (m_plan.empty())
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_extra_spacing = 1.f;
|
m_extra_spacing = 1.f;
|
||||||
|
@ -1325,9 +1340,6 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
|
||||||
plan_tower();
|
plan_tower();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_peters_wipe_tower)
|
|
||||||
make_wipe_tower_square();
|
|
||||||
|
|
||||||
m_layer_info = m_plan.begin();
|
m_layer_info = m_plan.begin();
|
||||||
|
|
||||||
// we don't know which extruder to start with - we'll set it according to the first toolchange
|
// we don't know which extruder to start with - we'll set it according to the first toolchange
|
||||||
|
@ -1346,65 +1358,41 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
|
||||||
std::vector<WipeTower::ToolChangeResult> layer_result;
|
std::vector<WipeTower::ToolChangeResult> layer_result;
|
||||||
for (auto layer : m_plan)
|
for (auto layer : m_plan)
|
||||||
{
|
{
|
||||||
set_layer(layer.z,layer.height,0,layer.z == m_plan.front().z,layer.z == m_plan.back().z);
|
set_layer(layer.z, layer.height, 0, false/*layer.z == m_plan.front().z*/, layer.z == m_plan.back().z);
|
||||||
if (m_peters_wipe_tower)
|
m_internal_rotation += 180.f;
|
||||||
m_internal_rotation += 90.f;
|
|
||||||
else
|
|
||||||
m_internal_rotation += 180.f;
|
|
||||||
|
|
||||||
if (!m_peters_wipe_tower && m_layer_info->depth < m_wipe_tower_depth - m_perimeter_width)
|
if (m_layer_info->depth < m_wipe_tower_depth - m_perimeter_width)
|
||||||
m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f;
|
m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f;
|
||||||
|
|
||||||
for (const auto &toolchange : layer.tool_changes)
|
int idx = first_toolchange_to_nonsoluble(layer.tool_changes);
|
||||||
layer_result.emplace_back(tool_change(toolchange.new_tool));
|
ToolChangeResult finish_layer_tcr;
|
||||||
|
|
||||||
if (! layer_finished()) {
|
if (idx == -1) {
|
||||||
auto finish_layer_toolchange = finish_layer();
|
// if there is no toolchange switching to non-soluble, finish layer
|
||||||
if ( ! layer.tool_changes.empty() ) { // we will merge it to the last toolchange
|
// will be called at the very beginning. That's the last possibility
|
||||||
auto& last_toolchange = layer_result.back();
|
// where a nonsoluble tool can be.
|
||||||
if (last_toolchange.end_pos != finish_layer_toolchange.start_pos) {
|
finish_layer_tcr = finish_layer();
|
||||||
char buf[2048]; // Add a travel move from tc1.end_pos to tc2.start_pos.
|
}
|
||||||
sprintf(buf, "G1 X%.3f Y%.3f F7200\n", finish_layer_toolchange.start_pos.x(), finish_layer_toolchange.start_pos.y());
|
|
||||||
last_toolchange.gcode += buf;
|
for (int i=0; i<int(layer.tool_changes.size()); ++i) {
|
||||||
}
|
layer_result.emplace_back(tool_change(layer.tool_changes[i].new_tool));
|
||||||
last_toolchange.gcode += finish_layer_toolchange.gcode;
|
if (i == idx) // finish_layer will be called after this toolchange
|
||||||
last_toolchange.extrusions.insert(last_toolchange.extrusions.end(), finish_layer_toolchange.extrusions.begin(), finish_layer_toolchange.extrusions.end());
|
finish_layer_tcr = finish_layer();
|
||||||
last_toolchange.end_pos = finish_layer_toolchange.end_pos;
|
}
|
||||||
last_toolchange.wipe_path = finish_layer_toolchange.wipe_path;
|
|
||||||
}
|
if (layer_result.empty()) {
|
||||||
|
// there is nothing to merge finish_layer with
|
||||||
|
layer_result.emplace_back(std::move(finish_layer_tcr));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (idx == -1)
|
||||||
|
layer_result[0] = merge_tcr(finish_layer_tcr, layer_result[0]);
|
||||||
else
|
else
|
||||||
layer_result.emplace_back(std::move(finish_layer_toolchange));
|
layer_result[idx] = merge_tcr(layer_result[idx], finish_layer_tcr);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.emplace_back(std::move(layer_result));
|
result.emplace_back(std::move(layer_result));
|
||||||
m_is_first_layer = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WipeTower::make_wipe_tower_square()
|
|
||||||
{
|
|
||||||
const float width = m_wipe_tower_width - 3 * m_perimeter_width;
|
|
||||||
const float depth = m_wipe_tower_depth - m_perimeter_width;
|
|
||||||
// area that we actually print into is width*depth
|
|
||||||
float side = sqrt(depth * width);
|
|
||||||
|
|
||||||
m_wipe_tower_width = side + 3 * m_perimeter_width;
|
|
||||||
m_wipe_tower_depth = side + 2 * m_perimeter_width;
|
|
||||||
// For all layers, find how depth changed and update all toolchange depths
|
|
||||||
for (auto &lay : m_plan)
|
|
||||||
{
|
|
||||||
side = sqrt(lay.depth * width);
|
|
||||||
float width_ratio = width / side;
|
|
||||||
|
|
||||||
//lay.extra_spacing = width_ratio;
|
|
||||||
for (auto &tch : lay.tool_changes)
|
|
||||||
tch.required_depth *= width_ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
plan_tower(); // propagates depth downwards again (width has changed)
|
|
||||||
for (auto& lay : m_plan) // depths set, now the spacing
|
|
||||||
lay.extra_spacing = lay.depth / lay.toolchanges_depth();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -84,6 +84,37 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct box_coordinates
|
||||||
|
{
|
||||||
|
box_coordinates(float left, float bottom, float width, float height) :
|
||||||
|
ld(left , bottom ),
|
||||||
|
lu(left , bottom + height),
|
||||||
|
rd(left + width, bottom ),
|
||||||
|
ru(left + width, bottom + height) {}
|
||||||
|
box_coordinates(const Vec2f &pos, float width, float height) : box_coordinates(pos(0), pos(1), width, height) {}
|
||||||
|
void translate(const Vec2f &shift) {
|
||||||
|
ld += shift; lu += shift;
|
||||||
|
rd += shift; ru += shift;
|
||||||
|
}
|
||||||
|
void translate(const float dx, const float dy) { translate(Vec2f(dx, dy)); }
|
||||||
|
void expand(const float offset) {
|
||||||
|
ld += Vec2f(- offset, - offset);
|
||||||
|
lu += Vec2f(- offset, offset);
|
||||||
|
rd += Vec2f( offset, - offset);
|
||||||
|
ru += Vec2f( offset, offset);
|
||||||
|
}
|
||||||
|
void expand(const float offset_x, const float offset_y) {
|
||||||
|
ld += Vec2f(- offset_x, - offset_y);
|
||||||
|
lu += Vec2f(- offset_x, offset_y);
|
||||||
|
rd += Vec2f( offset_x, - offset_y);
|
||||||
|
ru += Vec2f( offset_x, offset_y);
|
||||||
|
}
|
||||||
|
Vec2f ld; // left down
|
||||||
|
Vec2f lu; // left upper
|
||||||
|
Vec2f rd; // right lower
|
||||||
|
Vec2f ru; // right upper
|
||||||
|
};
|
||||||
|
|
||||||
// Construct ToolChangeResult from current state of WipeTower and WipeTowerWriter.
|
// Construct ToolChangeResult from current state of WipeTower and WipeTowerWriter.
|
||||||
// WipeTowerWriter is moved from !
|
// WipeTowerWriter is moved from !
|
||||||
ToolChangeResult construct_tcr(WipeTowerWriter& writer,
|
ToolChangeResult construct_tcr(WipeTowerWriter& writer,
|
||||||
|
@ -102,7 +133,7 @@ public:
|
||||||
|
|
||||||
// Appends into internal structure m_plan containing info about the future wipe tower
|
// Appends into internal structure m_plan containing info about the future wipe tower
|
||||||
// to be used before building begins. The entries must be added ordered in z.
|
// to be used before building begins. The entries must be added ordered in z.
|
||||||
void plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wipe_volume = 0.f);
|
void plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, float wipe_volume = 0.f);
|
||||||
|
|
||||||
// Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
|
// Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
|
||||||
void generate(std::vector<std::vector<ToolChangeResult>> &result);
|
void generate(std::vector<std::vector<ToolChangeResult>> &result);
|
||||||
|
@ -129,9 +160,8 @@ public:
|
||||||
{
|
{
|
||||||
m_z_pos = print_z;
|
m_z_pos = print_z;
|
||||||
m_layer_height = layer_height;
|
m_layer_height = layer_height;
|
||||||
m_is_first_layer = is_first_layer;
|
|
||||||
m_print_brim = is_first_layer;
|
|
||||||
m_depth_traversed = 0.f;
|
m_depth_traversed = 0.f;
|
||||||
|
m_current_layer_finished = false;
|
||||||
m_current_shape = (! is_first_layer && m_current_shape == SHAPE_NORMAL) ? SHAPE_REVERSED : SHAPE_NORMAL;
|
m_current_shape = (! is_first_layer && m_current_shape == SHAPE_NORMAL) ? SHAPE_REVERSED : SHAPE_NORMAL;
|
||||||
if (is_first_layer) {
|
if (is_first_layer) {
|
||||||
this->m_num_layer_changes = 0;
|
this->m_num_layer_changes = 0;
|
||||||
|
@ -175,7 +205,7 @@ public:
|
||||||
|
|
||||||
// Is the current layer finished?
|
// Is the current layer finished?
|
||||||
bool layer_finished() const {
|
bool layer_finished() const {
|
||||||
return ( (m_is_first_layer ? m_wipe_tower_depth - m_perimeter_width : m_layer_info->depth) - WT_EPSILON < m_depth_traversed);
|
return m_current_layer_finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> get_used_filament() const { return m_used_filament_length; }
|
std::vector<float> get_used_filament() const { return m_used_filament_length; }
|
||||||
|
@ -183,6 +213,7 @@ public:
|
||||||
|
|
||||||
struct FilamentParameters {
|
struct FilamentParameters {
|
||||||
std::string material = "PLA";
|
std::string material = "PLA";
|
||||||
|
bool is_soluble = false;
|
||||||
int temperature = 0;
|
int temperature = 0;
|
||||||
int first_layer_temperature = 0;
|
int first_layer_temperature = 0;
|
||||||
float loading_speed = 0.f;
|
float loading_speed = 0.f;
|
||||||
|
@ -208,7 +239,6 @@ private:
|
||||||
SHAPE_REVERSED = -1
|
SHAPE_REVERSED = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet
|
|
||||||
const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
|
const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
|
||||||
const float WT_EPSILON = 1e-3f;
|
const float WT_EPSILON = 1e-3f;
|
||||||
float filament_area() const {
|
float filament_area() const {
|
||||||
|
@ -228,8 +258,10 @@ private:
|
||||||
float m_z_pos = 0.f; // Current Z position.
|
float m_z_pos = 0.f; // Current Z position.
|
||||||
float m_layer_height = 0.f; // Current layer height.
|
float m_layer_height = 0.f; // Current layer height.
|
||||||
size_t m_max_color_changes = 0; // Maximum number of color changes per layer.
|
size_t m_max_color_changes = 0; // Maximum number of color changes per layer.
|
||||||
bool m_is_first_layer = false;// Is this the 1st layer of the print? If so, print the brim around the waste tower.
|
|
||||||
int m_old_temperature = -1; // To keep track of what was the last temp that we set (so we don't issue the command when not neccessary)
|
int m_old_temperature = -1; // To keep track of what was the last temp that we set (so we don't issue the command when not neccessary)
|
||||||
|
float m_travel_speed = 0.f;
|
||||||
|
float m_first_layer_speed = 0.f;
|
||||||
|
size_t m_first_layer_idx = size_t(-1);
|
||||||
|
|
||||||
// G-code generator parameters.
|
// G-code generator parameters.
|
||||||
float m_cooling_tube_retraction = 0.f;
|
float m_cooling_tube_retraction = 0.f;
|
||||||
|
@ -245,7 +277,8 @@ private:
|
||||||
// Bed properties
|
// Bed properties
|
||||||
enum {
|
enum {
|
||||||
RectangularBed,
|
RectangularBed,
|
||||||
CircularBed
|
CircularBed,
|
||||||
|
CustomBed
|
||||||
} m_bed_shape;
|
} m_bed_shape;
|
||||||
float m_bed_width; // width of the bed bounding box
|
float m_bed_width; // width of the bed bounding box
|
||||||
Vec2f m_bed_bottom_left; // bottom-left corner coordinates (for rectangular beds)
|
Vec2f m_bed_bottom_left; // bottom-left corner coordinates (for rectangular beds)
|
||||||
|
@ -268,9 +301,12 @@ private:
|
||||||
const std::vector<std::vector<float>> wipe_volumes;
|
const std::vector<std::vector<float>> wipe_volumes;
|
||||||
|
|
||||||
float m_depth_traversed = 0.f; // Current y position at the wipe tower.
|
float m_depth_traversed = 0.f; // Current y position at the wipe tower.
|
||||||
|
bool m_current_layer_finished = false;
|
||||||
bool m_left_to_right = true;
|
bool m_left_to_right = true;
|
||||||
float m_extra_spacing = 1.f;
|
float m_extra_spacing = 1.f;
|
||||||
|
|
||||||
|
bool is_first_layer() const { return size_t(m_layer_info - m_plan.begin()) == m_first_layer_idx; }
|
||||||
|
|
||||||
// Calculates extrusion flow needed to produce required line width for given layer height
|
// Calculates extrusion flow needed to produce required line width for given layer height
|
||||||
float extrusion_flow(float layer_height = -1.f) const // negative layer_height - return current m_extrusion_flow
|
float extrusion_flow(float layer_height = -1.f) const // negative layer_height - return current m_extrusion_flow
|
||||||
{
|
{
|
||||||
|
@ -294,39 +330,7 @@ private:
|
||||||
void save_on_last_wipe();
|
void save_on_last_wipe();
|
||||||
|
|
||||||
|
|
||||||
struct box_coordinates
|
// to store information about tool changes for a given layer
|
||||||
{
|
|
||||||
box_coordinates(float left, float bottom, float width, float height) :
|
|
||||||
ld(left , bottom ),
|
|
||||||
lu(left , bottom + height),
|
|
||||||
rd(left + width, bottom ),
|
|
||||||
ru(left + width, bottom + height) {}
|
|
||||||
box_coordinates(const Vec2f &pos, float width, float height) : box_coordinates(pos(0), pos(1), width, height) {}
|
|
||||||
void translate(const Vec2f &shift) {
|
|
||||||
ld += shift; lu += shift;
|
|
||||||
rd += shift; ru += shift;
|
|
||||||
}
|
|
||||||
void translate(const float dx, const float dy) { translate(Vec2f(dx, dy)); }
|
|
||||||
void expand(const float offset) {
|
|
||||||
ld += Vec2f(- offset, - offset);
|
|
||||||
lu += Vec2f(- offset, offset);
|
|
||||||
rd += Vec2f( offset, - offset);
|
|
||||||
ru += Vec2f( offset, offset);
|
|
||||||
}
|
|
||||||
void expand(const float offset_x, const float offset_y) {
|
|
||||||
ld += Vec2f(- offset_x, - offset_y);
|
|
||||||
lu += Vec2f(- offset_x, offset_y);
|
|
||||||
rd += Vec2f( offset_x, - offset_y);
|
|
||||||
ru += Vec2f( offset_x, offset_y);
|
|
||||||
}
|
|
||||||
Vec2f ld; // left down
|
|
||||||
Vec2f lu; // left upper
|
|
||||||
Vec2f rd; // right lower
|
|
||||||
Vec2f ru; // right upper
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// to store information about tool changes for a given layer
|
|
||||||
struct WipeTowerInfo{
|
struct WipeTowerInfo{
|
||||||
struct ToolChange {
|
struct ToolChange {
|
||||||
size_t old_tool;
|
size_t old_tool;
|
||||||
|
@ -356,11 +360,10 @@ private:
|
||||||
// Stores information about used filament length per extruder:
|
// Stores information about used filament length per extruder:
|
||||||
std::vector<float> m_used_filament_length;
|
std::vector<float> m_used_filament_length;
|
||||||
|
|
||||||
|
// Return index of first toolchange that switches to non-soluble extruder
|
||||||
// Returns gcode for wipe tower brim
|
// ot -1 if there is no such toolchange.
|
||||||
// sideOnly -- set to false -- experimental, draw brim on sides of wipe tower
|
int first_toolchange_to_nonsoluble(
|
||||||
// offset -- set to 0 -- experimental, offset to replace brim in front / rear of wipe tower
|
const std::vector<WipeTowerInfo::ToolChange>& tool_changes) const;
|
||||||
ToolChangeResult toolchange_Brim(bool sideOnly = false, float y_offset = 0.f);
|
|
||||||
|
|
||||||
void toolchange_Unload(
|
void toolchange_Unload(
|
||||||
WipeTowerWriter &writer,
|
WipeTowerWriter &writer,
|
||||||
|
@ -386,6 +389,6 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}; // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif // WipeTowerPrusaMM_hpp_
|
#endif // WipeTowerPrusaMM_hpp_
|
||||||
|
|
|
@ -13,13 +13,13 @@ namespace Slic3r {
|
||||||
void GCodeReader::apply_config(const GCodeConfig &config)
|
void GCodeReader::apply_config(const GCodeConfig &config)
|
||||||
{
|
{
|
||||||
m_config = config;
|
m_config = config;
|
||||||
m_extrusion_axis = m_config.get_extrusion_axis()[0];
|
m_extrusion_axis = get_extrusion_axis(m_config)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeReader::apply_config(const DynamicPrintConfig &config)
|
void GCodeReader::apply_config(const DynamicPrintConfig &config)
|
||||||
{
|
{
|
||||||
m_config.apply(config, true);
|
m_config.apply(config, true);
|
||||||
m_extrusion_axis = m_config.get_extrusion_axis()[0];
|
m_extrusion_axis = get_extrusion_axis(m_config)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair<const char*, const char*> &command)
|
const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair<const char*, const char*> &command)
|
||||||
|
|
|
@ -18,9 +18,10 @@ namespace Slic3r {
|
||||||
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
||||||
{
|
{
|
||||||
this->config.apply(print_config, true);
|
this->config.apply(print_config, true);
|
||||||
m_extrusion_axis = this->config.get_extrusion_axis();
|
m_extrusion_axis = get_extrusion_axis(this->config);
|
||||||
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
|
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
|
||||||
m_max_acceleration = std::lrint((print_config.gcode_flavor.value == gcfMarlin && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
|
bool is_marlin = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware;
|
||||||
|
m_max_acceleration = std::lrint((is_marlin && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
|
||||||
print_config.machine_max_acceleration_extruding.values.front() : 0);
|
print_config.machine_max_acceleration_extruding.values.front() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +49,8 @@ std::string GCodeWriter::preamble()
|
||||||
}
|
}
|
||||||
if (FLAVOR_IS(gcfRepRapSprinter) ||
|
if (FLAVOR_IS(gcfRepRapSprinter) ||
|
||||||
FLAVOR_IS(gcfRepRapFirmware) ||
|
FLAVOR_IS(gcfRepRapFirmware) ||
|
||||||
FLAVOR_IS(gcfMarlin) ||
|
FLAVOR_IS(gcfMarlinLegacy) ||
|
||||||
|
FLAVOR_IS(gcfMarlinFirmware) ||
|
||||||
FLAVOR_IS(gcfTeacup) ||
|
FLAVOR_IS(gcfTeacup) ||
|
||||||
FLAVOR_IS(gcfRepetier) ||
|
FLAVOR_IS(gcfRepetier) ||
|
||||||
FLAVOR_IS(gcfSmoothie))
|
FLAVOR_IS(gcfSmoothie))
|
||||||
|
@ -205,8 +207,12 @@ std::string GCodeWriter::set_acceleration(unsigned int acceleration)
|
||||||
// M202: Set max travel acceleration
|
// M202: Set max travel acceleration
|
||||||
gcode << "M202 X" << acceleration << " Y" << acceleration;
|
gcode << "M202 X" << acceleration << " Y" << acceleration;
|
||||||
} else if (FLAVOR_IS(gcfRepRapFirmware)) {
|
} else if (FLAVOR_IS(gcfRepRapFirmware)) {
|
||||||
// M204: Set default acceleration
|
// M204: Set default acceleration
|
||||||
gcode << "M204 P" << acceleration;
|
gcode << "M204 P" << acceleration;
|
||||||
|
} else if (FLAVOR_IS(gcfMarlinFirmware)) {
|
||||||
|
// This is new MarlinFirmware with separated print/retraction/travel acceleration.
|
||||||
|
// Use M204 P, we don't want to override travel acc by M204 S (which is deprecated anyway).
|
||||||
|
gcode << "M204 P" << acceleration;
|
||||||
} else {
|
} else {
|
||||||
// M204: Set default acceleration
|
// M204: Set default acceleration
|
||||||
gcode << "M204 S" << acceleration;
|
gcode << "M204 S" << acceleration;
|
||||||
|
|
|
@ -1087,11 +1087,13 @@ bool
|
||||||
MedialAxis::validate_edge(const VD::edge_type* edge)
|
MedialAxis::validate_edge(const VD::edge_type* edge)
|
||||||
{
|
{
|
||||||
// prevent overflows and detect almost-infinite edges
|
// prevent overflows and detect almost-infinite edges
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||||
std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||||
std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||||
std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED))
|
std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED))
|
||||||
return false;
|
return false;
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
|
||||||
// construct the line representing this edge of the Voronoi diagram
|
// construct the line representing this edge of the Voronoi diagram
|
||||||
const Line line(
|
const Line line(
|
||||||
|
|
|
@ -22,12 +22,14 @@
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
namespace ClipperLib {
|
namespace Slic3r {
|
||||||
class PolyNode;
|
|
||||||
using PolyNodes = std::vector<PolyNode*>;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Slic3r { namespace Geometry {
|
namespace ClipperLib {
|
||||||
|
class PolyNode;
|
||||||
|
using PolyNodes = std::vector<PolyNode*>;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Geometry {
|
||||||
|
|
||||||
// Generic result of an orientation predicate.
|
// Generic result of an orientation predicate.
|
||||||
enum Orientation
|
enum Orientation
|
||||||
|
@ -299,20 +301,23 @@ bool liang_barsky_line_clipping(
|
||||||
|
|
||||||
// Ugly named variant, that accepts the squared line
|
// Ugly named variant, that accepts the squared line
|
||||||
// Don't call me with a nearly zero length vector!
|
// Don't call me with a nearly zero length vector!
|
||||||
|
// sympy:
|
||||||
|
// factor(solve([a * x + b * y + c, x**2 + y**2 - r**2], [x, y])[0])
|
||||||
|
// factor(solve([a * x + b * y + c, x**2 + y**2 - r**2], [x, y])[1])
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int ray_circle_intersections_r2_lv2_c(T r2, T a, T b, T lv2, T c, std::pair<Eigen::Matrix<T, 2, 1, Eigen::DontAlign>, Eigen::Matrix<T, 2, 1, Eigen::DontAlign>> &out)
|
int ray_circle_intersections_r2_lv2_c(T r2, T a, T b, T lv2, T c, std::pair<Eigen::Matrix<T, 2, 1, Eigen::DontAlign>, Eigen::Matrix<T, 2, 1, Eigen::DontAlign>> &out)
|
||||||
{
|
{
|
||||||
T x0 = - a * c / lv2;
|
T x0 = - a * c;
|
||||||
T y0 = - b * c / lv2;
|
T y0 = - b * c;
|
||||||
T d = r2 - c * c / lv2;
|
T d2 = r2 * lv2 - c * c;
|
||||||
if (d < T(0))
|
if (d2 < T(0))
|
||||||
return 0;
|
return 0;
|
||||||
T mult = sqrt(d / lv2);
|
T d = sqrt(d2);
|
||||||
out.first.x() = x0 + b * mult;
|
out.first.x() = (x0 + b * d) / lv2;
|
||||||
out.first.y() = y0 - a * mult;
|
out.first.y() = (y0 - a * d) / lv2;
|
||||||
out.second.x() = x0 - b * mult;
|
out.second.x() = (x0 - b * d) / lv2;
|
||||||
out.second.y() = y0 + a * mult;
|
out.second.y() = (y0 + a * d) / lv2;
|
||||||
return mult == T(0) ? 1 : 2;
|
return d == T(0) ? 1 : 2;
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int ray_circle_intersections(T r, T a, T b, T c, std::pair<Eigen::Matrix<T, 2, 1, Eigen::DontAlign>, Eigen::Matrix<T, 2, 1, Eigen::DontAlign>> &out)
|
int ray_circle_intersections(T r, T a, T b, T c, std::pair<Eigen::Matrix<T, 2, 1, Eigen::DontAlign>, Eigen::Matrix<T, 2, 1, Eigen::DontAlign>> &out)
|
||||||
|
@ -527,6 +532,6 @@ inline bool is_rotation_ninety_degrees(const Vec3d &rotation)
|
||||||
return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z());
|
return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
} }
|
} } // namespace Slicer::Geometry
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,11 +39,11 @@ void Layer::make_slices()
|
||||||
ExPolygons slices;
|
ExPolygons slices;
|
||||||
if (m_regions.size() == 1) {
|
if (m_regions.size() == 1) {
|
||||||
// optimization: if we only have one region, take its slices
|
// optimization: if we only have one region, take its slices
|
||||||
slices = m_regions.front()->slices;
|
slices = to_expolygons(m_regions.front()->slices.surfaces);
|
||||||
} else {
|
} else {
|
||||||
Polygons slices_p;
|
Polygons slices_p;
|
||||||
for (LayerRegion *layerm : m_regions)
|
for (LayerRegion *layerm : m_regions)
|
||||||
polygons_append(slices_p, to_polygons(layerm->slices));
|
polygons_append(slices_p, to_polygons(layerm->slices.surfaces));
|
||||||
slices = union_ex(slices_p);
|
slices = union_ex(slices_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ ExPolygons Layer::merged(float offset_scaled) const
|
||||||
const PrintRegionConfig &config = layerm->region()->config();
|
const PrintRegionConfig &config = layerm->region()->config();
|
||||||
// Our users learned to bend Slic3r to produce empty volumes to act as subtracters. Only add the region if it is non-empty.
|
// Our users learned to bend Slic3r to produce empty volumes to act as subtracters. Only add the region if it is non-empty.
|
||||||
if (config.bottom_solid_layers > 0 || config.top_solid_layers > 0 || config.fill_density > 0. || config.perimeters > 0)
|
if (config.bottom_solid_layers > 0 || config.top_solid_layers > 0 || config.fill_density > 0. || config.perimeters > 0)
|
||||||
append(polygons, offset(to_expolygons(layerm->slices.surfaces), offset_scaled));
|
append(polygons, offset(layerm->slices.surfaces, offset_scaled));
|
||||||
}
|
}
|
||||||
ExPolygons out = union_ex(polygons);
|
ExPolygons out = union_ex(polygons);
|
||||||
if (offset_scaled2 != 0.f)
|
if (offset_scaled2 != 0.f)
|
||||||
|
@ -185,7 +185,7 @@ void Layer::make_perimeters()
|
||||||
}
|
}
|
||||||
// merge the surfaces assigned to each group
|
// merge the surfaces assigned to each group
|
||||||
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
|
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
|
||||||
new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front());
|
new_slices.append(offset_ex(surfaces_with_extra_perimeters.second, ClipperSafetyOffset), surfaces_with_extra_perimeters.second.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
// make perimeters
|
// make perimeters
|
||||||
|
@ -196,7 +196,7 @@ void Layer::make_perimeters()
|
||||||
if (!fill_surfaces.surfaces.empty()) {
|
if (!fill_surfaces.surfaces.empty()) {
|
||||||
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
||||||
// Separate the fill surfaces.
|
// Separate the fill surfaces.
|
||||||
ExPolygons expp = intersection_ex(to_polygons(fill_surfaces), (*l)->slices);
|
ExPolygons expp = intersection_ex(fill_surfaces.surfaces, (*l)->slices.surfaces);
|
||||||
(*l)->fill_expolygons = expp;
|
(*l)->fill_expolygons = expp;
|
||||||
(*l)->fill_surfaces.set(std::move(expp), fill_surfaces.surfaces.front());
|
(*l)->fill_surfaces.set(std::move(expp), fill_surfaces.surfaces.front());
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ protected:
|
||||||
// between the raft and the object first layer.
|
// between the raft and the object first layer.
|
||||||
SupportLayer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
|
SupportLayer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
|
||||||
Layer(id, object, height, print_z, slice_z) {}
|
Layer(id, object, height, print_z, slice_z) {}
|
||||||
virtual ~SupportLayer() {}
|
virtual ~SupportLayer() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,19 +49,17 @@ void LayerRegion::slices_to_fill_surfaces_clipped()
|
||||||
// in place. However we're now only using its boundaries (which are invariant)
|
// in place. However we're now only using its boundaries (which are invariant)
|
||||||
// so we're safe. This guarantees idempotence of prepare_infill() also in case
|
// so we're safe. This guarantees idempotence of prepare_infill() also in case
|
||||||
// that combine_infill() turns some fill_surface into VOID surfaces.
|
// that combine_infill() turns some fill_surface into VOID surfaces.
|
||||||
// Polygons fill_boundaries = to_polygons(std::move(this->fill_surfaces));
|
|
||||||
Polygons fill_boundaries = to_polygons(this->fill_expolygons);
|
|
||||||
// Collect polygons per surface type.
|
// Collect polygons per surface type.
|
||||||
std::vector<Polygons> polygons_by_surface;
|
std::vector<SurfacesPtr> by_surface;
|
||||||
polygons_by_surface.assign(size_t(stCount), Polygons());
|
by_surface.assign(size_t(stCount), SurfacesPtr());
|
||||||
for (Surface &surface : this->slices.surfaces)
|
for (Surface &surface : this->slices.surfaces)
|
||||||
polygons_append(polygons_by_surface[(size_t)surface.surface_type], surface.expolygon);
|
by_surface[size_t(surface.surface_type)].emplace_back(&surface);
|
||||||
// Trim surfaces by the fill_boundaries.
|
// Trim surfaces by the fill_boundaries.
|
||||||
this->fill_surfaces.surfaces.clear();
|
this->fill_surfaces.surfaces.clear();
|
||||||
for (size_t surface_type = 0; surface_type < size_t(stCount); ++ surface_type) {
|
for (size_t surface_type = 0; surface_type < size_t(stCount); ++ surface_type) {
|
||||||
const Polygons &polygons = polygons_by_surface[surface_type];
|
const SurfacesPtr &this_surfaces = by_surface[surface_type];
|
||||||
if (! polygons.empty())
|
if (! this_surfaces.empty())
|
||||||
this->fill_surfaces.append(intersection_ex(polygons, fill_boundaries), SurfaceType(surface_type));
|
this->fill_surfaces.append(intersection_ex(this_surfaces, this->fill_expolygons), SurfaceType(surface_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,12 +214,12 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Grown by 3mm.
|
// Grown by 3mm.
|
||||||
Polygons polys = offset(to_polygons(bridges[i].expolygon), margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
Polygons polys = offset(bridges[i].expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
||||||
if (idx_island == -1) {
|
if (idx_island == -1) {
|
||||||
BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!";
|
BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!";
|
||||||
} else {
|
} else {
|
||||||
// Found an island, to which this bridge region belongs. Trim it,
|
// Found an island, to which this bridge region belongs. Trim it,
|
||||||
polys = intersection(polys, to_polygons(fill_boundaries_ex[idx_island]));
|
polys = intersection(polys, fill_boundaries_ex[idx_island]);
|
||||||
}
|
}
|
||||||
bridge_bboxes.push_back(get_extents(polys));
|
bridge_bboxes.push_back(get_extents(polys));
|
||||||
bridges_grown.push_back(std::move(polys));
|
bridges_grown.push_back(std::move(polys));
|
||||||
|
@ -325,11 +323,11 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
|
||||||
if (s1.empty())
|
if (s1.empty())
|
||||||
continue;
|
continue;
|
||||||
Polygons polys;
|
Polygons polys;
|
||||||
polygons_append(polys, std::move(s1));
|
polygons_append(polys, to_polygons(std::move(s1)));
|
||||||
for (size_t j = i + 1; j < top.size(); ++ j) {
|
for (size_t j = i + 1; j < top.size(); ++ j) {
|
||||||
Surface &s2 = top[j];
|
Surface &s2 = top[j];
|
||||||
if (! s2.empty() && surfaces_could_merge(s1, s2)) {
|
if (! s2.empty() && surfaces_could_merge(s1, s2)) {
|
||||||
polygons_append(polys, std::move(s2));
|
polygons_append(polys, to_polygons(std::move(s2)));
|
||||||
s2.clear();
|
s2.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,11 +349,11 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
|
||||||
if (s1.empty())
|
if (s1.empty())
|
||||||
continue;
|
continue;
|
||||||
Polygons polys;
|
Polygons polys;
|
||||||
polygons_append(polys, std::move(s1));
|
polygons_append(polys, to_polygons(std::move(s1)));
|
||||||
for (size_t j = i + 1; j < internal.size(); ++ j) {
|
for (size_t j = i + 1; j < internal.size(); ++ j) {
|
||||||
Surface &s2 = internal[j];
|
Surface &s2 = internal[j];
|
||||||
if (! s2.empty() && surfaces_could_merge(s1, s2)) {
|
if (! s2.empty() && surfaces_could_merge(s1, s2)) {
|
||||||
polygons_append(polys, std::move(s2));
|
polygons_append(polys, to_polygons(std::move(s2)));
|
||||||
s2.clear();
|
s2.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,7 +421,7 @@ void LayerRegion::trim_surfaces(const Polygons &trimming_polygons)
|
||||||
for (const Surface &surface : this->slices.surfaces)
|
for (const Surface &surface : this->slices.surfaces)
|
||||||
assert(surface.surface_type == stInternal);
|
assert(surface.surface_type == stInternal);
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
this->slices.set(intersection_ex(to_polygons(std::move(this->slices.surfaces)), trimming_polygons, false), stInternal);
|
this->slices.set(intersection_ex(this->slices.surfaces, trimming_polygons), stInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerRegion::elephant_foot_compensation_step(const float elephant_foot_compensation_perimeter_step, const Polygons &trimming_polygons)
|
void LayerRegion::elephant_foot_compensation_step(const float elephant_foot_compensation_perimeter_step, const Polygons &trimming_polygons)
|
||||||
|
@ -432,10 +430,9 @@ void LayerRegion::elephant_foot_compensation_step(const float elephant_foot_comp
|
||||||
for (const Surface &surface : this->slices.surfaces)
|
for (const Surface &surface : this->slices.surfaces)
|
||||||
assert(surface.surface_type == stInternal);
|
assert(surface.surface_type == stInternal);
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
ExPolygons slices_expolygons = to_expolygons(std::move(this->slices.surfaces));
|
ExPolygons surfaces = to_expolygons(std::move(this->slices.surfaces));
|
||||||
Polygons slices_polygons = to_polygons(slices_expolygons);
|
Polygons tmp = intersection(surfaces, trimming_polygons);
|
||||||
Polygons tmp = intersection(slices_polygons, trimming_polygons, false);
|
append(tmp, diff(surfaces, offset(offset_ex(surfaces, -elephant_foot_compensation_perimeter_step), elephant_foot_compensation_perimeter_step)));
|
||||||
append(tmp, diff(slices_polygons, offset(offset_ex(slices_expolygons, -elephant_foot_compensation_perimeter_step), elephant_foot_compensation_perimeter_step)));
|
|
||||||
this->slices.set(union_ex(tmp), stInternal);
|
this->slices.set(union_ex(tmp), stInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class BoundingBox;
|
class BoundingBox;
|
||||||
|
@ -20,12 +22,28 @@ Linef3 transform(const Linef3& line, const Transform3d& t);
|
||||||
|
|
||||||
namespace line_alg {
|
namespace line_alg {
|
||||||
|
|
||||||
|
template<class L, class En = void> struct Traits {
|
||||||
|
static constexpr int Dim = L::Dim;
|
||||||
|
using Scalar = typename L::Scalar;
|
||||||
|
|
||||||
|
static Vec<Dim, Scalar>& get_a(L &l) { return l.a; }
|
||||||
|
static Vec<Dim, Scalar>& get_b(L &l) { return l.b; }
|
||||||
|
static const Vec<Dim, Scalar>& get_a(const L &l) { return l.a; }
|
||||||
|
static const Vec<Dim, Scalar>& get_b(const L &l) { return l.b; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class L> const constexpr int Dim = Traits<remove_cvref_t<L>>::Dim;
|
||||||
|
template<class L> using Scalar = typename Traits<remove_cvref_t<L>>::Scalar;
|
||||||
|
|
||||||
|
template<class L> auto get_a(L &&l) { return Traits<remove_cvref_t<L>>::get_a(l); }
|
||||||
|
template<class L> auto get_b(L &&l) { return Traits<remove_cvref_t<L>>::get_b(l); }
|
||||||
|
|
||||||
// Distance to the closest point of line.
|
// Distance to the closest point of line.
|
||||||
template<class L, class T, int N>
|
template<class L>
|
||||||
double distance_to_squared(const L &line, const Vec<N, T> &point)
|
double distance_to_squared(const L &line, const Vec<Dim<L>, Scalar<L>> &point)
|
||||||
{
|
{
|
||||||
const Vec<N, double> v = (line.b - line.a).template cast<double>();
|
const Vec<Dim<L>, double> v = (get_b(line) - get_a(line)).template cast<double>();
|
||||||
const Vec<N, double> va = (point - line.a).template cast<double>();
|
const Vec<Dim<L>, double> va = (point - get_a(line)).template cast<double>();
|
||||||
const double l2 = v.squaredNorm(); // avoid a sqrt
|
const double l2 = v.squaredNorm(); // avoid a sqrt
|
||||||
if (l2 == 0.0)
|
if (l2 == 0.0)
|
||||||
// a == b case
|
// a == b case
|
||||||
|
@ -35,12 +53,12 @@ double distance_to_squared(const L &line, const Vec<N, T> &point)
|
||||||
// It falls where t = [(this-a) . (b-a)] / |b-a|^2
|
// It falls where t = [(this-a) . (b-a)] / |b-a|^2
|
||||||
const double t = va.dot(v) / l2;
|
const double t = va.dot(v) / l2;
|
||||||
if (t < 0.0) return va.squaredNorm(); // beyond the 'a' end of the segment
|
if (t < 0.0) return va.squaredNorm(); // beyond the 'a' end of the segment
|
||||||
else if (t > 1.0) return (point - line.b).template cast<double>().squaredNorm(); // beyond the 'b' end of the segment
|
else if (t > 1.0) return (point - get_b(line)).template cast<double>().squaredNorm(); // beyond the 'b' end of the segment
|
||||||
return (t * v - va).squaredNorm();
|
return (t * v - va).squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class L, class T, int N>
|
template<class L>
|
||||||
double distance_to(const L &line, const Vec<N, T> &point)
|
double distance_to(const L &line, const Vec<Dim<L>, Scalar<L>> &point)
|
||||||
{
|
{
|
||||||
return std::sqrt(distance_to_squared(line, point));
|
return std::sqrt(distance_to_squared(line, point));
|
||||||
}
|
}
|
||||||
|
@ -84,6 +102,9 @@ public:
|
||||||
|
|
||||||
Point a;
|
Point a;
|
||||||
Point b;
|
Point b;
|
||||||
|
|
||||||
|
static const constexpr int Dim = 2;
|
||||||
|
using Scalar = Point::Scalar;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThickLine : public Line
|
class ThickLine : public Line
|
||||||
|
@ -107,6 +128,9 @@ public:
|
||||||
|
|
||||||
Vec3crd a;
|
Vec3crd a;
|
||||||
Vec3crd b;
|
Vec3crd b;
|
||||||
|
|
||||||
|
static const constexpr int Dim = 3;
|
||||||
|
using Scalar = Vec3crd::Scalar;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Linef
|
class Linef
|
||||||
|
@ -117,6 +141,9 @@ public:
|
||||||
|
|
||||||
Vec2d a;
|
Vec2d a;
|
||||||
Vec2d b;
|
Vec2d b;
|
||||||
|
|
||||||
|
static const constexpr int Dim = 2;
|
||||||
|
using Scalar = Vec2d::Scalar;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Linef3
|
class Linef3
|
||||||
|
@ -133,6 +160,9 @@ public:
|
||||||
|
|
||||||
Vec3d a;
|
Vec3d a;
|
||||||
Vec3d b;
|
Vec3d b;
|
||||||
|
|
||||||
|
static const constexpr int Dim = 3;
|
||||||
|
using Scalar = Vec3d::Scalar;
|
||||||
};
|
};
|
||||||
|
|
||||||
BoundingBox get_extents(const Lines &lines);
|
BoundingBox get_extents(const Lines &lines);
|
||||||
|
|
|
@ -106,13 +106,8 @@ template<class C> bool all_of(const C &container)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> struct remove_cvref
|
//template<class T>
|
||||||
{
|
//using remove_cvref_t = std::remove_reference_t<std::remove_cv_t<T>>;
|
||||||
using type =
|
|
||||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T> using remove_cvref_t = typename remove_cvref<T>::type;
|
|
||||||
|
|
||||||
/// Exactly like Matlab https://www.mathworks.com/help/matlab/ref/linspace.html
|
/// Exactly like Matlab https://www.mathworks.com/help/matlab/ref/linspace.html
|
||||||
template<class T, class I, class = IntegerOnly<I>>
|
template<class T, class I, class = IntegerOnly<I>>
|
||||||
|
|
|
@ -14,55 +14,9 @@
|
||||||
#include <boost/multiprecision/integer.hpp>
|
#include <boost/multiprecision/integer.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <libnest2d/geometry_traits.hpp>
|
#include <libnest2d/backends/libslic3r/geometries.hpp>
|
||||||
#include <libnest2d/utils/rotcalipers.hpp>
|
#include <libnest2d/utils/rotcalipers.hpp>
|
||||||
|
|
||||||
namespace libnest2d {
|
|
||||||
|
|
||||||
template<> struct PointType<Slic3r::Points> { using Type = Slic3r::Point; };
|
|
||||||
template<> struct CoordType<Slic3r::Point> { using Type = coord_t; };
|
|
||||||
template<> struct ShapeTag<Slic3r::ExPolygon> { using Type = PolygonTag; };
|
|
||||||
template<> struct ShapeTag<Slic3r::Polygon> { using Type = PolygonTag; };
|
|
||||||
template<> struct ShapeTag<Slic3r::Points> { using Type = PathTag; };
|
|
||||||
template<> struct ShapeTag<Slic3r::Point> { using Type = PointTag; };
|
|
||||||
template<> struct ContourType<Slic3r::ExPolygon> { using Type = Slic3r::Points; };
|
|
||||||
template<> struct ContourType<Slic3r::Polygon> { using Type = Slic3r::Points; };
|
|
||||||
|
|
||||||
namespace pointlike {
|
|
||||||
|
|
||||||
template<> inline coord_t x(const Slic3r::Point& p) { return p.x(); }
|
|
||||||
template<> inline coord_t y(const Slic3r::Point& p) { return p.y(); }
|
|
||||||
template<> inline coord_t& x(Slic3r::Point& p) { return p.x(); }
|
|
||||||
template<> inline coord_t& y(Slic3r::Point& p) { return p.y(); }
|
|
||||||
|
|
||||||
} // pointlike
|
|
||||||
|
|
||||||
namespace shapelike {
|
|
||||||
template<> inline Slic3r::Points& contour(Slic3r::ExPolygon& sh) { return sh.contour.points; }
|
|
||||||
template<> inline const Slic3r::Points& contour(const Slic3r::ExPolygon& sh) { return sh.contour.points; }
|
|
||||||
template<> inline Slic3r::Points& contour(Slic3r::Polygon& sh) { return sh.points; }
|
|
||||||
template<> inline const Slic3r::Points& contour(const Slic3r::Polygon& sh) { return sh.points; }
|
|
||||||
|
|
||||||
template<> Slic3r::Points::iterator begin(Slic3r::Points& pts, const PathTag&) { return pts.begin();}
|
|
||||||
template<> Slic3r::Points::const_iterator cbegin(const Slic3r::Points& pts, const PathTag&) { return pts.cbegin(); }
|
|
||||||
template<> Slic3r::Points::iterator end(Slic3r::Points& pts, const PathTag&) { return pts.end();}
|
|
||||||
template<> Slic3r::Points::const_iterator cend(const Slic3r::Points& pts, const PathTag&) { return pts.cend(); }
|
|
||||||
|
|
||||||
template<> inline Slic3r::ExPolygon create<Slic3r::ExPolygon>(Slic3r::Points&& contour)
|
|
||||||
{
|
|
||||||
Slic3r::ExPolygon expoly; expoly.contour.points.swap(contour);
|
|
||||||
return expoly;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline Slic3r::Polygon create<Slic3r::Polygon>(Slic3r::Points&& contour)
|
|
||||||
{
|
|
||||||
Slic3r::Polygon poly; poly.points.swap(contour);
|
|
||||||
return poly;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // shapelike
|
|
||||||
} // libnest2d
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
// Used as compute type.
|
// Used as compute type.
|
||||||
|
@ -74,13 +28,22 @@ using Rational = boost::rational<boost::multiprecision::int128_t>;
|
||||||
using Rational = boost::rational<__int128>;
|
using Rational = boost::rational<__int128>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<class P>
|
||||||
|
libnest2d::RotatedBox<Point, Unit> minAreaBoundigBox_(
|
||||||
|
const P &p, MinAreaBoundigBox::PolygonLevel lvl)
|
||||||
|
{
|
||||||
|
P chull = lvl == MinAreaBoundigBox::pcConvex ?
|
||||||
|
p :
|
||||||
|
libnest2d::sl::convexHull(p);
|
||||||
|
|
||||||
|
libnest2d::removeCollinearPoints(chull);
|
||||||
|
|
||||||
|
return libnest2d::minAreaBoundingBox<P, Unit, Rational>(chull);
|
||||||
|
}
|
||||||
|
|
||||||
MinAreaBoundigBox::MinAreaBoundigBox(const Polygon &p, PolygonLevel pc)
|
MinAreaBoundigBox::MinAreaBoundigBox(const Polygon &p, PolygonLevel pc)
|
||||||
{
|
{
|
||||||
const Polygon &chull = pc == pcConvex ? p :
|
libnest2d::RotatedBox<Point, Unit> box = minAreaBoundigBox_(p, pc);
|
||||||
libnest2d::sl::convexHull(p);
|
|
||||||
|
|
||||||
libnest2d::RotatedBox<Point, Unit> box =
|
|
||||||
libnest2d::minAreaBoundingBox<Polygon, Unit, Rational>(chull);
|
|
||||||
|
|
||||||
m_right = libnest2d::cast<long double>(box.right_extent());
|
m_right = libnest2d::cast<long double>(box.right_extent());
|
||||||
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
|
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
|
||||||
|
@ -89,11 +52,7 @@ MinAreaBoundigBox::MinAreaBoundigBox(const Polygon &p, PolygonLevel pc)
|
||||||
|
|
||||||
MinAreaBoundigBox::MinAreaBoundigBox(const ExPolygon &p, PolygonLevel pc)
|
MinAreaBoundigBox::MinAreaBoundigBox(const ExPolygon &p, PolygonLevel pc)
|
||||||
{
|
{
|
||||||
const ExPolygon &chull = pc == pcConvex ? p :
|
libnest2d::RotatedBox<Point, Unit> box = minAreaBoundigBox_(p, pc);
|
||||||
libnest2d::sl::convexHull(p);
|
|
||||||
|
|
||||||
libnest2d::RotatedBox<Point, Unit> box =
|
|
||||||
libnest2d::minAreaBoundingBox<ExPolygon, Unit, Rational>(chull);
|
|
||||||
|
|
||||||
m_right = libnest2d::cast<long double>(box.right_extent());
|
m_right = libnest2d::cast<long double>(box.right_extent());
|
||||||
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
|
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
|
||||||
|
@ -102,11 +61,7 @@ MinAreaBoundigBox::MinAreaBoundigBox(const ExPolygon &p, PolygonLevel pc)
|
||||||
|
|
||||||
MinAreaBoundigBox::MinAreaBoundigBox(const Points &pts, PolygonLevel pc)
|
MinAreaBoundigBox::MinAreaBoundigBox(const Points &pts, PolygonLevel pc)
|
||||||
{
|
{
|
||||||
const Points &chull = pc == pcConvex ? pts :
|
libnest2d::RotatedBox<Point, Unit> box = minAreaBoundigBox_(pts, pc);
|
||||||
libnest2d::sl::convexHull(pts);
|
|
||||||
|
|
||||||
libnest2d::RotatedBox<Point, Unit> box =
|
|
||||||
libnest2d::minAreaBoundingBox<Points, Unit, Rational>(chull);
|
|
||||||
|
|
||||||
m_right = libnest2d::cast<long double>(box.right_extent());
|
m_right = libnest2d::cast<long double>(box.right_extent());
|
||||||
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
|
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
|
||||||
|
|
|
@ -26,12 +26,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructors with various types of geometry data used in Slic3r.
|
// Constructors with various types of geometry data used in Slic3r.
|
||||||
// If the convexity is known apriory, pcConvex can be used to skip
|
// If the convexity is known apriory, pcConvex can be used to skip
|
||||||
// convex hull calculation. It is very important that the input polygons
|
// convex hull calculation.
|
||||||
// do NOT have any collinear points (except for the first and the last
|
|
||||||
// vertex being the same -- meaning a closed polygon for boost)
|
|
||||||
// To make sure this constraint is satisfied, you can call
|
|
||||||
// remove_collinear_points on the input polygon before handing over here)
|
|
||||||
explicit MinAreaBoundigBox(const Polygon&, PolygonLevel = pcSimple);
|
explicit MinAreaBoundigBox(const Polygon&, PolygonLevel = pcSimple);
|
||||||
explicit MinAreaBoundigBox(const ExPolygon&, PolygonLevel = pcSimple);
|
explicit MinAreaBoundigBox(const ExPolygon&, PolygonLevel = pcSimple);
|
||||||
explicit MinAreaBoundigBox(const Points&, PolygonLevel = pcSimple);
|
explicit MinAreaBoundigBox(const Points&, PolygonLevel = pcSimple);
|
||||||
|
|
|
@ -833,18 +833,6 @@ indexed_triangle_set ModelObject::raw_indexed_triangle_set() const
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
|
|
||||||
TriangleMesh ModelObject::full_raw_mesh() const
|
|
||||||
{
|
|
||||||
TriangleMesh mesh;
|
|
||||||
for (const ModelVolume *v : this->volumes)
|
|
||||||
{
|
|
||||||
TriangleMesh vol_mesh(v->mesh());
|
|
||||||
vol_mesh.transform(v->get_matrix());
|
|
||||||
mesh.merge(vol_mesh);
|
|
||||||
}
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
const BoundingBoxf3& ModelObject::raw_mesh_bounding_box() const
|
const BoundingBoxf3& ModelObject::raw_mesh_bounding_box() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -289,8 +289,6 @@ public:
|
||||||
TriangleMesh raw_mesh() const;
|
TriangleMesh raw_mesh() const;
|
||||||
// The same as above, but producing a lightweight indexed_triangle_set.
|
// The same as above, but producing a lightweight indexed_triangle_set.
|
||||||
indexed_triangle_set raw_indexed_triangle_set() const;
|
indexed_triangle_set raw_indexed_triangle_set() const;
|
||||||
// Non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
|
|
||||||
TriangleMesh full_raw_mesh() const;
|
|
||||||
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
|
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
|
||||||
// This bounding box is only used for the actual slicing.
|
// This bounding box is only used for the actual slicing.
|
||||||
const BoundingBoxf3& raw_bounding_box() const;
|
const BoundingBoxf3& raw_bounding_box() const;
|
||||||
|
|
|
@ -64,6 +64,7 @@ public:
|
||||||
bool has_duplicate_points() const;
|
bool has_duplicate_points() const;
|
||||||
// Remove exact duplicates, return true if any duplicate has been removed.
|
// Remove exact duplicates, return true if any duplicate has been removed.
|
||||||
bool remove_duplicate_points();
|
bool remove_duplicate_points();
|
||||||
|
void clear() { this->points.clear(); }
|
||||||
void append(const Point &point) { this->points.push_back(point); }
|
void append(const Point &point) { this->points.push_back(point); }
|
||||||
void append(const Points &src) { this->append(src.begin(), src.end()); }
|
void append(const Points &src) { this->append(src.begin(), src.end()); }
|
||||||
void append(const Points::const_iterator &begin, const Points::const_iterator &end) { this->points.insert(this->points.end(), begin, end); }
|
void append(const Points::const_iterator &begin, const Points::const_iterator &end) { this->points.insert(this->points.end(), begin, end); }
|
||||||
|
@ -83,6 +84,13 @@ public:
|
||||||
|
|
||||||
static Points _douglas_peucker(const Points &points, const double tolerance);
|
static Points _douglas_peucker(const Points &points, const double tolerance);
|
||||||
static Points visivalingam(const Points& pts, const double& tolerance);
|
static Points visivalingam(const Points& pts, const double& tolerance);
|
||||||
|
|
||||||
|
inline auto begin() { return points.begin(); }
|
||||||
|
inline auto begin() const { return points.begin(); }
|
||||||
|
inline auto end() { return points.end(); }
|
||||||
|
inline auto end() const { return points.end(); }
|
||||||
|
inline auto cbegin() const { return points.begin(); }
|
||||||
|
inline auto cend() const { return points.end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MultiPoint3
|
class MultiPoint3
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace Slic3r { namespace opt {
|
namespace Slic3r { namespace opt {
|
||||||
|
|
||||||
|
|
|
@ -349,9 +349,7 @@ void PerimeterGenerator::process()
|
||||||
coord_t min_width = coord_t(scale_(this->ext_perimeter_flow.nozzle_diameter() / 3));
|
coord_t min_width = coord_t(scale_(this->ext_perimeter_flow.nozzle_diameter() / 3));
|
||||||
ExPolygons expp = offset2_ex(
|
ExPolygons expp = offset2_ex(
|
||||||
// medial axis requires non-overlapping geometry
|
// medial axis requires non-overlapping geometry
|
||||||
diff_ex(to_polygons(last),
|
diff_ex(last, offset(offsets, float(ext_perimeter_width / 2.)), true),
|
||||||
offset(offsets, float(ext_perimeter_width / 2.)),
|
|
||||||
true),
|
|
||||||
- float(min_width / 2.), float(min_width / 2.));
|
- float(min_width / 2.), float(min_width / 2.));
|
||||||
// the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
|
// the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
|
||||||
for (ExPolygon &ex : expp)
|
for (ExPolygon &ex : expp)
|
||||||
|
@ -514,7 +512,7 @@ void PerimeterGenerator::process()
|
||||||
and use zigzag). */
|
and use zigzag). */
|
||||||
//FIXME Vojtech: This grows by a rounded extrusion width, not by line spacing,
|
//FIXME Vojtech: This grows by a rounded extrusion width, not by line spacing,
|
||||||
// therefore it may cover the area, but no the volume.
|
// therefore it may cover the area, but no the volume.
|
||||||
last = diff_ex(to_polygons(last), gap_fill.polygons_covered_by_width(10.f));
|
last = diff_ex(last, gap_fill.polygons_covered_by_width(10.f));
|
||||||
this->gap_fill->append(std::move(gap_fill.entities));
|
this->gap_fill->append(std::move(gap_fill.entities));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,42 +17,42 @@ class BoundingBox;
|
||||||
class Line;
|
class Line;
|
||||||
class MultiPoint;
|
class MultiPoint;
|
||||||
class Point;
|
class Point;
|
||||||
typedef Point Vector;
|
using Vector = Point;
|
||||||
|
|
||||||
// Eigen types, to replace the Slic3r's own types in the future.
|
// Eigen types, to replace the Slic3r's own types in the future.
|
||||||
// Vector types with a fixed point coordinate base type.
|
// Vector types with a fixed point coordinate base type.
|
||||||
typedef Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign> Vec2crd;
|
using Vec2crd = Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
|
using Vec3crd = Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<int, 2, 1, Eigen::DontAlign> Vec2i;
|
using Vec2i = Eigen::Matrix<int, 2, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> Vec3i;
|
using Vec3i = Eigen::Matrix<int, 3, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<int32_t, 2, 1, Eigen::DontAlign> Vec2i32;
|
using Vec2i32 = Eigen::Matrix<int32_t, 2, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign> Vec2i64;
|
using Vec2i64 = Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign> Vec3i32;
|
using Vec3i32 = Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign> Vec3i64;
|
using Vec3i64 = Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign>;
|
||||||
|
|
||||||
// Vector types with a double coordinate base type.
|
// Vector types with a double coordinate base type.
|
||||||
typedef Eigen::Matrix<float, 2, 1, Eigen::DontAlign> Vec2f;
|
using Vec2f = Eigen::Matrix<float, 2, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> Vec3f;
|
using Vec3f = Eigen::Matrix<float, 3, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<double, 2, 1, Eigen::DontAlign> Vec2d;
|
using Vec2d = Eigen::Matrix<double, 2, 1, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<double, 3, 1, Eigen::DontAlign> Vec3d;
|
using Vec3d = Eigen::Matrix<double, 3, 1, Eigen::DontAlign>;
|
||||||
|
|
||||||
typedef std::vector<Point> Points;
|
using Points = std::vector<Point>;
|
||||||
typedef std::vector<Point*> PointPtrs;
|
using PointPtrs = std::vector<Point*>;
|
||||||
typedef std::vector<const Point*> PointConstPtrs;
|
using PointConstPtrs = std::vector<const Point*>;
|
||||||
typedef std::vector<Vec3crd> Points3;
|
using Points3 = std::vector<Vec3crd>;
|
||||||
typedef std::vector<Vec2d> Pointfs;
|
using Pointfs = std::vector<Vec2d>;
|
||||||
typedef std::vector<Vec2d> Vec2ds;
|
using Vec2ds = std::vector<Vec2d>;
|
||||||
typedef std::vector<Vec3d> Pointf3s;
|
using Pointf3s = std::vector<Vec3d>;
|
||||||
|
|
||||||
typedef Eigen::Matrix<float, 2, 2, Eigen::DontAlign> Matrix2f;
|
using Matrix2f = Eigen::Matrix<float, 2, 2, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<double, 2, 2, Eigen::DontAlign> Matrix2d;
|
using Matrix2d = Eigen::Matrix<double, 2, 2, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<float, 3, 3, Eigen::DontAlign> Matrix3f;
|
using Matrix3f = Eigen::Matrix<float, 3, 3, Eigen::DontAlign>;
|
||||||
typedef Eigen::Matrix<double, 3, 3, Eigen::DontAlign> Matrix3d;
|
using Matrix3d = Eigen::Matrix<double, 3, 3, Eigen::DontAlign>;
|
||||||
|
|
||||||
typedef Eigen::Transform<float, 2, Eigen::Affine, Eigen::DontAlign> Transform2f;
|
using Transform2f = Eigen::Transform<float, 2, Eigen::Affine, Eigen::DontAlign>;
|
||||||
typedef Eigen::Transform<double, 2, Eigen::Affine, Eigen::DontAlign> Transform2d;
|
using Transform2d = Eigen::Transform<double, 2, Eigen::Affine, Eigen::DontAlign>;
|
||||||
typedef Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign> Transform3f;
|
using Transform3f = Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign>;
|
||||||
typedef Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign> Transform3d;
|
using Transform3d = Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign>;
|
||||||
|
|
||||||
inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
|
inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ template<int N, class T> using Vec = Eigen::Matrix<T, N, 1, Eigen::DontAlign, N
|
||||||
class Point : public Vec2crd
|
class Point : public Vec2crd
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef coord_t coord_type;
|
using coord_type = coord_t;
|
||||||
|
|
||||||
Point() : Vec2crd(0, 0) {}
|
Point() : Vec2crd(0, 0) {}
|
||||||
Point(int32_t x, int32_t y) : Vec2crd(coord_t(x), coord_t(y)) {}
|
Point(int32_t x, int32_t y) : Vec2crd(coord_t(x), coord_t(y)) {}
|
||||||
|
@ -337,7 +337,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef typename std::unordered_multimap<Vec2crd, ValueType, PointHash> map_type;
|
using map_type = typename std::unordered_multimap<Vec2crd, ValueType, PointHash>;
|
||||||
PointAccessor m_point_accessor;
|
PointAccessor m_point_accessor;
|
||||||
map_type m_map;
|
map_type m_map;
|
||||||
coord_t m_search_radius;
|
coord_t m_search_radius;
|
||||||
|
@ -413,6 +413,25 @@ unscaled(const Eigen::Matrix<Tin, N, EigenArgs...> &v) noexcept
|
||||||
return v.template cast<Tout>() * SCALING_FACTOR;
|
return v.template cast<Tout>() * SCALING_FACTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Align a coordinate to a grid. The coordinate may be negative,
|
||||||
|
// the aligned value will never be bigger than the original one.
|
||||||
|
inline coord_t align_to_grid(const coord_t coord, const coord_t spacing) {
|
||||||
|
// Current C++ standard defines the result of integer division to be rounded to zero,
|
||||||
|
// for both positive and negative numbers. Here we want to round down for negative
|
||||||
|
// numbers as well.
|
||||||
|
coord_t aligned = (coord < 0) ?
|
||||||
|
((coord - spacing + 1) / spacing) * spacing :
|
||||||
|
(coord / spacing) * spacing;
|
||||||
|
assert(aligned <= coord);
|
||||||
|
return aligned;
|
||||||
|
}
|
||||||
|
inline Point align_to_grid(Point coord, Point spacing)
|
||||||
|
{ return Point(align_to_grid(coord.x(), spacing.x()), align_to_grid(coord.y(), spacing.y())); }
|
||||||
|
inline coord_t align_to_grid(coord_t coord, coord_t spacing, coord_t base)
|
||||||
|
{ return base + align_to_grid(coord - base, spacing); }
|
||||||
|
inline Point align_to_grid(Point coord, Point spacing, Point base)
|
||||||
|
{ return Point(align_to_grid(coord.x(), spacing.x(), base.x()), align_to_grid(coord.y(), spacing.y(), base.y())); }
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
// start Boost
|
// start Boost
|
||||||
|
@ -420,11 +439,11 @@ unscaled(const Eigen::Matrix<Tin, N, EigenArgs...> &v) noexcept
|
||||||
#include <boost/polygon/polygon.hpp>
|
#include <boost/polygon/polygon.hpp>
|
||||||
namespace boost { namespace polygon {
|
namespace boost { namespace polygon {
|
||||||
template <>
|
template <>
|
||||||
struct geometry_concept<Slic3r::Point> { typedef point_concept type; };
|
struct geometry_concept<Slic3r::Point> { using type = point_concept; };
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct point_traits<Slic3r::Point> {
|
struct point_traits<Slic3r::Point> {
|
||||||
typedef coord_t coordinate_type;
|
using coordinate_type = coord_t;
|
||||||
|
|
||||||
static inline coordinate_type get(const Slic3r::Point& point, orientation_2d orient) {
|
static inline coordinate_type get(const Slic3r::Point& point, orientation_2d orient) {
|
||||||
return static_cast<coordinate_type>(point((orient == HORIZONTAL) ? 0 : 1));
|
return static_cast<coordinate_type>(point((orient == HORIZONTAL) ? 0 : 1));
|
||||||
|
@ -433,7 +452,7 @@ namespace boost { namespace polygon {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct point_mutable_traits<Slic3r::Point> {
|
struct point_mutable_traits<Slic3r::Point> {
|
||||||
typedef coord_t coordinate_type;
|
using coordinate_type = coord_t;
|
||||||
static inline void set(Slic3r::Point& point, orientation_2d orient, coord_t value) {
|
static inline void set(Slic3r::Point& point, orientation_2d orient, coord_t value) {
|
||||||
point((orient == HORIZONTAL) ? 0 : 1) = value;
|
point((orient == HORIZONTAL) ? 0 : 1) = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ double Polygon::area() const
|
||||||
|
|
||||||
bool Polygon::is_counter_clockwise() const
|
bool Polygon::is_counter_clockwise() const
|
||||||
{
|
{
|
||||||
return ClipperLib::Orientation(Slic3rMultiPoint_to_ClipperPath(*this));
|
return ClipperLib::Orientation(this->points);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Polygon::is_clockwise() const
|
bool Polygon::is_clockwise() const
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class Polygon;
|
class Polygon;
|
||||||
typedef std::vector<Polygon> Polygons;
|
using Polygons = std::vector<Polygon>;
|
||||||
|
using PolygonPtrs = std::vector<Polygon*>;
|
||||||
|
using ConstPolygonPtrs = std::vector<const Polygon*>;
|
||||||
|
|
||||||
class Polygon : public MultiPoint
|
class Polygon : public MultiPoint
|
||||||
{
|
{
|
||||||
|
@ -70,6 +72,9 @@ public:
|
||||||
// Projection of a point onto the polygon.
|
// Projection of a point onto the polygon.
|
||||||
Point point_projection(const Point &point) const;
|
Point point_projection(const Point &point) const;
|
||||||
std::vector<float> parameter_by_length() const;
|
std::vector<float> parameter_by_length() const;
|
||||||
|
|
||||||
|
using iterator = Points::iterator;
|
||||||
|
using const_iterator = Points::const_iterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const Polygon &lhs, const Polygon &rhs) { return lhs.points == rhs.points; }
|
inline bool operator==(const Polygon &lhs, const Polygon &rhs) { return lhs.points == rhs.points; }
|
||||||
|
@ -88,6 +93,8 @@ inline double total_length(const Polygons &polylines) {
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline double area(const Polygon &poly) { return poly.area(); }
|
||||||
|
|
||||||
inline double area(const Polygons &polys)
|
inline double area(const Polygons &polys)
|
||||||
{
|
{
|
||||||
double s = 0.;
|
double s = 0.;
|
||||||
|
@ -215,6 +222,24 @@ inline Polylines to_polylines(Polygons &&polys)
|
||||||
return polylines;
|
return polylines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Polygons to_polygons(const std::vector<Points> &paths)
|
||||||
|
{
|
||||||
|
Polygons out;
|
||||||
|
out.reserve(paths.size());
|
||||||
|
for (const Points &path : paths)
|
||||||
|
out.emplace_back(path);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Polygons to_polygons(std::vector<Points> &&paths)
|
||||||
|
{
|
||||||
|
Polygons out;
|
||||||
|
out.reserve(paths.size());
|
||||||
|
for (const Points &path : paths)
|
||||||
|
out.emplace_back(std::move(path));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
} // Slic3r
|
} // Slic3r
|
||||||
|
|
||||||
// start Boost
|
// start Boost
|
||||||
|
|
|
@ -124,6 +124,24 @@ inline Lines to_lines(const Polylines &polys)
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Polylines to_polylines(const std::vector<Points> &paths)
|
||||||
|
{
|
||||||
|
Polylines out;
|
||||||
|
out.reserve(paths.size());
|
||||||
|
for (const Points &path : paths)
|
||||||
|
out.emplace_back(path);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Polylines to_polylines(std::vector<Points> &&paths)
|
||||||
|
{
|
||||||
|
Polylines out;
|
||||||
|
out.reserve(paths.size());
|
||||||
|
for (const Points &path : paths)
|
||||||
|
out.emplace_back(std::move(path));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
inline void polylines_append(Polylines &dst, const Polylines &src)
|
inline void polylines_append(Polylines &dst, const Polylines &src)
|
||||||
{
|
{
|
||||||
dst.insert(dst.end(), src.begin(), src.end());
|
dst.insert(dst.end(), src.begin(), src.end());
|
||||||
|
|
|
@ -296,6 +296,13 @@ void Preset::normalize(DynamicPrintConfig &config)
|
||||||
if (auto *gap_fill_enabled = config.option<ConfigOptionBool>("gap_fill_enabled", false); gap_fill_enabled)
|
if (auto *gap_fill_enabled = config.option<ConfigOptionBool>("gap_fill_enabled", false); gap_fill_enabled)
|
||||||
gap_fill_enabled->value = false;
|
gap_fill_enabled->value = false;
|
||||||
}
|
}
|
||||||
|
if (auto *first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height", false); first_layer_height && first_layer_height->percent)
|
||||||
|
if (const auto *layer_height = config.option<ConfigOptionFloat>("layer_height", false); layer_height) {
|
||||||
|
// Legacy conversion - first_layer_height moved from PrintObject setting to a Print setting, thus we are getting rid of the dependency
|
||||||
|
// of first_layer_height on PrintObject specific layer_height. Covert the first layer heigth to an absolute value.
|
||||||
|
first_layer_height->value = first_layer_height->get_abs_value(layer_height->value);
|
||||||
|
first_layer_height->percent = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config)
|
std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config)
|
||||||
|
@ -427,7 +434,7 @@ const std::vector<std::string>& Preset::print_options()
|
||||||
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
||||||
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_style",
|
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_closing_radius", "support_material_style",
|
||||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
|
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
|
||||||
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
|
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
|
||||||
"support_material_contact_distance", "support_material_bottom_contact_distance",
|
"support_material_contact_distance", "support_material_bottom_contact_distance",
|
||||||
|
@ -468,7 +475,7 @@ const std::vector<std::string>& Preset::machine_limits_options()
|
||||||
static std::vector<std::string> s_opts;
|
static std::vector<std::string> s_opts;
|
||||||
if (s_opts.empty()) {
|
if (s_opts.empty()) {
|
||||||
s_opts = {
|
s_opts = {
|
||||||
"machine_max_acceleration_extruding", "machine_max_acceleration_retracting",
|
"machine_max_acceleration_extruding", "machine_max_acceleration_retracting", "machine_max_acceleration_travel",
|
||||||
"machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
|
"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_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
|
||||||
"machine_min_extruding_rate", "machine_min_travel_rate",
|
"machine_min_extruding_rate", "machine_min_travel_rate",
|
||||||
|
|
|
@ -100,7 +100,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||||
"filament_spool_weight",
|
"filament_spool_weight",
|
||||||
"first_layer_acceleration",
|
"first_layer_acceleration",
|
||||||
"first_layer_bed_temperature",
|
"first_layer_bed_temperature",
|
||||||
"first_layer_speed",
|
|
||||||
"gcode_comments",
|
"gcode_comments",
|
||||||
"gcode_label_objects",
|
"gcode_label_objects",
|
||||||
"infill_acceleration",
|
"infill_acceleration",
|
||||||
|
@ -139,7 +138,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||||
"start_filament_gcode",
|
"start_filament_gcode",
|
||||||
"toolchange_gcode",
|
"toolchange_gcode",
|
||||||
"threads",
|
"threads",
|
||||||
"travel_speed",
|
|
||||||
"use_firmware_retraction",
|
"use_firmware_retraction",
|
||||||
"use_relative_e_distances",
|
"use_relative_e_distances",
|
||||||
"use_volumetric_e",
|
"use_volumetric_e",
|
||||||
|
@ -182,7 +180,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||||
} else if (
|
} else if (
|
||||||
opt_key == "complete_objects"
|
opt_key == "complete_objects"
|
||||||
|| opt_key == "filament_type"
|
|| opt_key == "filament_type"
|
||||||
|| opt_key == "filament_soluble"
|
|
||||||
|| opt_key == "first_layer_temperature"
|
|| opt_key == "first_layer_temperature"
|
||||||
|| opt_key == "filament_loading_speed"
|
|| opt_key == "filament_loading_speed"
|
||||||
|| opt_key == "filament_loading_speed_start"
|
|| opt_key == "filament_loading_speed_start"
|
||||||
|
@ -210,9 +207,17 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||||
|| opt_key == "cooling_tube_retraction"
|
|| opt_key == "cooling_tube_retraction"
|
||||||
|| opt_key == "cooling_tube_length"
|
|| opt_key == "cooling_tube_length"
|
||||||
|| opt_key == "extra_loading_move"
|
|| opt_key == "extra_loading_move"
|
||||||
|
|| opt_key == "travel_speed"
|
||||||
|
|| opt_key == "first_layer_speed"
|
||||||
|| opt_key == "z_offset") {
|
|| opt_key == "z_offset") {
|
||||||
steps.emplace_back(psWipeTower);
|
steps.emplace_back(psWipeTower);
|
||||||
steps.emplace_back(psSkirt);
|
steps.emplace_back(psSkirt);
|
||||||
|
} else if (opt_key == "filament_soluble") {
|
||||||
|
steps.emplace_back(psWipeTower);
|
||||||
|
// Soluble support interface / non-soluble base interface produces non-soluble interface layers below soluble interface layers.
|
||||||
|
// Thus switching between soluble / non-soluble interface layer material may require recalculation of supports.
|
||||||
|
//FIXME Killing supports on any change of "filament_soluble" is rough. We should check for each object whether that is necessary.
|
||||||
|
osteps.emplace_back(posSupportMaterial);
|
||||||
} else if (
|
} else if (
|
||||||
opt_key == "first_layer_extrusion_width"
|
opt_key == "first_layer_extrusion_width"
|
||||||
|| opt_key == "min_layer_height"
|
|| opt_key == "min_layer_height"
|
||||||
|
@ -1293,7 +1298,7 @@ std::string Print::validate(std::string* warning) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_config.gcode_flavor != gcfRepRapSprinter && m_config.gcode_flavor != gcfRepRapFirmware &&
|
if (m_config.gcode_flavor != gcfRepRapSprinter && m_config.gcode_flavor != gcfRepRapFirmware &&
|
||||||
m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlin)
|
m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlinLegacy && m_config.gcode_flavor != gcfMarlinFirmware)
|
||||||
return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors.");
|
return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors.");
|
||||||
if (! m_config.use_relative_e_distances)
|
if (! m_config.use_relative_e_distances)
|
||||||
return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).");
|
return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).");
|
||||||
|
@ -1459,7 +1464,8 @@ std::string Print::validate(std::string* warning) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate first_layer_height
|
// validate first_layer_height
|
||||||
double first_layer_height = object->config().get_abs_value("first_layer_height");
|
assert(! m_config.first_layer_height.percent);
|
||||||
|
double first_layer_height = m_config.first_layer_height.value;
|
||||||
double first_layer_min_nozzle_diameter;
|
double first_layer_min_nozzle_diameter;
|
||||||
if (object->has_raft()) {
|
if (object->has_raft()) {
|
||||||
// if we have raft layers, only support material extruder is used on first layer
|
// if we have raft layers, only support material extruder is used on first layer
|
||||||
|
@ -1556,9 +1562,8 @@ BoundingBox Print::total_bounding_box() const
|
||||||
|
|
||||||
double Print::skirt_first_layer_height() const
|
double Print::skirt_first_layer_height() const
|
||||||
{
|
{
|
||||||
if (m_objects.empty())
|
assert(! m_config.first_layer_height.percent);
|
||||||
throw Slic3r::InvalidArgument("skirt_first_layer_height() can't be called without PrintObjects");
|
return m_config.first_layer_height.value;
|
||||||
return m_objects.front()->config().get_abs_value("first_layer_height");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Flow Print::brim_flow() const
|
Flow Print::brim_flow() const
|
||||||
|
@ -1987,9 +1992,7 @@ void Print::_make_wipe_tower()
|
||||||
|
|
||||||
// Set the extruder & material properties at the wipe tower object.
|
// Set the extruder & material properties at the wipe tower object.
|
||||||
for (size_t i = 0; i < number_of_extruders; ++ i)
|
for (size_t i = 0; i < number_of_extruders; ++ i)
|
||||||
|
wipe_tower.set_extruder(i, m_config);
|
||||||
wipe_tower.set_extruder(
|
|
||||||
i, m_config);
|
|
||||||
|
|
||||||
m_wipe_tower_data.priming = Slic3r::make_unique<std::vector<WipeTower::ToolChangeResult>>(
|
m_wipe_tower_data.priming = Slic3r::make_unique<std::vector<WipeTower::ToolChangeResult>>(
|
||||||
wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
|
wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
|
||||||
|
@ -2015,8 +2018,8 @@ void Print::_make_wipe_tower()
|
||||||
volume_to_wipe += (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
volume_to_wipe += (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||||
|
|
||||||
// request a toolchange at the wipe tower with at least volume_to_wipe purging amount
|
// request a toolchange at the wipe tower with at least volume_to_wipe purging amount
|
||||||
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, extruder_id,
|
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height,
|
||||||
first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back(), volume_to_wipe);
|
current_extruder_id, extruder_id, volume_to_wipe);
|
||||||
current_extruder_id = extruder_id;
|
current_extruder_id = extruder_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|