From e87dcffff1296c7292771db4639764c462c86090 Mon Sep 17 00:00:00 2001 From: Thomas Rahm <67757218+ThomasRahm@users.noreply.github.com> Date: Tue, 20 Dec 2022 22:27:35 +0100 Subject: [PATCH 1/5] Only calculate avoidance to model when it is requested --- src/libslic3r/TreeModelVolumes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libslic3r/TreeModelVolumes.cpp b/src/libslic3r/TreeModelVolumes.cpp index b416db634f..e23064f904 100644 --- a/src/libslic3r/TreeModelVolumes.cpp +++ b/src/libslic3r/TreeModelVolumes.cpp @@ -613,6 +613,8 @@ void TreeModelVolumes::calculateAvoidance(const std::vector &ke BOOST_LOG_TRIVIAL(debug) << "Calculation requested for value already calculated?"; continue; } + if ((task.to_model && !to_model) || (!task.to_model && !to_build_plate)) + continue; if (! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta) avoidance_tasks.emplace_back(task); } From a81f6703d91998a88a8abe8c9465771c83db7eae Mon Sep 17 00:00:00 2001 From: Thomas Rahm <67757218+ThomasRahm@users.noreply.github.com> Date: Tue, 20 Dec 2022 23:09:06 +0100 Subject: [PATCH 2/5] Fix xy_distance overriding overhangs when the overhang angle is smallish --- src/libslic3r/TreeModelVolumes.cpp | 43 ++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/TreeModelVolumes.cpp b/src/libslic3r/TreeModelVolumes.cpp index e23064f904..e0e940dc0b 100644 --- a/src/libslic3r/TreeModelVolumes.cpp +++ b/src/libslic3r/TreeModelVolumes.cpp @@ -494,14 +494,53 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex // 2) Sum over top / bottom ranges. const bool last = outline_idx == layer_outline_indices.size(); tbb::parallel_for(tbb::blocked_range(min_layer_last + 1, max_layer_idx + 1), - [&collision_areas_offsetted, &anti_overhang = m_anti_overhang, min_layer_bottom, radius, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last] + [&collision_areas_offsetted, &outlines, &machine_border = m_machine_border, &anti_overhang = m_anti_overhang, min_layer_bottom, radius, xy_distance, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last] (const tbb::blocked_range& range) { for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) { Polygons collisions; for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) { int j = layer_idx + i - min_layer_bottom; - if (j >= 0 && j < int(collision_areas_offsetted.size())) + if (j >= 0 && j < int(collision_areas_offsetted.size()) && i <= 0) append(collisions, collision_areas_offsetted[j]); + else if (j >= 0 && layer_idx + i < int(outlines.size()) && i > 0) { + Polygons collision_areas_original = machine_border; + append(collision_areas_original, outlines[layer_idx + i]); + + // If just the collision (including the xy distance) of the layers above is accumulated, it leads to the + // following issue: + // Example: assuming the z distance is 2 layer + // + = xy_distance + // - = model + // o = overhang of the area two layers above that should result in tips on this layer + // + // +-----+ + // +-----+ + // +-----+ + // o +-----+ + // If just the collision above is accumulated the overhang will get overwritten by the xy_distance of the + // layer below the overhang... + // + // This only causes issues if the overhang area is thinner than xy_distance + // Just accumulating areas of the model above without the xy distance is also problematic, as then support + // may get closer to the model (on the diagonal downwards) than the user intended. Example (s = support): + // +-----+ + // +-----+ + // +-----+ + // s+-----+ + + // technically the calculation below is off by one layer, as the actual distance between plastic one layer + // down is 0 not layer height, as this layer is filled with said plastic. But otherwise a part of the + // overhang that is expected to be supported is overwritten by the remaining part of the xy distance of the + // layer below the to be supported area. + coord_t required_range_x = + (xy_distance - ((i - (z_distance_top_layers == 1 ? 0.5 : 0)) * xy_distance / z_distance_top_layers)); + // the conditional -0.5 ensures that plastic can never touch on the diagonal + // downward when the z_distance_top_layers = 1. It is assumed to be better to + // not support an overhang<90 degree than to risk fusing to it. + + collision_areas_original = offset(union_ex(collision_areas_original), radius + required_range_x, ClipperLib::jtMiter, 1.2); + append(collisions, collision_areas_original); + } } collisions = last && layer_idx < int(anti_overhang.size()) ? union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) : union_(collisions); auto &dst = data[layer_idx - (min_layer_last + 1)]; From 6db30602a0f3e7aa3950e6fa730be2b11387c319 Mon Sep 17 00:00:00 2001 From: Thomas Rahm <67757218+ThomasRahm@users.noreply.github.com> Date: Tue, 20 Dec 2022 23:33:03 +0100 Subject: [PATCH 3/5] Make supported overhangs not differ between a tip radius of half of a line width to a tip radius of one line width --- src/libslic3r/TreeSupport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 1f0aa00b23..37ab584ffb 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -893,7 +893,7 @@ static void generate_initial_areas( //FIXME Vojtech: This is not sufficient for support enforcers to work. //FIXME There is no account for the support overhang angle. //FIXME There is no account for the width of the collision regions. - const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0) + const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width / 2) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0) //FIXME this is a heuristic value for support enforcers to work. // + 10 * mesh_config.support_line_width; ; From 062a619381b4c9c9e55ac1e3562643164bea6c2e Mon Sep 17 00:00:00 2001 From: Thomas Rahm <67757218+ThomasRahm@users.noreply.github.com> Date: Fri, 13 Jan 2023 02:58:43 +0100 Subject: [PATCH 4/5] Ensure that no points are placed the implicit line from last to first vertex, as the input is a line and not a polygon. --- src/libslic3r/TreeSupport.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 37ab584ffb..c48ef230b5 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -554,7 +554,8 @@ static std::optional> polyline_sample_next_point_at_dis double next_distance = current_distance; // Get points so that at least min_points are added and they each are current_distance away from each other. If that is impossible, decrease current_distance a bit. // The input are lines, that means that the line from the last to the first vertex does not have to exist, so exclude all points that are on this line! - while ((next_point = polyline_sample_next_point_at_distance(part.points, current_point, current_index, next_distance))) { + while ((next_point = polyline_sample_next_point_at_distance(part.points, current_point, current_index, next_distance)) && + next_point->second < coord_t(part.size()) - 1) { // Not every point that is distance away, is valid, as it may be much closer to another point. This is especially the case when the overhang is very thin. // So this ensures that the points are actually a certain distance from each other. // This assurance is only made on a per polygon basis, as different but close polygon may not be able to use support below the other polygon. @@ -3455,16 +3456,18 @@ static void draw_branches( const double max_nudge_smoothing = 1. * scale; static constexpr const size_t num_iter = 100; // 1000; - for (size_t iter = 0; iter < num_iter; ++ iter) { + for (size_t iter = 0; iter < num_iter; ++iter) { prev = pts; projections = pts; distances.assign(pts.size(), std::numeric_limits::max()); closest_surface_point->searchAndReplace(projections, distances); size_t num_moved = 0; + for (size_t i = 0; i < projections.size(); ++ i) { const SupportElement &element = *elements_with_link_down[i].first; const int below = elements_with_link_down[i].second; const bool locked = below == -1 && element.state.layer_idx > 0; + if (! locked && pts[i] != projections[i]) { // Nudge the circle center away from the collision. Vec3d v{ projections[i].x() - pts[i].x(), projections[i].y() - pts[i].y(), projections[i].z() - pts[i].z() }; From c9605580ee684d6f6c40e74566fe3a952a56ebbc Mon Sep 17 00:00:00 2001 From: Thomas Rahm <67757218+ThomasRahm@users.noreply.github.com> Date: Thu, 2 Feb 2023 23:19:03 +0100 Subject: [PATCH 5/5] Fix issue causing some tips to not generate, as remaining_overhang was nearly always empty Fixes https://github.com/prusa3d/PrusaSlicer/issues/9459 --- src/libslic3r/TreeSupport.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index c48ef230b5..19e4c7d899 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -1055,9 +1055,8 @@ static void generate_initial_areas( Polygons overhang_regular; { const Polygons &overhang_raw = overhangs[layer_idx + z_distance_delta]; - overhang_regular = mesh_group_settings.support_offset == 0 ? - overhang_raw : - safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1); + // When support_offset = 0 safe_offset_inc will only be the difference between overhang_raw and relevant_forbidden, that has to be calculated anyway. + overhang_regular = safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1); //check_self_intersections(overhang_regular, "overhang_regular1"); // offset ensures that areas that could be supported by a part of a support line, are not considered unsupported overhang