From c01d4a4ee61d44a74f79d683ccdcd7407e92ad5a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 28 Aug 2025 12:11:03 -0400 Subject: [PATCH] Refactor: Deduplicate position transform utilities The pattern of transforming many position vectors at once is quite common, both with separate source and result arrays, and when modifying an array in place. In some cases at least we used a separate function with a consistent name across files, but there were also many duplicate parallel transform implementations. This commit adds these utilities to the BLI_math_matrix.hh API and uses them where many positions from contiguous arrays are transformed at once. While there might be a more ideal location for these utilities, it's consistent with 3936d7a93e, and certainly better than duplicating them. This also reduces binary size of my build by 15 KB. Pull Request: https://projects.blender.org/blender/blender/pulls/145352 --- .../blenkernel/intern/curves_geometry.cc | 15 +---- .../blenkernel/intern/grease_pencil.cc | 15 +---- source/blender/blenkernel/intern/mesh.cc | 13 +---- source/blender/blenlib/BLI_math_matrix.hh | 9 +++ source/blender/blenlib/intern/math_matrix.cc | 58 +++++++++++++++++++ .../intern/draw_cache_impl_grease_pencil.cc | 53 ++++------------- .../intern/grease_pencil_bake_animation.cc | 6 +- .../intern/grease_pencil_geom.cc | 14 ++--- .../intern/grease_pencil_weight_paint.cc | 16 ++--- source/blender/editors/object/object_add.cc | 5 +- .../editors/object/object_data_transform.cc | 19 ++---- .../editors/object/object_transform.cc | 11 +--- .../sculpt_paint/brushes/multiplane_scrape.cc | 12 ++-- .../editors/sculpt_paint/brushes/plane.cc | 13 +---- .../sculpt_paint/curves_sculpt_density.cc | 4 +- .../sculpt_paint/grease_pencil_paint.cc | 6 +- .../editors/sculpt_paint/mesh_brush_common.hh | 3 - source/blender/editors/sculpt_paint/sculpt.cc | 18 ------ .../geometry/intern/realize_instances.cc | 42 +++----------- source/blender/geometry/intern/transform.cc | 15 +---- .../grease_pencil/intern/grease_pencil_io.cc | 10 +--- 21 files changed, 122 insertions(+), 235 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index bda46301778..aa392951a4d 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -1249,15 +1249,6 @@ static void translate_positions(MutableSpan positions, const float3 &tra }); } -static void transform_positions(MutableSpan positions, const float4x4 &matrix) -{ - threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { - for (float3 &position : positions.slice(range)) { - position = math::transform_point(matrix, position); - } - }); -} - void CurvesGeometry::calculate_bezier_auto_handles() { if (!this->has_curve_with_type(CURVE_TYPE_BEZIER)) { @@ -1319,12 +1310,12 @@ void CurvesGeometry::translate(const float3 &translation) void CurvesGeometry::transform(const float4x4 &matrix) { - transform_positions(this->positions_for_write(), matrix); + math::transform_points(matrix, this->positions_for_write()); if (this->handle_positions_left()) { - transform_positions(this->handle_positions_left_for_write(), matrix); + math::transform_points(matrix, this->handle_positions_left_for_write()); } if (this->handle_positions_right()) { - transform_positions(this->handle_positions_right_for_write(), matrix); + math::transform_points(matrix, this->handle_positions_right_for_write()); } MutableAttributeAccessor attributes = this->attributes_for_write(); transform_custom_normal_attribute(matrix, attributes); diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index f9ed4c84933..88bfa633992 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -3432,19 +3432,6 @@ blender::bke::greasepencil::Drawing *GreasePencil::get_eval_drawing( return this->get_drawing_at(layer, this->runtime->eval_frame); } -static void transform_positions(const Span src, - const blender::float4x4 &transform, - blender::MutableSpan dst) -{ - BLI_assert(src.size() == dst.size()); - - blender::threading::parallel_for(src.index_range(), 4096, [&](const blender::IndexRange range) { - for (const int i : range) { - dst[i] = blender::math::transform_point(transform, src[i]); - } - }); -} - std::optional> GreasePencil::bounds_min_max( const int frame, const bool use_radius) const { @@ -3471,7 +3458,7 @@ std::optional> GreasePencil::bounds_min_max( } const VArray radius = curves.radius(); Array positions_world(curves.evaluated_points_num()); - transform_positions(curves.evaluated_positions(), layer_to_object, positions_world); + math::transform_points(curves.evaluated_positions(), layer_to_object, positions_world); if (!use_radius) { const Bounds drawing_bounds = *bounds::min_max(positions_world.as_span()); bounds = bounds::merge(bounds, drawing_bounds); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 5512ce25bd5..34675170713 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1838,15 +1838,6 @@ const blender::VectorSet &Mesh::material_indices_used() const namespace blender::bke { -static void transform_positions(MutableSpan positions, const float4x4 &matrix) -{ - threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { - for (float3 &position : positions.slice(range)) { - position = math::transform_point(matrix, position); - } - }); -} - static void translate_positions(MutableSpan positions, const float3 &translation) { threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) { @@ -1886,11 +1877,11 @@ void mesh_translate(Mesh &mesh, const float3 &translation, const bool do_shape_k void mesh_transform(Mesh &mesh, const float4x4 &transform, bool do_shape_keys) { - transform_positions(mesh.vert_positions_for_write(), transform); + math::transform_points(transform, mesh.vert_positions_for_write()); if (do_shape_keys && mesh.key) { LISTBASE_FOREACH (KeyBlock *, kb, &mesh.key->block) { - transform_positions(MutableSpan(static_cast(kb->data), kb->totelem), transform); + math::transform_points(transform, MutableSpan(static_cast(kb->data), kb->totelem)); } } MutableAttributeAccessor attributes = mesh.attributes_for_write(); diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index 539b777cc60..4e58c8d3cae 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -1813,4 +1813,13 @@ extern template float4x4 perspective( void transform_normals(const float3x3 &transform, MutableSpan normals); void transform_normals(Span src, const float3x3 &transform, MutableSpan dst); +/** Transform point vectors with matrix multiplication, optionally using multi-threading. */ +void transform_points(const float4x4 &transform, + MutableSpan points, + bool use_threading = true); +void transform_points(Span src, + const float4x4 &transform, + MutableSpan dst, + bool use_threading = true); + } // namespace blender::math diff --git a/source/blender/blenlib/intern/math_matrix.cc b/source/blender/blenlib/intern/math_matrix.cc index 1e79bcfa320..fa8aa26f001 100644 --- a/source/blender/blenlib/intern/math_matrix.cc +++ b/source/blender/blenlib/intern/math_matrix.cc @@ -596,4 +596,62 @@ void transform_normals(Span src, const float3x3 &transform, MutableSpan< } } +static bool skip_transform(const float4x4 &transform) +{ + return math::is_equal(transform, float4x4::identity(), 1e-6f); +} + +static void transform_points_no_threading(const Span src, + const float4x4 &transform, + MutableSpan dst) +{ + for (const int64_t i : src.index_range()) { + dst[i] = math::transform_point(transform, src[i]); + } +} + +void transform_points(const Span src, + const float4x4 &transform, + MutableSpan dst, + const bool use_threading) +{ + if (skip_transform(transform)) { + dst.copy_from(src); + } + else { + if (use_threading) { + threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) { + transform_points_no_threading(src.slice(range), transform, dst.slice(range)); + }); + } + else { + transform_points_no_threading(src, transform, dst); + } + } +} + +static void transform_points_no_threading(const float4x4 &transform, MutableSpan points) +{ + for (float3 &position : points) { + position = math::transform_point(transform, position); + } +} + +void transform_points(const float4x4 &transform, + MutableSpan points, + const bool use_threading) +{ + if (skip_transform(transform)) { + return; + } + if (use_threading) { + threading::parallel_for(points.index_range(), 1024, [&](const IndexRange range) { + transform_points_no_threading(transform, points.slice(range)); + }); + } + else { + transform_points_no_threading(transform, points); + } +} + } // namespace blender::math diff --git a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc index 5de7ddacd00..dbffd2c56bb 100644 --- a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc @@ -246,16 +246,6 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float sof return packed; } -static void copy_transformed_positions(const Span src_positions, - const IndexRange range, - const float4x4 &transform, - MutableSpan dst_positions) -{ - for (const int point_i : range) { - dst_positions[point_i] = math::transform_point(transform, src_positions[point_i]); - } -} - [[maybe_unused]] static bool grease_pencil_batch_cache_is_edit_discarded( GreasePencilBatchCache *cache) { @@ -334,11 +324,8 @@ static void grease_pencil_weight_batch_ensure(Object &object, object, info.drawing, memory); const IndexRange points(drawing_start_offset, curves.points_num()); - const Span positions = curves.positions(); - MutableSpan positions_slice = points_pos.slice(points); - threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange range) { - copy_transformed_positions(positions, range, layer_space_to_object_space, positions_slice); - }); + math::transform_points( + curves.positions(), layer_space_to_object_space, points_pos.slice(points)); /* Get vertex weights of the active vertex group in this drawing. */ const VArray weights = *curves.attributes().lookup_or_default( @@ -532,14 +519,8 @@ static void grease_pencil_cache_add_nurbs(Object &object, MutableSpan positions_eval_slice = edit_line_points.slice(eval_slice); - /* This will copy over the position but without the layer transform. */ array_utils::gather(positions, nurbs_points, positions_eval_slice); - - /* Go through the position and apply the layer transform. */ - threading::parallel_for(nurbs_points.index_range(), 1024, [&](const IndexRange range) { - copy_transformed_positions( - positions_eval_slice, range, layer_space_to_object_space, positions_eval_slice); - }); + math::transform_points(layer_space_to_object_space, positions_eval_slice); MutableSpan selection_eval_slice = edit_line_selection.slice(eval_slice); @@ -844,22 +825,14 @@ static void grease_pencil_edit_batch_ensure(Object &object, const IndexRange points(drawing_start_offset, curves.points_num()); const IndexRange points_eval(drawing_line_start_offset, curves.evaluated_points_num()); - const Span positions = curves.positions(); if (!layer.is_locked()) { - MutableSpan positions_slice = edit_points.slice(points); - threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange range) { - copy_transformed_positions(positions, range, layer_space_to_object_space, positions_slice); - }); + math::transform_points( + curves.positions(), layer_space_to_object_space, edit_points.slice(points)); } - const Span positions_eval = curves.evaluated_positions(); - - MutableSpan positions_eval_slice = edit_line_points.slice(points_eval); - threading::parallel_for( - IndexRange(curves.evaluated_points_num()), 1024, [&](const IndexRange range) { - copy_transformed_positions( - positions_eval, range, layer_space_to_object_space, positions_eval_slice); - }); + math::transform_points(curves.evaluated_positions(), + layer_space_to_object_space, + edit_line_points.slice(points_eval)); /* Do not show selection for locked layers. */ if (!layer.is_locked()) { @@ -944,17 +917,11 @@ static void grease_pencil_edit_batch_ensure(Object &object, const Span handles_left = *curves.handle_positions_left(); const Span handles_right = *curves.handle_positions_right(); - /* This will copy over the position but without the layer transform. */ array_utils::gather(handles_left, bezier_points, positions_slice_left); array_utils::gather(handles_right, bezier_points, positions_slice_right); - /* Go through the position and apply the layer transform. */ - threading::parallel_for(bezier_points.index_range(), 1024, [&](const IndexRange range) { - copy_transformed_positions( - positions_slice_left, range, layer_space_to_object_space, positions_slice_left); - copy_transformed_positions( - positions_slice_right, range, layer_space_to_object_space, positions_slice_right); - }); + math::transform_points(layer_space_to_object_space, positions_slice_left); + math::transform_points(layer_space_to_object_space, positions_slice_right); const VArray selected_left = *curves.attributes().lookup_or_default( ".selection_handle_left", bke::AttrDomain::Point, true); diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_bake_animation.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_bake_animation.cc index f3629da7a09..22e85eedc44 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_bake_animation.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_bake_animation.cc @@ -263,11 +263,7 @@ static wmOperatorStatus bake_grease_pencil_animation_exec(bContext *C, wmOperato target_material_indices.finish(); MutableSpan positions = target_strokes.positions_for_write(); - threading::parallel_for(positions.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - positions[i] = math::transform_point(to_target, positions[i]); - } - }); + math::transform_points(to_target, positions); if (drawing_placement) { threading::parallel_for(positions.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc index 9476a887c97..703e1a32b2a 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc @@ -751,14 +751,11 @@ bke::CurvesGeometry create_curves_outline(const bke::greasepencil::Drawing &draw "material_index", bke::AttrDomain::Curve, 0); /* Transform positions and radii. */ - const float scale = math::average(math::to_scale(transform)); Array transformed_positions(src_positions.size()); + math::transform_points(src_positions, transform, transformed_positions); + Array transformed_radii(src_radii.size()); - threading::parallel_for(transformed_positions.index_range(), 4096, [&](const IndexRange range) { - for (const int i : range) { - transformed_positions[i] = math::transform_point(transform, src_positions[i]); - } - }); + const float scale = math::average(math::to_scale(transform)); threading::parallel_for(transformed_radii.index_range(), 4096, [&](const IndexRange range) { for (const int i : range) { transformed_radii[i] = src_radii[i] * scale; @@ -794,9 +791,8 @@ bke::CurvesGeometry create_curves_outline(const bke::greasepencil::Drawing &draw data.point_indices); /* Transform perimeter positions back into object space. */ - for (float3 &pos : data.positions.as_mutable_span().drop_front(prev_point_num)) { - pos = math::transform_point(transform_inv, pos); - } + math::transform_points(transform_inv, + data.positions.as_mutable_span().drop_front(prev_point_num)); data.curve_indices.append_n_times(curve_i, data.point_counts.size() - prev_curve_num); }); diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc index 6c32006985b..30b09e1ce8b 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc @@ -340,14 +340,10 @@ void add_armature_envelope_weights(Scene &scene, Object &object, const Object &o const float4x4 layer_to_world = layer.to_world_space(object); CurvesGeometry &curves = info.drawing.strokes_for_write(); - const Span src_positions = curves.positions(); + /* Get all the positions in world space. */ Array positions(curves.points_num()); - threading::parallel_for(positions.index_range(), 4096, [&](const IndexRange range) { - for (const int i : range) { - positions[i] = math::transform_point(layer_to_world, src_positions[i]); - } - }); + math::transform_points(curves.positions(), layer_to_world, positions); for (const int bone_i : skinnable_bones.index_range()) { const Bone *bone = skinnable_bones[bone_i]; @@ -411,14 +407,10 @@ void add_armature_automatic_weights(Scene &scene, Object &object, const Object & const float4x4 layer_to_world = layer.to_world_space(object); CurvesGeometry &curves = info.drawing.strokes_for_write(); - const Span src_positions = curves.positions(); + /* Get all the positions in world space. */ Array positions(curves.points_num()); - threading::parallel_for(positions.index_range(), 4096, [&](const IndexRange range) { - for (const int i : range) { - positions[i] = math::transform_point(layer_to_world, src_positions[i]); - } - }); + math::transform_points(curves.positions(), layer_to_world, positions); for (const int bone_i : skinnable_bones.index_range()) { const char *deform_group_name = deform_group_names[bone_i].c_str(); diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index f150d87fa10..bfcb075d519 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -3534,10 +3534,7 @@ static Object *convert_grease_pencil_to_mesh(Base &base, const bke::greasepencil::Layer *layer = grease_pencil->layers()[layer_index]; blender::float4x4 to_object = layer->to_object_space(*ob); bke::CurvesGeometry &new_curves = curves_id->geometry.wrap(); - MutableSpan positions = new_curves.positions_for_write(); - for (const int point_i : new_curves.points_range()) { - positions[point_i] = blender::math::transform_point(to_object, positions[point_i]); - } + math::transform_points(to_object, new_curves.positions_for_write()); geometries[i] = bke::GeometrySet::from_curves(curves_id); } if (geometries.size() > 0) { diff --git a/source/blender/editors/object/object_data_transform.cc b/source/blender/editors/object/object_data_transform.cc index 5fe73edf6b8..a51050993d1 100644 --- a/source/blender/editors/object/object_data_transform.cc +++ b/source/blender/editors/object/object_data_transform.cc @@ -509,17 +509,6 @@ std::unique_ptr data_xform_create_from_edit_mode(ID *id) return data_xform_create_ex(id, true); } -static void copy_transformed_positions(const Span src, - const float4x4 &transform, - MutableSpan dst) -{ - threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) { - for (const int i : range) { - dst[i] = math::transform_point(transform, src[i]); - } - }); -} - static void copy_transformed_radii(const Span src, const float4x4 &transform, MutableSpan dst) @@ -549,7 +538,7 @@ void data_xform_by_mat4(XFormObjectData &xod_base, const float4x4 &transform) // key_index = bm->shapenr - 1; } else { - copy_transformed_positions(xod.positions, transform, mesh->vert_positions_for_write()); + math::transform_points(xod.positions, transform, mesh->vert_positions_for_write()); mesh->tag_positions_changed(); } @@ -640,11 +629,11 @@ void data_xform_by_mat4(XFormObjectData &xod_base, const float4x4 &transform) bke::CurvesGeometry &curves = curves_id->geometry.wrap(); const auto &xod = reinterpret_cast(xod_base); if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) { - copy_transformed_positions(xod.positions, transform, curves.positions_for_write()); + math::transform_points(xod.positions, transform, curves.positions_for_write()); } else { Array transformed_positions(xod.positions.size()); - copy_transformed_positions(xod.positions, transform, transformed_positions); + math::transform_points(xod.positions, transform, transformed_positions); bke::curves::bezier::write_all_positions( curves, curves.curves_range(), transformed_positions); } @@ -654,7 +643,7 @@ void data_xform_by_mat4(XFormObjectData &xod_base, const float4x4 &transform) case ID_PT: { PointCloud *pointcloud = reinterpret_cast(xod_base.id); const auto &xod = reinterpret_cast(xod_base); - copy_transformed_positions(xod.positions, transform, pointcloud->positions_for_write()); + math::transform_points(xod.positions, transform, pointcloud->positions_for_write()); copy_transformed_radii(xod.radii, transform, pointcloud->radius_for_write()); break; } diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc index 997fa0355a0..e21decdcf2b 100644 --- a/source/blender/editors/object/object_transform.cc +++ b/source/blender/editors/object/object_transform.cc @@ -655,15 +655,6 @@ static bool apply_objects_internal_need_single_user(bContext *C) return (ID_REAL_USERS(ob->data) > CTX_DATA_COUNT(C, selected_editable_objects)); } -static void transform_positions(MutableSpan positions, const float4x4 &matrix) -{ - threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { - for (float3 &position : positions.slice(range)) { - position = math::transform_point(matrix, position); - } - }); -} - static wmOperatorStatus apply_objects_internal(bContext *C, ReportList *reports, bool apply_loc, @@ -956,7 +947,7 @@ static wmOperatorStatus apply_objects_internal(bContext *C, } else if (ob->type == OB_POINTCLOUD) { PointCloud &pointcloud = *static_cast(ob->data); - transform_positions(pointcloud.positions_for_write(), float4x4(mat)); + math::transform_points(float4x4(mat), pointcloud.positions_for_write()); pointcloud.tag_positions_changed(); } else if (ob->type == OB_CAMERA) { diff --git a/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc b/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc index ad133c4ad1f..3ca84856b86 100644 --- a/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc +++ b/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc @@ -168,7 +168,7 @@ static void sample_node_surface_mesh(const Depsgraph &depsgraph, tls.local_positions.resize(verts.size()); MutableSpan local_positions = tls.local_positions; - transform_positions(positions, mat, local_positions); + math::transform_points(positions, mat, local_positions, false); const MutableSpan normals = gather_data_mesh(vert_normals, verts, tls.normals); @@ -211,7 +211,7 @@ static void sample_node_surface_grids(const Depsgraph &depsgraph, tls.local_positions.resize(positions.size()); MutableSpan local_positions = tls.local_positions; - transform_positions(positions, mat, local_positions); + math::transform_points(positions, mat, local_positions, false); tls.normals.resize(positions.size()); MutableSpan normals = tls.normals; @@ -257,7 +257,7 @@ static void sample_node_surface_bmesh(const Depsgraph &depsgraph, tls.local_positions.resize(verts.size()); MutableSpan local_positions = tls.local_positions; - transform_positions(positions, mat, local_positions); + math::transform_points(positions, mat, local_positions, false); tls.normals.resize(verts.size()); MutableSpan normals = tls.normals; @@ -385,7 +385,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.local_positions.resize(verts.size()); MutableSpan local_positions = tls.local_positions; - transform_positions(positions, mat, local_positions); + math::transform_points(positions, mat, local_positions, false); if (angle >= 0.0f) { filter_plane_side_factors(positions, local_positions, scrape_planes, factors); @@ -447,7 +447,7 @@ static void calc_grids(const Depsgraph &depsgraph, tls.local_positions.resize(positions.size()); MutableSpan local_positions = tls.local_positions; - transform_positions(positions, mat, local_positions); + math::transform_points(positions, mat, local_positions, false); if (angle >= 0.0f) { filter_plane_side_factors(positions, local_positions, scrape_planes, factors); @@ -508,7 +508,7 @@ static void calc_bmesh(const Depsgraph &depsgraph, tls.local_positions.resize(verts.size()); MutableSpan local_positions = tls.local_positions; - transform_positions(positions, mat, local_positions); + math::transform_points(positions, mat, local_positions, false); if (angle >= 0.0f) { filter_plane_side_factors(positions, local_positions, scrape_planes, factors); diff --git a/source/blender/editors/sculpt_paint/brushes/plane.cc b/source/blender/editors/sculpt_paint/brushes/plane.cc index 0b48420450a..f2786bead3e 100644 --- a/source/blender/editors/sculpt_paint/brushes/plane.cc +++ b/source/blender/editors/sculpt_paint/brushes/plane.cc @@ -63,15 +63,6 @@ static void calc_local_positions(const float4x4 &mat, } } -static void calc_local_positions(const float4x4 &mat, - const Span positions, - const MutableSpan local_positions) -{ - for (const int i : positions.index_range()) { - local_positions[i] = math::transform_point(mat, positions[i]); - } -} - /** * Computes the local distances. For vertices above the plane, * the z-distances are divided by `height`, effectively scaling the @@ -280,7 +271,7 @@ static void calc_grids(const Depsgraph &depsgraph, tls.local_positions.resize(positions.size()); const MutableSpan local_positions = tls.local_positions; - calc_local_positions(mat, positions, local_positions); + math::transform_points(positions, mat, local_positions); tls.distances.resize(positions.size()); const MutableSpan distances = tls.distances; @@ -332,7 +323,7 @@ static void calc_bmesh(const Depsgraph &depsgraph, tls.local_positions.resize(positions.size()); const MutableSpan local_positions = tls.local_positions; - calc_local_positions(mat, positions, local_positions); + math::transform_points(positions, mat, local_positions); tls.distances.resize(positions.size()); const MutableSpan distances = tls.distances; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc index 6cc024083c3..8eae5d63768 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc @@ -173,9 +173,7 @@ struct DensityAddOperationExecutor { else { BLI_assert_unreachable(); } - for (float3 &pos : new_positions_cu) { - pos = math::transform_point(transforms_.surface_to_curves, pos); - } + math::transform_points(transforms_.surface_to_curves, new_positions_cu); if (stroke_extension.is_first) { this->prepare_curve_roots_kdtrees(); diff --git a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc index 912aa373f4d..78147b884ec 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc @@ -1591,11 +1591,7 @@ static void process_stroke_weights(const Scene &scene, /* Update the position of the stroke to undo the movement caused by the modifier. */ MutableSpan positions = curves.positions_for_write().slice(points); - threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { - for (float3 &position : positions.slice(range)) { - position = math::transform_point(matrix, position); - } - }); + math::transform_points(matrix, positions); } static bke::CurvesGeometry get_single_stroke(const bke::CurvesGeometry &src, const int curve) diff --git a/source/blender/editors/sculpt_paint/mesh_brush_common.hh b/source/blender/editors/sculpt_paint/mesh_brush_common.hh index 685844c24d1..c7d61c7643f 100644 --- a/source/blender/editors/sculpt_paint/mesh_brush_common.hh +++ b/source/blender/editors/sculpt_paint/mesh_brush_common.hh @@ -82,9 +82,6 @@ void translations_from_new_positions(Span new_positions, Span old_positions, MutableSpan translations); -void transform_positions(Span src, const float4x4 &transform, MutableSpan dst); -void transform_positions(const float4x4 &transform, MutableSpan positions); - /** Gather data from an array aligned with all geometry vertices. */ template void gather_data_mesh(Span src, Span indices, MutableSpan dst); template diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index c08619e65a8..5429430cfe8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -7553,24 +7553,6 @@ void translations_from_new_positions(const Span new_positions, } } -void transform_positions(const Span src, - const float4x4 &transform, - const MutableSpan dst) -{ - BLI_assert(src.size() == dst.size()); - - for (const int i : src.index_range()) { - dst[i] = math::transform_point(transform, src[i]); - } -} - -void transform_positions(const float4x4 &transform, const MutableSpan positions) -{ - for (const int i : positions.index_range()) { - positions[i] = math::transform_point(transform, positions[i]); - } -} - OffsetIndices create_node_vert_offsets(const Span nodes, const IndexMask &node_mask, Array &node_data) diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 23ae80d5a82..4d145fdedf7 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -445,31 +445,6 @@ static bool skip_transform(const float4x4 &transform) return math::is_equal(transform, float4x4::identity(), 1e-6f); } -static void copy_transformed_positions(const Span src, - const float4x4 &transform, - MutableSpan dst) -{ - if (skip_transform(transform)) { - dst.copy_from(src); - } - else { - threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) { - for (const int i : range) { - dst[i] = math::transform_point(transform, src[i]); - } - }); - } -} - -static void transform_positions(const float4x4 &transform, MutableSpan positions) -{ - threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { - for (const int i : range) { - positions[i] = math::transform_point(transform, positions[i]); - } - }); -} - static void threaded_copy(const GSpan src, GMutableSpan dst) { BLI_assert(src.size() == dst.size()); @@ -1236,7 +1211,7 @@ static void execute_realize_pointcloud_task( const PointCloud &pointcloud = *pointcloud_info.pointcloud; const IndexRange point_slice{task.start_index, pointcloud.totpoint}; - copy_transformed_positions( + math::transform_points( pointcloud_info.positions, task.transform, all_dst_positions.slice(point_slice)); /* Create point ids. */ @@ -1294,7 +1269,7 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti const RealizePointCloudTask &task = tasks.first(); PointCloud *new_points = BKE_pointcloud_copy_for_eval(task.pointcloud_info->pointcloud); if (!skip_transform(task.transform)) { - transform_positions(task.transform, new_points->positions_for_write()); + math::transform_points(task.transform, new_points->positions_for_write()); new_points->tag_positions_changed(); } add_instance_attributes_to_single_geometry( @@ -1564,11 +1539,8 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, MutableSpan dst_corner_verts = all_dst_corner_verts.slice(dst_loop_range); MutableSpan dst_corner_edges = all_dst_corner_edges.slice(dst_loop_range); - threading::parallel_for(src_positions.index_range(), 1024, [&](const IndexRange vert_range) { - for (const int i : vert_range) { - dst_positions[i] = math::transform_point(task.transform, src_positions[i]); - } - }); + math::transform_points(src_positions, task.transform, dst_positions); + threading::parallel_for(src_edges.index_range(), 1024, [&](const IndexRange edge_range) { for (const int i : edge_range) { dst_edges[i] = src_edges[i] + task.start_indices.vertex; @@ -1989,7 +1961,7 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options, const IndexRange dst_custom_knot_range{task.start_indices.custom_knot, curves.nurbs_custom_knots_by_curve().total_size()}; - copy_transformed_positions( + math::transform_points( curves.positions(), task.transform, dst_curves.positions_for_write().slice(dst_point_range)); /* Copy and transform handle positions if necessary. */ @@ -1998,14 +1970,14 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options, all_handle_left.slice(dst_point_range).fill(float3(0)); } else { - copy_transformed_positions( + math::transform_points( curves_info.handle_left, task.transform, all_handle_left.slice(dst_point_range)); } if (curves_info.handle_right.is_empty()) { all_handle_right.slice(dst_point_range).fill(float3(0)); } else { - copy_transformed_positions( + math::transform_points( curves_info.handle_right, task.transform, all_handle_right.slice(dst_point_range)); } } diff --git a/source/blender/geometry/intern/transform.cc b/source/blender/geometry/intern/transform.cc index de9949b2d06..8b733cad9ac 100644 --- a/source/blender/geometry/intern/transform.cc +++ b/source/blender/geometry/intern/transform.cc @@ -38,15 +38,6 @@ static void translate_positions(MutableSpan positions, const float3 &tra }); } -static void transform_positions(MutableSpan positions, const float4x4 &matrix) -{ - threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { - for (float3 &position : positions.slice(range)) { - position = math::transform_point(matrix, position); - } - }); -} - static void translate_pointcloud(PointCloud &pointcloud, const float3 translation) { if (math::is_zero(translation)) { @@ -76,7 +67,7 @@ static void transform_pointcloud(PointCloud &pointcloud, const float4x4 &transfo bke::MutableAttributeAccessor attributes = pointcloud.attributes_for_write(); bke::SpanAttributeWriter position = attributes.lookup_or_add_for_write_span( "position", bke::AttrDomain::Point); - transform_positions(position.span, transform); + math::transform_points(transform, position.span); position.finish(); } @@ -177,7 +168,7 @@ static void translate_volume(Volume &volume, const float3 translation) static void transform_curve_edit_hints(bke::CurvesEditHints &edit_hints, const float4x4 &transform) { if (const std::optional> positions = edit_hints.positions_for_write()) { - transform_positions(*positions, transform); + math::transform_points(transform, *positions); } float3x3 deform_mat; copy_m3_m4(deform_mat.ptr(), transform.ptr()); @@ -203,7 +194,7 @@ static void transform_grease_pencil_edit_hints(bke::GreasePencilEditHints &edit_ for (bke::GreasePencilDrawingEditHints &drawing_hints : *edit_hints.drawing_hints) { if (const std::optional> positions = drawing_hints.positions_for_write()) { - transform_positions(*positions, transform); + math::transform_points(transform, *positions); } float3x3 deform_mat = transform.view<3, 3>(); if (drawing_hints.deform_mats.has_value()) { diff --git a/source/blender/io/grease_pencil/intern/grease_pencil_io.cc b/source/blender/io/grease_pencil/intern/grease_pencil_io.cc index bae762b50d5..0f0486f3135 100644 --- a/source/blender/io/grease_pencil/intern/grease_pencil_io.cc +++ b/source/blender/io/grease_pencil/intern/grease_pencil_io.cc @@ -397,11 +397,7 @@ void GreasePencilExporter::foreach_stroke_in_layer(const Object &object, const VArraySpan vertex_colors = drawing.vertex_colors(); Array world_positions(positions.size()); - threading::parallel_for(positions.index_range(), 4096, [&](const IndexRange range) { - for (const int i : range) { - world_positions[i] = math::transform_point(layer_to_world, positions[i]); - } - }); + math::transform_points(positions, layer_to_world, world_positions); for (const int i_curve : curves.curves_range()) { const IndexRange points = points_by_curve[i_curve]; @@ -567,7 +563,7 @@ std::string GreasePencilExporter::coord_to_svg_string(const float2 &screen_co) c if (camera_persmat_) { return fmt::format("{},{}", screen_co.x, camera_rect_.size().y - screen_co.y); } - return fmt::format("{},{}", screen_co.x, screen_rect_.size().y - screen_co.y); - } + return fmt::format("{},{}", screen_co.x, screen_rect_.size().y - screen_co.y); +} } // namespace blender::io::grease_pencil