Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sla_print/sla_test_utils.cpp')
-rw-r--r--tests/sla_print/sla_test_utils.cpp146
1 files changed, 118 insertions, 28 deletions
diff --git a/tests/sla_print/sla_test_utils.cpp b/tests/sla_print/sla_test_utils.cpp
index a844b2eae..653221cd3 100644
--- a/tests/sla_print/sla_test_utils.cpp
+++ b/tests/sla_print/sla_test_utils.cpp
@@ -1,13 +1,14 @@
#include "sla_test_utils.hpp"
+#include "libslic3r/SLA/AGGRaster.hpp"
void test_support_model_collision(const std::string &obj_filename,
- const sla::SupportConfig &input_supportcfg,
+ const sla::SupportTreeConfig &input_supportcfg,
const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes)
{
SupportByproducts byproducts;
- sla::SupportConfig supportcfg = input_supportcfg;
+ sla::SupportTreeConfig supportcfg = input_supportcfg;
// Set head penetration to a small negative value which should ensure that
// the supports will not touch the model body.
@@ -37,7 +38,10 @@ void test_support_model_collision(const std::string &obj_filename,
Polygons intersections = intersection(sup_slice, mod_slice);
- notouch = notouch && intersections.empty();
+ double pinhead_r = scaled(input_supportcfg.head_front_radius_mm);
+
+ // TODO:: make it strict without a threshold of PI * pihead_radius ^ 2
+ notouch = notouch && area(intersections) < PI * pinhead_r * pinhead_r;
}
/*if (!notouch) */export_failed_case(support_slices, byproducts);
@@ -68,11 +72,12 @@ void export_failed_case(const std::vector<ExPolygons> &support_slices, const Sup
m.merge(byproducts.input_mesh);
m.repair();
m.require_shared_vertices();
- m.WriteOBJFile(byproducts.obj_fname.c_str());
+ m.WriteOBJFile((Catch::getResultCapture().getCurrentTestName() + "_" +
+ byproducts.obj_fname).c_str());
}
void test_supports(const std::string &obj_filename,
- const sla::SupportConfig &supportcfg,
+ const sla::SupportTreeConfig &supportcfg,
const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes,
SupportByproducts &out)
@@ -103,9 +108,14 @@ void test_supports(const std::string &obj_filename,
// Create the special index-triangle mesh with spatial indexing which
// is the input of the support point and support mesh generators
- sla::EigenMesh3D emesh{mesh};
+ sla::IndexedMesh emesh{mesh};
+
+#ifdef SLIC3R_HOLE_RAYCASTER
if (hollowingcfg.enabled)
emesh.load_holes(drainholes);
+#endif
+
+ // TODO: do the cgal hole cutting...
// Create the support point generator
sla::SupportPointGenerator::Config autogencfg;
@@ -123,8 +133,7 @@ void test_supports(const std::string &obj_filename,
// If there is no elevation, support points shall be removed from the
// bottom of the object.
if (std::abs(supportcfg.object_elevation_mm) < EPSILON) {
- sla::remove_bottom_points(support_points, zmin,
- supportcfg.base_height_mm);
+ sla::remove_bottom_points(support_points, zmin + supportcfg.base_height_mm);
} else {
// Should be support points at least on the bottom of the model
REQUIRE_FALSE(support_points.empty());
@@ -135,7 +144,8 @@ void test_supports(const std::string &obj_filename,
// Generate the actual support tree
sla::SupportTreeBuilder treebuilder;
- treebuilder.build(sla::SupportableMesh{emesh, support_points, supportcfg});
+ sla::SupportableMesh sm{emesh, support_points, supportcfg};
+ sla::SupportTreeBuildsteps::execute(treebuilder, sm);
check_support_tree_integrity(treebuilder, supportcfg);
@@ -151,8 +161,8 @@ void test_supports(const std::string &obj_filename,
if (std::abs(supportcfg.object_elevation_mm) < EPSILON)
allowed_zmin = zmin - 2 * supportcfg.head_back_radius_mm;
- REQUIRE(obb.min.z() >= allowed_zmin);
- REQUIRE(obb.max.z() <= zmax);
+ REQUIRE(obb.min.z() >= Approx(allowed_zmin));
+ REQUIRE(obb.max.z() <= Approx(zmax));
// Move out the support tree into the byproducts, we can examine it further
// in various tests.
@@ -162,15 +172,15 @@ void test_supports(const std::string &obj_filename,
}
void check_support_tree_integrity(const sla::SupportTreeBuilder &stree,
- const sla::SupportConfig &cfg)
+ const sla::SupportTreeConfig &cfg)
{
double gnd = stree.ground_level;
double H1 = cfg.max_solo_pillar_height_mm;
double H2 = cfg.max_dual_pillar_height_mm;
for (const sla::Head &head : stree.heads()) {
- REQUIRE((!head.is_valid() || head.pillar_id != sla::ID_UNSET ||
- head.bridge_id != sla::ID_UNSET));
+ REQUIRE((!head.is_valid() || head.pillar_id != sla::SupportTreeNode::ID_UNSET ||
+ head.bridge_id != sla::SupportTreeNode::ID_UNSET));
}
for (const sla::Pillar &pillar : stree.pillars()) {
@@ -198,7 +208,7 @@ void check_support_tree_integrity(const sla::SupportTreeBuilder &stree,
};
for (auto &bridge : stree.bridges()) chck_bridge(bridge, max_bridgelen);
- REQUIRE(max_bridgelen <= cfg.max_bridge_length_mm);
+ REQUIRE(max_bridgelen <= Approx(cfg.max_bridge_length_mm));
max_bridgelen = 0;
for (auto &bridge : stree.crossbridges()) chck_bridge(bridge, max_bridgelen);
@@ -293,18 +303,19 @@ void check_validity(const TriangleMesh &input_mesh, int flags)
}
}
-void check_raster_transformations(sla::Raster::Orientation o, sla::Raster::TMirroring mirroring)
+void check_raster_transformations(sla::RasterBase::Orientation o, sla::RasterBase::TMirroring mirroring)
{
double disp_w = 120., disp_h = 68.;
- sla::Raster::Resolution res{2560, 1440};
- sla::Raster::PixelDim pixdim{disp_w / res.width_px, disp_h / res.height_px};
+ sla::RasterBase::Resolution res{2560, 1440};
+ sla::RasterBase::PixelDim pixdim{disp_w / res.width_px, disp_h / res.height_px};
auto bb = BoundingBox({0, 0}, {scaled(disp_w), scaled(disp_h)});
- sla::Raster::Trafo trafo{o, mirroring};
- trafo.origin_x = bb.center().x();
- trafo.origin_y = bb.center().y();
+ sla::RasterBase::Trafo trafo{o, mirroring};
+ trafo.center_x = bb.center().x();
+ trafo.center_y = bb.center().y();
+ double gamma = 1.;
- sla::Raster raster{res, pixdim, trafo};
+ sla::RasterGrayscaleAAGammaPower raster{res, pixdim, trafo, gamma};
// create box of size 32x32 pixels (not 1x1 to avoid antialiasing errors)
coord_t pw = 32 * coord_t(std::ceil(scaled<double>(pixdim.w_mm)));
@@ -319,7 +330,7 @@ void check_raster_transformations(sla::Raster::Orientation o, sla::Raster::TMirr
// Now calculate the position of the translated box according to output
// trafo.
- if (o == sla::Raster::Orientation::roPortrait) expected_box.rotate(PI / 2.);
+ if (o == sla::RasterBase::Orientation::roPortrait) expected_box.rotate(PI / 2.);
if (mirroring[X])
for (auto &p : expected_box.contour.points) p.x() = -p.x();
@@ -340,10 +351,9 @@ void check_raster_transformations(sla::Raster::Orientation o, sla::Raster::TMirr
auto px = raster.read_pixel(w, h);
if (px != FullWhite) {
- sla::PNGImage img;
std::fstream outf("out.png", std::ios::out);
- outf << img.serialize(raster);
+ outf << raster.encode(sla::PNGRasterEncoder());
}
REQUIRE(px == FullWhite);
@@ -361,9 +371,21 @@ ExPolygon square_with_hole(double v)
return poly;
}
-double raster_white_area(const sla::Raster &raster)
+long raster_pxsum(const sla::RasterGrayscaleAA &raster)
{
- if (raster.empty()) return std::nan("");
+ auto res = raster.resolution();
+ long a = 0;
+
+ for (size_t x = 0; x < res.width_px; ++x)
+ for (size_t y = 0; y < res.height_px; ++y)
+ a += raster.read_pixel(x, y);
+
+ return a;
+}
+
+double raster_white_area(const sla::RasterGrayscaleAA &raster)
+{
+ if (raster.resolution().pixels() == 0) return std::nan("");
auto res = raster.resolution();
double a = 0;
@@ -377,7 +399,7 @@ double raster_white_area(const sla::Raster &raster)
return a;
}
-double predict_error(const ExPolygon &p, const sla::Raster::PixelDim &pd)
+double predict_error(const ExPolygon &p, const sla::RasterBase::PixelDim &pd)
{
auto lines = p.lines();
double pix_err = pixel_area(FullWhite, pd) / 2.;
@@ -392,3 +414,71 @@ double predict_error(const ExPolygon &p, const sla::Raster::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();
+}