Fix aligning

- function belong
- Calculation of move distance on outline

Separate utils tests
This commit is contained in:
Filip Sykala 2021-05-10 20:47:41 +02:00 committed by Lukas Matena
parent 12b320624b
commit a3d17119f6
9 changed files with 122 additions and 108 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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 <cassert>
@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -0,0 +1,59 @@
#include <catch2/catch.hpp>
#include <libslic3r/SLA/SupportIslands/LineUtils.hpp>
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<coord_t>();
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<coord_t>();
CHECK(PointUtils::is_equal(i_point, Point(4, 8)));
CHECK(PointUtils::is_equal(i_point, intersection2->cast<coord_t>()));
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<coord_t>();
CHECK(PointUtils::is_equal(i_point, Point(-1, -2)));
CHECK(PointUtils::is_equal(i_point, intersection2->cast<coord_t>()));
}
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)));
}

View File

@ -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>();
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 <libslic3r/SLA/SupportIslands/VectorUtils.hpp>
TEST_CASE("Reorder destructive", "[Utils]"){
std::vector<int> data {0, 1, 3, 2, 4, 7, 6, 5, 8};
std::vector<int> 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 <libslic3r/SLA/SupportIslands/LineUtils.hpp>
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<coord_t>();
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<coord_t>();
CHECK(PointUtils::is_equal(i_point, Point(4, 8)));
CHECK(PointUtils::is_equal(i_point, intersection2->cast<coord_t>()));
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<coord_t>();
CHECK(PointUtils::is_equal(i_point, Point(-1, -2)));
CHECK(PointUtils::is_equal(i_point, intersection2->cast<coord_t>()));
}
TEST_CASE("Disable visualization", "[hide]")
{
CHECK(true);

View File

@ -0,0 +1,25 @@
#include <catch2/catch.hpp>
#include <libslic3r/SLA/SupportIslands/VectorUtils.hpp>
using namespace Slic3r::sla;
TEST_CASE("Reorder", "[Utils], [VectorUtils]")
{
std::vector<int> data{0, 1, 3, 2, 4, 7, 6, 5, 8};
std::vector<int> 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<int> data {0, 1, 3, 2, 4, 7, 6, 5, 8};
std::vector<int> 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]);
}
}