diff options
author | Jacques Lucke <jacques@blender.org> | 2020-11-19 15:17:11 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-11-19 15:17:11 +0300 |
commit | 00928f7826e9f38416f6f1fb7112a2badc752656 (patch) | |
tree | 42dbf2e335630951ee8cb94e05f410456f47c30d | |
parent | 91971093bbb400e0f3446740372f1d80ebb58d17 (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.
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); |