[Bf-blender-cvs] [c75c08a737c] master: Geometry Nodes: Distribute points once per instance reference

Hans Goudey noreply at git.blender.org
Mon Sep 27 18:16:36 CEST 2021


Commit: c75c08a737c0737304bc7f6757152e4c99d4fe4d
Author: Hans Goudey
Date:   Mon Sep 27 11:16:25 2021 -0500
Branches: master
https://developer.blender.org/rBc75c08a737c0737304bc7f6757152e4c99d4fe4d

Geometry Nodes: Distribute points once per instance reference

With this commit, the distribute points on faces node runs only
once for every unique mesh in its input. That means if there are
100 instances of the same mesh, it will only run once.

This basically reverts rB84a4f2ae68d408301. The optimization there
didn't end up being worth it in the end, since it complicates code
quite a lot. It's also incompatible with this method of dealing with
instances, and it breaks field evaluation for instances, where we would
have to make sure to handle each instance transform properly otherwise,
evaluating the field separately for every instance.

Differential Revision: https://developer.blender.org/D12630

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

M	source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc

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

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 95987a15f32..3f2541dcded 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
@@ -17,6 +17,7 @@
 #include "BLI_kdtree.h"
 #include "BLI_noise.hh"
 #include "BLI_rand.hh"
+#include "BLI_task.hh"
 #include "BLI_timeit.hh"
 
 #include "DNA_mesh_types.h"
@@ -25,7 +26,6 @@
 
 #include "BKE_attribute_math.hh"
 #include "BKE_bvhutils.h"
-#include "BKE_geometry_set_instances.hh"
 #include "BKE_mesh.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_mesh_sample.hh"
@@ -96,7 +96,6 @@ static float3 normal_to_euler_rotation(const float3 normal)
 }
 
 static void sample_mesh_surface(const Mesh &mesh,
-                                const float4x4 &transform,
                                 const float base_density,
                                 const Span<float> density_factors,
                                 const int seed,
@@ -115,9 +114,9 @@ static void sample_mesh_surface(const Mesh &mesh,
     const int v0_index = mesh.mloop[v0_loop].v;
     const int v1_index = mesh.mloop[v1_loop].v;
     const int v2_index = mesh.mloop[v2_loop].v;
-    const float3 v0_pos = transform * float3(mesh.mvert[v0_index].co);
-    const float3 v1_pos = transform * float3(mesh.mvert[v1_index].co);
-    const float3 v2_pos = transform * float3(mesh.mvert[v2_index].co);
+    const float3 v0_pos = float3(mesh.mvert[v0_index].co);
+    const float3 v1_pos = float3(mesh.mvert[v1_index].co);
+    const float3 v2_pos = float3(mesh.mvert[v2_index].co);
 
     float looptri_density_factor = 1.0f;
     if (!density_factors.is_empty()) {
@@ -147,65 +146,53 @@ static void sample_mesh_surface(const Mesh &mesh,
   }
 }
 
-BLI_NOINLINE static KDTree_3d *build_kdtree(Span<Vector<float3>> positions_all,
-                                            const int initial_points_len)
+BLI_NOINLINE static KDTree_3d *build_kdtree(Span<float3> positions)
 {
-  KDTree_3d *kdtree = BLI_kdtree_3d_new(initial_points_len);
+  KDTree_3d *kdtree = BLI_kdtree_3d_new(positions.size());
 
   int i_point = 0;
-  for (const Vector<float3> &positions : positions_all) {
-    for (const float3 position : positions) {
-      BLI_kdtree_3d_insert(kdtree, i_point, position);
-      i_point++;
-    }
+  for (const float3 position : positions) {
+    BLI_kdtree_3d_insert(kdtree, i_point, position);
+    i_point++;
   }
+
   BLI_kdtree_3d_balance(kdtree);
   return kdtree;
 }
 
 BLI_NOINLINE static void update_elimination_mask_for_close_points(
-    Span<Vector<float3>> positions_all,
-    Span<int> instance_start_offsets,
-    const float minimum_distance,
-    MutableSpan<bool> elimination_mask,
-    const int initial_points_len)
+    Span<float3> positions, const float minimum_distance, MutableSpan<bool> elimination_mask)
 {
   if (minimum_distance <= 0.0f) {
     return;
   }
 
-  KDTree_3d *kdtree = build_kdtree(positions_all, initial_points_len);
-
-  /* The elimination mask is a flattened array for every point,
-   * so keep track of the index to it separately. */
-  for (const int i_instance : positions_all.index_range()) {
-    Span<float3> positions = positions_all[i_instance];
-    const int offset = instance_start_offsets[i_instance];
-
-    for (const int i : positions.index_range()) {
-      if (elimination_mask[offset + i]) {
-        continue;
-      }
-
-      struct CallbackData {
-        int index;
-        MutableSpan<bool> elimination_mask;
-      } callback_data = {offset + i, elimination_mask};
-
-      BLI_kdtree_3d_range_search_cb(
-          kdtree,
-          positions[i],
-          minimum_distance,
-          [](void *user_data, int index, const float *UNUSED(co), float UNUSED(dist_sq)) {
-            CallbackData &callback_data = *static_cast<CallbackData *>(user_data);
-            if (index != callback_data.index) {
-              callback_data.elimination_mask[index] = true;
-            }
-            return true;
-          },
-          &callback_data);
+  KDTree_3d *kdtree = build_kdtree(positions);
+
+  for (const int i : positions.index_range()) {
+    if (elimination_mask[i]) {
+      continue;
     }
+
+    struct CallbackData {
+      int index;
+      MutableSpan<bool> elimination_mask;
+    } callback_data = {i, elimination_mask};
+
+    BLI_kdtree_3d_range_search_cb(
+        kdtree,
+        positions[i],
+        minimum_distance,
+        [](void *user_data, int index, const float *UNUSED(co), float UNUSED(dist_sq)) {
+          CallbackData &callback_data = *static_cast<CallbackData *>(user_data);
+          if (index != callback_data.index) {
+            callback_data.elimination_mask[index] = true;
+          }
+          return true;
+        },
+        &callback_data);
   }
+
   BLI_kdtree_3d_free(kdtree);
 }
 
@@ -289,18 +276,19 @@ BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh,
 }
 
 BLI_NOINLINE static void propagate_existing_attributes(
-    const Span<GeometryInstanceGroup> set_groups,
-    const Span<int> instance_start_offsets,
+    const MeshComponent &mesh_component,
     const Map<AttributeIDRef, AttributeKind> &attributes,
-    GeometryComponent &component,
-    const Span<Vector<float3>> bary_coords_array,
-    const Span<Vector<int>> looptri_indices_array)
+    GeometryComponent &point_component,
+    const Span<float3> bary_coords,
+    const Span<int> looptri_indices)
 {
+  const Mesh &mesh = *mesh_component.get_for_read();
+
   for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
     const AttributeIDRef attribute_id = entry.key;
     const CustomDataType output_data_type = entry.value.data_type;
     /* The output domain is always #ATTR_DOMAIN_POINT, since we are creating a point cloud. */
-    OutputAttribute attribute_out = component.attribute_try_get_for_output_only(
+    OutputAttribute attribute_out = point_component.attribute_try_get_for_output_only(
         attribute_id, ATTR_DOMAIN_POINT, output_data_type);
     if (!attribute_out) {
       continue;
@@ -308,46 +296,22 @@ BLI_NOINLINE static void propagate_existing_attributes(
 
     GMutableSpan out_span = attribute_out.as_span();
 
-    int i_instance = 0;
-    for (const GeometryInstanceGroup &set_group : set_groups) {
-      const GeometrySet &set = set_group.geometry_set;
-      const MeshComponent &source_component = *set.get_component_for_read<MeshComponent>();
-      const Mesh &mesh = *source_component.get_for_read();
-
-      std::optional<AttributeMetaData> attribute_info = component.attribute_get_meta_data(
-          attribute_id);
-      if (!attribute_info) {
-        i_instance += set_group.transforms.size();
-        continue;
-      }
-
-      const AttributeDomain source_domain = attribute_info->domain;
-      GVArrayPtr source_attribute = source_component.attribute_get_for_read(
-          attribute_id, source_domain, output_data_type, nullptr);
-      if (!source_attribute) {
-        i_instance += set_group.transforms.size();
-        continue;
-      }
-
-      for (const int UNUSED(i_set_instance) : set_group.transforms.index_range()) {
-        const int offset = instance_start_offsets[i_instance];
-        Span<float3> bary_coords = bary_coords_array[i_instance];
-        Span<int> looptri_indices = looptri_indices_array[i_instance];
-
-        GMutableSpan instance_span = out_span.slice(offset, bary_coords.size());
-        interpolate_attribute(
-            mesh, bary_coords, looptri_indices, source_domain, *source_attribute, instance_span);
-
-        i_instance++;
-      }
-
-      attribute_math::convert_to_static_type(output_data_type, [&](auto dummy) {
-        using T = decltype(dummy);
-
-        GVArray_Span<T> source_span{*source_attribute};
-      });
+    std::optional<AttributeMetaData> attribute_info = point_component.attribute_get_meta_data(
+        attribute_id);
+    if (!attribute_info) {
+      continue;
     }
 
+    const AttributeDomain source_domain = attribute_info->domain;
+    GVArrayPtr source_attribute = mesh_component.attribute_get_for_read(
+        attribute_id, source_domain, output_data_type, nullptr);
+    if (!source_attribute) {
+      continue;
+    }
+
+    interpolate_attribute(
+        mesh, bary_coords, looptri_indices, source_domain, *source_attribute, out_span);
+
     attribute_out.save();
   }
 }
@@ -360,87 +324,64 @@ struct AttributeOutputs {
 };
 }  // namespace
 
-BLI_NOINLINE static void compute_attribute_outputs(const Span<GeometryInstanceGroup> sets,
-                                                   const Span<int> instance_start_offsets,
-                                                   GeometryComponent &component,
-                                                   const Span<Vector<float3>> bary_coords_array,
-                                                   const Span<Vector<int>> looptri_indices_array,
+BLI_NOINLINE static void compute_attribute_outputs(const MeshComponent &mesh_component,
+                                                   PointCloudComponent &point_component,
+                                                   const Span<float3> bary_coords,
+                                                   const Span<int> looptri_indices,
                                                    const AttributeOutputs &attribute_outputs)
 {
   std::optional<OutputAttribute_Typed<int>> id_attribute;
   std::optional<OutputAttribute_Typed<float3>> normal_attribute;
   std::optional<OutputAttribute_Typed<float3>> rotation_attribute;
 
-  MutableSpan<int> result_ids;
-  MutableSpan<float3> result_normals;
-  MutableSpan<float3> result_rotations;
+  MutableSpan<int> ids;
+  MutableSpan<float3> normals;
+  MutableSpan<float3> rotations;
 
   if (attribute_outputs.stable_id_id) {
-    id_attribute.emplace(component.attribute_try_get_for_output_only<int>(
+    id_attribute.emplace(point_component.attribute_try_get_for_output_only<int>(
         attribute_outputs.stable_id_id.get(), ATTR_DOMAIN_POINT));
-    result_ids = id_attribute->as_span();
+    ids = id_attribute->as_span();
  

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list