FIX: adjust the sort for segment intersections

and revert the modify of I64dbbcf9e35477b597c4755863f307cf444f50d9
jira: STUDIO-10841

Change-Id: Id6a56372cade4e62f3714aae6892468575298904
This commit is contained in:
zhimin.zeng 2025-03-17 18:26:57 +08:00 committed by lane.wei
parent d38cbada3e
commit 1968c8b117
1 changed files with 62 additions and 1 deletions

View File

@ -365,6 +365,66 @@ struct SegmentedIntersectionLine
std::vector<SegmentIntersection> intersections; std::vector<SegmentIntersection> intersections;
}; };
static void adjust_sort_for_segment_intersections(std::vector<SegmentIntersection> &intersections)
{
using IntersectionType = SegmentIntersection::SegmentIntersectionType;
std::stack<IntersectionType> stack;
bool has_out_low = false;
auto is_valid_type = [&stack, &has_out_low](IntersectionType type) {
if (stack.empty()) {
return type == IntersectionType::OUTER_LOW;
} else {
auto top_type = stack.top();
switch (type) {
case SegmentIntersection::OUTER_LOW: return false;
case SegmentIntersection::OUTER_HIGH: return top_type == IntersectionType::OUTER_LOW;
case SegmentIntersection::INNER_LOW: return top_type != IntersectionType::OUTER_HIGH;
case SegmentIntersection::INNER_HIGH: return top_type == IntersectionType::INNER_LOW;
default: break;
}
return true;
}
};
std::vector<bool> visited(intersections.size(), false);
std::vector<int> index_group;
for (size_t i = 0; i < intersections.size();) {
if (is_valid_type(intersections[i].type)) {
index_group.clear();
// std::fill()
if (intersections[i].type == SegmentIntersection::OUTER_LOW || intersections[i].type == SegmentIntersection::INNER_LOW) {
stack.push(intersections[i].type);
} else if (intersections[i].type == SegmentIntersection::OUTER_HIGH || intersections[i].type == SegmentIntersection::INNER_HIGH) {
stack.pop();
}
++i;
} else {
visited[i] = true;
for (size_t j = i + 1; j < intersections.size(); ++j) {
if (!visited[j] && abs(intersections[j].pos() - intersections[i].pos()) < scale_(EPSILON)) { index_group.push_back(j); }
}
if (!index_group.empty()) {
int swap_index = -1;
for (auto index : index_group) {
if (!visited[index]) {
swap_index = index;
visited[index] = true;
break;
}
}
if (swap_index != -1) {
std::swap(intersections[i], intersections[swap_index]);
continue;
}
}
++i;
}
}
}
static SegmentIntersection phony_outer_intersection(SegmentIntersection::SegmentIntersectionType type, coord_t pos) static SegmentIntersection phony_outer_intersection(SegmentIntersection::SegmentIntersectionType type, coord_t pos)
{ {
assert(type == SegmentIntersection::OUTER_LOW || type == SegmentIntersection::OUTER_HIGH); assert(type == SegmentIntersection::OUTER_LOW || type == SegmentIntersection::OUTER_HIGH);
@ -859,11 +919,12 @@ static std::vector<SegmentedIntersectionLine> slice_region_by_vertical_lines(con
// Sort the intersection points using exact rational arithmetic. // Sort the intersection points using exact rational arithmetic.
//BBS: if the LOW and HIGH has seam y pos, LOW should be first //BBS: if the LOW and HIGH has seam y pos, LOW should be first
std::sort(sil.intersections.begin(), sil.intersections.end(), [](const SegmentIntersection &l, const SegmentIntersection &r) { std::sort(sil.intersections.begin(), sil.intersections.end(), [](const SegmentIntersection &l, const SegmentIntersection &r) {
if (abs(l.pos() - r.pos()) < scale_(EPSILON) && l.iContour == r.iContour) if (l.pos() == r.pos() && l.iContour == r.iContour)
return l.type < r.type; return l.type < r.type;
return l.pos() < r.pos(); return l.pos() < r.pos();
}); });
adjust_sort_for_segment_intersections(sil.intersections);
// Assign the intersection types, remove duplicate or overlapping intersection points. // Assign the intersection types, remove duplicate or overlapping intersection points.
// When a loop vertex touches a vertical line, intersection point is generated for both segments. // When a loop vertex touches a vertical line, intersection point is generated for both segments.
// If such two segments are oriented equally, then one of them is removed. // If such two segments are oriented equally, then one of them is removed.