[Bf-blender-cvs] [d0968a9c520] master: BLI: add probabilistic rounding utility

Jacques Lucke noreply at git.blender.org
Thu Mar 17 12:49:36 CET 2022


Commit: d0968a9c52019b817c001562adbb875780d94786
Author: Jacques Lucke
Date:   Thu Mar 17 12:48:41 2022 +0100
Branches: master
https://developer.blender.org/rBd0968a9c52019b817c001562adbb875780d94786

BLI: add probabilistic rounding utility

===================================================================

M	source/blender/blenlib/BLI_rand.hh
M	source/blender/blenlib/intern/rand.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
M	source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh
index 069a81bb84b..2c4484bd63f 100644
--- a/source/blender/blenlib/BLI_rand.hh
+++ b/source/blender/blenlib/BLI_rand.hh
@@ -103,6 +103,12 @@ class RandomNumberGenerator {
     return float3(rand1, rand2, 1.0f - rand1 - rand2);
   }
 
+  /**
+   * Round value to the next integer randomly.
+   * 4.9f is more likely to round to 5 than 4.6f.
+   */
+  int round_probabilistic(float x);
+
   float2 get_unit_float2();
   float3 get_unit_float3();
   /**
diff --git a/source/blender/blenlib/intern/rand.cc b/source/blender/blenlib/intern/rand.cc
index 27774cad31b..17bf5585f3f 100644
--- a/source/blender/blenlib/intern/rand.cc
+++ b/source/blender/blenlib/intern/rand.cc
@@ -374,6 +374,15 @@ void RandomNumberGenerator::seed_random(uint32_t seed)
   this->seed(seed + hash[seed & 255]);
 }
 
+int RandomNumberGenerator::round_probabilistic(float x)
+{
+  /* Support for negative values can be added when necessary. */
+  BLI_assert(x >= 0.0f);
+  const float round_up_probability = fractf(x);
+  const bool round_up = round_up_probability > this->get_float();
+  return (int)x + (int)round_up;
+}
+
 float2 RandomNumberGenerator::get_unit_float2()
 {
   float a = (float)(M_PI * 2.0) * this->get_float();
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
index 178505e2276..ae57a462242 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
@@ -378,13 +378,6 @@ class AddOperation : public CurvesSculptStrokeOperation {
     return kdtree;
   }
 
-  int float_to_int_amount(float amount_f, RandomNumberGenerator &rng)
-  {
-    const float add_probability = fractf(amount_f);
-    const bool add_point = add_probability > rng.get_float();
-    return (int)amount_f + (int)add_point;
-  }
-
   bool is_too_close_to_existing_point(const float3 position, const float minimum_distance) const
   {
     if (old_kdtree_ == nullptr) {
@@ -439,7 +432,7 @@ class AddOperation : public CurvesSculptStrokeOperation {
          * the triangle directly. If the triangle is larger than the brush, distribute new points
          * in a circle on the triangle plane. */
         if (looptri_area < area_threshold) {
-          const int amount = this->float_to_int_amount(looptri_area * density, looptri_rng);
+          const int amount = looptri_rng.round_probabilistic(looptri_area * density);
 
           threading::parallel_for(IndexRange(amount), 512, [&](const IndexRange amount_range) {
             RandomNumberGenerator point_rng{rng_base_seed + looptri_index * 1000 +
@@ -476,7 +469,7 @@ class AddOperation : public CurvesSculptStrokeOperation {
           const float radius_proj = std::sqrt(radius_proj_sq);
           const float circle_area = M_PI * radius_proj_sq;
 
-          const int amount = this->float_to_int_amount(circle_area * density, rng);
+          const int amount = rng.round_probabilistic(circle_area * density);
 
           const float3 axis_1 = math::normalize(v1 - v0) * radius_proj;
           const float3 axis_2 = math::normalize(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
index bdd4d74fe4b..8e28a4ba9b9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
@@ -114,10 +114,8 @@ static void sample_mesh_surface(const Mesh &mesh,
     const int looptri_seed = noise::hash(looptri_index, seed);
     RandomNumberGenerator looptri_rng(looptri_seed);
 
-    const float points_amount_fl = area * base_density * looptri_density_factor;
-    const float add_point_probability = fractf(points_amount_fl);
-    const bool add_point = add_point_probability > looptri_rng.get_float();
-    const int point_amount = (int)points_amount_fl + (int)add_point;
+    const int point_amount = looptri_rng.round_probabilistic(area * base_density *
+                                                             looptri_density_factor);
 
     for (int i = 0; i < point_amount; i++) {
       const float3 bary_coord = looptri_rng.get_barycentric_coordinates();



More information about the Bf-blender-cvs mailing list