From 835c08beeb66a4f49678c8cffdb293dddbe950ac Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 5 Oct 2022 10:12:28 +0200 Subject: [PATCH 1/6] Remove accidental leftover commented source file --- src/libslic3r/CMakeLists.txt | 1 - src/libslic3r/TriangulateWall.cpp | 159 ------------------------------ 2 files changed, 160 deletions(-) delete mode 100644 src/libslic3r/TriangulateWall.cpp diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index f77bbaee83..a118f6ef39 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -268,7 +268,6 @@ set(SLIC3R_SOURCES TriangleMeshSlicer.hpp MeshSplitImpl.hpp TriangulateWall.hpp - TriangulateWall.cpp utils.cpp Utils.hpp Time.cpp diff --git a/src/libslic3r/TriangulateWall.cpp b/src/libslic3r/TriangulateWall.cpp deleted file mode 100644 index eb710d9a57..0000000000 --- a/src/libslic3r/TriangulateWall.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "TriangulateWall.hpp" -#include "MTUtils.hpp" - -namespace Slic3r { - -//class Ring { -// size_t idx = 0, nextidx = 1, startidx = 0, begin = 0, end = 0; - -//public: -// explicit Ring(size_t from, size_t to) : begin(from), end(to) { init(begin); } - -// size_t size() const { return end - begin; } -// std::pair pos() const { return {idx, nextidx}; } -// bool is_lower() const { return idx < size(); } - -// void inc() -// { -// if (nextidx != startidx) nextidx++; -// if (nextidx == end) nextidx = begin; -// idx ++; -// if (idx == end) idx = begin; -// } - -// void init(size_t pos) -// { -// startidx = begin + (pos - begin) % size(); -// idx = startidx; -// nextidx = begin + (idx + 1 - begin) % size(); -// } - -// bool is_finished() const { return nextidx == idx; } -//}; - -//template -//static Sc sq_dst(const Vec<3, Sc> &v1, const Vec<3, Sc>& v2) -//{ -// Vec<3, Sc> v = v1 - v2; -// return v.x() * v.x() + v.y() * v.y() /*+ v.z() * v.z()*/; -//} - -//template -//static Sc trscore(const Ring & onring, -// const Ring & offring, -// const std::vector> &pts) -//{ -// Sc a = sq_dst(pts[onring.pos().first], pts[offring.pos().first]); -// Sc b = sq_dst(pts[onring.pos().second], pts[offring.pos().first]); -// return (std::abs(a) + std::abs(b)) / 2.; -//} - -//template -//class Triangulator { -// const std::vector> *pts; -// Ring *onring, *offring; - -// double calc_score() const -// { -// return trscore(*onring, *offring, *pts); -// } - -// void synchronize_rings() -// { -// Ring lring = *offring; -// auto minsc = trscore(*onring, lring, *pts); -// size_t imin = lring.pos().first; - -// lring.inc(); - -// while(!lring.is_finished()) { -// double score = trscore(*onring, lring, *pts); -// if (score < minsc) { minsc = score; imin = lring.pos().first; } -// lring.inc(); -// } - -// offring->init(imin); -// } - -// void emplace_indices(std::vector &indices) -// { -// Vec3i tr{int(onring->pos().first), int(onring->pos().second), -// int(offring->pos().first)}; -// if (onring->is_lower()) std::swap(tr(0), tr(1)); -// indices.emplace_back(tr); -// } - -//public: -// void run(std::vector &indices) -// { -// synchronize_rings(); - -// double score = 0, prev_score = 0; -// while (!onring->is_finished() || !offring->is_finished()) { -// prev_score = score; -// if (onring->is_finished() || (score = calc_score()) > prev_score) { -// std::swap(onring, offring); -// } else { -// emplace_indices(indices); -// onring->inc(); -// } -// } -// } - -// explicit Triangulator(const std::vector> *points, -// Ring & lower, -// Ring & upper) -// : pts{points}, onring{&upper}, offring{&lower} -// {} -//}; - -//template -//void triangulate_wall(std::vector> &pts, -// std::vector> & ind, -// const Polygon & lower, -// const Polygon & upper, -// double lower_z_mm, -// double upper_z_mm) -//{ -// if (upper.points.size() < 3 || lower.points.size() < 3) return; - -// pts.reserve(lower.points.size() + upper.points.size()); -// for (auto &p : lower.points) -// pts.emplace_back(unscaled(p.x()), unscaled(p.y()), lower_z_mm); -// for (auto &p : upper.points) -// pts.emplace_back(unscaled(p.x()), unscaled(p.y()), upper_z_mm); - -// ind.reserve(2 * (lower.size() + upper.size())); - -// Ring lring{0, lower.points.size()}, uring{lower.points.size(), pts.size()}; -// Triangulator t{&pts, lring, uring}; -// t.run(ind); -//} - -//Wall triangulate_wall(const Polygon &lower, -// const Polygon &upper, -// double lower_z_mm, -// double upper_z_mm) -//{ -// if (upper.points.size() < 3 || lower.points.size() < 3) return {}; - -// Wall wall; -// auto &pts = wall.first; -// auto &ind = wall.second; - -// pts.reserve(lower.points.size() + upper.points.size()); -// for (auto &p : lower.points) -// wall.first.emplace_back(unscaled(p.x()), unscaled(p.y()), lower_z_mm); -// for (auto &p : upper.points) -// wall.first.emplace_back(unscaled(p.x()), unscaled(p.y()), upper_z_mm); - -// ind.reserve(2 * (lower.size() + upper.size())); - -// Ring lring{0, lower.points.size()}, uring{lower.points.size(), pts.size()}; -// Triangulator t{&pts, lring, uring}; -// t.run(ind); - -// return wall; -//} - -} // namespace Slic3r From 6549342008ea73b15b0f17d6f06783e998124bae Mon Sep 17 00:00:00 2001 From: rtyr <36745189+rtyr@users.noreply.github.com> Date: Wed, 5 Oct 2022 11:49:44 +0200 Subject: [PATCH 2/6] Initial Print4Taste bundle. https://github.com/prusa3d/PrusaSlicer-settings/pull/168 --- resources/profiles/Print4Taste.idx | 2 + resources/profiles/Print4Taste.ini | 131 ++++++++++++++ resources/profiles/Print4Taste/MC2.0_bed.stl | Bin 0 -> 684 bytes .../profiles/Print4Taste/MC2.0_texture.svg | 165 ++++++++++++++++++ .../profiles/Print4Taste/MC2.0_thumbnail.png | Bin 0 -> 45346 bytes 5 files changed, 298 insertions(+) create mode 100644 resources/profiles/Print4Taste.idx create mode 100644 resources/profiles/Print4Taste.ini create mode 100644 resources/profiles/Print4Taste/MC2.0_bed.stl create mode 100644 resources/profiles/Print4Taste/MC2.0_texture.svg create mode 100644 resources/profiles/Print4Taste/MC2.0_thumbnail.png diff --git a/resources/profiles/Print4Taste.idx b/resources/profiles/Print4Taste.idx new file mode 100644 index 0000000000..b19d0f3e1a --- /dev/null +++ b/resources/profiles/Print4Taste.idx @@ -0,0 +1,2 @@ +min_slic3r_version = 2.6.0-alpha1 +0.0.1 Initial version \ No newline at end of file diff --git a/resources/profiles/Print4Taste.ini b/resources/profiles/Print4Taste.ini new file mode 100644 index 0000000000..05f76e1c33 --- /dev/null +++ b/resources/profiles/Print4Taste.ini @@ -0,0 +1,131 @@ +# Print profiles for Print4Taste printers (mycusini and procusini brands) +# Created from scratch from default FFF + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = Print4Taste +# Configuration version of this file. Config file will only be installed, if the config_version differs. +# This means, the server may force the PrusaSlicer configuration to be downgraded. +config_version = 0.0.1 +# Where to get the updates from? +config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Print4Taste/ + +# The printer models will be shown by the Configuration Wizard in this order, +# also the first model installed & the first nozzle installed will be activated after install. +# Printer model name will be shown by the installation wizard. + + +[printer_model:MC2.0] +name = mycusini 2.0 +variants = 1.0 +technology = FFF +family = mycusini +bed_model = MC2.0_bed.stl +bed_texture = MC2.0_texture.svg +default_materials = mycusini 3D Choco @MC2.0 + +[print:*common_MC2.0*] +bottom_solid_layers = 2 +bridge_speed = 30 +brim_type = no_brim +compatible_printers_condition = printer_notes=~/.*PRINT4TASTE.*/ and printer_notes=~/.*MYCUSINI2.0.*/ +elefant_foot_compensation = 0.1 +ensure_vertical_shell_thickness = 1 +external_perimeter_extrusion_width = 1.15 +external_perimeter_speed = 100% +extra_perimeters = 0 +extruder_clearance_height = 45 +extruder_clearance_radius = 40 +extrusion_width = 1.15 +fill_density = 20% +fill_pattern = grid +first_layer_extrusion_width = 1.15 +first_layer_height = 0.5 +first_layer_speed = 100% +gap_fill_speed = 30 +infill_anchor = 250% +infill_extrusion_width = 1 +infill_overlap = 5% +infill_speed = 30 +layer_height = 0.5 +max_print_speed = 80 +max_volumetric_extrusion_rate_slope_negative = 2 +max_volumetric_extrusion_rate_slope_positive = 2 +max_volumetric_speed = 8 +notes = Extruder clearances:\nHeight: 45 Radius: 40\nHeight: 8 Radius: 12\n\nDon'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_PRINT4TASTE\nPRINTER_MODEL_MYCUSINI2.0 +output_filename_format = [input_filename_base].gco +perimeter_extrusion_width = 1.15 +perimeter_speed = 30 +perimeters = 1 +slice_closing_radius = 0.49 +small_perimeter_speed = 100% +solid_infill_below_area = 10 +solid_infill_extrusion_width = 1.15 +solid_infill_speed = 100% +thin_walls = 0 +top_infill_extrusion_width = 1.15 +top_solid_infill_speed = 100% +top_solid_layers = 3 +travel_speed = 80 +skirts = 0 + +[print:0.50mm SOLID @MC2.0] +inherits = *common_MC2.0* + +[print:0.50mm FILLABLE @MC2.0] +inherits = 0.50mm SOLID @MC2.0 +top_solid_layers = 0 +fill_density = 0% +spiral_vase = 1 + +[print:0.50mm OUTLINES @MC2.0] +inherits = 0.50mm FILLABLE @MC2.0 +bottom_solid_layers = 0 + +[filament:mycusini 3D Choco @MC2.0] +filament_vendor = Print4Taste +bed_temperature = 0 +bridge_fan_speed = 0 +compatible_printers_condition = printer_notes=~/.*PRINT4TASTE.*/ and printer_notes=~/.*MYCUSINI2.0.*/ +cooling = 1 +disable_fan_first_layers = 0 +end_filament_gcode = "" +extrusion_multiplier = 0.95 +fan_always_on = 0 +fan_below_layer_time = 60 +filament_colour = #F4A6FF +filament_density = 1.26 +filament_diameter = 18 +filament_max_volumetric_speed = 8 +filament_notes = "Full cartridge: 18 x 100 mm, 32g\nDensity: 1.26 g/cm3\nCut cartrige size: 18 x ~50 mm, 16g\nMycusini 2.0 does not require temperature control in gcode\n\n\nDon'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_PRINT4TASTE\nPRINTER_MODEL_MYCUSINI2.0" +ilament_retract_before_wipe = 30% +filament_retract_layer_change = 1 +filament_retract_length = 0.3 +filament_retract_lift = 1 +filament_type = GLAZE +filament_wipe = 1 +first_layer_bed_temperature = 0 +first_layer_temperature = 0 +max_fan_speed = 0 +min_fan_speed = 0 +min_print_speed = 9 +slowdown_below_layer_time = 15 +start_filament_gcode = "" +temperature = 0 + +[printer:mycusini 2.0] +printer_model = MC2.0 +printer_variant = 1.0 +bed_shape = 5x2.5,105x2.5,105x112.5,5x112.5 +color_change_gcode = +end_gcode = M83 ;Relative mode to retract\nG1 F2400 E-0.1 ;Retract\nM84 ;Back to absolute mode after retract\nG0 F2400 X90 Y55 Z45 ;Park +max_layer_height = 0.75 +max_print_height = 45 +min_layer_height = 0.3 +nozzle_diameter = 1 +pause_print_gcode = +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_PRINT4TASTE\nPRINTER_MODEL_MYCUSINI2.0 +retract_length = 0.1 +start_gcode = G1 F2400 E-0.3 ;Retract\nG0 F2400 X100 Y55 Z20.7 ;Full coordinates to prevent ramming down\nG0 F2400 X100 Y40 Z0.5 ;Start purge line\nG0 F570 X100 Y10 Z0.5 E0.025 ;Purge slightly more, should make a line only a few mm long +default_print_profile = 0.50mm SOLID @MC2.0 +default_filament_profile = mycusini 3D Choco @MC2.0 \ No newline at end of file diff --git a/resources/profiles/Print4Taste/MC2.0_bed.stl b/resources/profiles/Print4Taste/MC2.0_bed.stl new file mode 100644 index 0000000000000000000000000000000000000000..2db61908d88bde355a170c3a5bc9bc5cc46cf06d GIT binary patch literal 684 zcmb7>!41MN3`IQvLu7)eJ;4PbiiCQoS_yh&3l_*I-K0_%gKx)9QVItwC2^d*Z#%h< zUE|K<)z!7%`^wkV!Ci)KxE-fydbz)CM{Hr1MW%KkdSI}L-xNOLVSe`C30Bzob=>ue{Q2nA0&9my3Z&|)2 z`b8ffM9N`=(wX2|11PIkYFAzHnZTZi|HCX1a-wgAn{4@KSHzrel~sukmHfI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/profiles/Print4Taste/MC2.0_thumbnail.png b/resources/profiles/Print4Taste/MC2.0_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..886dd34547efe01a2a50a2cd9c787a1257b0e698 GIT binary patch literal 45346 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%0Av3sDG^ku3d^GD3$h%g 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 literal 0 HcmV?d00001 From 8a54f91548d72fa43e5fec15410b32f194e8aebb Mon Sep 17 00:00:00 2001 From: rtyr <36745189+rtyr@users.noreply.github.com> Date: Wed, 5 Oct 2022 13:29:45 +0200 Subject: [PATCH 3/6] Sync with PrusaSlicer-settings. --- resources/profiles/Elegoo.idx | 5 +- resources/profiles/Elegoo.ini | 1020 ++++++++++++++++----------------- 2 files changed, 513 insertions(+), 512 deletions(-) diff --git a/resources/profiles/Elegoo.idx b/resources/profiles/Elegoo.idx index cf0da371b1..6fcdedd3f8 100644 --- a/resources/profiles/Elegoo.idx +++ b/resources/profiles/Elegoo.idx @@ -1,2 +1,3 @@ -min_slic3r_version = 2.5.0-alpha3 -1.0.0 Initial version +min_slic3r_version = 2.5.0-alpha3 +1.0.1 Decreased bed size to 220x220. +1.0.0 Initial version diff --git a/resources/profiles/Elegoo.ini b/resources/profiles/Elegoo.ini index a39d33f3f5..d9053e5a24 100644 --- a/resources/profiles/Elegoo.ini +++ b/resources/profiles/Elegoo.ini @@ -1,510 +1,510 @@ -# PrusaSlicer print profiles for the Elegoo printers. -# By Andrew Suzuki (andrewsuzuki.com), adapted from Creality.ini - -[vendor] -# Vendor name will be shown by the Config Wizard. -name = Elegoo -# Configuration version of this file. Config file will only be installed, if the config_version differs. -# This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.0.0 -config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Elegoo/ - -# The printer models will be shown by the Configuration Wizard in this order, -# also the first model installed & the first nozzle installed will be activated after install. -# Printer model name will be shown by the installation wizard. - -[printer_model:NEPTUNE1] -name = Elegoo Neptune-1 -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE2] -name = Elegoo Neptune-2 -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE2D] -name = Elegoo Neptune-2D -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE2S] -name = Elegoo Neptune-2S -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNE3] -name = Elegoo Neptune-3 -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -[printer_model:NEPTUNEX] -name = Elegoo Neptune-X -variants = 0.4 -technology = FFF -family = NEPTUNE -bed_model = -bed_texture = -default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO - -# All presets starting with asterisk, for example *common*, are intermediate and they will -# not make it into the user interface. - -# Common print preset -[print:*common*] -avoid_crossing_perimeters = 0 -bridge_angle = 0 -bridge_flow_ratio = 0.95 -bridge_speed = 25 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -complete_objects = 0 -dont_support_bridges = 1 -elefant_foot_compensation = 0.1 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeters_first = 0 -external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 25 -extra_perimeters = 0 -extruder_clearance_height = 25 -extruder_clearance_radius = 45 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = grid -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 20 -gap_fill_speed = 30 -gcode_comments = 0 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.45 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 50 -interface_shells = 0 -max_print_speed = 100 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -overhangs = 0 -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode -perimeters = 2 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 40 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -single_extruder_multi_material_priming = 0 -skirts = 1 -skirt_distance = 2 -skirt_height = 2 -small_perimeter_speed = 25 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.45 -solid_infill_speed = 40 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.38 -support_material_interface_extruder = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_enforce_layers = 0 -support_material_contact_distance = 0.15 -support_material_interface_contact_loops = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 40 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -top_infill_extrusion_width = 0.4 -top_solid_infill_speed = 30 -travel_speed = 150 -wipe_tower = 0 -wipe_tower_bridging = 10 -wipe_tower_rotation_angle = 0 -wipe_tower_width = 60 -wipe_tower_x = 170 -wipe_tower_y = 140 -xy_size_compensation = 0 - -[print:*0.08mm*] -inherits = *common* -layer_height = 0.08 -perimeters = 3 -bottom_solid_layers = 9 -top_solid_layers = 11 - -[print:*0.10mm*] -inherits = *common* -layer_height = 0.1 -perimeters = 3 -bottom_solid_layers = 7 -top_solid_layers = 9 - -[print:*0.12mm*] -inherits = *common* -layer_height = 0.12 -perimeters = 3 -bottom_solid_layers = 6 -top_solid_layers = 7 - -[print:*0.16mm*] -inherits = *common* -layer_height = 0.16 -bottom_solid_layers = 5 -top_solid_layers = 7 - -[print:*0.20mm*] -inherits = *common* -layer_height = 0.20 -bottom_solid_layers = 4 -top_solid_layers = 5 - -[print:*0.24mm*] -inherits = *common* -layer_height = 0.24 -top_infill_extrusion_width = 0.45 -bottom_solid_layers = 3 -top_solid_layers = 4 - -[print:*0.28mm*] -inherits = *common* -layer_height = 0.28 -top_infill_extrusion_width = 0.45 -bottom_solid_layers = 3 -top_solid_layers = 4 - -[print:0.08mm SUPERDETAIL @ELEGOO] -inherits = *0.08mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.10mm HIGHDETAIL @ELEGOO] -inherits = *0.10mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.12mm DETAIL @ELEGOO] -inherits = *0.12mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.16mm OPTIMAL @ELEGOO] -inherits = *0.16mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.20mm NORMAL @ELEGOO] -inherits = *0.20mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.24mm DRAFT @ELEGOO] -inherits = *0.24mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -[print:0.28mm SUPERDRAFT @ELEGOO] -inherits = *0.28mm* -compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 - -# When submitting new filaments please print the following temperature tower at 0.1mm layer height: -# https://www.thingiverse.com/thing:2615842 -# Pay particular attention to bridging, overhangs and retractions. -# Also print the following bed adhesion test at 0.1 layer height as well: -# https://www.prusaprinters.org/prints/4634-bed-adhesion-warp-test -# At least for PLA, please keep bed temp at 60, as many Elegoo printers do not have any ABL -# So having some leeway to get good bed adhesion is not a luxury for many users - -[filament:*common*] -cooling = 0 -compatible_printers = -extrusion_multiplier = 1 -filament_cost = 0 -filament_density = 0 -filament_diameter = 1.75 -filament_notes = "" -filament_settings_id = "" -filament_soluble = 0 -min_print_speed = 15 -slowdown_below_layer_time = 20 -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ELEGOO.*/ - -[filament:*PLA*] -inherits = *common* -bed_temperature = 60 -fan_below_layer_time = 100 -filament_colour = #DDDDDD -filament_max_volumetric_speed = 15 -filament_type = PLA -filament_density = 1.24 -filament_cost = 20 -first_layer_bed_temperature = 60 -first_layer_temperature = 210 -fan_always_on = 1 -cooling = 1 -max_fan_speed = 100 -min_fan_speed = 100 -bridge_fan_speed = 100 -disable_fan_first_layers = 1 -temperature = 205 - -[filament:*PET*] -inherits = *common* -bed_temperature = 70 -cooling = 1 -disable_fan_first_layers = 3 -fan_below_layer_time = 20 -filament_colour = #DDDDDD -filament_max_volumetric_speed = 8 -filament_type = PETG -filament_density = 1.27 -filament_cost = 20 -first_layer_bed_temperature = 70 -first_layer_temperature = 240 -fan_always_on = 1 -max_fan_speed = 50 -min_fan_speed = 20 -bridge_fan_speed = 100 -temperature = 240 - -[filament:*ABS*] -inherits = *common* -bed_temperature = 100 -cooling = 0 -disable_fan_first_layers = 3 -fan_below_layer_time = 20 -filament_colour = #DDDDDD -filament_max_volumetric_speed = 11 -filament_type = ABS -filament_density = 1.04 -filament_cost = 20 -first_layer_bed_temperature = 100 -first_layer_temperature = 245 -fan_always_on = 0 -max_fan_speed = 0 -min_fan_speed = 0 -bridge_fan_speed = 30 -top_fan_speed = 0 -temperature = 245 - -[filament:Generic PLA @ELEGOO] -inherits = *PLA* -filament_vendor = Generic - -[filament:Generic PETG @ELEGOO] -inherits = *PET* -filament_vendor = Generic - -[filament:Generic ABS @ELEGOO] -inherits = *ABS* -first_layer_bed_temperature = 90 -bed_temperature = 90 -filament_vendor = Generic - -# Common printer preset -[printer:*common*] -printer_technology = FFF -before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]\n\n -bed_shape = 0x0,235x0,235x235,0x235 -between_objects_gcode = -pause_print_gcode = -deretract_speed = 0 -extruder_colour = #FCE94F -extruder_offset = 0x0 -gcode_flavor = marlin -silent_mode = 0 -remaining_times = 0 -machine_max_acceleration_e = 5000 -machine_max_acceleration_extruding = 500 -machine_max_acceleration_retracting = 1000 -machine_max_acceleration_x = 500 -machine_max_acceleration_y = 500 -machine_max_acceleration_z = 100 -machine_max_feedrate_e = 60 -machine_max_feedrate_x = 500 -machine_max_feedrate_y = 500 -machine_max_feedrate_z = 10 -machine_max_jerk_e = 5 -machine_max_jerk_x = 8 -machine_max_jerk_y = 8 -machine_max_jerk_z = 0.4 -machine_min_extruding_rate = 0 -machine_min_travel_rate = 0 -layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] -max_layer_height = 0.3 -min_layer_height = 0.07 -max_print_height = 250 -nozzle_diameter = 0.4 -printer_notes = -printer_settings_id = -retract_before_travel = 1 -retract_before_wipe = 0% -retract_layer_change = 1 -retract_length = 1 -retract_length_toolchange = 1 -retract_lift = 0 -retract_lift_above = 0 -retract_lift_below = 0 -retract_restart_extra = 0 -retract_restart_extra_toolchange = 0 -retract_speed = 35 -single_extruder_multi_material = 0 -thumbnails = 16x16,220x124 -toolchange_gcode = -use_firmware_retraction = 0 -use_relative_e_distances = 1 -use_volumetric_e = 0 -variable_layer_height = 1 -wipe = 1 -z_offset = 0 -printer_model = -default_print_profile = 0.16mm OPTIMAL @ELEGOO -default_filament_profile = Generic PLA @ELEGOO - -[printer:Elegoo Neptune-2] -inherits = *common* -printer_model = NEPTUNE2 -printer_variant = 0.4 -max_layer_height = 0.28 -min_layer_height = 0.08 -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_ELEGOO\nPRINTER_MODEL_NEPTUNE2\nPRINTER_HAS_BOWDEN -max_print_height = 250 -machine_max_acceleration_e = 5000 -machine_max_acceleration_extruding = 500 -machine_max_acceleration_retracting = 1000 -machine_max_acceleration_x = 500 -machine_max_acceleration_y = 500 -machine_max_acceleration_z = 100 -machine_max_feedrate_e = 60 -machine_max_feedrate_x = 500 -machine_max_feedrate_y = 500 -machine_max_feedrate_z = 10 -machine_max_jerk_e = 5 -machine_max_jerk_x = 8 -machine_max_jerk_y = 8 -machine_max_jerk_z = 0.4 -machine_min_extruding_rate = 0 -machine_min_travel_rate = 0 -nozzle_diameter = 0.4 -retract_before_travel = 2 -retract_length = 5 -retract_speed = 60 -deretract_speed = 40 -retract_before_wipe = 70% -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 -end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors - - -# Intended for printers with a smaller bed -# [printer:*fastabl*] -# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 - -# Intended for printers with a larger bed -# [printer:*slowabl*] -# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 - -# Intended for printers with vendor official firmware verified to support M25 -# [printer:*pauseprint*] -# pause_print_gcode = M25 ; pause print - -# Intended for printers where the Z-axis lowers the print bed during printing -# [printer:*invertedz*] -# end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed down further down\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors - -# Intended for printers with dual extruders and a single hotend/nozzle -[printer:*dualextruder*] -single_extruder_multi_material = 1 -cooling_tube_length = 23 -cooling_tube_retraction = 35 -extra_loading_move = -2 -parking_pos_retraction = 80 -deretract_speed = 40,40 -extruder_colour = #0080C0;#FFFF9F -extruder_offset = 0x0,0x0 -max_layer_height = 0.28,0.28 -min_layer_height = 0.08,0.08 -nozzle_diameter = 0.4,0.4 -retract_before_travel = 2,2 -retract_before_wipe = 70%,70% -retract_layer_change = 1,1 -retract_length = 5,5 -retract_length_toolchange = 1,1 -retract_lift = 0,0 -retract_lift_above = 0,0 -retract_lift_below = 0,0 -retract_restart_extra = 0,0 -retract_restart_extra_toolchange = 0,0 -retract_speed = 60,60 -wipe = 1,1 -start_gcode = T[initial_tool] ; set active extruder\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM140 S{first_layer_bed_temperature[0]} ; set final bed temp\nM104 S150 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\n;G29 ; auto bed levelling - remove ; at beginning of line to enable\n;M420 S1 ; enable mesh - remove ; at beginning of line to enable\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S{first_layer_temperature[0]} ; set final nozzle temp\nM190 S{first_layer_bed_temperature[0]} ; wait for bed temp to stabilize\nM109 S{first_layer_temperature[0]} ; wait for nozzle temp to stabilize\nG1 Z0.28 F240 ; move down to prime nozzle\nG92 E0 ; reset extruder\nG1 E90 ; load filament\nG92 E0 ; reset extruder\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000 ; move over for second prime line\nG92 E0 ; reset extruder\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 ; reset extruder -end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\nG1 E-80 F2000 ; unload filament\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors - -# Copy of Creality CR-X config for the Neptune 2D (dual extruder, single hotend) - -[printer:Elegoo Neptune-2D] -inherits = Elegoo Neptune-2; *dualextruder* -retract_length = 6,6 -printer_model = NEPTUNE2D -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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-2S] -inherits = Elegoo Neptune-2 -printer_model = NEPTUNE2S -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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-X] -inherits = Elegoo Neptune-2 -max_print_height = 300 -printer_model = NEPTUNEX -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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-3] -inherits = Elegoo Neptune-2 -max_print_height = 280 -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; run abl mesh\nM420 S1 ; load mesh\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 -printer_model = NEPTUNE3 -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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN - -[printer:Elegoo Neptune-1] -inherits = Elegoo Neptune-2 -bed_shape = 0x0,210x0,210x210,0x210 -max_print_height = 200 -printer_model = NEPTUNE1 -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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN +# PrusaSlicer print profiles for the Elegoo printers. +# By Andrew Suzuki (andrewsuzuki.com), adapted from Creality.ini + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = Elegoo +# Configuration version of this file. Config file will only be installed, if the config_version differs. +# This means, the server may force the PrusaSlicer configuration to be downgraded. +config_version = 1.0.1 +config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Elegoo/ + +# The printer models will be shown by the Configuration Wizard in this order, +# also the first model installed & the first nozzle installed will be activated after install. +# Printer model name will be shown by the installation wizard. + +[printer_model:NEPTUNE1] +name = Elegoo Neptune-1 +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE2] +name = Elegoo Neptune-2 +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE2D] +name = Elegoo Neptune-2D +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE2S] +name = Elegoo Neptune-2S +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNE3] +name = Elegoo Neptune-3 +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +[printer_model:NEPTUNEX] +name = Elegoo Neptune-X +variants = 0.4 +technology = FFF +family = NEPTUNE +bed_model = +bed_texture = +default_materials = Generic PLA @ELEGOO; Generic PETG @ELEGOO; Generic ABS @ELEGOO + +# All presets starting with asterisk, for example *common*, are intermediate and they will +# not make it into the user interface. + +# Common print preset +[print:*common*] +avoid_crossing_perimeters = 0 +bridge_angle = 0 +bridge_flow_ratio = 0.95 +bridge_speed = 25 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +complete_objects = 0 +dont_support_bridges = 1 +elefant_foot_compensation = 0.1 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeters_first = 0 +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 25 +extra_perimeters = 0 +extruder_clearance_height = 25 +extruder_clearance_radius = 45 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 20 +gap_fill_speed = 30 +gcode_comments = 0 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 50 +interface_shells = 0 +max_print_speed = 100 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +overhangs = 0 +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode +perimeters = 2 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +perimeter_speed = 40 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +single_extruder_multi_material_priming = 0 +skirts = 1 +skirt_distance = 2 +skirt_height = 2 +small_perimeter_speed = 25 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 40 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.38 +support_material_interface_extruder = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_enforce_layers = 0 +support_material_contact_distance = 0.15 +support_material_interface_contact_loops = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 40 +support_material_synchronize_layers = 0 +support_material_threshold = 45 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 30 +travel_speed = 150 +wipe_tower = 0 +wipe_tower_bridging = 10 +wipe_tower_rotation_angle = 0 +wipe_tower_width = 60 +wipe_tower_x = 170 +wipe_tower_y = 140 +xy_size_compensation = 0 + +[print:*0.08mm*] +inherits = *common* +layer_height = 0.08 +perimeters = 3 +bottom_solid_layers = 9 +top_solid_layers = 11 + +[print:*0.10mm*] +inherits = *common* +layer_height = 0.1 +perimeters = 3 +bottom_solid_layers = 7 +top_solid_layers = 9 + +[print:*0.12mm*] +inherits = *common* +layer_height = 0.12 +perimeters = 3 +bottom_solid_layers = 6 +top_solid_layers = 7 + +[print:*0.16mm*] +inherits = *common* +layer_height = 0.16 +bottom_solid_layers = 5 +top_solid_layers = 7 + +[print:*0.20mm*] +inherits = *common* +layer_height = 0.20 +bottom_solid_layers = 4 +top_solid_layers = 5 + +[print:*0.24mm*] +inherits = *common* +layer_height = 0.24 +top_infill_extrusion_width = 0.45 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:*0.28mm*] +inherits = *common* +layer_height = 0.28 +top_infill_extrusion_width = 0.45 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:0.08mm SUPERDETAIL @ELEGOO] +inherits = *0.08mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.10mm HIGHDETAIL @ELEGOO] +inherits = *0.10mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.12mm DETAIL @ELEGOO] +inherits = *0.12mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.16mm OPTIMAL @ELEGOO] +inherits = *0.16mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.20mm NORMAL @ELEGOO] +inherits = *0.20mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.24mm DRAFT @ELEGOO] +inherits = *0.24mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +[print:0.28mm SUPERDRAFT @ELEGOO] +inherits = *0.28mm* +compatible_printers_condition = printer_model=~/(NEPTUNE).*/ and nozzle_diameter[0]==0.4 + +# When submitting new filaments please print the following temperature tower at 0.1mm layer height: +# https://www.thingiverse.com/thing:2615842 +# Pay particular attention to bridging, overhangs and retractions. +# Also print the following bed adhesion test at 0.1 layer height as well: +# https://www.prusaprinters.org/prints/4634-bed-adhesion-warp-test +# At least for PLA, please keep bed temp at 60, as many Elegoo printers do not have any ABL +# So having some leeway to get good bed adhesion is not a luxury for many users + +[filament:*common*] +cooling = 0 +compatible_printers = +extrusion_multiplier = 1 +filament_cost = 0 +filament_density = 0 +filament_diameter = 1.75 +filament_notes = "" +filament_settings_id = "" +filament_soluble = 0 +min_print_speed = 15 +slowdown_below_layer_time = 20 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ELEGOO.*/ + +[filament:*PLA*] +inherits = *common* +bed_temperature = 60 +fan_below_layer_time = 100 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 15 +filament_type = PLA +filament_density = 1.24 +filament_cost = 20 +first_layer_bed_temperature = 60 +first_layer_temperature = 210 +fan_always_on = 1 +cooling = 1 +max_fan_speed = 100 +min_fan_speed = 100 +bridge_fan_speed = 100 +disable_fan_first_layers = 1 +temperature = 205 + +[filament:*PET*] +inherits = *common* +bed_temperature = 70 +cooling = 1 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 8 +filament_type = PETG +filament_density = 1.27 +filament_cost = 20 +first_layer_bed_temperature = 70 +first_layer_temperature = 240 +fan_always_on = 1 +max_fan_speed = 50 +min_fan_speed = 20 +bridge_fan_speed = 100 +temperature = 240 + +[filament:*ABS*] +inherits = *common* +bed_temperature = 100 +cooling = 0 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 11 +filament_type = ABS +filament_density = 1.04 +filament_cost = 20 +first_layer_bed_temperature = 100 +first_layer_temperature = 245 +fan_always_on = 0 +max_fan_speed = 0 +min_fan_speed = 0 +bridge_fan_speed = 30 +top_fan_speed = 0 +temperature = 245 + +[filament:Generic PLA @ELEGOO] +inherits = *PLA* +filament_vendor = Generic + +[filament:Generic PETG @ELEGOO] +inherits = *PET* +filament_vendor = Generic + +[filament:Generic ABS @ELEGOO] +inherits = *ABS* +first_layer_bed_temperature = 90 +bed_temperature = 90 +filament_vendor = Generic + +# Common printer preset +[printer:*common*] +printer_technology = FFF +before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]\n\n +bed_shape = 0x0,220x0,220x220,0x220 +between_objects_gcode = +pause_print_gcode = +deretract_speed = 0 +extruder_colour = #FCE94F +extruder_offset = 0x0 +gcode_flavor = marlin +silent_mode = 0 +remaining_times = 0 +machine_max_acceleration_e = 5000 +machine_max_acceleration_extruding = 500 +machine_max_acceleration_retracting = 1000 +machine_max_acceleration_x = 500 +machine_max_acceleration_y = 500 +machine_max_acceleration_z = 100 +machine_max_feedrate_e = 60 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 10 +machine_max_jerk_e = 5 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 0.4 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] +max_layer_height = 0.3 +min_layer_height = 0.07 +max_print_height = 250 +nozzle_diameter = 0.4 +printer_notes = +printer_settings_id = +retract_before_travel = 1 +retract_before_wipe = 0% +retract_layer_change = 1 +retract_length = 1 +retract_length_toolchange = 1 +retract_lift = 0 +retract_lift_above = 0 +retract_lift_below = 0 +retract_restart_extra = 0 +retract_restart_extra_toolchange = 0 +retract_speed = 35 +single_extruder_multi_material = 0 +thumbnails = 16x16,220x124 +toolchange_gcode = +use_firmware_retraction = 0 +use_relative_e_distances = 1 +use_volumetric_e = 0 +variable_layer_height = 1 +wipe = 1 +z_offset = 0 +printer_model = +default_print_profile = 0.16mm OPTIMAL @ELEGOO +default_filament_profile = Generic PLA @ELEGOO + +[printer:Elegoo Neptune-2] +inherits = *common* +printer_model = NEPTUNE2 +printer_variant = 0.4 +max_layer_height = 0.28 +min_layer_height = 0.08 +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_ELEGOO\nPRINTER_MODEL_NEPTUNE2\nPRINTER_HAS_BOWDEN +max_print_height = 250 +machine_max_acceleration_e = 5000 +machine_max_acceleration_extruding = 500 +machine_max_acceleration_retracting = 1000 +machine_max_acceleration_x = 500 +machine_max_acceleration_y = 500 +machine_max_acceleration_z = 100 +machine_max_feedrate_e = 60 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 10 +machine_max_jerk_e = 5 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 0.4 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +nozzle_diameter = 0.4 +retract_before_travel = 2 +retract_length = 5 +retract_speed = 60 +deretract_speed = 40 +retract_before_wipe = 70% +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 +end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + + +# Intended for printers with a smaller bed +# [printer:*fastabl*] +# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 + +# Intended for printers with a larger bed +# [printer:*slowabl*] +# start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 + +# Intended for printers with vendor official firmware verified to support M25 +# [printer:*pauseprint*] +# pause_print_gcode = M25 ; pause print + +# Intended for printers where the Z-axis lowers the print bed during printing +# [printer:*invertedz*] +# end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed down further down\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + +# Intended for printers with dual extruders and a single hotend/nozzle +[printer:*dualextruder*] +single_extruder_multi_material = 1 +cooling_tube_length = 23 +cooling_tube_retraction = 35 +extra_loading_move = -2 +parking_pos_retraction = 80 +deretract_speed = 40,40 +extruder_colour = #0080C0;#FFFF9F +extruder_offset = 0x0,0x0 +max_layer_height = 0.28,0.28 +min_layer_height = 0.08,0.08 +nozzle_diameter = 0.4,0.4 +retract_before_travel = 2,2 +retract_before_wipe = 70%,70% +retract_layer_change = 1,1 +retract_length = 5,5 +retract_length_toolchange = 1,1 +retract_lift = 0,0 +retract_lift_above = 0,0 +retract_lift_below = 0,0 +retract_restart_extra = 0,0 +retract_restart_extra_toolchange = 0,0 +retract_speed = 60,60 +wipe = 1,1 +start_gcode = T[initial_tool] ; set active extruder\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM140 S{first_layer_bed_temperature[0]} ; set final bed temp\nM104 S150 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\n;G29 ; auto bed levelling - remove ; at beginning of line to enable\n;M420 S1 ; enable mesh - remove ; at beginning of line to enable\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S{first_layer_temperature[0]} ; set final nozzle temp\nM190 S{first_layer_bed_temperature[0]} ; wait for bed temp to stabilize\nM109 S{first_layer_temperature[0]} ; wait for nozzle temp to stabilize\nG1 Z0.28 F240 ; move down to prime nozzle\nG92 E0 ; reset extruder\nG1 E90 ; load filament\nG92 E0 ; reset extruder\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000 ; move over for second prime line\nG92 E0 ; reset extruder\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 ; reset extruder +end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\nG1 E-80 F2000 ; unload filament\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + +# Copy of Creality CR-X config for the Neptune 2D (dual extruder, single hotend) + +[printer:Elegoo Neptune-2D] +inherits = Elegoo Neptune-2; *dualextruder* +retract_length = 6,6 +printer_model = NEPTUNE2D +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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-2S] +inherits = Elegoo Neptune-2 +printer_model = NEPTUNE2S +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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-X] +inherits = Elegoo Neptune-2 +max_print_height = 300 +printer_model = NEPTUNEX +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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-3] +inherits = Elegoo Neptune-2 +max_print_height = 280 +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; run abl mesh\nM420 S1 ; load mesh\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 +printer_model = NEPTUNE3 +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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN + +[printer:Elegoo Neptune-1] +inherits = Elegoo Neptune-2 +bed_shape = 0x0,210x0,210x210,0x210 +max_print_height = 200 +printer_model = NEPTUNE1 +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_ELEGOO\nPRINTER_MODEL_NEPTUNE2D\nPRINTER_HAS_BOWDEN From 20bd7f9a263b7b23a5c0f8d08065f6ff45a4b485 Mon Sep 17 00:00:00 2001 From: PavelMikus Date: Mon, 3 Oct 2022 15:59:34 +0200 Subject: [PATCH 4/6] improvements in islands recognition; LinesDistancer class for both Point based and Floating based lines --- src/libslic3r/AABBTreeLines.hpp | 56 +++++++++-- src/libslic3r/SupportSpotsGenerator.cpp | 127 ++++++------------------ 2 files changed, 77 insertions(+), 106 deletions(-) diff --git a/src/libslic3r/AABBTreeLines.hpp b/src/libslic3r/AABBTreeLines.hpp index 39f828b558..7d6ff1ccc6 100644 --- a/src/libslic3r/AABBTreeLines.hpp +++ b/src/libslic3r/AABBTreeLines.hpp @@ -3,6 +3,7 @@ #include "libslic3r/AABBTreeIndirect.hpp" #include "libslic3r/Line.hpp" +#include namespace Slic3r { @@ -24,16 +25,16 @@ struct IndexedLinesDistancer { inline VectorType closest_point_to_origin(size_t primitive_index, ScalarType &squared_distance) { - VectorType nearest_point; + Vec nearest_point; const LineType &line = lines[primitive_index]; - squared_distance = line_alg::distance_to_squared(line, origin, &nearest_point); - return nearest_point; + squared_distance = line_alg::distance_to_squared(line, origin.template cast(), &nearest_point); + return nearest_point.template cast(); } }; } -// Build a balanced AABB Tree over a vector of float lines, balancing the tree +// Build a balanced AABB Tree over a vector of lines, balancing the tree // on centroids of the lines. // Epsilon is applied to the bounding boxes of the AABB Tree to cope with numeric inaccuracies // during tree traversal. @@ -41,7 +42,7 @@ template inline AABBTreeIndirect::Tree<2, typename LineType::Scalar> build_aabb_tree_over_indexed_lines( const std::vector &lines, //FIXME do we want to apply an epsilon? - const float eps = 0) + const double eps = 0) { using TreeType = AABBTreeIndirect::Tree<2, typename LineType::Scalar>; // using CoordType = typename TreeType::CoordType; @@ -103,8 +104,49 @@ inline typename VectorType::Scalar squared_distance_to_indexed_lines( std::numeric_limits::infinity(), hit_idx_out, hit_point_out); } -} +template class LinesDistancer +{ +private: + std::vector lines; + using Scalar = typename LineType::Scalar; + using Floating = typename std::conditional::value, Scalar, double>::type; + AABBTreeIndirect::Tree<2, Scalar> tree; -} +public: + explicit LinesDistancer(const std::vector &lines) : lines(lines) + { + tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(this->lines); + } + + // negative sign means inside + std::tuple> signed_distance_from_lines_extra(const Vec<2, Scalar> &point) const + { + size_t nearest_line_index_out = size_t(-1); + Vec<2, Floating> nearest_point_out = Vec<2, Floating>::Zero(); + Vec<2, Floating> p = point.template cast(); + auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, nearest_line_index_out, nearest_point_out); + + if (distance < 0) { return {std::numeric_limits::infinity(), nearest_line_index_out, nearest_point_out}; } + + distance = sqrt(distance); + const LineType &line = lines[nearest_line_index_out]; + Vec<2, Floating> v1 = (line.b - line.a).template cast(); + Vec<2, Floating> v2 = (point - line.a).template cast(); + if ((v1.x() * v2.y()) - (v1.y() * v2.x()) > 0.0) { distance *= -1.0; } + return {distance, nearest_line_index_out, nearest_point_out}; + } + + Floating signed_distance_from_lines(const Vec<2, typename LineType::Scalar> &point) const + { + auto [dist, idx, np] = signed_distance_from_lines_extra(point); + return dist; + } + + const LineType &get_line(size_t line_idx) const { return lines[line_idx]; } + + const std::vector &get_lines() const { return lines; } +}; + +}} // namespace Slic3r::AABBTreeLines #endif /* SRC_LIBSLIC3R_AABBTREELINES_HPP_ */ diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index 697518bd08..09b2bc5aea 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -1,6 +1,9 @@ #include "SupportSpotsGenerator.hpp" +#include "ExPolygon.hpp" #include "ExtrusionEntity.hpp" +#include "Line.hpp" +#include "Polygon.hpp" #include "tbb/parallel_for.h" #include "tbb/blocked_range.h" #include "tbb/blocked_range2d.h" @@ -70,46 +73,10 @@ SupportPoint::SupportPoint(const Vec3f &position, float force, float spot_radius position(position), force(force), spot_radius(spot_radius), direction(direction) { } -class LinesDistancer { -private: - std::vector lines; - AABBTreeIndirect::Tree<2, float> tree; - -public: - explicit LinesDistancer(const std::vector &lines) : - lines(lines) { - tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(this->lines); - } - - // negative sign means inside - float signed_distance_from_lines(const Vec2f &point, size_t &nearest_line_index_out, - Vec2f &nearest_point_out) const { - auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, point, nearest_line_index_out, - nearest_point_out); - if (distance < 0) - return std::numeric_limits::infinity(); - - distance = sqrt(distance); - const ExtrusionLine &line = lines[nearest_line_index_out]; - Vec2f v1 = line.b - line.a; - Vec2f v2 = point - line.a; - if ((v1.x() * v2.y()) - (v1.y() * v2.x()) > 0.0) { - distance *= -1; - } - return distance; - } - - const ExtrusionLine& get_line(size_t line_idx) const { - return lines[line_idx]; - } - - const std::vector& get_lines() const { - return lines; - } -}; - static const size_t NULL_ISLAND = std::numeric_limits::max(); +using LD = AABBTreeLines::LinesDistancer; + class PixelGrid { Vec2f pixel_size; Vec2f origin; @@ -387,7 +354,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity, std::vector &checked_lines_out, float layer_z, const LayerRegion *layer_region, - const LinesDistancer &prev_layer_lines, + const LD &prev_layer_lines, Issues &issues, const Params ¶ms) { @@ -429,11 +396,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity, // malformation in concave angles does not happen malformation_acc.add_angle(std::max(0.0f, curr_angle)); - size_t nearest_line_idx; - Vec2f nearest_point; - float dist_from_prev_layer = prev_layer_lines.signed_distance_from_lines(current_line.b, nearest_line_idx, - nearest_point); - + auto [dist_from_prev_layer, nearest_line_idx, nearest_point] = prev_layer_lines.signed_distance_from_lines_extra(current_line.b); if (fabs(dist_from_prev_layer) < overhang_dist) { bridging_acc.reset(); } else { @@ -491,53 +454,18 @@ std::tuple reckon_islands( } } - std::vector islands; // these search trees will be used to determine to which island does the extrusion belong. - std::vector> island_extrusions; //final assigment of each extrusion to an island. - // initliaze the search from external perimeters - at the beginning, there is island candidate for each external perimeter. - // some of them will disappear (e.g. holes) - for (size_t e = 0; e < extrusions.size(); ++e) { - if (layer_lines[extrusions[e].first].origin_entity->is_loop() && - layer_lines[extrusions[e].first].is_external_perimeter()) { - std::vector copy(extrusions[e].second - extrusions[e].first); - for (size_t ex_line_idx = extrusions[e].first; ex_line_idx < extrusions[e].second; ++ex_line_idx) { - copy[ex_line_idx - extrusions[e].first] = layer_lines[ex_line_idx]; - } - islands.emplace_back(copy); - island_extrusions.push_back( { e }); - } + std::vector> islands; // these search trees will be used to determine to which island does the extrusion belong. + for (const ExPolygon& island : layer->lslices) { + islands.emplace_back(to_lines(island)); } - // backup code if islands not found - // If that happens, just make the first extrusion into island - it may be wrong, but it won't crash. - if (islands.empty() && !extrusions.empty()) { - std::vector copy(extrusions[0].second - extrusions[0].first); - for (size_t ex_line_idx = extrusions[0].first; ex_line_idx < extrusions[0].second; ++ex_line_idx) { - copy[ex_line_idx - extrusions[0].first] = layer_lines[ex_line_idx]; - } - islands.emplace_back(copy); - island_extrusions.push_back( { 0 }); - } - - // assign non external extrusions to islands - for (size_t e = 0; e < extrusions.size(); ++e) { - if (!layer_lines[extrusions[e].first].origin_entity->is_loop() || - !layer_lines[extrusions[e].first].is_external_perimeter()) { - bool island_assigned = false; - for (size_t i = 0; i < islands.size(); ++i) { - if (island_extrusions[i].empty()) { - continue; - } - size_t idx = 0; - Vec2f pt = Vec2f::Zero(); - if (islands[i].signed_distance_from_lines(layer_lines[extrusions[e].first].a, idx, pt) < 0) { - island_extrusions[i].push_back(e); - island_assigned = true; - break; - } - } - if (!island_assigned) { // If extrusion is not assigned for some reason, push it into the first island. As with the previous backup code, - // it may be wrong, but it won't crash - island_extrusions[0].push_back(e); + std::vector> island_extrusions(islands.size(), + std::vector{}); // final assigment of each extrusion to an island. + for (size_t extrusion_idx = 0; extrusion_idx < extrusions.size(); extrusion_idx++) { + Point second_point = Point::new_scale(layer_lines[extrusions[extrusion_idx].first].b); + for (size_t island_idx = 0; island_idx < islands.size(); island_idx++) { + if (islands[island_idx].signed_distance_from_lines(second_point) <= 0.0) { + island_extrusions[island_idx].push_back(extrusion_idx); } } } @@ -553,10 +481,14 @@ std::tuple reckon_islands( } Island island { }; - island.external_lines.insert(island.external_lines.end(), - layer_lines.begin() + extrusions[island_ex[0]].first, - layer_lines.begin() + extrusions[island_ex[0]].second); for (size_t extrusion_idx : island_ex) { + + if (layer_lines[extrusions[extrusion_idx].first].is_external_perimeter()) { + island.external_lines.insert(island.external_lines.end(), + layer_lines.begin() + extrusions[extrusion_idx].first, + layer_lines.begin() + extrusions[extrusion_idx].second); + } + for (size_t lidx = extrusions[extrusion_idx].first; lidx < extrusions[extrusion_idx].second; ++lidx) { line_to_island_mapping[lidx] = result.islands.size(); const ExtrusionLine &line = layer_lines[lidx]; @@ -1050,7 +982,7 @@ Issues check_global_stability(SupportGridFilter supports_presence_grid, #ifdef DETAILED_DEBUG_LOGS weakest_conn.print_info("weakest connection info: "); #endif - LinesDistancer island_lines_dist(island.external_lines); + LD island_lines_dist(island.external_lines); float unchecked_dist = params.min_distance_between_support_points + 1.0f; for (const ExtrusionLine &line : island.external_lines) { @@ -1059,12 +991,9 @@ Issues check_global_stability(SupportGridFilter supports_presence_grid, unchecked_dist += line.len; } else { unchecked_dist = line.len; - Vec2f target_point; - size_t idx; Vec3f pivot_site_search_point = to_3d(Vec2f(line.b + (line.b - line.a).normalized() * 300.0f), layer_z); - island_lines_dist.signed_distance_from_lines(pivot_site_search_point.head<2>(), idx, - target_point); + auto [dist, nidx, target_point] = island_lines_dist.signed_distance_from_lines_extra(pivot_site_search_point.head<2>()); Vec3f support_point = to_3d(target_point, layer_z); auto force = part.is_stable_while_extruding(weakest_conn, line, support_point, layer_z, params); if (force > 0) { @@ -1147,7 +1076,7 @@ std::tuple> check_extrusions_and_build_graph(c } } #endif - LinesDistancer external_lines(layer_lines); + LD external_lines(layer_lines); layer_lines.clear(); prev_layer_grid = layer_grid; @@ -1199,7 +1128,7 @@ std::tuple> check_extrusions_and_build_graph(c } } #endif - external_lines = LinesDistancer(layer_lines); + external_lines = LD(layer_lines); layer_lines.clear(); prev_layer_grid = layer_grid; } From b49a2425ca92512d4a2d0dfdb3e85817dad60dcd Mon Sep 17 00:00:00 2001 From: Pavel Mikus Date: Tue, 4 Oct 2022 19:27:15 +0200 Subject: [PATCH 5/6] Improve Lines Distancer quality, use it also in SeamPlacer --- src/libslic3r/AABBTreeLines.hpp | 20 +++++++++-- src/libslic3r/ExPolygon.hpp | 23 +++++++++++++ src/libslic3r/GCode/SeamPlacer.cpp | 53 ++++-------------------------- 3 files changed, 47 insertions(+), 49 deletions(-) diff --git a/src/libslic3r/AABBTreeLines.hpp b/src/libslic3r/AABBTreeLines.hpp index 7d6ff1ccc6..89a8a7cd58 100644 --- a/src/libslic3r/AABBTreeLines.hpp +++ b/src/libslic3r/AABBTreeLines.hpp @@ -1,6 +1,8 @@ #ifndef SRC_LIBSLIC3R_AABBTREELINES_HPP_ #define SRC_LIBSLIC3R_AABBTREELINES_HPP_ +#include "Utils.hpp" +#include "libslic3r.h" #include "libslic3r/AABBTreeIndirect.hpp" #include "libslic3r/Line.hpp" #include @@ -127,12 +129,26 @@ public: auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, nearest_line_index_out, nearest_point_out); if (distance < 0) { return {std::numeric_limits::infinity(), nearest_line_index_out, nearest_point_out}; } - distance = sqrt(distance); const LineType &line = lines[nearest_line_index_out]; Vec<2, Floating> v1 = (line.b - line.a).template cast(); Vec<2, Floating> v2 = (point - line.a).template cast(); - if ((v1.x() * v2.y()) - (v1.y() * v2.x()) > 0.0) { distance *= -1.0; } + auto d1 = (v1.x() * v2.y()) - (v1.y() * v2.x()); + + LineType second_line = line; + if ((line.a.template cast() - nearest_point_out).squaredNorm() < SCALED_EPSILON) { + second_line = lines[prev_idx_modulo(nearest_line_index_out, lines.size())]; + } else { + second_line = lines[next_idx_modulo(nearest_line_index_out, lines.size())]; + } + v1 = (second_line.b - second_line.a).template cast(); + v2 = (point - second_line.a).template cast(); + auto d2 = (v1.x() * v2.y()) - (v1.y() * v2.x()); + + auto d = abs(d1) > abs(d2) ? d1 : d2; + + if (d > 0.0) { distance *= -1.0; } + return {distance, nearest_line_index_out, nearest_point_out}; } diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index 3e42c86707..7f2aac6281 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -1,6 +1,7 @@ #ifndef slic3r_ExPolygon_hpp_ #define slic3r_ExPolygon_hpp_ +#include "Point.hpp" #include "libslic3r.h" #include "Polygon.hpp" #include "Polyline.hpp" @@ -124,6 +125,28 @@ inline Lines to_lines(const ExPolygons &src) return lines; } +inline std::vector to_linesf(const ExPolygons &src) +{ + size_t n_lines = 0; + for (ExPolygons::const_iterator it_expoly = src.begin(); it_expoly != src.end(); ++ it_expoly) { + n_lines += it_expoly->contour.points.size(); + for (size_t i = 0; i < it_expoly->holes.size(); ++ i) + n_lines += it_expoly->holes[i].points.size(); + } + std::vector lines; + lines.reserve(n_lines); + for (ExPolygons::const_iterator it_expoly = src.begin(); it_expoly != src.end(); ++ it_expoly) { + for (size_t i = 0; i <= it_expoly->holes.size(); ++ i) { + const Points &points = ((i == 0) ? it_expoly->contour : it_expoly->holes[i - 1]).points; + for (Points::const_iterator it = points.begin(); it != points.end()-1; ++it) + lines.push_back(Linef(unscaled(*it), unscaled(*(it + 1)))); + lines.push_back(Linef(unscaled(points.back()), unscaled(points.front()))); + } + } + return lines; +} + + inline Polylines to_polylines(const ExPolygon &src) { Polylines polylines; diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 926538ec9c..e18984a641 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -1,6 +1,7 @@ #include "SeamPlacer.hpp" #include "Color.hpp" +#include "Polygon.hpp" #include "PrintConfig.hpp" #include "tbb/parallel_for.h" #include "tbb/blocked_range.h" @@ -995,49 +996,6 @@ void pick_random_seam_point(const std::vector &perimeter_points, perimeter.finalized = true; } -class PerimeterDistancer { - std::vector lines; - AABBTreeIndirect::Tree<2, double> tree; - -public: - PerimeterDistancer(const Layer *layer) { - ExPolygons layer_outline = layer->lslices; - for (const ExPolygon &island : layer_outline) { - assert(island.contour.is_counter_clockwise()); - for (const auto &line : island.contour.lines()) { - lines.emplace_back(unscale(line.a), unscale(line.b)); - } - for (const Polygon &hole : island.holes) { - assert(hole.is_clockwise()); - for (const auto &line : hole.lines()) { - lines.emplace_back(unscale(line.a), unscale(line.b)); - } - } - } - tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines); - } - - float distance_from_perimeter(const Vec2f &point) const { - Vec2d p = point.cast(); - size_t hit_idx_out { }; - Vec2d hit_point_out = Vec2d::Zero(); - auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, hit_idx_out, hit_point_out); - if (distance < 0) { - return std::numeric_limits::max(); - } - - distance = sqrt(distance); - const Linef &line = lines[hit_idx_out]; - Vec2d v1 = line.b - line.a; - Vec2d v2 = p - line.a; - if ((v1.x() * v2.y()) - (v1.y() * v2.x()) > 0.0) { - distance *= -1; - } - return distance; - } -} -; - } // namespace SeamPlacerImpl // Parallel process and extract each perimeter polygon of the given print object. @@ -1089,13 +1047,14 @@ void SeamPlacer::calculate_candidates_visibility(const PrintObject *po, void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) { using namespace SeamPlacerImpl; + using PerimeterDistancer = AABBTreeLines::LinesDistancer; std::vector &layers = m_seam_per_object[po].layers; tbb::parallel_for(tbb::blocked_range(0, layers.size()), [po, &layers](tbb::blocked_range r) { std::unique_ptr prev_layer_distancer; if (r.begin() > 0) { // previous layer exists - prev_layer_distancer = std::make_unique(po->layers()[r.begin() - 1]); + prev_layer_distancer = std::make_unique(to_linesf(po->layers()[r.begin() - 1]->lslices)); } for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { @@ -1106,12 +1065,12 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) } }; bool should_compute_layer_embedding = regions_with_perimeter > 1; - std::unique_ptr current_layer_distancer = std::make_unique(po->layers()[layer_idx]); + std::unique_ptr current_layer_distancer = std::make_unique(to_linesf(po->layers()[layer_idx]->lslices)); for (SeamCandidate &perimeter_point : layers[layer_idx].points) { Vec2f point = Vec2f { perimeter_point.position.head<2>() }; if (prev_layer_distancer.get() != nullptr) { - perimeter_point.overhang = prev_layer_distancer->distance_from_perimeter(point) + perimeter_point.overhang = prev_layer_distancer->signed_distance_from_lines(point.cast()) + 0.6f * perimeter_point.perimeter.flow_width - tan(SeamPlacer::overhang_angle_threshold) * po->layers()[layer_idx]->height; @@ -1120,7 +1079,7 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) } if (should_compute_layer_embedding) { // search for embedded perimeter points (points hidden inside the print ,e.g. multimaterial join, best position for seam) - perimeter_point.embedded_distance = current_layer_distancer->distance_from_perimeter(point) + perimeter_point.embedded_distance = current_layer_distancer->signed_distance_from_lines(point.cast()) + 0.6f * perimeter_point.perimeter.flow_width; } } From e02aed31d259c030dae05fed1d5c0a5cd958a144 Mon Sep 17 00:00:00 2001 From: Pavel Mikus Date: Wed, 5 Oct 2022 14:50:22 +0200 Subject: [PATCH 6/6] Added new query to AABBTree: all primitives (triangles/lines) within radius --- src/libslic3r/AABBTreeIndirect.hpp | 60 ++++++++++++++++++++++++++- src/libslic3r/AABBTreeLines.hpp | 49 +++++++++++++++------- tests/libslic3r/test_aabbindirect.cpp | 20 +++++++++ 3 files changed, 114 insertions(+), 15 deletions(-) diff --git a/src/libslic3r/AABBTreeIndirect.hpp b/src/libslic3r/AABBTreeIndirect.hpp index 3db74b8b91..b4b74ef138 100644 --- a/src/libslic3r/AABBTreeIndirect.hpp +++ b/src/libslic3r/AABBTreeIndirect.hpp @@ -519,7 +519,7 @@ namespace detail { const VectorType origin; inline VectorType closest_point_to_origin(size_t primitive_index, - ScalarType& squared_distance){ + ScalarType& squared_distance) const { const auto &triangle = this->faces[primitive_index]; VectorType closest_point = closest_point_to_triangle(origin, this->vertices[triangle(0)].template cast(), @@ -613,6 +613,37 @@ namespace detail { return up_sqr_d; } + template + static inline void indexed_primitives_within_distance_squared_recurisve(const IndexedPrimitivesDistancerType &distancer, + size_t node_idx, + Scalar squared_distance_limit, + std::vector &found_primitives_indices) + { + const auto &node = distancer.tree.node(node_idx); + assert(node.is_valid()); + if (node.is_leaf()) { + Scalar sqr_dist; + distancer.closest_point_to_origin(node.idx, sqr_dist); + if (sqr_dist < squared_distance_limit) { found_primitives_indices.push_back(node.idx); } + } else { + size_t left_node_idx = node_idx * 2 + 1; + size_t right_node_idx = left_node_idx + 1; + const auto &node_left = distancer.tree.node(left_node_idx); + const auto &node_right = distancer.tree.node(right_node_idx); + assert(node_left.is_valid()); + assert(node_right.is_valid()); + + if (node_left.bbox.squaredExteriorDistance(distancer.origin) < squared_distance_limit) { + indexed_primitives_within_distance_squared_recurisve(distancer, left_node_idx, squared_distance_limit, + found_primitives_indices); + } + if (node_right.bbox.squaredExteriorDistance(distancer.origin) < squared_distance_limit) { + indexed_primitives_within_distance_squared_recurisve(distancer, right_node_idx, squared_distance_limit, + found_primitives_indices); + } + } + } + } // namespace detail // Build a balanced AABB Tree over an indexed triangles set, balancing the tree @@ -799,6 +830,33 @@ inline bool is_any_triangle_in_radius( return hit_point.allFinite(); } +// Returns all triangles within the given radius limit +template +inline std::vector all_triangles_in_radius( + // Indexed triangle set - 3D vertices. + const std::vector &vertices, + // Indexed triangle set - triangular faces, references to vertices. + const std::vector &faces, + // AABBTreeIndirect::Tree over vertices & faces, bounding boxes built with the accuracy of vertices. + const TreeType &tree, + // Point to which the distances on the indexed triangle set is searched for. + const VectorType &point, + //Square of maximum distance in which triangles are searched for + typename VectorType::Scalar max_distance_squared) +{ + auto distancer = detail::IndexedTriangleSetDistancer + { vertices, faces, tree, point }; + + if(tree.empty()) + { + return {}; + } + + std::vector found_triangles{}; + detail::indexed_primitives_within_distance_squared_recurisve(distancer, size_t(0), max_distance_squared, found_triangles); + return found_triangles; +} + // Traverse the tree and return the index of an entity whose bounding box // contains a given point. Returns size_t(-1) when the point is outside. diff --git a/src/libslic3r/AABBTreeLines.hpp b/src/libslic3r/AABBTreeLines.hpp index 89a8a7cd58..8432feda74 100644 --- a/src/libslic3r/AABBTreeLines.hpp +++ b/src/libslic3r/AABBTreeLines.hpp @@ -6,6 +6,7 @@ #include "libslic3r/AABBTreeIndirect.hpp" #include "libslic3r/Line.hpp" #include +#include namespace Slic3r { @@ -26,7 +27,7 @@ struct IndexedLinesDistancer { const VectorType origin; inline VectorType closest_point_to_origin(size_t primitive_index, - ScalarType &squared_distance) { + ScalarType &squared_distance) const { Vec nearest_point; const LineType &line = lines[primitive_index]; squared_distance = line_alg::distance_to_squared(line, origin.template cast(), &nearest_point); @@ -90,20 +91,35 @@ inline AABBTreeIndirect::Tree<2, typename LineType::Scalar> build_aabb_tree_over // Finding a closest line, its closest point and squared distance to the closest point // Returns squared distance to the closest point or -1 if the input is empty. template -inline typename VectorType::Scalar squared_distance_to_indexed_lines( - const std::vector &lines, - const TreeType &tree, - const VectorType &point, - size_t &hit_idx_out, - Eigen::PlainObjectBase &hit_point_out) - { - using Scalar = typename VectorType::Scalar; - auto distancer = detail::IndexedLinesDistancer - { lines, tree, point }; +inline typename VectorType::Scalar squared_distance_to_indexed_lines(const std::vector &lines, + const TreeType &tree, + const VectorType &point, + size_t &hit_idx_out, + Eigen::PlainObjectBase &hit_point_out) +{ + using Scalar = typename VectorType::Scalar; + auto distancer = detail::IndexedLinesDistancer{lines, tree, point}; return tree.empty() ? - Scalar(-1) : - AABBTreeIndirect::detail::squared_distance_to_indexed_primitives_recursive(distancer, size_t(0), Scalar(0), - std::numeric_limits::infinity(), hit_idx_out, hit_point_out); + Scalar(-1) : + AABBTreeIndirect::detail::squared_distance_to_indexed_primitives_recursive(distancer, size_t(0), Scalar(0), + std::numeric_limits::infinity(), + hit_idx_out, hit_point_out); +} + +// Returns all lines within the given radius limit +template +inline std::vector all_lines_in_radius(const std::vector &lines, + const TreeType &tree, + const VectorType &point, + typename VectorType::Scalar max_distance_squared) +{ + auto distancer = detail::IndexedLinesDistancer{lines, tree, point}; + + if (tree.empty()) { return {}; } + + std::vector found_lines{}; + AABBTreeIndirect::detail::indexed_primitives_within_distance_squared_recurisve(distancer, size_t(0), max_distance_squared, found_lines); + return found_lines; } template class LinesDistancer @@ -158,6 +174,11 @@ public: return dist; } + std::vector all_lines_in_radius(const Vec<2, typename LineType::Scalar> &point, Floating radius) + { + return all_lines_in_radius(this->lines, this->tree, point, radius * radius); + } + const LineType &get_line(size_t line_idx) const { return lines[line_idx]; } const std::vector &get_lines() const { return lines; } diff --git a/tests/libslic3r/test_aabbindirect.cpp b/tests/libslic3r/test_aabbindirect.cpp index 87cf80943a..def349042e 100644 --- a/tests/libslic3r/test_aabbindirect.cpp +++ b/tests/libslic3r/test_aabbindirect.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -87,6 +88,25 @@ TEST_CASE("Creating a several 2d lines, testing closest point query", "[AABBIndi REQUIRE(hit_point_out.y() == Approx(0.5)); } +TEST_CASE("Creating a several 2d lines, testing all lines in radius query", "[AABBIndirect]") +{ + std::vector lines { }; + lines.push_back(Linef(Vec2d(0.0, 0.0), Vec2d(10.0, 0.0))); + lines.push_back(Linef(Vec2d(-10.0, 10.0), Vec2d(10.0, -10.0))); + lines.push_back(Linef(Vec2d(-2.0, -1.0), Vec2d(-2.0, 1.0))); + lines.push_back(Linef(Vec2d(-1.0, -1.0), Vec2d(-1.0, -1.0))); + lines.push_back(Linef(Vec2d(1.0, 1.0), Vec2d(1.0, 1.0))); + + auto tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines); + + auto indices = AABBTreeLines::all_lines_in_radius(lines, tree, Vec2d{1.0,1.0}, 4.0); + + REQUIRE(std::find(indices.begin(),indices.end(), 0) != indices.end()); + REQUIRE(std::find(indices.begin(),indices.end(), 1) != indices.end()); + REQUIRE(std::find(indices.begin(),indices.end(), 4) != indices.end()); + REQUIRE(indices.size() == 3); +} + #if 0 #include "libslic3r/EdgeGrid.hpp" #include