From a6450b00d2c7e030d308bc07e16ee11b8355b18b Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Tue, 5 Nov 2024 16:31:15 +0100 Subject: [PATCH] Fix non-straight user-defined seam CURA-12264 With a high-definition model, the new vertex created especially for the seam is quite close to the other points of its former segment. So the two other vertices would end up at good enough outsiders for the distance criterion. Now the distance factor of the criterion is a setting, so that in this specific case we can change the value to give more weight to the specific vertex and less to others, even if very close. --- include/PathOrderOptimizer.h | 5 ++++- include/utils/scoring/DistanceScoringCriterion.h | 12 +++++++++++- src/utils/scoring/DistanceScoringCriterion.cpp | 9 +++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/PathOrderOptimizer.h b/include/PathOrderOptimizer.h index ae01be4b25..a2e917fae8 100644 --- a/include/PathOrderOptimizer.h +++ b/include/PathOrderOptimizer.h @@ -740,7 +740,10 @@ class PathOrderOptimizer if (path.force_start_index_.has_value()) // Actually handles EZSeamType::USER_SPECIFIED { - main_criterion.criterion = std::make_shared(points, points.at(path.force_start_index_.value())); + // Use a much smaller distance divider because we want points around the forced points to be filtered out very easily + constexpr double distance_divider = 1.0; + constexpr auto distance_type = DistanceScoringCriterion::DistanceType::Euclidian; + main_criterion.criterion = std::make_shared(points, points.at(path.force_start_index_.value()), distance_type, distance_divider); } else { diff --git a/include/utils/scoring/DistanceScoringCriterion.h b/include/utils/scoring/DistanceScoringCriterion.h index 3b6d8785d3..800e0a8c72 100644 --- a/include/utils/scoring/DistanceScoringCriterion.h +++ b/include/utils/scoring/DistanceScoringCriterion.h @@ -30,8 +30,18 @@ class DistanceScoringCriterion : public ScoringCriterion const Point2LL& target_pos_; const DistanceType distance_type_; + /*! + * Fixed divider for shortest distances computation. The divider should be set so that the minimum encountered + * distance gives a score very close to 1.0, and a medium-far distance gives a score close to 0.5 + */ + const double distance_divider_; + public: - explicit DistanceScoringCriterion(const PointsSet& points, const Point2LL& target_pos, DistanceType distance_type = DistanceType::Euclidian); + explicit DistanceScoringCriterion( + const PointsSet& points, + const Point2LL& target_pos, + DistanceType distance_type = DistanceType::Euclidian, + const double distance_divider = 20.0); virtual double computeScore(const size_t candidate_index) const override; }; diff --git a/src/utils/scoring/DistanceScoringCriterion.cpp b/src/utils/scoring/DistanceScoringCriterion.cpp index 0c68e875b8..d087162365 100644 --- a/src/utils/scoring/DistanceScoringCriterion.cpp +++ b/src/utils/scoring/DistanceScoringCriterion.cpp @@ -9,10 +9,11 @@ namespace cura { -DistanceScoringCriterion::DistanceScoringCriterion(const PointsSet& points, const Point2LL& target_pos, DistanceType distance_type) +DistanceScoringCriterion::DistanceScoringCriterion(const PointsSet& points, const Point2LL& target_pos, DistanceType distance_type, const double distance_divider) : points_(points) , target_pos_(target_pos) , distance_type_(distance_type) + , distance_divider_(distance_divider) { } @@ -20,10 +21,6 @@ double DistanceScoringCriterion::computeScore(const size_t candidate_index) cons { const Point2LL& candidate_position = points_.at(candidate_index); - // Fixed divider for shortest distances computation. The divider should be set so that the minimum encountered - // distance gives a score very close to 1.0, and a medium-far distance gives a score close to 0.5 - constexpr double distance_divider = 20.0; - double distance = 0.0; switch (distance_type_) { @@ -40,7 +37,7 @@ double DistanceScoringCriterion::computeScore(const size_t candidate_index) cons } // Use reciprocal function to normalize distance score decreasingly - return 1.0 / (1.0 + (distance / distance_divider)); + return 1.0 / (1.0 + (distance / distance_divider_)); } } // namespace cura