[Bf-blender-cvs] [e5425b566d0] master: Geometry Nodes: separate Instances from InstancesComponent

Jacques Lucke noreply at git.blender.org
Mon Oct 17 11:40:35 CEST 2022


Commit: e5425b566d0f25f60b5895c4025c183fd67c7d9c
Author: Jacques Lucke
Date:   Mon Oct 17 11:39:40 2022 +0200
Branches: master
https://developer.blender.org/rBe5425b566d0f25f60b5895c4025c183fd67c7d9c

Geometry Nodes: separate Instances from InstancesComponent

This makes instance handling more consistent with all the other geometry
component types. For example, `MeshComponent` contains a `Mesh *` and
now `InstancesComponent` has a `Instances *`.

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

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

M	source/blender/blenkernel/BKE_geometry_fields.hh
M	source/blender/blenkernel/BKE_geometry_set.hh
A	source/blender/blenkernel/BKE_instances.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/geometry_component_instances.cc
M	source/blender/blenkernel/intern/geometry_fields.cc
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/blenkernel/intern/geometry_set_instances.cc
A	source/blender/blenkernel/intern/instances.cc
M	source/blender/blenkernel/intern/object_dupli.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_column.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc
M	source/blender/geometry/intern/realize_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
M	source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
M	source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
M	source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc
M	source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
M	source/blender/nodes/geometry/nodes/node_geo_object_info.cc
M	source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
M	source/blender/nodes/geometry/nodes/node_geo_transform.cc
M	source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
M	source/blender/nodes/intern/geometry_nodes_log.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh
index 988e0017f04..2eef67dba98 100644
--- a/source/blender/blenkernel/BKE_geometry_fields.hh
+++ b/source/blender/blenkernel/BKE_geometry_fields.hh
@@ -75,14 +75,14 @@ class PointCloudFieldContext : public fn::FieldContext {
 
 class InstancesFieldContext : public fn::FieldContext {
  private:
-  const InstancesComponent &instances_;
+  const Instances &instances_;
 
  public:
-  InstancesFieldContext(const InstancesComponent &instances) : instances_(instances)
+  InstancesFieldContext(const Instances &instances) : instances_(instances)
   {
   }
 
-  const InstancesComponent &instances() const
+  const Instances &instances() const
   {
     return instances_;
   }
@@ -128,13 +128,13 @@ class GeometryFieldContext : public fn::FieldContext {
   const Mesh *mesh() const;
   const CurvesGeometry *curves() const;
   const PointCloud *pointcloud() const;
-  const InstancesComponent *instances() const;
+  const Instances *instances() const;
 
  private:
   GeometryFieldContext(const Mesh &mesh, eAttrDomain domain);
   GeometryFieldContext(const CurvesGeometry &curves, eAttrDomain domain);
   GeometryFieldContext(const PointCloud &points);
-  GeometryFieldContext(const InstancesComponent &instances);
+  GeometryFieldContext(const Instances &instances);
 };
 
 class GeometryFieldInput : public fn::FieldInput {
@@ -187,8 +187,7 @@ class InstancesFieldInput : public fn::FieldInput {
   GVArray get_varray_for_context(const fn::FieldContext &context,
                                  IndexMask mask,
                                  ResourceScope &scope) const override;
-  virtual GVArray get_varray_for_context(const InstancesComponent &instances,
-                                         IndexMask mask) const = 0;
+  virtual GVArray get_varray_for_context(const Instances &instances, IndexMask mask) const = 0;
 };
 
 class AttributeFieldInput : public GeometryFieldInput {
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 2ef9556afc7..b488806c8e7 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -43,6 +43,7 @@ enum class GeometryOwnershipType {
 namespace blender::bke {
 class ComponentAttributeProviders;
 class CurvesEditHints;
+class Instances;
 }  // namespace blender::bke
 
 class GeometryComponent;
@@ -246,6 +247,12 @@ struct GeometrySet {
    */
   static GeometrySet create_with_curves(
       Curves *curves, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  /**
+   * Create a new geometry set that only contains the given instances.
+   */
+  static GeometrySet create_with_instances(
+      blender::bke::Instances *instances,
+      GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 
   /* Utility methods for access. */
   /**
@@ -293,6 +300,10 @@ struct GeometrySet {
    * Returns a read-only curves data-block or null.
    */
   const Curves *get_curves_for_read() const;
+  /**
+   * Returns read-only instances or null.
+   */
+  const blender::bke::Instances *get_instances_for_read() const;
   /**
    * Returns read-only curve edit hints or null.
    */
@@ -314,6 +325,10 @@ struct GeometrySet {
    * Returns a mutable curves data-block or null. No ownership is transferred.
    */
   Curves *get_curves_for_write();
+  /**
+   * Returns mutable instances or null. No ownership is transferred.
+   */
+  blender::bke::Instances *get_instances_for_write();
   /**
    * Returns mutable curve edit hints or null.
    */
@@ -339,6 +354,11 @@ struct GeometrySet {
    */
   void replace_curves(Curves *curves,
                       GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  /**
+   * Clear the existing instances and replace them with the given one.
+   */
+  void replace_instances(blender::bke::Instances *instances,
+                         GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 
  private:
   /**
@@ -515,244 +535,35 @@ class CurveComponent : public GeometryComponent {
 };
 
 /**
- * Holds a reference to conceptually unique geometry or a pointer to object/collection data
- * that is instanced with a transform in #InstancesComponent.
- */
-class InstanceReference {
- public:
-  enum class Type {
-    /**
-     * An empty instance. This allows an `InstanceReference` to be default constructed without
-     * being in an invalid state. There might also be other use cases that we haven't explored much
-     * yet (such as changing the instance later on, and "disabling" some instances).
-     */
-    None,
-    Object,
-    Collection,
-    GeometrySet,
-  };
-
- private:
-  Type type_ = Type::None;
-  /** Depending on the type this is either null, an Object or Collection pointer. */
-  void *data_ = nullptr;
-  std::unique_ptr<GeometrySet> geometry_set_;
-
- public:
-  InstanceReference() = default;
-
-  InstanceReference(Object &object) : type_(Type::Object), data_(&object)
-  {
-  }
-
-  InstanceReference(Collection &collection) : type_(Type::Collection), data_(&collection)
-  {
-  }
-
-  InstanceReference(GeometrySet geometry_set)
-      : type_(Type::GeometrySet),
-        geometry_set_(std::make_unique<GeometrySet>(std::move(geometry_set)))
-  {
-  }
-
-  InstanceReference(const InstanceReference &other) : type_(other.type_), data_(other.data_)
-  {
-    if (other.geometry_set_) {
-      geometry_set_ = std::make_unique<GeometrySet>(*other.geometry_set_);
-    }
-  }
-
-  InstanceReference(InstanceReference &&other)
-      : type_(other.type_), data_(other.data_), geometry_set_(std::move(other.geometry_set_))
-  {
-    other.type_ = Type::None;
-    other.data_ = nullptr;
-  }
-
-  InstanceReference &operator=(const InstanceReference &other)
-  {
-    if (this == &other) {
-      return *this;
-    }
-    this->~InstanceReference();
-    new (this) InstanceReference(other);
-    return *this;
-  }
-
-  InstanceReference &operator=(InstanceReference &&other)
-  {
-    if (this == &other) {
-      return *this;
-    }
-    this->~InstanceReference();
-    new (this) InstanceReference(std::move(other));
-    return *this;
-  }
-
-  Type type() const
-  {
-    return type_;
-  }
-
-  Object &object() const
-  {
-    BLI_assert(type_ == Type::Object);
-    return *(Object *)data_;
-  }
-
-  Collection &collection() const
-  {
-    BLI_assert(type_ == Type::Collection);
-    return *(Collection *)data_;
-  }
-
-  const GeometrySet &geometry_set() const
-  {
-    BLI_assert(type_ == Type::GeometrySet);
-    return *geometry_set_;
-  }
-
-  bool owns_direct_data() const
-  {
-    if (type_ != Type::GeometrySet) {
-      /* The object and collection instances are not direct data. */
-      return true;
-    }
-    return geometry_set_->owns_direct_data();
-  }
-
-  void ensure_owns_direct_data()
-  {
-    if (type_ != Type::GeometrySet) {
-      return;
-    }
-    geometry_set_->ensure_owns_direct_data();
-  }
-
-  uint64_t hash() const
-  {
-    return blender::get_default_hash_2(data_, geometry_set_.get());
-  }
-
-  friend bool operator==(const InstanceReference &a, const InstanceReference &b)
-  {
-    return a.data_ == b.data_ && a.geometry_set_.get() == b.geometry_set_.get();
-  }
-};
-
-/**
- * A geometry component that stores instances. The instance data can be any type described by
- * #InstanceReference. Geometry instances can even contain instances themselves, for nested
- * instancing. Each instance has an index into an array of unique instance data, and a transform.
- * The component can also store generic attributes for each instance.
- *
- * The component works differently from other geometry components in that it stores
- * data about instancing directly, rather than owning a pointer to a separate data structure.
- *
- * This component is not responsible for handling the interface to a render engine, or other
- * areas that work with all visible geometry, that is handled by the dependency graph iterator
- * (see `DEG_depsgraph_query.h`).
+ * A geometry component that stores #Instances.
  */
 class InstancesComponent : public GeometryComponent {
  private:
-  /**
-   * Indexed set containing information about the data that is instanced.
-   * Actual instances store an index ("handle") into this set.
-   */
-  blender::VectorSet<InstanceReference> references_;
-
-  /** Index into `references_`. Determines what data is instanced. */
-  blender::Vector<int> instance_reference_handles_;
-  /** Transformation of the instances. */
-  blender::Vector<blender::float4x4> instance_transforms_;
-
-  /* These almost unique ids are generated based on the `id` attribute, which might not contain
-   * unique ids at all. They are *almost* unique, because under certain very unlikely
-   * circumstances, they are not unique. Code using these ids should not crash when they are not
-   * unique but can generally expect them to be unique. */
-  mutable std::mutex almost_unique_ids_mutex_;
-  mutable blender::Array<int> almost_unique_ids_;
-
-  blender::bke::CustomDataAttributes attributes_;
+  blender::bke::Instances *instances_ = nullptr;
+  GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
 
  public:
   InstancesComponent();
-  ~InstancesComponent() = default;
+  ~InstancesComponent();
   GeometryComponent *copy() const override;
 
   void clear();
 
-  void reserve(int min_capacity);
-  /**
-   * Resize the transform, handles, and attributes to the specified capacity.
-   *
-   * \note This function should be used carefully, only when it's guaranteed
-   * that the data will be filled.
-   */
-  void resize(int capacity);
+  const blender::bke::Instances *get_for_read() const;
+  blender::bke::Instances *get_for_write();
 
-  /**
-   * Returns a handle for the given reference.
-   * If the reference exists already, the handle of the existing reference is returned.
-   * Otherwise a new handle is added.
-   */
-  int add_reference(const InstanceReference &reference);
-  /**
-   * Add a reference to the instance reference with an index specified by the #instance_handle
-   * argument. For adding many instances, using #resize and accessing

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list