From 26fbf6e11162d13fdd60b860f923aa6525b466d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ach?= Date: Wed, 27 Sep 2023 14:22:38 +0200 Subject: [PATCH] Refactor out reckon_new_support_point In support spots generator, reckon_new_support_point was lamda with many captures. This led to confusion. Now it is a proper function. --- src/libslic3r/SupportSpotsGenerator.cpp | 138 ++++++++++++++---------- src/libslic3r/SupportSpotsGenerator.hpp | 7 +- 2 files changed, 84 insertions(+), 61 deletions(-) diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index 4d531900b4..93389a6d03 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -53,8 +53,12 @@ #ifdef DEBUG_FILES #include #include "libslic3r/Color.hpp" +constexpr bool debug_files = true; +#else +constexpr bool debug_files = false; #endif + namespace Slic3r::SupportSpotsGenerator { ExtrusionLine::ExtrusionLine() : a(Vec2f::Zero()), b(Vec2f::Zero()), len(0.0), origin_entity(nullptr) {} @@ -72,10 +76,6 @@ bool ExtrusionLine::is_external_perimeter() const return origin_entity->role().is_external_perimeter(); } -auto get_a(ExtrusionLine &&l) { return l.a; } -auto get_b(ExtrusionLine &&l) { return l.b; } - - using LD = AABBTreeLines::LinesDistancer; struct SupportGridFilter @@ -761,6 +761,41 @@ public: } }; +// Function that is used when new support point is generated. It will update the ObjectPart stability, weakest conneciton info, +// and the support presence grid and add the point to the issues. +void reckon_new_support_point(ObjectPart &part, + SliceConnection &weakest_conn, + SupportPoints &supp_points, + SupportGridFilter &supports_presence_grid, + const SupportPoint& support_point, + bool is_global = false) +{ + // if position is taken and point is for global stability (force > 0) or we are too close to the bed, do not add + // This allows local support points (e.g. bridging) to be generated densely + if ((supports_presence_grid.position_taken(support_point.position) && is_global)) { + return; + } + + float area = support_point.spot_radius * support_point.spot_radius * float(PI); + // add the stability effect of the point only if the spot is not taken, so that the densely created local support points do + // not add unrealistic amount of stability to the object (due to overlaping of local support points) + if (!(supports_presence_grid.position_taken(support_point.position))) { + part.add_support_point(support_point.position, area); + } + + supp_points.push_back(support_point); + supports_presence_grid.take_position(support_point.position); + + // The support point also increases the stability of the weakest connection of the object, which should be reflected + if (weakest_conn.area > EPSILON) { // Do not add it to the weakest connection if it is not valid - does not exist + weakest_conn.area += area; + weakest_conn.centroid_accumulator += support_point.position * area; + weakest_conn.second_moment_of_area_accumulator += area * + support_point.position.head<2>().cwiseProduct(support_point.position.head<2>()); + weakest_conn.second_moment_of_area_covariance_accumulator += area * support_point.position.x() * support_point.position.y(); + } +} + std::tuple check_stability(const PrintObject *po, const PrecomputedSliceConnections &precomputed_slices_connections, const PrintTryCancel &cancel_func, @@ -931,23 +966,37 @@ std::tuple check_stability(const PrintObject std::vector> unstable_lines_per_slice(layer->lslices_ex.size()); std::vector> ext_perim_lines_per_slice(layer->lslices_ex.size()); - tbb::parallel_for(tbb::blocked_range(0, entities_to_check.size()), - [&entities_to_check, &prev_layer_ext_perim_lines, &prev_layer_boundary, &unstable_lines_per_slice, - &ext_perim_lines_per_slice, ¶ms](tbb::blocked_range r) { - for (size_t entity_idx = r.begin(); entity_idx < r.end(); ++entity_idx) { - const auto &e_to_check = entities_to_check[entity_idx]; - for (const auto &line : - check_extrusion_entity_stability(e_to_check.e, e_to_check.region, prev_layer_ext_perim_lines, - prev_layer_boundary, params)) { - if (line.support_point_generated.has_value()) { - unstable_lines_per_slice[e_to_check.slice_idx].push_back(line); - } - if (line.is_external_perimeter()) { - ext_perim_lines_per_slice[e_to_check.slice_idx].push_back(line); + if constexpr (debug_files) { + for (const auto &e_to_check : entities_to_check) { + for (const auto &line : check_extrusion_entity_stability(e_to_check.e, e_to_check.region, prev_layer_ext_perim_lines, + prev_layer_boundary, params)) { + if (line.support_point_generated.has_value()) { + unstable_lines_per_slice[e_to_check.slice_idx].push_back(line); + } + if (line.is_external_perimeter()) { + ext_perim_lines_per_slice[e_to_check.slice_idx].push_back(line); + } + } + } + } else { + tbb::parallel_for(tbb::blocked_range(0, entities_to_check.size()), + [&entities_to_check, &prev_layer_ext_perim_lines, &prev_layer_boundary, &unstable_lines_per_slice, + &ext_perim_lines_per_slice, ¶ms](tbb::blocked_range r) { + for (size_t entity_idx = r.begin(); entity_idx < r.end(); ++entity_idx) { + const auto &e_to_check = entities_to_check[entity_idx]; + for (const auto &line : + check_extrusion_entity_stability(e_to_check.e, e_to_check.region, prev_layer_ext_perim_lines, + prev_layer_boundary, params)) { + if (line.support_point_generated.has_value()) { + unstable_lines_per_slice[e_to_check.slice_idx].push_back(line); + } + if (line.is_external_perimeter()) { + ext_perim_lines_per_slice[e_to_check.slice_idx].push_back(line); + } } } - } - }); + }); + } std::vector current_layer_ext_perims_lines{}; current_layer_ext_perims_lines.reserve(prev_layer_ext_perim_lines.get_lines().size()); @@ -960,40 +1009,14 @@ std::tuple check_stability(const PrintObject #ifdef DETAILED_DEBUG_LOGS weakest_conn.print_info("weakest connection info: "); #endif - // Function that is used when new support point is generated. It will update the ObjectPart stability, weakest conneciton info, - // and the support presence grid and add the point to the issues. - auto reckon_new_support_point = [&part, &weakest_conn, &supp_points, &supports_presence_grid, ¶ms, - &layer_idx](SupportPointCause cause, const Vec3f &support_point, float force, - const Vec2f &dir) { - // if position is taken and point is for global stability (force > 0) or we are too close to the bed, do not add - // This allows local support points (e.g. bridging) to be generated densely - if ((supports_presence_grid.position_taken(support_point) && force > 0) || layer_idx <= 1) { - return; + + if (layer_idx > 1) { + for (const auto &l : unstable_lines_per_slice[slice_idx]) { + assert(l.support_point_generated.has_value()); + SupportPoint support_point{*l.support_point_generated, create_support_point_position(l.b), + params.support_points_interface_radius}; + reckon_new_support_point(part, weakest_conn, supp_points, supports_presence_grid, support_point); } - - float area = params.support_points_interface_radius * params.support_points_interface_radius * float(PI); - // add the stability effect of the point only if the spot is not taken, so that the densely created local support points do - // not add unrealistic amount of stability to the object (due to overlaping of local support points) - if (!(supports_presence_grid.position_taken(support_point))) { - part.add_support_point(support_point, area); - } - - float radius = params.support_points_interface_radius; - supp_points.emplace_back(cause, support_point, force, radius, dir); - supports_presence_grid.take_position(support_point); - - // The support point also increases the stability of the weakest connection of the object, which should be reflected - if (weakest_conn.area > EPSILON) { // Do not add it to the weakest connection if it is not valid - does not exist - weakest_conn.area += area; - weakest_conn.centroid_accumulator += support_point * area; - weakest_conn.second_moment_of_area_accumulator += area * support_point.head<2>().cwiseProduct(support_point.head<2>()); - weakest_conn.second_moment_of_area_covariance_accumulator += area * support_point.x() * support_point.y(); - } - }; - - for (const auto &l : unstable_lines_per_slice[slice_idx]) { - assert(l.support_point_generated.has_value()); - reckon_new_support_point(*l.support_point_generated, create_support_point_position(l.b), float(-EPSILON), Vec2f::Zero()); } LD current_slice_lines_distancer({ext_perim_lines_per_slice[slice_idx].begin(), ext_perim_lines_per_slice[slice_idx].end()}); @@ -1008,10 +1031,13 @@ std::tuple check_stability(const PrintObject Vec2f pivot_site_search_point = Vec2f(line.b + (line.b - line.a).normalized() * 300.0f); auto [dist, nidx, nearest_point] = current_slice_lines_distancer.distance_from_lines_extra(pivot_site_search_point); - Vec3f support_point = create_support_point_position(nearest_point); - auto [force, cause] = part.is_stable_while_extruding(weakest_conn, line, support_point, bottom_z, params); - if (force > 0) { - reckon_new_support_point(cause, support_point, force, (line.b - line.a).normalized()); + Vec3f position = create_support_point_position(nearest_point); + auto [force, cause] = part.is_stable_while_extruding(weakest_conn, line, position, bottom_z, params); + if (force > 0 && layer_idx > 1) { + SupportPoint support_point{ + cause, position, params.support_points_interface_radius + }; + reckon_new_support_point(part, weakest_conn, supp_points, supports_presence_grid, support_point, true); } } } diff --git a/src/libslic3r/SupportSpotsGenerator.hpp b/src/libslic3r/SupportSpotsGenerator.hpp index 62f4e960d4..3cdc222abe 100644 --- a/src/libslic3r/SupportSpotsGenerator.hpp +++ b/src/libslic3r/SupportSpotsGenerator.hpp @@ -104,8 +104,8 @@ enum class SupportPointCause { // Note that the force is only the difference - the amount needed to stabilize the object again. struct SupportPoint { - SupportPoint(SupportPointCause cause, const Vec3f &position, float force, float spot_radius, const Vec2f &direction) - : cause(cause), position(position), force(force), spot_radius(spot_radius), direction(direction) + SupportPoint(SupportPointCause cause, const Vec3f &position, float spot_radius) + : cause(cause), position(position), spot_radius(spot_radius) {} bool is_local_extrusion_support() const @@ -122,12 +122,9 @@ struct SupportPoint // values gathered from large XL model: Min : 0 | Max : 18713800 | Average : 1361186 | Median : 329103 // For reference 18713800 is weight of 1.8 Kg object, 329103 is weight of 0.03 Kg // The final sliced object weight was approx 0.5 Kg - float force; // Expected spot size. The support point strength is calculated from the area defined by this value. // Currently equal to the support_points_interface_radius parameter above float spot_radius; - // direction of the fall of the object (z part is neglected) - Vec2f direction; }; using SupportPoints = std::vector;