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:
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh15
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc26
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc20
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_boolean.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc24
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc42
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc57
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc11
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc111
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_edge_split.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc64
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_field_on_domain.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_material_selection.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc42
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc15
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc26
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_raycast.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_id.cc26
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_position.cc52
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc25
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_triangulate.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc6
-rw-r--r--source/blender/nodes/intern/geometry_nodes_eval_log.cc12
66 files changed, 547 insertions, 485 deletions
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index c2dd1cd3ab5..0d5ba6cf5db 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -5,7 +5,6 @@
#include "FN_field.hh"
#include "FN_multi_function_builder.hh"
-#include "BKE_attribute_access.hh"
#include "BKE_geometry_fields.hh"
#include "BKE_geometry_set.hh"
@@ -20,16 +19,22 @@ struct ModifierData;
namespace blender::nodes {
using bke::AnonymousAttributeFieldInput;
+using bke::AttributeAccessor;
using bke::AttributeFieldInput;
using bke::AttributeIDRef;
+using bke::AttributeKind;
+using bke::AttributeMetaData;
+using bke::AttributeReader;
+using bke::AttributeWriter;
+using bke::GAttributeReader;
+using bke::GAttributeWriter;
using bke::GeometryComponentFieldContext;
using bke::GeometryFieldInput;
-using bke::OutputAttribute;
-using bke::OutputAttribute_Typed;
-using bke::ReadAttributeLookup;
+using bke::GSpanAttributeWriter;
+using bke::MutableAttributeAccessor;
+using bke::SpanAttributeWriter;
using bke::StrongAnonymousAttributeID;
using bke::WeakAnonymousAttributeID;
-using bke::WriteAttributeLookup;
using fn::Field;
using fn::FieldContext;
using fn::FieldEvaluator;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
index be7b3446125..58fbfb5a000 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
@@ -217,16 +217,20 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu
IndexMask UNUSED(mask)) const final
{
const GeometryComponentFieldContext field_context{component, source_domain_};
- const int domain_num = component.attribute_domain_num(field_context.domain());
+ const int domain_size = component.attribute_domain_size(field_context.domain());
+ if (domain_size == 0) {
+ return {};
+ }
+ const AttributeAccessor attributes = *component.attributes();
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.add(input_);
evaluator.add(group_index_);
evaluator.evaluate();
const VArray<T> values = evaluator.get_evaluated<T>(0);
const VArray<int> group_indices = evaluator.get_evaluated<int>(1);
- Array<T> accumulations_out(domain_num);
+ Array<T> accumulations_out(domain_size);
if (group_indices.is_single()) {
T accumulation = T();
@@ -261,7 +265,7 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu
}
}
- return component.attribute_try_adapt_domain<T>(
+ return attributes.adapt_domain<T>(
VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, domain);
}
@@ -303,9 +307,13 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput {
IndexMask UNUSED(mask)) const final
{
const GeometryComponentFieldContext field_context{component, source_domain_};
- const int domain_num = component.attribute_domain_num(field_context.domain());
+ const int domain_size = component.attribute_domain_size(field_context.domain());
+ if (domain_size == 0) {
+ return {};
+ }
+ const AttributeAccessor attributes = *component.attributes();
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.add(input_);
evaluator.add(group_index_);
evaluator.evaluate();
@@ -317,10 +325,10 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput {
for (const int i : values.index_range()) {
accumulation = values[i] + accumulation;
}
- return VArray<T>::ForSingle(accumulation, domain_num);
+ return VArray<T>::ForSingle(accumulation, domain_size);
}
- Array<T> accumulations_out(domain_num);
+ Array<T> accumulations_out(domain_size);
Map<int, T> accumulations;
for (const int i : values.index_range()) {
T &value = accumulations.lookup_or_add_default(group_indices[i]);
@@ -330,7 +338,7 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput {
accumulations_out[i] = accumulations.lookup(group_indices[i]);
}
- return component.attribute_try_adapt_domain<T>(
+ return attributes.adapt_domain<T>(
VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, domain);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
index 496fb081d6b..9f317075bb5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
@@ -111,19 +111,26 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
const eAttrDomain domain,
const GField &field)
{
+ const int domain_size = component.attribute_domain_size(domain);
+ if (domain_size == 0) {
+ return;
+ }
GeometryComponentFieldContext field_context{component, domain};
- const int domain_num = component.attribute_domain_num(domain);
- const IndexMask mask{IndexMask(domain_num)};
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ const IndexMask mask{IndexMask(domain_size)};
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(field.cpp_type());
- OutputAttribute output_attribute = component.attribute_try_get_for_output_only(
+ GAttributeWriter output_attribute = attributes.lookup_or_add_for_write(
attribute_id, domain, data_type);
+ if (!output_attribute) {
+ return;
+ }
fn::FieldEvaluator evaluator{field_context, &mask};
- evaluator.add_with_destination(field, output_attribute.varray());
+ evaluator.add_with_destination(field, output_attribute.varray);
evaluator.evaluate();
- output_attribute.save();
+ output_attribute.finish();
}
static StringRefNull identifier_suffix(eCustomDataType data_type)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
index 8ab0eb678e7..7e4904a7a6a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
@@ -72,11 +72,11 @@ static void node_geo_exec(GeoNodeExecParams params)
case GEO_COMPONENT_TYPE_MESH: {
if (geometry_set.has_mesh()) {
const MeshComponent *component = geometry_set.get_component_for_read<MeshComponent>();
- params.set_output("Point Count", component->attribute_domain_num(ATTR_DOMAIN_POINT));
- params.set_output("Edge Count", component->attribute_domain_num(ATTR_DOMAIN_EDGE));
- params.set_output("Face Count", component->attribute_domain_num(ATTR_DOMAIN_FACE));
- params.set_output("Face Corner Count",
- component->attribute_domain_num(ATTR_DOMAIN_CORNER));
+ const AttributeAccessor attributes = *component->attributes();
+ params.set_output("Point Count", attributes.domain_size(ATTR_DOMAIN_POINT));
+ params.set_output("Edge Count", attributes.domain_size(ATTR_DOMAIN_EDGE));
+ params.set_output("Face Count", attributes.domain_size(ATTR_DOMAIN_FACE));
+ params.set_output("Face Corner Count", attributes.domain_size(ATTR_DOMAIN_CORNER));
}
else {
params.set_default_remaining_outputs();
@@ -86,8 +86,9 @@ static void node_geo_exec(GeoNodeExecParams params)
case GEO_COMPONENT_TYPE_CURVE: {
if (geometry_set.has_curves()) {
const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>();
- params.set_output("Point Count", component->attribute_domain_num(ATTR_DOMAIN_POINT));
- params.set_output("Spline Count", component->attribute_domain_num(ATTR_DOMAIN_CURVE));
+ const AttributeAccessor attributes = *component->attributes();
+ params.set_output("Point Count", attributes.domain_size(ATTR_DOMAIN_POINT));
+ params.set_output("Spline Count", attributes.domain_size(ATTR_DOMAIN_CURVE));
}
else {
params.set_default_remaining_outputs();
@@ -98,7 +99,7 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_pointcloud()) {
const PointCloudComponent *component =
geometry_set.get_component_for_read<PointCloudComponent>();
- params.set_output("Point Count", component->attribute_domain_num(ATTR_DOMAIN_POINT));
+ params.set_output("Point Count", component->attributes()->domain_size(ATTR_DOMAIN_POINT));
}
else {
params.set_default_remaining_outputs();
@@ -109,7 +110,8 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_instances()) {
const InstancesComponent *component =
geometry_set.get_component_for_read<InstancesComponent>();
- params.set_output("Instance Count", component->attribute_domain_num(ATTR_DOMAIN_INSTANCE));
+ params.set_output("Instance Count",
+ component->attributes()->domain_size(ATTR_DOMAIN_INSTANCE));
}
else {
params.set_default_remaining_outputs();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
index 08e72dae8f6..34e28e50c81 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
@@ -195,9 +195,13 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<float> input_field = params.get_input<Field<float>>("Attribute");
Vector<float> data;
for (const GeometryComponent *component : components) {
- if (component->attribute_domain_supported(domain)) {
+ const std::optional<AttributeAccessor> attributes = component->attributes();
+ if (!attributes.has_value()) {
+ continue;
+ }
+ if (attributes->domain_supported(domain)) {
GeometryComponentFieldContext field_context{*component, domain};
- const int domain_num = component->attribute_domain_num(domain);
+ const int domain_num = attributes->domain_size(domain);
fn::FieldEvaluator data_evaluator{field_context, domain_num};
data_evaluator.add(input_field);
@@ -273,9 +277,13 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<float3> input_field = params.get_input<Field<float3>>("Attribute_001");
Vector<float3> data;
for (const GeometryComponent *component : components) {
- if (component->attribute_domain_supported(domain)) {
+ const std::optional<AttributeAccessor> attributes = component->attributes();
+ if (!attributes.has_value()) {
+ continue;
+ }
+ if (attributes->domain_supported(domain)) {
GeometryComponentFieldContext field_context{*component, domain};
- const int domain_num = component->attribute_domain_num(domain);
+ const int domain_num = attributes->domain_size(domain);
fn::FieldEvaluator data_evaluator{field_context, domain_num};
data_evaluator.add(input_field);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index 81cce1fc5da..69938f3e447 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -154,17 +154,15 @@ static void node_geo_exec(GeoNodeExecParams params)
/* Store intersecting edges in attribute. */
if (attribute_outputs.intersecting_edges_id) {
- MeshComponent mesh_component;
- mesh_component.replace(result, GeometryOwnershipType::Editable);
- OutputAttribute_Typed<bool> attribute = mesh_component.attribute_try_get_for_output_only<bool>(
+ MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*result);
+ SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_only_span<bool>(
attribute_outputs.intersecting_edges_id.get(), ATTR_DOMAIN_EDGE);
- MutableSpan<bool> selection = attribute.as_span();
- selection.fill(false);
+
+ selection.span.fill(false);
for (const int i : intersecting_edges) {
- selection[i] = true;
+ selection.span[i] = true;
}
-
- attribute.save();
+ selection.finish();
params.set_output(
"Intersecting Edges",
diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
index 045206d04cd..489b618b8be 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
@@ -143,7 +143,8 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
if (geometry_set.has_mesh()) {
count++;
const MeshComponent *component = geometry_set.get_component_for_read<MeshComponent>();
- total_num += component->attribute_domain_num(ATTR_DOMAIN_POINT);
+ const Mesh *mesh = component->get_for_read();
+ total_num += mesh->totvert;
}
if (geometry_set.has_pointcloud()) {
@@ -151,10 +152,9 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
span_count++;
const PointCloudComponent *component =
geometry_set.get_component_for_read<PointCloudComponent>();
- VArray<float3> varray = component->attribute_get_for_read<float3>(
- "position", ATTR_DOMAIN_POINT, {0, 0, 0});
- total_num += varray.size();
- positions_span = varray.get_internal_span();
+ const PointCloud *pointcloud = component->get_for_read();
+ positions_span = {reinterpret_cast<const float3 *>(pointcloud->co), pointcloud->totpoint};
+ total_num += pointcloud->totpoint;
}
if (geometry_set.has_curves()) {
@@ -181,8 +181,8 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
if (geometry_set.has_mesh()) {
const MeshComponent *component = geometry_set.get_component_for_read<MeshComponent>();
- VArray<float3> varray = component->attribute_get_for_read<float3>(
- "position", ATTR_DOMAIN_POINT, {0, 0, 0});
+ const VArray<float3> varray = component->attributes()->lookup<float3>("position",
+ ATTR_DOMAIN_POINT);
varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
offset += varray.size();
}
@@ -190,8 +190,8 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
if (geometry_set.has_pointcloud()) {
const PointCloudComponent *component =
geometry_set.get_component_for_read<PointCloudComponent>();
- VArray<float3> varray = component->attribute_get_for_read<float3>(
- "position", ATTR_DOMAIN_POINT, {0, 0, 0});
+ const VArray<float3> varray = component->attributes()->lookup<float3>("position",
+ ATTR_DOMAIN_POINT);
varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
offset += varray.size();
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
index fb8a488ddae..e200350dc18 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -581,8 +581,8 @@ static void calculate_curve_fillet(GeometrySet &geometry_set,
CurveComponent &component = geometry_set.get_component_for_write<CurveComponent>();
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
- fn::FieldEvaluator field_evaluator{field_context, domain_num};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ fn::FieldEvaluator field_evaluator{field_context, domain_size};
field_evaluator.add(radius_field);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc
index 91ba5f2845f..286d9993d0e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc
@@ -61,13 +61,13 @@ static Curves *create_star_curve(const float inner_radius,
static void create_selection_output(CurveComponent &component,
StrongAnonymousAttributeID &r_attribute)
{
- OutputAttribute_Typed<bool> attribute = component.attribute_try_get_for_output_only<bool>(
- r_attribute.get(), ATTR_DOMAIN_POINT);
- MutableSpan<bool> selection = attribute.as_span();
- for (int i : selection.index_range()) {
- selection[i] = i % 2 == 0;
+ SpanAttributeWriter<bool> selection =
+ component.attributes_for_write()->lookup_or_add_for_write_only_span<bool>(r_attribute.get(),
+ ATTR_DOMAIN_POINT);
+ for (int i : selection.span.index_range()) {
+ selection.span[i] = i % 2 == 0;
}
- attribute.save();
+ selection.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
index 64a174df599..de29735bd2d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -27,9 +27,9 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<bool> selection_field = params.get_input<Field<bool>>("Selection");
const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>();
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator selection_evaluator{field_context, domain_num};
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc
index 469d8d8d13b..f7ba724c377 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc
@@ -98,8 +98,8 @@ static void node_geo_exec(GeoNodeExecParams params)
}
has_curves = true;
const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>();
- if (!component.attribute_exists("handle_type_left") ||
- !component.attribute_exists("handle_type_right")) {
+ const AttributeAccessor attributes = *component.attributes();
+ if (!attributes.contains("handle_type_left") || !attributes.contains("handle_type_right")) {
return;
}
has_bezier = true;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
index 7d83b4b3ecb..6c4fb2e0855 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
@@ -126,19 +126,18 @@ static GMutableSpan ensure_point_attribute(PointCloudComponent &points,
const AttributeIDRef &attribute_id,
const eCustomDataType data_type)
{
- points.attribute_try_create(attribute_id, ATTR_DOMAIN_POINT, data_type, AttributeInitDefault());
- WriteAttributeLookup attribute = points.attribute_try_get_for_write(attribute_id);
- BLI_assert(attribute);
- return attribute.varray.get_internal_span();
+ return points.attributes_for_write()
+ ->lookup_or_add_for_write(attribute_id, ATTR_DOMAIN_POINT, data_type)
+ .varray.get_internal_span();
}
template<typename T>
static MutableSpan<T> ensure_point_attribute(PointCloudComponent &points,
const AttributeIDRef &attribute_id)
{
- GMutableSpan attribute = ensure_point_attribute(
- points, attribute_id, bke::cpp_type_to_custom_data_type(CPPType::get<T>()));
- return attribute.typed<T>();
+ return points.attributes_for_write()
+ ->lookup_or_add_for_write<T>(attribute_id, ATTR_DOMAIN_POINT)
+ .varray.get_internal_span();
}
namespace {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
index 2b90428acb1..00a79168087 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -506,9 +506,9 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
CurveComponent &component = geometry_set.get_component_for_write<CurveComponent>();
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.add(start_field);
evaluator.add(end_field);
evaluator.evaluate();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
index 60b5f0383ca..ab7ddfa71f1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
@@ -252,10 +252,8 @@ static void node_geo_exec(GeoNodeExecParams params)
BKE_mesh_wrapper_ensure_mdata(surface_mesh_eval);
- MeshComponent mesh_eval;
- mesh_eval.replace(surface_mesh_eval, GeometryOwnershipType::ReadOnly);
- MeshComponent mesh_orig;
- mesh_orig.replace(surface_mesh_orig, GeometryOwnershipType::ReadOnly);
+ const AttributeAccessor mesh_attributes_eval = bke::mesh_attributes(*surface_mesh_eval);
+ const AttributeAccessor mesh_attributes_orig = bke::mesh_attributes(*surface_mesh_orig);
Curves &curves_id = *curves_geometry.get_curves_for_write();
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
@@ -266,7 +264,7 @@ static void node_geo_exec(GeoNodeExecParams params)
params.error_message_add(NodeWarningType::Error, message);
return;
}
- if (!mesh_eval.attribute_exists(uv_map_name)) {
+ if (!mesh_attributes_eval.contains(uv_map_name)) {
pass_through_input();
char *message = BLI_sprintfN(TIP_("Evaluated surface missing UV map: %s."),
uv_map_name.c_str());
@@ -274,7 +272,7 @@ static void node_geo_exec(GeoNodeExecParams params)
MEM_freeN(message);
return;
}
- if (!mesh_orig.attribute_exists(uv_map_name)) {
+ if (!mesh_attributes_orig.contains(uv_map_name)) {
pass_through_input();
char *message = BLI_sprintfN(TIP_("Original surface missing UV map: %s."),
uv_map_name.c_str());
@@ -282,7 +280,7 @@ static void node_geo_exec(GeoNodeExecParams params)
MEM_freeN(message);
return;
}
- if (!mesh_eval.attribute_exists(rest_position_name)) {
+ if (!mesh_attributes_eval.contains(rest_position_name)) {
pass_through_input();
params.error_message_add(NodeWarningType::Error,
TIP_("Evaluated surface missing attribute: rest_position."));
@@ -294,12 +292,12 @@ static void node_geo_exec(GeoNodeExecParams params)
TIP_("Curves are not attached to any UV map."));
return;
}
- const VArraySpan<float2> uv_map_orig = mesh_orig.attribute_get_for_read<float2>(
- uv_map_name, ATTR_DOMAIN_CORNER, {0.0f, 0.0f});
- const VArraySpan<float2> uv_map_eval = mesh_eval.attribute_get_for_read<float2>(
- uv_map_name, ATTR_DOMAIN_CORNER, {0.0f, 0.0f});
- const VArraySpan<float3> rest_positions = mesh_eval.attribute_get_for_read<float3>(
- rest_position_name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f});
+ const VArraySpan<float2> uv_map_orig = mesh_attributes_orig.lookup<float2>(uv_map_name,
+ ATTR_DOMAIN_CORNER);
+ const VArraySpan<float2> uv_map_eval = mesh_attributes_eval.lookup<float2>(uv_map_name,
+ ATTR_DOMAIN_CORNER);
+ const VArraySpan<float3> rest_positions = mesh_attributes_eval.lookup<float3>(rest_position_name,
+ ATTR_DOMAIN_POINT);
const Span<float2> surface_uv_coords = curves.surface_uv_coords();
const Span<MLoopTri> looptris_orig{BKE_mesh_runtime_looptri_ensure(surface_mesh_orig),
diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
index 68489d1b9a6..408596b65aa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -49,7 +49,7 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader attribute = in_component.attributes()->lookup(attribute_id);
if (!attribute) {
continue;
}
@@ -60,8 +60,9 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
- OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
- attribute_id, attribute.domain, data_type);
+ GSpanAttributeWriter result_attribute =
+ result_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, attribute.domain, data_type);
if (!result_attribute) {
continue;
@@ -70,10 +71,10 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.as_span<T>();
+ MutableSpan<T> out_span = result_attribute.span.typed<T>();
out_span.copy_from(span);
});
- result_attribute.save();
+ result_attribute.finish();
}
}
@@ -89,7 +90,7 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader attribute = in_component.attributes()->lookup(attribute_id);
if (!attribute) {
continue;
}
@@ -100,8 +101,9 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
- OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
- attribute_id, attribute.domain, data_type);
+ GSpanAttributeWriter result_attribute =
+ result_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, attribute.domain, data_type);
if (!result_attribute) {
continue;
@@ -110,10 +112,10 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.as_span<T>();
+ MutableSpan<T> out_span = result_attribute.span.typed<T>();
copy_data_based_on_mask(span, out_span, mask);
});
- result_attribute.save();
+ result_attribute.finish();
}
}
@@ -125,7 +127,7 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader attribute = in_component.attributes()->lookup(attribute_id);
if (!attribute) {
continue;
}
@@ -136,8 +138,9 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
- OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
- attribute_id, attribute.domain, data_type);
+ GSpanAttributeWriter result_attribute =
+ result_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, attribute.domain, data_type);
if (!result_attribute) {
continue;
@@ -146,10 +149,10 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.as_span<T>();
+ MutableSpan<T> out_span = result_attribute.span.typed<T>();
copy_data_based_on_map(span, out_span, index_map);
});
- result_attribute.save();
+ result_attribute.finish();
}
}
@@ -319,7 +322,7 @@ static void delete_curves_selection(GeometrySet &geometry_set,
const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>();
GeometryComponentFieldContext field_context{src_component, selection_domain};
- const int domain_num = src_component.attribute_domain_num(selection_domain);
+ const int domain_num = src_component.attribute_domain_size(selection_domain);
fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.set_selection(selection_field);
evaluator.evaluate();
@@ -351,7 +354,7 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set,
*geometry_set.get_component_for_read<PointCloudComponent>();
GeometryComponentFieldContext field_context{src_points, ATTR_DOMAIN_POINT};
- fn::FieldEvaluator evaluator{field_context, src_points.attribute_domain_num(ATTR_DOMAIN_POINT)};
+ fn::FieldEvaluator evaluator{field_context, src_points.attribute_domain_size(ATTR_DOMAIN_POINT)};
evaluator.set_selection(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
@@ -379,8 +382,7 @@ static void delete_selected_instances(GeometrySet &geometry_set,
InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
GeometryComponentFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE};
- fn::FieldEvaluator evaluator{field_context,
- instances.attribute_domain_num(ATTR_DOMAIN_INSTANCE)};
+ fn::FieldEvaluator evaluator{field_context, instances.instances_num()};
evaluator.set_selection(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
@@ -1058,7 +1060,7 @@ static void separate_mesh_selection(GeometrySet &geometry_set,
GeometryComponentFieldContext field_context{src_component, selection_domain};
fn::FieldEvaluator evaluator{field_context,
- src_component.attribute_domain_num(selection_domain)};
+ src_component.attribute_domain_size(selection_domain)};
evaluator.add(selection_field);
evaluator.evaluate();
const VArray<bool> selection = evaluator.get_evaluated<bool>(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
index f95601813a3..faf5b7f65fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
@@ -290,31 +290,32 @@ BLI_NOINLINE static void propagate_existing_attributes(
const Span<int> looptri_indices)
{
const Mesh &mesh = *mesh_component.get_for_read();
+ const AttributeAccessor mesh_attributes = *mesh_component.attributes();
+ MutableAttributeAccessor point_attributes = *point_component.attributes_for_write();
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
const eCustomDataType output_data_type = entry.value.data_type;
- ReadAttributeLookup source_attribute = mesh_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader source_attribute = mesh_attributes.lookup(attribute_id);
if (!source_attribute) {
continue;
}
/* The output domain is always #ATTR_DOMAIN_POINT, since we are creating a point cloud. */
- OutputAttribute attribute_out = point_component.attribute_try_get_for_output_only(
+ GSpanAttributeWriter attribute_out = point_attributes.lookup_or_add_for_write_only_span(
attribute_id, ATTR_DOMAIN_POINT, output_data_type);
if (!attribute_out) {
continue;
}
- GMutableSpan out_span = attribute_out.as_span();
interpolate_attribute(mesh,
bary_coords,
looptri_indices,
source_attribute.domain,
source_attribute.varray,
- out_span);
- attribute_out.save();
+ attribute_out.span);
+ attribute_out.finish();
}
}
@@ -331,25 +332,21 @@ BLI_NOINLINE static void compute_attribute_outputs(const MeshComponent &mesh_com
const Span<int> looptri_indices,
const AttributeOutputs &attribute_outputs)
{
- OutputAttribute_Typed<int> id_attribute = point_component.attribute_try_get_for_output_only<int>(
- "id", ATTR_DOMAIN_POINT);
- MutableSpan<int> ids = id_attribute.as_span();
+ MutableAttributeAccessor pointcloud_attributes = *point_component.attributes_for_write();
- OutputAttribute_Typed<float3> normal_attribute;
- OutputAttribute_Typed<float3> rotation_attribute;
+ SpanAttributeWriter<int> ids = pointcloud_attributes.lookup_or_add_for_write_only_span<int>(
+ "id", ATTR_DOMAIN_POINT);
- MutableSpan<float3> normals;
- MutableSpan<float3> rotations;
+ SpanAttributeWriter<float3> normals;
+ SpanAttributeWriter<float3> rotations;
if (attribute_outputs.normal_id) {
- normal_attribute = point_component.attribute_try_get_for_output_only<float3>(
+ normals = pointcloud_attributes.lookup_or_add_for_write_only_span<float3>(
attribute_outputs.normal_id.get(), ATTR_DOMAIN_POINT);
- normals = normal_attribute.as_span();
}
if (attribute_outputs.rotation_id) {
- rotation_attribute = point_component.attribute_try_get_for_output_only<float3>(
+ rotations = pointcloud_attributes.lookup_or_add_for_write_only_span<float3>(
attribute_outputs.rotation_id.get(), ATTR_DOMAIN_POINT);
- rotations = rotation_attribute.as_span();
}
const Mesh &mesh = *mesh_component.get_for_read();
@@ -368,27 +365,27 @@ BLI_NOINLINE static void compute_attribute_outputs(const MeshComponent &mesh_com
const float3 v1_pos = float3(mesh.mvert[v1_index].co);
const float3 v2_pos = float3(mesh.mvert[v2_index].co);
- ids[i] = noise::hash(noise::hash_float(bary_coord), looptri_index);
+ ids.span[i] = noise::hash(noise::hash_float(bary_coord), looptri_index);
float3 normal;
- if (!normals.is_empty() || !rotations.is_empty()) {
+ if (!normals.span.is_empty() || !rotations.span.is_empty()) {
normal_tri_v3(normal, v0_pos, v1_pos, v2_pos);
}
- if (!normals.is_empty()) {
- normals[i] = normal;
+ if (!normals.span.is_empty()) {
+ normals.span[i] = normal;
}
- if (!rotations.is_empty()) {
- rotations[i] = normal_to_euler_rotation(normal);
+ if (!rotations.span.is_empty()) {
+ rotations.span[i] = normal_to_euler_rotation(normal);
}
}
- id_attribute.save();
+ ids.finish();
- if (normal_attribute) {
- normal_attribute.save();
+ if (normals) {
+ normals.finish();
}
- if (rotation_attribute) {
- rotation_attribute.save();
+ if (rotations) {
+ rotations.finish();
}
}
@@ -398,11 +395,11 @@ static Array<float> calc_full_density_factors_with_selection(const MeshComponent
{
const eAttrDomain attribute_domain = ATTR_DOMAIN_CORNER;
GeometryComponentFieldContext field_context{component, attribute_domain};
- const int domain_num = component.attribute_domain_num(attribute_domain);
+ const int domain_size = component.attribute_domain_size(attribute_domain);
- Array<float> densities(domain_num, 0.0f);
+ Array<float> densities(domain_size, 0.0f);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(density_field, densities.as_mutable_span());
evaluator.evaluate();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
index 8a256a9b91b..bf5479d552e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
@@ -146,9 +146,12 @@ static void transfer_attributes(
const GeometryComponent &src_component,
GeometryComponent &dst_component)
{
+ const AttributeAccessor src_attributes = *src_component.attributes();
+ MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write();
+
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader src_attribute = src_attributes.lookup(attribute_id);
if (!src_attribute) {
continue;
}
@@ -166,7 +169,7 @@ static void transfer_attributes(
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
+ GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
if (!dst_attribute) {
@@ -176,7 +179,7 @@ static void transfer_attributes(
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> span{src_attribute.varray.typed<T>()};
- MutableSpan<T> dst_span = dst_attribute.as_span<T>();
+ MutableSpan<T> dst_span = dst_attribute.span.typed<T>();
if (src_attribute.domain == ATTR_DOMAIN_FACE) {
dst_span.take_front(span.size()).copy_from(span);
if (keep_boundaries) {
@@ -193,7 +196,7 @@ static void transfer_attributes(
copy_data_based_on_new_to_old_map(span, dst_span, new_to_old_face_corners_map);
}
});
- dst_attribute.save();
+ dst_attribute.finish();
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
index 5fe300e0a08..41136060ab7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
@@ -147,17 +147,17 @@ static void create_duplicate_index_attribute(GeometryComponent &component,
const IndexAttributes &attribute_outputs,
const Span<int> offsets)
{
- OutputAttribute_Typed<int> copy_attribute = component.attribute_try_get_for_output_only<int>(
- attribute_outputs.duplicate_index.get(), output_domain);
- MutableSpan<int> duplicate_indices = copy_attribute.as_span();
+ SpanAttributeWriter<int> duplicate_indices =
+ component.attributes_for_write()->lookup_or_add_for_write_only_span<int>(
+ attribute_outputs.duplicate_index.get(), output_domain);
for (const int i : IndexRange(selection.size())) {
const IndexRange range = range_for_offsets_index(offsets, i);
- MutableSpan<int> indices = duplicate_indices.slice(range);
+ MutableSpan<int> indices = duplicate_indices.span.slice(range);
for (const int i : indices.index_range()) {
indices[i] = i;
}
}
- copy_attribute.save();
+ duplicate_indices.finish();
}
/**
@@ -168,20 +168,21 @@ static void copy_stable_id_point(const Span<int> offsets,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
{
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read("id");
+ GAttributeReader src_attribute = src_component.attributes()->lookup("id");
if (!src_attribute) {
return;
}
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
}
VArraySpan<int> src{src_attribute.varray.typed<int>()};
- MutableSpan<int> dst = dst_attribute.as_span<int>();
+ MutableSpan<int> dst = dst_attribute.span.typed<int>();
threaded_id_offset_copy(offsets, src, dst);
- dst_attribute.save();
+ dst_attribute.finish();
}
static void copy_attributes_without_id(GeometrySet &geometry_set,
@@ -197,25 +198,26 @@ static void copy_attributes_without_id(GeometrySet &geometry_set,
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
if (!src_attribute || src_attribute.domain != domain) {
continue;
}
eAttrDomain out_domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- attribute_id, out_domain, data_type);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
}
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> src = src_attribute.varray.typed<T>();
- MutableSpan<T> dst = dst_attribute.as_span<T>();
+ MutableSpan<T> dst = dst_attribute.span.typed<T>();
threaded_slice_fill<T>(offsets, selection, src, dst);
});
- dst_attribute.save();
+ dst_attribute.finish();
}
}
@@ -242,7 +244,7 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
if (!src_attribute) {
continue;
}
@@ -250,8 +252,9 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
eAttrDomain out_domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- attribute_id, out_domain, data_type);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
}
@@ -259,7 +262,7 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> src{src_attribute.varray.typed<T>()};
- MutableSpan<T> dst = dst_attribute.as_span<T>();
+ MutableSpan<T> dst = dst_attribute.span.typed<T>();
switch (out_domain) {
case ATTR_DOMAIN_CURVE:
@@ -280,7 +283,7 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
break;
}
});
- dst_attribute.save();
+ dst_attribute.finish();
}
}
@@ -297,18 +300,19 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves,
bke::CurvesGeometry &dst_curves,
CurveComponent &dst_component)
{
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read("id");
+ GAttributeReader src_attribute = src_component.attributes()->lookup("id");
if (!src_attribute) {
return;
}
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
}
VArraySpan<int> src{src_attribute.varray.typed<int>()};
- MutableSpan<int> dst = dst_attribute.as_span<int>();
+ MutableSpan<int> dst = dst_attribute.span.typed<int>();
threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
for (const int i_selection : range) {
@@ -322,7 +326,7 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves,
}
}
});
- dst_attribute.save();
+ dst_attribute.finish();
}
static void duplicate_curves(GeometrySet &geometry_set,
@@ -423,7 +427,7 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
if (!src_attribute) {
continue;
}
@@ -431,8 +435,9 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
eAttrDomain out_domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- attribute_id, out_domain, data_type);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
}
@@ -440,7 +445,7 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> src{src_attribute.varray.typed<T>()};
- MutableSpan<T> dst = dst_attribute.as_span<T>();
+ MutableSpan<T> dst = dst_attribute.span.typed<T>();
switch (out_domain) {
case ATTR_DOMAIN_FACE:
@@ -459,7 +464,7 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
break;
}
});
- dst_attribute.save();
+ dst_attribute.finish();
}
}
@@ -477,18 +482,19 @@ static void copy_stable_id_faces(const Mesh &mesh,
const MeshComponent &src_component,
MeshComponent &dst_component)
{
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read("id");
+ GAttributeReader src_attribute = src_component.attributes()->lookup("id");
if (!src_attribute) {
return;
}
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
}
VArraySpan<int> src{src_attribute.varray.typed<int>()};
- MutableSpan<int> dst = dst_attribute.as_span<int>();
+ MutableSpan<int> dst = dst_attribute.span.typed<int>();
Span<MPoly> polys(mesh.mpoly, mesh.totpoly);
int loop_index = 0;
@@ -511,7 +517,7 @@ static void copy_stable_id_faces(const Mesh &mesh,
}
}
- dst_attribute.save();
+ dst_attribute.finish();
}
static void duplicate_faces(GeometrySet &geometry_set,
@@ -636,7 +642,7 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
if (!src_attribute) {
continue;
}
@@ -644,15 +650,16 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
const eAttrDomain out_domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- attribute_id, out_domain, data_type);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
}
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> src{src_attribute.varray.typed<T>()};
- MutableSpan<T> dst = dst_attribute.as_span<T>();
+ MutableSpan<T> dst = dst_attribute.span.typed<T>();
switch (out_domain) {
case ATTR_DOMAIN_EDGE:
@@ -665,7 +672,7 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
break;
}
});
- dst_attribute.save();
+ dst_attribute.finish();
}
}
@@ -679,12 +686,13 @@ static void copy_stable_id_edges(const Mesh &mesh,
const MeshComponent &src_component,
MeshComponent &dst_component)
{
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read("id");
+ GAttributeReader src_attribute = src_component.attributes()->lookup("id");
if (!src_attribute) {
return;
}
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
}
@@ -692,7 +700,7 @@ static void copy_stable_id_edges(const Mesh &mesh,
Span<MEdge> edges(mesh.medge, mesh.totedge);
VArraySpan<int> src{src_attribute.varray.typed<int>()};
- MutableSpan<int> dst = dst_attribute.as_span<int>();
+ MutableSpan<int> dst = dst_attribute.span.typed<int>();
threading::parallel_for(IndexRange(selection.size()), 1024, [&](IndexRange range) {
for (const int i_selection : range) {
const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_selection);
@@ -710,7 +718,7 @@ static void copy_stable_id_edges(const Mesh &mesh,
}
}
});
- dst_attribute.save();
+ dst_attribute.finish();
}
static void duplicate_edges(GeometrySet &geometry_set,
@@ -837,7 +845,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
if (!src_attribute) {
continue;
}
@@ -845,8 +853,9 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
eAttrDomain domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- attribute_id, domain, data_type);
+ GSpanAttributeWriter dst_attribute =
+ dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, domain, data_type);
if (!dst_attribute) {
continue;
}
@@ -854,7 +863,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArraySpan<T> src{src_attribute.varray.typed<T>()};
- MutableSpan<T> dst = dst_attribute.as_span<T>();
+ MutableSpan<T> dst = dst_attribute.span.typed<T>();
switch (domain) {
case ATTR_DOMAIN_CURVE:
@@ -873,7 +882,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
break;
}
});
- dst_attribute.save();
+ dst_attribute.finish();
}
copy_stable_id_point(offsets, src_component, dst_component);
@@ -949,7 +958,7 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
{
const PointCloudComponent &src_points =
*geometry_set.get_component_for_read<PointCloudComponent>();
- const int point_num = src_points.attribute_domain_num(ATTR_DOMAIN_POINT);
+ const int point_num = src_points.attribute_domain_size(ATTR_DOMAIN_POINT);
GeometryComponentFieldContext field_context{src_points, ATTR_DOMAIN_POINT};
FieldEvaluator evaluator{field_context, point_num};
diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
index 94fbec66bfe..84acab47661 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
@@ -57,8 +57,8 @@ static void node_geo_exec(GeoNodeExecParams params)
const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>();
GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_EDGE};
- const int domain_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_EDGE);
- fn::FieldEvaluator selection_evaluator{field_context, domain_num};
+ const int domain_size = mesh_component.attribute_domain_size(ATTR_DOMAIN_EDGE);
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
index 59d7154db6e..baa9952b950 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -66,21 +66,21 @@ static void save_selection_as_attribute(MeshComponent &component,
const eAttrDomain domain,
const IndexMask selection)
{
- BLI_assert(!component.attribute_exists(id));
+ BLI_assert(!component.attributes()->contains(id));
- OutputAttribute_Typed<bool> attribute = component.attribute_try_get_for_output_only<bool>(
- id, domain);
+ SpanAttributeWriter<bool> attribute =
+ component.attributes_for_write()->lookup_or_add_for_write_span<bool>(id, domain);
/* Rely on the new attribute being zeroed by default. */
- BLI_assert(!attribute.as_span().as_span().contains(true));
+ BLI_assert(!attribute.span.as_span().contains(true));
if (selection.is_range()) {
- attribute.as_span().slice(selection.as_range()).fill(true);
+ attribute.span.slice(selection.as_range()).fill(true);
}
else {
- attribute.as_span().fill_indices(selection, true);
+ attribute.span.fill_indices(selection, true);
}
- attribute.save();
+ attribute.finish();
}
static MutableSpan<MVert> mesh_verts(Mesh &mesh)
@@ -168,7 +168,7 @@ static MutableSpan<int> get_orig_index_layer(Mesh &mesh, const eAttrDomain domai
component.replace(&mesh, GeometryOwnershipType::ReadOnly);
CustomData &custom_data = get_customdata(mesh, domain);
if (int *orig_indices = static_cast<int *>(CustomData_get_layer(&custom_data, CD_ORIGINDEX))) {
- return {orig_indices, component.attribute_domain_num(domain)};
+ return {orig_indices, component.attribute_domain_size(domain)};
}
return {};
}
@@ -280,16 +280,18 @@ static void extrude_mesh_vertices(MeshComponent &component,
new_edges[i_selection] = new_loose_edge(selection[i_selection], new_vert_range[i_selection]);
}
- component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
if (!ELEM(meta_data.domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE)) {
return true;
}
- OutputAttribute attribute = component.attribute_try_get_for_output(
+ GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
- MutableSpan<T> data = attribute.as_span().typed<T>();
- switch (attribute.domain()) {
+ MutableSpan<T> data = attribute.span.typed<T>();
+ switch (attribute.domain) {
case ATTR_DOMAIN_POINT: {
/* New vertices copy the attribute values from their source vertex. */
copy_with_mask(data.slice(new_vert_range), data.as_span(), selection);
@@ -307,7 +309,7 @@ static void extrude_mesh_vertices(MeshComponent &component,
}
});
- attribute.save();
+ attribute.finish();
return true;
});
@@ -524,8 +526,10 @@ static void extrude_mesh_edges(MeshComponent &component,
const Array<Vector<int>> new_vert_to_duplicate_edge_map = create_vert_to_edge_map(
new_vert_range.size(), duplicate_edges, orig_vert_size);
- component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
- OutputAttribute attribute = component.attribute_try_get_for_output(
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+ GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
return true; /* Impossible to write the "normal" attribute. */
@@ -533,8 +537,8 @@ static void extrude_mesh_edges(MeshComponent &component,
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
- MutableSpan<T> data = attribute.as_span().typed<T>();
- switch (attribute.domain()) {
+ MutableSpan<T> data = attribute.span.typed<T>();
+ switch (attribute.domain) {
case ATTR_DOMAIN_POINT: {
/* New vertices copy the attribute values from their source vertex. */
copy_with_indices(data.slice(new_vert_range), data.as_span(), new_vert_indices);
@@ -626,7 +630,7 @@ static void extrude_mesh_edges(MeshComponent &component,
}
});
- attribute.save();
+ attribute.finish();
return true;
});
@@ -902,8 +906,10 @@ static void extrude_mesh_face_regions(MeshComponent &component,
const Array<Vector<int>> new_vert_to_duplicate_edge_map = create_vert_to_edge_map(
new_vert_range.size(), boundary_edges, orig_vert_size);
- component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
- OutputAttribute attribute = component.attribute_try_get_for_output(
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+ GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
return true; /* Impossible to write the "normal" attribute. */
@@ -911,8 +917,8 @@ static void extrude_mesh_face_regions(MeshComponent &component,
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
- MutableSpan<T> data = attribute.as_span().typed<T>();
- switch (attribute.domain()) {
+ MutableSpan<T> data = attribute.span.typed<T>();
+ switch (attribute.domain) {
case ATTR_DOMAIN_POINT: {
/* New vertices copy the attributes from their original vertices. */
copy_with_indices(data.slice(new_vert_range), data.as_span(), new_vert_indices);
@@ -991,7 +997,7 @@ static void extrude_mesh_face_regions(MeshComponent &component,
}
});
- attribute.save();
+ attribute.finish();
return true;
});
@@ -1154,8 +1160,10 @@ static void extrude_individual_mesh_faces(MeshComponent &component,
}
});
- component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
- OutputAttribute attribute = component.attribute_try_get_for_output(
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+ GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
return true; /* Impossible to write the "normal" attribute. */
@@ -1163,8 +1171,8 @@ static void extrude_individual_mesh_faces(MeshComponent &component,
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
- MutableSpan<T> data = attribute.as_span().typed<T>();
- switch (attribute.domain()) {
+ MutableSpan<T> data = attribute.span.typed<T>();
+ switch (attribute.domain) {
case ATTR_DOMAIN_POINT: {
/* New vertices copy the attributes from their original vertices. */
MutableSpan<T> new_data = data.slice(new_vert_range);
@@ -1267,7 +1275,7 @@ static void extrude_individual_mesh_faces(MeshComponent &component,
}
});
- attribute.save();
+ attribute.finish();
return true;
});
diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc
index 7839e148ee3..64861e529bc 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc
@@ -91,7 +91,7 @@ class FieldAtIndex final : public GeometryFieldInput {
{
const GeometryComponentFieldContext value_field_context{component, value_field_domain_};
FieldEvaluator value_evaluator{value_field_context,
- component.attribute_domain_num(value_field_domain_)};
+ component.attribute_domain_size(value_field_domain_)};
value_evaluator.add(value_field_);
value_evaluator.evaluate();
const GVArray &values = value_evaluator.get_evaluated(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_on_domain.cc b/source/blender/nodes/geometry/nodes/node_geo_field_on_domain.cc
index e6906f4fb21..5939ed5334d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_field_on_domain.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_field_on_domain.cc
@@ -85,12 +85,12 @@ class FieldOnDomain final : public GeometryFieldInput {
IndexMask /* mask */) const final
{
const GeometryComponentFieldContext context{component, src_domain_};
- FieldEvaluator value_evaluator{context, component.attribute_domain_num(src_domain_)};
+ FieldEvaluator value_evaluator{context, component.attribute_domain_size(src_domain_)};
value_evaluator.add(src_field_);
value_evaluator.evaluate();
const GVArray &values = value_evaluator.get_evaluated(0);
- return component.attribute_try_adapt_domain(values, src_domain_, domain);
+ return component.attributes()->adapt_domain(values, src_domain_, domain);
}
};
diff --git a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
index 0484017cf3b..15b2822805a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
@@ -22,11 +22,11 @@ static void node_declare(NodeDeclarationBuilder &b)
static void mesh_flip_faces(MeshComponent &component, const Field<bool> &selection_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE);
+ if (domain_size == 0) {
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.add(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_as_mask(0);
@@ -49,20 +49,21 @@ static void mesh_flip_faces(MeshComponent &component, const Field<bool> &selecti
}
}
- component.attribute_foreach(
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ attributes.for_all(
[&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
if (meta_data.domain == ATTR_DOMAIN_CORNER) {
- OutputAttribute attribute = component.attribute_try_get_for_output(
- attribute_id, ATTR_DOMAIN_CORNER, meta_data.data_type, nullptr);
+ GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
+ attribute_id, ATTR_DOMAIN_CORNER, meta_data.data_type);
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
- MutableSpan<T> dst_span = attribute.as_span<T>();
+ MutableSpan<T> dst_span = attribute.span.typed<T>();
for (const int j : selection.index_range()) {
const MPoly &poly = polys[selection[j]];
dst_span.slice(poly.loopstart + 1, poly.totloop - 1).reverse();
}
});
- attribute.save();
+ attribute.finish();
}
return true;
});
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
index e0aaf43235c..bc1b9e940a1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
@@ -39,11 +39,13 @@ class HandlePositionFieldInput final : public GeometryFieldInput {
evaluator.evaluate();
const VArray<bool> relative = evaluator.get_evaluated<bool>(0);
- VArray<float3> positions = component.attribute_get_for_read<float3>(
+ const AttributeAccessor attributes = *component.attributes();
+
+ VArray<float3> positions = attributes.lookup_or_default<float3>(
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
StringRef side = left_ ? "handle_left" : "handle_right";
- VArray<float3> handles = component.attribute_get_for_read<float3>(
+ VArray<float3> handles = attributes.lookup_or_default<float3>(
side, ATTR_DOMAIN_POINT, {0, 0, 0});
if (relative.is_single()) {
@@ -52,10 +54,10 @@ class HandlePositionFieldInput final : public GeometryFieldInput {
for (const int i : positions.index_range()) {
output[i] = handles[i] - positions[i];
}
- return component.attribute_try_adapt_domain<float3>(
+ return attributes.adapt_domain<float3>(
VArray<float3>::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain);
}
- return component.attribute_try_adapt_domain<float3>(handles, ATTR_DOMAIN_POINT, domain);
+ return attributes.adapt_domain<float3>(handles, ATTR_DOMAIN_POINT, domain);
}
Array<float3> output(positions.size());
@@ -67,7 +69,7 @@ class HandlePositionFieldInput final : public GeometryFieldInput {
output[i] = handles[i];
}
}
- return component.attribute_try_adapt_domain<float3>(
+ return component.attributes()->adapt_domain<float3>(
VArray<float3>::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc
index f27e0305c7d..b009aaa5291 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc
@@ -91,7 +91,7 @@ class AngleFieldInput final : public GeometryFieldInput {
};
VArray<float> angles = VArray<float>::ForFunc(mesh->totedge, angle_fn);
- return component.attribute_try_adapt_domain<float>(
+ return component.attributes()->adapt_domain<float>(
std::move(angles), ATTR_DOMAIN_EDGE, domain);
}
@@ -166,7 +166,7 @@ class SignedAngleFieldInput final : public GeometryFieldInput {
};
VArray<float> angles = VArray<float>::ForFunc(mesh->totedge, angle_fn);
- return component.attribute_try_adapt_domain<float>(
+ return component.attributes()->adapt_domain<float>(
std::move(angles), ATTR_DOMAIN_EDGE, domain);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
index cbc2ebc3e68..50d6998bb27 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
@@ -40,7 +40,7 @@ class EdgeNeighborCountFieldInput final : public GeometryFieldInput {
face_count[mesh->mloop[i].e]++;
}
- return mesh_component.attribute_try_adapt_domain<int>(
+ return mesh_component.attributes()->adapt_domain<int>(
VArray<int>::ForContainer(std::move(face_count)), ATTR_DOMAIN_EDGE, domain);
}
return {};
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
index 6201ad26bfb..83e511f45c2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
@@ -93,14 +93,14 @@ static VArray<float3> construct_edge_positions_gvarray(const MeshComponent &comp
}
if (vertex == VERTEX_ONE) {
- return component.attribute_try_adapt_domain<float3>(
+ return component.attributes()->adapt_domain<float3>(
VArray<float3>::ForFunc(
mesh->totedge,
[mesh](const int i) { return float3(mesh->mvert[mesh->medge[i].v1].co); }),
ATTR_DOMAIN_EDGE,
domain);
}
- return component.attribute_try_adapt_domain<float3>(
+ return component.attributes()->adapt_domain<float3>(
VArray<float3>::ForFunc(
mesh->totedge,
[mesh](const int i) { return float3(mesh->mvert[mesh->medge[i].v2].co); }),
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
index 7a0e3e37a65..4d21bf9443a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
@@ -29,7 +29,7 @@ static VArray<float> construct_face_area_gvarray(const MeshComponent &component,
return BKE_mesh_calc_poly_area(mp, &mesh->mloop[mp->loopstart], mesh->mvert);
};
- return component.attribute_try_adapt_domain<float>(
+ return component.attributes()->adapt_domain<float>(
VArray<float>::ForFunc(mesh->totpoly, area_fn), ATTR_DOMAIN_FACE, domain);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc
index d02f7291704..6b04ff08d9e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc
@@ -80,7 +80,7 @@ class PlanarFieldInput final : public GeometryFieldInput {
return max - min < thresholds[i_poly] / 2.0f;
};
- return component.attribute_try_adapt_domain<bool>(
+ return component.attributes()->adapt_domain<bool>(
VArray<bool>::ForFunc(mesh->totpoly, planar_fn), ATTR_DOMAIN_FACE, domain);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
index 67a21cb06f0..a225ce61b14 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
@@ -40,7 +40,7 @@ static VArray<int> construct_neighbor_count_gvarray(const MeshComponent &compone
}
}
- return component.attribute_try_adapt_domain<int>(
+ return component.attributes()->adapt_domain<int>(
VArray<int>::ForContainer(std::move(poly_count)), ATTR_DOMAIN_FACE, domain);
}
@@ -83,7 +83,7 @@ static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component
return {};
}
- return component.attribute_try_adapt_domain<int>(
+ return component.attributes()->adapt_domain<int>(
VArray<int>::ForFunc(mesh->totpoly,
[mesh](const int i) -> float { return mesh->mpoly[i].totloop; }),
ATTR_DOMAIN_FACE,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
index bd57924d685..2c7eef5665f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
@@ -54,7 +54,7 @@ class IslandFieldInput final : public GeometryFieldInput {
output[i] = ordered_roots.index_of_or_add(root);
}
- return mesh_component.attribute_try_adapt_domain<int>(
+ return mesh_component.attributes()->adapt_domain<int>(
VArray<int>::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain);
}
@@ -101,7 +101,8 @@ class IslandCountFieldInput final : public GeometryFieldInput {
island_list.add(root);
}
- return VArray<int>::ForSingle(island_list.size(), mesh_component.attribute_domain_num(domain));
+ return VArray<int>::ForSingle(island_list.size(),
+ mesh_component.attribute_domain_size(domain));
}
uint64_t hash() const override
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
index def82eefca5..267ba44cc00 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
@@ -32,7 +32,7 @@ static VArray<int> construct_curve_point_count_gvarray(const CurveComponent &com
}
if (domain == ATTR_DOMAIN_POINT) {
VArray<int> count = VArray<int>::ForFunc(curves.curves_num(), count_fn);
- return component.attribute_try_adapt_domain<int>(
+ return component.attributes()->adapt_domain<int>(
std::move(count), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
index f5831941094..a2aab5464aa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
@@ -75,7 +75,7 @@ static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &comp
const VArray<int8_t> types = curves.curve_types();
if (curves.is_single_type(CURVE_TYPE_POLY)) {
- return component.attribute_try_adapt_domain<float3>(
+ return component.attributes()->adapt_domain<float3>(
VArray<float3>::ForSpan(curves.evaluated_tangents()), ATTR_DOMAIN_POINT, domain);
}
@@ -86,7 +86,7 @@ static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &comp
}
if (domain == ATTR_DOMAIN_CURVE) {
- return component.attribute_try_adapt_domain<float3>(
+ return component.attributes()->adapt_domain<float3>(
VArray<float3>::ForContainer(std::move(tangents)), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
index 21ef8765e43..3ce26a086e2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
@@ -50,7 +50,7 @@ static void add_instances_from_component(
const Map<AttributeIDRef, AttributeKind> &attributes_to_propagate)
{
const eAttrDomain domain = ATTR_DOMAIN_POINT;
- const int domain_num = src_component.attribute_domain_num(domain);
+ const int domain_num = src_component.attribute_domain_size(domain);
VArray<bool> pick_instance;
VArray<int> indices;
@@ -82,7 +82,7 @@ static void add_instances_from_component(
MutableSpan<float4x4> dst_transforms = dst_component.instance_transforms().slice(start_len,
select_len);
- VArray<float3> positions = src_component.attribute_get_for_read<float3>(
+ VArray<float3> positions = src_component.attributes()->lookup_or_default<float3>(
"position", domain, {0, 0, 0});
const InstancesComponent *src_instances = instance.get_component_for_read<InstancesComponent>();
@@ -154,12 +154,12 @@ static void add_instances_from_component(
}
}
- bke::CustomDataAttributes &instance_attributes = dst_component.attributes();
+ bke::CustomDataAttributes &instance_attributes = dst_component.instance_attributes();
for (const auto item : attributes_to_propagate.items()) {
const AttributeIDRef &attribute_id = item.key;
const AttributeKind attribute_kind = item.value;
- const GVArray src_attribute = src_component.attribute_get_for_read(
+ const GVArray src_attribute = src_component.attributes()->lookup_or_default(
attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type);
BLI_assert(src_attribute);
std::optional<GMutableSpan> dst_attribute_opt = instance_attributes.get_for_write(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
index ffc6137cf83..edbe6e1593f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
@@ -40,9 +40,9 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
const InstancesComponent &instances = *geometry_set.get_component_for_read<InstancesComponent>();
GeometryComponentFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE};
- const int domain_num = instances.attribute_domain_num(ATTR_DOMAIN_INSTANCE);
+ const int domain_size = instances.instances_num();
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(std::move(selection_field));
evaluator.add(std::move(position_field));
evaluator.add(std::move(radius_field));
@@ -75,18 +75,18 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
const AttributeIDRef &attribute_id = item.key;
const AttributeKind attribute_kind = item.value;
- const GVArray src = instances.attribute_get_for_read(
+ const GVArray src = instances.attributes()->lookup_or_default(
attribute_id, ATTR_DOMAIN_INSTANCE, attribute_kind.data_type);
BLI_assert(src);
- OutputAttribute dst = points.attribute_try_get_for_output_only(
+ GSpanAttributeWriter dst = points.attributes_for_write()->lookup_or_add_for_write_only_span(
attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type);
BLI_assert(dst);
attribute_math::convert_to_static_type(attribute_kind.data_type, [&](auto dummy) {
using T = decltype(dummy);
- copy_attribute_to_points(src.typed<T>(), selection, dst.as_span().typed<T>());
+ copy_attribute_to_points(src.typed<T>(), selection, dst.span.typed<T>());
});
- dst.save();
+ dst.finish();
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index 62cd1d8ac3a..083a505539a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -24,7 +24,7 @@ static Map<AttributeIDRef, AttributeMetaData> get_final_attribute_info(
Map<AttributeIDRef, AttributeMetaData> info;
for (const GeometryComponent *component : components) {
- component->attribute_foreach(
+ component->attributes()->for_all(
[&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
if (attribute_id.is_named() && ignored_attributes.contains(attribute_id.name())) {
return true;
@@ -56,11 +56,11 @@ static void fill_new_attribute(Span<const GeometryComponent *> src_components,
int offset = 0;
for (const GeometryComponent *component : src_components) {
- const int domain_num = component->attribute_domain_num(domain);
+ const int domain_num = component->attribute_domain_size(domain);
if (domain_num == 0) {
continue;
}
- GVArray read_attribute = component->attribute_get_for_read(
+ GVArray read_attribute = component->attributes()->lookup_or_default(
attribute_id, domain, data_type, nullptr);
GVArraySpan src_span{read_attribute};
@@ -83,15 +83,15 @@ static void join_attributes(Span<const GeometryComponent *> src_components,
const AttributeIDRef attribute_id = item.key;
const AttributeMetaData &meta_data = item.value;
- OutputAttribute write_attribute = result.attribute_try_get_for_output_only(
- attribute_id, meta_data.domain, meta_data.data_type);
+ GSpanAttributeWriter write_attribute =
+ result.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, meta_data.domain, meta_data.data_type);
if (!write_attribute) {
continue;
}
- GMutableSpan dst_span = write_attribute.as_span();
fill_new_attribute(
- src_components, attribute_id, meta_data.data_type, meta_data.domain, dst_span);
- write_attribute.save();
+ src_components, attribute_id, meta_data.data_type, meta_data.domain, write_attribute.span);
+ write_attribute.finish();
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
index 5875606da97..ca613ae009b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
@@ -71,7 +71,7 @@ class MaterialSelectionFieldInput final : public GeometryFieldInput {
Array<bool> selection(mesh->totpoly);
select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
- return mesh_component.attribute_try_adapt_domain<bool>(
+ return mesh_component.attributes()->adapt_domain<bool>(
VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
return nullptr;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
index 1def4089115..4bc84a7a08a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
@@ -39,7 +39,7 @@ static PointCloud *pointcloud_merge_by_distance(const PointCloudComponent &src_p
const float merge_distance,
const Field<bool> &selection_field)
{
- const int src_num = src_points.attribute_domain_num(ATTR_DOMAIN_POINT);
+ const int src_num = src_points.attribute_domain_size(ATTR_DOMAIN_POINT);
GeometryComponentFieldContext context{src_points, ATTR_DOMAIN_POINT};
FieldEvaluator evaluator{context, src_num};
evaluator.add(selection_field);
@@ -57,7 +57,7 @@ static std::optional<Mesh *> mesh_merge_by_distance_connected(const MeshComponen
const float merge_distance,
const Field<bool> &selection_field)
{
- const int src_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ const int src_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
Array<bool> selection(src_num);
GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT};
FieldEvaluator evaluator{context, src_num};
@@ -72,7 +72,7 @@ static std::optional<Mesh *> mesh_merge_by_distance_all(const MeshComponent &mes
const float merge_distance,
const Field<bool> &selection_field)
{
- const int src_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ const int src_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT};
FieldEvaluator evaluator{context, src_num};
evaluator.add(selection_field);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index b882d4bdf09..cb79ef93de9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
@@ -480,53 +480,49 @@ static void calculate_selection_outputs(Mesh *mesh,
const ConeConfig &config,
ConeAttributeOutputs &attribute_outputs)
{
- MeshComponent mesh_component;
- mesh_component.replace(mesh, GeometryOwnershipType::Editable);
+ MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*mesh);
/* Populate "Top" selection output. */
if (attribute_outputs.top_id) {
const bool face = !config.top_is_point && config.fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE;
- OutputAttribute_Typed<bool> attribute = mesh_component.attribute_try_get_for_output_only<bool>(
+ SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_only_span<bool>(
attribute_outputs.top_id.get(), face ? ATTR_DOMAIN_FACE : ATTR_DOMAIN_POINT);
- MutableSpan<bool> selection = attribute.as_span();
if (config.top_is_point) {
- selection[config.first_vert] = true;
+ selection.span[config.first_vert] = true;
}
else {
- selection.slice(0, face ? config.top_faces_len : config.circle_segments).fill(true);
+ selection.span.slice(0, face ? config.top_faces_len : config.circle_segments).fill(true);
}
- attribute.save();
+ selection.finish();
}
/* Populate "Bottom" selection output. */
if (attribute_outputs.bottom_id) {
const bool face = !config.bottom_is_point &&
config.fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE;
- OutputAttribute_Typed<bool> attribute = mesh_component.attribute_try_get_for_output_only<bool>(
+ SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_only_span<bool>(
attribute_outputs.bottom_id.get(), face ? ATTR_DOMAIN_FACE : ATTR_DOMAIN_POINT);
- MutableSpan<bool> selection = attribute.as_span();
if (config.bottom_is_point) {
- selection[config.last_vert] = true;
+ selection.span[config.last_vert] = true;
}
else if (face) {
- selection.slice(config.bottom_faces_start, config.bottom_faces_len).fill(true);
+ selection.span.slice(config.bottom_faces_start, config.bottom_faces_len).fill(true);
}
else {
- selection.slice(config.last_ring_verts_start + 1, config.circle_segments).fill(true);
+ selection.span.slice(config.last_ring_verts_start + 1, config.circle_segments).fill(true);
}
- attribute.save();
+ selection.finish();
}
/* Populate "Side" selection output. */
if (attribute_outputs.side_id) {
- OutputAttribute_Typed<bool> attribute = mesh_component.attribute_try_get_for_output_only<bool>(
+ SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_only_span<bool>(
attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE);
- MutableSpan<bool> selection = attribute.as_span();
- selection.slice(config.side_faces_start, config.side_faces_len).fill(true);
- attribute.save();
+ selection.span.slice(config.side_faces_start, config.side_faces_len).fill(true);
+ selection.finish();
}
}
@@ -540,11 +536,11 @@ static void calculate_selection_outputs(Mesh *mesh,
*/
static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config)
{
- MeshComponent mesh_component;
- mesh_component.replace(mesh, GeometryOwnershipType::Editable);
- OutputAttribute_Typed<float2> uv_attribute =
- mesh_component.attribute_try_get_for_output_only<float2>("uv_map", ATTR_DOMAIN_CORNER);
- MutableSpan<float2> uvs = uv_attribute.as_span();
+ MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*mesh);
+
+ SpanAttributeWriter<float2> uv_attribute = attributes.lookup_or_add_for_write_only_span<float2>(
+ "uv_map", ATTR_DOMAIN_CORNER);
+ MutableSpan<float2> uvs = uv_attribute.span;
Array<float2> circle(config.circle_segments);
float angle = 0.0f;
@@ -654,7 +650,7 @@ static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config)
}
}
- uv_attribute.save();
+ uv_attribute.finish();
}
static Mesh *create_vertex_mesh()
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
index 523dbd5dac2..9baf0b3171e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
@@ -18,23 +18,22 @@ namespace blender::nodes {
static void calculate_uvs(
Mesh *mesh, Span<MVert> verts, Span<MLoop> loops, const float size_x, const float size_y)
{
- MeshComponent mesh_component;
- mesh_component.replace(mesh, GeometryOwnershipType::Editable);
- OutputAttribute_Typed<float2> uv_attribute =
- mesh_component.attribute_try_get_for_output_only<float2>("uv_map", ATTR_DOMAIN_CORNER);
- MutableSpan<float2> uvs = uv_attribute.as_span();
+ MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*mesh);
+
+ SpanAttributeWriter<float2> uv_attribute = attributes.lookup_or_add_for_write_only_span<float2>(
+ "uv_map", ATTR_DOMAIN_CORNER);
const float dx = (size_x == 0.0f) ? 0.0f : 1.0f / size_x;
const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y;
threading::parallel_for(loops.index_range(), 1024, [&](IndexRange range) {
for (const int i : range) {
const float3 &co = verts[loops[i].v].co;
- uvs[i].x = (co.x + size_x * 0.5f) * dx;
- uvs[i].y = (co.y + size_y * 0.5f) * dy;
+ uv_attribute.span[i].x = (co.x + size_x * 0.5f) * dx;
+ uv_attribute.span[i].y = (co.y + size_y * 0.5f) * dy;
}
});
- uv_attribute.save();
+ uv_attribute.finish();
}
Mesh *create_grid_mesh(const int verts_x,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
index 4e0e5c7c912..f78752387c6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
@@ -220,11 +220,11 @@ static void calculate_sphere_faces(MutableSpan<MLoop> loops,
static void calculate_sphere_uvs(Mesh *mesh, const float segments, const float rings)
{
- MeshComponent mesh_component;
- mesh_component.replace(mesh, GeometryOwnershipType::Editable);
- OutputAttribute_Typed<float2> uv_attribute =
- mesh_component.attribute_try_get_for_output_only<float2>("uv_map", ATTR_DOMAIN_CORNER);
- MutableSpan<float2> uvs = uv_attribute.as_span();
+ MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*mesh);
+
+ SpanAttributeWriter<float2> uv_attribute = attributes.lookup_or_add_for_write_only_span<float2>(
+ "uv_map", ATTR_DOMAIN_CORNER);
+ MutableSpan<float2> uvs = uv_attribute.span;
int loop_index = 0;
const float dy = 1.0f / rings;
@@ -254,7 +254,7 @@ static void calculate_sphere_uvs(Mesh *mesh, const float segments, const float r
uvs[loop_index++] = float2(segment / segments, 1.0f - dy);
}
- uv_attribute.save();
+ uv_attribute.finish();
}
static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const int rings)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
index ec6acf55dd8..f6ee3d00dee 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
@@ -25,7 +25,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const MeshComponent &component = *geometry_set.get_component_for_read<MeshComponent>();
GeometryComponentFieldContext context{component, ATTR_DOMAIN_EDGE};
- fn::FieldEvaluator evaluator{context, component.attribute_domain_num(ATTR_DOMAIN_EDGE)};
+ fn::FieldEvaluator evaluator{context, component.attribute_domain_size(ATTR_DOMAIN_EDGE)};
evaluator.add(params.get_input<Field<bool>>("Selection"));
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_as_mask(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
index 7463eb01471..8e621d3ed97 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
@@ -66,7 +66,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
return;
}
GeometryComponentFieldContext field_context{*mesh_component, domain};
- const int domain_num = mesh_component->attribute_domain_num(domain);
+ const int domain_num = mesh_component->attribute_domain_size(domain);
if (domain_num == 0) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
return;
@@ -83,20 +83,20 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
geometry_set.replace_pointcloud(pointcloud);
- PointCloudComponent &point_component =
- geometry_set.get_component_for_write<PointCloudComponent>();
+ MutableAttributeAccessor pointcloud_attributes = bke::pointcloud_attributes_for_write(
+ *pointcloud);
- OutputAttribute position = point_component.attribute_try_get_for_output_only(
+ GSpanAttributeWriter position = pointcloud_attributes.lookup_or_add_for_write_only_span(
"position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
materialize_compressed_to_uninitialized_threaded(
- evaluator.get_evaluated(0), selection, position.as_span());
- position.save();
+ evaluator.get_evaluated(0), selection, position.span);
+ position.finish();
- OutputAttribute radius = point_component.attribute_try_get_for_output_only(
+ GSpanAttributeWriter radius = pointcloud_attributes.lookup_or_add_for_write_only_span(
"radius", ATTR_DOMAIN_POINT, CD_PROP_FLOAT);
materialize_compressed_to_uninitialized_threaded(
- evaluator.get_evaluated(1), selection, radius.as_span());
- radius.save();
+ evaluator.get_evaluated(1), selection, radius.span);
+ radius.finish();
Map<AttributeIDRef, AttributeKind> attributes;
geometry_set.gather_attributes_for_propagation(
@@ -106,12 +106,12 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
const eCustomDataType data_type = entry.value.data_type;
- GVArray src = mesh_component->attribute_get_for_read(attribute_id, domain, data_type);
- OutputAttribute dst = point_component.attribute_try_get_for_output_only(
+ GVArray src = mesh_component->attributes()->lookup_or_default(attribute_id, domain, data_type);
+ GSpanAttributeWriter dst = pointcloud_attributes.lookup_or_add_for_write_only_span(
attribute_id, ATTR_DOMAIN_POINT, data_type);
if (dst && src) {
- materialize_compressed_to_uninitialized_threaded(src, selection, dst.as_span());
- dst.save();
+ materialize_compressed_to_uninitialized_threaded(src, selection, dst.span);
+ dst.finish();
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points.cc b/source/blender/nodes/geometry/nodes/node_geo_points.cc
index da414960e1d..dd32e6714f4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points.cc
@@ -72,19 +72,20 @@ static void node_geo_exec(GeoNodeExecParams params)
PointCloud *new_point_cloud = BKE_pointcloud_new_nomain(count);
GeometrySet geometry_set = GeometrySet::create_with_pointcloud(new_point_cloud);
PointCloudComponent &points = geometry_set.get_component_for_write<PointCloudComponent>();
- OutputAttribute_Typed<float3> output_position = points.attribute_try_get_for_output_only<float3>(
+ MutableAttributeAccessor attributes = *points.attributes_for_write();
+ AttributeWriter<float3> output_position = attributes.lookup_or_add_for_write<float3>(
"position", ATTR_DOMAIN_POINT);
- OutputAttribute_Typed<float> output_radii = points.attribute_try_get_for_output_only<float>(
+ AttributeWriter<float> output_radii = attributes.lookup_or_add_for_write<float>(
"radius", ATTR_DOMAIN_POINT);
PointsFieldContext context{count};
fn::FieldEvaluator evaluator{context, count};
- evaluator.add_with_destination(position_field, output_position.as_span());
- evaluator.add_with_destination(radius_field, output_radii.as_span());
+ evaluator.add_with_destination(position_field, output_position.varray);
+ evaluator.add_with_destination(radius_field, output_radii.varray);
evaluator.evaluate();
- output_position.save();
- output_radii.save();
+ output_position.finish();
+ output_radii.finish();
params.set_output("Geometry", std::move(geometry_set));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
index 95ff53b7146..9cc64d4bc44 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
@@ -38,7 +38,7 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
}
GeometryComponentFieldContext field_context{*point_component, ATTR_DOMAIN_POINT};
- const int domain_num = point_component->attribute_domain_num(ATTR_DOMAIN_POINT);
+ const int domain_num = point_component->attribute_domain_size(ATTR_DOMAIN_POINT);
if (domain_num == 0) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
return;
@@ -60,18 +60,19 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
const eCustomDataType data_type = entry.value.data_type;
- GVArray src = point_component->attribute_get_for_read(
- attribute_id, ATTR_DOMAIN_POINT, data_type);
- OutputAttribute dst = mesh_component.attribute_try_get_for_output_only(
+ GVArray src = point_component->attributes()->lookup_or_default(
attribute_id, ATTR_DOMAIN_POINT, data_type);
+ GSpanAttributeWriter dst =
+ mesh_component.attributes_for_write()->lookup_or_add_for_write_only_span(
+ attribute_id, ATTR_DOMAIN_POINT, data_type);
if (dst && src) {
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray<T> src_typed = src.typed<T>();
VArraySpan<T> src_typed_span{src_typed};
- copy_attribute_to_vertices(src_typed_span, selection, dst.as_span().typed<T>());
+ copy_attribute_to_vertices(src_typed_span, selection, dst.span.typed<T>());
});
- dst.save();
+ dst.finish();
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
index 42cee4c0efe..28a01a5cbce 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
@@ -163,12 +163,15 @@ static void gather_point_data_from_component(GeoNodeExecParams &params,
Vector<float3> &r_positions,
Vector<float> &r_radii)
{
- VArray<float3> positions = component.attribute_get_for_read<float3>(
+ if (component.is_empty()) {
+ return;
+ }
+ VArray<float3> positions = component.attributes()->lookup_or_default<float3>(
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
Field<float> radius_field = params.get_input<Field<float>>("Radius");
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ const int domain_num = component.attribute_domain_size(ATTR_DOMAIN_POINT);
r_positions.resize(r_positions.size() + domain_num);
positions.materialize(r_positions.as_mutable_span().take_back(domain_num));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
index a92cee2d066..f81748da587 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
@@ -312,8 +312,8 @@ class RaycastFunction : public fn::MultiFunction {
}
const MeshComponent &mesh_component = *target_.get_component_for_read<MeshComponent>();
target_context_.emplace(GeometryComponentFieldContext{mesh_component, domain_});
- const int domain_num = mesh_component.attribute_domain_num(domain_);
- target_evaluator_ = std::make_unique<FieldEvaluator>(*target_context_, domain_num);
+ const int domain_size = mesh_component.attribute_domain_size(domain_);
+ target_evaluator_ = std::make_unique<FieldEvaluator>(*target_context_, domain_size);
target_evaluator_->add(std::move(src_field));
target_evaluator_->evaluate();
target_data_ = &target_evaluator_->get_evaluated(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc
index da42b8c5ee0..ee279ba58f9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc
@@ -39,7 +39,7 @@ static void node_geo_exec(GeoNodeExecParams params)
/* First check if the attribute exists before getting write access,
* to avoid potentially expensive unnecessary copies. */
const GeometryComponent &read_only_component = *geometry_set.get_component_for_read(type);
- if (read_only_component.attribute_exists(name)) {
+ if (read_only_component.attributes()->contains(name)) {
attribute_exists = true;
}
else {
@@ -47,7 +47,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
GeometryComponent &component = geometry_set.get_component_for_write(type);
- if (!component.attribute_try_delete(name)) {
+ if (!component.attributes_for_write()->remove(name)) {
cannot_delete = true;
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
index 37533a7b99a..fc3cb7006bb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
@@ -75,12 +75,12 @@ static void set_position_in_component(CurveComponent &component,
const Field<float3> &offset_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
evaluator.add(position_field);
evaluator.add(offset_field);
@@ -146,8 +146,8 @@ static void node_geo_exec(GeoNodeExecParams params)
}
has_curves = true;
const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>();
- if (!component.attribute_exists("handle_left") ||
- !component.attribute_exists("handle_right")) {
+ const AttributeAccessor attributes = *component.attributes();
+ if (!attributes.contains("handle_left") || !attributes.contains("handle_right")) {
return;
}
has_bezier = true;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
index 4c84093bfcb..90411baac3e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
@@ -20,21 +20,22 @@ static void set_radius_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<float> &radius_field)
{
- GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
- "radius", ATTR_DOMAIN_POINT);
+ AttributeWriter<float> radii = attributes.lookup_or_add_for_write<float>("radius",
+ ATTR_DOMAIN_POINT);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(radius_field, radii.varray());
+ evaluator.add_with_destination(radius_field, radii.varray);
evaluator.evaluate();
- radii.save();
+ radii.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
index 8b1e5935a61..2211ac62727 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
@@ -16,21 +16,23 @@ static void set_tilt_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<float> &tilt_field)
{
- GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- OutputAttribute_Typed<float> tilts = component.attribute_try_get_for_output_only<float>(
- "tilt", ATTR_DOMAIN_POINT);
+ AttributeWriter<float> tilts = attributes.lookup_or_add_for_write<float>("tilt",
+ ATTR_DOMAIN_POINT);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(tilt_field, tilts.varray());
+ evaluator.add_with_destination(tilt_field, tilts.varray);
evaluator.evaluate();
- tilts.save();
+ tilts.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
index a7f17c02ce8..fbb2ecbb799 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
@@ -19,34 +19,34 @@ static void set_id_in_component(GeometryComponent &component,
const eAttrDomain domain = (component.type() == GEO_COMPONENT_TYPE_INSTANCES) ?
ATTR_DOMAIN_INSTANCE :
ATTR_DOMAIN_POINT;
- GeometryComponentFieldContext field_context{component, domain};
- const int domain_num = component.attribute_domain_num(domain);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(domain);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ GeometryComponentFieldContext field_context{component, domain};
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
/* Since adding the ID attribute can change the result of the field evaluation (the random value
* node uses the index if the ID is unavailable), make sure that it isn't added before evaluating
* the field. However, as an optimization, use a faster code path when it already exists. */
- if (component.attribute_exists("id")) {
- OutputAttribute_Typed<int> id_attribute = component.attribute_try_get_for_output_only<int>(
- "id", domain);
- evaluator.add_with_destination(id_field, id_attribute.varray());
+ if (attributes.contains("id")) {
+ AttributeWriter<int> id_attribute = attributes.lookup_or_add_for_write<int>("id", domain);
+ evaluator.add_with_destination(id_field, id_attribute.varray);
evaluator.evaluate();
- id_attribute.save();
+ id_attribute.finish();
}
else {
evaluator.add(id_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
const VArray<int> result_ids = evaluator.get_evaluated<int>(0);
- OutputAttribute_Typed<int> id_attribute = component.attribute_try_get_for_output_only<int>(
- "id", domain);
- result_ids.materialize(selection, id_attribute.as_span());
- id_attribute.save();
+ SpanAttributeWriter<int> id_attribute = attributes.lookup_or_add_for_write_span<int>("id",
+ domain);
+ result_ids.materialize(selection, id_attribute.span);
+ id_attribute.finish();
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
index 58613dae832..0dc89bb7ef4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
@@ -16,20 +16,21 @@ static void set_material_index_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<int> &index_field)
{
- GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
- OutputAttribute_Typed<int> indices = component.attribute_try_get_for_output_only<int>(
- "material_index", ATTR_DOMAIN_FACE);
+ AttributeWriter<int> indices = attributes.lookup_or_add_for_write<int>("material_index",
+ ATTR_DOMAIN_FACE);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(index_field, indices.varray());
+ evaluator.add_with_destination(index_field, indices.varray);
evaluator.evaluate();
- indices.save();
+ indices.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
index 571bead9743..da7977a4fb4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
@@ -20,21 +20,22 @@ static void set_radius_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<float> &radius_field)
{
- GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_POINT);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
- OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
- "radius", ATTR_DOMAIN_POINT);
+ AttributeWriter<float> radii = attributes.lookup_or_add_for_write<float>("radius",
+ ATTR_DOMAIN_POINT);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(radius_field, radii.varray());
+ evaluator.add_with_destination(radius_field, radii.varray);
evaluator.evaluate();
- radii.save();
+ radii.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
index 1935409b3e5..880252de4fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
@@ -25,12 +25,10 @@ static void node_declare(NodeDeclarationBuilder &b)
static void set_computed_position_and_offset(GeometryComponent &component,
const VArray<float3> &in_positions,
const VArray<float3> &in_offsets,
- const eAttrDomain domain,
const IndexMask selection)
{
-
- OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
- "position", domain, {0, 0, 0});
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ AttributeWriter<float3> positions = attributes.lookup_for_write<float3>("position");
const int grain_size = 10000;
@@ -38,7 +36,7 @@ static void set_computed_position_and_offset(GeometryComponent &component,
case GEO_COMPONENT_TYPE_MESH: {
Mesh *mesh = static_cast<MeshComponent &>(component).get_for_write();
MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert};
- if (in_positions.is_same(positions.varray())) {
+ if (in_positions.is_same(positions.varray)) {
devirtualize_varray(in_offsets, [&](const auto in_offsets) {
threading::parallel_for(
selection.index_range(), grain_size, [&](const IndexRange range) {
@@ -67,18 +65,13 @@ static void set_computed_position_and_offset(GeometryComponent &component,
CurveComponent &curve_component = static_cast<CurveComponent &>(component);
Curves &curves_id = *curve_component.get_for_write();
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- if (component.attribute_exists("handle_right") &&
- component.attribute_exists("handle_left")) {
- OutputAttribute_Typed<float3> handle_right_attribute =
- component.attribute_try_get_for_output<float3>(
- "handle_right", ATTR_DOMAIN_POINT, {0, 0, 0});
- OutputAttribute_Typed<float3> handle_left_attribute =
- component.attribute_try_get_for_output<float3>(
- "handle_left", ATTR_DOMAIN_POINT, {0, 0, 0});
- MutableSpan<float3> handle_right = handle_right_attribute.as_span();
- MutableSpan<float3> handle_left = handle_left_attribute.as_span();
-
- MutableSpan<float3> out_positions_span = positions.as_span();
+ if (attributes.contains("handle_right") && attributes.contains("handle_left")) {
+ SpanAttributeWriter<float3> handle_right_attribute =
+ attributes.lookup_or_add_for_write_span<float3>("handle_right", ATTR_DOMAIN_POINT);
+ SpanAttributeWriter<float3> handle_left_attribute =
+ attributes.lookup_or_add_for_write_span<float3>("handle_left", ATTR_DOMAIN_POINT);
+
+ MutableVArraySpan<float3> out_positions_span = positions.varray;
devirtualize_varray2(
in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) {
threading::parallel_for(
@@ -86,15 +79,16 @@ static void set_computed_position_and_offset(GeometryComponent &component,
for (const int i : selection.slice(range)) {
const float3 new_position = in_positions[i] + in_offsets[i];
const float3 delta = new_position - out_positions_span[i];
- handle_right[i] += delta;
- handle_left[i] += delta;
+ handle_right_attribute.span[i] += delta;
+ handle_left_attribute.span[i] += delta;
out_positions_span[i] = new_position;
}
});
});
- handle_right_attribute.save();
- handle_left_attribute.save();
+ out_positions_span.save();
+ handle_right_attribute.finish();
+ handle_left_attribute.finish();
/* Automatic Bezier handles must be recalculated based on the new positions. */
curves.calculate_bezier_auto_handles();
@@ -105,8 +99,8 @@ static void set_computed_position_and_offset(GeometryComponent &component,
}
}
default: {
- MutableSpan<float3> out_positions_span = positions.as_span();
- if (in_positions.is_same(positions.varray())) {
+ MutableVArraySpan<float3> out_positions_span = positions.varray;
+ if (in_positions.is_same(positions.varray)) {
devirtualize_varray(in_offsets, [&](const auto in_offsets) {
threading::parallel_for(
selection.index_range(), grain_size, [&](const IndexRange range) {
@@ -127,11 +121,12 @@ static void set_computed_position_and_offset(GeometryComponent &component,
});
});
}
+ out_positions_span.save();
break;
}
}
- positions.save();
+ positions.finish();
}
static void set_position_in_component(GeometryComponent &component,
@@ -142,21 +137,22 @@ static void set_position_in_component(GeometryComponent &component,
eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE :
ATTR_DOMAIN_POINT;
GeometryComponentFieldContext field_context{component, domain};
- const int domain_num = component.attribute_domain_num(domain);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(domain);
+ if (domain_size == 0) {
return;
}
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
evaluator.add(position_field);
evaluator.add(offset_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+
const VArray<float3> positions_input = evaluator.get_evaluated<float3>(0);
const VArray<float3> offsets_input = evaluator.get_evaluated<float3>(1);
- set_computed_position_and_offset(component, positions_input, offsets_input, domain, selection);
+ set_computed_position_and_offset(component, positions_input, offsets_input, selection);
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
index b98fbd0a0fe..e0cf0f98d58 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
@@ -16,21 +16,23 @@ static void set_smooth_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<bool> &shade_field)
{
- GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
- OutputAttribute_Typed<bool> shades = component.attribute_try_get_for_output_only<bool>(
- "shade_smooth", ATTR_DOMAIN_FACE);
+ AttributeWriter<bool> shades = attributes.lookup_or_add_for_write<bool>("shade_smooth",
+ ATTR_DOMAIN_FACE);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(shade_field, shades.varray());
+ evaluator.add_with_destination(shade_field, shades.varray);
evaluator.evaluate();
- shades.save();
+ shades.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
index 976857883f0..a35d8d66558 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
@@ -16,21 +16,23 @@ static void set_cyclic_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<bool> &cyclic_field)
{
- GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- OutputAttribute_Typed<bool> cyclics = component.attribute_try_get_for_output_only<bool>(
- "cyclic", ATTR_DOMAIN_CURVE);
+ AttributeWriter<bool> cyclics = attributes.lookup_or_add_for_write<bool>("cyclic",
+ ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(cyclic_field, cyclics.varray());
+ evaluator.add_with_destination(cyclic_field, cyclics.varray);
evaluator.evaluate();
- cyclics.save();
+ cyclics.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
index 8b665376c01..fcebc1116d7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
@@ -16,21 +16,23 @@ static void set_resolution_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<int> &resolution_field)
{
- GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_CURVE);
- if (domain_num == 0) {
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
+ if (domain_size == 0) {
return;
}
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
- OutputAttribute_Typed<int> resolutions = component.attribute_try_get_for_output_only<int>(
- "resolution", ATTR_DOMAIN_CURVE);
+ AttributeWriter<int> resolutions = attributes.lookup_or_add_for_write<int>("resolution",
+ ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator evaluator{field_context, domain_num};
+ fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(resolution_field, resolutions.varray());
+ evaluator.add_with_destination(resolution_field, resolutions.varray);
evaluator.evaluate();
- resolutions.save();
+ resolutions.finish();
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
index abac6d8d6b3..69a4fad10e2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
@@ -87,9 +87,14 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
const eAttrDomain domain,
const GField &field)
{
+ const int domain_size = component.attribute_domain_size(domain);
+ if (domain_size == 0) {
+ return;
+ }
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+
GeometryComponentFieldContext field_context{component, domain};
- const int domain_num = component.attribute_domain_num(domain);
- const IndexMask mask{IndexMask(domain_num)};
+ const IndexMask mask{IndexMask(domain_size)};
const CPPType &type = field.cpp_type();
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(type);
@@ -97,28 +102,28 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
/* Could avoid allocating a new buffer if:
* - We are writing to an attribute that exists already.
* - The field does not depend on that attribute (we can't easily check for that yet). */
- void *buffer = MEM_mallocN(type.size() * domain_num, __func__);
+ void *buffer = MEM_mallocN(type.size() * domain_size, __func__);
fn::FieldEvaluator evaluator{field_context, &mask};
- evaluator.add_with_destination(field, GMutableSpan{type, buffer, domain_num});
+ evaluator.add_with_destination(field, GMutableSpan{type, buffer, domain_size});
evaluator.evaluate();
- component.attribute_try_delete(name);
- if (component.attribute_exists(name)) {
- WriteAttributeLookup write_attribute = component.attribute_try_get_for_write(name);
+ attributes.remove(name);
+ if (attributes.contains(name)) {
+ GAttributeWriter write_attribute = attributes.lookup_for_write(name);
if (write_attribute && write_attribute.domain == domain &&
write_attribute.varray.type() == type) {
write_attribute.varray.set_all(buffer);
- write_attribute.tag_modified_fn();
+ write_attribute.finish();
}
else {
/* Cannot change type of built-in attribute. */
}
- type.destruct_n(buffer, domain_num);
+ type.destruct_n(buffer, domain_size);
MEM_freeN(buffer);
}
else {
- if (!component.attribute_try_create(name, domain, data_type, AttributeInitMove{buffer})) {
+ if (!attributes.add(name, domain, data_type, bke::AttributeInitMove{buffer})) {
MEM_freeN(buffer);
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
index 94d5d7f946f..afd7db6604d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
@@ -335,13 +335,14 @@ static void create_attributes(GeoNodeExecParams &params,
const TextLayout &layout,
InstancesComponent &instances)
{
+ MutableAttributeAccessor attributes = *instances.attributes_for_write();
+
if (params.output_is_required("Line")) {
StrongAnonymousAttributeID line_id = StrongAnonymousAttributeID("Line");
- OutputAttribute_Typed<int> line_attribute = instances.attribute_try_get_for_output_only<int>(
+ SpanAttributeWriter<int> line_attribute = attributes.lookup_or_add_for_write_only_span<int>(
line_id.get(), ATTR_DOMAIN_INSTANCE);
- MutableSpan<int> lines = line_attribute.as_span();
- lines.copy_from(layout.line_numbers);
- line_attribute.save();
+ line_attribute.span.copy_from(layout.line_numbers);
+ line_attribute.finish();
params.set_output("Line",
AnonymousAttributeFieldInput::Create<int>(std::move(line_id),
params.attribute_producer_name()));
@@ -349,15 +350,14 @@ static void create_attributes(GeoNodeExecParams &params,
if (params.output_is_required("Pivot Point")) {
StrongAnonymousAttributeID pivot_id = StrongAnonymousAttributeID("Pivot");
- OutputAttribute_Typed<float3> pivot_attribute =
- instances.attribute_try_get_for_output_only<float3>(pivot_id.get(), ATTR_DOMAIN_INSTANCE);
- MutableSpan<float3> pivots = pivot_attribute.as_span();
+ SpanAttributeWriter<float3> pivot_attribute =
+ attributes.lookup_or_add_for_write_only_span<float3>(pivot_id.get(), ATTR_DOMAIN_INSTANCE);
for (const int i : layout.char_codes.index_range()) {
- pivots[i] = layout.pivot_points.lookup(layout.char_codes[i]);
+ pivot_attribute.span[i] = layout.pivot_points.lookup(layout.char_codes[i]);
}
- pivot_attribute.save();
+ pivot_attribute.finish();
params.set_output("Pivot Point",
AnonymousAttributeFieldInput::Create<float3>(
std::move(pivot_id), params.attribute_producer_name()));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
index 9eda5bb34ff..eda6a51d412 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -6,6 +6,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
+#include "BKE_attribute.hh"
#include "BKE_mesh.h"
#include "BKE_subdiv.h"
#include "BKE_subdiv_mesh.h"
@@ -79,10 +80,11 @@ static void write_vertex_creases(Mesh &mesh, const VArray<float> &crease_varray)
static void write_edge_creases(MeshComponent &mesh, const VArray<float> &crease_varray)
{
- OutputAttribute_Typed<float> attribute = mesh.attribute_try_get_for_output_only<float>(
- "crease", ATTR_DOMAIN_EDGE);
- materialize_and_clamp_creases(crease_varray, attribute.as_span());
- attribute.save();
+ bke::SpanAttributeWriter<float> attribute =
+ mesh.attributes_for_write()->lookup_or_add_for_write_only_span<float>("crease",
+ ATTR_DOMAIN_EDGE);
+ materialize_and_clamp_creases(crease_varray, attribute.span);
+ attribute.finish();
}
static bool varray_is_nonzero(const VArray<float> &varray)
@@ -118,8 +120,8 @@ static void node_geo_exec(GeoNodeExecParams params)
}
const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>();
- const int verts_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
- const int edges_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_EDGE);
+ const int verts_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ const int edges_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_EDGE);
if (verts_num == 0 || edges_num == 0) {
return;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
index 0af6c76feaf..cd75822f665 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
@@ -365,7 +365,7 @@ static bool component_is_available(const GeometrySet &geometry,
if (component.is_empty()) {
return false;
}
- return component.attribute_domain_num(domain) != 0;
+ return component.attribute_domain_size(domain) != 0;
}
/**
@@ -433,7 +433,7 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction {
{
const MeshComponent &mesh_component = *source_.get_component_for_read<MeshComponent>();
source_context_.emplace(GeometryComponentFieldContext{mesh_component, domain_});
- const int domain_num = mesh_component.attribute_domain_num(domain_);
+ const int domain_num = mesh_component.attribute_domain_size(domain_);
source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_num);
source_evaluator_->add(src_field_);
source_evaluator_->evaluate();
@@ -578,7 +578,7 @@ class NearestTransferFunction : public fn::MultiFunction {
{
if (use_mesh_) {
const MeshComponent &mesh = *source_.get_component_for_read<MeshComponent>();
- const int domain_num = mesh.attribute_domain_num(domain_);
+ const int domain_num = mesh.attribute_domain_size(domain_);
mesh_context_.emplace(GeometryComponentFieldContext(mesh, domain_));
mesh_evaluator_ = std::make_unique<FieldEvaluator>(*mesh_context_, domain_num);
mesh_evaluator_->add(src_field_);
@@ -588,7 +588,7 @@ class NearestTransferFunction : public fn::MultiFunction {
if (use_points_) {
const PointCloudComponent &points = *source_.get_component_for_read<PointCloudComponent>();
- const int domain_num = points.attribute_domain_num(domain_);
+ const int domain_num = points.attribute_domain_size(domain_);
point_context_.emplace(GeometryComponentFieldContext(points, domain_));
point_evaluator_ = std::make_unique<FieldEvaluator>(*point_context_, domain_num);
point_evaluator_->add(src_field_);
@@ -658,7 +658,7 @@ class IndexTransferFunction : public fn::MultiFunction {
if (component == nullptr) {
return;
}
- const int domain_num = component->attribute_domain_num(domain_);
+ const int domain_num = component->attribute_domain_size(domain_);
geometry_context_.emplace(GeometryComponentFieldContext(*component, domain_));
evaluator_ = std::make_unique<FieldEvaluator>(*geometry_context_, domain_num);
evaluator_->add(src_field_);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
index e47dc22da04..992470e8279 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
@@ -83,9 +83,9 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometryComponent &component = geometry_set.get_component_for_write<MeshComponent>();
const Mesh &mesh_in = *geometry_set.get_mesh_for_read();
- const int domain_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE);
GeometryComponentFieldContext context{component, ATTR_DOMAIN_FACE};
- FieldEvaluator evaluator{context, domain_num};
+ FieldEvaluator evaluator{context, domain_size};
evaluator.add(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_as_mask(0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
index feff6efc3f8..17413e64f7d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
@@ -40,7 +40,7 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component,
return {};
}
- const int face_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
+ const int face_num = component.attribute_domain_size(ATTR_DOMAIN_FACE);
GeometryComponentFieldContext face_context{component, ATTR_DOMAIN_FACE};
FieldEvaluator face_evaluator{face_context, face_num};
face_evaluator.add(selection_field);
@@ -50,7 +50,7 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component,
return {};
}
- const int corner_num = component.attribute_domain_num(ATTR_DOMAIN_CORNER);
+ const int corner_num = component.attribute_domain_size(ATTR_DOMAIN_CORNER);
GeometryComponentFieldContext corner_context{component, ATTR_DOMAIN_CORNER};
FieldEvaluator evaluator{corner_context, corner_num};
Array<float3> uv(corner_num);
@@ -88,7 +88,7 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component,
GEO_uv_parametrizer_flush(handle);
GEO_uv_parametrizer_delete(handle);
- return component.attribute_try_adapt_domain<float3>(
+ return component.attributes()->adapt_domain<float3>(
VArray<float3>::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
index 364106455b6..2ec14ad2d29 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
@@ -65,7 +65,7 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component,
return {};
}
- const int face_num = component.attribute_domain_num(ATTR_DOMAIN_FACE);
+ const int face_num = component.attribute_domain_size(ATTR_DOMAIN_FACE);
GeometryComponentFieldContext face_context{component, ATTR_DOMAIN_FACE};
FieldEvaluator face_evaluator{face_context, face_num};
face_evaluator.add(selection_field);
@@ -75,7 +75,7 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component,
return {};
}
- const int edge_num = component.attribute_domain_num(ATTR_DOMAIN_EDGE);
+ const int edge_num = component.attribute_domain_size(ATTR_DOMAIN_EDGE);
GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE};
FieldEvaluator edge_evaluator{edge_context, edge_num};
edge_evaluator.add(seam_field);
@@ -126,7 +126,7 @@ static VArray<float3> construct_uv_gvarray(const MeshComponent &component,
GEO_uv_parametrizer_flush(handle);
GEO_uv_parametrizer_delete(handle);
- return component.attribute_try_adapt_domain<float3>(
+ return component.attributes()->adapt_domain<float3>(
VArray<float3>::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain);
}
diff --git a/source/blender/nodes/intern/geometry_nodes_eval_log.cc b/source/blender/nodes/intern/geometry_nodes_eval_log.cc
index 85dfdf03b82..cf7cbbdc4bf 100644
--- a/source/blender/nodes/intern/geometry_nodes_eval_log.cc
+++ b/source/blender/nodes/intern/geometry_nodes_eval_log.cc
@@ -228,7 +228,7 @@ GeometryValueLog::GeometryValueLog(const GeometrySet &geometry_set, bool log_ful
all_component_types,
true,
[&](const bke::AttributeIDRef &attribute_id,
- const AttributeMetaData &meta_data,
+ const bke::AttributeMetaData &meta_data,
const GeometryComponent &UNUSED(component)) {
if (attribute_id.is_named() && names.add(attribute_id.name())) {
this->attributes_.append({attribute_id.name(), meta_data.domain, meta_data.data_type});
@@ -241,21 +241,21 @@ GeometryValueLog::GeometryValueLog(const GeometrySet &geometry_set, bool log_ful
case GEO_COMPONENT_TYPE_MESH: {
const MeshComponent &mesh_component = *(const MeshComponent *)component;
MeshInfo &info = this->mesh_info.emplace();
- info.verts_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_POINT);
- info.edges_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_EDGE);
- info.faces_num = mesh_component.attribute_domain_num(ATTR_DOMAIN_FACE);
+ info.verts_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ info.edges_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_EDGE);
+ info.faces_num = mesh_component.attribute_domain_size(ATTR_DOMAIN_FACE);
break;
}
case GEO_COMPONENT_TYPE_CURVE: {
const CurveComponent &curve_component = *(const CurveComponent *)component;
CurveInfo &info = this->curve_info.emplace();
- info.splines_num = curve_component.attribute_domain_num(ATTR_DOMAIN_CURVE);
+ info.splines_num = curve_component.attribute_domain_size(ATTR_DOMAIN_CURVE);
break;
}
case GEO_COMPONENT_TYPE_POINT_CLOUD: {
const PointCloudComponent &pointcloud_component = *(const PointCloudComponent *)component;
PointCloudInfo &info = this->pointcloud_info.emplace();
- info.points_num = pointcloud_component.attribute_domain_num(ATTR_DOMAIN_POINT);
+ info.points_num = pointcloud_component.attribute_domain_size(ATTR_DOMAIN_POINT);
break;
}
case GEO_COMPONENT_TYPE_INSTANCES: {