ENH: C++11 random number generator for fuzzy skin

Github: 4253

Change-Id: Ib58022485c131b6c28f4bd1e78a3bf6e1188cf23
(cherry picked from commit 6dd9ceb6065aa6eb664acf7ba3d1510f31407258)
This commit is contained in:
SeaRyanC 2024-06-12 15:53:22 -07:00 committed by Lane.Wei
parent 4bebe9eb6a
commit 70a0f0a447
1 changed files with 17 additions and 8 deletions

View File

@ -9,6 +9,8 @@
#include "Line.hpp"
#include <cmath>
#include <cassert>
#include <random>
#include <unordered_set>
#include "libslic3r/AABBTreeLines.hpp"
static const int overhang_sampling_number = 6;
static const double narrow_loop_length_threshold = 10;
@ -22,6 +24,15 @@ static constexpr double SMALLER_EXT_INSET_OVERLAP_TOLERANCE = 0.22;
namespace Slic3r {
// Produces a random value between 0 and 1. Thread-safe.
static double random_value() {
thread_local std::random_device rd;
// Hash thread ID for random number seed if no hardware rng seed is available
thread_local std::mt19937 gen(rd.entropy() > 0 ? rd() : std::hash<std::thread::id>()(std::this_thread::get_id()));
thread_local std::uniform_real_distribution<double> dist(0.0, 1.0);
return dist(gen);
}
// Hierarchy of perimeters.
class PerimeterGeneratorLoop {
public:
@ -52,7 +63,7 @@ static void fuzzy_polygon(Polygon &poly, double fuzzy_skin_thickness, double fuz
{
const double min_dist_between_points = fuzzy_skin_point_distance * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value
const double range_random_point_dist = fuzzy_skin_point_distance / 2.;
double dist_left_over = double(rand()) * (min_dist_between_points / 2) / double(RAND_MAX); // the distance to be traversed on the line before making the first new point
double dist_left_over = random_value() * (min_dist_between_points / 2.); // the distance to be traversed on the line before making the first new point
Point* p0 = &poly.points.back();
Points out;
out.reserve(poly.points.size());
@ -60,16 +71,14 @@ static void fuzzy_polygon(Polygon &poly, double fuzzy_skin_thickness, double fuz
{ // 'a' is the (next) new point between p0 and p1
Vec2d p0p1 = (p1 - *p0).cast<double>();
double p0p1_size = p0p1.norm();
// so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size
double dist_last_point = dist_left_over + p0p1_size * 2.;
for (double p0pa_dist = dist_left_over; p0pa_dist < p0p1_size;
p0pa_dist += min_dist_between_points + double(rand()) * range_random_point_dist / double(RAND_MAX))
double p0pa_dist = dist_left_over;
for (; p0pa_dist < p0p1_size;
p0pa_dist += min_dist_between_points + random_value() * range_random_point_dist)
{
double r = double(rand()) * (fuzzy_skin_thickness * 2.) / double(RAND_MAX) - fuzzy_skin_thickness;
double r = random_value() * (fuzzy_skin_thickness * 2.) - fuzzy_skin_thickness;
out.emplace_back(*p0 + (p0p1 * (p0pa_dist / p0p1_size) + perp(p0p1).cast<double>().normalized() * r).cast<coord_t>());
dist_last_point = p0pa_dist;
}
dist_left_over = p0p1_size - dist_last_point;
dist_left_over = p0p1_size - p0pa_dist;
p0 = &p1;
}
while (out.size() < 3) {