From 9bf4a5f14b3cdd081817ef848d03d92a07ccc1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ach?= Date: Fri, 10 May 2024 10:34:56 +0200 Subject: [PATCH] Add continuity modifier to seam aligned. Previously, when searching for the optimal seam candidate, no previous seams were taken into account. This sometimes led to ugly leaps in the seam path. Now the visibility of a seam candidate that continues from a previous seam is reduced, meaning there is a bigger chance it will be picked. --- src/libslic3r/GCode/SeamAligned.cpp | 48 +++++++++++++++++++++++++++-- src/libslic3r/GCode/SeamAligned.hpp | 1 + src/libslic3r/GCode/SeamPlacer.cpp | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode/SeamAligned.cpp b/src/libslic3r/GCode/SeamAligned.cpp index a2e22c6b33..209a5a85d2 100644 --- a/src/libslic3r/GCode/SeamAligned.cpp +++ b/src/libslic3r/GCode/SeamAligned.cpp @@ -420,7 +420,9 @@ std::vector get_shells_seam_candidates( std::vector get_shell_seam( const Shells::Shell<> &shell, - std::vector seam_candidates + std::vector seam_candidates, + const Perimeters::Perimeter::OptionalPointTree &previous_points, + const Params ¶ms ) { std::vector seam; double visibility{std::numeric_limits::infinity()}; @@ -429,8 +431,27 @@ std::vector get_shell_seam( using Perimeters::Perimeter, Perimeters::AngleType; SeamCandidate seam_candidate{seam_candidates[i]}; + const Vec2d first_point{seam_candidate.choices.front().position}; - double seam_candidate_visibility{0.0}; + std::optional closest_point; + if (previous_points) { + std::size_t closest_point_index{find_closest_point(*previous_points, first_point)}; + Vec2d point; + point.x() = previous_points->coordinate(closest_point_index, 0); + point.y() = previous_points->coordinate(closest_point_index, 1); + closest_point = point; + } + + std::optional previous_distance; + if (closest_point) { + previous_distance = (*closest_point - first_point).norm(); + } + const bool is_near_previous{closest_point && *previous_distance < params.max_detour}; + + double seam_candidate_visibility{ + is_near_previous ? -params.continuity_modifier * + (params.max_detour - *previous_distance) / params.max_detour : + 0.0}; for (std::size_t slice_index{}; slice_index < shell.size(); ++slice_index) { seam_candidate_visibility += seam_candidate.visibilities[slice_index]; } @@ -476,8 +497,29 @@ std::vector> get_object_seams( for (std::size_t shell_index{0}; shell_index < shells.size(); ++shell_index) { Shells::Shell<> &shell{shells[shell_index]}; + if (shell.empty()) { + continue; + } + + const std::size_t layer_index{shell.front().layer_index}; + tcb::span previous_seams{ + layer_index == 0 ? tcb::span{} : layer_seams[layer_index - 1]}; + std::vector previous_seams_positions; + std::transform( + previous_seams.begin(), previous_seams.end(), + std::back_inserter(previous_seams_positions), + [](const SeamPerimeterChoice &seam) { return seam.choice.position; } + ); + + Perimeters::Perimeter::OptionalPointTree previous_seams_positions_tree; + const Perimeters::Perimeter::IndexToCoord index_to_coord{previous_seams_positions}; + if (!previous_seams_positions.empty()) { + previous_seams_positions_tree = + Perimeters::Perimeter::PointTree{index_to_coord, index_to_coord.positions.size()}; + } + std::vector seam{ - Aligned::get_shell_seam(shell, seam_candidates[shell_index])}; + Aligned::get_shell_seam(shell, seam_candidates[shell_index], previous_seams_positions_tree, params)}; for (std::size_t perimeter_id{}; perimeter_id < shell.size(); ++perimeter_id) { const SeamChoice &choice{seam[perimeter_id]}; diff --git a/src/libslic3r/GCode/SeamAligned.hpp b/src/libslic3r/GCode/SeamAligned.hpp index d3fbebab6c..ee3b581ec1 100644 --- a/src/libslic3r/GCode/SeamAligned.hpp +++ b/src/libslic3r/GCode/SeamAligned.hpp @@ -83,6 +83,7 @@ private: struct Params { double max_detour{}; double jump_visibility_threshold{}; + double continuity_modifier{}; }; std::vector> get_object_seams( diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index d1fd54e069..3c93ed4f07 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -100,6 +100,7 @@ Params Placer::get_params(const DynamicPrintConfig &config) { params.random_seed = 1653710332u; params.aligned.max_detour = 1.0; + params.aligned.continuity_modifier = 2.0; params.convex_visibility_modifier = 1.1; params.concave_visibility_modifier = 0.9; params.perimeter.overhang_threshold = Slic3r::Geometry::deg2rad(55.0);