mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-25 00:24:29 +08:00
Fix medial axis creating points on top of each other.
supermerill/SuperSlicer#2099 supermerill/SuperSlicer#2102
This commit is contained in:
parent
f1f60cd468
commit
a358fe2704
@ -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));
|
||||
|
@ -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/"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user