[Bf-blender-cvs] [d84bf961f86] geometry-nodes: Geometry Nodes: improve geometry component

Jacques Lucke noreply at git.blender.org
Mon Nov 23 19:13:33 CET 2020


Commit: d84bf961f86f1476a27e3f5dd0e39efdf9d1376a
Author: Jacques Lucke
Date:   Mon Nov 23 19:05:27 2020 +0100
Branches: geometry-nodes
https://developer.blender.org/rBd84bf961f86f1476a27e3f5dd0e39efdf9d1376a

Geometry Nodes: improve geometry component

* It now knows its own component type.
* Add virtual method to check if the component is empty.
* Add virtual methods to find all attribute names.
* Support adding existing components to a geometry set.

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

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/geometry_set.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 366477dcc81..1e5a4d3c543 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -26,6 +26,7 @@
 #include "BLI_float3.hh"
 #include "BLI_hash.hh"
 #include "BLI_map.hh"
+#include "BLI_set.hh"
 #include "BLI_user_counter.hh"
 
 #include "BKE_attribute_access.hh"
@@ -70,19 +71,23 @@ class GeometryComponent {
  private:
   /* The reference count has two purposes. When it becomes zero, the component is freed. When it is
    * larger than one, the component becomes immutable. */
-  std::atomic<int> users_ = 1;
+  mutable std::atomic<int> users_ = 1;
+  GeometryComponentType type_;
 
  public:
+  GeometryComponent(GeometryComponentType type);
   virtual ~GeometryComponent();
   static GeometryComponent *create(GeometryComponentType component_type);
 
   /* The returned component should be of the same type as the type this is called on. */
   virtual GeometryComponent *copy() const = 0;
 
-  void user_add();
-  void user_remove();
+  void user_add() const;
+  void user_remove() const;
   bool is_mutable() const;
 
+  GeometryComponentType type() const;
+
   /* Returns true when the geometry component supports this attribute domain. */
   virtual bool attribute_domain_supported(const AttributeDomain domain) const;
   /* Returns true when the given data type is supported in the given domain. */
@@ -117,6 +122,9 @@ class GeometryComponent {
                                     const AttributeDomain domain,
                                     const CustomDataType data_type);
 
+  virtual blender::Set<std::string> attribute_names() const;
+  virtual bool is_empty() const;
+
   /* Get a read-only attribute for the given domain and data type.
    * Returns null when it does not exist. */
   blender::bke::ReadAttributePtr attribute_try_get_for_read(
@@ -176,30 +184,32 @@ struct GeometrySet {
   template<typename Component> Component &get_component_for_write()
   {
     BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
-    return static_cast<Component &>(this->get_component_for_write(Component::type));
+    return static_cast<Component &>(this->get_component_for_write(Component::static_type));
   }
 
   const GeometryComponent *get_component_for_read(GeometryComponentType component_type) const;
   template<typename Component> const Component *get_component_for_read() const
   {
     BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
-    return static_cast<const Component *>(get_component_for_read(Component::type));
+    return static_cast<const Component *>(get_component_for_read(Component::static_type));
   }
 
   bool has(const GeometryComponentType component_type) const;
   template<typename Component> bool has() const
   {
     BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
-    return this->has(Component::type);
+    return this->has(Component::static_type);
   }
 
   void remove(const GeometryComponentType component_type);
   template<typename Component> void remove()
   {
     BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
-    return this->remove(Component::type);
+    return this->remove(Component::static_type);
   }
 
+  void add(const GeometryComponent &component);
+
   friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
   friend bool operator==(const GeometrySet &a, const GeometrySet &b);
   uint64_t hash() const;
@@ -236,6 +246,7 @@ class MeshComponent : public GeometryComponent {
   blender::Map<std::string, int> vertex_group_names_;
 
  public:
+  MeshComponent();
   ~MeshComponent();
   GeometryComponent *copy() const override;
 
@@ -265,7 +276,10 @@ class MeshComponent : public GeometryComponent {
                             const AttributeDomain domain,
                             const CustomDataType data_type) final;
 
-  static constexpr inline GeometryComponentType type = GeometryComponentType::Mesh;
+  blender::Set<std::string> attribute_names() const final;
+  bool is_empty() const final;
+
+  static constexpr inline GeometryComponentType static_type = GeometryComponentType::Mesh;
 };
 
 /** A geometry component that stores a point cloud. */
@@ -275,6 +289,7 @@ class PointCloudComponent : public GeometryComponent {
   GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
 
  public:
+  PointCloudComponent();
   ~PointCloudComponent();
   GeometryComponent *copy() const override;
 
@@ -303,7 +318,10 @@ class PointCloudComponent : public GeometryComponent {
                             const AttributeDomain domain,
                             const CustomDataType data_type) final;
 
-  static constexpr inline GeometryComponentType type = GeometryComponentType::PointCloud;
+  blender::Set<std::string> attribute_names() const final;
+  bool is_empty() const final;
+
+  static constexpr inline GeometryComponentType static_type = GeometryComponentType::PointCloud;
 };
 
 /** A geometry component that stores instances. */
@@ -315,6 +333,7 @@ class InstancesComponent : public GeometryComponent {
   blender::Vector<const Object *> objects_;
 
  public:
+  InstancesComponent();
   ~InstancesComponent() = default;
   GeometryComponent *copy() const override;
 
@@ -331,5 +350,7 @@ class InstancesComponent : public GeometryComponent {
   blender::MutableSpan<blender::float3> positions();
   int instances_amount() const;
 
-  static constexpr inline GeometryComponentType type = GeometryComponentType::Instances;
+  bool is_empty() const final;
+
+  static constexpr inline GeometryComponentType static_type = GeometryComponentType::Instances;
 };
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 106b83783a6..ad5f7e1a781 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -34,6 +34,7 @@
 #include "NOD_node_tree_multi_function.hh"
 
 using blender::float3;
+using blender::Set;
 using blender::StringRef;
 using blender::bke::ReadAttributePtr;
 using blender::bke::WriteAttributePtr;
@@ -392,6 +393,19 @@ static bool delete_named_custom_data_layer(CustomData &custom_data,
   return false;
 }
 
+static void get_custom_data_layer_attribute_names(const CustomData &custom_data,
+                                                  const GeometryComponent &component,
+                                                  const AttributeDomain domain,
+                                                  Set<std::string> &r_names)
+{
+  for (const CustomDataLayer &layer : blender::Span(custom_data.layers, custom_data.totlayer)) {
+    if (component.attribute_domain_with_type_supported(domain,
+                                                       static_cast<CustomDataType>(layer.type))) {
+      r_names.add(layer.name);
+    }
+  }
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -453,6 +467,11 @@ bool GeometryComponent::attribute_try_create(const StringRef UNUSED(attribute_na
   return false;
 }
 
+Set<std::string> GeometryComponent::attribute_names() const
+{
+  return {};
+}
+
 static ReadAttributePtr try_adapt_data_type(ReadAttributePtr attribute,
                                             const blender::fn::CPPType &to_type)
 {
@@ -517,6 +536,9 @@ ReadAttributePtr GeometryComponent::attribute_get_for_read(const StringRef attri
 
   const blender::fn::CPPType *cpp_type = blender::bke::custom_data_type_to_cpp_type(data_type);
   BLI_assert(cpp_type != nullptr);
+  if (default_value == nullptr) {
+    default_value = cpp_type->default_value();
+  }
   const int domain_size = this->attribute_domain_size(domain);
   return std::make_unique<blender::bke::ConstantReadAttribute>(
       domain, domain_size, *cpp_type, default_value);
@@ -657,6 +679,17 @@ bool PointCloudComponent::attribute_try_create(const StringRef attribute_name,
   return true;
 }
 
+Set<std::string> PointCloudComponent::attribute_names() const
+{
+  if (pointcloud_ == nullptr) {
+    return {};
+  }
+
+  Set<std::string> names;
+  get_custom_data_layer_attribute_names(pointcloud_->pdata, *this, ATTR_DOMAIN_POINT, names);
+  return names;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -899,4 +932,22 @@ bool MeshComponent::attribute_try_create(const StringRef attribute_name,
   }
 }
 
+Set<std::string> MeshComponent::attribute_names() const
+{
+  if (mesh_ == nullptr) {
+    return {};
+  }
+
+  Set<std::string> names;
+  names.add("Position");
+  for (StringRef name : vertex_group_names_.keys()) {
+    names.add(name);
+  }
+  get_custom_data_layer_attribute_names(mesh_->pdata, *this, ATTR_DOMAIN_CORNER, names);
+  get_custom_data_layer_attribute_names(mesh_->vdata, *this, ATTR_DOMAIN_POINT, names);
+  get_custom_data_layer_attribute_names(mesh_->edata, *this, ATTR_DOMAIN_EDGE, names);
+  get_custom_data_layer_attribute_names(mesh_->pdata, *this, ATTR_DOMAIN_POLYGON, names);
+  return names;
+}
+
 /** \} */
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 7dfc857616f..4450e5d8f59 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -33,6 +33,10 @@ using blender::Vector;
 /** \name Geometry Component
  * \{ */
 
+GeometryComponent::GeometryComponent(GeometryComponentType type) : type_(type)
+{
+}
+
 GeometryComponent ::~GeometryComponent()
 {
 }
@@ -51,12 +55,12 @@ GeometryComponent *GeometryComponent::create(GeometryComponentType component_typ
   return nullptr;
 }
 
-void GeometryComponent::user_add()
+void GeometryComponent::user_add() const
 {
   users_.fetch_add(1);
 }
 
-void GeometryComponent::user_remove()
+void GeometryComponent::user_remove() const
 {
   const int new_users = users_.fetch_sub(1) - 1;
   if (new_users == 0) {
@@ -71,6 +75,16 @@ bool GeometryComponent::is_mutable() const
   return users_ <= 1;
 }
 
+GeometryComponentType GeometryComponent::type() const
+{
+  return type_;
+}
+
+bool GeometryComponent::is_empty() const
+{
+  return false;
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list