Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2021-12-21 22:25:24 +0300
committersupermerill <merill@free.fr>2021-12-22 21:09:38 +0300
commita358fe27046dd18c3935a7bd76513c64bc295648 (patch)
treeec5990407cc42db8cced6790084a2b7ba370c713 /src
parentf1f60cd4680ac6fc55a094a4ab6dc5066e59f215 (diff)
Fix medial axis creating points on top of each other.
supermerill/SuperSlicer#2099 supermerill/SuperSlicer#2102
Diffstat (limited to 'src')
-rw-r--r--src/libslic3r/MedialAxis.cpp32
-rw-r--r--src/libslic3r/libslic3r.h26
2 files changed, 39 insertions, 19 deletions
diff --git a/src/libslic3r/MedialAxis.cpp b/src/libslic3r/MedialAxis.cpp
index db05fbd17..02b4816e2 100644
--- a/src/libslic3r/MedialAxis.cpp
+++ b/src/libslic3r/MedialAxis.cpp
@@ -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));
diff --git a/src/libslic3r/libslic3r.h b/src/libslic3r/libslic3r.h
index 3b4f34264..d1c816bcb 100644
--- a/src/libslic3r/libslic3r.h
+++ b/src/libslic3r/libslic3r.h
@@ -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/"