From 0009d17c74c68dd1a8d417bb9d503020e2002aa9 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Mar 2024 07:50:05 +0100 Subject: [PATCH] Avoid seam on overhang positions by checking the area covered below CURA-11630 --- include/PathOrderOptimizer.h | 17 ++++++++++++++++- src/InsetOrderOptimizer.cpp | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/include/PathOrderOptimizer.h b/include/PathOrderOptimizer.h index df1cc07c7e..e6d06f2a7f 100644 --- a/include/PathOrderOptimizer.h +++ b/include/PathOrderOptimizer.h @@ -87,6 +87,8 @@ class PathOrderOptimizer */ ZSeamConfig seam_config_; + Polygons model_outline_layer_below_; + static const std::unordered_multimap no_order_requirements_; /*! @@ -110,7 +112,8 @@ class PathOrderOptimizer const Polygons* combing_boundary = nullptr, const bool reverse_direction = false, const std::unordered_multimap& order_requirements = no_order_requirements_, - const bool group_outer_walls = false) + const bool group_outer_walls = false, + const Polygons& model_outline_layer_below = Polygons()) : start_point_(start_point) , seam_config_(seam_config) , combing_boundary_((combing_boundary != nullptr && ! combing_boundary->empty()) ? combing_boundary : nullptr) @@ -118,6 +121,7 @@ class PathOrderOptimizer , reverse_direction_(reverse_direction) , _group_outer_walls(group_outer_walls) , order_requirements_(&order_requirements) + , model_outline_layer_below_(model_outline_layer_below) { } @@ -718,6 +722,17 @@ class PathOrderOptimizer } } + // TBD: Create the circle once (with a slightly higher res) and translate for every point + Polygons circle; + circle.add(PolygonUtils::makeCircle(here, 200)); + Polygons supported_area = model_outline_layer_below_.intersection(circle); + double area = supported_area.area(); + static constexpr double max_area = std::numbers::pi * (200 * 200); + if (area > 0.0) + { + score /= 1 - std::pow((area / max_area - 1), 2); + } + constexpr double EPSILON = 5.0; if (std::abs(best_score - score) <= EPSILON) { diff --git a/src/InsetOrderOptimizer.cpp b/src/InsetOrderOptimizer.cpp index 82d4199d01..efd516824e 100644 --- a/src/InsetOrderOptimizer.cpp +++ b/src/InsetOrderOptimizer.cpp @@ -98,8 +98,37 @@ bool InsetOrderOptimizer::addToLayer() const auto group_outer_walls = settings_.get("group_outer_walls"); // When we alternate walls, also alternate the direction at which the first wall starts in. // On even layers we start with normal direction, on odd layers with inverted direction. - PathOrderOptimizer - order_optimizer(gcode_layer_.getLastPlannedPositionOrStartingPosition(), z_seam_config_, detect_loops, combing_boundary, reverse, order, group_outer_walls); + + // SVG svg(fmt::format("/tmp/outline_{}.svg", layer_nr_.value), AABB(storage_.getMachineBorder()), 0.001); + + Polygons model_outline_layer_below; + if (layer_nr_ == 0) + { + model_outline_layer_below = storage_.getMachineBorder(); + } + else + { + for (const std::shared_ptr& mesh : storage_.meshes) + { + const SliceLayer& slice_layer = mesh->layers[layer_nr_ - 1]; + for (const SliceLayerPart& part : slice_layer.parts) + { + model_outline_layer_below.add(part.print_outline); + } + } + } + + // svg.writePolygons(model_outline_layer_below, SVG::Color::BLACK, 0.05); + + PathOrderOptimizer order_optimizer( + gcode_layer_.getLastPlannedPositionOrStartingPosition(), + z_seam_config_, + detect_loops, + combing_boundary, + reverse, + order, + group_outer_walls, + model_outline_layer_below); for (const auto& line : walls_to_be_added) {