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:
authorJacques Lucke <jacques@blender.org>2020-11-19 15:17:11 +0300
committerJacques Lucke <jacques@blender.org>2020-11-19 15:17:11 +0300
commit00928f7826e9f38416f6f1fb7112a2badc752656 (patch)
tree42dbf2e335630951ee8cb94e05f410456f47c30d
parent91971093bbb400e0f3446740372f1d80ebb58d17 (diff)
Geometry Nodes: simplify attributes api and support deletion
The main difference is that the functions to access attributes have been moved to MeshComponent and PointCloudComponent.
-rw-r--r--source/blender/blenkernel/BKE_attribute_access.hh64
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh49
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc279
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc5
-rw-r--r--source/blender/depsgraph/CMakeLists.txt1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_instance.cc15
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_random_attribute.cc25
8 files changed, 243 insertions, 199 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index 41f5a1a3605..39fe3e6ba06 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -19,7 +19,8 @@
#include "FN_cpp_type.hh"
#include "BKE_attribute.h"
-#include "BKE_geometry_set.hh"
+
+#include "BLI_float3.hh"
struct Mesh;
@@ -196,65 +197,6 @@ using Float3ReadAttribute = TypedReadAttribute<float3>;
using FloatWriteAttribute = TypedWriteAttribute<float>;
using Float3WriteAttribute = TypedWriteAttribute<float3>;
-/* --------------------------------------------------------------------
- * Main attribute getters.
- */
-
-ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component,
- const StringRef attribute_name);
-WriteAttributePtr mesh_attribute_get_for_write(MeshComponent &mesh_component,
- const StringRef attribute_name);
-
-ReadAttributePtr pointcloud_attribute_get_for_read(const PointCloudComponent &pointcloud_component,
- const StringRef attribute_name);
-WriteAttributePtr pointcloud_attribute_get_for_write(
- const PointCloudComponent &pointcloud_component, const StringRef attribute_name);
-
-/* --------------------------------------------------------------------
- * Utilities for getting more specific attributes.
- */
-
-ReadAttributePtr mesh_attribute_adapt_domain(const MeshComponent &mesh_component,
- ReadAttributePtr attribute,
- const AttributeDomain to_domain);
-
-ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component,
- const StringRef attribute_name,
- const CPPType &cpp_type,
- const AttributeDomain domain,
- const void *default_value = nullptr);
-
-template<typename T>
-TypedReadAttribute<T> mesh_attribute_get_for_read(const MeshComponent &mesh_component,
- const StringRef attribute_name,
- const AttributeDomain domain,
- const T &default_value)
-{
- ReadAttributePtr attribute = mesh_attribute_get_for_read(
- mesh_component,
- attribute_name,
- CPPType::get<T>(),
- domain,
- static_cast<const void *>(&default_value));
- BLI_assert(attribute);
- return attribute;
-}
-
-ReadAttributePtr pointcloud_attribute_get_for_read(const PointCloudComponent &pointcloud_component,
- const StringRef attribute_name,
- const CPPType &cpp_type,
- const void *default_value = nullptr);
-
-template<typename T>
-TypedReadAttribute<T> pointcloud_attribute_get_for_read(
- const PointCloudComponent &pointcloud_component,
- const StringRef attribute_name,
- const T &default_value)
-{
- ReadAttributePtr attribute = pointcloud_attribute_get_for_read(
- pointcloud_component, attribute_name, CPPType::get<T>(), &default_value);
- BLI_assert(attribute);
- return attribute;
-}
+const CPPType *custom_data_type_to_cpp_type(const int type);
} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 4fe74aa2e1d..6e375f42e78 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -28,6 +28,7 @@
#include "BLI_map.hh"
#include "BLI_user_counter.hh"
+#include "BKE_attribute_access.hh"
#include "BKE_geometry_set.h"
struct Mesh;
@@ -52,6 +53,12 @@ enum class GeometryOwnershipType {
ReadOnly = 2,
};
+enum class AttributeDeleteStatus {
+ Deleted,
+ NotFound,
+ CannotBeDeleted,
+};
+
/* Make it possible to use the component type as key in hash tables. */
namespace blender {
template<> struct DefaultHash<GeometryComponentType> {
@@ -159,11 +166,32 @@ class MeshComponent : public GeometryComponent {
Mesh *release();
void copy_vertex_group_names_from_object(const struct Object &object);
- int vertex_group_index(blender::StringRef vertex_group_name) const;
const Mesh *get_for_read() const;
Mesh *get_for_write();
+ blender::bke::ReadAttributePtr attribute_get_for_read(
+ const blender::StringRef attribute_name) const;
+
+ blender::bke::WriteAttributePtr attribute_get_for_write(const blender::StringRef attribute_name);
+
+ blender::bke::ReadAttributePtr attribute_get_for_read(const blender::StringRef attribute_name,
+ const blender::fn::CPPType &cpp_type,
+ const AttributeDomain domain,
+ const void *default_value = nullptr) const;
+
+ template<typename T>
+ blender::bke::TypedReadAttribute<T> attribute_get_for_read(
+ const blender::StringRef attribute_name,
+ const AttributeDomain domain,
+ const T &default_value) const
+ {
+ return this->attribute_get_for_read(
+ attribute_name, blender::fn::CPPType::get<T>(), domain, &default_value);
+ }
+
+ AttributeDeleteStatus attribute_delete(const blender::StringRef attribute_name);
+
static constexpr inline GeometryComponentType type = GeometryComponentType::Mesh;
};
@@ -186,6 +214,25 @@ class PointCloudComponent : public GeometryComponent {
const PointCloud *get_for_read() const;
PointCloud *get_for_write();
+ blender::bke::ReadAttributePtr attribute_get_for_read(
+ const blender::StringRef attribute_name) const;
+
+ blender::bke::WriteAttributePtr attribute_get_for_write(const blender::StringRef attribute_name);
+
+ blender::bke::ReadAttributePtr attribute_get_for_read(const blender::StringRef attribute_name,
+ const blender::fn::CPPType &cpp_type,
+ const void *default_value) const;
+
+ template<typename T>
+ blender::bke::TypedReadAttribute<T> attribute_get_for_read(
+ const blender::StringRef attribute_name, const T &default_value) const
+ {
+ return this->attribute_get_for_read(
+ attribute_name, blender::fn::CPPType::get<T>(), &default_value);
+ }
+
+ AttributeDeleteStatus attribute_delete(const blender::StringRef attribute_name);
+
static constexpr inline GeometryComponentType type = GeometryComponentType::PointCloud;
};
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index a0d9c5b7df1..10834e6e885 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -17,7 +17,9 @@
#include <utility>
#include "BKE_attribute_access.hh"
+#include "BKE_customdata.h"
#include "BKE_deform.h"
+#include "BKE_geometry_set.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -279,22 +281,77 @@ static WriteAttributePtr write_attribute_from_custom_data(CustomData custom_data
return {};
}
-/** \} */
+const CPPType *custom_data_type_to_cpp_type(const int type)
+{
+ switch (type) {
+ case CD_PROP_FLOAT:
+ return &CPPType::get<float>();
+ case CD_PROP_FLOAT2:
+ return &CPPType::get<float2>();
+ case CD_PROP_FLOAT3:
+ return &CPPType::get<float3>();
+ case CD_PROP_INT32:
+ return &CPPType::get<int>();
+ case CD_PROP_COLOR:
+ return &CPPType::get<Color4f>();
+ }
+ return nullptr;
+}
-/* -------------------------------------------------------------------- */
-/** \name Get Read/Write attributes for meshes.
- * \{ */
+/** \} */
-ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component,
- const StringRef attribute_name)
+static int get_domain_length(const Mesh *mesh, const AttributeDomain domain)
{
- const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
+ return 0;
+ }
+ switch (domain) {
+ case ATTR_DOMAIN_CORNER:
+ return mesh->totloop;
+ case ATTR_DOMAIN_VERTEX:
+ return mesh->totvert;
+ case ATTR_DOMAIN_EDGE:
+ return mesh->totedge;
+ case ATTR_DOMAIN_POLYGON:
+ return mesh->totpoly;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* Returns true when the layer was found and is deleted. */
+static bool delete_named_custom_data_layer(CustomData &custom_data,
+ const StringRef attribute_name,
+ const int size)
+{
+ for (const int index : IndexRange(custom_data.totlayer)) {
+ const CustomDataLayer &layer = custom_data.layers[index];
+ if (layer.name == attribute_name) {
+ CustomData_free_layer(
+ &custom_data, layer.type, size, index - custom_data.typemap[layer.type]);
+ return true;
+ }
+ }
+ return false;
+}
+
+/** \} */
+
+} // namespace blender::bke
+
+blender::bke::ReadAttributePtr MeshComponent::attribute_get_for_read(
+ const blender::StringRef attribute_name) const
+{
+ using namespace blender;
+ using namespace blender::bke;
+
+ if (mesh_ == nullptr) {
return {};
}
ReadAttributePtr corner_attribute = read_attribute_from_custom_data(
- mesh->ldata, mesh->totloop, attribute_name, ATTR_DOMAIN_CORNER);
+ mesh_->ldata, mesh_->totloop, attribute_name, ATTR_DOMAIN_CORNER);
if (corner_attribute) {
return corner_attribute;
}
@@ -303,29 +360,29 @@ ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component
auto get_vertex_position = [](const MVert &vert) { return float3(vert.co); };
return std::make_unique<
DerivedArrayReadAttribute<MVert, float3, decltype(get_vertex_position)>>(
- ATTR_DOMAIN_VERTEX, Span(mesh->mvert, mesh->totvert), get_vertex_position);
+ ATTR_DOMAIN_VERTEX, Span(mesh_->mvert, mesh_->totvert), get_vertex_position);
}
- const int vertex_group_index = mesh_component.vertex_group_index(attribute_name);
+ const int vertex_group_index = vertex_group_names_.lookup_default(attribute_name, -1);
if (vertex_group_index >= 0) {
return std::make_unique<VertexWeightReadAttribute>(
- mesh->dvert, mesh->totvert, vertex_group_index);
+ mesh_->dvert, mesh_->totvert, vertex_group_index);
}
ReadAttributePtr vertex_attribute = read_attribute_from_custom_data(
- mesh->vdata, mesh->totvert, attribute_name, ATTR_DOMAIN_VERTEX);
+ mesh_->vdata, mesh_->totvert, attribute_name, ATTR_DOMAIN_VERTEX);
if (vertex_attribute) {
return vertex_attribute;
}
ReadAttributePtr edge_attribute = read_attribute_from_custom_data(
- mesh->edata, mesh->totedge, attribute_name, ATTR_DOMAIN_EDGE);
+ mesh_->edata, mesh_->totedge, attribute_name, ATTR_DOMAIN_EDGE);
if (edge_attribute) {
return edge_attribute;
}
ReadAttributePtr polygon_attribute = read_attribute_from_custom_data(
- mesh->pdata, mesh->totpoly, attribute_name, ATTR_DOMAIN_POLYGON);
+ mesh_->pdata, mesh_->totpoly, attribute_name, ATTR_DOMAIN_POLYGON);
if (polygon_attribute) {
return polygon_attribute;
}
@@ -333,16 +390,18 @@ ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component
return {};
}
-WriteAttributePtr mesh_attribute_get_for_write(MeshComponent &mesh_component,
- const StringRef attribute_name)
+blender::bke::WriteAttributePtr MeshComponent::attribute_get_for_write(
+ const blender::StringRef attribute_name)
{
- Mesh *mesh = mesh_component.get_for_write();
- if (mesh == nullptr) {
+ using namespace blender;
+ using namespace blender::bke;
+
+ if (mesh_ == nullptr) {
return {};
}
WriteAttributePtr corner_attribute = write_attribute_from_custom_data(
- mesh->ldata, mesh->totloop, attribute_name, ATTR_DOMAIN_CORNER);
+ mesh_->ldata, mesh_->totloop, attribute_name, ATTR_DOMAIN_CORNER);
if (corner_attribute) {
return corner_attribute;
}
@@ -355,31 +414,31 @@ WriteAttributePtr mesh_attribute_get_for_write(MeshComponent &mesh_component,
decltype(get_vertex_position),
decltype(set_vertex_position)>>(
ATTR_DOMAIN_VERTEX,
- MutableSpan(mesh->mvert, mesh->totvert),
+ MutableSpan(mesh_->mvert, mesh_->totvert),
get_vertex_position,
set_vertex_position);
}
- const int vertex_group_index = mesh_component.vertex_group_index(attribute_name);
+ const int vertex_group_index = vertex_group_names_.lookup_default_as(attribute_name, -1);
if (vertex_group_index >= 0) {
return std::make_unique<VertexWeightWriteAttribute>(
- mesh->dvert, mesh->totvert, vertex_group_index);
+ mesh_->dvert, mesh_->totvert, vertex_group_index);
}
WriteAttributePtr vertex_attribute = write_attribute_from_custom_data(
- mesh->vdata, mesh->totvert, attribute_name, ATTR_DOMAIN_VERTEX);
+ mesh_->vdata, mesh_->totvert, attribute_name, ATTR_DOMAIN_VERTEX);
if (vertex_attribute) {
return vertex_attribute;
}
WriteAttributePtr edge_attribute = write_attribute_from_custom_data(
- mesh->edata, mesh->totedge, attribute_name, ATTR_DOMAIN_EDGE);
+ mesh_->edata, mesh_->totedge, attribute_name, ATTR_DOMAIN_EDGE);
if (edge_attribute) {
return edge_attribute;
}
WriteAttributePtr polygon_attribute = write_attribute_from_custom_data(
- mesh->pdata, mesh->totpoly, attribute_name, ATTR_DOMAIN_POLYGON);
+ mesh_->pdata, mesh_->totpoly, attribute_name, ATTR_DOMAIN_POLYGON);
if (polygon_attribute) {
return polygon_attribute;
}
@@ -387,63 +446,20 @@ WriteAttributePtr mesh_attribute_get_for_write(MeshComponent &mesh_component,
return {};
}
-ReadAttributePtr mesh_attribute_adapt_domain(const MeshComponent &UNUSED(mesh_component),
- ReadAttributePtr attribute,
- const AttributeDomain to_domain)
-{
- if (!attribute) {
- return {};
- }
- const AttributeDomain from_domain = attribute->domain();
- if (from_domain == to_domain) {
- return attribute;
- }
-
- /* TODO: Actually implement domain interpolation. */
- return {};
-}
-
-static int get_domain_length(const MeshComponent &mesh_component, const AttributeDomain domain)
-{
- const Mesh *mesh = mesh_component.get_for_read();
- if (mesh == nullptr) {
- return 0;
- }
- switch (domain) {
- case ATTR_DOMAIN_CORNER:
- return mesh->totloop;
- case ATTR_DOMAIN_VERTEX:
- return mesh->totvert;
- case ATTR_DOMAIN_EDGE:
- return mesh->totedge;
- case ATTR_DOMAIN_POLYGON:
- return mesh->totpoly;
- default:
- break;
- }
- return 0;
-}
-
-static ReadAttributePtr make_default_attribute(const MeshComponent &mesh_component,
- const AttributeDomain domain,
- const CPPType &cpp_type,
- const void *default_value)
+blender::bke::ReadAttributePtr MeshComponent::attribute_get_for_read(
+ const blender::StringRef attribute_name,
+ const blender::fn::CPPType &cpp_type,
+ const AttributeDomain domain,
+ const void *default_value) const
{
+ using namespace blender;
+ using namespace blender::bke;
- const int length = get_domain_length(mesh_component, domain);
- return std::make_unique<ConstantReadAttribute>(domain, length, cpp_type, default_value);
-}
-
-ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component,
- const StringRef attribute_name,
- const CPPType &cpp_type,
- const AttributeDomain domain,
- const void *default_value)
-{
- ReadAttributePtr attribute = mesh_attribute_get_for_read(mesh_component, attribute_name);
+ ReadAttributePtr attribute = this->attribute_get_for_read(attribute_name);
auto get_default_or_empty = [&]() -> ReadAttributePtr {
if (default_value != nullptr) {
- return make_default_attribute(mesh_component, domain, cpp_type, default_value);
+ const int length = get_domain_length(mesh_, domain);
+ return std::make_unique<ConstantReadAttribute>(domain, length, cpp_type, default_value);
}
return {};
};
@@ -452,7 +468,8 @@ ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component
return get_default_or_empty();
}
if (attribute->domain() != domain) {
- attribute = mesh_attribute_adapt_domain(mesh_component, std::move(attribute), domain);
+ /* TODO: Support domain interpolation. */
+ return {};
}
if (!attribute) {
return get_default_or_empty();
@@ -464,55 +481,64 @@ ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component
return attribute;
}
-/** \} */
+AttributeDeleteStatus MeshComponent::attribute_delete(const blender::StringRef attribute_name)
+{
+ using namespace blender;
+ using namespace blender::bke;
-/* -------------------------------------------------------------------- */
-/** \name Get Read/Write attributes for point clouds.
- * \{ */
+ if (attribute_name == "Position") {
+ return AttributeDeleteStatus::CannotBeDeleted;
+ }
-ReadAttributePtr pointcloud_attribute_get_for_read(const PointCloudComponent &pointcloud_component,
- const StringRef attribute_name)
-{
- const PointCloud *pointcloud = pointcloud_component.get_for_read();
- if (pointcloud == nullptr) {
- return {};
+ if (mesh_ == nullptr) {
+ return AttributeDeleteStatus::CannotBeDeleted;
}
- return read_attribute_from_custom_data(
- pointcloud->pdata, pointcloud->totpoint, attribute_name, ATTR_DOMAIN_POINT);
-}
+ bool deleted = false;
+ deleted |= delete_named_custom_data_layer(mesh_->ldata, attribute_name, mesh_->totloop);
+ deleted |= delete_named_custom_data_layer(mesh_->vdata, attribute_name, mesh_->totvert);
+ deleted |= delete_named_custom_data_layer(mesh_->edata, attribute_name, mesh_->totedge);
+ deleted |= delete_named_custom_data_layer(mesh_->pdata, attribute_name, mesh_->totpoly);
-WriteAttributePtr pointcloud_attribute_get_for_write(
- const PointCloudComponent &pointcloud_component, const StringRef attribute_name)
-{
- const PointCloud *pointcloud = pointcloud_component.get_for_read();
- if (pointcloud == nullptr) {
- return {};
+ const int vertex_group_index = vertex_group_names_.lookup_default_as(attribute_name, -1);
+ if (vertex_group_index != -1) {
+ for (MDeformVert &dvert : MutableSpan(mesh_->dvert, mesh_->totvert)) {
+ MDeformWeight *weight = BKE_defvert_find_index(&dvert, vertex_group_index);
+ BKE_defvert_remove_group(&dvert, weight);
+ }
+ vertex_group_names_.remove_as(attribute_name);
+ deleted = true;
}
- return write_attribute_from_custom_data(
- pointcloud->pdata, pointcloud->totpoint, attribute_name, ATTR_DOMAIN_POINT);
+ if (deleted) {
+ return AttributeDeleteStatus::Deleted;
+ }
+ return AttributeDeleteStatus::NotFound;
}
-static int get_domain_length(const PointCloudComponent &pointcloud_component)
+blender::bke::ReadAttributePtr PointCloudComponent::attribute_get_for_read(
+ const blender::StringRef attribute_name) const
{
- const PointCloud *pointcloud = pointcloud_component.get_for_read();
- if (pointcloud == nullptr) {
- return 0;
+ if (pointcloud_ == nullptr) {
+ return {};
}
- return pointcloud->totpoint;
+
+ return blender::bke::read_attribute_from_custom_data(
+ pointcloud_->pdata, pointcloud_->totpoint, attribute_name, ATTR_DOMAIN_POINT);
}
-ReadAttributePtr pointcloud_attribute_get_for_read(const PointCloudComponent &pointcloud_component,
- const StringRef attribute_name,
- const CPPType &cpp_type,
- const void *default_value)
+blender::bke::ReadAttributePtr PointCloudComponent::attribute_get_for_read(
+ const blender::StringRef attribute_name,
+ const blender::fn::CPPType &cpp_type,
+ const void *default_value) const
{
- ReadAttributePtr attribute = pointcloud_attribute_get_for_read(pointcloud_component,
- attribute_name);
+ using namespace blender;
+ using namespace blender::bke;
+
+ ReadAttributePtr attribute = this->attribute_get_for_read(attribute_name);
auto get_default_or_empty = [&]() -> ReadAttributePtr {
if (default_value != nullptr) {
- const int length = get_domain_length(pointcloud_component);
+ const int length = pointcloud_ == nullptr ? 0 : pointcloud_->totpoint;
return std::make_unique<ConstantReadAttribute>(
ATTR_DOMAIN_POINT, length, cpp_type, default_value);
}
@@ -529,6 +555,31 @@ ReadAttributePtr pointcloud_attribute_get_for_read(const PointCloudComponent &po
return attribute;
}
-/** \} */
+blender::bke::WriteAttributePtr PointCloudComponent::attribute_get_for_write(
+ const blender::StringRef attribute_name)
+{
+ if (pointcloud_ == nullptr) {
+ return {};
+ }
-} // namespace blender::bke
+ return blender::bke::write_attribute_from_custom_data(
+ pointcloud_->pdata, pointcloud_->totpoint, attribute_name, ATTR_DOMAIN_POINT);
+}
+
+AttributeDeleteStatus PointCloudComponent::attribute_delete(
+ const blender::StringRef attribute_name)
+{
+ if (attribute_name == "Position") {
+ return AttributeDeleteStatus::CannotBeDeleted;
+ }
+
+ if (pointcloud_ == nullptr) {
+ return AttributeDeleteStatus::NotFound;
+ }
+
+ if (blender::bke::delete_named_custom_data_layer(
+ pointcloud_->pdata, attribute_name, pointcloud_->totpoint)) {
+ return AttributeDeleteStatus::Deleted;
+ }
+ return AttributeDeleteStatus::NotFound;
+}
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index c286514707c..c167f79982f 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -285,11 +285,6 @@ void MeshComponent::copy_vertex_group_names_from_object(const Object &object)
}
}
-int MeshComponent::vertex_group_index(StringRef vertex_group_name) const
-{
- return vertex_group_names_.lookup_default_as(vertex_group_name, -1);
-}
-
/* Get the mesh from this component. This method can be used by multiple threads at the same
* time. Therefore, the returned mesh should not be modified. No ownership is transferred. */
const Mesh *MeshComponent::get_for_read() const
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 2f613a0d416..95ae587f4ce 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../blenlib
../bmesh
../draw
+ ../functions
../makesdna
../makesrna
../modifiers
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 d7912c34645..37f027a83d8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -112,8 +112,8 @@ static void geo_point_distribute_exec(GeoNodeExecParams params)
const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>();
const Mesh *mesh_in = mesh_component.get_for_read();
- const FloatReadAttribute density_factors = bke::mesh_attribute_get_for_read<float>(
- mesh_component, density_attribute, ATTR_DOMAIN_VERTEX, 1.0f);
+ const FloatReadAttribute density_factors = mesh_component.attribute_get_for_read<float>(
+ density_attribute, ATTR_DOMAIN_VERTEX, 1.0f);
Vector<float3> points = scatter_points_from_mesh(mesh_in, density, density_factors);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
index 24f2ce8591d..4d37c647df2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -47,10 +47,9 @@ static void geo_point_instance_exec(GeoNodeExecParams params)
const PointCloudComponent *pointcloud_component =
geometry_set.get_component_for_read<PointCloudComponent>();
if (pointcloud_component != nullptr) {
- Float3ReadAttribute positions = bke::pointcloud_attribute_get_for_read<float3>(
- *pointcloud_component, "Position", {0, 0, 0});
- FloatReadAttribute radii = bke::pointcloud_attribute_get_for_read<float>(
- *pointcloud_component, "Radius", 1.0f);
+ Float3ReadAttribute positions = pointcloud_component->attribute_get_for_read<float3>(
+ "Position", {0, 0, 0});
+ FloatReadAttribute radii = pointcloud_component->attribute_get_for_read<float>("Radius", 1.0f);
for (const int i : IndexRange(positions.size())) {
const float radius = radii[i];
@@ -60,10 +59,10 @@ static void geo_point_instance_exec(GeoNodeExecParams params)
const MeshComponent *mesh_component = geometry_set.get_component_for_read<MeshComponent>();
if (mesh_component != nullptr) {
- Float3ReadAttribute positions = bke::mesh_attribute_get_for_read<float3>(
- *mesh_component, "Position", ATTR_DOMAIN_VERTEX, {0, 0, 0});
- FloatReadAttribute radii = bke::mesh_attribute_get_for_read<float>(
- *mesh_component, "Radius", ATTR_DOMAIN_VERTEX, 1.0f);
+ Float3ReadAttribute positions = mesh_component->attribute_get_for_read<float3>(
+ "Position", ATTR_DOMAIN_VERTEX, {0, 0, 0});
+ FloatReadAttribute radii = mesh_component->attribute_get_for_read<float>(
+ "Radius", ATTR_DOMAIN_VERTEX, 1.0f);
for (const int i : IndexRange(positions.size())) {
const float radius = radii[i];
diff --git a/source/blender/nodes/geometry/nodes/node_geo_random_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_random_attribute.cc
index c3c10a53e47..7a6723c50e4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_random_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_random_attribute.cc
@@ -82,18 +82,23 @@ static void geo_random_attribute_exec(GeoNodeExecParams params)
RandomNumberGenerator rng;
rng.seed_random(seed);
+ const CPPType &attribute_type = *bke::custom_data_type_to_cpp_type(data_type);
+
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
Mesh *mesh = mesh_component.get_for_write();
if (mesh != nullptr) {
- WriteAttributePtr attribute = bke::mesh_attribute_get_for_write(mesh_component,
- attribute_name);
+ WriteAttributePtr attribute = mesh_component.attribute_get_for_write(attribute_name);
+ if (attribute && attribute->cpp_type() != attribute_type) {
+ if (mesh_component.attribute_delete(attribute_name) == AttributeDeleteStatus::Deleted) {
+ attribute = {};
+ }
+ }
if (!attribute) {
BKE_id_attribute_new(&mesh->id, attribute_name.c_str(), data_type, domain, nullptr);
- attribute = bke::mesh_attribute_get_for_write(mesh_component, attribute_name);
+ attribute = mesh_component.attribute_get_for_write(attribute_name);
}
if (attribute) {
- const int size = attribute->size();
if (attribute->cpp_type().is<float>()) {
FloatWriteAttribute float_attribute = std::move(attribute);
randomize_attribute(float_attribute, min_value.x, max_value.x, rng);
@@ -109,15 +114,19 @@ static void geo_random_attribute_exec(GeoNodeExecParams params)
geometry_set.get_component_for_write<PointCloudComponent>();
PointCloud *pointcloud = pointcloud_component.get_for_write();
if (pointcloud != nullptr) {
- WriteAttributePtr attribute = bke::pointcloud_attribute_get_for_write(pointcloud_component,
- attribute_name);
+ WriteAttributePtr attribute = pointcloud_component.attribute_get_for_write(attribute_name);
+ if (attribute && attribute->cpp_type() != attribute_type) {
+ if (pointcloud_component.attribute_delete(attribute_name) ==
+ AttributeDeleteStatus::Deleted) {
+ attribute = {};
+ }
+ }
if (!attribute) {
BKE_id_attribute_new(&pointcloud->id, attribute_name.c_str(), data_type, domain, nullptr);
- attribute = bke::pointcloud_attribute_get_for_write(pointcloud_component, attribute_name);
+ attribute = pointcloud_component.attribute_get_for_write(attribute_name);
}
if (attribute) {
- const int size = attribute->size();
if (attribute->cpp_type().is<float>()) {
FloatWriteAttribute float_attribute = std::move(attribute);
randomize_attribute(float_attribute, min_value.x, max_value.x, rng);