From 3721bf802a6d449a21c7f7bc630faeabfe53e28a Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 24 Jan 2024 09:54:35 +0100 Subject: [PATCH 1/7] Fix Scripta integration --- src/slicer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slicer.cpp b/src/slicer.cpp index 22040b1480..b608bef85d 100644 --- a/src/slicer.cpp +++ b/src/slicer.cpp @@ -12,6 +12,7 @@ #include "Application.h" #include "Slice.h" +#include "raft.h" #include "plugins/slots.h" #include "settings/AdaptiveLayerHeights.h" #include "settings/EnumSettings.h" @@ -824,7 +825,8 @@ Slicer::Slicer(Mesh* i_mesh, const coord_t thickness, const size_t slice_layer_c mesh->settings_.get("raft_interface_thickness"), mesh->settings_.get("raft_base_thickness"), mesh->settings_.get("raft_airgap"), - mesh->settings_.get("layer_0_z_overlap")); + mesh->settings_.get("layer_0_z_overlap"), + Raft::getFillerLayerCount()); std::vector> zbbox = buildZHeightsForFaces(*mesh); From db72e720c0872fc23a68d39d8ddc42e428a08b8a Mon Sep 17 00:00:00 2001 From: wawanbreton Date: Wed, 24 Jan 2024 08:55:05 +0000 Subject: [PATCH 2/7] Applied clang-format. --- src/slicer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slicer.cpp b/src/slicer.cpp index b608bef85d..d13908458f 100644 --- a/src/slicer.cpp +++ b/src/slicer.cpp @@ -12,8 +12,8 @@ #include "Application.h" #include "Slice.h" -#include "raft.h" #include "plugins/slots.h" +#include "raft.h" #include "settings/AdaptiveLayerHeights.h" #include "settings/EnumSettings.h" #include "settings/types/LayerIndex.h" From 41a80297aedb7e10780df0f4d184e9dc886052a8 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 24 Jan 2024 11:15:42 +0100 Subject: [PATCH 3/7] Fix Scripta integration --- src/SkeletalTrapezoidation.cpp | 50 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/SkeletalTrapezoidation.cpp b/src/SkeletalTrapezoidation.cpp index 887059324d..d31aa52ce9 100644 --- a/src/SkeletalTrapezoidation.cpp +++ b/src/SkeletalTrapezoidation.cpp @@ -544,27 +544,27 @@ void SkeletalTrapezoidation::generateToolpaths(std::vector& scripta::CellVDI{ "is_central", [](const auto& edge) { - return static_cast(edge.data.is_central); + return static_cast(edge.data_.is_central); } }, scripta::CellVDI{ "type", [](const auto& edge) { - return static_cast(edge.data.type); + return static_cast(edge.data_.type_); } }, scripta::PointVDI{ "distance_to_boundary", [](const auto& node) { - return node->data.distance_to_boundary; + return node->data_.distance_to_boundary_; } }, scripta::PointVDI{ "bead_count", [](const auto& node) { - return node->data.bead_count; + return node->data_.bead_count_; } }, scripta::PointVDI{ "transition_ratio", [](const auto& node) { - return node->data.transition_ratio; + return node->data_.transition_ratio_; } }); filterNoncentralRegions(); @@ -576,27 +576,27 @@ void SkeletalTrapezoidation::generateToolpaths(std::vector& scripta::CellVDI{ "is_central", [](const auto& edge) { - return static_cast(edge.data.is_central); + return static_cast(edge.data_.is_central); } }, scripta::CellVDI{ "type", [](const auto& edge) { - return static_cast(edge.data.type); + return static_cast(edge.data_.type_); } }, scripta::PointVDI{ "distance_to_boundary", [](const auto& node) { - return node->data.distance_to_boundary; + return node->data_.distance_to_boundary_; } }, scripta::PointVDI{ "bead_count", [](const auto& node) { - return node->data.bead_count; + return node->data_.bead_count_; } }, scripta::PointVDI{ "transition_ratio", [](const auto& node) { - return node->data.transition_ratio; + return node->data_.transition_ratio_; } }); generateTransitioningRibs(); @@ -608,27 +608,27 @@ void SkeletalTrapezoidation::generateToolpaths(std::vector& scripta::CellVDI{ "is_central", [](const auto& edge) { - return static_cast(edge.data.is_central); + return static_cast(edge.data_.is_central); } }, scripta::CellVDI{ "type", [](const auto& edge) { - return static_cast(edge.data.type); + return static_cast(edge.data_.type_); } }, scripta::PointVDI{ "distance_to_boundary", [](const auto& node) { - return node->data.distance_to_boundary; + return node->data_.distance_to_boundary_; } }, scripta::PointVDI{ "bead_count", [](const auto& node) { - return node->data.bead_count; + return node->data_.bead_count_; } }, scripta::PointVDI{ "transition_ratio", [](const auto& node) { - return node->data.transition_ratio; + return node->data_.transition_ratio_; } }); generateExtraRibs(); @@ -640,27 +640,27 @@ void SkeletalTrapezoidation::generateToolpaths(std::vector& scripta::CellVDI{ "is_central", [](const auto& edge) { - return static_cast(edge.data.is_central); + return static_cast(edge.data_.is_central); } }, scripta::CellVDI{ "type", [](const auto& edge) { - return static_cast(edge.data.type); + return static_cast(edge.data_.type_); } }, scripta::PointVDI{ "distance_to_boundary", [](const auto& node) { - return node->data.distance_to_boundary; + return node->data_.distance_to_boundary_; } }, scripta::PointVDI{ "bead_count", [](const auto& node) { - return node->data.bead_count; + return node->data_.bead_count_; } }, scripta::PointVDI{ "transition_ratio", [](const auto& node) { - return node->data.transition_ratio; + return node->data_.transition_ratio_; } }); generateSegments(); @@ -672,27 +672,27 @@ void SkeletalTrapezoidation::generateToolpaths(std::vector& scripta::CellVDI{ "is_central", [](const auto& edge) { - return static_cast(edge.data.is_central); + return static_cast(edge.data_.is_central); } }, scripta::CellVDI{ "type", [](const auto& edge) { - return static_cast(edge.data.type); + return static_cast(edge.data_.type_); } }, scripta::PointVDI{ "distance_to_boundary", [](const auto& node) { - return node->data.distance_to_boundary; + return node->data_.distance_to_boundary_; } }, scripta::PointVDI{ "bead_count", [](const auto& node) { - return node->data.bead_count; + return node->data_.bead_count_; } }, scripta::PointVDI{ "transition_ratio", [](const auto& node) { - return node->data.transition_ratio; + return node->data_.transition_ratio_; } }); } From bc297b70b02dc14dd8e9e95d7b1bd68028ef260e Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 24 Jan 2024 11:24:53 +0100 Subject: [PATCH 4/7] Apply C++ good practices --- include/PathOrder.h | 11 ++++++++++- include/PathOrderMonotonic.h | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/PathOrder.h b/include/PathOrder.h index bd95594ee7..7fd338fbfc 100644 --- a/include/PathOrder.h +++ b/include/PathOrder.h @@ -42,7 +42,7 @@ class PathOrder * The location where the nozzle is assumed to start from before printing * these parts. */ - Point2LL start_point_; + const Point2LL start_point_; /*! * Seam settings. @@ -97,6 +97,15 @@ class PathOrder */ constexpr static coord_t coincident_point_distance_ = 10; + /*! + * \brief Basic constructor with a given start point + * \param start_point The location where the nozzle is assumed to start + * from before printing these parts. + */ + PathOrder(const Point2LL& start_point) + : start_point_(start_point) + { + } /*! * In the current set of paths, detect all loops and mark them as such. diff --git a/include/PathOrderMonotonic.h b/include/PathOrderMonotonic.h index 356eb248f5..2b8aa5dfc1 100644 --- a/include/PathOrderMonotonic.h +++ b/include/PathOrderMonotonic.h @@ -45,11 +45,11 @@ class PathOrderMonotonic : public PathOrder using PathOrder::coincident_point_distance_; PathOrderMonotonic(const AngleRadians monotonic_direction, const coord_t max_adjacent_distance, const Point2LL start_point) + : PathOrder(start_point) // The monotonic vector needs to rotate clockwise instead of counter-clockwise, the same as how the infill patterns are generated. - : monotonic_vector_(-std::cos(monotonic_direction) * monotonic_vector_resolution_, std::sin(monotonic_direction) * monotonic_vector_resolution_) + , monotonic_vector_(-std::cos(monotonic_direction) * monotonic_vector_resolution_, std::sin(monotonic_direction) * monotonic_vector_resolution_) , max_adjacent_distance_(max_adjacent_distance) { - this->start_point_ = start_point; } void optimize() From 96d0a2e45b12a2140060e1b0c8847b18ff7ca8ea Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 24 Jan 2024 11:52:39 +0100 Subject: [PATCH 5/7] Apply monotonic ordering in raft surface layer --- src/FffGcodeWriter.cpp | 195 ++++++++++++++++++++++++----------------- 1 file changed, 117 insertions(+), 78 deletions(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 30d85f2386..a6782627ab 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -22,6 +22,7 @@ #include "FffProcessor.h" #include "InsetOrderOptimizer.h" #include "LayerPlan.h" +#include "PathOrderMonotonic.h" //Monotonic ordering of skin lines. #include "Slice.h" #include "WallToolPaths.h" #include "bridge.h" @@ -907,6 +908,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) const coord_t surface_line_width = surface_settings.get("raft_surface_line_width"); const coord_t surface_avoid_distance = surface_settings.get("travel_avoid_distance"); const Ratio surface_fan_speed = surface_settings.get("raft_surface_fan_speed"); + const bool surface_monotonic = surface_settings.get("raft_surface_monotonic"); for (LayerIndex raft_surface_layer = 1; static_cast(raft_surface_layer) <= num_surface_layers; raft_surface_layer++) { // raft surface layers @@ -965,7 +967,9 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) const size_t wall_line_count = surface_settings.get("raft_surface_wall_count"); const coord_t small_area_width = 0; // A raft never has a small region due to the large horizontal expansion. const Point2LL& infill_origin = Point2LL(); - constexpr bool skip_stitching = false; + const GCodePathConfig& config = gcode_layer.configs_storage_.raft_surface_config; + const bool monotonic = (raft_surface_layer == num_surface_layers && surface_monotonic); + const bool skip_stitching = monotonic; constexpr bool connected_zigzags = false; constexpr bool connect_polygons = false; // midway connections between polygons can make the surface less smooth constexpr bool use_endpieces = true; @@ -979,88 +983,123 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) raft_outline_path = raft_outline_path.difference(storage.primeTower.getOuterPoly(layer_nr)); } - Infill infill_comp( - EFillMethod::ZIG_ZAG, - zig_zaggify_infill, - connect_polygons, - raft_outline_path, - infill_outline_width, - surface_line_spacing, - fill_overlap, - infill_multiplier, - fill_angle, - z, - extra_infill_shift, - surface_max_resolution, - surface_max_deviation, - wall_line_count, - small_area_width, - infill_origin, - skip_stitching, - fill_gaps, - connected_zigzags, - use_endpieces, - skip_some_zags, - zag_skip_count, - pocket_size); - - std::vector raft_paths; - infill_comp.generate(raft_paths, raft_polygons, raft_lines, surface_settings, layer_nr, SectionType::ADHESION); - - if (! raft_paths.empty()) + std::vector raft_islands; + if(monotonic) { - const GCodePathConfig& config = gcode_layer.configs_storage_.raft_surface_config; - const ZSeamConfig z_seam_config(EZSeamType::SHORTEST, gcode_layer.getLastPlannedPositionOrStartingPosition(), EZSeamCornerPrefType::Z_SEAM_CORNER_PREF_NONE, false); - InsetOrderOptimizer wall_orderer( - *this, - storage, - gcode_layer, - surface_settings, - surface_extruder_nr, - config, - config, - config, - config, - retract_before_outer_wall, - wipe_dist, - wipe_dist, - surface_extruder_nr, - surface_extruder_nr, - z_seam_config, - raft_paths); - wall_orderer.addToLayer(); + // When using monotonic infill, process islands separately otherwise multiple rafts + // will be printed in parallel in a global monotonic order, which doesn't look good + for(const PolygonRef raft_island : raft_outline_path) + { + Polygons island; + island.add(raft_island); + raft_islands.emplace_back(island); + } + } + else + { + raft_islands.emplace_back(raft_outline_path); } - const auto wipe_dist = 0; - const auto spiralize = false; - const auto flow_ratio = 1.0_r; - const auto enable_travel_optimization = false; - const auto always_retract = false; - const auto reverse_order = false; + for(const Polygons raft_island : raft_islands) + { + Infill infill_comp( + EFillMethod::ZIG_ZAG, + zig_zaggify_infill, + connect_polygons, + raft_island, + infill_outline_width, + surface_line_spacing, + fill_overlap, + infill_multiplier, + fill_angle, + z, + extra_infill_shift, + surface_max_resolution, + surface_max_deviation, + wall_line_count, + small_area_width, + infill_origin, + skip_stitching, + fill_gaps, + connected_zigzags, + use_endpieces, + skip_some_zags, + zag_skip_count, + pocket_size); - gcode_layer.addLinesByOptimizer( - raft_lines, - gcode_layer.configs_storage_.raft_surface_config, - SpaceFillType::Lines, - enable_travel_optimization, - wipe_dist, - flow_ratio, - last_planned_position); - last_planned_position = gcode_layer.getLastPlannedPositionOrStartingPosition(); - gcode_layer.addPolygonsByOptimizer( - raft_polygons, - gcode_layer.configs_storage_.raft_surface_config, - ZSeamConfig(), - wipe_dist, - spiralize, - flow_ratio, - always_retract, - reverse_order, - last_planned_position); - last_planned_position = gcode_layer.getLastPlannedPositionOrStartingPosition(); + std::vector raft_paths; + infill_comp.generate(raft_paths, raft_polygons, raft_lines, surface_settings, layer_nr, SectionType::ADHESION); - raft_polygons.clear(); - raft_lines.clear(); + if (! raft_paths.empty()) + { + const ZSeamConfig z_seam_config(EZSeamType::SHORTEST, gcode_layer.getLastPlannedPositionOrStartingPosition(), EZSeamCornerPrefType::Z_SEAM_CORNER_PREF_NONE, false); + InsetOrderOptimizer wall_orderer( + *this, + storage, + gcode_layer, + surface_settings, + surface_extruder_nr, + config, + config, + config, + config, + retract_before_outer_wall, + wipe_dist, + wipe_dist, + surface_extruder_nr, + surface_extruder_nr, + z_seam_config, + raft_paths); + wall_orderer.addToLayer(); + } + + const auto wipe_dist = 0; + const auto spiralize = false; + const auto flow_ratio = 1.0_r; + const auto enable_travel_optimization = false; + const auto always_retract = false; + const auto reverse_order = false; + + if(monotonic) + { + const AngleRadians monotonic_direction = fill_angle; + constexpr SpaceFillType space_fill_type = SpaceFillType::PolyLines; + const coord_t max_adjacent_distance = surface_line_spacing; + + gcode_layer.addLinesMonotonic(raft_island, + raft_lines, + config, + space_fill_type, + monotonic_direction, + max_adjacent_distance); + } + else + { + gcode_layer.addLinesByOptimizer( + raft_lines, + gcode_layer.configs_storage_.raft_surface_config, + SpaceFillType::Lines, + enable_travel_optimization, + wipe_dist, + flow_ratio, + last_planned_position); + last_planned_position = gcode_layer.getLastPlannedPositionOrStartingPosition(); + gcode_layer.addPolygonsByOptimizer( + raft_polygons, + gcode_layer.configs_storage_.raft_surface_config, + ZSeamConfig(), + wipe_dist, + spiralize, + flow_ratio, + always_retract, + reverse_order, + last_planned_position); + last_planned_position = gcode_layer.getLastPlannedPositionOrStartingPosition(); + } + + raft_polygons.clear(); + raft_lines.clear(); + } if (! prime_tower_added_on_this_layer) { From 891cd45682a3e99c37bcc2a375749a46e5e4f9dd Mon Sep 17 00:00:00 2001 From: wawanbreton Date: Wed, 24 Jan 2024 10:53:29 +0000 Subject: [PATCH 6/7] Applied clang-format. --- src/FffGcodeWriter.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index a6782627ab..bbb4b7c10c 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -984,11 +984,11 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) } std::vector raft_islands; - if(monotonic) + if (monotonic) { // When using monotonic infill, process islands separately otherwise multiple rafts // will be printed in parallel in a global monotonic order, which doesn't look good - for(const PolygonRef raft_island : raft_outline_path) + for (const PolygonRef raft_island : raft_outline_path) { Polygons island; island.add(raft_island); @@ -1000,7 +1000,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) raft_islands.emplace_back(raft_outline_path); } - for(const Polygons raft_island : raft_islands) + for (const Polygons raft_island : raft_islands) { Infill infill_comp( EFillMethod::ZIG_ZAG, @@ -1060,18 +1060,13 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) const auto always_retract = false; const auto reverse_order = false; - if(monotonic) + if (monotonic) { const AngleRadians monotonic_direction = fill_angle; constexpr SpaceFillType space_fill_type = SpaceFillType::PolyLines; const coord_t max_adjacent_distance = surface_line_spacing; - gcode_layer.addLinesMonotonic(raft_island, - raft_lines, - config, - space_fill_type, - monotonic_direction, - max_adjacent_distance); + gcode_layer.addLinesMonotonic(raft_island, raft_lines, config, space_fill_type, monotonic_direction, max_adjacent_distance); } else { From d9795005f4fc7ba48a015f40c73b88751a598858 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 24 Jan 2024 12:55:59 +0100 Subject: [PATCH 7/7] Fix unit tests --- tests/integration/SlicePhaseTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/SlicePhaseTest.cpp b/tests/integration/SlicePhaseTest.cpp index 95fd638fa1..de814b5099 100644 --- a/tests/integration/SlicePhaseTest.cpp +++ b/tests/integration/SlicePhaseTest.cpp @@ -44,6 +44,7 @@ class SlicePhaseTest : public testing::Test scene.settings.add("raft_interface_layers", "1"); scene.settings.add("raft_surface_thickness", "0.2"); scene.settings.add("raft_surface_layers", "1"); + scene.settings.add("raft_surface_extruder_nr", "0"); scene.settings.add("magic_mesh_surface_mode", "normal"); scene.settings.add("meshfix_extensive_stitching", "false"); scene.settings.add("meshfix_keep_open_polygons", "false");