mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 04:22:04 +08:00
Fix aligning
- function belong - Calculation of move distance on outline Separate utils tests
This commit is contained in:
parent
12b320624b
commit
a3d17119f6
@ -285,9 +285,11 @@ bool LineUtils::belongs(const Line &line, const Point &point, double benevolence
|
|||||||
const Point &b = line.b;
|
const Point &b = line.b;
|
||||||
auto is_in_interval = [](coord_t value, coord_t from, coord_t to) -> bool
|
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;
|
if (from > value || to < value) return false;
|
||||||
} else {
|
} else {
|
||||||
|
// to < value < from
|
||||||
if (from < value || to > value) return false;
|
if (from < value || to > value) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
result.half_distance = result.max_distance / 2;
|
result.half_distance = result.max_distance / 2;
|
||||||
result.head_radius = head_diameter / 2;
|
result.head_radius = head_diameter / 2;
|
||||||
result.minimal_distance_from_outline = result.head_radius;
|
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);
|
assert(result.minimal_distance_from_outline < result.maximal_distance_from_outline);
|
||||||
result.minimal_support_distance = result.minimal_distance_from_outline +
|
result.minimal_support_distance = result.minimal_distance_from_outline +
|
||||||
result.half_distance;
|
result.half_distance;
|
||||||
|
@ -20,10 +20,11 @@
|
|||||||
// comment definition of NDEBUG to enable assert()
|
// comment definition of NDEBUG to enable assert()
|
||||||
//#define NDEBUG
|
//#define NDEBUG
|
||||||
|
|
||||||
#define SLA_SAMPLE_ISLAND_UTILS_STORE_VORONOI_GRAPH_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_INITIAL_SAMPLE_POSITION_TO_SVG
|
||||||
#define SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_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_ALIGN_ONCE_TO_SVG
|
||||||
|
//#define SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGNED_TO_SVG
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@ -410,8 +411,18 @@ void SampleIslandUtils::align_samples(SupportIslandPoints &samples,
|
|||||||
max_move = align_once(samples, island, config);
|
max_move = align_once(samples, island, config);
|
||||||
if (max_move < config.minimal_move) break;
|
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,
|
bool is_points_in_distance(const Slic3r::Point & p,
|
||||||
@ -472,7 +483,10 @@ coord_t SampleIslandUtils::align_once(SupportIslandPoints &samples,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(island_cell != nullptr);
|
assert(island_cell != nullptr);
|
||||||
|
|
||||||
|
|
||||||
Point center = island_cell->centroid();
|
Point center = island_cell->centroid();
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
SVG cell_svg("island_cell.svg", island_cell->points);
|
SVG cell_svg("island_cell.svg", island_cell->points);
|
||||||
cell_svg.draw(cell_polygon, "lightgray");
|
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(*island_cell, "gray");
|
||||||
cell_svg.draw(sample->point, "green", config.head_radius);
|
cell_svg.draw(sample->point, "green", config.head_radius);
|
||||||
cell_svg.draw(center, "black", config.head_radius);
|
cell_svg.draw(center, "black", config.head_radius);
|
||||||
}
|
}*/
|
||||||
assert(is_points_in_distance(center, island_cell->points, config.max_distance));
|
assert(is_points_in_distance(center, island_cell->points, config.max_distance));
|
||||||
#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG
|
#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG
|
||||||
svg.draw(cell_polygon, color_point_cell);
|
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()),
|
Line edge(VoronoiGraphUtils::to_point(neighbor.edge->vertex0()),
|
||||||
VoronoiGraphUtils::to_point(neighbor.edge->vertex1()));
|
VoronoiGraphUtils::to_point(neighbor.edge->vertex1()));
|
||||||
for (const auto &support_point : near_no_move) {
|
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;
|
exist_no_move = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1681,6 +1695,9 @@ bool SampleIslandUtils::is_visualization_disabled()
|
|||||||
#endif
|
#endif
|
||||||
#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG
|
#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
|
#ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGNED_TO_SVG
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -128,9 +128,8 @@ coord_t SupportOutlineIslandPoint::move(const Point &destination)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply closest result of move
|
// apply closest result of move
|
||||||
this->point = closest.point;
|
|
||||||
this->position = closest.position;
|
this->position = closest.position;
|
||||||
return closest.distance;
|
return SupportIslandPoint::move(closest.point);
|
||||||
}
|
}
|
||||||
|
|
||||||
Slic3r::Point SupportOutlineIslandPoint::calc_point(const Position &position, const Restriction &restriction)
|
Slic3r::Point SupportOutlineIslandPoint::calc_point(const Position &position, const Restriction &restriction)
|
||||||
|
@ -87,7 +87,7 @@ public:
|
|||||||
--remaining;
|
--remaining;
|
||||||
value_t temp = v[s];
|
value_t temp = v[s];
|
||||||
while (d = order_begin[d], d != s) {
|
while (d = order_begin[d], d != s) {
|
||||||
swap(temp, v[d]);
|
std::swap(temp, v[d]);
|
||||||
--remaining;
|
--remaining;
|
||||||
}
|
}
|
||||||
v[s] = temp;
|
v[s] = temp;
|
||||||
|
@ -6,6 +6,8 @@ add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp
|
|||||||
sla_raycast_tests.cpp
|
sla_raycast_tests.cpp
|
||||||
sla_parabola_tests.cpp
|
sla_parabola_tests.cpp
|
||||||
sla_voronoi_graph_tests.cpp
|
sla_voronoi_graph_tests.cpp
|
||||||
|
sla_vectorUtils_tests.cpp
|
||||||
|
sla_lineUtils_tests.cpp
|
||||||
sla_supptreeutils_tests.cpp
|
sla_supptreeutils_tests.cpp
|
||||||
sla_archive_readwrite_tests.cpp
|
sla_archive_readwrite_tests.cpp
|
||||||
sla_zcorrection_tests.cpp)
|
sla_zcorrection_tests.cpp)
|
||||||
|
59
tests/sla_print/sla_lineUtils_tests.cpp
Normal file
59
tests/sla_print/sla_lineUtils_tests.cpp
Normal 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)));
|
||||||
|
}
|
@ -456,12 +456,15 @@ SupportIslandPoints test_island_sampling(const ExPolygon & island,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SampleConfig create_sample_config(double size) {
|
SampleConfig create_sample_config(double size) {
|
||||||
|
//SupportPointGenerator::Config spg_config;
|
||||||
|
//return SampleConfigFactory::create(spg_config);
|
||||||
|
|
||||||
SampleConfig cfg;
|
SampleConfig cfg;
|
||||||
cfg.max_distance = 3 * size + 0.1;
|
cfg.max_distance = 3 * size + 0.1;
|
||||||
cfg.half_distance = cfg.max_distance/2;
|
cfg.half_distance = cfg.max_distance/2;
|
||||||
cfg.head_radius = size / 4;
|
cfg.head_radius = size / 4;
|
||||||
cfg.minimal_distance_from_outline = cfg.head_radius;
|
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.min_side_branch_length = 2 * cfg.minimal_distance_from_outline;
|
||||||
cfg.minimal_support_distance = cfg.minimal_distance_from_outline + cfg.half_distance;
|
cfg.minimal_support_distance = cfg.minimal_distance_from_outline + cfg.half_distance;
|
||||||
cfg.max_length_for_one_support_point = 2*size;
|
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.outline_sample_distance = cfg.max_distance;
|
||||||
|
|
||||||
cfg.minimal_move = std::max(10000., size/40);
|
cfg.minimal_move = std::max(10000., size/40);
|
||||||
cfg.count_iteration = 100;
|
cfg.count_iteration = 50;
|
||||||
cfg.max_align_distance = 0;
|
cfg.max_align_distance = 0;
|
||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
@ -587,8 +590,7 @@ TEST_CASE("Small islands should be supported in center", "[SupGen], [VoronoiSkel
|
|||||||
double size = 3e7;
|
double size = 3e7;
|
||||||
SampleConfig cfg = create_sample_config(size);
|
SampleConfig cfg = create_sample_config(size);
|
||||||
ExPolygons islands = createTestIslands(size);
|
ExPolygons islands = createTestIslands(size);
|
||||||
|
islands = { create_disc(3 * size, 2*size , 20)};
|
||||||
islands = {islands[16]};
|
|
||||||
for (ExPolygon &island : islands) {
|
for (ExPolygon &island : islands) {
|
||||||
// information for debug which island cause problem
|
// information for debug which island cause problem
|
||||||
[[maybe_unused]] size_t debug_index = &island - &islands.front();
|
[[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]")
|
TEST_CASE("Disable visualization", "[hide]")
|
||||||
{
|
{
|
||||||
CHECK(true);
|
CHECK(true);
|
||||||
|
25
tests/sla_print/sla_vectorUtils_tests.cpp
Normal file
25
tests/sla_print/sla_vectorUtils_tests.cpp
Normal 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]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user