Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh22
-rw-r--r--source/blender/blenkernel/BKE_geometry_set_instances.hh42
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc143
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc163
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc4
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh3
7 files changed, 212 insertions, 167 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 5b429a61b3f..02b3c88183a 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -467,25 +467,3 @@ class VolumeComponent : public GeometryComponent {
static constexpr inline GeometryComponentType static_type = GeometryComponentType::Volume;
};
-
-/**
- * Used to keep track of a group of instances using the same geometry data.
- */
-struct GeometryInstanceGroup {
- /**
- * The geometry set instanced on each of the transforms. The components are not necessarily
- * owned here. For example, they may be owned by the instanced object. This cannot be a
- * reference because not all instanced data will necessarily have a #geometry_set_eval.
- */
- GeometrySet geometry_set;
-
- /**
- * As an optimization to avoid copying, the same geometry set can be associated with multiple
- * instances. Each instance is stored as a transform matrix here. Again, these must be owned
- * because they may be transformed from the original data. TODO: Validate that last statement.
- */
- blender::Vector<blender::float4x4> transforms;
-};
-
-blender::Vector<GeometryInstanceGroup> BKE_geometry_set_gather_instances(
- const GeometrySet &geometry_set);
diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh
new file mode 100644
index 00000000000..11725d75df9
--- /dev/null
+++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh
@@ -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.
+ */
+
+#include "BKE_geometry_set.hh"
+
+namespace blender::bke {
+
+/**
+ * Used to keep track of a group of instances using the same geometry data.
+ */
+struct GeometryInstanceGroup {
+ /**
+ * The geometry set instanced on each of the transforms. The components are not necessarily
+ * owned here. For example, they may be owned by the instanced object. This cannot be a
+ * reference because not all instanced data will necessarily have a #geometry_set_eval.
+ */
+ GeometrySet geometry_set;
+
+ /**
+ * As an optimization to avoid copying, the same geometry set can be associated with multiple
+ * instances. Each instance is stored as a transform matrix here. Again, these must be owned
+ * because they may be transformed from the original data. TODO: Validate that last statement.
+ */
+ Vector<float4x4> transforms;
+};
+
+Vector<GeometryInstanceGroup> geometry_set_gather_instances(const GeometrySet &geometry_set);
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 6b6d2b45d02..ead01dbd6cb 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -130,6 +130,7 @@ set(SRC
intern/font.c
intern/freestyle.c
intern/geometry_set.cc
+ intern/geometry_set_instances.cc
intern/gpencil.c
intern/gpencil_curve.c
intern/gpencil_geom.c
@@ -327,6 +328,7 @@ set(SRC
BKE_freestyle.h
BKE_geometry_set.h
BKE_geometry_set.hh
+ BKE_geometry_set_instances.hh
BKE_global.h
BKE_gpencil.h
BKE_gpencil_curve.h
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index e6ecb6e5821..74d8b9afd82 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -586,149 +586,6 @@ bool InstancesComponent::is_empty() const
return transforms_.size() == 0;
}
-/**
- * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
- */
-static GeometrySet object_get_geometry_set_for_read(const Object &object)
-{
- /* Objects evaluated with a nodes modifier will have a geometry set already. */
- if (object.runtime.geometry_set_eval != nullptr) {
- return *object.runtime.geometry_set_eval;
- }
-
- /* Otherwise, construct a new geometry set with the component based on the object type. */
- GeometrySet new_geometry_set;
-
- if (object.type == OB_MESH) {
- Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(
- &const_cast<Object &>(object), false);
-
- if (mesh != nullptr) {
- BKE_mesh_wrapper_ensure_mdata(mesh);
-
- MeshComponent &mesh_component = new_geometry_set.get_component_for_write<MeshComponent>();
- mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
- mesh_component.copy_vertex_group_names_from_object(object);
- }
- }
-
- /* TODO: Cover the case of point-clouds without modifiers-- they may not be covered by the
- * #geometry_set_eval case above. */
-
- /* TODO: Add volume support. */
-
- /* Return by value since there is not always an existing geometry set owned elsewhere to use. */
- return new_geometry_set;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Geometry Set Gather Recursive Instances
- * \{ */
-
-static void geometry_set_collect_recursive(const GeometrySet &geometry_set,
- const float4x4 &transform,
- Vector<GeometryInstanceGroup> &r_sets);
-
-static void geometry_set_collect_recursive_collection(const Collection &collection,
- const float4x4 &transform,
- Vector<GeometryInstanceGroup> &r_sets);
-
-static void geometry_set_collect_recursive_collection_instance(
- const Collection &collection, const float4x4 &transform, Vector<GeometryInstanceGroup> &r_sets)
-{
- float4x4 offset_matrix;
- unit_m4(offset_matrix.values);
- sub_v3_v3(offset_matrix.values[3], collection.instance_offset);
- const float4x4 instance_transform = transform * offset_matrix;
- geometry_set_collect_recursive_collection(collection, instance_transform, r_sets);
-}
-
-static void geometry_set_collect_recursive_object(const Object &object,
- const float4x4 &transform,
- Vector<GeometryInstanceGroup> &r_sets)
-{
- GeometrySet instance_geometry_set = object_get_geometry_set_for_read(object);
- geometry_set_collect_recursive(instance_geometry_set, transform, r_sets);
-
- if (object.type == OB_EMPTY) {
- const Collection *collection_instance = object.instance_collection;
- if (collection_instance != nullptr) {
- geometry_set_collect_recursive_collection_instance(*collection_instance, transform, r_sets);
- }
- }
-}
-
-static void geometry_set_collect_recursive_collection(const Collection &collection,
- const float4x4 &transform,
- Vector<GeometryInstanceGroup> &r_sets)
-{
- LISTBASE_FOREACH (const CollectionObject *, collection_object, &collection.gobject) {
- BLI_assert(collection_object->ob != nullptr);
- const Object &object = *collection_object->ob;
- const float4x4 object_transform = transform * object.obmat;
- geometry_set_collect_recursive_object(object, object_transform, r_sets);
- }
- LISTBASE_FOREACH (const CollectionChild *, collection_child, &collection.children) {
- BLI_assert(collection_child->collection != nullptr);
- const Collection &collection = *collection_child->collection;
- geometry_set_collect_recursive_collection(collection, transform, r_sets);
- }
-}
-
-static void geometry_set_collect_recursive(const GeometrySet &geometry_set,
- const float4x4 &transform,
- Vector<GeometryInstanceGroup> &r_sets)
-{
- r_sets.append({geometry_set, {transform}});
-
- if (geometry_set.has_instances()) {
- const InstancesComponent &instances_component =
- *geometry_set.get_component_for_read<InstancesComponent>();
-
- Span<float4x4> transforms = instances_component.transforms();
- Span<InstancedData> instances = instances_component.instanced_data();
- for (const int i : instances.index_range()) {
- const InstancedData &data = instances[i];
- const float4x4 instance_transform = transform * transforms[i];
-
- if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
- BLI_assert(data.data.object != nullptr);
- const Object &object = *data.data.object;
- geometry_set_collect_recursive_object(object, instance_transform, r_sets);
- }
- else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
- BLI_assert(data.data.collection != nullptr);
- const Collection &collection = *data.data.collection;
- geometry_set_collect_recursive_collection_instance(collection, instance_transform, r_sets);
- }
- }
- }
-}
-
-/**
- * Return flattened vector of the geometry component's recursive instances. I.e. all collection
- * instances and object instances will be expanded into the instances of their geometry components.
- * Even the instances in those geometry components' will be included.
- *
- * \note For convenience (to avoid duplication in the caller), the returned vector also contains
- * the argument geometry set.
- *
- * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
- */
-Vector<GeometryInstanceGroup> BKE_geometry_set_gather_instances(const GeometrySet &geometry_set)
-{
- Vector<GeometryInstanceGroup> result_vector;
-
- float4x4 unit_transform;
- unit_m4(unit_transform.values);
-
- geometry_set_collect_recursive(geometry_set, unit_transform, result_vector);
-
- return result_vector;
-}
-
static blender::Array<int> generate_unique_instance_ids(Span<int> original_ids)
{
using namespace blender;
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
new file mode 100644
index 00000000000..6410aeb49fa
--- /dev/null
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+#include "BKE_geometry_set_instances.hh"
+#include "BKE_mesh_wrapper.h"
+#include "BKE_modifier.h"
+
+#include "DNA_collection_types.h"
+#include "DNA_object_types.h"
+
+namespace blender::bke {
+
+static void geometry_set_collect_recursive(const GeometrySet &geometry_set,
+ const float4x4 &transform,
+ Vector<GeometryInstanceGroup> &r_sets);
+
+static void geometry_set_collect_recursive_collection(const Collection &collection,
+ const float4x4 &transform,
+ Vector<GeometryInstanceGroup> &r_sets);
+
+/**
+ * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
+ */
+static GeometrySet object_get_geometry_set_for_read(const Object &object)
+{
+ /* Objects evaluated with a nodes modifier will have a geometry set already. */
+ if (object.runtime.geometry_set_eval != nullptr) {
+ return *object.runtime.geometry_set_eval;
+ }
+
+ /* Otherwise, construct a new geometry set with the component based on the object type. */
+ GeometrySet new_geometry_set;
+
+ if (object.type == OB_MESH) {
+ Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(
+ &const_cast<Object &>(object), false);
+
+ if (mesh != nullptr) {
+ BKE_mesh_wrapper_ensure_mdata(mesh);
+
+ MeshComponent &mesh_component = new_geometry_set.get_component_for_write<MeshComponent>();
+ mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
+ mesh_component.copy_vertex_group_names_from_object(object);
+ }
+ }
+
+ /* TODO: Cover the case of point-clouds without modifiers-- they may not be covered by the
+ * #geometry_set_eval case above. */
+
+ /* TODO: Add volume support. */
+
+ /* Return by value since there is not always an existing geometry set owned elsewhere to use. */
+ return new_geometry_set;
+}
+
+static void geometry_set_collect_recursive_collection_instance(
+ const Collection &collection, const float4x4 &transform, Vector<GeometryInstanceGroup> &r_sets)
+{
+ float4x4 offset_matrix;
+ unit_m4(offset_matrix.values);
+ sub_v3_v3(offset_matrix.values[3], collection.instance_offset);
+ const float4x4 instance_transform = transform * offset_matrix;
+ geometry_set_collect_recursive_collection(collection, instance_transform, r_sets);
+}
+
+static void geometry_set_collect_recursive_object(const Object &object,
+ const float4x4 &transform,
+ Vector<GeometryInstanceGroup> &r_sets)
+{
+ GeometrySet instance_geometry_set = object_get_geometry_set_for_read(object);
+ geometry_set_collect_recursive(instance_geometry_set, transform, r_sets);
+
+ if (object.type == OB_EMPTY) {
+ const Collection *collection_instance = object.instance_collection;
+ if (collection_instance != nullptr) {
+ geometry_set_collect_recursive_collection_instance(*collection_instance, transform, r_sets);
+ }
+ }
+}
+
+static void geometry_set_collect_recursive_collection(const Collection &collection,
+ const float4x4 &transform,
+ Vector<GeometryInstanceGroup> &r_sets)
+{
+ LISTBASE_FOREACH (const CollectionObject *, collection_object, &collection.gobject) {
+ BLI_assert(collection_object->ob != nullptr);
+ const Object &object = *collection_object->ob;
+ const float4x4 object_transform = transform * object.obmat;
+ geometry_set_collect_recursive_object(object, object_transform, r_sets);
+ }
+ LISTBASE_FOREACH (const CollectionChild *, collection_child, &collection.children) {
+ BLI_assert(collection_child->collection != nullptr);
+ const Collection &collection = *collection_child->collection;
+ geometry_set_collect_recursive_collection(collection, transform, r_sets);
+ }
+}
+
+static void geometry_set_collect_recursive(const GeometrySet &geometry_set,
+ const float4x4 &transform,
+ Vector<GeometryInstanceGroup> &r_sets)
+{
+ r_sets.append({geometry_set, {transform}});
+
+ if (geometry_set.has_instances()) {
+ const InstancesComponent &instances_component =
+ *geometry_set.get_component_for_read<InstancesComponent>();
+
+ Span<float4x4> transforms = instances_component.transforms();
+ Span<InstancedData> instances = instances_component.instanced_data();
+ for (const int i : instances.index_range()) {
+ const InstancedData &data = instances[i];
+ const float4x4 instance_transform = transform * transforms[i];
+
+ if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
+ BLI_assert(data.data.object != nullptr);
+ const Object &object = *data.data.object;
+ geometry_set_collect_recursive_object(object, instance_transform, r_sets);
+ }
+ else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
+ BLI_assert(data.data.collection != nullptr);
+ const Collection &collection = *data.data.collection;
+ geometry_set_collect_recursive_collection_instance(collection, instance_transform, r_sets);
+ }
+ }
+ }
+}
+
+/**
+ * Return flattened vector of the geometry component's recursive instances. I.e. all collection
+ * instances and object instances will be expanded into the instances of their geometry components.
+ * Even the instances in those geometry components' will be included.
+ *
+ * \note For convenience (to avoid duplication in the caller), the returned vector also contains
+ * the argument geometry set.
+ *
+ * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
+ */
+Vector<GeometryInstanceGroup> geometry_set_gather_instances(const GeometrySet &geometry_set)
+{
+ Vector<GeometryInstanceGroup> result_vector;
+
+ float4x4 unit_transform;
+ unit_m4(unit_transform.values);
+
+ geometry_set_collect_recursive(geometry_set, unit_transform, result_vector);
+
+ return result_vector;
+}
+
+} // namespace blender::bke
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 08de467cd55..daee693c24f 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -26,6 +26,8 @@
namespace blender::nodes {
+using bke::GeometryInstanceGroup;
+
void gather_attribute_info(Map<std::string, AttributeInfo> &attributes,
const GeometryComponentType component_type,
Span<GeometryInstanceGroup> set_groups,
@@ -261,7 +263,7 @@ GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
GeometrySet new_geometry_set;
- Vector<GeometryInstanceGroup> set_groups = BKE_geometry_set_gather_instances(geometry_set);
+ Vector<GeometryInstanceGroup> set_groups = bke::geometry_set_gather_instances(geometry_set);
join_instance_groups_mesh(set_groups, new_geometry_set);
join_instance_groups_pointcloud(set_groups, new_geometry_set);
join_instance_groups_volume(set_groups, new_geometry_set);
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 687763b4728..78418b37011 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -25,6 +25,7 @@
#include "DNA_node_types.h"
+#include "BKE_geometry_set_instances.hh"
#include "BKE_node.h"
#include "BLT_translation.h"
@@ -61,7 +62,7 @@ struct AttributeInfo {
*/
void gather_attribute_info(Map<std::string, AttributeInfo> &attributes,
const GeometryComponentType component_type,
- Span<GeometryInstanceGroup> set_groups,
+ Span<bke::GeometryInstanceGroup> set_groups,
const Set<std::string> &ignored_attributes);
} // namespace blender::nodes