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
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_attribute_access.hh5
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh19
-rw-r--r--source/blender/blenkernel/BKE_geometry_set_instances.hh5
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc70
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc35
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc1
6 files changed, 129 insertions, 6 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index 77db479f525..da3de2f08bd 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -122,6 +122,11 @@ struct AttributeMetaData {
}
};
+struct AttributeKind {
+ AttributeDomain domain;
+ CustomDataType data_type;
+};
+
/**
* Base class for the attribute initializer types described below.
*/
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 317d513dae6..a6c77c74b9e 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -25,6 +25,7 @@
#include "BLI_float3.hh"
#include "BLI_float4x4.hh"
+#include "BLI_function_ref.hh"
#include "BLI_hash.hh"
#include "BLI_map.hh"
#include "BLI_set.hh"
@@ -293,6 +294,21 @@ struct GeometrySet {
bool owns_direct_data() const;
void ensure_owns_direct_data();
+ using AttributeForeachCallback =
+ blender::FunctionRef<void(const blender::bke::AttributeIDRef &attribute_id,
+ const AttributeMetaData &meta_data,
+ const GeometryComponent &component)>;
+
+ void attribute_foreach(blender::Span<GeometryComponentType> component_types,
+ bool include_instances,
+ AttributeForeachCallback callback) const;
+
+ void gather_attributes_for_propagation(
+ blender::Span<GeometryComponentType> component_types,
+ GeometryComponentType dst_component_type,
+ bool include_instances,
+ blender::Map<blender::bke::AttributeIDRef, AttributeKind> &r_attributes) const;
+
/* Utility methods for creation. */
static GeometrySet create_with_mesh(
Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
@@ -597,6 +613,9 @@ class InstancesComponent : public GeometryComponent {
int attribute_domain_size(const AttributeDomain domain) const final;
+ void foreach_referenced_geometry(
+ blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const;
+
bool is_empty() const final;
bool owns_direct_data() const override;
diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh
index 44a0ee30c4c..9d68d726c3a 100644
--- a/source/blender/blenkernel/BKE_geometry_set_instances.hh
+++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh
@@ -49,11 +49,6 @@ void geometry_set_gather_instances(const GeometrySet &geometry_set,
GeometrySet geometry_set_realize_mesh_for_modifier(const GeometrySet &geometry_set);
GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set);
-struct AttributeKind {
- CustomDataType data_type;
- AttributeDomain domain;
-};
-
/**
* Add information about all the attributes on every component of the type. The resulting info
* will contain the highest complexity data type and the highest priority domain among every
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index e717d289894..54e9fadf8ed 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -375,6 +375,76 @@ CurveEval *GeometrySet::get_curve_for_write()
return component.get_for_write();
}
+void GeometrySet::attribute_foreach(const Span<GeometryComponentType> component_types,
+ const bool include_instances,
+ const AttributeForeachCallback callback) const
+{
+ using namespace blender;
+ using namespace blender::bke;
+ for (const GeometryComponentType component_type : component_types) {
+ if (!this->has(component_type)) {
+ continue;
+ }
+ const GeometryComponent &component = *this->get_component_for_read(component_type);
+ component.attribute_foreach(
+ [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
+ callback(attribute_id, meta_data, component);
+ return true;
+ });
+ }
+ if (include_instances && this->has_instances()) {
+ const InstancesComponent &instances = *this->get_component_for_read<InstancesComponent>();
+ instances.foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
+ instance_geometry_set.attribute_foreach(component_types, include_instances, callback);
+ });
+ }
+}
+
+void GeometrySet::gather_attributes_for_propagation(
+ const Span<GeometryComponentType> component_types,
+ const GeometryComponentType dst_component_type,
+ bool include_instances,
+ blender::Map<blender::bke::AttributeIDRef, AttributeKind> &r_attributes) const
+{
+ using namespace blender;
+ using namespace blender::bke;
+ /* Only needed right now to check if an attribute is built-in on this component type.
+ * TODO: Get rid of the dummy component. */
+ const GeometryComponent *dummy_component = GeometryComponent::create(dst_component_type);
+ this->attribute_foreach(
+ component_types,
+ include_instances,
+ [&](const AttributeIDRef &attribute_id,
+ const AttributeMetaData &meta_data,
+ const GeometryComponent &component) {
+ if (component.attribute_is_builtin(attribute_id)) {
+ if (!dummy_component->attribute_is_builtin(attribute_id)) {
+ /* Don't propagate built-in attributes that are not built-in on the destination
+ * component. */
+ return;
+ }
+ }
+ if (attribute_id.is_anonymous()) {
+ if (!BKE_anonymous_attribute_id_has_strong_references(&attribute_id.anonymous_id())) {
+ /* Don't propagate anonymous attributes that are not used anymore. */
+ return;
+ }
+ }
+ auto add_info = [&](AttributeKind *attribute_kind) {
+ attribute_kind->domain = meta_data.domain;
+ attribute_kind->data_type = meta_data.data_type;
+ };
+ auto modify_info = [&](AttributeKind *attribute_kind) {
+ attribute_kind->domain = bke::attribute_domain_highest_priority(
+ {attribute_kind->domain, meta_data.domain});
+ attribute_kind->data_type = bke::attribute_data_type_highest_complexity(
+ {attribute_kind->data_type, meta_data.data_type});
+ };
+ r_attributes.add_or_modify(attribute_id, add_info, modify_info);
+ });
+ delete dummy_component;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 9dca2c2907e..10e698c8f8a 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -14,6 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "BKE_collection.h"
#include "BKE_geometry_set_instances.hh"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -23,6 +24,7 @@
#include "BKE_spline.hh"
#include "DNA_collection_types.h"
+#include "DNA_layer_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -745,3 +747,36 @@ GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
}
} // namespace blender::bke
+
+void InstancesComponent::foreach_referenced_geometry(
+ blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const
+{
+ using namespace blender::bke;
+ for (const InstanceReference &reference : references_) {
+ switch (reference.type()) {
+ case InstanceReference::Type::Object: {
+ const Object &object = reference.object();
+ const GeometrySet object_geometry_set = object_get_geometry_set_for_read(object);
+ callback(object_geometry_set);
+ break;
+ }
+ case InstanceReference::Type::Collection: {
+ Collection &collection = reference.collection();
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (&collection, object) {
+ const GeometrySet object_geometry_set = object_get_geometry_set_for_read(*object);
+ callback(object_geometry_set);
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ break;
+ }
+ case InstanceReference::Type::GeometrySet: {
+ const GeometrySet &instance_geometry_set = reference.geometry_set();
+ callback(instance_geometry_set);
+ break;
+ }
+ case InstanceReference::Type::None: {
+ break;
+ }
+ }
+ }
+}
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 04b4003daed..f95b0da86ed 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -36,7 +36,6 @@
#include "node_geometry_util.hh"
-using blender::bke::AttributeKind;
using blender::bke::GeometryInstanceGroup;
namespace blender::nodes {