From 3721bf802a6d449a21c7f7bc630faeabfe53e28a Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 24 Jan 2024 09:54:35 +0100 Subject: [PATCH 01/34] 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 02/34] 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 03/34] 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 04/34] 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 05/34] 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 06/34] 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 07/34] 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"); From 9ab1c821a88c2823d90fb68d4f2e0a6882988d03 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 26 Jan 2024 13:37:12 +0100 Subject: [PATCH 08/34] Implement basic roofing logic Lot of annoying routing of the new config CURA-11129 --- include/InsetOrderOptimizer.h | 6 +++- include/LayerPlan.h | 16 ++++++++-- src/FffGcodeWriter.cpp | 57 +++++++++++++++++++++++++++++------ src/InsetOrderOptimizer.cpp | 15 ++++++--- src/LayerPlan.cpp | 37 +++++++++++++++++++++-- src/TopSurface.cpp | 4 ++- 6 files changed, 115 insertions(+), 20 deletions(-) diff --git a/include/InsetOrderOptimizer.h b/include/InsetOrderOptimizer.h index e813a134af..a0734c3ea6 100644 --- a/include/InsetOrderOptimizer.h +++ b/include/InsetOrderOptimizer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Ultimaker B.V. +// Copyright (c) 2024 Ultimaker B.V. // CuraEngine is released under the terms of the AGPLv3 or higher #ifndef INSET_ORDER_OPTIMIZER_H @@ -45,6 +45,8 @@ class InsetOrderOptimizer const int extruder_nr, const GCodePathConfig& inset_0_non_bridge_config, const GCodePathConfig& inset_X_non_bridge_config, + const GCodePathConfig& inset_0_roofing_config, + const GCodePathConfig& inset_X_roofing_config, const GCodePathConfig& inset_0_bridge_config, const GCodePathConfig& inset_X_bridge_config, const bool retract_before_outer_wall, @@ -92,6 +94,8 @@ class InsetOrderOptimizer const size_t extruder_nr_; const GCodePathConfig& inset_0_non_bridge_config_; const GCodePathConfig& inset_X_non_bridge_config_; + const GCodePathConfig& inset_0_roofing_config_; + const GCodePathConfig& inset_X_roofing_config_; const GCodePathConfig& inset_0_bridge_config_; const GCodePathConfig& inset_X_bridge_config_; const bool retract_before_outer_wall_; diff --git a/include/LayerPlan.h b/include/LayerPlan.h index 1d3b3628a3..34173ef331 100644 --- a/include/LayerPlan.h +++ b/include/LayerPlan.h @@ -1,4 +1,4 @@ -// Copyright (c) 2023 UltiMaker +// Copyright (c) 2024 UltiMaker // CuraEngine is released under the terms of the AGPLv3 or higher #ifndef LAYER_PLAN_H @@ -96,6 +96,7 @@ class LayerPlan : public NoCopy coord_t comb_move_inside_distance_; //!< Whenever using the minimum boundary for combing it tries to move the coordinates inside by this distance after calculating the combing. Polygons bridge_wall_mask_; //!< The regions of a layer part that are not supported, used for bridging Polygons overhang_mask_; //!< The regions of a layer part where the walls overhang + Polygons roofing_mask_; //!< The regions of a layer part where the walls are exposed to the air const std::vector fan_speed_layer_time_settings_per_extruder_; @@ -257,6 +258,13 @@ class LayerPlan : public NoCopy */ void setOverhangMask(const Polygons& polys); + /*! + * Set roofing_mask. + * + * \param polys The areas of the part currently being processed that will require roofing. + */ + void setRoofingMask(const Polygons& polys); + /*! * Travel to a certain point, with all of the procedures necessary to do so. * @@ -414,6 +422,7 @@ class LayerPlan : public NoCopy const Point2LL& p1, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, double flow, const Ratio width_factor, @@ -441,6 +450,7 @@ class LayerPlan : public NoCopy int start_idx, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, double flow_ratio, @@ -470,6 +480,7 @@ class LayerPlan : public NoCopy int start_idx, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, double flow_ratio, @@ -502,6 +513,7 @@ class LayerPlan : public NoCopy const Polygons& walls, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, const ZSeamConfig& z_seam_config = ZSeamConfig(), coord_t wall_0_wipe_dist = 0, @@ -625,7 +637,7 @@ class LayerPlan : public NoCopy return start_idx; } - Polygons air_below(bridge_wall_mask_.unionPolygons(overhang_mask_)); + const auto air_below = bridge_wall_mask_.unionPolygons(overhang_mask_); unsigned curr_idx = start_idx; diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index bbb4b7c10c..4289026f86 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023 UltiMaker +// Copyright (c) 2024 UltiMaker // CuraEngine is released under the terms of the AGPLv3 or higher #include "FffGcodeWriter.h" @@ -690,6 +690,8 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, @@ -851,6 +853,8 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, @@ -1043,6 +1047,8 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, @@ -2239,6 +2245,8 @@ bool FffGcodeWriter::processSingleLayerInfill( mesh_config.infill_config[0], mesh_config.infill_config[0], mesh_config.infill_config[0], + mesh_config.infill_config[0], + mesh_config.infill_config[0], retract_before_outer_wall, wipe_dist, wipe_dist, @@ -2587,6 +2595,28 @@ bool FffGcodeWriter::processInsets( Polygons overhang_region = part.outline.offset(-half_outer_wall_width).difference(outlines_below.offset(10 + overhang_width - half_outer_wall_width)).offset(10); gcode_layer.setOverhangMask(overhang_region); } + + const auto roofing_mask = [&gcode_layer, &mesh, &boundaryBox]() -> Polygons + { + const size_t roofing_layer_count = std::min(mesh.settings.get("roofing_layer_count"), mesh.settings.get("top_layers")); + + if (gcode_layer.getLayerNr() + roofing_layer_count >= mesh.layers.size()) + { + return Polygons(); + } + + auto roofing_mask = Polygons(); + for (const auto& layer_part : mesh.layers[gcode_layer.getLayerNr() + roofing_layer_count].parts) + { + if (boundaryBox.hit(layer_part.boundaryBox)) + { + roofing_mask.add(layer_part.outline); + } + } + return roofing_mask.offset(100); + }(); + + gcode_layer.setRoofingMask(roofing_mask); } else { @@ -2594,6 +2624,8 @@ bool FffGcodeWriter::processInsets( gcode_layer.setBridgeWallMask(Polygons()); // clear to disable overhang detection gcode_layer.setOverhangMask(Polygons()); + // clear to disable use of roofing settings + gcode_layer.setRoofingMask(Polygons()); } if (spiralize && extruder_nr == mesh.settings.get("wall_0_extruder_nr").extruder_nr_ && ! part.spiral_wall.empty()) @@ -2611,16 +2643,11 @@ bool FffGcodeWriter::processInsets( else { // Print the spiral walls of other parts as single walls without Z gradient. - gcode_layer.addWalls(part.spiral_wall, mesh.settings, mesh_config.inset0_config, mesh_config.inset0_config); + gcode_layer.addWalls(part.spiral_wall, mesh.settings, mesh_config.inset0_config, mesh_config.inset0_config, mesh_config.inset0_config); } } else { - // TODO use roofing config for layers-parts that are exposed to air - auto use_roofing_config = false; - const GCodePathConfig& inset0_config = use_roofing_config ? mesh_config.inset0_roofing_config : mesh_config.inset0_config; - const GCodePathConfig& insetX_config = use_roofing_config ? mesh_config.insetX_roofing_config : mesh_config.insetX_config; - // Main case: Optimize the insets with the InsetOrderOptimizer. const coord_t wall_x_wipe_dist = 0; const ZSeamConfig z_seam_config( @@ -2634,8 +2661,10 @@ bool FffGcodeWriter::processInsets( gcode_layer, mesh.settings, extruder_nr, - inset0_config, - insetX_config, + mesh_config.inset0_config, + mesh_config.insetX_config, + mesh_config.inset0_roofing_config, + mesh_config.insetX_roofing_config, mesh_config.bridge_inset0_config, mesh_config.bridge_insetX_config, mesh.settings.get("travel_retract_before_outer_wall"), @@ -3061,6 +3090,8 @@ void FffGcodeWriter::processSkinPrintFeature( config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, @@ -3324,6 +3355,8 @@ bool FffGcodeWriter::processSupportInfill(const SliceDataStorage& storage, Layer config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, @@ -3500,6 +3533,8 @@ bool FffGcodeWriter::processSupportInfill(const SliceDataStorage& storage, Layer config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, @@ -3636,6 +3671,8 @@ bool FffGcodeWriter::addSupportRoofsToGCode( config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, @@ -3747,6 +3784,8 @@ bool FffGcodeWriter::addSupportBottomsToGCode(const SliceDataStorage& storage, L config, config, config, + config, + config, retract_before_outer_wall, wipe_dist, wipe_dist, diff --git a/src/InsetOrderOptimizer.cpp b/src/InsetOrderOptimizer.cpp index 88a550c11f..976504cd6a 100644 --- a/src/InsetOrderOptimizer.cpp +++ b/src/InsetOrderOptimizer.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023 UltiMaker +// Copyright (c) 2024 UltiMaker // CuraEngine is released under the terms of the AGPLv3 or higher #include "InsetOrderOptimizer.h" @@ -40,6 +40,8 @@ InsetOrderOptimizer::InsetOrderOptimizer( const int extruder_nr, const GCodePathConfig& inset_0_non_bridge_config, const GCodePathConfig& inset_X_non_bridge_config, + const GCodePathConfig& inset_0_roofing_config, + const GCodePathConfig& inset_X_roofing_config, const GCodePathConfig& inset_0_bridge_config, const GCodePathConfig& inset_X_bridge_config, const bool retract_before_outer_wall, @@ -56,6 +58,8 @@ InsetOrderOptimizer::InsetOrderOptimizer( , extruder_nr_(extruder_nr) , inset_0_non_bridge_config_(inset_0_non_bridge_config) , inset_X_non_bridge_config_(inset_X_non_bridge_config) + , inset_0_roofing_config_(inset_0_roofing_config) + , inset_X_roofing_config_(inset_X_roofing_config) , inset_0_bridge_config_(inset_0_bridge_config) , inset_X_bridge_config_(inset_X_bridge_config) , retract_before_outer_wall_(retract_before_outer_wall) @@ -114,23 +118,26 @@ bool InsetOrderOptimizer::addToLayer() for (const PathOrdering& path : order_optimizer.paths_) { if (path.vertices_->empty()) + { continue; + } const bool is_outer_wall = path.vertices_->inset_idx_ == 0; // or thin wall 'gap filler' const bool is_gap_filler = path.vertices_->is_odd_; const GCodePathConfig& non_bridge_config = is_outer_wall ? inset_0_non_bridge_config_ : inset_X_non_bridge_config_; + const GCodePathConfig& roofing_config = is_outer_wall ? inset_0_roofing_config_ : inset_X_roofing_config_; const GCodePathConfig& bridge_config = is_outer_wall ? inset_0_bridge_config_ : inset_X_bridge_config_; const coord_t wipe_dist = is_outer_wall && ! is_gap_filler ? wall_0_wipe_dist_ : wall_x_wipe_dist_; const bool retract_before = is_outer_wall ? retract_before_outer_wall_ : false; - const bool revert_inset = alternate_walls && (path.vertices_->inset_idx_ % 2); - const bool revert_layer = alternate_walls && (layer_nr_ % 2); + const bool revert_inset = alternate_walls && (path.vertices_->inset_idx_ % 2 != 0); + const bool revert_layer = alternate_walls && (layer_nr_ % 2 != 0); const bool backwards = path.backwards_ != (revert_inset != revert_layer); const size_t start_index = (backwards != path.backwards_) ? path.vertices_->size() - (path.start_vertex_ + 1) : path.start_vertex_; const bool linked_path = ! path.is_closed_; gcode_layer_.setIsInside(true); // Going to print walls, which are always inside. - gcode_layer_.addWall(*path.vertices_, start_index, settings_, non_bridge_config, bridge_config, wipe_dist, flow, retract_before, path.is_closed_, backwards, linked_path); + gcode_layer_.addWall(*path.vertices_, start_index, settings_, non_bridge_config, roofing_config, bridge_config, wipe_dist, flow, retract_before, path.is_closed_, backwards, linked_path); added_something = true; } return added_something; diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index 4f498caffd..b80251a715 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -647,6 +647,7 @@ void LayerPlan::addWallLine( const Point2LL& p1, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, double flow, const Ratio width_factor, @@ -760,7 +761,28 @@ void LayerPlan::addWallLine( } }; - if (bridge_wall_mask_.empty()) + const auto use_roofing_config = [&]() -> bool + { + if (roofing_config == non_bridge_config) + { + // if the roofing config and normal config are the same any way there is no need to check what part of the line segment + return false; + } + return roofing_mask_.empty() || PolygonUtils::polygonCollidesWithLineSegment(roofing_mask_, p0, p1) || !roofing_mask_.inside(p1, true); + }(); + + if (use_roofing_config) + { + addExtrusionMove( + p1, + roofing_config, + SpaceFillType::Polygons, + flow, + width_factor, + spiralize, + 1.0_r); + } + else if (bridge_wall_mask_.empty()) { // no bridges required addExtrusionMove( @@ -867,6 +889,7 @@ void LayerPlan::addWall( int start_idx, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, double flow_ratio, @@ -895,7 +918,7 @@ void LayerPlan::addWall( constexpr bool is_closed = true; constexpr bool is_reversed = false; constexpr bool is_linked_path = false; - addWall(ewall, start_idx, settings, non_bridge_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract, is_closed, is_reversed, is_linked_path); + addWall(ewall, start_idx, settings, non_bridge_config, roofing_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract, is_closed, is_reversed, is_linked_path); } void LayerPlan::addWall( @@ -903,6 +926,7 @@ void LayerPlan::addWall( int start_idx, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, double flow_ratio, @@ -1094,6 +1118,7 @@ void LayerPlan::addWall( destination, settings, non_bridge_config, + roofing_config, bridge_config, flow_ratio, line_width * nominal_line_width_multiplier, @@ -1168,6 +1193,7 @@ void LayerPlan::addWalls( const Polygons& walls, const Settings& settings, const GCodePathConfig& non_bridge_config, + const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, const ZSeamConfig& z_seam_config, coord_t wall_0_wipe_dist, @@ -1183,7 +1209,7 @@ void LayerPlan::addWalls( orderOptimizer.optimize(); for (const PathOrdering& path : orderOptimizer.paths_) { - addWall(**path.vertices_, path.start_vertex_, settings, non_bridge_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract); + addWall(**path.vertices_, path.start_vertex_, settings, non_bridge_config, roofing_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract); } } @@ -2489,4 +2515,9 @@ void LayerPlan::setOverhangMask(const Polygons& polys) overhang_mask_ = polys; } +void LayerPlan::setRoofingMask(const Polygons& polys) +{ + roofing_mask_ = polys; +} + } // namespace cura diff --git a/src/TopSurface.cpp b/src/TopSurface.cpp index acbbe94f7d..a717ccb3bb 100644 --- a/src/TopSurface.cpp +++ b/src/TopSurface.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023 UltiMaker +// Copyright (c) 2024 UltiMaker // CuraEngine is released under the terms of the AGPLv3 or higher #include "TopSurface.h" @@ -176,6 +176,8 @@ bool TopSurface::ironing(const SliceDataStorage& storage, const SliceMeshStorage line_config, line_config, line_config, + line_config, + line_config, retract_before_outer_wall, wipe_dist, wipe_dist, From 8298f8e0ab5a9e10609ac7b46d32f519d74d9790 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 26 Jan 2024 15:01:52 +0100 Subject: [PATCH 09/34] Cut up line segments that are partially within the roofing area CURA-11129 --- src/FffGcodeWriter.cpp | 2 +- src/LayerPlan.cpp | 58 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 4289026f86..caf425ca75 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -2613,7 +2613,7 @@ bool FffGcodeWriter::processInsets( roofing_mask.add(layer_part.outline); } } - return roofing_mask.offset(100); + return roofing_mask; }(); gcode_layer.setRoofingMask(roofing_mask); diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index b80251a715..894972259e 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -642,6 +642,8 @@ void LayerPlan::addPolygonsByOptimizer( static constexpr double max_non_bridge_line_volume = MM2INT(100); // limit to accumulated "volume" of non-bridge lines which is proportional to distance x extrusion rate +static int i = 0; + void LayerPlan::addWallLine( const Point2LL& p0, const Point2LL& p1, @@ -773,14 +775,54 @@ void LayerPlan::addWallLine( if (use_roofing_config) { - addExtrusionMove( - p1, - roofing_config, - SpaceFillType::Polygons, - flow, - width_factor, - spiralize, - 1.0_r); + // The line segment is wholly or partially in the roofing area. The line is intersected + // with the roofing area into line segments. Each line segment left in this intersection + // will be printed using the roofing config, all removed segments will be printed using + // the non_bridge_config. Since the original line segment was straight we can simply print + // to the first and last point of the intersected line segments alternating between + // roofing and non_bridge_config's. + Polygons line_polys; + line_polys.addLine(p0, p1); + constexpr bool restitch = false; // only a single line doesn't need stitching + auto has_area_above_poly_lines = roofing_mask_.intersectionPolyLines(line_polys, restitch); + + if (has_area_above_poly_lines.empty()) + { + addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + else + { + // reorder all the line segments so all lines start at p0 and end at p1 + for (auto& line_poly : has_area_above_poly_lines) + { + const Point2LL& line_p0 = line_poly.front(); + const Point2LL& line_p1 = line_poly.back(); + if (vSize2(line_p1 - p0) < vSize2(line_p0 - p0)) + { + std::reverse(line_poly.begin(), line_poly.end()); + } + } + std::sort(has_area_above_poly_lines.begin(), has_area_above_poly_lines.end(), [&](auto& a, auto& b) { return vSize2(a.front() - p0) < vSize2(b.front() - p0); }); + + // add intersected line segments, alternating between roofing and non_bridge_config + for (const auto& line_poly : has_area_above_poly_lines) + { + // This is only relevant for the very fist iteration of the loop + // if the start of the line segment is already the same as p0 then no move is required + if (line_poly.front() != p0) + { + addExtrusionMove(line_poly.front(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + + addExtrusionMove(line_poly.back(), non_bridge_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + + // if the last point is not yet at p1 then add a move to p1 + if (has_area_above_poly_lines.back().back() != p1) + { + addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + } + } } else if (bridge_wall_mask_.empty()) { From d2e72609c9756b38a426feafd22e72043c38be88 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 26 Jan 2024 15:04:27 +0100 Subject: [PATCH 10/34] Rename `non_bridge_config` with `default_config` `non_bridge_config` made sense previously since there were only two configs: `bridge_config` and `non_bridge_config`. Since we introduced a third one (`roofing_config`) the variable name didn't make much sense anymore. CURA-11129 --- include/InsetOrderOptimizer.h | 8 +++--- include/LayerPlan.h | 16 +++++------ src/InsetOrderOptimizer.cpp | 12 ++++---- src/LayerPlan.cpp | 52 +++++++++++++++++------------------ 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/include/InsetOrderOptimizer.h b/include/InsetOrderOptimizer.h index a0734c3ea6..7ff5300090 100644 --- a/include/InsetOrderOptimizer.h +++ b/include/InsetOrderOptimizer.h @@ -43,8 +43,8 @@ class InsetOrderOptimizer LayerPlan& gcode_layer, const Settings& settings, const int extruder_nr, - const GCodePathConfig& inset_0_non_bridge_config, - const GCodePathConfig& inset_X_non_bridge_config, + const GCodePathConfig& inset_0_default_config, + const GCodePathConfig& inset_X_default_config, const GCodePathConfig& inset_0_roofing_config, const GCodePathConfig& inset_X_roofing_config, const GCodePathConfig& inset_0_bridge_config, @@ -92,8 +92,8 @@ class InsetOrderOptimizer LayerPlan& gcode_layer_; const Settings& settings_; const size_t extruder_nr_; - const GCodePathConfig& inset_0_non_bridge_config_; - const GCodePathConfig& inset_X_non_bridge_config_; + const GCodePathConfig& inset_0_default_config_; + const GCodePathConfig& inset_X_default_config_; const GCodePathConfig& inset_0_roofing_config_; const GCodePathConfig& inset_X_roofing_config_; const GCodePathConfig& inset_0_bridge_config_; diff --git a/include/LayerPlan.h b/include/LayerPlan.h index 34173ef331..47189f1114 100644 --- a/include/LayerPlan.h +++ b/include/LayerPlan.h @@ -403,7 +403,7 @@ class LayerPlan : public NoCopy * \param p1 The end vertex of the line. * \param settings The settings which should apply to this line added to the * layer plan. - * \param non_bridge_config The config with which to print the wall lines + * \param default_config The config with which to print the wall lines * that are not spanning a bridge. * \param bridge_config The config with which to print the wall lines that * are spanning a bridge. @@ -421,7 +421,7 @@ class LayerPlan : public NoCopy const Point2LL& p0, const Point2LL& p1, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, double flow, @@ -435,7 +435,7 @@ class LayerPlan : public NoCopy * \param wall The vertices of the wall to add. * \param start_idx The index of the starting vertex to start at. * \param settings The settings which should apply to this wall added to the layer plan. - * \param non_bridge_config The config with which to print the wall lines + * \param default_config The config with which to print the wall lines * that are not spanning a bridge. * \param bridge_config The config with which to print the wall lines that * are spanning a bridge. @@ -449,7 +449,7 @@ class LayerPlan : public NoCopy ConstPolygonRef wall, int start_idx, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, @@ -461,7 +461,7 @@ class LayerPlan : public NoCopy * \param wall The wall of type ExtrusionJunctions * \param start_idx The index of the starting vertex to start at. * \param mesh The current mesh being added to the layer plan. - * \param non_bridge_config The config with which to print the wall lines + * \param default_config The config with which to print the wall lines * that are not spanning a bridge. * \param bridge_config The config with which to print the wall lines that * are spanning a bridge @@ -479,7 +479,7 @@ class LayerPlan : public NoCopy const ExtrusionLine& wall, int start_idx, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, @@ -501,7 +501,7 @@ class LayerPlan : public NoCopy * Add walls (polygons) to the gcode with optimized order. * \param walls The walls * \param settings The settings which should apply to these walls added to the layer plan. - * \param non_bridge_config The config with which to print the wall lines that are not spanning a bridge + * \param default_config The config with which to print the wall lines that are not spanning a bridge * \param bridge_config The config with which to print the wall lines that are spanning a bridge * \param z_seam_config Optional configuration for z-seam * \param wall_0_wipe_dist The distance to travel along each wall after it has been laid down, in order to wipe the start and end of the wall together @@ -512,7 +512,7 @@ class LayerPlan : public NoCopy void addWalls( const Polygons& walls, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, const ZSeamConfig& z_seam_config = ZSeamConfig(), diff --git a/src/InsetOrderOptimizer.cpp b/src/InsetOrderOptimizer.cpp index 976504cd6a..c494f61f39 100644 --- a/src/InsetOrderOptimizer.cpp +++ b/src/InsetOrderOptimizer.cpp @@ -38,8 +38,8 @@ InsetOrderOptimizer::InsetOrderOptimizer( LayerPlan& gcode_layer, const Settings& settings, const int extruder_nr, - const GCodePathConfig& inset_0_non_bridge_config, - const GCodePathConfig& inset_X_non_bridge_config, + const GCodePathConfig& inset_0_default_config, + const GCodePathConfig& inset_X_default_config, const GCodePathConfig& inset_0_roofing_config, const GCodePathConfig& inset_X_roofing_config, const GCodePathConfig& inset_0_bridge_config, @@ -56,8 +56,8 @@ InsetOrderOptimizer::InsetOrderOptimizer( , gcode_layer_(gcode_layer) , settings_(settings) , extruder_nr_(extruder_nr) - , inset_0_non_bridge_config_(inset_0_non_bridge_config) - , inset_X_non_bridge_config_(inset_X_non_bridge_config) + , inset_0_default_config_(inset_0_default_config) + , inset_X_default_config_(inset_X_default_config) , inset_0_roofing_config_(inset_0_roofing_config) , inset_X_roofing_config_(inset_X_roofing_config) , inset_0_bridge_config_(inset_0_bridge_config) @@ -124,7 +124,7 @@ bool InsetOrderOptimizer::addToLayer() const bool is_outer_wall = path.vertices_->inset_idx_ == 0; // or thin wall 'gap filler' const bool is_gap_filler = path.vertices_->is_odd_; - const GCodePathConfig& non_bridge_config = is_outer_wall ? inset_0_non_bridge_config_ : inset_X_non_bridge_config_; + const GCodePathConfig& default_config = is_outer_wall ? inset_0_default_config_ : inset_X_default_config_; const GCodePathConfig& roofing_config = is_outer_wall ? inset_0_roofing_config_ : inset_X_roofing_config_; const GCodePathConfig& bridge_config = is_outer_wall ? inset_0_bridge_config_ : inset_X_bridge_config_; const coord_t wipe_dist = is_outer_wall && ! is_gap_filler ? wall_0_wipe_dist_ : wall_x_wipe_dist_; @@ -137,7 +137,7 @@ bool InsetOrderOptimizer::addToLayer() const bool linked_path = ! path.is_closed_; gcode_layer_.setIsInside(true); // Going to print walls, which are always inside. - gcode_layer_.addWall(*path.vertices_, start_index, settings_, non_bridge_config, roofing_config, bridge_config, wipe_dist, flow, retract_before, path.is_closed_, backwards, linked_path); + gcode_layer_.addWall(*path.vertices_, start_index, settings_, default_config, roofing_config, bridge_config, wipe_dist, flow, retract_before, path.is_closed_, backwards, linked_path); added_something = true; } return added_something; diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index 894972259e..bcdbfc47dd 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -648,7 +648,7 @@ void LayerPlan::addWallLine( const Point2LL& p0, const Point2LL& p1, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, double flow, @@ -695,7 +695,7 @@ void LayerPlan::addWallLine( // speed_flow_factor approximates how the extrusion rate alters between the non-bridge wall line and the following bridge wall line // if the extrusion rates are the same, its value will be 1, if the bridge config extrusion rate is < the non-bridge config extrusion rate, the value is < 1 - const Ratio speed_flow_factor((bridge_config.getSpeed() * bridge_config.getFlowRatio()) / (non_bridge_config.getSpeed() * non_bridge_config.getFlowRatio())); + const Ratio speed_flow_factor((bridge_config.getSpeed() * bridge_config.getFlowRatio()) / (default_config.getSpeed() * default_config.getFlowRatio())); // coast distance is proportional to distance, speed and flow of non-bridge segments just printed and is throttled by speed_flow_factor const double coast_dist = std::min(non_bridge_line_volume, max_non_bridge_line_volume) * (1 - speed_flow_factor) * bridge_wall_coast / 40; @@ -714,7 +714,7 @@ void LayerPlan::addWallLine( // segment is longer than coast distance so extrude using non-bridge config to start of coast addExtrusionMove( segment_end + coast_dist * (cur_point - segment_end) / len, - non_bridge_config, + default_config, SpaceFillType::Polygons, segment_flow, width_factor, @@ -723,14 +723,14 @@ void LayerPlan::addWallLine( } // then coast to start of bridge segment constexpr Ratio no_flow = 0.0_r; // Coasting has no flow rate. - addExtrusionMove(segment_end, non_bridge_config, SpaceFillType::Polygons, no_flow, width_factor, spiralize, speed_factor); + addExtrusionMove(segment_end, default_config, SpaceFillType::Polygons, no_flow, width_factor, spiralize, speed_factor); } else { // no coasting required, just normal segment using non-bridge config addExtrusionMove( segment_end, - non_bridge_config, + default_config, SpaceFillType::Polygons, segment_flow, width_factor, @@ -745,14 +745,14 @@ void LayerPlan::addWallLine( // no coasting required, just normal segment using non-bridge config addExtrusionMove( segment_end, - non_bridge_config, + default_config, SpaceFillType::Polygons, segment_flow, width_factor, spiralize, (overhang_mask_.empty() || (! overhang_mask_.inside(p0, true) && ! overhang_mask_.inside(p1, true))) ? speed_factor : overhang_speed_factor); } - non_bridge_line_volume += vSize(cur_point - segment_end) * segment_flow * width_factor * speed_factor * non_bridge_config.getSpeed(); + non_bridge_line_volume += vSize(cur_point - segment_end) * segment_flow * width_factor * speed_factor * default_config.getSpeed(); cur_point = segment_end; speed_factor = 1 - (1 - speed_factor) * acceleration_factor; if (speed_factor >= 0.9) @@ -765,7 +765,7 @@ void LayerPlan::addWallLine( const auto use_roofing_config = [&]() -> bool { - if (roofing_config == non_bridge_config) + if (roofing_config == default_config) { // if the roofing config and normal config are the same any way there is no need to check what part of the line segment return false; @@ -778,9 +778,9 @@ void LayerPlan::addWallLine( // The line segment is wholly or partially in the roofing area. The line is intersected // with the roofing area into line segments. Each line segment left in this intersection // will be printed using the roofing config, all removed segments will be printed using - // the non_bridge_config. Since the original line segment was straight we can simply print + // the default_config. Since the original line segment was straight we can simply print // to the first and last point of the intersected line segments alternating between - // roofing and non_bridge_config's. + // roofing and default_config's. Polygons line_polys; line_polys.addLine(p0, p1); constexpr bool restitch = false; // only a single line doesn't need stitching @@ -804,7 +804,7 @@ void LayerPlan::addWallLine( } std::sort(has_area_above_poly_lines.begin(), has_area_above_poly_lines.end(), [&](auto& a, auto& b) { return vSize2(a.front() - p0) < vSize2(b.front() - p0); }); - // add intersected line segments, alternating between roofing and non_bridge_config + // add intersected line segments, alternating between roofing and default_config for (const auto& line_poly : has_area_above_poly_lines) { // This is only relevant for the very fist iteration of the loop @@ -814,7 +814,7 @@ void LayerPlan::addWallLine( addExtrusionMove(line_poly.front(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } - addExtrusionMove(line_poly.back(), non_bridge_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(line_poly.back(), default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } // if the last point is not yet at p1 then add a move to p1 @@ -829,7 +829,7 @@ void LayerPlan::addWallLine( // no bridges required addExtrusionMove( p1, - non_bridge_config, + default_config, SpaceFillType::Polygons, flow, width_factor, @@ -879,7 +879,7 @@ void LayerPlan::addWallLine( b1 = bridge[0]; } - // extrude using non_bridge_config to the start of the next bridge segment + // extrude using default_config to the start of the next bridge segment addNonBridgeLine(b0); @@ -895,7 +895,7 @@ void LayerPlan::addWallLine( non_bridge_line_volume = 0; cur_point = b1; // after a bridge segment, start slow and accelerate to avoid under-extrusion due to extruder lag - speed_factor = std::max(std::min(Ratio(bridge_config.getSpeed() / non_bridge_config.getSpeed()), 1.0_r), 0.5_r); + speed_factor = std::max(std::min(Ratio(bridge_config.getSpeed() / default_config.getSpeed()), 1.0_r), 0.5_r); } } else @@ -909,7 +909,7 @@ void LayerPlan::addWallLine( line_polys.remove(nearest); } - // if we haven't yet reached p1, fill the gap with non_bridge_config line + // if we haven't yet reached p1, fill the gap with default_config line addNonBridgeLine(p1); } else if (bridge_wall_mask_.inside(p0, true) && vSize(p0 - p1) >= min_bridge_line_len) @@ -930,7 +930,7 @@ void LayerPlan::addWall( ConstPolygonRef wall, int start_idx, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, @@ -945,7 +945,7 @@ void LayerPlan::addWall( constexpr size_t dummy_perimeter_id = 0; // <-- Here, don't care about which perimeter any more. const coord_t nominal_line_width - = non_bridge_config + = default_config .getLineWidth(); // <-- The line width which it's 'supposed to' be will be used to adjust the flow ratio each time, this'll give a flow-ratio-multiplier of 1. ExtrusionLine ewall; @@ -960,14 +960,14 @@ void LayerPlan::addWall( constexpr bool is_closed = true; constexpr bool is_reversed = false; constexpr bool is_linked_path = false; - addWall(ewall, start_idx, settings, non_bridge_config, roofing_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract, is_closed, is_reversed, is_linked_path); + addWall(ewall, start_idx, settings, default_config, roofing_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract, is_closed, is_reversed, is_linked_path); } void LayerPlan::addWall( const ExtrusionLine& wall, int start_idx, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, coord_t wall_0_wipe_dist, @@ -994,7 +994,7 @@ void LayerPlan::addWall( const coord_t min_bridge_line_len = settings.get("bridge_wall_min_length"); const Ratio nominal_line_width_multiplier{ - 1.0 / Ratio{ static_cast(non_bridge_config.getLineWidth()) } + 1.0 / Ratio{ static_cast(default_config.getLineWidth()) } }; // we multiply the flow with the actual wanted line width (for that junction), and then multiply with this // helper function to calculate the distance from the start of the current wall line to the first bridge segment @@ -1083,7 +1083,7 @@ void LayerPlan::addWall( const bool is_small_feature = (small_feature_max_length > 0) && (layer_nr_ == 0 || wall.inset_idx_ == 0) && cura::shorterThan(wall, small_feature_max_length); Ratio small_feature_speed_factor = settings.get((layer_nr_ == 0) ? "small_feature_speed_factor_0" : "small_feature_speed_factor"); const Velocity min_speed = fan_speed_layer_time_settings_per_extruder_[getLastPlannedExtruderTrain()->extruder_nr_].cool_min_speed; - small_feature_speed_factor = std::max((double)small_feature_speed_factor, (double)(min_speed / non_bridge_config.getSpeed())); + small_feature_speed_factor = std::max((double)small_feature_speed_factor, (double)(min_speed / default_config.getSpeed())); const coord_t max_area_deviation = std::max(settings.get("meshfix_maximum_extrusion_area_deviation"), 1); // Square micrometres! const coord_t max_resolution = std::max(settings.get("meshfix_maximum_resolution"), coord_t(1)); @@ -1145,7 +1145,7 @@ void LayerPlan::addWall( constexpr bool spiralize = false; addExtrusionMove( destination, - non_bridge_config, + default_config, SpaceFillType::Polygons, flow_ratio, line_width * nominal_line_width_multiplier, @@ -1159,7 +1159,7 @@ void LayerPlan::addWall( origin, destination, settings, - non_bridge_config, + default_config, roofing_config, bridge_config, flow_ratio, @@ -1234,7 +1234,7 @@ void LayerPlan::addInfillWall(const ExtrusionLine& wall, const GCodePathConfig& void LayerPlan::addWalls( const Polygons& walls, const Settings& settings, - const GCodePathConfig& non_bridge_config, + const GCodePathConfig& default_config, const GCodePathConfig& roofing_config, const GCodePathConfig& bridge_config, const ZSeamConfig& z_seam_config, @@ -1251,7 +1251,7 @@ void LayerPlan::addWalls( orderOptimizer.optimize(); for (const PathOrdering& path : orderOptimizer.paths_) { - addWall(**path.vertices_, path.start_vertex_, settings, non_bridge_config, roofing_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract); + addWall(**path.vertices_, path.start_vertex_, settings, default_config, roofing_config, bridge_config, wall_0_wipe_dist, flow_ratio, always_retract); } } From 7a4645794382a123c1fa8ad75ebf49b0c70541a3 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 26 Jan 2024 15:07:07 +0100 Subject: [PATCH 11/34] Update documentation CURA-11129 --- include/LayerPlan.h | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/include/LayerPlan.h b/include/LayerPlan.h index 47189f1114..de831d00a2 100644 --- a/include/LayerPlan.h +++ b/include/LayerPlan.h @@ -404,7 +404,9 @@ class LayerPlan : public NoCopy * \param settings The settings which should apply to this line added to the * layer plan. * \param default_config The config with which to print the wall lines - * that are not spanning a bridge. + * that are not spanning a bridge or are exposed to air. + * \param roofing_config The config with which to print the wall lines + * that are exposed to air. * \param bridge_config The config with which to print the wall lines that * are spanning a bridge. * \param flow The ratio with which to multiply the extrusion amount. @@ -436,9 +438,9 @@ class LayerPlan : public NoCopy * \param start_idx The index of the starting vertex to start at. * \param settings The settings which should apply to this wall added to the layer plan. * \param default_config The config with which to print the wall lines - * that are not spanning a bridge. - * \param bridge_config The config with which to print the wall lines that - * are spanning a bridge. + * that are not spanning a bridge or are exposed to air. + * \param roofing_config The config with which to print the wall lines + * that are exposed to air. * \param wall_0_wipe_dist The distance to travel along the wall after it * has been laid down, in order to wipe the start and end of the wall * \param flow_ratio The ratio with which to multiply the extrusion amount. @@ -462,7 +464,9 @@ class LayerPlan : public NoCopy * \param start_idx The index of the starting vertex to start at. * \param mesh The current mesh being added to the layer plan. * \param default_config The config with which to print the wall lines - * that are not spanning a bridge. + * that are not spanning a bridge or are exposed to air. + * \param roofing_config The config with which to print the wall lines + * that are exposed to air. * \param bridge_config The config with which to print the wall lines that * are spanning a bridge * \param wall_0_wipe_dist The distance to travel along the wall after it @@ -501,7 +505,10 @@ class LayerPlan : public NoCopy * Add walls (polygons) to the gcode with optimized order. * \param walls The walls * \param settings The settings which should apply to these walls added to the layer plan. - * \param default_config The config with which to print the wall lines that are not spanning a bridge + * \param default_config The config with which to print the wall lines + * that are not spanning a bridge or are exposed to air. + * \param roofing_config The config with which to print the wall lines + * that are exposed to air. * \param bridge_config The config with which to print the wall lines that are spanning a bridge * \param z_seam_config Optional configuration for z-seam * \param wall_0_wipe_dist The distance to travel along each wall after it has been laid down, in order to wipe the start and end of the wall together From ebebf3e12df702d02439bb26da3723cd638c04af Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Fri, 26 Jan 2024 14:07:54 +0000 Subject: [PATCH 12/34] Applied clang-format. --- src/InsetOrderOptimizer.cpp | 14 +++++++++++++- src/LayerPlan.cpp | 10 ++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/InsetOrderOptimizer.cpp b/src/InsetOrderOptimizer.cpp index c494f61f39..82d4199d01 100644 --- a/src/InsetOrderOptimizer.cpp +++ b/src/InsetOrderOptimizer.cpp @@ -137,7 +137,19 @@ bool InsetOrderOptimizer::addToLayer() const bool linked_path = ! path.is_closed_; gcode_layer_.setIsInside(true); // Going to print walls, which are always inside. - gcode_layer_.addWall(*path.vertices_, start_index, settings_, default_config, roofing_config, bridge_config, wipe_dist, flow, retract_before, path.is_closed_, backwards, linked_path); + gcode_layer_.addWall( + *path.vertices_, + start_index, + settings_, + default_config, + roofing_config, + bridge_config, + wipe_dist, + flow, + retract_before, + path.is_closed_, + backwards, + linked_path); added_something = true; } return added_something; diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index bcdbfc47dd..b986727c55 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -770,7 +770,7 @@ void LayerPlan::addWallLine( // if the roofing config and normal config are the same any way there is no need to check what part of the line segment return false; } - return roofing_mask_.empty() || PolygonUtils::polygonCollidesWithLineSegment(roofing_mask_, p0, p1) || !roofing_mask_.inside(p1, true); + return roofing_mask_.empty() || PolygonUtils::polygonCollidesWithLineSegment(roofing_mask_, p0, p1) || ! roofing_mask_.inside(p1, true); }(); if (use_roofing_config) @@ -802,7 +802,13 @@ void LayerPlan::addWallLine( std::reverse(line_poly.begin(), line_poly.end()); } } - std::sort(has_area_above_poly_lines.begin(), has_area_above_poly_lines.end(), [&](auto& a, auto& b) { return vSize2(a.front() - p0) < vSize2(b.front() - p0); }); + std::sort( + has_area_above_poly_lines.begin(), + has_area_above_poly_lines.end(), + [&](auto& a, auto& b) + { + return vSize2(a.front() - p0) < vSize2(b.front() - p0); + }); // add intersected line segments, alternating between roofing and default_config for (const auto& line_poly : has_area_above_poly_lines) From f861a380ebe89cd8adda0378099a676bdcbacd78 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 26 Jan 2024 15:13:20 +0100 Subject: [PATCH 13/34] Update documentation CURA-11129 --- src/LayerPlan.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index bcdbfc47dd..ecf62a7b00 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -768,6 +768,7 @@ void LayerPlan::addWallLine( if (roofing_config == default_config) { // if the roofing config and normal config are the same any way there is no need to check what part of the line segment + // what part of the line segment will be printed with what config. return false; } return roofing_mask_.empty() || PolygonUtils::polygonCollidesWithLineSegment(roofing_mask_, p0, p1) || !roofing_mask_.inside(p1, true); From 2ea1f875f07c68d9531ec384a7e1eb39a8b28362 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 29 Jan 2024 09:57:19 +0100 Subject: [PATCH 14/34] Fix printing rafts-holes in monotonic order CURA-11438 --- src/FffGcodeWriter.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index bbb4b7c10c..615f338ddc 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -983,24 +983,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage) raft_outline_path = raft_outline_path.difference(storage.primeTower.getOuterPoly(layer_nr)); } - std::vector raft_islands; - 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) - { - Polygons island; - island.add(raft_island); - raft_islands.emplace_back(island); - } - } - else - { - raft_islands.emplace_back(raft_outline_path); - } - - for (const Polygons raft_island : raft_islands) + for (const Polygons raft_island : raft_outline_path.splitIntoParts()) { Infill infill_comp( EFillMethod::ZIG_ZAG, From dab88c0237c6303b9372d56b98df2b9b221f0090 Mon Sep 17 00:00:00 2001 From: Casper Lamboo Date: Mon, 29 Jan 2024 10:57:14 +0100 Subject: [PATCH 15/34] Update src/LayerPlan.cpp Co-authored-by: Saumya Jain <70144862+saumyaj3@users.noreply.github.com> --- src/LayerPlan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index c94e1ac857..2e2806d652 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -767,7 +767,7 @@ void LayerPlan::addWallLine( { if (roofing_config == default_config) { - // if the roofing config and normal config are the same any way there is no need to check what part of the line segment + // if the roofing config and normal config are the same any way there is no need to check // what part of the line segment will be printed with what config. return false; } From 0ad6a45ec9b589ab9ff2d0e70a5edc5d3701bad8 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Mon, 29 Jan 2024 09:57:45 +0000 Subject: [PATCH 16/34] Applied clang-format. --- src/LayerPlan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index 2e2806d652..aa5e8042fe 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -767,7 +767,7 @@ void LayerPlan::addWallLine( { if (roofing_config == default_config) { - // if the roofing config and normal config are the same any way there is no need to check + // if the roofing config and normal config are the same any way there is no need to check // what part of the line segment will be printed with what config. return false; } From ca91529ec0132a0fc44557f58d526bcc257d3f2e Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Tue, 30 Jan 2024 15:29:40 +0100 Subject: [PATCH 17/34] Only use top layers We are not in skin, so only look at top layers CURA-11129 --- src/FffGcodeWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index fc3b2ef01d..0661488f0c 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -2581,7 +2581,7 @@ bool FffGcodeWriter::processInsets( const auto roofing_mask = [&gcode_layer, &mesh, &boundaryBox]() -> Polygons { - const size_t roofing_layer_count = std::min(mesh.settings.get("roofing_layer_count"), mesh.settings.get("top_layers")); + const size_t roofing_layer_count = mesh.settings.get("top_layers"); if (gcode_layer.getLayerNr() + roofing_layer_count >= mesh.layers.size()) { From c24506250074c9daacdca2e3da3136d3b0af4c9f Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Tue, 30 Jan 2024 17:13:33 +0100 Subject: [PATCH 18/34] Invert roofing mask The area described in the mask was actually the inverse roofing mask which was a bit confusing CURA-11129 --- src/FffGcodeWriter.cpp | 10 ++++++---- src/LayerPlan.cpp | 29 ++++++++++++++++------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 0661488f0c..6859218aa4 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -2579,21 +2579,23 @@ bool FffGcodeWriter::processInsets( gcode_layer.setOverhangMask(overhang_region); } - const auto roofing_mask = [&gcode_layer, &mesh, &boundaryBox]() -> Polygons + const auto roofing_mask = [&]() -> Polygons { const size_t roofing_layer_count = mesh.settings.get("top_layers"); + auto roofing_mask = storage.getMachineBorder(mesh.settings.get("wall_0_extruder_nr").extruder_nr_); + if (gcode_layer.getLayerNr() + roofing_layer_count >= mesh.layers.size()) { - return Polygons(); + return roofing_mask; } - auto roofing_mask = Polygons(); + const auto wall_line_width_0 = mesh.settings.get("wall_line_width_0"); for (const auto& layer_part : mesh.layers[gcode_layer.getLayerNr() + roofing_layer_count].parts) { if (boundaryBox.hit(layer_part.boundaryBox)) { - roofing_mask.add(layer_part.outline); + roofing_mask = roofing_mask.difference(layer_part.outline.offset(-wall_line_width_0 / 4)); } } return roofing_mask; diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index aa5e8042fe..6af9a0ce21 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -771,7 +771,7 @@ void LayerPlan::addWallLine( // what part of the line segment will be printed with what config. return false; } - return roofing_mask_.empty() || PolygonUtils::polygonCollidesWithLineSegment(roofing_mask_, p0, p1) || ! roofing_mask_.inside(p1, true); + return PolygonUtils::polygonCollidesWithLineSegment(roofing_mask_, p0, p1) || roofing_mask_.inside(p1, true); }(); if (use_roofing_config) @@ -785,16 +785,19 @@ void LayerPlan::addWallLine( Polygons line_polys; line_polys.addLine(p0, p1); constexpr bool restitch = false; // only a single line doesn't need stitching - auto has_area_above_poly_lines = roofing_mask_.intersectionPolyLines(line_polys, restitch); + auto roofing_line_segments = roofing_mask_.intersectionPolyLines(line_polys, restitch); - if (has_area_above_poly_lines.empty()) + if (roofing_line_segments.empty()) { - addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + // roofing_line_segments should never be empty since we already checked that the line segment + // intersects with the roofing area. But if it is empty then just print the line segment + // using the default_config. + addExtrusionMove(p1, default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } else { // reorder all the line segments so all lines start at p0 and end at p1 - for (auto& line_poly : has_area_above_poly_lines) + for (auto& line_poly : roofing_line_segments) { const Point2LL& line_p0 = line_poly.front(); const Point2LL& line_p1 = line_poly.back(); @@ -804,30 +807,30 @@ void LayerPlan::addWallLine( } } std::sort( - has_area_above_poly_lines.begin(), - has_area_above_poly_lines.end(), + roofing_line_segments.begin(), + roofing_line_segments.end(), [&](auto& a, auto& b) { return vSize2(a.front() - p0) < vSize2(b.front() - p0); }); // add intersected line segments, alternating between roofing and default_config - for (const auto& line_poly : has_area_above_poly_lines) + for (const auto& line_poly : roofing_line_segments) { // This is only relevant for the very fist iteration of the loop // if the start of the line segment is already the same as p0 then no move is required - if (line_poly.front() != p0) + if (vSize(line_poly.front() - p0) > min_line_len * min_line_len) { - addExtrusionMove(line_poly.front(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(line_poly.front(), default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } - addExtrusionMove(line_poly.back(), default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(line_poly.back(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } // if the last point is not yet at p1 then add a move to p1 - if (has_area_above_poly_lines.back().back() != p1) + if (vSize2(roofing_line_segments.back().back() - p1) > min_line_len * min_line_len) { - addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(p1, default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } } } From 873a11edf6348e0daa96b8e1c099526446654428 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Tue, 30 Jan 2024 17:23:16 +0100 Subject: [PATCH 19/34] Test use roofing config every where see if this has an effect on micro segments CURA-11129 --- src/LayerPlan.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index 6af9a0ce21..b9ebbb6712 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -695,7 +695,7 @@ void LayerPlan::addWallLine( // speed_flow_factor approximates how the extrusion rate alters between the non-bridge wall line and the following bridge wall line // if the extrusion rates are the same, its value will be 1, if the bridge config extrusion rate is < the non-bridge config extrusion rate, the value is < 1 - const Ratio speed_flow_factor((bridge_config.getSpeed() * bridge_config.getFlowRatio()) / (default_config.getSpeed() * default_config.getFlowRatio())); + const Ratio speed_flow_factor((bridge_config.getSpeed() * bridge_config.getFlowRatio()) / (roofing_config.getSpeed() * roofing_config.getFlowRatio())); // coast distance is proportional to distance, speed and flow of non-bridge segments just printed and is throttled by speed_flow_factor const double coast_dist = std::min(non_bridge_line_volume, max_non_bridge_line_volume) * (1 - speed_flow_factor) * bridge_wall_coast / 40; @@ -714,7 +714,7 @@ void LayerPlan::addWallLine( // segment is longer than coast distance so extrude using non-bridge config to start of coast addExtrusionMove( segment_end + coast_dist * (cur_point - segment_end) / len, - default_config, + roofing_config, SpaceFillType::Polygons, segment_flow, width_factor, @@ -723,14 +723,14 @@ void LayerPlan::addWallLine( } // then coast to start of bridge segment constexpr Ratio no_flow = 0.0_r; // Coasting has no flow rate. - addExtrusionMove(segment_end, default_config, SpaceFillType::Polygons, no_flow, width_factor, spiralize, speed_factor); + addExtrusionMove(segment_end, roofing_config, SpaceFillType::Polygons, no_flow, width_factor, spiralize, speed_factor); } else { // no coasting required, just normal segment using non-bridge config addExtrusionMove( segment_end, - default_config, + roofing_config, SpaceFillType::Polygons, segment_flow, width_factor, @@ -745,14 +745,14 @@ void LayerPlan::addWallLine( // no coasting required, just normal segment using non-bridge config addExtrusionMove( segment_end, - default_config, + roofing_config, SpaceFillType::Polygons, segment_flow, width_factor, spiralize, (overhang_mask_.empty() || (! overhang_mask_.inside(p0, true) && ! overhang_mask_.inside(p1, true))) ? speed_factor : overhang_speed_factor); } - non_bridge_line_volume += vSize(cur_point - segment_end) * segment_flow * width_factor * speed_factor * default_config.getSpeed(); + non_bridge_line_volume += vSize(cur_point - segment_end) * segment_flow * width_factor * speed_factor * roofing_config.getSpeed(); cur_point = segment_end; speed_factor = 1 - (1 - speed_factor) * acceleration_factor; if (speed_factor >= 0.9) @@ -779,9 +779,9 @@ void LayerPlan::addWallLine( // The line segment is wholly or partially in the roofing area. The line is intersected // with the roofing area into line segments. Each line segment left in this intersection // will be printed using the roofing config, all removed segments will be printed using - // the default_config. Since the original line segment was straight we can simply print + // the roofing_config. Since the original line segment was straight we can simply print // to the first and last point of the intersected line segments alternating between - // roofing and default_config's. + // roofing and roofing_config's. Polygons line_polys; line_polys.addLine(p0, p1); constexpr bool restitch = false; // only a single line doesn't need stitching @@ -791,8 +791,8 @@ void LayerPlan::addWallLine( { // roofing_line_segments should never be empty since we already checked that the line segment // intersects with the roofing area. But if it is empty then just print the line segment - // using the default_config. - addExtrusionMove(p1, default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + // using the roofing_config. + addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } else { @@ -814,14 +814,14 @@ void LayerPlan::addWallLine( return vSize2(a.front() - p0) < vSize2(b.front() - p0); }); - // add intersected line segments, alternating between roofing and default_config + // add intersected line segments, alternating between roofing and roofing_config for (const auto& line_poly : roofing_line_segments) { // This is only relevant for the very fist iteration of the loop // if the start of the line segment is already the same as p0 then no move is required if (vSize(line_poly.front() - p0) > min_line_len * min_line_len) { - addExtrusionMove(line_poly.front(), default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(line_poly.front(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } addExtrusionMove(line_poly.back(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); @@ -830,7 +830,7 @@ void LayerPlan::addWallLine( // if the last point is not yet at p1 then add a move to p1 if (vSize2(roofing_line_segments.back().back() - p1) > min_line_len * min_line_len) { - addExtrusionMove(p1, default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } } } @@ -839,7 +839,7 @@ void LayerPlan::addWallLine( // no bridges required addExtrusionMove( p1, - default_config, + roofing_config, SpaceFillType::Polygons, flow, width_factor, @@ -889,7 +889,7 @@ void LayerPlan::addWallLine( b1 = bridge[0]; } - // extrude using default_config to the start of the next bridge segment + // extrude using roofing_config to the start of the next bridge segment addNonBridgeLine(b0); @@ -905,7 +905,7 @@ void LayerPlan::addWallLine( non_bridge_line_volume = 0; cur_point = b1; // after a bridge segment, start slow and accelerate to avoid under-extrusion due to extruder lag - speed_factor = std::max(std::min(Ratio(bridge_config.getSpeed() / default_config.getSpeed()), 1.0_r), 0.5_r); + speed_factor = std::max(std::min(Ratio(bridge_config.getSpeed() / roofing_config.getSpeed()), 1.0_r), 0.5_r); } } else @@ -919,7 +919,7 @@ void LayerPlan::addWallLine( line_polys.remove(nearest); } - // if we haven't yet reached p1, fill the gap with default_config line + // if we haven't yet reached p1, fill the gap with roofing_config line addNonBridgeLine(p1); } else if (bridge_wall_mask_.inside(p0, true) && vSize(p0 - p1) >= min_bridge_line_len) From 84bac03d5a4d99e8a869aed51f6aa90fcf74f80e Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Tue, 30 Jan 2024 17:30:54 +0100 Subject: [PATCH 20/34] Revert "Test use roofing config every where" This reverts commit 873a11edf6348e0daa96b8e1c099526446654428. --- src/LayerPlan.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index b9ebbb6712..6af9a0ce21 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -695,7 +695,7 @@ void LayerPlan::addWallLine( // speed_flow_factor approximates how the extrusion rate alters between the non-bridge wall line and the following bridge wall line // if the extrusion rates are the same, its value will be 1, if the bridge config extrusion rate is < the non-bridge config extrusion rate, the value is < 1 - const Ratio speed_flow_factor((bridge_config.getSpeed() * bridge_config.getFlowRatio()) / (roofing_config.getSpeed() * roofing_config.getFlowRatio())); + const Ratio speed_flow_factor((bridge_config.getSpeed() * bridge_config.getFlowRatio()) / (default_config.getSpeed() * default_config.getFlowRatio())); // coast distance is proportional to distance, speed and flow of non-bridge segments just printed and is throttled by speed_flow_factor const double coast_dist = std::min(non_bridge_line_volume, max_non_bridge_line_volume) * (1 - speed_flow_factor) * bridge_wall_coast / 40; @@ -714,7 +714,7 @@ void LayerPlan::addWallLine( // segment is longer than coast distance so extrude using non-bridge config to start of coast addExtrusionMove( segment_end + coast_dist * (cur_point - segment_end) / len, - roofing_config, + default_config, SpaceFillType::Polygons, segment_flow, width_factor, @@ -723,14 +723,14 @@ void LayerPlan::addWallLine( } // then coast to start of bridge segment constexpr Ratio no_flow = 0.0_r; // Coasting has no flow rate. - addExtrusionMove(segment_end, roofing_config, SpaceFillType::Polygons, no_flow, width_factor, spiralize, speed_factor); + addExtrusionMove(segment_end, default_config, SpaceFillType::Polygons, no_flow, width_factor, spiralize, speed_factor); } else { // no coasting required, just normal segment using non-bridge config addExtrusionMove( segment_end, - roofing_config, + default_config, SpaceFillType::Polygons, segment_flow, width_factor, @@ -745,14 +745,14 @@ void LayerPlan::addWallLine( // no coasting required, just normal segment using non-bridge config addExtrusionMove( segment_end, - roofing_config, + default_config, SpaceFillType::Polygons, segment_flow, width_factor, spiralize, (overhang_mask_.empty() || (! overhang_mask_.inside(p0, true) && ! overhang_mask_.inside(p1, true))) ? speed_factor : overhang_speed_factor); } - non_bridge_line_volume += vSize(cur_point - segment_end) * segment_flow * width_factor * speed_factor * roofing_config.getSpeed(); + non_bridge_line_volume += vSize(cur_point - segment_end) * segment_flow * width_factor * speed_factor * default_config.getSpeed(); cur_point = segment_end; speed_factor = 1 - (1 - speed_factor) * acceleration_factor; if (speed_factor >= 0.9) @@ -779,9 +779,9 @@ void LayerPlan::addWallLine( // The line segment is wholly or partially in the roofing area. The line is intersected // with the roofing area into line segments. Each line segment left in this intersection // will be printed using the roofing config, all removed segments will be printed using - // the roofing_config. Since the original line segment was straight we can simply print + // the default_config. Since the original line segment was straight we can simply print // to the first and last point of the intersected line segments alternating between - // roofing and roofing_config's. + // roofing and default_config's. Polygons line_polys; line_polys.addLine(p0, p1); constexpr bool restitch = false; // only a single line doesn't need stitching @@ -791,8 +791,8 @@ void LayerPlan::addWallLine( { // roofing_line_segments should never be empty since we already checked that the line segment // intersects with the roofing area. But if it is empty then just print the line segment - // using the roofing_config. - addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + // using the default_config. + addExtrusionMove(p1, default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } else { @@ -814,14 +814,14 @@ void LayerPlan::addWallLine( return vSize2(a.front() - p0) < vSize2(b.front() - p0); }); - // add intersected line segments, alternating between roofing and roofing_config + // add intersected line segments, alternating between roofing and default_config for (const auto& line_poly : roofing_line_segments) { // This is only relevant for the very fist iteration of the loop // if the start of the line segment is already the same as p0 then no move is required if (vSize(line_poly.front() - p0) > min_line_len * min_line_len) { - addExtrusionMove(line_poly.front(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(line_poly.front(), default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } addExtrusionMove(line_poly.back(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); @@ -830,7 +830,7 @@ void LayerPlan::addWallLine( // if the last point is not yet at p1 then add a move to p1 if (vSize2(roofing_line_segments.back().back() - p1) > min_line_len * min_line_len) { - addExtrusionMove(p1, roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); + addExtrusionMove(p1, default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } } } @@ -839,7 +839,7 @@ void LayerPlan::addWallLine( // no bridges required addExtrusionMove( p1, - roofing_config, + default_config, SpaceFillType::Polygons, flow, width_factor, @@ -889,7 +889,7 @@ void LayerPlan::addWallLine( b1 = bridge[0]; } - // extrude using roofing_config to the start of the next bridge segment + // extrude using default_config to the start of the next bridge segment addNonBridgeLine(b0); @@ -905,7 +905,7 @@ void LayerPlan::addWallLine( non_bridge_line_volume = 0; cur_point = b1; // after a bridge segment, start slow and accelerate to avoid under-extrusion due to extruder lag - speed_factor = std::max(std::min(Ratio(bridge_config.getSpeed() / roofing_config.getSpeed()), 1.0_r), 0.5_r); + speed_factor = std::max(std::min(Ratio(bridge_config.getSpeed() / default_config.getSpeed()), 1.0_r), 0.5_r); } } else @@ -919,7 +919,7 @@ void LayerPlan::addWallLine( line_polys.remove(nearest); } - // if we haven't yet reached p1, fill the gap with roofing_config line + // if we haven't yet reached p1, fill the gap with default_config line addNonBridgeLine(p1); } else if (bridge_wall_mask_.inside(p0, true) && vSize(p0 - p1) >= min_bridge_line_len) From d300a68c5333456289c24d233ca2f6cee0f3e67c Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 31 Jan 2024 10:34:12 +0100 Subject: [PATCH 21/34] Use correct squared vsize CURA-11129 --- src/LayerPlan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index 6af9a0ce21..27846bea8f 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -819,7 +819,7 @@ void LayerPlan::addWallLine( { // This is only relevant for the very fist iteration of the loop // if the start of the line segment is already the same as p0 then no move is required - if (vSize(line_poly.front() - p0) > min_line_len * min_line_len) + if (vSize2(line_poly.front() - p0) > min_line_len * min_line_len) { addExtrusionMove(line_poly.front(), default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } From e3854cc460d8747f24658c999759c5be3349b873 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 31 Jan 2024 11:40:42 +0100 Subject: [PATCH 22/34] allign comments with the code --- src/LayerPlan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp index 27846bea8f..b1a553646a 100644 --- a/src/LayerPlan.cpp +++ b/src/LayerPlan.cpp @@ -818,7 +818,7 @@ void LayerPlan::addWallLine( for (const auto& line_poly : roofing_line_segments) { // This is only relevant for the very fist iteration of the loop - // if the start of the line segment is already the same as p0 then no move is required + // if the start of the line segment is not at minimum distance from p0 if (vSize2(line_poly.front() - p0) > min_line_len * min_line_len) { addExtrusionMove(line_poly.front(), default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); @@ -827,7 +827,7 @@ void LayerPlan::addWallLine( addExtrusionMove(line_poly.back(), roofing_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); } - // if the last point is not yet at p1 then add a move to p1 + // if the last point is not yet at a minimum distance from p1 then add a move to p1 if (vSize2(roofing_line_segments.back().back() - p1) > min_line_len * min_line_len) { addExtrusionMove(p1, default_config, SpaceFillType::Polygons, flow, width_factor, spiralize, 1.0_r); From dca51eacdc564bc2ad6168ae025b3bf8fd2072e7 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 1 Feb 2024 16:28:17 +0100 Subject: [PATCH 23/34] Revert "Only use top layers" This reverts commit ca91529ec0132a0fc44557f58d526bcc257d3f2e. --- src/FffGcodeWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 6859218aa4..6008826fbf 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -2581,7 +2581,7 @@ bool FffGcodeWriter::processInsets( const auto roofing_mask = [&]() -> Polygons { - const size_t roofing_layer_count = mesh.settings.get("top_layers"); + const size_t roofing_layer_count = std::min(mesh.settings.get("roofing_layer_count"), mesh.settings.get("top_layers")); auto roofing_mask = storage.getMachineBorder(mesh.settings.get("wall_0_extruder_nr").extruder_nr_); From 97e1b4c6c7b0c4493d7748c2a3e1a84d1acc1430 Mon Sep 17 00:00:00 2001 From: Thomas Rahm <67757218+ThomasRahm@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:12:39 +0100 Subject: [PATCH 24/34] Fix tree support related crash that occurs if there are no overhangs. Also abort tree support generation early if there are no overhangs to support. --- include/TreeSupport.h | 3 ++- src/TreeModelVolumes.cpp | 6 +++--- src/TreeSupport.cpp | 17 +++++++++++++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/TreeSupport.h b/include/TreeSupport.h index 6ad2a5fac4..b2b12e6531 100644 --- a/include/TreeSupport.h +++ b/include/TreeSupport.h @@ -74,8 +74,9 @@ class TreeSupport * * \param storage[in] Background storage to access meshes. * \param currently_processing_meshes[in] Indexes of all meshes that are processed in this iteration + * \return Uppermost layer precalculated. -1 if no layer were precalculated as no overhang is present. */ - void precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes); + LayerIndex precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes); /*! diff --git a/src/TreeModelVolumes.cpp b/src/TreeModelVolumes.cpp index 7318061091..fa8fe4bedf 100644 --- a/src/TreeModelVolumes.cpp +++ b/src/TreeModelVolumes.cpp @@ -1084,7 +1084,6 @@ void TreeModelVolumes::calculateAvoidanceToModel(const std::deque max_required_layer) { - spdlog::debug("Requested calculation for value already calculated ?"); + spdlog::debug("Requested calculation for value already calculated or max_required_layer is 0?"); return; } - start_layer = std::max(start_layer, LayerIndex(1)); + getPlaceableAreas(radius, max_required_layer); // ensuring Placeable Areas are calculated latest_avoidance = getAvoidance(radius, start_layer - 1, type, true, true); // minDist as the delta was already added, also avoidance for layer 0 will return the collision. diff --git a/src/TreeSupport.cpp b/src/TreeSupport.cpp index 64710447a4..ee596f82d5 100644 --- a/src/TreeSupport.cpp +++ b/src/TreeSupport.cpp @@ -159,7 +159,12 @@ void TreeSupport::generateSupportAreas(SliceDataStorage& storage) exclude); // ### Precalculate avoidances, collision etc. - precalculate(storage, processing.second); + const LayerIndex max_required_layer = precalculate(storage, processing.second); + if(max_required_layer < 0) + { + spdlog::info("Support tree mesh group {} does not have any overhang. Skipping tree support generation for this support tree mesh group.",counter + 1); + continue; //If there is no overhang to support, skip these meshes + } const auto t_precalc = std::chrono::high_resolution_clock::now(); // ### Place tips of the support tree @@ -212,10 +217,10 @@ void TreeSupport::generateSupportAreas(SliceDataStorage& storage) storage.support.generated = true; } -void TreeSupport::precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes) +LayerIndex TreeSupport::precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes) { // Calculate top most layer that is relevant for support. - LayerIndex max_layer = 0; + LayerIndex max_layer = -1; for (size_t mesh_idx : currently_processing_meshes) { const SliceMeshStorage& mesh = *storage.meshes[mesh_idx]; @@ -244,7 +249,11 @@ void TreeSupport::precalculate(const SliceDataStorage& storage, std::vector= 0) + { + volumes_.precalculate(max_layer); + } + return max_layer; } From 8be88c26a10476832ccccebd8d0d1234d6fbc8d1 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 13 Feb 2024 15:04:54 +0100 Subject: [PATCH 25/34] in case of only single vertex is present In such a case path_order_optimisation is not needed. Slicing crash https://github.com/Ultimaker/Cura/issues/17499 CURA-11570 --- src/FffGcodeWriter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 6008826fbf..f2a504e953 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -1643,7 +1643,8 @@ void FffGcodeWriter::addMeshLayerToGCode_meshSurfaceMode(const SliceMeshStorage& Polygons polygons; for (const SliceLayerPart& part : layer->parts) { - polygons.add(part.outline); + if(!part.outline.empty()) + polygons.add(part.outline); } polygons = Simplify(mesh.settings).polygon(polygons); @@ -1707,7 +1708,10 @@ void FffGcodeWriter::addMeshLayerToGCode( { part_order_optimizer.addPolygon(&part); } - part_order_optimizer.optimize(false); + if (part_order_optimizer.vertices_to_paths_.size() > 1) + { + part_order_optimizer.optimize(false); + } for (const PathOrdering& path : part_order_optimizer.paths_) { addMeshPartToGCode(storage, mesh, extruder_nr, mesh_config, *path.vertices_, gcode_layer); From 3303a52dcd53e5d4f5c5767483a6153dcafd2dfd Mon Sep 17 00:00:00 2001 From: saumyaj3 Date: Tue, 13 Feb 2024 14:05:39 +0000 Subject: [PATCH 26/34] Applied clang-format. --- src/FffGcodeWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index f2a504e953..705ecbebcb 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -1643,7 +1643,7 @@ void FffGcodeWriter::addMeshLayerToGCode_meshSurfaceMode(const SliceMeshStorage& Polygons polygons; for (const SliceLayerPart& part : layer->parts) { - if(!part.outline.empty()) + if (! part.outline.empty()) polygons.add(part.outline); } From b8f6bbfa1517c154f8d87e39ce705d387e6159c5 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 13 Feb 2024 15:07:45 +0100 Subject: [PATCH 27/34] preventing empty outline slicelayerpart preventive coading CURA-11570 --- src/FffPolygonGenerator.cpp | 145 +++++++++++++++++++----------------- src/layerPart.cpp | 8 ++ src/skin.cpp | 4 + src/sliceDataStorage.cpp | 5 +- src/support.cpp | 4 + 5 files changed, 98 insertions(+), 68 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 384093794c..a146db73cb 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -568,6 +568,10 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz // they have to be polylines, because they might break up further when doing the cutting for (SliceLayerPart& part : layer.parts) { + if(part.outline.empty()) + { + continue; + } for (PolygonRef poly : part.outline) { layer.openPolyLines.add(poly); @@ -642,6 +646,10 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz layer.parts.clear(); for (PolygonsPart& part : new_parts) { + if (part.empty()){ + spdlog::warn("ffp"); + continue; + } layer.parts.emplace_back(); layer.parts.back().outline = part; layer.parts.back().boundaryBox.calculate(part); @@ -1101,96 +1109,99 @@ void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh) SliceLayer& layer = mesh.layers[layer_nr]; for (SliceLayerPart& part : layer.parts) { - std::vector result_paths; - for (auto& toolpath : part.wall_toolpaths) + if (!part.outline.empty()) { - if (toolpath.front().inset_idx_ != 0) - { - result_paths.push_back(toolpath); - continue; - } - - auto& result_lines = result_paths.emplace_back(); - - if (apply_outside_only) + std::vector result_paths; + for (auto& toolpath : part.wall_toolpaths) { - hole_area = part.print_outline.getOutsidePolygons().offset(-line_width); - accumulate_is_in_hole = [&hole_area](const bool& prev_result, const ExtrusionJunction& junction) + if (toolpath.front().inset_idx_ != 0) { - return prev_result || hole_area.inside(junction.p_); - }; - } - for (auto& line : toolpath) - { - if (apply_outside_only && std::accumulate(line.begin(), line.end(), false, accumulate_is_in_hole)) - { - result_lines.push_back(line); + result_paths.push_back(toolpath); continue; } - auto& result = result_lines.emplace_back(line.inset_idx_, line.is_odd_, line.is_closed_); + auto& result_lines = result_paths.emplace_back(); - // generate points in between p0 and p1 - int64_t dist_left_over - = (min_dist_between_points / 4) + rand() % (min_dist_between_points / 4); // the distance to be traversed on the line before making the first new point - auto* p0 = &line.front(); - for (auto& p1 : line) + if (apply_outside_only) { - if (p0->p_ == p1.p_) // avoid seams + hole_area = part.print_outline.getOutsidePolygons().offset(-line_width); + accumulate_is_in_hole = [&hole_area](const bool& prev_result, const ExtrusionJunction& junction) { - result.emplace_back(p1.p_, p1.w_, p1.perimeter_index_); + return prev_result || hole_area.inside(junction.p_); + }; + } + for (auto& line : toolpath) + { + if (apply_outside_only && std::accumulate(line.begin(), line.end(), false, accumulate_is_in_hole)) + { + result_lines.push_back(line); continue; } - // 'a' is the (next) new point between p0 and p1 - const Point2LL p0p1 = p1.p_ - p0->p_; - const int64_t p0p1_size = vSize(p0p1); - int64_t p0pa_dist = dist_left_over; - if (p0pa_dist >= p0p1_size) + auto& result = result_lines.emplace_back(line.inset_idx_, line.is_odd_, line.is_closed_); + + // generate points in between p0 and p1 + int64_t dist_left_over + = (min_dist_between_points / 4) + rand() % (min_dist_between_points / 4); // the distance to be traversed on the line before making the first new point + auto* p0 = &line.front(); + for (auto& p1 : line) { - const Point2LL p = p1.p_ - (p0p1 / 2); - const double width = (p1.w_ * vSize(p1.p_ - p) + p0->w_ * vSize(p0->p_ - p)) / p0p1_size; - result.emplace_back(p, width, p1.perimeter_index_); + if (p0->p_ == p1.p_) // avoid seams + { + result.emplace_back(p1.p_, p1.w_, p1.perimeter_index_); + continue; + } + + // 'a' is the (next) new point between p0 and p1 + const Point2LL p0p1 = p1.p_ - p0->p_; + const int64_t p0p1_size = vSize(p0p1); + int64_t p0pa_dist = dist_left_over; + if (p0pa_dist >= p0p1_size) + { + const Point2LL p = p1.p_ - (p0p1 / 2); + const double width = (p1.w_ * vSize(p1.p_ - p) + p0->w_ * vSize(p0->p_ - p)) / p0p1_size; + result.emplace_back(p, width, p1.perimeter_index_); + } + for (; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist) + { + const int r = rand() % (fuzziness * 2) - fuzziness; + const Point2LL perp_to_p0p1 = turn90CCW(p0p1); + const Point2LL fuzz = normal(perp_to_p0p1, r); + const Point2LL pa = p0->p_ + normal(p0p1, p0pa_dist); + const double width = (p1.w_ * vSize(p1.p_ - pa) + p0->w_ * vSize(p0->p_ - pa)) / p0p1_size; + result.emplace_back(pa + fuzz, width, p1.perimeter_index_); + } + // p0pa_dist > p0p1_size now because we broke out of the for-loop + dist_left_over = p0pa_dist - p0p1_size; + + p0 = &p1; } - for (; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist) + while (result.size() < 3) { - const int r = rand() % (fuzziness * 2) - fuzziness; - const Point2LL perp_to_p0p1 = turn90CCW(p0p1); - const Point2LL fuzz = normal(perp_to_p0p1, r); - const Point2LL pa = p0->p_ + normal(p0p1, p0pa_dist); - const double width = (p1.w_ * vSize(p1.p_ - pa) + p0->w_ * vSize(p0->p_ - pa)) / p0p1_size; - result.emplace_back(pa + fuzz, width, p1.perimeter_index_); + size_t point_idx = line.size() - 2; + result.emplace_back(line[point_idx].p_, line[point_idx].w_, line[point_idx].perimeter_index_); + if (point_idx == 0) + { + break; + } + point_idx--; } - // p0pa_dist > p0p1_size now because we broke out of the for-loop - dist_left_over = p0pa_dist - p0p1_size; - - p0 = &p1; - } - while (result.size() < 3) - { - size_t point_idx = line.size() - 2; - result.emplace_back(line[point_idx].p_, line[point_idx].w_, line[point_idx].perimeter_index_); - if (point_idx == 0) + if (result.size() < 3) { - break; + result.clear(); + for (auto& p : line) + { + result.emplace_back(p.p_, p.w_, p.perimeter_index_); + } } - point_idx--; - } - if (result.size() < 3) - { - result.clear(); - for (auto& p : line) + if (line.back().p_ == line.front().p_) // avoid seams { - result.emplace_back(p.p_, p.w_, p.perimeter_index_); + result.back().p_ = result.front().p_; } } - if (line.back().p_ == line.front().p_) // avoid seams - { - result.back().p_ = result.front().p_; - } } + part.wall_toolpaths = result_paths; } - part.wall_toolpaths = result_paths; } } } diff --git a/src/layerPart.cpp b/src/layerPart.cpp index b0fb7ece93..db08a9a196 100644 --- a/src/layerPart.cpp +++ b/src/layerPart.cpp @@ -51,6 +51,10 @@ void createLayerWithParts(const Settings& settings, SliceLayer& storageLayer, Sl result.reserve(layer->polygons.size()); for (const PolygonRef poly : layer->polygons) { + if (poly.empty()) + { + continue; + } result.emplace_back(); result.back().add(poly); } @@ -63,6 +67,10 @@ void createLayerWithParts(const Settings& settings, SliceLayer& storageLayer, Sl for (auto& part : result) { storageLayer.parts.emplace_back(); + if (part.empty()) + { + continue; + } storageLayer.parts.back().outline = part; storageLayer.parts.back().boundaryBox.calculate(storageLayer.parts.back().outline); if (storageLayer.parts.back().outline.empty()) diff --git a/src/skin.cpp b/src/skin.cpp index 1f36864698..0fbd302541 100644 --- a/src/skin.cpp +++ b/src/skin.cpp @@ -156,6 +156,10 @@ void SkinInfillAreaComputation::generateSkinAndInfillAreas(SliceLayerPart& part) for (PolygonsPart& skin_area_part : skin.splitIntoParts()) { + if (skin_area_part.empty()) + { + continue; + } part.skin_parts.emplace_back(); part.skin_parts.back().outline = skin_area_part; } diff --git a/src/sliceDataStorage.cpp b/src/sliceDataStorage.cpp index e87250191b..3f94495d89 100644 --- a/src/sliceDataStorage.cpp +++ b/src/sliceDataStorage.cpp @@ -740,7 +740,10 @@ void SupportLayer::excludeAreasFromSupportInfillAreas(const Polygons& exclude_po { const size_t remove_idx = to_remove_part_indices.back(); to_remove_part_indices.pop_back(); - + if (support_infill_parts.empty()) + { + continue; + } if (remove_idx < support_infill_parts.size() - 1) { // move last element to the to-be-removed element so that we can erase the last place in the vector support_infill_parts[remove_idx] = std::move(support_infill_parts.back()); diff --git a/src/support.cpp b/src/support.cpp index 3ef52db616..3097afdbbb 100644 --- a/src/support.cpp +++ b/src/support.cpp @@ -1491,6 +1491,10 @@ void AreaSupport::detectOverhangPoints(const SliceDataStorage& storage, SliceMes for (const SliceLayerPart& part : layer.parts) { + if (part.outline.empty()) + { + continue; + } if (part.outline.outerPolygon().area() >= max_tower_supported_area) { // area is too big for support towers, should be supported by normal overhang detection From 8ae9aabf7e71f06b0e3557429b87b94c153b0acf Mon Sep 17 00:00:00 2001 From: saumyaj3 Date: Tue, 13 Feb 2024 14:08:37 +0000 Subject: [PATCH 28/34] Applied clang-format. --- src/FffPolygonGenerator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index a146db73cb..40dc3fe87f 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -568,7 +568,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz // they have to be polylines, because they might break up further when doing the cutting for (SliceLayerPart& part : layer.parts) { - if(part.outline.empty()) + if (part.outline.empty()) { continue; } @@ -646,7 +646,8 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz layer.parts.clear(); for (PolygonsPart& part : new_parts) { - if (part.empty()){ + if (part.empty()) + { spdlog::warn("ffp"); continue; } @@ -1109,7 +1110,7 @@ void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh) SliceLayer& layer = mesh.layers[layer_nr]; for (SliceLayerPart& part : layer.parts) { - if (!part.outline.empty()) + if (! part.outline.empty()) { std::vector result_paths; for (auto& toolpath : part.wall_toolpaths) From 5f7c0d78ed457a1d86f5a0945391fac846bf9409 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 13 Feb 2024 15:18:20 +0100 Subject: [PATCH 29/34] removing debug message CURA-11570 --- src/FffPolygonGenerator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 40dc3fe87f..5be91a2bc6 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023 UltiMaker +// Copyright (c) 2024 UltiMaker // CuraEngine is released under the terms of the AGPLv3 or higher #include @@ -648,7 +648,6 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz { if (part.empty()) { - spdlog::warn("ffp"); continue; } layer.parts.emplace_back(); From 57d528ba6d453b5aaaf62514fbf170ba3584c92d Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 13 Feb 2024 16:12:31 +0100 Subject: [PATCH 30/34] removing condition on fuzzy skin not needed CURA-11570 --- src/FffPolygonGenerator.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 5be91a2bc6..3a3ea6461c 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -1109,9 +1109,7 @@ void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh) SliceLayer& layer = mesh.layers[layer_nr]; for (SliceLayerPart& part : layer.parts) { - if (! part.outline.empty()) - { - std::vector result_paths; + std::vector result_paths; for (auto& toolpath : part.wall_toolpaths) { if (toolpath.front().inset_idx_ != 0) @@ -1201,7 +1199,6 @@ void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh) } } part.wall_toolpaths = result_paths; - } } } } From 1d1746d1f9e67b64ec9321537d2df31ed7a088dc Mon Sep 17 00:00:00 2001 From: saumyaj3 Date: Tue, 13 Feb 2024 15:13:42 +0000 Subject: [PATCH 31/34] Applied clang-format. --- src/FffPolygonGenerator.cpp | 136 ++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 3a3ea6461c..ff36a1226c 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -1110,95 +1110,95 @@ void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh) for (SliceLayerPart& part : layer.parts) { std::vector result_paths; - for (auto& toolpath : part.wall_toolpaths) + for (auto& toolpath : part.wall_toolpaths) + { + if (toolpath.front().inset_idx_ != 0) + { + result_paths.push_back(toolpath); + continue; + } + + auto& result_lines = result_paths.emplace_back(); + + if (apply_outside_only) + { + hole_area = part.print_outline.getOutsidePolygons().offset(-line_width); + accumulate_is_in_hole = [&hole_area](const bool& prev_result, const ExtrusionJunction& junction) + { + return prev_result || hole_area.inside(junction.p_); + }; + } + for (auto& line : toolpath) { - if (toolpath.front().inset_idx_ != 0) + if (apply_outside_only && std::accumulate(line.begin(), line.end(), false, accumulate_is_in_hole)) { - result_paths.push_back(toolpath); + result_lines.push_back(line); continue; } - auto& result_lines = result_paths.emplace_back(); + auto& result = result_lines.emplace_back(line.inset_idx_, line.is_odd_, line.is_closed_); - if (apply_outside_only) + // generate points in between p0 and p1 + int64_t dist_left_over + = (min_dist_between_points / 4) + rand() % (min_dist_between_points / 4); // the distance to be traversed on the line before making the first new point + auto* p0 = &line.front(); + for (auto& p1 : line) { - hole_area = part.print_outline.getOutsidePolygons().offset(-line_width); - accumulate_is_in_hole = [&hole_area](const bool& prev_result, const ExtrusionJunction& junction) + if (p0->p_ == p1.p_) // avoid seams { - return prev_result || hole_area.inside(junction.p_); - }; - } - for (auto& line : toolpath) - { - if (apply_outside_only && std::accumulate(line.begin(), line.end(), false, accumulate_is_in_hole)) - { - result_lines.push_back(line); + result.emplace_back(p1.p_, p1.w_, p1.perimeter_index_); continue; } - auto& result = result_lines.emplace_back(line.inset_idx_, line.is_odd_, line.is_closed_); - - // generate points in between p0 and p1 - int64_t dist_left_over - = (min_dist_between_points / 4) + rand() % (min_dist_between_points / 4); // the distance to be traversed on the line before making the first new point - auto* p0 = &line.front(); - for (auto& p1 : line) + // 'a' is the (next) new point between p0 and p1 + const Point2LL p0p1 = p1.p_ - p0->p_; + const int64_t p0p1_size = vSize(p0p1); + int64_t p0pa_dist = dist_left_over; + if (p0pa_dist >= p0p1_size) { - if (p0->p_ == p1.p_) // avoid seams - { - result.emplace_back(p1.p_, p1.w_, p1.perimeter_index_); - continue; - } - - // 'a' is the (next) new point between p0 and p1 - const Point2LL p0p1 = p1.p_ - p0->p_; - const int64_t p0p1_size = vSize(p0p1); - int64_t p0pa_dist = dist_left_over; - if (p0pa_dist >= p0p1_size) - { - const Point2LL p = p1.p_ - (p0p1 / 2); - const double width = (p1.w_ * vSize(p1.p_ - p) + p0->w_ * vSize(p0->p_ - p)) / p0p1_size; - result.emplace_back(p, width, p1.perimeter_index_); - } - for (; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist) - { - const int r = rand() % (fuzziness * 2) - fuzziness; - const Point2LL perp_to_p0p1 = turn90CCW(p0p1); - const Point2LL fuzz = normal(perp_to_p0p1, r); - const Point2LL pa = p0->p_ + normal(p0p1, p0pa_dist); - const double width = (p1.w_ * vSize(p1.p_ - pa) + p0->w_ * vSize(p0->p_ - pa)) / p0p1_size; - result.emplace_back(pa + fuzz, width, p1.perimeter_index_); - } - // p0pa_dist > p0p1_size now because we broke out of the for-loop - dist_left_over = p0pa_dist - p0p1_size; - - p0 = &p1; + const Point2LL p = p1.p_ - (p0p1 / 2); + const double width = (p1.w_ * vSize(p1.p_ - p) + p0->w_ * vSize(p0->p_ - p)) / p0p1_size; + result.emplace_back(p, width, p1.perimeter_index_); } - while (result.size() < 3) + for (; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist) { - size_t point_idx = line.size() - 2; - result.emplace_back(line[point_idx].p_, line[point_idx].w_, line[point_idx].perimeter_index_); - if (point_idx == 0) - { - break; - } - point_idx--; + const int r = rand() % (fuzziness * 2) - fuzziness; + const Point2LL perp_to_p0p1 = turn90CCW(p0p1); + const Point2LL fuzz = normal(perp_to_p0p1, r); + const Point2LL pa = p0->p_ + normal(p0p1, p0pa_dist); + const double width = (p1.w_ * vSize(p1.p_ - pa) + p0->w_ * vSize(p0->p_ - pa)) / p0p1_size; + result.emplace_back(pa + fuzz, width, p1.perimeter_index_); } - if (result.size() < 3) + // p0pa_dist > p0p1_size now because we broke out of the for-loop + dist_left_over = p0pa_dist - p0p1_size; + + p0 = &p1; + } + while (result.size() < 3) + { + size_t point_idx = line.size() - 2; + result.emplace_back(line[point_idx].p_, line[point_idx].w_, line[point_idx].perimeter_index_); + if (point_idx == 0) { - result.clear(); - for (auto& p : line) - { - result.emplace_back(p.p_, p.w_, p.perimeter_index_); - } + break; } - if (line.back().p_ == line.front().p_) // avoid seams + point_idx--; + } + if (result.size() < 3) + { + result.clear(); + for (auto& p : line) { - result.back().p_ = result.front().p_; + result.emplace_back(p.p_, p.w_, p.perimeter_index_); } } + if (line.back().p_ == line.front().p_) // avoid seams + { + result.back().p_ = result.front().p_; + } } - part.wall_toolpaths = result_paths; + } + part.wall_toolpaths = result_paths; } } } From cd858c15c9cc50f77314863c611b1fe10c2b4207 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 13 Feb 2024 17:53:20 +0100 Subject: [PATCH 32/34] removing another non necessary condition CURA-11570 --- src/FffPolygonGenerator.cpp | 8 ++------ src/skin.cpp | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index ff36a1226c..765492eee6 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -568,11 +568,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz // they have to be polylines, because they might break up further when doing the cutting for (SliceLayerPart& part : layer.parts) { - if (part.outline.empty()) - { - continue; - } - for (PolygonRef poly : part.outline) + for (const PolygonRef poly : part.outline) { layer.openPolyLines.add(poly); layer.openPolyLines.back().add(layer.openPolyLines.back()[0]); // add the segment which closes the polygon @@ -644,7 +640,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz } layer.parts.clear(); - for (PolygonsPart& part : new_parts) + for (const PolygonsPart& part : new_parts) { if (part.empty()) { diff --git a/src/skin.cpp b/src/skin.cpp index 0fbd302541..842a6e576f 100644 --- a/src/skin.cpp +++ b/src/skin.cpp @@ -154,7 +154,7 @@ void SkinInfillAreaComputation::generateSkinAndInfillAreas(SliceLayerPart& part) generateInfill(part); } - for (PolygonsPart& skin_area_part : skin.splitIntoParts()) + for (const PolygonsPart& skin_area_part : skin.splitIntoParts()) { if (skin_area_part.empty()) { From 1cac0af0d101c161a3a4555987b2b7afd7691ab5 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 14 Feb 2024 20:57:04 +0100 Subject: [PATCH 33/34] Code-style. + If const then it can also be a reference. done as part of CURA-11570 --- src/FffGcodeWriter.cpp | 2 ++ src/FffPolygonGenerator.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 705ecbebcb..db6cb931e0 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -1644,7 +1644,9 @@ void FffGcodeWriter::addMeshLayerToGCode_meshSurfaceMode(const SliceMeshStorage& for (const SliceLayerPart& part : layer->parts) { if (! part.outline.empty()) + { polygons.add(part.outline); + } } polygons = Simplify(mesh.settings).polygon(polygons); diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 765492eee6..4b79053174 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -568,7 +568,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz // they have to be polylines, because they might break up further when doing the cutting for (SliceLayerPart& part : layer.parts) { - for (const PolygonRef poly : part.outline) + for (const PolygonRef& poly : part.outline) { layer.openPolyLines.add(poly); layer.openPolyLines.back().add(layer.openPolyLines.back()[0]); // add the segment which closes the polygon From db1231e4e6aee630436347ebfc52289bc7546619 Mon Sep 17 00:00:00 2001 From: saumyaj3 Date: Thu, 15 Feb 2024 09:20:49 +0000 Subject: [PATCH 34/34] Applied clang-format. --- src/TreeSupport.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TreeSupport.cpp b/src/TreeSupport.cpp index d5b48ab758..9ac7a9eebb 100644 --- a/src/TreeSupport.cpp +++ b/src/TreeSupport.cpp @@ -156,10 +156,10 @@ void TreeSupport::generateSupportAreas(SliceDataStorage& storage) // ### Precalculate avoidances, collision etc. const LayerIndex max_required_layer = precalculate(storage, processing.second); - if(max_required_layer < 0) + if (max_required_layer < 0) { - spdlog::info("Support tree mesh group {} does not have any overhang. Skipping tree support generation for this support tree mesh group.",counter + 1); - continue; //If there is no overhang to support, skip these meshes + spdlog::info("Support tree mesh group {} does not have any overhang. Skipping tree support generation for this support tree mesh group.", counter + 1); + continue; // If there is no overhang to support, skip these meshes } const auto t_precalc = std::chrono::high_resolution_clock::now(); @@ -245,7 +245,7 @@ LayerIndex TreeSupport::precalculate(const SliceDataStorage& storage, std::vecto } // ### The actual precalculation happens in TreeModelVolumes. - if(max_layer >= 0) + if (max_layer >= 0) { volumes_.precalculate(max_layer); }