diff --git a/src/libslic3r/SLA/SupportIslands/LineUtils.cpp b/src/libslic3r/SLA/SupportIslands/LineUtils.cpp index 3c0cc73e33..7434ec525f 100644 --- a/src/libslic3r/SLA/SupportIslands/LineUtils.cpp +++ b/src/libslic3r/SLA/SupportIslands/LineUtils.cpp @@ -285,9 +285,11 @@ bool LineUtils::belongs(const Line &line, const Point &point, double benevolence const Point &b = line.b; auto is_in_interval = [](coord_t value, coord_t from, coord_t to) -> bool { - if (from > to) { + if (from < to) { + // from < value < to if (from > value || to < value) return false; } else { + // to < value < from if (from < value || to > value) return false; } return true; diff --git a/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.hpp b/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.hpp index 63ea56047c..545eefedc2 100644 --- a/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.hpp +++ b/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.hpp @@ -28,7 +28,7 @@ public: result.half_distance = result.max_distance / 2; result.head_radius = head_diameter / 2; result.minimal_distance_from_outline = result.head_radius; - result.maximal_distance_from_outline = result.half_distance; + result.maximal_distance_from_outline = result.max_distance/4; assert(result.minimal_distance_from_outline < result.maximal_distance_from_outline); result.minimal_support_distance = result.minimal_distance_from_outline + result.half_distance; diff --git a/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp b/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp index e1764e3c4d..db32683fcd 100644 --- a/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp +++ b/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp @@ -20,10 +20,11 @@ // comment definition of NDEBUG to enable assert() //#define NDEBUG -#define SLA_SAMPLE_ISLAND_UTILS_STORE_VORONOI_GRAPH_TO_SVG -#define SLA_SAMPLE_ISLAND_UTILS_STORE_INITIAL_SAMPLE_POSITION_TO_SVG -#define SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_TO_SVG +//#define SLA_SAMPLE_ISLAND_UTILS_STORE_VORONOI_GRAPH_TO_SVG +//#define SLA_SAMPLE_ISLAND_UTILS_STORE_INITIAL_SAMPLE_POSITION_TO_SVG +//#define SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_TO_SVG //#define SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG +//#define SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGNED_TO_SVG #include @@ -410,8 +411,18 @@ void SampleIslandUtils::align_samples(SupportIslandPoints &samples, max_move = align_once(samples, island, config); if (max_move < config.minimal_move) break; } - //std::cout << "Align use " << config.count_iteration - count_iteration - // << " iteration and finish with precision " << max_move << "nano meters" << std::endl; + +#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGNED_TO_SVG + static int counter = 0; + SVG svg(("aligned_" + std::to_string(counter++) + ".svg").c_str(),BoundingBox(island)); + svg.draw(island); + draw(svg, samples, config.head_radius); + svg.Close(); + std::cout << "Align use " << config.count_iteration - count_iteration + << " iteration and finish with precision " << unscale(max_move,0)[0] << + " mm" << std::endl; +#endif + } bool is_points_in_distance(const Slic3r::Point & p, @@ -472,7 +483,10 @@ coord_t SampleIslandUtils::align_once(SupportIslandPoints &samples, } } assert(island_cell != nullptr); + + Point center = island_cell->centroid(); + /* { SVG cell_svg("island_cell.svg", island_cell->points); cell_svg.draw(cell_polygon, "lightgray"); @@ -480,7 +494,7 @@ coord_t SampleIslandUtils::align_once(SupportIslandPoints &samples, cell_svg.draw(*island_cell, "gray"); cell_svg.draw(sample->point, "green", config.head_radius); cell_svg.draw(center, "black", config.head_radius); - } + }*/ assert(is_points_in_distance(center, island_cell->points, config.max_distance)); #ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG svg.draw(cell_polygon, color_point_cell); @@ -1115,7 +1129,7 @@ void SampleIslandUtils::create_sample_center_end( Line edge(VoronoiGraphUtils::to_point(neighbor.edge->vertex0()), VoronoiGraphUtils::to_point(neighbor.edge->vertex1())); for (const auto &support_point : near_no_move) { - if (LineUtils::belongs(edge, support_point->point)) { + if (LineUtils::belongs(edge, support_point->point, 10000)) { exist_no_move = true; break; } @@ -1681,6 +1695,9 @@ bool SampleIslandUtils::is_visualization_disabled() #endif #ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG return false; +#endif +#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGNED_TO_SVG + return false; #endif return true; } diff --git a/src/libslic3r/SLA/SupportIslands/SupportIslandPoint.cpp b/src/libslic3r/SLA/SupportIslands/SupportIslandPoint.cpp index 0fb88fd216..692572b7aa 100644 --- a/src/libslic3r/SLA/SupportIslands/SupportIslandPoint.cpp +++ b/src/libslic3r/SLA/SupportIslands/SupportIslandPoint.cpp @@ -128,9 +128,8 @@ coord_t SupportOutlineIslandPoint::move(const Point &destination) } // apply closest result of move - this->point = closest.point; this->position = closest.position; - return closest.distance; + return SupportIslandPoint::move(closest.point); } Slic3r::Point SupportOutlineIslandPoint::calc_point(const Position &position, const Restriction &restriction) diff --git a/src/libslic3r/SLA/SupportIslands/VectorUtils.hpp b/src/libslic3r/SLA/SupportIslands/VectorUtils.hpp index ccdc728dee..e1efc40059 100644 --- a/src/libslic3r/SLA/SupportIslands/VectorUtils.hpp +++ b/src/libslic3r/SLA/SupportIslands/VectorUtils.hpp @@ -87,7 +87,7 @@ public: --remaining; value_t temp = v[s]; while (d = order_begin[d], d != s) { - swap(temp, v[d]); + std::swap(temp, v[d]); --remaining; } v[s] = temp; diff --git a/tests/sla_print/CMakeLists.txt b/tests/sla_print/CMakeLists.txt index 8ab44e5407..e599c66c8c 100644 --- a/tests/sla_print/CMakeLists.txt +++ b/tests/sla_print/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp sla_raycast_tests.cpp sla_parabola_tests.cpp sla_voronoi_graph_tests.cpp + sla_vectorUtils_tests.cpp + sla_lineUtils_tests.cpp sla_supptreeutils_tests.cpp sla_archive_readwrite_tests.cpp sla_zcorrection_tests.cpp) diff --git a/tests/sla_print/sla_lineUtils_tests.cpp b/tests/sla_print/sla_lineUtils_tests.cpp new file mode 100644 index 0000000000..b5cdef5bca --- /dev/null +++ b/tests/sla_print/sla_lineUtils_tests.cpp @@ -0,0 +1,59 @@ +#include +#include + +using namespace Slic3r; +using namespace Slic3r::sla; + +TEST_CASE("Intersection point", "[Utils], [LineUtils]") +{ + Point a1(0, 0); + Point b1(3, 6); + Line l1(a1, b1); + auto intersection = LineUtils::intersection(l1, Line(Point(0, 4), + Point(5, 4))); + CHECK(intersection.has_value()); + Point i_point = intersection->cast(); + CHECK(PointUtils::is_equal(i_point, Point(2, 4))); + + // same line + auto bad_intersection = LineUtils::intersection(l1, l1); + CHECK(!bad_intersection.has_value()); + + // oposit direction + bad_intersection = LineUtils::intersection(l1, Line(b1, a1)); + CHECK(!bad_intersection.has_value()); + + // parallel line + bad_intersection = LineUtils::intersection(l1, Line(a1 + Point(0, 1), + b1 + Point(0, 1))); + CHECK(!bad_intersection.has_value()); + + // out of line segment, but ray has intersection + Line l2(Point(0, 8), Point(6, 8)); + intersection = LineUtils::intersection(l1, l2); + auto intersection2 = LineUtils::intersection(l2, l1); + CHECK(intersection.has_value()); + CHECK(intersection2.has_value()); + i_point = intersection->cast(); + CHECK(PointUtils::is_equal(i_point, Point(4, 8))); + CHECK(PointUtils::is_equal(i_point, intersection2->cast())); + + Line l3(Point(-2, -2), Point(1, -2)); + intersection = LineUtils::intersection(l1, l3); + intersection2 = LineUtils::intersection(l3, l1); + CHECK(intersection.has_value()); + CHECK(intersection2.has_value()); + i_point = intersection->cast(); + CHECK(PointUtils::is_equal(i_point, Point(-1, -2))); + CHECK(PointUtils::is_equal(i_point, intersection2->cast())); +} + +TEST_CASE("Point belongs to line", "[Utils], [LineUtils]") +{ + Line l(Point(10, 10), Point(50, 30)); + CHECK(LineUtils::belongs(l, Point(30, 20))); + CHECK(!LineUtils::belongs(l, Point(30, 30))); + CHECK(LineUtils::belongs(l, Point(30, 30), 10.)); + CHECK(!LineUtils::belongs(l, Point(30, 10))); + CHECK(!LineUtils::belongs(l, Point(70, 40))); +} diff --git a/tests/sla_print/sla_supptgen_tests.cpp b/tests/sla_print/sla_supptgen_tests.cpp index 3f78021e5e..c0670e7833 100644 --- a/tests/sla_print/sla_supptgen_tests.cpp +++ b/tests/sla_print/sla_supptgen_tests.cpp @@ -456,12 +456,15 @@ SupportIslandPoints test_island_sampling(const ExPolygon & island, } SampleConfig create_sample_config(double size) { + //SupportPointGenerator::Config spg_config; + //return SampleConfigFactory::create(spg_config); + SampleConfig cfg; cfg.max_distance = 3 * size + 0.1; cfg.half_distance = cfg.max_distance/2; cfg.head_radius = size / 4; cfg.minimal_distance_from_outline = cfg.head_radius; - cfg.maximal_distance_from_outline = cfg.half_distance; + cfg.maximal_distance_from_outline = cfg.max_distance/4; cfg.min_side_branch_length = 2 * cfg.minimal_distance_from_outline; cfg.minimal_support_distance = cfg.minimal_distance_from_outline + cfg.half_distance; cfg.max_length_for_one_support_point = 2*size; @@ -471,7 +474,7 @@ SampleConfig create_sample_config(double size) { cfg.outline_sample_distance = cfg.max_distance; cfg.minimal_move = std::max(10000., size/40); - cfg.count_iteration = 100; + cfg.count_iteration = 50; cfg.max_align_distance = 0; return cfg; } @@ -587,8 +590,7 @@ TEST_CASE("Small islands should be supported in center", "[SupGen], [VoronoiSkel double size = 3e7; SampleConfig cfg = create_sample_config(size); ExPolygons islands = createTestIslands(size); - - islands = {islands[16]}; + islands = { create_disc(3 * size, 2*size , 20)}; for (ExPolygon &island : islands) { // information for debug which island cause problem [[maybe_unused]] size_t debug_index = &island - &islands.front(); @@ -708,98 +710,6 @@ TEST_CASE("Compare sampling test", "[hide]") } } -// source: https://en.wikipedia.org/wiki/Centroid -Slic3r::Point centroid(const Slic3r::Polygon &polygon) { - double sum_x = 0.; - double sum_y = 0.; - double signed_area = 0.; - auto add = [&](const Point &p1, const Point &p2) { - Vec2d p1d = p1.cast(); - double area = p1d.x() * p2.y() - p1d.y() * p2.x(); - sum_x += (p1d.x() + p2.x()) * area; - sum_y += (p1d.y() + p2.y()) * area; - signed_area += area; - }; - const Points &points = polygon.points; - for (size_t i = 1; i < points.size(); i++) { - add(points[i - 1], points[i]); - } - add(points.back(), points.front()); - double area6 = signed_area * 3; - return Point(sum_x / area6, sum_y / area6); -} - -TEST_CASE("Trapezoid centroid should be inside of trapezoid", "[Utils]") -{ - Slic3r::Polygon polygon({ - Point(4702134, 1124765853), - Point(-4702134, 1124765853), - Point(-9404268, 1049531706), - Point(9404268, 1049531706) - }); - - Point my_centroid = centroid(polygon); - CHECK(polygon.contains(my_centroid)); - - Point centroid = polygon.centroid(); - CHECK(polygon.contains(centroid)); -} - -#include -TEST_CASE("Reorder destructive", "[Utils]"){ - std::vector data {0, 1, 3, 2, 4, 7, 6, 5, 8}; - std::vector order{0, 1, 3, 2, 4, 7, 6, 5, 8}; - - VectorUtils::reorder_destructive(order.begin(), order.end(), data.begin()); - for (size_t i = 0; i < data.size() - 1;++i) { - CHECK(data[i] < data[i + 1]); - } -} - -#include -TEST_CASE("Intersection point", "[Utils]") -{ - Point a1(0, 0); - Point b1(3, 6); - Line l1(a1, b1); - auto intersection = LineUtils::intersection(l1, Line(Point(0, 4), Point(5, 4))); - CHECK(intersection.has_value()); - Point i_point = intersection->cast(); - CHECK(PointUtils::is_equal(i_point, Point(2, 4))); - - // same line - auto bad_intersection = LineUtils::intersection(l1, l1); - CHECK(!bad_intersection.has_value()); - - // oposit direction - bad_intersection = LineUtils::intersection(l1, Line(b1,a1)); - CHECK(!bad_intersection.has_value()); - - // parallel line - bad_intersection = LineUtils::intersection(l1, Line(a1 + Point(0, 1), - b1 + Point(0, 1))); - CHECK(!bad_intersection.has_value()); - - // out of line segment, but ray has intersection - Line l2(Point(0, 8), Point(6, 8)); - intersection = LineUtils::intersection(l1, l2); - auto intersection2 = LineUtils::intersection(l2, l1); - CHECK(intersection.has_value()); - CHECK(intersection2.has_value()); - i_point = intersection->cast(); - CHECK(PointUtils::is_equal(i_point, Point(4, 8))); - CHECK(PointUtils::is_equal(i_point, intersection2->cast())); - - Line l3(Point(-2, -2), Point(1, -2)); - intersection = LineUtils::intersection(l1, l3); - intersection2 = LineUtils::intersection(l3, l1); - CHECK(intersection.has_value()); - CHECK(intersection2.has_value()); - i_point = intersection->cast(); - CHECK(PointUtils::is_equal(i_point, Point(-1, -2))); - CHECK(PointUtils::is_equal(i_point, intersection2->cast())); -} - TEST_CASE("Disable visualization", "[hide]") { CHECK(true); diff --git a/tests/sla_print/sla_vectorUtils_tests.cpp b/tests/sla_print/sla_vectorUtils_tests.cpp new file mode 100644 index 0000000000..f43fb7a15d --- /dev/null +++ b/tests/sla_print/sla_vectorUtils_tests.cpp @@ -0,0 +1,25 @@ +#include +#include + +using namespace Slic3r::sla; + +TEST_CASE("Reorder", "[Utils], [VectorUtils]") +{ + std::vector data{0, 1, 3, 2, 4, 7, 6, 5, 8}; + std::vector order{0, 1, 3, 2, 4, 7, 6, 5, 8}; + + VectorUtils::reorder(order.begin(), order.end(), data.begin()); + for (size_t i = 0; i < data.size() - 1; ++i) { + CHECK(data[i] < data[i + 1]); + } +} + +TEST_CASE("Reorder destructive", "[Utils], [VectorUtils]"){ + std::vector data {0, 1, 3, 2, 4, 7, 6, 5, 8}; + std::vector order{0, 1, 3, 2, 4, 7, 6, 5, 8}; + + VectorUtils::reorder_destructive(order.begin(), order.end(), data.begin()); + for (size_t i = 0; i < data.size() - 1;++i) { + CHECK(data[i] < data[i + 1]); + } +}