Fixed asserts and calculations in calculateExtrusionAreaDeviationError.
The previous method worked just for near collinear edges. But it was also used for sharp corners, and for those sharp corners, there was an overflow in the computation of weighted width. Also, the computation of deviation error was wrong for those sharp corners.
This commit is contained in:
parent
7a5639f322
commit
89b9f702d6
@ -113,8 +113,7 @@ void ExtrusionLine::simplify(const int64_t smallest_line_segment_squared, const
|
|||||||
//h^2 = (L / b)^2 [square it]
|
//h^2 = (L / b)^2 [square it]
|
||||||
//h^2 = L^2 / b^2 [factor the divisor]
|
//h^2 = L^2 / b^2 [factor the divisor]
|
||||||
const auto height_2 = int64_t(double(area_removed_so_far) * double(area_removed_so_far) / double(base_length_2));
|
const auto height_2 = int64_t(double(area_removed_so_far) * double(area_removed_so_far) / double(base_length_2));
|
||||||
coord_t weighted_average_width;
|
const int64_t extrusion_area_error = calculateExtrusionAreaDeviationError(previous, current, next);
|
||||||
const int64_t extrusion_area_error = calculateExtrusionAreaDeviationError(previous, current, next, weighted_average_width);
|
|
||||||
if ((height_2 <= scaled<coord_t>(0.001) //Almost exactly colinear (barring rounding errors).
|
if ((height_2 <= scaled<coord_t>(0.001) //Almost exactly colinear (barring rounding errors).
|
||||||
&& Line::distance_to_infinite(current.p, previous.p, next.p) <= scaled<double>(0.001)) // Make sure that height_2 is not small because of cancellation of positive and negative areas
|
&& Line::distance_to_infinite(current.p, previous.p, next.p) <= scaled<double>(0.001)) // Make sure that height_2 is not small because of cancellation of positive and negative areas
|
||||||
// We shouldn't remove middle junctions of colinear segments if the area changed for the C-P segment is exceeding the maximum allowed
|
// We shouldn't remove middle junctions of colinear segments if the area changed for the C-P segment is exceeding the maximum allowed
|
||||||
@ -189,8 +188,7 @@ void ExtrusionLine::simplify(const int64_t smallest_line_segment_squared, const
|
|||||||
junctions = new_junctions;
|
junctions = new_junctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t ExtrusionLine::calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C, coord_t& weighted_average_width)
|
int64_t ExtrusionLine::calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* A B C A C
|
* A B C A C
|
||||||
* --------------- **************
|
* --------------- **************
|
||||||
@ -208,27 +206,19 @@ int64_t ExtrusionLine::calculateExtrusionAreaDeviationError(ExtrusionJunction A,
|
|||||||
* weighted-average width for the entire extrusion line.
|
* weighted-average width for the entire extrusion line.
|
||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
const int64_t ab_length = (B - A).cast<int64_t>().norm();
|
const int64_t ab_length = (B.p - A.p).cast<int64_t>().norm();
|
||||||
const int64_t bc_length = (C - B).cast<int64_t>().norm();
|
const int64_t bc_length = (C.p - B.p).cast<int64_t>().norm();
|
||||||
const coord_t width_diff = std::max(std::abs(B.w - A.w), std::abs(C.w - B.w));
|
if (const coord_t width_diff = std::max(std::abs(B.w - A.w), std::abs(C.w - B.w)); width_diff > 1) {
|
||||||
if (width_diff > 1)
|
|
||||||
{
|
|
||||||
// Adjust the width only if there is a difference, or else the rounding errors may produce the wrong
|
// Adjust the width only if there is a difference, or else the rounding errors may produce the wrong
|
||||||
// weighted average value.
|
// weighted average value.
|
||||||
const int64_t ab_weight = (A.w + B.w) / 2;
|
const int64_t ab_weight = (A.w + B.w) / 2;
|
||||||
const int64_t bc_weight = (B.w + C.w) / 2;
|
const int64_t bc_weight = (B.w + C.w) / 2;
|
||||||
assert(((ab_length * ab_weight + bc_length * bc_weight) / (C - A).cast<int64_t>().norm()) <= std::numeric_limits<coord_t>::max());
|
const int64_t weighted_average_width = (ab_length * ab_weight + bc_length * bc_weight) / (ab_length + bc_length);
|
||||||
weighted_average_width = (ab_length * ab_weight + bc_length * bc_weight) / (C - A).cast<int64_t>().norm();
|
const int64_t ac_length = (C.p - A.p).cast<int64_t>().norm();
|
||||||
assert((int64_t(std::abs(ab_weight - weighted_average_width)) * ab_length + int64_t(std::abs(bc_weight - weighted_average_width)) * bc_length) <= double(std::numeric_limits<int64_t>::max()));
|
return std::abs((ab_weight * ab_length + bc_weight * bc_length) - (weighted_average_width * ac_length));
|
||||||
return std::abs(ab_weight - weighted_average_width) * ab_length + std::abs(bc_weight - weighted_average_width) * bc_length;
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the width difference is very small, then select the width of the segment that is longer
|
// If the width difference is very small, then select the width of the segment that is longer
|
||||||
weighted_average_width = ab_length > bc_length ? A.w : B.w;
|
return ab_length > bc_length ? int64_t(width_diff) * bc_length : int64_t(width_diff) * ab_length;
|
||||||
assert((int64_t(width_diff) * int64_t(bc_length)) <= std::numeric_limits<coord_t>::max());
|
|
||||||
assert((int64_t(width_diff) * int64_t(ab_length)) <= std::numeric_limits<coord_t>::max());
|
|
||||||
return ab_length > bc_length ? width_diff * bc_length : width_diff * ab_length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,9 +186,8 @@ struct ExtrusionLine
|
|||||||
* \param A Start point of the 3-point-straight line
|
* \param A Start point of the 3-point-straight line
|
||||||
* \param B Intermediate point of the 3-point-straight line
|
* \param B Intermediate point of the 3-point-straight line
|
||||||
* \param C End point of the 3-point-straight line
|
* \param C End point of the 3-point-straight line
|
||||||
* \param weighted_average_width The weighted average of the widths of the two colinear extrusion segments
|
|
||||||
* */
|
* */
|
||||||
static int64_t calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C, coord_t& weighted_average_width);
|
static int64_t calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C);
|
||||||
|
|
||||||
bool is_contour() const;
|
bool is_contour() const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user