[Bf-blender-cvs] [94572a4e30b] geometry-nodes: Geometry Nodes: use density attribute name instead of index as node input

Jacques Lucke noreply at git.blender.org
Thu Nov 12 16:58:47 CET 2020


Commit: 94572a4e30b919ec8391ca8d3f9e118229e80aab
Author: Jacques Lucke
Date:   Thu Nov 12 16:58:30 2020 +0100
Branches: geometry-nodes
https://developer.blender.org/rB94572a4e30b919ec8391ca8d3f9e118229e80aab

Geometry Nodes: use density attribute name instead of index as node input

This implements a workaround for the issue that (for historical reasons)
the names of vertex groups are stored on the object while the actual vertex
group data is stored on the mesh.

The solution is to copy the vertex group names from the object into
the `MeshComponent` so that the information is not lost, when the
object cannot be accessed.

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

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/geometry/nodes/node_geo_object_info.cc
M	source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 0d531deee0a..e2200d79cb8 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -168,6 +168,10 @@ class MeshComponent : public GeometryComponent {
  private:
   Mesh *mesh_ = nullptr;
   GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
+  /* Due to historical design choices, vertex group data is stored in the mesh, but the vertex
+   * group names are stored on an object. Since we don't have an object here, we copy over the
+   * names into this map. */
+  Map<std::string, int> vertex_group_names_;
 
  public:
   ~MeshComponent();
@@ -178,6 +182,9 @@ class MeshComponent : public GeometryComponent {
   void replace(Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
   Mesh *release();
 
+  void copy_vertex_group_names_from_object(const struct Object &object);
+  int vertex_group_index(StringRef vertex_group_name) const;
+
   const Mesh *get_for_read() const;
   Mesh *get_for_write();
 
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index cf6861cfec7..af07b66eb3c 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -19,6 +19,8 @@
 #include "BKE_mesh.h"
 #include "BKE_pointcloud.h"
 
+#include "DNA_object_types.h"
+
 #include "MEM_guardedalloc.h"
 
 namespace blender::bke {
@@ -270,6 +272,7 @@ void MeshComponent::clear()
     }
     mesh_ = nullptr;
   }
+  vertex_group_names_.clear();
 }
 
 bool MeshComponent::has_mesh() const
@@ -296,6 +299,22 @@ Mesh *MeshComponent::release()
   return mesh;
 }
 
+void MeshComponent::copy_vertex_group_names_from_object(const Object &object)
+{
+  BLI_assert(this->is_mutable());
+  vertex_group_names_.clear();
+  int index = 0;
+  LISTBASE_FOREACH (const bDeformGroup *, group, &object.defbase) {
+    vertex_group_names_.add(group->name, index);
+    index++;
+  }
+}
+
+int MeshComponent::vertex_group_index(StringRef vertex_group_name) const
+{
+  return vertex_group_names_.lookup_default_as(vertex_group_name, -1);
+}
+
 /* Get the mesh from this component. This method can be used by multiple threads at the same
  * time. Therefore, the returned mesh should not be modified. No ownership is transferred. */
 const Mesh *MeshComponent::get_for_read() const
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index a2cfebddcc5..28d01a266f2 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -851,6 +851,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
 {
   GeometrySetPtr input_geometry_set = GeometrySet::create_with_mesh(
       mesh, GeometryOwnershipType::Editable);
+  input_geometry_set->get_component_for_write<MeshComponent>().copy_vertex_group_names_from_object(
+      *ctx->object);
   GeometrySetPtr output_geometry_set = modifyGeometry(md, ctx, std::move(input_geometry_set));
   if (!output_geometry_set.has_value()) {
     return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
index 422ea01b9f5..5931b3a5b65 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
@@ -57,6 +57,8 @@ static void geo_object_info_exec(GeoNodeExecParams params)
         /* Make a copy because the life time of the other mesh might be shorter. */
         Mesh *copied_mesh = BKE_mesh_copy_for_eval(mesh, false);
         geometry_set = GeometrySet::create_with_mesh(copied_mesh);
+        geometry_set->get_component_for_write<MeshComponent>().copy_vertex_group_names_from_object(
+            *object);
       }
     }
   }
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 57056f5e3cf..97b292c7011 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -34,8 +34,7 @@
 static bNodeSocketTemplate geo_node_point_distribute_in[] = {
     {SOCK_GEOMETRY, N_("Geometry")},
     {SOCK_FLOAT, N_("Density"), 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 100000.0f, PROP_NONE},
-    /* Use an index, because the vertex group names are not available in the mesh... */
-    {SOCK_INT, N_("Density Attribute Index"), -1, 0, 0, 0, -1, 1000},
+    {SOCK_STRING, N_("Density Attribute")},
     {-1, ""},
 };
 
@@ -111,8 +110,7 @@ static void geo_point_distribute_exec(GeoNodeExecParams params)
   }
 
   const float density = params.extract_input<float>("Density");
-  const int density_attribute_index = std::max(
-      -1, params.extract_input<int>("Density Attribute Index"));
+  const std::string density_attribute = params.extract_input<std::string>("Density Attribute");
 
   if (density <= 0.0f) {
     geometry_set->replace_mesh(nullptr);
@@ -121,7 +119,9 @@ static void geo_point_distribute_exec(GeoNodeExecParams params)
     return;
   }
 
-  const Mesh *mesh_in = geometry_set->get_mesh_for_read();
+  const MeshComponent &mesh_component = *geometry_set->get_component_for_read<MeshComponent>();
+  const Mesh *mesh_in = mesh_component.get_for_read();
+  const int density_attribute_index = mesh_component.vertex_group_index(density_attribute);
   Vector<float3> points = scatter_points_from_mesh(mesh_in, density, density_attribute_index);
 
   PointCloud *pointcloud = BKE_pointcloud_new_nomain(points.size());



More information about the Bf-blender-cvs mailing list