FIX: fix slice error: invalid infill
Reason: sorting errors caused by precision jira: STUDIO-10841 Change-Id: I64dbbcf9e35477b597c4755863f307cf444f50d9
This commit is contained in:
parent
5656c89d32
commit
611f022a0c
|
@ -135,7 +135,7 @@ struct SegmentIntersection
|
|||
p -= int64_t(pos_q>>1);
|
||||
else
|
||||
p += int64_t(pos_q>>1);
|
||||
return coord_t(p / int64_t(pos_q));
|
||||
return coord_t(p / int64_t(pos_q));
|
||||
}
|
||||
|
||||
// Left vertical line / contour intersection point.
|
||||
|
@ -251,7 +251,7 @@ struct SegmentIntersection
|
|||
int vertical_down(Side side) const { return side == Side::Left ? this->left_vertical_down() : this->right_vertical_down(); }
|
||||
int vertical_outside(Side side) const { return side == Side::Left ? this->left_vertical_outside() : this->right_vertical_outside(); }
|
||||
// Returns -1 if there is no link up.
|
||||
int vertical_up() const {
|
||||
int vertical_up() const {
|
||||
return this->has_left_vertical_up() ? this->left_vertical_up() : this->right_vertical_up();
|
||||
}
|
||||
LinkQuality vertical_up_quality() const {
|
||||
|
@ -322,7 +322,7 @@ struct SegmentIntersection
|
|||
}
|
||||
}
|
||||
|
||||
bool operator==(const SegmentIntersection &other) const
|
||||
bool operator==(const SegmentIntersection &other) const
|
||||
{
|
||||
assert(pos_q > 0);
|
||||
assert(other.pos_q > 0);
|
||||
|
@ -414,7 +414,7 @@ public:
|
|||
//assert(aoffset1 < 0);
|
||||
assert(aoffset2 <= 0);
|
||||
// assert(aoffset2 == 0 || aoffset2 < aoffset1);
|
||||
// bool sticks_removed =
|
||||
// bool sticks_removed =
|
||||
remove_sticks(polygons_src);
|
||||
// if (sticks_removed) BOOST_LOG_TRIVIAL(error) << "Sticks removed!";
|
||||
polygons_outer = aoffset1 == 0 ? to_polygons(polygons_src) : offset(polygons_src, float(aoffset1), ClipperLib::jtMiter, miterLimit);
|
||||
|
@ -454,7 +454,7 @@ public:
|
|||
// Any contour with offset2
|
||||
bool is_contour_inner(size_t idx) const { return idx >= n_contours_outer; }
|
||||
|
||||
const Polygon& contour(size_t idx) const
|
||||
const Polygon& contour(size_t idx) const
|
||||
{ return is_contour_outer(idx) ? polygons_outer[idx] : polygons_inner[idx - n_contours_outer]; }
|
||||
|
||||
Polygon& contour(size_t idx)
|
||||
|
@ -462,11 +462,11 @@ public:
|
|||
|
||||
bool is_contour_ccw(size_t idx) const { return polygons_ccw[idx]; }
|
||||
|
||||
BoundingBox bounding_box_src() const
|
||||
BoundingBox bounding_box_src() const
|
||||
{ return get_extents(polygons_src); }
|
||||
BoundingBox bounding_box_outer() const
|
||||
BoundingBox bounding_box_outer() const
|
||||
{ return get_extents(polygons_outer); }
|
||||
BoundingBox bounding_box_inner() const
|
||||
BoundingBox bounding_box_inner() const
|
||||
{ return get_extents(polygons_inner); }
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
|
@ -545,16 +545,16 @@ static inline bool intersection_on_prev_next_vertical_line_valid(
|
|||
}
|
||||
|
||||
static inline bool intersection_on_prev_vertical_line_valid(
|
||||
const std::vector<SegmentedIntersectionLine> &segs,
|
||||
size_t iVerticalLine,
|
||||
const std::vector<SegmentedIntersectionLine> &segs,
|
||||
size_t iVerticalLine,
|
||||
size_t iIntersection)
|
||||
{
|
||||
return intersection_on_prev_next_vertical_line_valid(segs, iVerticalLine, iIntersection, SegmentIntersection::Side::Left);
|
||||
}
|
||||
|
||||
static inline bool intersection_on_next_vertical_line_valid(
|
||||
const std::vector<SegmentedIntersectionLine> &segs,
|
||||
size_t iVerticalLine,
|
||||
const std::vector<SegmentedIntersectionLine> &segs,
|
||||
size_t iVerticalLine,
|
||||
size_t iIntersection)
|
||||
{
|
||||
return intersection_on_prev_next_vertical_line_valid(segs, iVerticalLine, iIntersection, SegmentIntersection::Side::Right);
|
||||
|
@ -562,7 +562,7 @@ static inline bool intersection_on_next_vertical_line_valid(
|
|||
|
||||
// Measure an Euclidian length of a perimeter segment when going from iIntersection to iIntersection2.
|
||||
static inline coordf_t measure_perimeter_horizontal_segment_length(
|
||||
const ExPolygonWithOffset &poly_with_offset,
|
||||
const ExPolygonWithOffset &poly_with_offset,
|
||||
const std::vector<SegmentedIntersectionLine> &segs,
|
||||
size_t iVerticalLine,
|
||||
size_t iIntersection,
|
||||
|
@ -859,7 +859,7 @@ static std::vector<SegmentedIntersectionLine> slice_region_by_vertical_lines(con
|
|||
// Sort the intersection points using exact rational arithmetic.
|
||||
//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) {
|
||||
if (l.pos() == r.pos() && l.iContour == r.iContour)
|
||||
if (abs(l.pos() - r.pos()) < scale_(EPSILON) && l.iContour == r.iContour)
|
||||
return l.type < r.type;
|
||||
|
||||
return l.pos() < r.pos();
|
||||
|
@ -1134,7 +1134,7 @@ static void connect_segment_intersections_by_contours(
|
|||
assert(inext >= 0);
|
||||
|
||||
itsct.prev_on_contour = iprev;
|
||||
itsct.prev_on_contour_type = same_prev ?
|
||||
itsct.prev_on_contour_type = same_prev ?
|
||||
(iprev < i_intersection ? SegmentIntersection::LinkType::Down : SegmentIntersection::LinkType::Up) :
|
||||
SegmentIntersection::LinkType::Horizontal;
|
||||
itsct.next_on_contour = inext;
|
||||
|
@ -1191,7 +1191,7 @@ static void connect_segment_intersections_by_contours(
|
|||
} else if (link_max_length > 0) {
|
||||
// Measure length of the links.
|
||||
if (itsct.prev_on_contour_quality == SegmentIntersection::LinkQuality::Valid &&
|
||||
(same_prev ?
|
||||
(same_prev ?
|
||||
measure_perimeter_segment_on_vertical_line_length(poly_with_offset, segs, i_vline, iprev, i_intersection, forward) :
|
||||
measure_perimeter_horizontal_segment_length(poly_with_offset, segs, i_vline - 1, iprev, i_intersection)) > link_max_length)
|
||||
itsct.prev_on_contour_quality = SegmentIntersection::LinkQuality::TooLong;
|
||||
|
@ -1533,9 +1533,9 @@ static void traverse_graph_generate_polylines(const ExPolygonWithOffset
|
|||
|
||||
// Try to connect to a previous or next point on the same vertical line.
|
||||
int i_vertical = it->vertical_outside();
|
||||
auto vertical_link_quality = (i_vertical == -1 || vline.intersections[i_vertical + (going_up ? 0 : -1)].consumed_vertical_up) ?
|
||||
auto vertical_link_quality = (i_vertical == -1 || vline.intersections[i_vertical + (going_up ? 0 : -1)].consumed_vertical_up) ?
|
||||
SegmentIntersection::LinkQuality::Invalid : it->vertical_outside_quality();
|
||||
#if 0
|
||||
#if 0
|
||||
if (vertical_link_quality == SegmentIntersection::LinkQuality::Valid ||
|
||||
// Follow the link if there is no horizontal link available.
|
||||
(! intersection_horizontal_valid && vertical_link_quality != SegmentIntersection::LinkQuality::Invalid)) {
|
||||
|
@ -1642,7 +1642,7 @@ struct MonotonicRegionLink
|
|||
{
|
||||
MonotonicRegion *region;
|
||||
bool flipped;
|
||||
// Distance of right side of this region to left side of the next region, if the "flipped" flag of this region and the next region
|
||||
// Distance of right side of this region to left side of the next region, if the "flipped" flag of this region and the next region
|
||||
// is applied as defined.
|
||||
AntPath *next;
|
||||
// Distance of right side of this region to left side of the next region, if the "flipped" flag of this region and the next region
|
||||
|
@ -1656,10 +1656,10 @@ class AntPathMatrix
|
|||
{
|
||||
public:
|
||||
AntPathMatrix(
|
||||
const std::vector<MonotonicRegion> ®ions,
|
||||
const ExPolygonWithOffset &poly_with_offset,
|
||||
const std::vector<MonotonicRegion> ®ions,
|
||||
const ExPolygonWithOffset &poly_with_offset,
|
||||
const std::vector<SegmentedIntersectionLine> &segs,
|
||||
const float initial_pheromone) :
|
||||
const float initial_pheromone) :
|
||||
m_regions(regions),
|
||||
m_poly_with_offset(poly_with_offset),
|
||||
m_segs(segs),
|
||||
|
@ -2028,7 +2028,7 @@ static float montonous_region_path_length(const MonotonicRegion ®ion, bool di
|
|||
break;
|
||||
assert(it->iContour == vline.intersections[inext].iContour);
|
||||
it = vline.intersections.data() + inext;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Going down.
|
||||
assert(it->is_high());
|
||||
|
@ -2045,7 +2045,7 @@ static float montonous_region_path_length(const MonotonicRegion ®ion, bool di
|
|||
break;
|
||||
assert(it->iContour == vline.intersections[inext].iContour);
|
||||
it = vline.intersections.data() + inext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i_vline == region.right.vline)
|
||||
|
@ -2057,7 +2057,7 @@ static float montonous_region_path_length(const MonotonicRegion ®ion, bool di
|
|||
|
||||
// Find the end of the next overlapping vertical segment.
|
||||
const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
|
||||
const SegmentIntersection *right = going_up ?
|
||||
const SegmentIntersection *right = going_up ?
|
||||
&vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
|
||||
i_intersection = int(right - vline_right.intersections.data());
|
||||
|
||||
|
@ -2302,7 +2302,7 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
|||
} else {
|
||||
if (regions_in_queue[iprev])
|
||||
assert(left_neighbors_unprocessed[iprev] == 1);
|
||||
else
|
||||
else
|
||||
assert(left_neighbors_unprocessed[iprev] > 1);
|
||||
++ num_predecessors_unprocessed;
|
||||
}
|
||||
|
@ -2394,7 +2394,7 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
|||
total_length += next_region->length(next_dir) + path_matrix(*path_end.region, path_end.flipped, *next_region, next_dir).length;
|
||||
path_end = { next_region, next_dir };
|
||||
assert(left_neighbors_unprocessed[next_region - regions.data()] == 1);
|
||||
left_neighbors_unprocessed[next_region - regions.data()] = 0;
|
||||
left_neighbors_unprocessed[next_region - regions.data()] = 0;
|
||||
}
|
||||
|
||||
// Set an initial pheromone value to 10% of the greedy path's value.
|
||||
|
@ -2421,7 +2421,7 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
|||
for (int round = 0; round < num_rounds && num_rounds_no_change < num_rounds_no_change_exit; ++ round)
|
||||
{
|
||||
bool improved = false;
|
||||
for (int ant = 0; ant < num_ants; ++ ant)
|
||||
for (int ant = 0; ant < num_ants; ++ ant)
|
||||
{
|
||||
// Find a new path following the pheromones deposited by the previous ants.
|
||||
print_ant("Round %1% ant %2%", round, ant);
|
||||
|
@ -2440,10 +2440,10 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
|||
assert(left_neighbors_unprocessed[path.back().region - regions.data()] == 0);
|
||||
assert(validate_unprocessed());
|
||||
print_ant("\tRegion (%1%:%2%,%3%) (%4%:%5%,%6%)",
|
||||
path.back().region->left.vline,
|
||||
path.back().region->left.vline,
|
||||
path.back().flipped ? path.back().region->left.high : path.back().region->left.low,
|
||||
path.back().flipped ? path.back().region->left.low : path.back().region->left.high,
|
||||
path.back().region->right.vline,
|
||||
path.back().region->right.vline,
|
||||
path.back().flipped == path.back().region->flips ? path.back().region->right.high : path.back().region->right.low,
|
||||
path.back().flipped == path.back().region->flips ? path.back().region->right.low : path.back().region->right.high);
|
||||
|
||||
|
@ -2521,11 +2521,11 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
|||
path.emplace_back(MonotonicRegionLink{ next_region, next_dir });
|
||||
assert(left_neighbors_unprocessed[next_region - regions.data()] == 1);
|
||||
left_neighbors_unprocessed[next_region - regions.data()] = 0;
|
||||
print_ant("\tRegion (%1%:%2%,%3%) (%4%:%5%,%6%) length to prev %7%",
|
||||
next_region->left.vline,
|
||||
print_ant("\tRegion (%1%:%2%,%3%) (%4%:%5%,%6%) length to prev %7%",
|
||||
next_region->left.vline,
|
||||
next_dir ? next_region->left.high : next_region->left.low,
|
||||
next_dir ? next_region->left.low : next_region->left.high,
|
||||
next_region->right.vline,
|
||||
next_region->right.vline,
|
||||
next_dir == next_region->flips ? next_region->right.high : next_region->right.low,
|
||||
next_dir == next_region->flips ? next_region->right.low : next_region->right.high,
|
||||
take_path->link->length);
|
||||
|
@ -2552,7 +2552,7 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
|||
assert(! path.empty());
|
||||
float path_length = std::accumulate(path.begin(), path.end() - 1,
|
||||
path.back().region->length(path.back().flipped),
|
||||
[&path_matrix](const float l, const MonotonicRegionLink &r) {
|
||||
[&path_matrix](const float l, const MonotonicRegionLink &r) {
|
||||
const MonotonicRegionLink &next = *(&r + 1);
|
||||
return l + r.region->length(r.flipped) + path_matrix(*r.region, r.flipped, *next.region, next.flipped).length;
|
||||
});
|
||||
|
@ -2682,7 +2682,7 @@ static void polylines_from_paths(const std::vector<MonotonicRegionLink> &path, c
|
|||
assert(it->iContour == vline.intersections[inext].iContour);
|
||||
emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_left_vertical_up());
|
||||
it = vline.intersections.data() + inext;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Going down.
|
||||
assert(it->is_high());
|
||||
|
@ -2701,7 +2701,7 @@ static void polylines_from_paths(const std::vector<MonotonicRegionLink> &path, c
|
|||
assert(it->iContour == vline.intersections[inext].iContour);
|
||||
emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_right_vertical_down());
|
||||
it = vline.intersections.data() + inext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i_vline == region.right.vline)
|
||||
|
@ -2713,7 +2713,7 @@ static void polylines_from_paths(const std::vector<MonotonicRegionLink> &path, c
|
|||
|
||||
// Find the end of the next overlapping vertical segment.
|
||||
const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
|
||||
const SegmentIntersection *right = going_up ?
|
||||
const SegmentIntersection *right = going_up ?
|
||||
&vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
|
||||
i_intersection = int(right - vline_right.intersections.data());
|
||||
|
||||
|
@ -2776,8 +2776,8 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
|
|||
|
||||
// On the polygons of poly_with_offset, the infill lines will be connected.
|
||||
ExPolygonWithOffset poly_with_offset(
|
||||
surface->expolygon,
|
||||
- rotate_vector.first,
|
||||
surface->expolygon,
|
||||
- rotate_vector.first,
|
||||
float(scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing)),
|
||||
float(scale_(this->overlap - 0.5f * this->spacing)));
|
||||
if (poly_with_offset.n_contours_inner == 0) {
|
||||
|
@ -2803,8 +2803,8 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
|
|||
coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
|
||||
refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
|
||||
bounding_box.merge(align_to_grid(
|
||||
bounding_box.min,
|
||||
Point(line_spacing, line_spacing),
|
||||
bounding_box.min,
|
||||
Point(line_spacing, line_spacing),
|
||||
refpt));
|
||||
}
|
||||
|
||||
|
@ -3066,11 +3066,11 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams ¶
|
|||
Polylines polylines_out;
|
||||
coordf_t dx = sqrt(0.5) * z;
|
||||
if (! this->fill_surface_by_multilines(
|
||||
surface, params,
|
||||
surface, params,
|
||||
{ { 0.f, float(dx) }, { float(M_PI / 3.), - float(dx) }, { float(M_PI * 2. / 3.), float(dx) } },
|
||||
polylines_out))
|
||||
BOOST_LOG_TRIVIAL(error) << "FillCubic::fill_surface() failed to fill a region.";
|
||||
return polylines_out;
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
Polylines FillSupportBase::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||
|
@ -3106,7 +3106,7 @@ Points sample_grid_pattern(const ExPolygon& expolygon, coord_t spacing, const Bo
|
|||
{
|
||||
ExPolygonWithOffset poly_with_offset(expolygon, 0, 0, 0);
|
||||
std::vector<SegmentedIntersectionLine> segs = slice_region_by_vertical_lines(
|
||||
poly_with_offset,
|
||||
poly_with_offset,
|
||||
(global_bounding_box.max.x() - global_bounding_box.min.x() + spacing - 1) / spacing,
|
||||
global_bounding_box.min.x(),
|
||||
spacing);
|
||||
|
@ -3248,7 +3248,7 @@ void FillMonotonicLineWGapFill::fill_surface_by_lines(const Surface* surface, co
|
|||
// On the polygons of poly_with_offset, the infill lines will be connected.
|
||||
ExPolygonWithOffset poly_with_offset(
|
||||
surface->expolygon,
|
||||
- rotate_vector.first,
|
||||
- rotate_vector.first,
|
||||
float(scale_(0 - (0.5 - INFILL_OVERLAP_OVER_SPACING) * params.flow.spacing())),
|
||||
float(scale_(0 - 0.5f * params.flow.spacing())));
|
||||
if (poly_with_offset.n_contours_inner == 0) {
|
||||
|
|
Loading…
Reference in New Issue