-
-
Notifications
You must be signed in to change notification settings - Fork 890
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use a multi-pass scoring to better handle seams on regular shapes
CURA-12218 The previous rework of the score calculation removed the relative comparison between vertices scores to ensure the consistency. The new strategy performed very badly on shapes where multiple points would get a similar score, e.g. finding sharp corners on a cylinder. We now process a multi-pass scoring, so that all points having a very similar score at their main criterion will now go through a second pass with different criteria.
- Loading branch information
1 parent
d15d273
commit 81d2ce0
Showing
15 changed files
with
604 additions
and
310 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Copyright (c) 2024 Ultimaker B.V. | ||
// CuraEngine is released under the terms of the AGPLv3 or higher. | ||
|
||
#ifndef UTILS_SCORING_BESTCANDIDATEFINDER_H | ||
#define UTILS_SCORING_BESTCANDIDATEFINDER_H | ||
|
||
#include <algorithm> | ||
#include <memory> | ||
#include <optional> | ||
#include <vector> | ||
|
||
namespace cura | ||
{ | ||
class ScoringCriterion; | ||
|
||
/*! | ||
* This class implements an algorithm to find an element amongst a list, regarding one or multiple scoring criteria. The | ||
* criteria are implemented by subclassing the CriterionScoring class. It is also possible to setup multiple passes of | ||
* criteria. Thus, if the first pass gives a few best results that are too close to each other, a new pass is processed | ||
* with different criteria, and so on until we have a single outsider or no more criteria. | ||
*/ | ||
class BestElementFinder | ||
{ | ||
private: | ||
/*! | ||
* Contains the index of an element in the source list, and its calculated score | ||
*/ | ||
struct Candidate | ||
{ | ||
size_t candidate_index; | ||
double score{ 0.0 }; | ||
}; | ||
|
||
public: | ||
/*! | ||
* Contains a criterion to be processed to calculate the score of an element, and the weight is has on the global | ||
* score calculation. | ||
*/ | ||
struct WeighedCriterion | ||
{ | ||
std::shared_ptr<ScoringCriterion> criterion; | ||
|
||
/*! | ||
* The weight to be given when taking this criterion into the global score. A score that contributes "normally" | ||
* to the global score should have a weight of 1.0, and others should be adjusted around this value, to give | ||
* them more or less influence. | ||
*/ | ||
double weight{ 1.0 }; | ||
}; | ||
|
||
/*! | ||
* Contains multiple criteria to be processed on each element in a single pass | ||
*/ | ||
struct CriteriaPass | ||
{ | ||
std::vector<WeighedCriterion> criteria; | ||
|
||
/*! | ||
* Once we have calculated the global scores of each element for this pass, we calculate the score difference | ||
* between the best candidate and the following ones. If the following ones have a score close enough to the | ||
* best, within this threshold, they will also be considered outsiders and will be run for the next pass. | ||
*/ | ||
double outsider_delta_threshold{ 0.0 }; | ||
}; | ||
|
||
private: | ||
std::vector<CriteriaPass> criteria_; | ||
|
||
public: | ||
explicit BestElementFinder() = default; | ||
|
||
void appendCriteriaPass(const CriteriaPass& pass) | ||
{ | ||
criteria_.push_back(pass); | ||
} | ||
|
||
std::optional<size_t> findBestElement(const size_t candidates_count); | ||
}; | ||
|
||
} // namespace cura | ||
#endif // UTILS_SCORING_BESTCANDIDATEFINDER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (c) 2021 Ultimaker B.V. | ||
// CuraEngine is released under the terms of the AGPLv3 or higher. | ||
|
||
#ifndef CORNERSCORINGCRITERION_H | ||
#define CORNERSCORINGCRITERION_H | ||
|
||
#include <stddef.h> | ||
|
||
#include "geometry/Point2LL.h" | ||
#include "settings/EnumSettings.h" | ||
#include "utils/Coord_t.h" | ||
#include "utils/scoring/ScoringCriterion.h" | ||
|
||
namespace cura | ||
{ | ||
class PointsSet; | ||
|
||
/*! | ||
* Criterion that will give a score according to whether the point is creating a corner or lies on a flat line. | ||
* Depending on the given preference, concave or convex corners may get a higher score. | ||
*/ | ||
class CornerScoringCriterion : public ScoringCriterion | ||
{ | ||
private: | ||
const PointsSet& points_; | ||
const EZSeamCornerPrefType corner_preference_; | ||
std::vector<coord_t> segments_sizes_; | ||
coord_t total_length_{ 0 }; | ||
|
||
public: | ||
explicit CornerScoringCriterion(const PointsSet& points, const EZSeamCornerPrefType corner_preference); | ||
|
||
virtual double computeScore(const size_t candidate_index) const override; | ||
|
||
private: | ||
/*! | ||
* Some models have very sharp corners, but also have a high resolution. If a sharp corner | ||
* consists of many points each point individual might have a shallow corner, but the | ||
* collective angle of all nearby points is greater. To counter this the cornerAngle is | ||
* calculated from two points within angle_query_distance of the query point, no matter | ||
* what segment this leads us to | ||
* \param vertex_index index of the query point | ||
* \param angle_query_distance query range (default to 1mm) | ||
* \return angle between the reference point and the two sibling points, weighed to [-1.0 ; 1.0] | ||
*/ | ||
double cornerAngle(size_t vertex_index, const coord_t angle_query_distance = 1000) const; | ||
|
||
/*! | ||
* Finds a neighbour point on the path, located before or after the given reference point. The neighbour point | ||
* is computed by travelling on the path and stopping when the distance has been reached, For example: | ||
* |------|---------|------|--------------*---| | ||
* H A B C N D | ||
* In this case, H is the start point of the path and ABCD are the actual following points of the path. | ||
* The neighbour point N is found by reaching point D then going a bit backward on the previous segment. | ||
* This approach gets rid of the mesh actual resolution and gives a neighbour point that is on the path | ||
* at a given physical distance. | ||
* \param vertex_index The starting point index | ||
* \param distance The distance we want to travel on the path, which may be positive to go forward | ||
* or negative to go backward | ||
* \return The position of the path a the given distance from the reference point | ||
*/ | ||
Point2LL findNeighbourPoint(size_t vertex_index, coord_t distance) const; | ||
}; | ||
|
||
} // namespace cura | ||
|
||
#endif // CORNERSCORINGCRITERION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (c) 2021 Ultimaker B.V. | ||
// CuraEngine is released under the terms of the AGPLv3 or higher. | ||
|
||
#ifndef DISTANCESCORINGCRITERION_H | ||
#define DISTANCESCORINGCRITERION_H | ||
|
||
#include "geometry/Point2LL.h" | ||
#include "utils/scoring/ScoringCriterion.h" | ||
|
||
namespace cura | ||
{ | ||
class PointsSet; | ||
|
||
/*! | ||
* Criterion that will give a score according to the distance from the point to a target point. Closer points will get | ||
* a higher score. | ||
*/ | ||
class DistanceScoringCriterion : public ScoringCriterion | ||
{ | ||
private: | ||
const PointsSet& points_; | ||
const Point2LL& target_pos_; | ||
|
||
public: | ||
explicit DistanceScoringCriterion(const PointsSet& points, const Point2LL& target_pos); | ||
|
||
virtual double computeScore(const size_t candidate_index) const override; | ||
}; | ||
|
||
} // namespace cura | ||
|
||
#endif // DISTANCESCORINGCRITERION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (c) 2021 Ultimaker B.V. | ||
// CuraEngine is released under the terms of the AGPLv3 or higher. | ||
|
||
#ifndef EXCLUSIONAREASCORINGCRITERION_H | ||
#define EXCLUSIONAREASCORINGCRITERION_H | ||
|
||
#include <stddef.h> | ||
|
||
#include "utils/scoring/ScoringCriterion.h" | ||
|
||
namespace cura | ||
{ | ||
class PointsSet; | ||
class Shape; | ||
|
||
/*! | ||
* Criterion that will give a score according to whether the point is located inside or outside of an exclusion area. | ||
* This is currently a binary test and the score will be either 0 or 1. | ||
*/ | ||
class ExclusionAreaScoringCriterion : public ScoringCriterion | ||
{ | ||
private: | ||
const PointsSet& points_; | ||
const Shape& exclusion_area_; | ||
|
||
public: | ||
explicit ExclusionAreaScoringCriterion(const PointsSet& points, const Shape& exclusion_area); | ||
|
||
virtual double computeScore(const size_t candidate_index) const override; | ||
}; | ||
|
||
} // namespace cura | ||
|
||
#endif // EXCLUSIONAREASCORINGCRITERION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (c) 2021 Ultimaker B.V. | ||
// CuraEngine is released under the terms of the AGPLv3 or higher. | ||
|
||
#ifndef RANDOMSCORINGCRITERION_H | ||
#define RANDOMSCORINGCRITERION_H | ||
|
||
#include <stddef.h> | ||
|
||
#include "utils/scoring/ScoringCriterion.h" | ||
|
||
namespace cura | ||
{ | ||
|
||
/*! | ||
* Criterion that will give a random score whatever the element is. | ||
*/ | ||
class RandomScoringCriterion : public ScoringCriterion | ||
{ | ||
public: | ||
explicit RandomScoringCriterion(); | ||
|
||
virtual double computeScore(const size_t candidate_index) const override; | ||
}; | ||
|
||
} // namespace cura | ||
|
||
#endif // RANDOMSCORINGCRITERION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (c) 2024 Ultimaker B.V. | ||
// CuraEngine is released under the terms of the AGPLv3 or higher. | ||
|
||
#ifndef UTILS_SCORING_SCORINGCRITERION_H | ||
#define UTILS_SCORING_SCORINGCRITERION_H | ||
|
||
#include <stddef.h> | ||
|
||
namespace cura | ||
{ | ||
|
||
/*! | ||
* Base class for implementing a selection criterion when calculating a multi-criteria score to select the best element | ||
* amongst a list. | ||
*/ | ||
class ScoringCriterion | ||
{ | ||
public: | ||
ScoringCriterion() = default; | ||
|
||
virtual ~ScoringCriterion() = default; | ||
|
||
/*! | ||
* \brief Computes the score of an element regarding this criterion. To ensure a proper selection, this value must | ||
* be contained in [0.0, 1.0] and the different given scores must be evenly distributed in this range. | ||
* \param candidate_index The index of the candidate of the original list | ||
* \return The raw score of the element regarding this criterion | ||
*/ | ||
virtual double computeScore(const size_t candidate_index) const = 0; | ||
}; | ||
|
||
} // namespace cura | ||
|
||
#endif // UTILS_SCORING_SCORINGCRITERION_H |
Oops, something went wrong.