mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 22:10:36 +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());
|
assert(!changes.empty());
|
||||||
size_t change_index = 0;
|
size_t change_index = 0;
|
||||||
if (!points.empty()) { // Not first point, could lead to termination
|
if (!points.empty()) { // Not first point, could lead to termination
|
||||||
const Point &last_point = points.back();
|
|
||||||
LineUtils::SortFromAToB pred(lines[index]);
|
LineUtils::SortFromAToB pred(lines[index]);
|
||||||
bool no_change = false;
|
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;
|
++change_index;
|
||||||
if (change_index >= changes.size()) {
|
if (change_index >= changes.size()) {
|
||||||
no_change = true;
|
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;
|
size_t outline_index = input_index;
|
||||||
// Done indexes is used to detect holes in field
|
// Done indexes is used to detect holes in field
|
||||||
std::set<size_t> done_indices; // IMPROVE: use vector(size of lines count) with bools
|
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 {
|
do {
|
||||||
if (!insert_changes(outline_index, points, done_indices, input_index))
|
if (!insert_changes(outline_index, points, done_indices, input_index))
|
||||||
break;
|
break;
|
||||||
inser_point_b(outline_index, points, done_indices);
|
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);
|
} while (outline_index != input_index);
|
||||||
|
|
||||||
assert(points.size() >= 3);
|
assert(points.size() >= 3);
|
||||||
|
if (points.size() < 3)
|
||||||
|
return {}; // invalid field
|
||||||
|
|
||||||
ExPolygon border{Polygon{points}};
|
ExPolygon border{Polygon{points}};
|
||||||
// finding holes(another closed polygon)
|
// finding holes(another closed polygon)
|
||||||
if (done_indices.size() < field_line_indices.size()) {
|
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_source_line_indexes = true;
|
||||||
bool draw_border_line_indexes = false;
|
bool draw_border_line_indexes = false;
|
||||||
bool draw_field_source_indexes = true;
|
bool draw_field_source_indexes = true;
|
||||||
static int counter = 0;
|
SVG svg(field_to_svg_path.c_str(),LineUtils::create_bounding_box(lines));
|
||||||
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));
|
|
||||||
LineUtils::draw(svg, lines, source_line_color, 0., draw_source_line_indexes);
|
LineUtils::draw(svg, lines, source_line_color, 0., draw_source_line_indexes);
|
||||||
draw(svg, field, border, draw_border_line_indexes, draw_field_source_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());
|
//assert(edge->is_linear());
|
||||||
|
|
||||||
Point edge_point = create_edge_point(position);
|
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());
|
assert(edge->is_finite());
|
||||||
const VD::cell_type *cell = edge->cell();
|
const VD::cell_type *cell = edge->cell();
|
||||||
size_t line_index = cell->source_index();
|
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));
|
Line intersecting_line(edge_point, edge_point + PointUtils::perp(dir));
|
||||||
std::optional<Vec2d> intersection = LineUtils::intersection(line, intersecting_line);
|
std::optional<Vec2d> intersection = LineUtils::intersection(line, intersecting_line);
|
||||||
assert(intersection.has_value());
|
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())};
|
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]")
|
TEST_CASE("Disable visualization", "[hide]")
|
||||||
{
|
{
|
||||||
CHECK(true);
|
CHECK(true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user