mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-30 08:11:59 +08:00
SPE-2709: Fix precision of calculation line cross for thick field creation purpose:
Fixes freezing of SLA support point generator in certain cases
This commit is contained in:
parent
f6a60c3e84
commit
faa778d349
@ -1164,10 +1164,9 @@ Field create_thick_field(const ThickPart& part, const Lines &lines, const Sample
|
||||
assert(!changes.empty());
|
||||
size_t change_index = 0;
|
||||
if (!points.empty()) { // Not first point, could lead to termination
|
||||
const Point &last_point = points.back();
|
||||
LineUtils::SortFromAToB pred(lines[index]);
|
||||
bool no_change = false;
|
||||
while (pred.compare(changes[change_index].new_b, last_point)) {
|
||||
while (pred.compare(changes[change_index].new_b, points.back())) {
|
||||
++change_index;
|
||||
if (change_index >= changes.size()) {
|
||||
no_change = true;
|
||||
@ -1244,13 +1243,39 @@ Field create_thick_field(const ThickPart& part, const Lines &lines, const Sample
|
||||
size_t outline_index = input_index;
|
||||
// Done indexes is used to detect holes in field
|
||||
std::set<size_t> done_indices; // IMPROVE: use vector(size of lines count) with bools
|
||||
#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_TO_SVG_PATH
|
||||
static int counter = 0;
|
||||
std::string field_to_svg_path = replace_first(
|
||||
SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_TO_SVG_PATH, "<<COUNTER>>", std::to_string(counter++));
|
||||
{
|
||||
SVG svg(field_to_svg_path.c_str(), LineUtils::create_bounding_box(lines));
|
||||
LineUtils::draw(svg, lines, "black", 0., /*indices*/ true);
|
||||
for(const auto& change_it: wide_tiny_changes)
|
||||
for (const auto& change: change_it.second){
|
||||
Line bisector(change.new_b, change.next_new_a);
|
||||
LineUtils::draw(svg, bisector, "red");
|
||||
std::string text = "from " + std::to_string(change_it.first)
|
||||
+ " to " + std::to_string(change.next_line_index);
|
||||
svg.draw_text(bisector.a/2 + bisector.b/2, text.c_str(), "orange");
|
||||
}
|
||||
} // flush svg file
|
||||
#endif // SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_TO_SVG_PATH
|
||||
do {
|
||||
if (!insert_changes(outline_index, points, done_indices, input_index))
|
||||
break;
|
||||
inser_point_b(outline_index, points, done_indices);
|
||||
|
||||
if (points.size() > (lines.size() + 2*part.ends.size())){
|
||||
// protection against endless loop
|
||||
assert(false);
|
||||
return {};
|
||||
}
|
||||
} while (outline_index != input_index);
|
||||
|
||||
assert(points.size() >= 3);
|
||||
if (points.size() < 3)
|
||||
return {}; // invalid field
|
||||
|
||||
ExPolygon border{Polygon{points}};
|
||||
// finding holes(another closed polygon)
|
||||
if (done_indices.size() < field_line_indices.size()) {
|
||||
@ -1279,9 +1304,7 @@ Field create_thick_field(const ThickPart& part, const Lines &lines, const Sample
|
||||
bool draw_source_line_indexes = true;
|
||||
bool draw_border_line_indexes = false;
|
||||
bool draw_field_source_indexes = true;
|
||||
static int counter = 0;
|
||||
SVG svg(replace_first(SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_TO_SVG_PATH,
|
||||
"<<COUNTER>>", std::to_string(counter++)).c_str(),LineUtils::create_bounding_box(lines));
|
||||
SVG svg(field_to_svg_path.c_str(),LineUtils::create_bounding_box(lines));
|
||||
LineUtils::draw(svg, lines, source_line_color, 0., draw_source_line_indexes);
|
||||
draw(svg, field, border, draw_border_line_indexes, draw_field_source_indexes);
|
||||
}
|
||||
|
@ -983,7 +983,7 @@ std::pair<Slic3r::Point, Slic3r::Point> VoronoiGraphUtils::point_on_lines(
|
||||
//assert(edge->is_linear());
|
||||
|
||||
Point edge_point = create_edge_point(position);
|
||||
auto point_on_line = [&](const VD::edge_type *edge) -> Point {
|
||||
auto point_on_line = [&](const VD::edge_type *edge) -> Point {
|
||||
assert(edge->is_finite());
|
||||
const VD::cell_type *cell = edge->cell();
|
||||
size_t line_index = cell->source_index();
|
||||
@ -1000,7 +1000,16 @@ std::pair<Slic3r::Point, Slic3r::Point> VoronoiGraphUtils::point_on_lines(
|
||||
Line intersecting_line(edge_point, edge_point + PointUtils::perp(dir));
|
||||
std::optional<Vec2d> intersection = LineUtils::intersection(line, intersecting_line);
|
||||
assert(intersection.has_value());
|
||||
return intersection->cast<coord_t>();
|
||||
Point result = intersection->cast<coord_t>();
|
||||
// result MUST lay on the line, accuracy of float intersection could move point out of line
|
||||
coord_t tolerance = 5; // for sure it is 5 but found case which need tolerance(1) - SPE-2709
|
||||
if (abs(result.x() - line.a.x()) < tolerance &&
|
||||
abs(result.y() - line.a.y()) < tolerance)
|
||||
return line.a; // almost point a
|
||||
if (abs(result.x() - line.b.x()) < tolerance &&
|
||||
abs(result.y() - line.b.y()) < tolerance)
|
||||
return line.b; // almost point b
|
||||
return result;
|
||||
};
|
||||
|
||||
return {point_on_line(edge), point_on_line(edge->twin())};
|
||||
|
1176
tests/data/sla_islands/SPE-2709.svg
Normal file
1176
tests/data/sla_islands/SPE-2709.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 189 KiB |
@ -587,6 +587,34 @@ TEST_CASE("Uniform sample test islands", "[SupGen], [VoronoiSkeleton]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Sample island with config", "[SupportIsland]") {
|
||||
// set_logging_level(5);
|
||||
SampleConfig cfg{
|
||||
/*thin_max_distance*/ 5832568,
|
||||
/*thick_inner_max_distance*/ 7290710,
|
||||
/*thick_outline_max_distance*/ 5468032,
|
||||
/*head_radius*/ 250000,
|
||||
/*minimal_distance_from_outline*/ 250000,
|
||||
/*maximal_distance_from_outline*/ 1944189,
|
||||
/*max_length_for_one_support_point*/ 1869413,
|
||||
/*max_length_for_two_support_points*/ 7290710,
|
||||
/*max_length_ratio_for_two_support_points*/ 0.250000000f,
|
||||
/*thin_max_width*/ 4673532,
|
||||
/*thick_min_width*/ 4019237,
|
||||
/*min_part_length*/ 5832568,
|
||||
/*minimal_move*/ 100000,
|
||||
/*count_iteration*/ 30,
|
||||
/*max_align_distance*/ 3645355,
|
||||
/*simplification_tolerance*/ 50000.000000000007
|
||||
//*path*/, "C:/data/temp/islands/<<order>>.svg" // need define OPTION_TO_STORE_ISLAND in SampleConfig.hpp
|
||||
};
|
||||
std::string dir = std::string(TEST_DATA_DIR PATH_SEPARATOR) + "sla_islands/";
|
||||
ExPolygon island = load_svg(dir + "SPE-2709.svg"); // Bad field creation
|
||||
SupportIslandPoints points = test_island_sampling(island, cfg);
|
||||
// in time of write poins.size() == 39
|
||||
CHECK(points.size() > 22); // not only thin parts
|
||||
}
|
||||
|
||||
TEST_CASE("Disable visualization", "[hide]")
|
||||
{
|
||||
CHECK(true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user