[Bf-blender-cvs] [999abee874b] master: Geometry Nodes: convert point cloud to mesh vertices for modifiers

Jacques Lucke noreply at git.blender.org
Thu Feb 18 10:14:31 CET 2021


Commit: 999abee874bd7d69f6a40c27969598869799e8dc
Author: Jacques Lucke
Date:   Thu Feb 18 10:13:56 2021 +0100
Branches: master
https://developer.blender.org/rB999abee874bd7d69f6a40c27969598869799e8dc

Geometry Nodes: convert point cloud to mesh vertices for modifiers

Previously, when a Geometry Nodes modifier outputs a point cloud
(e.g. generated using the Point Distribute node), other modifiers
could not use that data. Now, the point cloud data is converted to
mesh vertices for such modifiers.

Ref T85281.

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

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

M	source/blender/blenkernel/BKE_geometry_set_instances.hh
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/geometry_set_instances.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh
index 4f3c9c65203..f918adaff7c 100644
--- a/source/blender/blenkernel/BKE_geometry_set_instances.hh
+++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh
@@ -41,6 +41,7 @@ struct GeometryInstanceGroup {
 
 Vector<GeometryInstanceGroup> geometry_set_gather_instances(const GeometrySet &geometry_set);
 
+GeometrySet geometry_set_realize_mesh_for_modifier(const GeometrySet &geometry_set);
 GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set);
 
 struct AttributeInfo {
@@ -54,7 +55,7 @@ struct AttributeInfo {
  * attribute with the given name on all of the input components.
  */
 void gather_attribute_info(Map<std::string, AttributeInfo> &attributes,
-                           const GeometryComponentType component_type,
+                           Span<GeometryComponentType> component_types,
                            Span<bke::GeometryInstanceGroup> set_groups,
                            const Set<std::string> &ignored_attributes);
 
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 213e72d496b..4aa7cfae009 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -890,7 +890,7 @@ void BKE_mesh_wrapper_deferred_finalize(Mesh *me_eval,
  */
 static Mesh *prepare_geometry_set_for_mesh_modifier(Mesh *mesh, GeometrySet &r_geometry_set)
 {
-  if (!r_geometry_set.has_instances()) {
+  if (!r_geometry_set.has_instances() && !r_geometry_set.has_pointcloud()) {
     return mesh;
   }
 
@@ -901,7 +901,8 @@ static Mesh *prepare_geometry_set_for_mesh_modifier(Mesh *mesh, GeometrySet &r_g
   }
   {
     /* Combine mesh and all instances into a single mesh that can be passed to the modifier. */
-    GeometrySet new_geometry_set = blender::bke::geometry_set_realize_instances(r_geometry_set);
+    GeometrySet new_geometry_set = blender::bke::geometry_set_realize_mesh_for_modifier(
+        r_geometry_set);
     MeshComponent &mesh_component = new_geometry_set.get_component_for_write<MeshComponent>();
     Mesh *new_mesh = mesh_component.release();
     r_geometry_set = new_geometry_set;
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 436fc0f1d1d..66c7f53cdf5 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -24,6 +24,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
+#include "DNA_pointcloud_types.h"
 
 namespace blender::bke {
 
@@ -165,44 +166,47 @@ Vector<GeometryInstanceGroup> geometry_set_gather_instances(const GeometrySet &g
 }
 
 void gather_attribute_info(Map<std::string, AttributeInfo> &attributes,
-                           const GeometryComponentType component_type,
+                           Span<GeometryComponentType> component_types,
                            Span<GeometryInstanceGroup> set_groups,
                            const Set<std::string> &ignored_attributes)
 {
   for (const GeometryInstanceGroup &set_group : set_groups) {
     const GeometrySet &set = set_group.geometry_set;
-    if (!set.has(component_type)) {
-      continue;
-    }
-    const GeometryComponent &component = *set.get_component_for_read(component_type);
-
-    for (const std::string &name : component.attribute_names()) {
-      if (ignored_attributes.contains(name)) {
+    for (const GeometryComponentType component_type : component_types) {
+      if (!set.has(component_type)) {
         continue;
       }
-      const ReadAttributePtr read_attribute = component.attribute_try_get_for_read(name);
-      if (!read_attribute) {
-        continue;
+      const GeometryComponent &component = *set.get_component_for_read(component_type);
+
+      for (const std::string &name : component.attribute_names()) {
+        if (ignored_attributes.contains(name)) {
+          continue;
+        }
+        const ReadAttributePtr read_attribute = component.attribute_try_get_for_read(name);
+        if (!read_attribute) {
+          continue;
+        }
+        const AttributeDomain domain = read_attribute->domain();
+        const CustomDataType data_type = read_attribute->custom_data_type();
+
+        auto add_info = [&, data_type, domain](AttributeInfo *info) {
+          info->domain = domain;
+          info->data_type = data_type;
+        };
+        auto modify_info = [&, data_type, domain](AttributeInfo *info) {
+          info->domain = domain; /* TODO: Use highest priority domain. */
+          info->data_type = bke::attribute_data_type_highest_complexity(
+              {info->data_type, data_type});
+        };
+
+        attributes.add_or_modify(name, add_info, modify_info);
       }
-      const AttributeDomain domain = read_attribute->domain();
-      const CustomDataType data_type = read_attribute->custom_data_type();
-
-      auto add_info = [&, data_type, domain](AttributeInfo *info) {
-        info->domain = domain;
-        info->data_type = data_type;
-      };
-      auto modify_info = [&, data_type, domain](AttributeInfo *info) {
-        info->domain = domain; /* TODO: Use highest priority domain. */
-        info->data_type = bke::attribute_data_type_highest_complexity(
-            {info->data_type, data_type});
-      };
-
-      attributes.add_or_modify(name, add_info, modify_info);
     }
   }
 }
 
-static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGroup> set_groups)
+static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGroup> set_groups,
+                                                       const bool convert_points_to_vertices)
 {
   int totverts = 0;
   int totloops = 0;
@@ -214,17 +218,22 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
   int64_t cd_dirty_loop = 0;
   for (const GeometryInstanceGroup &set_group : set_groups) {
     const GeometrySet &set = set_group.geometry_set;
+    const int tot_transforms = set_group.transforms.size();
     if (set.has_mesh()) {
       const Mesh &mesh = *set.get_mesh_for_read();
-      totverts += mesh.totvert * set_group.transforms.size();
-      totloops += mesh.totloop * set_group.transforms.size();
-      totedges += mesh.totedge * set_group.transforms.size();
-      totpolys += mesh.totpoly * set_group.transforms.size();
+      totverts += mesh.totvert * tot_transforms;
+      totloops += mesh.totloop * tot_transforms;
+      totedges += mesh.totedge * tot_transforms;
+      totpolys += mesh.totpoly * tot_transforms;
       cd_dirty_vert |= mesh.runtime.cd_dirty_vert;
       cd_dirty_poly |= mesh.runtime.cd_dirty_poly;
       cd_dirty_edge |= mesh.runtime.cd_dirty_edge;
       cd_dirty_loop |= mesh.runtime.cd_dirty_loop;
     }
+    if (convert_points_to_vertices && set.has_pointcloud()) {
+      const PointCloud &pointcloud = *set.get_pointcloud_for_read();
+      totverts += pointcloud.totpoint * tot_transforms;
+    }
   }
 
   Mesh *new_mesh = BKE_mesh_new_nomain(totverts, totedges, 0, totloops, totpolys);
@@ -287,13 +296,25 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
         poly_offset += mesh.totpoly;
       }
     }
+    if (convert_points_to_vertices && set.has_pointcloud()) {
+      const PointCloud &pointcloud = *set.get_pointcloud_for_read();
+      for (const float4x4 &transform : set_group.transforms) {
+        for (const int i : IndexRange(pointcloud.totpoint)) {
+          MVert &new_vert = new_mesh->mvert[vert_offset + i];
+          const float3 old_position = pointcloud.co[i];
+          const float3 new_position = transform * old_position;
+          copy_v3_v3(new_vert.co, new_position);
+        }
+        vert_offset += pointcloud.totpoint;
+      }
+    }
   }
 
   return new_mesh;
 }
 
 static void join_attributes(Span<GeometryInstanceGroup> set_groups,
-                            const GeometryComponentType component_type,
+                            Span<GeometryComponentType> component_types,
                             const Map<std::string, AttributeInfo> &attribute_info,
                             GeometryComponent &result)
 {
@@ -315,26 +336,28 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
     int offset = 0;
     for (const GeometryInstanceGroup &set_group : set_groups) {
       const GeometrySet &set = set_group.geometry_set;
-      if (set.has(component_type)) {
-        const GeometryComponent &component = *set.get_component_for_read(component_type);
-        const int domain_size = component.attribute_domain_size(domain_output);
-        if (domain_size == 0) {
-          continue; /* Domain size is 0, so no need to increment the offset. */
-        }
-        ReadAttributePtr source_attribute = component.attribute_try_get_for_read(
-            name, domain_output, data_type_output);
-
-        if (source_attribute) {
-          fn::GSpan src_span = source_attribute->get_span();
-          const void *src_buffer = src_span.data();
-          for (const int UNUSED(i) : set_group.transforms.index_range()) {
-            void *dst_buffer = dst_span[offset];
-            cpp_type->copy_to_initialized_n(src_buffer, dst_buffer, domain_size);
-            offset += domain_size;
+      for (const GeometryComponentType component_type : component_types) {
+        if (set.has(component_type)) {
+          const GeometryComponent &component = *set.get_component_for_read(component_type);
+          const int domain_size = component.attribute_domain_size(domain_output);
+          if (domain_size == 0) {
+            continue; /* Domain size is 0, so no need to increment the offset. */
+          }
+          ReadAttributePtr source_attribute = component.attribute_try_get_for_read(
+              name, domain_output, data_type_output);
+
+          if (source_attribute) {
+            fn::GSpan src_span = source_attribute->get_span();
+            const void *src_buffer = src_span.data();
+            for (const int UNU

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list