diff --git a/src/libslic3r/SLA/SupportPointGenerator.cpp b/src/libslic3r/SLA/SupportPointGenerator.cpp index 55124d4fc..78c2ced35 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.cpp +++ b/src/libslic3r/SLA/SupportPointGenerator.cpp @@ -49,26 +49,6 @@ float SupportPointGenerator::distance_limit(float angle) const return 1./(2.4*get_required_density(angle)); }*/ -class SupportPointGenerator::RandomGen { - std::mt19937 m_; -public: - - using result_type = long; - - RandomGen() - { - std::random_device rd; - m_.seed(rd()); - } - - explicit RandomGen(long seedval) { seed(seedval); } - - void seed(long s) { m_.seed(std::mt19937::result_type(s)); } - long operator() () { return long(m_()); } - long min() const { return m_.min(); } - long max() const { return m_.max(); } -}; - SupportPointGenerator::SupportPointGenerator( const sla::EigenMesh3D &emesh, const std::vector &slices, @@ -78,6 +58,8 @@ SupportPointGenerator::SupportPointGenerator( std::function statusfn) : SupportPointGenerator(emesh, config, throw_on_cancel, statusfn) { + std::random_device rd; + m_rng.seed(rd()); execute(slices, heights); } @@ -96,17 +78,7 @@ SupportPointGenerator::SupportPointGenerator( void SupportPointGenerator::execute(const std::vector &slices, const std::vector & heights) { - RandomGen rng; - process(slices, heights, rng); - project_onto_mesh(m_output); -} - -void SupportPointGenerator::execute(const std::vector &slices, - const std::vector & heights, - long seed) -{ - RandomGen rng(seed); - process(slices, heights, rng); + process(slices, heights); project_onto_mesh(m_output); } @@ -230,7 +202,7 @@ static std::vector make_layers( return layers; } -void SupportPointGenerator::process(const std::vector& slices, const std::vector& heights, RandomGen &rng) +void SupportPointGenerator::process(const std::vector& slices, const std::vector& heights) { #ifdef SLA_SUPPORTPOINTGEN_DEBUG std::vector> islands; @@ -285,15 +257,15 @@ void SupportPointGenerator::process(const std::vector& slices, const //float force_deficit = s.support_force_deficit(m_config.tear_pressure()); if (s.islands_below.empty()) { // completely new island - needs support no doubt - uniformly_cover({ *s.polygon }, s, point_grid, rng, true); + uniformly_cover({ *s.polygon }, s, point_grid, true); } else if (! s.dangling_areas.empty()) { // Let's see if there's anything that overlaps enough to need supports: // What we now have in polygons needs support, regardless of what the forces are, so we can add them. //FIXME is it an island point or not? Vojtech thinks it is. - uniformly_cover(s.dangling_areas, s, point_grid, rng); + uniformly_cover(s.dangling_areas, s, point_grid); } else if (! s.overhangs_slopes.empty()) { //FIXME add the support force deficit as a parameter, only cover until the defficiency is covered. - uniformly_cover(s.overhangs_slopes, s, point_grid, rng); + uniformly_cover(s.overhangs_slopes, s, point_grid); } } @@ -312,7 +284,7 @@ void SupportPointGenerator::process(const std::vector& slices, const } } -std::vector sample_expolygon(const ExPolygon &expoly, float samples_per_mm2, SupportPointGenerator::RandomGen &rng) +std::vector sample_expolygon(const ExPolygon &expoly, float samples_per_mm2, std::mt19937 &rng) { // Triangulate the polygon with holes into triplets of 3D points. std::vector triangles = Slic3r::triangulate_expolygon_2f(expoly); @@ -352,7 +324,7 @@ std::vector sample_expolygon(const ExPolygon &expoly, float samples_per_m return out; } -std::vector sample_expolygon_with_boundary(const ExPolygon &expoly, float samples_per_mm2, float samples_per_mm_boundary, SupportPointGenerator::RandomGen &rng) +std::vector sample_expolygon_with_boundary(const ExPolygon &expoly, float samples_per_mm2, float samples_per_mm_boundary, std::mt19937 &rng) { std::vector out = sample_expolygon(expoly, samples_per_mm2, rng); double point_stepping_scaled = scale_(1.f) / samples_per_mm_boundary; @@ -365,7 +337,7 @@ std::vector sample_expolygon_with_boundary(const ExPolygon &expoly, float return out; } -std::vector sample_expolygon_with_boundary(const ExPolygons &expolys, float samples_per_mm2, float samples_per_mm_boundary, SupportPointGenerator::RandomGen &rng) +std::vector sample_expolygon_with_boundary(const ExPolygons &expolys, float samples_per_mm2, float samples_per_mm_boundary, std::mt19937 &rng) { std::vector out; for (const ExPolygon &expoly : expolys) @@ -488,7 +460,7 @@ static inline std::vector poisson_disk_from_samples(const std::vector raw_samples = sample_expolygon_with_boundary(islands, samples_per_mm2, 5.f / poisson_radius, rng); + std::vector raw_samples = sample_expolygon_with_boundary(islands, samples_per_mm2, 5.f / poisson_radius, m_rng); std::vector poisson_samples; for (size_t iter = 0; iter < 4; ++ iter) { poisson_samples = poisson_disk_from_samples(raw_samples, poisson_radius, @@ -541,7 +513,7 @@ void SupportPointGenerator::uniformly_cover(const ExPolygons& islands, Structure // assert(! poisson_samples.empty()); if (poisson_samples_target < poisson_samples.size()) { - std::shuffle(poisson_samples.begin(), poisson_samples.end(), rng); + std::shuffle(poisson_samples.begin(), poisson_samples.end(), m_rng); poisson_samples.erase(poisson_samples.begin() + poisson_samples_target, poisson_samples.end()); } for (const Vec2f &pt : poisson_samples) { diff --git a/src/libslic3r/SLA/SupportPointGenerator.hpp b/src/libslic3r/SLA/SupportPointGenerator.hpp index b8f5b607e..738fc5730 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.hpp +++ b/src/libslic3r/SLA/SupportPointGenerator.hpp @@ -1,6 +1,8 @@ #ifndef SLA_SUPPORTPOINTGENERATOR_HPP #define SLA_SUPPORTPOINTGENERATOR_HPP +#include + #include #include #include @@ -190,18 +192,14 @@ public: void execute(const std::vector &slices, const std::vector & heights); - void execute(const std::vector &slices, - const std::vector & heights, long seed); - - class RandomGen; - + void seed(std::mt19937::result_type s) { m_rng.seed(s); } private: std::vector m_output; SupportPointGenerator::Config m_config; - void process(const std::vector& slices, const std::vector& heights, RandomGen&); - void uniformly_cover(const ExPolygons& islands, Structure& structure, PointGrid3D &grid3d, RandomGen&, bool is_new_island = false, bool just_one = false); + void process(const std::vector& slices, const std::vector& heights); + void uniformly_cover(const ExPolygons& islands, Structure& structure, PointGrid3D &grid3d, bool is_new_island = false, bool just_one = false); void project_onto_mesh(std::vector& points) const; #ifdef SLA_SUPPORTPOINTGEN_DEBUG @@ -212,6 +210,8 @@ private: const EigenMesh3D& m_emesh; std::function m_throw_on_cancel; std::function m_statusfn; + + std::mt19937 m_rng; }; void remove_bottom_points(std::vector &pts, double gnd_lvl, double tolerance); diff --git a/tests/sla_print/sla_print_tests.cpp b/tests/sla_print/sla_print_tests.cpp index 8f69b8434..b08c931e3 100644 --- a/tests/sla_print/sla_print_tests.cpp +++ b/tests/sla_print/sla_print_tests.cpp @@ -108,7 +108,8 @@ TEST_CASE("Support point generator should be deterministic if seeded", std::vector slices; slicer.slice(slicegrid, CLOSING_RADIUS, &slices, []{}); - point_gen.execute(slices, slicegrid, 0); + point_gen.seed(0); + point_gen.execute(slices, slicegrid); auto get_chksum = [](const std::vector &pts){ long long chksum = 0; @@ -126,7 +127,7 @@ TEST_CASE("Support point generator should be deterministic if seeded", for (int i = 0; i < 20; ++i) { point_gen.output().clear(); - point_gen.execute(slices, slicegrid, 0); + point_gen.execute(slices, slicegrid); REQUIRE(point_gen.output().size() == ptnum); REQUIRE(checksum == get_chksum(point_gen.output())); } diff --git a/tests/sla_print/sla_test_utils.cpp b/tests/sla_print/sla_test_utils.cpp index ab1bbac0e..0804adb4f 100644 --- a/tests/sla_print/sla_test_utils.cpp +++ b/tests/sla_print/sla_test_utils.cpp @@ -112,8 +112,8 @@ void test_supports(const std::string &obj_filename, autogencfg.head_diameter = float(2 * supportcfg.head_front_radius_mm); sla::SupportPointGenerator point_gen{emesh, autogencfg, [] {}, [](int) {}}; - long seed = 0; // Make the test repeatable - point_gen.execute(out.model_slices, out.slicegrid, seed); + point_gen.seed(0); // Make the test repeatable + point_gen.execute(out.model_slices, out.slicegrid); // Get the calculated support points. std::vector support_points = point_gen.output();