mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-26 16:12:02 +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() > best_candidate->width[1]) {
|
||||||
polyline.width.back() = std::min(polyline.width[polyline.width.size() - 2], 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());
|
//be far enough
|
||||||
polyline.width.insert(polyline.width.end(), best_candidate->width.begin() + 1, best_candidate->width.end());
|
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;
|
polyline.endpoints.second = best_candidate->endpoints.second;
|
||||||
assert(polyline.width.size() == polyline.points.size());
|
assert(polyline.width.size() == polyline.points.size());
|
||||||
if (best_idx < i) i--;
|
if (best_idx < i) i--;
|
||||||
@ -1799,6 +1803,24 @@ MedialAxis::build(ThickPolylines &polylines_out)
|
|||||||
// pp.erase(pp.begin() + tp_idx);
|
// pp.erase(pp.begin() + tp_idx);
|
||||||
// --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";
|
//std::cout << "polyline_from_voronoi\n";
|
||||||
//{
|
//{
|
||||||
@ -2078,8 +2100,11 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (i > 0 && resolution_internal > line_len + prev_line_len) {
|
} else if (i > 0 && resolution_internal > line_len + prev_line_len) {
|
||||||
ThickLine& prev_line = lines[i - 1];
|
|
||||||
//merge lines?
|
//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;
|
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;
|
width += line_len * (line.a_width + line.b_width) / 2;
|
||||||
prev_line.b = line.b;
|
prev_line.b = line.b;
|
||||||
@ -2149,6 +2174,7 @@ thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow fl
|
|||||||
path.height = flow.height;
|
path.height = flow.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(path.polyline.points.size() > 2 || path.first_point() != path.last_point());
|
||||||
}
|
}
|
||||||
if (path.polyline.is_valid())
|
if (path.polyline.is_valid())
|
||||||
paths.emplace_back(std::move(path));
|
paths.emplace_back(std::move(path));
|
||||||
|
@ -34,32 +34,27 @@ using coord_t = int64_t;
|
|||||||
|
|
||||||
using coordf_t = double;
|
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
|
// 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:
|
// This scaling generates a following fixed point representation with for a 32bit integer:
|
||||||
// 0..4294mm with 1nm resolution
|
// 0..4294mm with 1nm resolution
|
||||||
// int32_t fits an interval of (-2147.48mm, +2147.48mm)
|
// 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.
|
// with int64_t we don't have to worry anymore about the size of the int.
|
||||||
static constexpr double SCALING_FACTOR = 0.000001;
|
static constexpr double SCALING_FACTOR = 0.000001;
|
||||||
#ifdef __linux__
|
static constexpr double UNSCALING_FACTOR = 1000000; // 1 / SCALING_FACTOR;
|
||||||
static constexpr double UNSCALING_FACTOR = 1000000;
|
|
||||||
#else
|
//FIXME This epsilon value is used for many non-related purposes:
|
||||||
static constexpr double UNSCALING_FACTOR = 1 / SCALING_FACTOR;
|
// For a threshold of a squared Euclidean distance,
|
||||||
#endif
|
// 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.
|
// RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm.
|
||||||
//#define RESOLUTION 0.0125
|
//#define RESOLUTION 0.0125
|
||||||
//#define SCALED_RESOLUTION 12500
|
//#define SCALED_RESOLUTION 12500
|
||||||
//#define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR)
|
//#define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR)
|
||||||
static constexpr coordf_t RESOLUTION = 0.0125;
|
static constexpr coordf_t RESOLUTION = 0.0125;
|
||||||
#ifdef __linux__
|
static constexpr coord_t SCALED_RESOLUTION = 12500; // coord_t(0.0125 * UNSCALING_FACTOR);
|
||||||
static constexpr coord_t SCALED_RESOLUTION = 12500;
|
|
||||||
#else
|
|
||||||
static constexpr coord_t SCALED_RESOLUTION = coord_t(0.0125 * UNSCALING_FACTOR);
|
|
||||||
#endif
|
|
||||||
//for creating circles (for brim_ear)
|
//for creating circles (for brim_ear)
|
||||||
#define POLY_SIDES 24
|
#define POLY_SIDES 24
|
||||||
#define PI 3.141592653589793238
|
#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)); }
|
//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 scale_(val) (coord_t)((val) / SCALING_FACTOR)
|
||||||
|
|
||||||
#define SCALED_EPSILON scale_(EPSILON)
|
|
||||||
|
|
||||||
#define SLIC3R_DEBUG_OUT_PATH_PREFIX "out/"
|
#define SLIC3R_DEBUG_OUT_PATH_PREFIX "out/"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user