mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 07:55:55 +08:00
Fix #13870: Prefer a corner if there is one clearly rearest corner to be picked when placing rear seam
This commit is contained in:
parent
6176dcc540
commit
6494a3badd
@ -24,13 +24,48 @@ BoundingBoxf get_bounding_box(const Shells::Shell<> &shell) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<SeamChoice> get_clear_max_y_corner(
|
||||
const std::vector<PerimeterLine> &possible_lines,
|
||||
const Perimeters::Perimeter &perimeter,
|
||||
const SeamChoice &max_y_choice,
|
||||
const double rear_tolerance
|
||||
) {
|
||||
if (perimeter.angle_types[max_y_choice.previous_index] != Perimeters::AngleType::concave) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double epsilon{1e-2};
|
||||
|
||||
// Check if there are two max y corners (e.g. on a cube).
|
||||
for (const PerimeterLine &line : possible_lines) {
|
||||
if (
|
||||
line.previous_index != max_y_choice.previous_index
|
||||
&& perimeter.angle_types[line.previous_index] == Perimeters::AngleType::concave
|
||||
&& max_y_choice.position.y() < line.a.y() + epsilon
|
||||
&& (max_y_choice.position - line.a).norm() > epsilon
|
||||
) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (
|
||||
line.next_index != max_y_choice.next_index
|
||||
&& perimeter.angle_types[line.next_index] == Perimeters::AngleType::concave
|
||||
&& max_y_choice.position.y() < line.b.y() + epsilon
|
||||
&& (max_y_choice.position - line.b).norm() > epsilon
|
||||
) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
return max_y_choice;
|
||||
}
|
||||
|
||||
SeamChoice get_max_y_choice(const std::vector<PerimeterLine> &possible_lines) {
|
||||
if (possible_lines.empty()) {
|
||||
throw std::runtime_error{"No possible lines!"};
|
||||
}
|
||||
|
||||
Vec2d point{possible_lines.front().a};
|
||||
std::size_t point_index{0};
|
||||
std::size_t point_index{possible_lines.front().previous_index};
|
||||
|
||||
for (const PerimeterLine &line : possible_lines) {
|
||||
if (line.a.y() > point.y()) {
|
||||
@ -69,24 +104,37 @@ struct RearestPointCalculator {
|
||||
const PointClassification point_classification
|
||||
) {
|
||||
std::vector<PerimeterLine> possible_lines;
|
||||
for (std::size_t i{0}; i < perimeter.positions.size() - 1; ++i) {
|
||||
for (std::size_t i{0}; i < perimeter.positions.size(); ++i) {
|
||||
const std::size_t next_index{i == perimeter.positions.size() - 1 ? 0 : i + 1};
|
||||
if (perimeter.point_types[i] != point_type) {
|
||||
continue;
|
||||
}
|
||||
if (perimeter.point_classifications[i] != point_classification) {
|
||||
continue;
|
||||
}
|
||||
if (perimeter.point_types[i + 1] != point_type) {
|
||||
if (perimeter.point_types[next_index] != point_type) {
|
||||
continue;
|
||||
}
|
||||
if (perimeter.point_classifications[i + 1] != point_classification) {
|
||||
if (perimeter.point_classifications[next_index] != point_classification) {
|
||||
continue;
|
||||
}
|
||||
possible_lines.push_back(PerimeterLine{perimeter.positions[i], perimeter.positions[i+1], i, i + 1});
|
||||
possible_lines.push_back(PerimeterLine{perimeter.positions[i], perimeter.positions[next_index], i, next_index});
|
||||
}
|
||||
if (possible_lines.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const SeamChoice max_y_choice{get_max_y_choice(possible_lines)};
|
||||
|
||||
if (const auto clear_max_y_corner{get_clear_max_y_corner(
|
||||
possible_lines,
|
||||
perimeter,
|
||||
max_y_choice,
|
||||
rear_tolerance
|
||||
)}) {
|
||||
return *clear_max_y_corner;
|
||||
}
|
||||
|
||||
const BoundingBoxf bounding_box{perimeter.positions};
|
||||
const AABBTreeLines::LinesDistancer<PerimeterLine> possible_distancer{possible_lines};
|
||||
const double center_x{(bounding_box.max.x() + bounding_box.min.x()) / 2.0};
|
||||
@ -112,7 +160,7 @@ struct RearestPointCalculator {
|
||||
}
|
||||
|
||||
if (bounding_box.max.y() - result.position.y() > rear_tolerance) {
|
||||
return get_max_y_choice(possible_lines);
|
||||
return max_y_choice;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
Loading…
x
Reference in New Issue
Block a user