[Bf-blender-cvs] [3390b191b2d] geometry-nodes-distribute-points: WIP posion attribute map point removal

Sebastian Parborg noreply at git.blender.org
Thu Nov 26 22:48:17 CET 2020


Commit: 3390b191b2d7d06793a01d639c531032035f89ac
Author: Sebastian Parborg
Date:   Thu Nov 26 22:47:45 2020 +0100
Branches: geometry-nodes-distribute-points
https://developer.blender.org/rB3390b191b2d7d06793a01d639c531032035f89ac

WIP posion attribute map point removal

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

M	source/blender/nodes/geometry/nodes/cySampleElim.hh
M	source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc

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

diff --git a/source/blender/nodes/geometry/nodes/cySampleElim.hh b/source/blender/nodes/geometry/nodes/cySampleElim.hh
index 395d6ec4a4b..4703aed34d6 100644
--- a/source/blender/nodes/geometry/nodes/cySampleElim.hh
+++ b/source/blender/nodes/geometry/nodes/cySampleElim.hh
@@ -737,27 +737,27 @@ class WeightedSampleElimination {
   // weight (IE they are within d_max if we are using the default weighting function). We don't
   // stop at any specific number of points.
   template<typename WeightFunction>
-  SIZE_TYPE Eliminate_all(PointType const *inputPoints,
-                          SIZE_TYPE inputSize,
-                          PointType *outputPoints,
-                          SIZE_TYPE outputSize,
-                          bool progressive,
-                          FType d_max,
-                          int dimensions,
-                          WeightFunction weightFunction) const
+  std::vector<SIZE_TYPE> Eliminate_all(PointType const *inputPoints,
+                                       SIZE_TYPE inputSize,
+                                       PointType *outputPoints,
+                                       SIZE_TYPE outputSize,
+                                       bool progressive,
+                                       FType d_max,
+                                       int dimensions,
+                                       WeightFunction weightFunction) const
   {
     BLI_assert(outputSize == inputSize);
     BLI_assert(dimensions <= DIMENSIONS && dimensions >= 2);
     if (d_max <= FType(0)) {
       d_max = 2 * GetMaxPoissonDiskRadius(dimensions, outputSize);
     }
-    SIZE_TYPE remaining_points = DoEliminate_all(
+    std::vector<SIZE_TYPE> remaining_points = DoEliminate_all(
         inputPoints, inputSize, outputPoints, outputSize, d_max, weightFunction, false);
     if (progressive) {
-      std::vector<PointType> tmpPoints(remaining_points);
+      std::vector<PointType> tmpPoints(remaining_points.size());
       PointType *inPts = outputPoints;
       PointType *outPts = tmpPoints.data();
-      SIZE_TYPE inSize = remaining_points;
+      SIZE_TYPE inSize = remaining_points.size();
       SIZE_TYPE outSize = 0;
       while (inSize >= 3) {
         outSize = inSize / 2;
@@ -778,13 +778,13 @@ class WeightedSampleElimination {
     return remaining_points;
   }
 
-  SIZE_TYPE Eliminate_all(PointType const *inputPoints,
-                          SIZE_TYPE inputSize,
-                          PointType *outputPoints,
-                          SIZE_TYPE outputSize,
-                          bool progressive = false,
-                          FType d_max = FType(0),
-                          int dimensions = DIMENSIONS) const
+  std::vector<SIZE_TYPE> Eliminate_all(PointType const *inputPoints,
+                                       SIZE_TYPE inputSize,
+                                       PointType *outputPoints,
+                                       SIZE_TYPE outputSize,
+                                       bool progressive = false,
+                                       FType d_max = FType(0),
+                                       int dimensions = DIMENSIONS) const
   {
     if (d_max <= FType(0)) {
       d_max = 2 * GetMaxPoissonDiskRadius(dimensions, outputSize);
@@ -826,13 +826,13 @@ class WeightedSampleElimination {
 
  private:
   template<typename WeightFunction>
-  SIZE_TYPE DoEliminate_all(PointType const *inputPoints,
-                            SIZE_TYPE inputSize,
-                            PointType *outputPoints,
-                            SIZE_TYPE outputSize,
-                            FType d_max,
-                            WeightFunction weightFunction,
-                            bool copyEliminated) const
+  std::vector<SIZE_TYPE> DoEliminate_all(PointType const *inputPoints,
+                                         SIZE_TYPE inputSize,
+                                         PointType *outputPoints,
+                                         SIZE_TYPE outputSize,
+                                         FType d_max,
+                                         WeightFunction weightFunction,
+                                         bool copyEliminated) const
   {
     // Build a k-d tree for samples
     PointCloud<PointType, FType, DIMENSIONS, SIZE_TYPE> kdtree;
@@ -908,11 +908,15 @@ class WeightedSampleElimination {
     }
 
     // Copy the samples to the output array
-    SIZE_TYPE targetSize = copyEliminated ? inputSize : outputSize;
+    SIZE_TYPE targetSize = copyEliminated ? inputSize : sampleSize;
+    std::vector<SIZE_TYPE> orig_point_idx;
+    orig_point_idx.reserve(targetSize);
     for (SIZE_TYPE i = 0; i < targetSize; i++) {
-      outputPoints[i] = inputPoints[heap.GetIDFromHeap(i)];
+      SIZE_TYPE idx = heap.GetIDFromHeap(i);
+      outputPoints[i] = inputPoints[idx];
+      orig_point_idx.push_back(idx);
     }
-    return sampleSize;
+    return orig_point_idx;
   }
 };
 
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
index c6e624ed6cb..f64c4e544d6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -35,7 +35,7 @@
 static bNodeSocketTemplate geo_node_point_distribute_in[] = {
     {SOCK_GEOMETRY, N_("Geometry")},
     {SOCK_FLOAT, N_("Minimum Distance"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 100000.0f, PROP_NONE},
-    {SOCK_FLOAT, N_("Maximum Density"), 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 100000.0f, PROP_NONE},
+    {SOCK_FLOAT, N_("Maximum Density"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 100000.0f, PROP_NONE},
     {SOCK_STRING, N_("Density Attribute")},
     {-1, ""},
 };
@@ -110,7 +110,7 @@ static Vector<float3> poisson_scatter_points_from_mesh(const Mesh *mesh,
 
   Vector<float3> points;
 
-  if (min_dist <= 0.0f || density <= 0.0f) {
+  if (min_dist <= FLT_EPSILON || density <= FLT_EPSILON) {
     return points;
   }
 
@@ -118,7 +118,7 @@ static Vector<float3> poisson_scatter_points_from_mesh(const Mesh *mesh,
   // good quality possion disk distributions.
 
   int quality = 5;
-  Vector<int> point_weights;
+  Vector<bool> remove_point;
 
   for (const int looptri_index : IndexRange(looptris_len)) {
     const MLoopTri &looptri = looptris[looptri_index];
@@ -137,9 +137,7 @@ static Vector<float3> poisson_scatter_points_from_mesh(const Mesh *mesh,
     RandomNumberGenerator looptri_rng(looptri_seed);
 
     const float points_amount_fl = area / (2.0f * sqrtf(3.0f) * min_dist * min_dist);
-    const float add_point_probability = fractf(points_amount_fl);
-    const bool add_point = add_point_probability > looptri_rng.get_float();
-    const int point_amount = quality * ((int)points_amount_fl + (int)add_point);
+    const int point_amount = quality * (int)ceilf(points_amount_fl);
 
     for (int i = 0; i < point_amount; i++) {
       const float3 bary_coords = looptri_rng.get_barycentric_coordinates();
@@ -149,7 +147,7 @@ static Vector<float3> poisson_scatter_points_from_mesh(const Mesh *mesh,
 
       const float weight = bary_coords[0] * v0_density_factor +
                            bary_coords[1] * v1_density_factor + bary_coords[2] * v2_density_factor;
-      point_weights.append(density * weight);
+      remove_point.append(looptri_rng.get_float() <= density * weight);
     }
   }
 
@@ -163,7 +161,7 @@ static Vector<float3> poisson_scatter_points_from_mesh(const Mesh *mesh,
 
   float d_min = d_max * wse.GetWeightLimitFraction(points.size(), points.size() / quality);
   float alpha = wse.GetParamAlpha();
-  int num_points = wse.Eliminate_all(
+  std::vector<size_t> output_idx = wse.Eliminate_all(
       points.data(),
       points.size(),
       output_points.data(),
@@ -179,8 +177,16 @@ static Vector<float3> poisson_scatter_points_from_mesh(const Mesh *mesh,
         return std::pow(1.0f - d / d_max, alpha);
       });
 
-  output_points.resize(num_points);
-  points = output_points;
+  output_points.resize(output_idx.size());
+  points.clear();
+  points.reserve(output_points.size());
+
+  for (int i = 0; i < output_points.size(); i++) {
+    if (!remove_point[output_idx[i]]) {
+      continue;
+    }
+    points.append(output_points[i]);
+  }
 
   return points;
 }



More information about the Bf-blender-cvs mailing list