WIP: Functions: new local allocator for better memory reuse and performance #104630

Draft
Jacques Lucke wants to merge 44 commits from JacquesLucke/blender:local-allocator into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
22 changed files with 222 additions and 105 deletions
Showing only changes of commit 1ce0482981 - Show all commits

View File

@ -73,6 +73,7 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context
threading::parallel_for(mask.index_range(), grain_size, [&](const IndexRange sub_range) {
const IndexMask sliced_mask = mask.slice(sub_range);
MFContextBuilder sub_context{&context.allocator().local()};
if (!hints.allocates_array) {
/* There is no benefit to changing indices in this case. */
this->call(sliced_mask, params, context);
@ -80,7 +81,7 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context
}
if (sliced_mask[0] < grain_size) {
/* The indices are low, no need to offset them. */
this->call(sliced_mask, params, context);
this->call(sliced_mask, params, sub_context);
return;
}
const int64_t input_slice_start = sliced_mask[0];
@ -127,7 +128,6 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context
}
}
MFContextBuilder sub_context{&context.allocator().local()};
this->call(offset_mask, offset_params, sub_context);
});
}

View File

@ -82,6 +82,7 @@ void separate_geometry(GeometrySet &geometry_set,
GeometryNodeDeleteGeometryMode mode,
const Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator,
bool &r_is_error);
void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,

View File

@ -307,14 +307,15 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
static void delete_curves_selection(GeometrySet &geometry_set,
const Field<bool> &selection_field,
const eAttrDomain selection_domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
const Curves &src_curves_id = *geometry_set.get_curves_for_read();
const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry);
const int domain_size = src_curves.attributes().domain_size(selection_domain);
bke::CurvesFieldContext field_context{src_curves, selection_domain};
fn::FieldEvaluator evaluator{field_context, domain_size};
fn::FieldEvaluator evaluator{field_context, domain_size, &allocator};
evaluator.set_selection(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
@ -341,12 +342,13 @@ static void delete_curves_selection(GeometrySet &geometry_set,
static void separate_point_cloud_selection(
GeometrySet &geometry_set,
const Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
const PointCloud &src_pointcloud = *geometry_set.get_pointcloud_for_read();
bke::PointCloudFieldContext field_context{src_pointcloud};
fn::FieldEvaluator evaluator{field_context, src_pointcloud.totpoint};
fn::FieldEvaluator evaluator{field_context, src_pointcloud.totpoint, &allocator};
evaluator.set_selection(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
@ -374,12 +376,13 @@ static void separate_point_cloud_selection(
static void delete_selected_instances(GeometrySet &geometry_set,
const Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
bke::Instances &instances = *geometry_set.get_instances_for_write();
bke::InstancesFieldContext field_context{instances};
fn::FieldEvaluator evaluator{field_context, instances.instances_num()};
fn::FieldEvaluator evaluator{field_context, instances.instances_num(), &allocator};
evaluator.set_selection(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
@ -1096,6 +1099,7 @@ void separate_geometry(GeometrySet &geometry_set,
const GeometryNodeDeleteGeometryMode mode,
const Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator,
bool &r_is_error)
{
namespace file_ns = blender::nodes::node_geo_delete_geometry_cc;
@ -1103,7 +1107,8 @@ void separate_geometry(GeometrySet &geometry_set,
bool some_valid_domain = false;
if (geometry_set.has_pointcloud()) {
if (domain == ATTR_DOMAIN_POINT) {
file_ns::separate_point_cloud_selection(geometry_set, selection_field, propagation_info);
file_ns::separate_point_cloud_selection(
geometry_set, selection_field, propagation_info, allocator);
some_valid_domain = true;
}
}
@ -1116,14 +1121,18 @@ void separate_geometry(GeometrySet &geometry_set,
}
if (geometry_set.has_curves()) {
if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE)) {
file_ns::delete_curves_selection(
geometry_set, fn::invert_boolean_field(selection_field), domain, propagation_info);
file_ns::delete_curves_selection(geometry_set,
fn::invert_boolean_field(selection_field),
domain,
propagation_info,
allocator);
some_valid_domain = true;
}
}
if (geometry_set.has_instances()) {
if (domain == ATTR_DOMAIN_INSTANCE) {
file_ns::delete_selected_instances(geometry_set, selection_field, propagation_info);
file_ns::delete_selected_instances(
geometry_set, selection_field, propagation_info, allocator);
some_valid_domain = true;
}
}
@ -1188,13 +1197,20 @@ static void node_geo_exec(GeoNodeExecParams params)
if (domain == ATTR_DOMAIN_INSTANCE) {
bool is_error;
separate_geometry(geometry_set, domain, mode, selection, propagation_info, is_error);
separate_geometry(
geometry_set, domain, mode, selection, propagation_info, params.allocator(), is_error);
}
else {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
bool is_error;
/* Invert here because we want to keep the things not in the selection. */
separate_geometry(geometry_set, domain, mode, selection, propagation_info, is_error);
separate_geometry(geometry_set,
domain,
mode,
selection,
propagation_info,
params.allocator().local(),
is_error);
});
}

View File

@ -385,14 +385,15 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh,
static Array<float> calc_full_density_factors_with_selection(const Mesh &mesh,
const Field<float> &density_field,
const Field<bool> &selection_field)
const Field<bool> &selection_field,
LocalAllocator &allocator)
{
const eAttrDomain domain = ATTR_DOMAIN_CORNER;
const int domain_size = mesh.attributes().domain_size(domain);
Array<float> densities(domain_size, 0.0f);
bke::MeshFieldContext field_context{mesh, domain};
fn::FieldEvaluator evaluator{field_context, domain_size};
fn::FieldEvaluator evaluator{field_context, domain_size, &allocator};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(density_field, densities.as_mutable_span());
evaluator.evaluate();
@ -403,12 +404,13 @@ static void distribute_points_random(const Mesh &mesh,
const Field<float> &density_field,
const Field<bool> &selection_field,
const int seed,
LocalAllocator &allocator,
Vector<float3> &positions,
Vector<float3> &bary_coords,
Vector<int> &looptri_indices)
{
const Array<float> densities = calc_full_density_factors_with_selection(
mesh, density_field, selection_field);
mesh, density_field, selection_field, allocator);
sample_mesh_surface(mesh, 1.0f, densities, seed, positions, bary_coords, looptri_indices);
}
@ -418,6 +420,7 @@ static void distribute_points_poisson_disk(const Mesh &mesh,
const Field<float> &density_factor_field,
const Field<bool> &selection_field,
const int seed,
LocalAllocator &allocator,
Vector<float3> &positions,
Vector<float3> &bary_coords,
Vector<int> &looptri_indices)
@ -428,7 +431,7 @@ static void distribute_points_poisson_disk(const Mesh &mesh,
update_elimination_mask_for_close_points(positions, minimum_distance, elimination_mask);
const Array<float> density_factors = calc_full_density_factors_with_selection(
mesh, density_factor_field, selection_field);
mesh, density_factor_field, selection_field, allocator);
update_elimination_mask_based_on_density_factors(
mesh, density_factors, bary_coords, looptri_indices, elimination_mask.as_mutable_span());
@ -442,7 +445,8 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
const GeometryNodeDistributePointsOnFacesMode method,
const int seed,
const AttributeOutputs &attribute_outputs,
const GeoNodeExecParams &params)
const GeoNodeExecParams &params,
LocalAllocator &allocator)
{
if (!geometry_set.has_mesh()) {
return;
@ -457,8 +461,14 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
switch (method) {
case GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_RANDOM: {
const Field<float> density_field = params.get_input<Field<float>>("Density");
distribute_points_random(
mesh, density_field, selection_field, seed, positions, bary_coords, looptri_indices);
distribute_points_random(mesh,
density_field,
selection_field,
seed,
allocator,
positions,
bary_coords,
looptri_indices);
break;
}
case GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_POISSON: {
@ -471,6 +481,7 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
density_factors_field,
selection_field,
seed,
allocator,
positions,
bary_coords,
looptri_indices);
@ -527,8 +538,13 @@ static void node_geo_exec(GeoNodeExecParams params)
lazy_threading::send_hint();
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
point_distribution_calculate(
geometry_set, selection_field, method, seed, attribute_outputs, params);
point_distribution_calculate(geometry_set,
selection_field,
method,
seed,
attribute_outputs,
params,
params.allocator().local());
/* Keep instances because the original geometry set may contain instances that are processed as
* well. */
geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD});

View File

@ -324,7 +324,8 @@ static void duplicate_curves(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
if (!geometry_set.has_curves()) {
geometry_set.remove_geometry_during_modify();
@ -337,7 +338,7 @@ static void duplicate_curves(GeometrySet &geometry_set,
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE};
FieldEvaluator evaluator{field_context, curves.curves_num()};
FieldEvaluator evaluator{field_context, curves.curves_num(), &allocator};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -516,7 +517,8 @@ static void duplicate_faces(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
if (!geometry_set.has_mesh()) {
geometry_set.remove_geometry_during_modify();
@ -531,7 +533,7 @@ static void duplicate_faces(GeometrySet &geometry_set,
const Span<MLoop> loops = mesh.loops();
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE};
FieldEvaluator evaluator(field_context, polys.size());
FieldEvaluator evaluator(field_context, polys.size(), &allocator);
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -718,7 +720,8 @@ static void duplicate_edges(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
if (!geometry_set.has_mesh()) {
geometry_set.remove_geometry_during_modify();
@ -728,7 +731,7 @@ static void duplicate_edges(GeometrySet &geometry_set,
const Span<MEdge> edges = mesh.edges();
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE};
FieldEvaluator evaluator{field_context, edges.size()};
FieldEvaluator evaluator{field_context, edges.size(), &allocator};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -798,7 +801,8 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
const Curves &src_curves_id = *geometry_set.get_curves_for_read();
const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry);
@ -807,7 +811,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
}
bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_POINT};
FieldEvaluator evaluator{field_context, src_curves.points_num()};
FieldEvaluator evaluator{field_context, src_curves.points_num(), &allocator};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -902,13 +906,14 @@ static void duplicate_points_mesh(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
const Mesh &mesh = *geometry_set.get_mesh_for_read();
const Span<MVert> src_verts = mesh.verts();
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_POINT};
FieldEvaluator evaluator{field_context, src_verts.size()};
FieldEvaluator evaluator{field_context, src_verts.size(), &allocator};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -954,12 +959,13 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
const PointCloud &src_points = *geometry_set.get_pointcloud_for_read();
bke::PointCloudFieldContext field_context{src_points};
FieldEvaluator evaluator{field_context, src_points.totpoint};
FieldEvaluator evaluator{field_context, src_points.totpoint, &allocator};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -1001,27 +1007,40 @@ static void duplicate_points(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
Vector<GeometryComponentType> component_types = geometry_set.gather_component_types(true, true);
for (const GeometryComponentType component_type : component_types) {
switch (component_type) {
case GEO_COMPONENT_TYPE_POINT_CLOUD:
if (geometry_set.has_pointcloud()) {
duplicate_points_pointcloud(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_points_pointcloud(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
allocator);
}
break;
case GEO_COMPONENT_TYPE_MESH:
if (geometry_set.has_mesh()) {
duplicate_points_mesh(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_points_mesh(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
allocator);
}
break;
case GEO_COMPONENT_TYPE_CURVE:
if (geometry_set.has_curves()) {
duplicate_points_curve(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_points_curve(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
allocator);
}
break;
default:
@ -1042,7 +1061,8 @@ static void duplicate_instances(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
if (!geometry_set.has_instances()) {
geometry_set.clear();
@ -1052,7 +1072,7 @@ static void duplicate_instances(GeometrySet &geometry_set,
const bke::Instances &src_instances = *geometry_set.get_instances_for_read();
bke::InstancesFieldContext field_context{src_instances};
FieldEvaluator evaluator{field_context, src_instances.instances_num()};
FieldEvaluator evaluator{field_context, src_instances.instances_num(), &allocator};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -1124,27 +1144,48 @@ static void node_geo_exec(GeoNodeExecParams params)
"Geometry");
if (duplicate_domain == ATTR_DOMAIN_INSTANCE) {
duplicate_instances(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_instances(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
params.allocator());
}
else {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
LocalAllocator &allocator = params.allocator().local();
switch (duplicate_domain) {
case ATTR_DOMAIN_CURVE:
duplicate_curves(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_curves(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
allocator);
break;
case ATTR_DOMAIN_FACE:
duplicate_faces(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_faces(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
allocator);
break;
case ATTR_DOMAIN_EDGE:
duplicate_edges(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_edges(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
allocator);
break;
case ATTR_DOMAIN_POINT:
duplicate_points(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
duplicate_points(geometry_set,
count_field,
selection_field,
attribute_outputs,
propagation_info,
allocator);
break;
default:
BLI_assert_unreachable();

View File

@ -25,7 +25,8 @@ static void node_geo_exec(GeoNodeExecParams params)
if (const Mesh *mesh = geometry_set.get_mesh_for_read()) {
bke::MeshFieldContext field_context{*mesh, ATTR_DOMAIN_EDGE};
fn::FieldEvaluator selection_evaluator{field_context, mesh->totedge};
fn::FieldEvaluator selection_evaluator{
field_context, mesh->totedge, &params.allocator().local()};
selection_evaluator.set_selection(selection_field);
selection_evaluator.evaluate();
const IndexMask mask = selection_evaluator.get_evaluated_selection_as_mask();

View File

@ -200,13 +200,14 @@ static Array<Vector<int>> create_vert_to_edge_map(const int vert_size,
static void extrude_mesh_vertices(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs)
const AttributeOutputs &attribute_outputs,
LocalAllocator &allocator)
{
const int orig_vert_size = mesh.totvert;
const int orig_edge_size = mesh.totedge;
const bke::MeshFieldContext context{mesh, ATTR_DOMAIN_POINT};
FieldEvaluator evaluator{context, mesh.totvert};
FieldEvaluator evaluator{context, mesh.totvert, &allocator};
evaluator.add(offset_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@ -368,7 +369,8 @@ static VectorSet<int> vert_indices_from_edges(const Mesh &mesh, const Span<T> ed
static void extrude_mesh_edges(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs)
const AttributeOutputs &attribute_outputs,
LocalAllocator &allocator)
{
const int orig_vert_size = mesh.totvert;
const Span<MEdge> orig_edges = mesh.edges();
@ -376,7 +378,7 @@ static void extrude_mesh_edges(Mesh &mesh,
const int orig_loop_size = mesh.totloop;
const bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE};
FieldEvaluator edge_evaluator{edge_context, mesh.totedge};
FieldEvaluator edge_evaluator{edge_context, mesh.totedge, &allocator};
edge_evaluator.set_selection(selection_field);
edge_evaluator.add(offset_field);
edge_evaluator.evaluate();
@ -647,7 +649,8 @@ static void extrude_mesh_edges(Mesh &mesh,
static void extrude_mesh_face_regions(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs)
const AttributeOutputs &attribute_outputs,
LocalAllocator &allocator)
{
const int orig_vert_size = mesh.totvert;
const Span<MEdge> orig_edges = mesh.edges();
@ -655,7 +658,7 @@ static void extrude_mesh_face_regions(Mesh &mesh,
const Span<MLoop> orig_loops = mesh.loops();
const bke::MeshFieldContext poly_context{mesh, ATTR_DOMAIN_FACE};
FieldEvaluator poly_evaluator{poly_context, mesh.totpoly};
FieldEvaluator poly_evaluator{poly_context, mesh.totpoly, &allocator};
poly_evaluator.set_selection(selection_field);
poly_evaluator.add(offset_field);
poly_evaluator.evaluate();
@ -1050,7 +1053,8 @@ static IndexRange selected_corner_range(Span<int> offsets, const int index)
static void extrude_individual_mesh_faces(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs)
const AttributeOutputs &attribute_outputs,
LocalAllocator &allocator)
{
const int orig_vert_size = mesh.totvert;
const int orig_edge_size = mesh.totedge;
@ -1061,7 +1065,7 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
* the vertices are moved, and the evaluated result might reference an attribute. */
Array<float3> poly_offset(orig_polys.size());
const bke::MeshFieldContext poly_context{mesh, ATTR_DOMAIN_FACE};
FieldEvaluator poly_evaluator{poly_context, mesh.totpoly};
FieldEvaluator poly_evaluator{poly_context, mesh.totpoly, &allocator};
poly_evaluator.set_selection(selection_field);
poly_evaluator.add_with_destination(offset_field, poly_offset.as_mutable_span());
poly_evaluator.evaluate();
@ -1342,19 +1346,22 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
LocalAllocator &allocator = params.allocator().local();
switch (mode) {
case GEO_NODE_EXTRUDE_MESH_VERTICES:
extrude_mesh_vertices(*mesh, selection, final_offset, attribute_outputs);
extrude_mesh_vertices(*mesh, selection, final_offset, attribute_outputs, allocator);
break;
case GEO_NODE_EXTRUDE_MESH_EDGES:
extrude_mesh_edges(*mesh, selection, final_offset, attribute_outputs);
extrude_mesh_edges(*mesh, selection, final_offset, attribute_outputs, allocator);
break;
case GEO_NODE_EXTRUDE_MESH_FACES: {
if (extrude_individual) {
extrude_individual_mesh_faces(*mesh, selection, final_offset, attribute_outputs);
extrude_individual_mesh_faces(
*mesh, selection, final_offset, attribute_outputs, allocator);
}
else {
extrude_mesh_face_regions(*mesh, selection, final_offset, attribute_outputs);
extrude_mesh_face_regions(
*mesh, selection, final_offset, attribute_outputs, allocator);
}
break;
}

View File

@ -79,7 +79,7 @@ static void node_geo_exec(GeoNodeExecParams params)
"radius", ATTR_DOMAIN_POINT);
PointsFieldContext context{count};
fn::FieldEvaluator evaluator{context, count};
fn::FieldEvaluator evaluator{context, count, &params.allocator()};
evaluator.add_with_destination(position_field, output_position.varray);
evaluator.add_with_destination(radius_field, output_radii.varray);
evaluator.evaluate();

View File

@ -24,7 +24,8 @@ static void node_declare(NodeDeclarationBuilder &b)
static void geometry_set_points_to_vertices(
GeometrySet &geometry_set,
Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info)
const AnonymousAttributePropagationInfo &propagation_info,
LocalAllocator &allocator)
{
const PointCloud *points = geometry_set.get_pointcloud_for_read();
if (points == nullptr) {
@ -37,7 +38,7 @@ static void geometry_set_points_to_vertices(
}
bke::PointCloudFieldContext field_context{*points};
fn::FieldEvaluator selection_evaluator{field_context, points->totpoint};
fn::FieldEvaluator selection_evaluator{field_context, points->totpoint, &allocator};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
@ -78,8 +79,10 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
geometry_set_points_to_vertices(
geometry_set, selection_field, params.get_output_propagation_info("Mesh"));
geometry_set_points_to_vertices(geometry_set,
selection_field,
params.get_output_propagation_info("Mesh"),
params.allocator().local());
});
params.set_output("Mesh", std::move(geometry_set));

View File

@ -307,10 +307,12 @@ static AxisScaleParams evaluate_axis_scale_fields(FieldEvaluator &evaluator,
return out;
}
static void scale_faces_on_axis(Mesh &mesh, const AxisScaleFields &fields)
static void scale_faces_on_axis(Mesh &mesh,
const AxisScaleFields &fields,
LocalAllocator &allocator)
{
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE};
FieldEvaluator evaluator{field_context, mesh.totpoly};
FieldEvaluator evaluator{field_context, mesh.totpoly, &allocator};
AxisScaleParams params = evaluate_axis_scale_fields(evaluator, fields);
Vector<ElementIsland> island = prepare_face_islands(mesh, params.selection);
@ -329,10 +331,12 @@ static UniformScaleParams evaluate_uniform_scale_fields(FieldEvaluator &evaluato
return out;
}
static void scale_faces_uniformly(Mesh &mesh, const UniformScaleFields &fields)
static void scale_faces_uniformly(Mesh &mesh,
const UniformScaleFields &fields,
LocalAllocator &allocator)
{
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE};
FieldEvaluator evaluator{field_context, mesh.totpoly};
FieldEvaluator evaluator{field_context, mesh.totpoly, &allocator};
UniformScaleParams params = evaluate_uniform_scale_fields(evaluator, fields);
Vector<ElementIsland> island = prepare_face_islands(mesh, params.selection);
@ -381,20 +385,24 @@ static void get_edge_verts(const Span<MEdge> edges,
r_vertex_indices.add(edge.v2);
}
static void scale_edges_uniformly(Mesh &mesh, const UniformScaleFields &fields)
static void scale_edges_uniformly(Mesh &mesh,
const UniformScaleFields &fields,
LocalAllocator &allocator)
{
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE};
FieldEvaluator evaluator{field_context, mesh.totedge};
FieldEvaluator evaluator{field_context, mesh.totedge, &allocator};
UniformScaleParams params = evaluate_uniform_scale_fields(evaluator, fields);
Vector<ElementIsland> island = prepare_edge_islands(mesh, params.selection);
scale_vertex_islands_uniformly(mesh, island, params, get_edge_verts);
}
static void scale_edges_on_axis(Mesh &mesh, const AxisScaleFields &fields)
static void scale_edges_on_axis(Mesh &mesh,
const AxisScaleFields &fields,
LocalAllocator &allocator)
{
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE};
FieldEvaluator evaluator{field_context, mesh.totedge};
FieldEvaluator evaluator{field_context, mesh.totedge, &allocator};
AxisScaleParams params = evaluate_axis_scale_fields(evaluator, fields);
Vector<ElementIsland> island = prepare_edge_islands(mesh, params.selection);
@ -419,15 +427,18 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry.modify_geometry_sets([&](GeometrySet &geometry) {
if (Mesh *mesh = geometry.get_mesh_for_write()) {
LocalAllocator &allocator = params.allocator().local();
switch (domain) {
case ATTR_DOMAIN_FACE: {
switch (scale_mode) {
case GEO_NODE_SCALE_ELEMENTS_UNIFORM: {
scale_faces_uniformly(*mesh, {selection_field, scale_field, center_field});
scale_faces_uniformly(
*mesh, {selection_field, scale_field, center_field}, allocator);
break;
}
case GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS: {
scale_faces_on_axis(*mesh, {selection_field, scale_field, center_field, axis_field});
scale_faces_on_axis(
*mesh, {selection_field, scale_field, center_field, axis_field}, allocator);
break;
}
}
@ -436,11 +447,13 @@ static void node_geo_exec(GeoNodeExecParams params)
case ATTR_DOMAIN_EDGE: {
switch (scale_mode) {
case GEO_NODE_SCALE_ELEMENTS_UNIFORM: {
scale_edges_uniformly(*mesh, {selection_field, scale_field, center_field});
scale_edges_uniformly(
*mesh, {selection_field, scale_field, center_field}, allocator);
break;
}
case GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS: {
scale_edges_on_axis(*mesh, {selection_field, scale_field, center_field, axis_field});
scale_edges_on_axis(
*mesh, {selection_field, scale_field, center_field, axis_field}, allocator);
break;
}
}

View File

@ -21,7 +21,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static void scale_instances(GeoNodeExecParams &params, bke::Instances &instances)
{
const bke::InstancesFieldContext context{instances};
fn::FieldEvaluator evaluator{context, instances.instances_num()};
fn::FieldEvaluator evaluator{context, instances.instances_num(), &params.allocator()};
evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
evaluator.add(params.extract_input<Field<float3>>("Scale"));
evaluator.add(params.extract_input<Field<float3>>("Center"));

View File

@ -59,6 +59,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GEO_NODE_DELETE_GEOMETRY_MODE_ALL,
selection,
propagation_info,
params.allocator(),
is_error);
}
else {
@ -68,6 +69,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GEO_NODE_DELETE_GEOMETRY_MODE_ALL,
selection,
propagation_info,
params.allocator().local(),
is_error);
});
}

View File

@ -20,7 +20,8 @@ static void node_declare(NodeDeclarationBuilder &b)
static void set_radius(bke::CurvesGeometry &curves,
const Field<bool> &selection_field,
const Field<float> &radius_field)
const Field<float> &radius_field,
LocalAllocator &allocator)
{
if (curves.points_num() == 0) {
return;
@ -30,7 +31,7 @@ static void set_radius(bke::CurvesGeometry &curves,
ATTR_DOMAIN_POINT);
bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_POINT};
fn::FieldEvaluator evaluator{field_context, curves.points_num()};
fn::FieldEvaluator evaluator{field_context, curves.points_num(), &allocator};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(radius_field, radii.varray);
evaluator.evaluate();
@ -46,7 +47,10 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (Curves *curves_id = geometry_set.get_curves_for_write()) {
set_radius(bke::CurvesGeometry::wrap(curves_id->geometry), selection_field, radii_field);
set_radius(bke::CurvesGeometry::wrap(curves_id->geometry),
selection_field,
radii_field,
params.allocator().local());
}
});

View File

@ -16,7 +16,8 @@ static void node_declare(NodeDeclarationBuilder &b)
static void set_tilt(bke::CurvesGeometry &curves,
const Field<bool> &selection_field,
const Field<float> &tilt_field)
const Field<float> &tilt_field,
LocalAllocator &allocator)
{
if (curves.points_num() == 0) {
return;
@ -26,7 +27,7 @@ static void set_tilt(bke::CurvesGeometry &curves,
ATTR_DOMAIN_POINT);
bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_POINT};
fn::FieldEvaluator evaluator{field_context, curves.points_num()};
fn::FieldEvaluator evaluator{field_context, curves.points_num(), &allocator};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(tilt_field, tilts.varray);
evaluator.evaluate();
@ -42,7 +43,10 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (Curves *curves_id = geometry_set.get_curves_for_write()) {
set_tilt(bke::CurvesGeometry::wrap(curves_id->geometry), selection_field, tilt_field);
set_tilt(bke::CurvesGeometry::wrap(curves_id->geometry),
selection_field,
tilt_field,
params.allocator().local());
}
});

View File

@ -75,7 +75,8 @@ static void node_geo_exec(GeoNodeExecParams params)
Mesh &mesh = *mesh_component.get_for_write();
bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE};
fn::FieldEvaluator selection_evaluator{field_context, mesh.totpoly};
fn::FieldEvaluator selection_evaluator{
field_context, mesh.totpoly, &params.allocator().local()};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);

View File

@ -20,7 +20,8 @@ static void node_declare(NodeDeclarationBuilder &b)
static void set_radius_in_component(PointCloud &pointcloud,
const Field<bool> &selection_field,
const Field<float> &radius_field)
const Field<float> &radius_field,
LocalAllocator &allocator)
{
if (pointcloud.totpoint == 0) {
return;
@ -30,7 +31,7 @@ static void set_radius_in_component(PointCloud &pointcloud,
ATTR_DOMAIN_POINT);
bke::PointCloudFieldContext field_context{pointcloud};
fn::FieldEvaluator evaluator{field_context, pointcloud.totpoint};
fn::FieldEvaluator evaluator{field_context, pointcloud.totpoint, &allocator};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(radius_field, radii.varray);
evaluator.evaluate();
@ -46,7 +47,8 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (PointCloud *pointcloud = geometry_set.get_pointcloud_for_write()) {
set_radius_in_component(*pointcloud, selection_field, radii_field);
set_radius_in_component(
*pointcloud, selection_field, radii_field, params.allocator().local());
}
});

View File

@ -147,7 +147,8 @@ static void set_computed_position_and_offset(GeometryComponent &component,
static void set_position_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<float3> &position_field,
const Field<float3> &offset_field)
const Field<float3> &offset_field,
LocalAllocator &allocator)
{
eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE :
ATTR_DOMAIN_POINT;
@ -157,7 +158,7 @@ static void set_position_in_component(GeometryComponent &component,
return;
}
fn::FieldEvaluator evaluator{field_context, domain_size};
fn::FieldEvaluator evaluator{field_context, domain_size, &allocator};
evaluator.set_selection(selection_field);
evaluator.add(position_field);
evaluator.add(offset_field);
@ -182,8 +183,11 @@ static void node_geo_exec(GeoNodeExecParams params)
GEO_COMPONENT_TYPE_CURVE,
GEO_COMPONENT_TYPE_INSTANCES}) {
if (geometry.has(type)) {
set_position_in_component(
geometry.get_component_for_write(type), selection_field, position_field, offset_field);
set_position_in_component(geometry.get_component_for_write(type),
selection_field,
position_field,
offset_field,
params.allocator());
}
}

View File

@ -162,7 +162,7 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has(type)) {
GeometryComponent &component = geometry_set.get_component_for_write(type);
if (!bke::try_capture_field_on_geometry(
component, name, domain, field, &params.allocator())) {
component, name, domain, field, &params.allocator().local())) {
if (component.attribute_domain_size(domain) != 0) {
failure.store(true);
}

View File

@ -124,14 +124,16 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
LocalAllocator &allocator = params.allocator().local();
bke::MeshFieldContext point_context{mesh, ATTR_DOMAIN_POINT};
FieldEvaluator point_evaluator(point_context, mesh.totvert);
FieldEvaluator point_evaluator(point_context, mesh.totvert, &allocator);
point_evaluator.add(vertex_crease_field);
point_evaluator.evaluate();
const VArray<float> vertex_creases = point_evaluator.get_evaluated<float>(0);
bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE};
FieldEvaluator edge_evaluator(edge_context, mesh.totedge);
FieldEvaluator edge_evaluator(edge_context, mesh.totedge, &allocator);
edge_evaluator.add(edge_crease_field);
edge_evaluator.evaluate();
const VArray<float> edge_creases = edge_evaluator.get_evaluated<float>(0);

View File

@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static void translate_instances(GeoNodeExecParams &params, bke::Instances &instances)
{
const bke::InstancesFieldContext context{instances};
fn::FieldEvaluator evaluator{context, instances.instances_num()};
fn::FieldEvaluator evaluator{context, instances.instances_num(), &params.allocator()};
evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
evaluator.add(params.extract_input<Field<float3>>("Translation"));
evaluator.add(params.extract_input<Field<bool>>("Local Space"));

View File

@ -78,7 +78,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Mesh &mesh_in = *geometry_set.get_mesh_for_read();
bke::MeshFieldContext context{mesh_in, ATTR_DOMAIN_FACE};
FieldEvaluator evaluator{context, mesh_in.totpoly};
FieldEvaluator evaluator{context, mesh_in.totpoly, &params.allocator().local()};
evaluator.add(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_as_mask(0);

View File

@ -148,7 +148,7 @@ static void node_geo_exec(GeoNodeExecParams params)
/* Evaluate input field on a 3D grid. */
Grid3DFieldContext context(resolution, bounds_min, bounds_max);
FieldEvaluator evaluator(context, context.points_num());
FieldEvaluator evaluator(context, context.points_num(), &params.allocator());
Array<float> densities(context.points_num());
evaluator.add_with_destination(std::move(input_field), densities.as_mutable_span());
evaluator.evaluate();