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/geometry/nodes')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc3
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc47
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc4
16 files changed, 123 insertions, 47 deletions
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 0169ead5bd2..040ebf55ec5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -19,6 +19,8 @@ static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (!geometry_set.has_curves()) {
return;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
index ba7985f26bc..c1f631a86fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
@@ -309,6 +309,7 @@ class SampleCurveFunction : public fn::MultiFunction {
if (curves.points_num() == 0) {
return return_default();
}
+ curves.ensure_can_interpolate_to_evaluated();
Span<float3> evaluated_positions = curves.evaluated_positions();
Span<float3> evaluated_tangents;
Span<float3> evaluated_normals;
@@ -527,29 +528,33 @@ static void node_geo_exec(GeoNodeExecParams params)
mode == GEO_NODE_CURVE_SAMPLE_FACTOR ? "Factor" : "Length");
GField src_values_field = get_input_attribute_field(params, data_type);
- auto sample_fn = std::make_unique<SampleCurveFunction>(
- std::move(geometry_set), mode, std::move(src_values_field));
-
std::shared_ptr<FieldOperation> sample_op;
if (curves.curves_num() == 1) {
- sample_op = FieldOperation::Create(std::move(sample_fn),
- {fn::make_constant_field<int>(0), std::move(length_field)});
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), mode, std::move(src_values_field)),
+ {fn::make_constant_field<int>(0), std::move(length_field)});
}
else {
- Field<int> curve_index;
- Field<float> length_in_curve;
if (storage.use_all_curves) {
auto index_fn = std::make_unique<SampleFloatSegmentsFunction>(
curve_accumulated_lengths(curves), mode);
auto index_op = FieldOperation::Create(std::move(index_fn), {std::move(length_field)});
- curve_index = Field<int>(index_op, 0);
- length_in_curve = Field<float>(index_op, 1);
+ Field<int> curve_index = Field<int>(index_op, 0);
+ Field<float> length_in_curve = Field<float>(index_op, 1);
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), GEO_NODE_CURVE_SAMPLE_LENGTH, std::move(src_values_field)),
+ {std::move(curve_index), std::move(length_in_curve)});
}
else {
- curve_index = params.extract_input<Field<int>>("Curve Index");
- length_in_curve = std::move(length_field);
+ Field<int> curve_index = params.extract_input<Field<int>>("Curve Index");
+ Field<float> length_in_curve = std::move(length_field);
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), mode, std::move(src_values_field)),
+ {std::move(curve_index), std::move(length_in_curve)});
}
- sample_op = FieldOperation::Create(std::move(sample_fn), {curve_index, length_in_curve});
}
params.set_output("Position", Field<float3>(sample_op, 0));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
index 3dc89a9058e..159a4661df0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
@@ -117,9 +117,8 @@ static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry
threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) {
for (const int i_curve : range) {
- const float total_length = curves.evaluated_length_total_for_curve(i_curve,
- cyclic[i_curve]);
MutableSpan<float> curve_lengths = lengths.slice(curves.points_for_curve(i_curve));
+ const float total_length = curve_lengths.last();
if (total_length > 0.0f) {
const float factor = 1.0f / total_length;
for (float &value : curve_lengths) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
index 4d60ab939ca..459f45ef8fb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
@@ -48,6 +48,11 @@ class CurveOfPointInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class PointIndexInCurveInput final : public bke::CurvesFieldInput {
@@ -86,6 +91,11 @@ class PointIndexInCurveInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/)
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
index 9f3d3c2caf3..7f69503831f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
@@ -113,6 +113,11 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
};
class CurvePointCountInput final : public bke::CurvesFieldInput {
@@ -146,6 +151,11 @@ class CurvePointCountInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
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 3ec71877b7c..b0c2f3117fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -19,6 +19,7 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveTrim)
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
+ b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_input<decl::Float>(N_("Start"))
.min(0.0f)
.max(1.0f)
@@ -64,7 +65,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryCurveTrim &storage = node_storage(*node);
const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
- bNodeSocket *start_fac = static_cast<bNodeSocket *>(node->inputs.first)->next;
+ bNodeSocket *start_fac = static_cast<bNodeSocket *>(node->inputs.first)->next->next;
bNodeSocket *end_fac = start_fac->next;
bNodeSocket *start_len = end_fac->next;
bNodeSocket *end_len = start_len->next;
@@ -109,6 +110,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void geometry_set_curve_trim(GeometrySet &geometry_set,
const GeometryNodeCurveSampleMode mode,
+ Field<bool> &selection_field,
Field<float> &start_field,
Field<float> &end_field)
{
@@ -123,41 +125,21 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()};
+ evaluator.add(selection_field);
evaluator.add(start_field);
evaluator.add(end_field);
evaluator.evaluate();
- const VArray<float> starts = evaluator.get_evaluated<float>(0);
- const VArray<float> ends = evaluator.get_evaluated<float>(1);
-
- const VArray<bool> cyclic = src_curves.cyclic();
-
- /* If node length input is on form [0, 1] instead of [0, length]*/
- const bool normalized_length_lookup = mode == GEO_NODE_CURVE_SAMPLE_FACTOR;
-
- /* Stack start + end field. */
- Vector<float> length_factors(src_curves.curves_num() * 2);
- Vector<int64_t> lookup_indices(src_curves.curves_num() * 2);
- threading::parallel_for(src_curves.curves_range(), 512, [&](IndexRange curve_range) {
- for (const int64_t curve_i : curve_range) {
- const bool negative_trim = !cyclic[curve_i] && starts[curve_i] > ends[curve_i];
- length_factors[curve_i] = starts[curve_i];
- length_factors[curve_i + src_curves.curves_num()] = negative_trim ? starts[curve_i] :
- ends[curve_i];
- lookup_indices[curve_i] = curve_i;
- lookup_indices[curve_i + src_curves.curves_num()] = curve_i;
- }
- });
- /* Create curve trim lookup table. */
- Array<bke::curves::CurvePoint, 12> point_lookups = geometry::lookup_curve_points(
- src_curves, length_factors, lookup_indices, normalized_length_lookup);
+ const IndexMask selection = evaluator.get_evaluated_as_mask(0);
+ const VArray<float> starts = evaluator.get_evaluated<float>(1);
+ const VArray<float> ends = evaluator.get_evaluated<float>(2);
- bke::CurvesGeometry dst_curves = geometry::trim_curves(
- src_curves,
- src_curves.curves_range().as_span(),
- point_lookups.as_span().slice(0, src_curves.curves_num()),
- point_lookups.as_span().slice(src_curves.curves_num(), src_curves.curves_num()));
+ if (selection.is_empty()) {
+ return;
+ }
+ bke::CurvesGeometry dst_curves = geometry::trim_curves(
+ src_curves, selection, starts, ends, mode);
Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
bke::curves_copy_parameters(src_curves_id, *dst_curves_id);
geometry_set.replace_curves(dst_curves_id);
@@ -171,18 +153,19 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) {
Field<float> start_field = params.extract_input<Field<float>>("Start");
Field<float> end_field = params.extract_input<Field<float>>("End");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- geometry_set_curve_trim(geometry_set, mode, start_field, end_field);
+ geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field);
});
}
else if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
Field<float> start_field = params.extract_input<Field<float>>("Start_001");
Field<float> end_field = params.extract_input<Field<float>>("End_001");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- geometry_set_curve_trim(geometry_set, mode, start_field, end_field);
+ geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field);
});
}
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 4bb4618588b..5a42949d4c8 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
@@ -56,6 +56,11 @@ class SplineCountFieldInput final : public bke::CurvesFieldInput {
{
return dynamic_cast<const SplineCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
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 7e7b0eb215f..aa27fa70e64 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
@@ -110,6 +110,11 @@ class TangentFieldInput final : public bke::CurvesFieldInput {
{
return dynamic_cast<const TangentFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
index 94bca02640b..b464832409c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
@@ -117,6 +117,11 @@ class CornersOfFaceInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static int get_poly_totloop(const MPoly &poly)
@@ -153,6 +158,11 @@ class CornersOfFaceCountInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
index 036af2d3b93..c01c4149864 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
@@ -138,6 +138,11 @@ class CornersOfVertInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class CornersOfVertCountInput final : public bke::MeshFieldInput {
@@ -174,6 +179,11 @@ class CornersOfVertCountInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
index 84b560cb48a..e46061e0d65 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
@@ -59,6 +59,11 @@ class CornerNextEdgeFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
class CornerPreviousEdgeFieldInput final : public bke::MeshFieldInput {
@@ -100,6 +105,11 @@ class CornerPreviousEdgeFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
index f0cc191e217..7aadc15f7f8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
@@ -138,6 +138,11 @@ class EdgesOfVertInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class EdgesOfVertCountInput final : public bke::MeshFieldInput {
@@ -175,6 +180,11 @@ class EdgesOfVertCountInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
index d9f944ca11e..2cf7ed2c687 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
@@ -85,6 +85,11 @@ class CornerIndexInFaceInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
index 2cb9ae82fa1..ef5c9a445f2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
@@ -86,6 +86,11 @@ class OffsetCornerInFaceFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
index f0163fa553a..9f730367931 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
@@ -53,6 +53,11 @@ class CornerVertFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
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 d46ceac92ba..dcd910b8ad2 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
@@ -24,11 +24,13 @@ static void set_resolution(bke::CurvesGeometry &curves,
MutableAttributeAccessor attributes = curves.attributes_for_write();
AttributeWriter<int> resolutions = attributes.lookup_or_add_for_write<int>("resolution",
ATTR_DOMAIN_CURVE);
+ bke::AttributeValidator validator = attributes.lookup_validator("resolution");
bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{field_context, curves.curves_num()};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(resolution_field, resolutions.varray);
+ evaluator.add_with_destination(validator.validate_field_if_necessary(resolution_field),
+ resolutions.varray);
evaluator.evaluate();
resolutions.finish();