diff options
author | enricoturri1966 <enricoturri@seznam.cz> | 2020-08-19 09:18:23 +0300 |
---|---|---|
committer | enricoturri1966 <enricoturri@seznam.cz> | 2020-08-19 09:18:23 +0300 |
commit | af200e47c13e34a4155f70ac822fb6f1a8e615cd (patch) | |
tree | 17339e26762ec8f57e33d94ac4c15a13030d1085 /tests | |
parent | 7b5f84b7dfdb9de22bfb87d3d69ab29e021a5a23 (diff) | |
parent | 5052149b819c438b107a28268e3da0f48f57e8cb (diff) |
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_gcode_viewer
Diffstat (limited to 'tests')
-rw-r--r-- | tests/sla_print/CMakeLists.txt | 5 | ||||
-rw-r--r-- | tests/sla_print/sla_supptgen_tests.cpp | 148 | ||||
-rw-r--r-- | tests/sla_print/sla_test_utils.cpp | 68 | ||||
-rw-r--r-- | tests/sla_print/sla_test_utils.hpp | 9 |
4 files changed, 228 insertions, 2 deletions
diff --git a/tests/sla_print/CMakeLists.txt b/tests/sla_print/CMakeLists.txt index f6b261fda..d071b4973 100644 --- a/tests/sla_print/CMakeLists.txt +++ b/tests/sla_print/CMakeLists.txt @@ -1,7 +1,8 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) -add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp - sla_print_tests.cpp +add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp + sla_print_tests.cpp sla_test_utils.hpp sla_test_utils.cpp sla_treebuilder_tests.cpp + sla_supptgen_tests.cpp sla_raycast_tests.cpp) target_link_libraries(${_TEST_NAME}_tests test_common libslic3r) set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") diff --git a/tests/sla_print/sla_supptgen_tests.cpp b/tests/sla_print/sla_supptgen_tests.cpp new file mode 100644 index 000000000..1d7a3ebee --- /dev/null +++ b/tests/sla_print/sla_supptgen_tests.cpp @@ -0,0 +1,148 @@ +#include <catch2/catch.hpp> +#include <test_utils.hpp> + +#include <libslic3r/ExPolygon.hpp> +#include <libslic3r/BoundingBox.hpp> + +#include "sla_test_utils.hpp" + +namespace Slic3r { namespace sla { + +TEST_CASE("Overhanging point should be supported", "[SupGen]") { + + // Pyramid with 45 deg slope + TriangleMesh mesh = make_pyramid(10.f, 10.f); + mesh.rotate_y(PI); + mesh.require_shared_vertices(); + mesh.WriteOBJFile("Pyramid.obj"); + + sla::SupportPoints pts = calc_support_pts(mesh); + + // The overhang, which is the upside-down pyramid's edge + Vec3f overh{0., 0., -10.}; + + REQUIRE(!pts.empty()); + + float dist = (overh - pts.front().pos).norm(); + + for (const auto &pt : pts) + dist = std::min(dist, (overh - pt.pos).norm()); + + // Should require exactly one support point at the overhang + REQUIRE(pts.size() > 0); + REQUIRE(dist < 1.f); +} + +double min_point_distance(const sla::SupportPoints &pts) +{ + sla::PointIndex index; + + for (size_t i = 0; i < pts.size(); ++i) + index.insert(pts[i].pos.cast<double>(), i); + + auto d = std::numeric_limits<double>::max(); + index.foreach([&d, &index](const sla::PointIndexEl &el) { + auto res = index.nearest(el.first, 2); + for (const sla::PointIndexEl &r : res) + if (r.second != el.second) + d = std::min(d, (el.first - r.first).norm()); + }); + + return d; +} + +TEST_CASE("Overhanging horizontal surface should be supported", "[SupGen]") { + double width = 10., depth = 10., height = 1.; + + TriangleMesh mesh = make_cube(width, depth, height); + mesh.translate(0., 0., 5.); // lift up + mesh.require_shared_vertices(); + mesh.WriteOBJFile("Cuboid.obj"); + + sla::SupportPointGenerator::Config cfg; + sla::SupportPoints pts = calc_support_pts(mesh, cfg); + + double mm2 = width * depth; + + REQUIRE(!pts.empty()); + REQUIRE(pts.size() * cfg.support_force() > mm2 * cfg.tear_pressure()); + REQUIRE(min_point_distance(pts) >= cfg.minimal_distance); +} + +template<class M> auto&& center_around_bb(M &&mesh) +{ + auto bb = mesh.bounding_box(); + mesh.translate(-bb.center().template cast<float>()); + + return std::forward<M>(mesh); +} + +TEST_CASE("Overhanging edge should be supported", "[SupGen]") { + float width = 10.f, depth = 10.f, height = 5.f; + + TriangleMesh mesh = make_prism(width, depth, height); + mesh.rotate_y(PI); // rotate on its back + mesh.translate(0., 0., height); + mesh.require_shared_vertices(); + mesh.WriteOBJFile("Prism.obj"); + + sla::SupportPointGenerator::Config cfg; + sla::SupportPoints pts = calc_support_pts(mesh, cfg); + + REQUIRE(min_point_distance(pts) >= cfg.minimal_distance); + + Linef3 overh{ {0.f, -depth / 2.f, 0.f}, {0.f, depth / 2.f, 0.f}}; + + // Get all the points closer that 1 mm to the overhanging edge: + sla::SupportPoints overh_pts; overh_pts.reserve(pts.size()); + + std::copy_if(pts.begin(), pts.end(), std::back_inserter(overh_pts), + [&overh](const sla::SupportPoint &pt){ + return line_alg::distance_to(overh, Vec3d{pt.pos.cast<double>()}) < 1.; + }); + + REQUIRE(overh_pts.size() * cfg.support_force() > overh.length() * cfg.tear_pressure()); + REQUIRE(min_point_distance(pts) >= cfg.minimal_distance); +} + +// FIXME: Not working yet +//TEST_CASE("Hollowed cube should be supported from the inside", "[SupGen][Hollowed]") { +// TriangleMesh mesh = make_cube(20., 20., 20.); + +// hollow_mesh(mesh, HollowingConfig{}); + +// mesh.WriteOBJFile("cube_hollowed.obj"); + +// auto bb = mesh.bounding_box(); +// auto h = float(bb.max.z() - bb.min.z()); +// Vec3f mv = bb.center().cast<float>() - Vec3f{0.f, 0.f, 0.5f * h}; +// mesh.translate(-mv); +// mesh.require_shared_vertices(); + +// sla::SupportPointGenerator::Config cfg; +// sla::SupportPoints pts = calc_support_pts(mesh, cfg); +// sla::remove_bottom_points(pts, mesh.bounding_box().min.z() + EPSILON); + +// REQUIRE(!pts.empty()); +//} + +TEST_CASE("Two parallel plates should be supported", "[SupGen][Hollowed]") +{ + double width = 20., depth = 20., height = 1.; + + TriangleMesh mesh = center_around_bb(make_cube(width + 5., depth + 5., height)); + TriangleMesh mesh_high = center_around_bb(make_cube(width, depth, height)); + mesh_high.translate(0., 0., 10.); // lift up + mesh.merge(mesh_high); + mesh.require_shared_vertices(); + + mesh.WriteOBJFile("parallel_plates.obj"); + + sla::SupportPointGenerator::Config cfg; + sla::SupportPoints pts = calc_support_pts(mesh, cfg); + sla::remove_bottom_points(pts, mesh.bounding_box().min.z() + EPSILON); + + REQUIRE(!pts.empty()); +} + +}} // namespace Slic3r::sla diff --git a/tests/sla_print/sla_test_utils.cpp b/tests/sla_print/sla_test_utils.cpp index 8978281d8..f6b548fa0 100644 --- a/tests/sla_print/sla_test_utils.cpp +++ b/tests/sla_print/sla_test_utils.cpp @@ -411,3 +411,71 @@ double predict_error(const ExPolygon &p, const sla::RasterBase::PixelDim &pd) return error; } + + +// Make a 3D pyramid +TriangleMesh make_pyramid(float base, float height) +{ + float a = base / 2.f; + + TriangleMesh mesh( + { + {-a, -a, 0}, {a, -a, 0}, {a, a, 0}, + {-a, a, 0}, {0.f, 0.f, height} + }, + { + {0, 1, 2}, + {0, 2, 3}, + {0, 1, 4}, + {1, 2, 4}, + {2, 3, 4}, + {3, 0, 4} + }); + + mesh.repair(); + + return mesh; +} + + TriangleMesh make_prism(double width, double length, double height) +{ + // We need two upward facing triangles + + double x = width / 2., y = length / 2.; + + TriangleMesh mesh( + { + {-x, -y, 0.}, {x, -y, 0.}, {0., -y, height}, + {-x, y, 0.}, {x, y, 0.}, {0., y, height}, + }, + { + {0, 1, 2}, // side 1 + {4, 3, 5}, // side 2 + {1, 4, 2}, {2, 4, 5}, // roof 1 + {0, 2, 5}, {0, 5, 3}, // roof 2 + {3, 4, 1}, {3, 1, 0} // bottom + }); + + return mesh; +} + +sla::SupportPoints calc_support_pts( + const TriangleMesh & mesh, + const sla::SupportPointGenerator::Config &cfg) +{ + // Prepare the slice grid and the slices + std::vector<ExPolygons> slices; + auto bb = cast<float>(mesh.bounding_box()); + std::vector<float> heights = grid(bb.min.z(), bb.max.z(), 0.1f); + slice_mesh(mesh, heights, slices, CLOSING_RADIUS, [] {}); + + // Prepare the support point calculator + sla::IndexedMesh emesh{mesh}; + sla::SupportPointGenerator spgen{emesh, cfg, []{}, [](int){}}; + + // Calculate the support points + spgen.seed(0); + spgen.execute(slices, heights); + + return spgen.output(); +} diff --git a/tests/sla_print/sla_test_utils.hpp b/tests/sla_print/sla_test_utils.hpp index fdd883ed8..d10a85b25 100644 --- a/tests/sla_print/sla_test_utils.hpp +++ b/tests/sla_print/sla_test_utils.hpp @@ -185,4 +185,13 @@ long raster_pxsum(const sla::RasterGrayscaleAA &raster); double predict_error(const ExPolygon &p, const sla::RasterBase::PixelDim &pd); +// Make a 3D pyramid +TriangleMesh make_pyramid(float base, float height); + +TriangleMesh make_prism(double width, double length, double height); + +sla::SupportPoints calc_support_pts( + const TriangleMesh & mesh, + const sla::SupportPointGenerator::Config &cfg = {}); + #endif // SLA_TEST_UTILS_HPP |