[Bf-blender-cvs] [107a0894cc5] geometry-nodes: Geometry Nodes: improve GeometrySet

Jacques Lucke noreply at git.blender.org
Thu Nov 12 13:30:43 CET 2020


Commit: 107a0894cc5de5e5cb2a9738d86027948dd403b9
Author: Jacques Lucke
Date:   Thu Nov 12 11:47:48 2020 +0100
Branches: geometry-nodes
https://developer.blender.org/rB107a0894cc5de5e5cb2a9738d86027948dd403b9

Geometry Nodes: improve GeometrySet

This commits implements multiple changes:
* Adds a simple C API.
* Improves the ownership handling by introducing GeometryOwnershipType.
* Adds an InstancesComponent that stores positions and Object pointers.

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

A	source/blender/blenkernel/BKE_geometry_set.h
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/modifiers/intern/MOD_nodes.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h
new file mode 100644
index 00000000000..be36ab47f85
--- /dev/null
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -0,0 +1,42 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Object;
+
+typedef struct GeometrySetC GeometrySetC;
+
+void BKE_geometry_set_user_add(GeometrySetC *geometry_set_c);
+void BKE_geometry_set_user_remove(GeometrySetC *geometry_set_c);
+
+bool BKE_geometry_set_has_instances(const GeometrySetC *geometry_set_c);
+
+int BKE_geometry_set_instances(const GeometrySetC *geometry_set_c,
+                               float (**r_positions)[3],
+                               struct Object ***r_objects);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 36c77619139..0d531deee0a 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -23,12 +23,16 @@
 #include <atomic>
 #include <iostream>
 
+#include "BLI_float3.hh"
 #include "BLI_hash.hh"
 #include "BLI_map.hh"
 #include "BLI_user_counter.hh"
 
+#include "BKE_geometry_set.h"
+
 struct Mesh;
 struct PointCloud;
+struct Object;
 
 namespace blender::bke {
 
@@ -39,8 +43,18 @@ using GeometrySetPtr = UserCounter<class GeometrySet>;
  * stores. Functions modifying a geometry will usually just modify a subset of the component types.
  */
 enum class GeometryComponentType {
-  Mesh,
-  PointCloud,
+  Mesh = 0,
+  PointCloud = 1,
+  Instances = 2,
+};
+
+enum class GeometryOwnershipType {
+  /* The geometry is owned. This implies that it can be changed. */
+  Owned = 0,
+  /* The geometry can be changed, but someone else is responsible for freeing it. */
+  Editable = 1,
+  /* The geometry cannot be changed and someone else is responsible for freeing it. */
+  ReadOnly = 2,
 };
 
 }  // namespace blender::bke
@@ -127,19 +141,24 @@ class GeometrySet {
   }
 
   /* Utility methods for creation. */
-  static GeometrySetPtr create_with_mesh(Mesh *mesh, bool transfer_ownership = true);
+  static GeometrySetPtr create_with_mesh(
+      Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  static GeometrySetPtr create_with_pointcloud(
+      PointCloud *pointcloud, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 
   /* Utility methods for access. */
   bool has_mesh() const;
   bool has_pointcloud() const;
+  bool has_instances() const;
   const Mesh *get_mesh_for_read() const;
   const PointCloud *get_pointcloud_for_read() const;
   Mesh *get_mesh_for_write();
   PointCloud *get_pointcloud_for_write();
 
   /* Utility methods for replacement. */
-  void replace_mesh(Mesh *mesh, bool transfer_ownership = true);
-  void replace_pointcloud(PointCloud *pointcloud, bool transfer_ownership = true);
+  void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  void replace_pointcloud(PointCloud *pointcloud,
+                          GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 };
 
 void make_geometry_set_mutable(GeometrySetPtr &geometry);
@@ -148,7 +167,7 @@ void make_geometry_set_mutable(GeometrySetPtr &geometry);
 class MeshComponent : public GeometryComponent {
  private:
   Mesh *mesh_ = nullptr;
-  bool owned_ = false;
+  GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
 
  public:
   ~MeshComponent();
@@ -156,7 +175,7 @@ class MeshComponent : public GeometryComponent {
 
   void clear();
   bool has_mesh() const;
-  void replace(Mesh *mesh, bool transfer_ownership = true);
+  void replace(Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
   Mesh *release();
 
   const Mesh *get_for_read() const;
@@ -169,7 +188,7 @@ class MeshComponent : public GeometryComponent {
 class PointCloudComponent : public GeometryComponent {
  private:
   PointCloud *pointcloud_ = nullptr;
-  bool owned_ = false;
+  GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
 
  public:
   ~PointCloudComponent();
@@ -177,7 +196,8 @@ class PointCloudComponent : public GeometryComponent {
 
   void clear();
   bool has_pointcloud() const;
-  void replace(PointCloud *pointcloud, bool transfer_ownership = true);
+  void replace(PointCloud *pointcloud,
+               GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
   PointCloud *release();
 
   const PointCloud *get_for_read() const;
@@ -186,4 +206,45 @@ class PointCloudComponent : public GeometryComponent {
   static constexpr inline GeometryComponentType type = GeometryComponentType::PointCloud;
 };
 
+/** A geometry component that stores instances. */
+class InstancesComponent : public GeometryComponent {
+ private:
+  Vector<float3> positions_;
+  Vector<const Object *> objects_;
+
+ public:
+  ~InstancesComponent() = default;
+  GeometryComponent *copy() const override;
+
+  void replace(Vector<float3> positions, Vector<const Object *> objects);
+  void replace(Vector<float3> positions, const Object *object);
+
+  Span<const Object *> objects() const;
+  Span<float3> positions() const;
+  MutableSpan<float3> positions();
+  int instances_amount() const;
+
+  static constexpr inline GeometryComponentType type = GeometryComponentType::Instances;
+};
+
+inline GeometrySetC *wrap(blender::bke::GeometrySet *geometry_set)
+{
+  return reinterpret_cast<GeometrySetC *>(geometry_set);
+}
+
+inline const GeometrySetC *wrap(const blender::bke::GeometrySet *geometry_set)
+{
+  return reinterpret_cast<const GeometrySetC *>(geometry_set);
+}
+
+inline blender::bke::GeometrySet *unwrap(GeometrySetC *geometry_set_c)
+{
+  return reinterpret_cast<blender::bke::GeometrySet *>(geometry_set_c);
+}
+
+inline const blender::bke::GeometrySet *unwrap(const GeometrySetC *geometry_set_c)
+{
+  return reinterpret_cast<const blender::bke::GeometrySet *>(geometry_set_c);
+}
+
 }  // namespace blender::bke
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index bea485db6f6..ef093174dd5 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -312,6 +312,7 @@ set(SRC
   BKE_fluid.h
   BKE_font.h
   BKE_freestyle.h
+  BKE_geometry_set.h
   BKE_geometry_set.hh
   BKE_global.h
   BKE_gpencil.h
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 568e581fd85..cf6861cfec7 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -38,6 +38,8 @@ GeometryComponent *GeometryComponent::create(GeometryComponentType component_typ
       return new MeshComponent();
     case GeometryComponentType::PointCloud:
       return new PointCloudComponent();
+    case GeometryComponentType::Instances:
+      return new InstancesComponent();
   }
   BLI_assert(false);
   return nullptr;
@@ -162,28 +164,44 @@ bool GeometrySet::has_pointcloud() const
   return component != nullptr && component->has_pointcloud();
 }
 
-/* Create a new geometry set that only contains the given mesh. Ownership of the mesh is
- * transferred to the new geometry. */
-GeometrySetPtr GeometrySet::create_with_mesh(Mesh *mesh, bool transfer_ownership)
+/* Returns true when the geometry set has an instances component that has at least one instance. */
+bool GeometrySet::has_instances() const
+{
+  const InstancesComponent *component = this->get_component_for_read<InstancesComponent>();
+  return component != nullptr && component->instances_amount() >= 1;
+}
+
+/* Create a new geometry set that only contains the given mesh. */
+GeometrySetPtr GeometrySet::create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership)
 {
   GeometrySet *geometry_set = new GeometrySet();
   MeshComponent &component = geometry_set->get_component_for_write<MeshComponent>();
-  component.replace(mesh, transfer_ownership);
+  component.replace(mesh, ownership);
+  return geometry_set;
+}
+
+/* Create a new geometry set that only contains the given point cloud. */
+GeometrySetPtr GeometrySet::create_with_pointcloud(PointCloud *pointcloud,
+                                                   GeometryOwnershipType ownership)
+{
+  GeometrySet *geometry_set = new GeometrySet();
+  PointCloudComponent &component = geometry_set->get_component_for_write<PointCloudComponent>();
+  component.replace(pointcloud, ownership);
   return geometry_set;
 }
 
 /* Clear the existing mesh and replace it with the given one. */
-void GeometrySet::replace_mesh(Mesh *mesh, bool transfer_ownership)
+void GeometrySet::replace_mesh(Mesh *mesh, GeometryOwnershipType ownership)
 {
   MeshComponent &component = this->get_component_for_write<MeshComponent>();
-  component.replace(mesh, transfer_ownership);
+  component.replace(mesh, ownership);
 }
 
 /* Clear the existing point cloud and replace with the given one. */
-void GeometrySet::replace_pointcloud(PointCloud *pointcloud, bool transfer_ownership)
+void GeometrySet::replace_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership)
 {
   PointCloudComponent &pointcloud_component = this->get_component_for_write<PointCloudComponent>();
-  pointcloud_component.replace(pointcloud, transfer_ownership);
+  pointcloud_component.replace(pointcloud, ownership);
 }
 
 /* Returns a mutable mesh or null. No ownership is tran

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list