Fix medial axis creating points on top of each other.

supermerill/SuperSlicer#2099
supermerill/SuperSlicer#2102
This commit is contained in:
supermerill 2021-12-21 20:25:24 +01:00
parent f1f60cd468
commit a358fe2704
2 changed files with 39 additions and 19 deletions

View File

@ -1330,8 +1330,12 @@ MedialAxis::concatenate_polylines_with_crossing(ThickPolylines& pp)
&& polyline.width.back() > best_candidate->width[1]) {
polyline.width.back() = std::min(polyline.width[polyline.width.size() - 2], best_candidate->width[1]);
}
polyline.points.insert(polyline.points.end(), best_candidate->points.begin() + 1, best_candidate->points.end());
polyline.width.insert(polyline.width.end(), best_candidate->width.begin() + 1, best_candidate->width.end());
//be far enough
int far_idx = 1;
while (far_idx < best_candidate->points.size() && polyline.last_point().coincides_with_epsilon(best_candidate->points[far_idx]))
far_idx++;
polyline.points.insert(polyline.points.end(), best_candidate->points.begin() + far_idx, best_candidate->points.end());
polyline.width.insert(polyline.width.end(), best_candidate->width.begin() + far_idx, best_candidate->width.end());
polyline.endpoints.second = best_candidate->endpoints.second;
assert(polyline.width.size() == polyline.points.size());
if (best_idx < i) i--;
@ -1799,6 +1803,24 @@ MedialAxis::build(ThickPolylines &polylines_out)
// pp.erase(pp.begin() + tp_idx);
// --tp_idx;
//}
//voronoi problem: can put two consecutive points at the same position. Delete one.
for (size_t i = 1; i < tp.points.size()-1; i++) {
if (tp.points[i-1].distance_to_square(tp.points[i]) < SCALED_EPSILON) {
tp.points.erase(tp.points.begin() + i);
tp.width.erase(tp.width.begin() + i);
i--;
}
}
//delete the inner one
if (tp.points.size()>2 && tp.points[tp.points.size() - 2].distance_to_square(tp.points.back()) < SCALED_EPSILON) {
tp.points.erase(tp.points.end() - 2);
tp.width.erase(tp.width.end() - 2);
}
//delete null-length polylines
if (tp.length() < SCALED_EPSILON && tp.first_point().coincides_with_epsilon(tp.last_point())) {
pp.erase(pp.begin() + tp_idx);
--tp_idx;
}
}
//std::cout << "polyline_from_voronoi\n";
//{
@ -2078,8 +2100,11 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl
continue;
}
} else if (i > 0 && resolution_internal > line_len + prev_line_len) {
ThickLine& prev_line = lines[i - 1];
//merge lines?
//if it's a loop, merge only if the distance is high enough
if (p.first_point() == p.last_point() && p.length() < (line_len + prev_line_len) * 6)
continue;
ThickLine& prev_line = lines[i - 1];
coordf_t width = prev_line_len * (prev_line.a_width + prev_line.b_width) / 2;
width += line_len * (line.a_width + line.b_width) / 2;
prev_line.b = line.b;
@ -2149,6 +2174,7 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl
path.height = flow.height;
}
}
assert(path.polyline.points.size() > 2 || path.first_point() != path.last_point());
}
if (path.polyline.is_valid())
paths.emplace_back(std::move(path));

View File

@ -34,32 +34,27 @@ using coord_t = int64_t;
using coordf_t = double;
//FIXME This epsilon value is used for many non-related purposes:
// For a threshold of a squared Euclidean distance,
// for a trheshold in a difference of radians,
// for a threshold of a cross product of two non-normalized vectors etc.
static constexpr double EPSILON = 1e-4;
// Scaling factor for a conversion from coord_t to coordf_t: 10e-6
// This scaling generates a following fixed point representation with for a 32bit integer:
// 0..4294mm with 1nm resolution
// int32_t fits an interval of (-2147.48mm, +2147.48mm)
// with int64_t we don't have to worry anymore about the size of the int.
static constexpr double SCALING_FACTOR = 0.000001;
#ifdef __linux__
static constexpr double UNSCALING_FACTOR = 1000000;
#else
static constexpr double UNSCALING_FACTOR = 1 / SCALING_FACTOR;
#endif
static constexpr double UNSCALING_FACTOR = 1000000; // 1 / SCALING_FACTOR;
//FIXME This epsilon value is used for many non-related purposes:
// For a threshold of a squared Euclidean distance,
// for a trheshold in a difference of radians,
// for a threshold of a cross product of two non-normalized vectors etc.
static constexpr double EPSILON = 1e-4;
static constexpr coord_t SCALED_EPSILON = 100; // coord_t(EPSILON/ SCALING_FACTOR);
// RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm.
//#define RESOLUTION 0.0125
//#define SCALED_RESOLUTION 12500
//#define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR)
static constexpr coordf_t RESOLUTION = 0.0125;
#ifdef __linux__
static constexpr coord_t SCALED_RESOLUTION = 12500;
#else
static constexpr coord_t SCALED_RESOLUTION = coord_t(0.0125 * UNSCALING_FACTOR);
#endif
static constexpr coord_t SCALED_RESOLUTION = 12500; // coord_t(0.0125 * UNSCALING_FACTOR);
//for creating circles (for brim_ear)
#define POLY_SIDES 24
#define PI 3.141592653589793238
@ -72,7 +67,6 @@ static constexpr double INSET_OVERLAP_TOLERANCE = 0.4;
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
#define scale_(val) (coord_t)((val) / SCALING_FACTOR)
#define SCALED_EPSILON scale_(EPSILON)
#define SLIC3R_DEBUG_OUT_PATH_PREFIX "out/"