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
This commit is contained in:
@@ -1249,15 +1249,6 @@ static void translate_positions(MutableSpan<float3> positions, const float3 &tra
|
||||
});
|
||||
}
|
||||
|
||||
static void transform_positions(MutableSpan<float3> 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);
|
||||
|
||||
@@ -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<blender::float3> src,
|
||||
const blender::float4x4 &transform,
|
||||
blender::MutableSpan<blender::float3> 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<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max(
|
||||
const int frame, const bool use_radius) const
|
||||
{
|
||||
@@ -3471,7 +3458,7 @@ std::optional<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max(
|
||||
}
|
||||
const VArray<float> radius = curves.radius();
|
||||
Array<float3> 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<float3> drawing_bounds = *bounds::min_max(positions_world.as_span());
|
||||
bounds = bounds::merge(bounds, drawing_bounds);
|
||||
|
||||
@@ -1838,15 +1838,6 @@ const blender::VectorSet<int> &Mesh::material_indices_used() const
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
static void transform_positions(MutableSpan<float3> 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<float3> 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<float3 *>(kb->data), kb->totelem), transform);
|
||||
math::transform_points(transform, MutableSpan(static_cast<float3 *>(kb->data), kb->totelem));
|
||||
}
|
||||
}
|
||||
MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
|
||||
@@ -1813,4 +1813,13 @@ extern template float4x4 perspective(
|
||||
void transform_normals(const float3x3 &transform, MutableSpan<float3> normals);
|
||||
void transform_normals(Span<float3> src, const float3x3 &transform, MutableSpan<float3> dst);
|
||||
|
||||
/** Transform point vectors with matrix multiplication, optionally using multi-threading. */
|
||||
void transform_points(const float4x4 &transform,
|
||||
MutableSpan<float3> points,
|
||||
bool use_threading = true);
|
||||
void transform_points(Span<float3> src,
|
||||
const float4x4 &transform,
|
||||
MutableSpan<float3> dst,
|
||||
bool use_threading = true);
|
||||
|
||||
} // namespace blender::math
|
||||
|
||||
@@ -596,4 +596,62 @@ void transform_normals(Span<float3> 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<float3> src,
|
||||
const float4x4 &transform,
|
||||
MutableSpan<float3> dst)
|
||||
{
|
||||
for (const int64_t i : src.index_range()) {
|
||||
dst[i] = math::transform_point(transform, src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void transform_points(const Span<float3> src,
|
||||
const float4x4 &transform,
|
||||
MutableSpan<float3> 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<float3> points)
|
||||
{
|
||||
for (float3 &position : points) {
|
||||
position = math::transform_point(transform, position);
|
||||
}
|
||||
}
|
||||
|
||||
void transform_points(const float4x4 &transform,
|
||||
MutableSpan<float3> 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
|
||||
|
||||
@@ -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<float3> src_positions,
|
||||
const IndexRange range,
|
||||
const float4x4 &transform,
|
||||
MutableSpan<float3> 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<float3> positions = curves.positions();
|
||||
MutableSpan<float3> 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<float> weights = *curves.attributes().lookup_or_default<float>(
|
||||
@@ -532,14 +519,8 @@ static void grease_pencil_cache_add_nurbs(Object &object,
|
||||
|
||||
MutableSpan<float3> 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<float> 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<float3> positions = curves.positions();
|
||||
if (!layer.is_locked()) {
|
||||
MutableSpan<float3> 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<float3> positions_eval = curves.evaluated_positions();
|
||||
|
||||
MutableSpan<float3> 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<float3> handles_left = *curves.handle_positions_left();
|
||||
const Span<float3> 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<float> selected_left = *curves.attributes().lookup_or_default<float>(
|
||||
".selection_handle_left", bke::AttrDomain::Point, true);
|
||||
|
||||
@@ -263,11 +263,7 @@ static wmOperatorStatus bake_grease_pencil_animation_exec(bContext *C, wmOperato
|
||||
|
||||
target_material_indices.finish();
|
||||
MutableSpan<float3> 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) {
|
||||
|
||||
@@ -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<float3> transformed_positions(src_positions.size());
|
||||
math::transform_points(src_positions, transform, transformed_positions);
|
||||
|
||||
Array<float> 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);
|
||||
});
|
||||
|
||||
@@ -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<float3> src_positions = curves.positions();
|
||||
|
||||
/* Get all the positions in world space. */
|
||||
Array<float3> 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<float3> src_positions = curves.positions();
|
||||
|
||||
/* Get all the positions in world space. */
|
||||
Array<float3> 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();
|
||||
|
||||
@@ -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<blender::float3> 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) {
|
||||
|
||||
@@ -509,17 +509,6 @@ std::unique_ptr<XFormObjectData> data_xform_create_from_edit_mode(ID *id)
|
||||
return data_xform_create_ex(id, true);
|
||||
}
|
||||
|
||||
static void copy_transformed_positions(const Span<float3> src,
|
||||
const float4x4 &transform,
|
||||
MutableSpan<float3> 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<float> src,
|
||||
const float4x4 &transform,
|
||||
MutableSpan<float> 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<const XFormObjectData_Curves &>(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<float3> 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<PointCloud *>(xod_base.id);
|
||||
const auto &xod = reinterpret_cast<const XFormObjectData_PointCloud &>(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;
|
||||
}
|
||||
|
||||
@@ -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<float3> 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<PointCloud *>(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) {
|
||||
|
||||
@@ -168,7 +168,7 @@ static void sample_node_surface_mesh(const Depsgraph &depsgraph,
|
||||
|
||||
tls.local_positions.resize(verts.size());
|
||||
MutableSpan<float3> 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<float3> 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<float3> normals = tls.normals;
|
||||
@@ -257,7 +257,7 @@ static void sample_node_surface_bmesh(const Depsgraph &depsgraph,
|
||||
|
||||
tls.local_positions.resize(verts.size());
|
||||
MutableSpan<float3> 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<float3> normals = tls.normals;
|
||||
@@ -385,7 +385,7 @@ static void calc_faces(const Depsgraph &depsgraph,
|
||||
|
||||
tls.local_positions.resize(verts.size());
|
||||
MutableSpan<float3> 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<float3> 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<float3> 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);
|
||||
|
||||
@@ -63,15 +63,6 @@ static void calc_local_positions(const float4x4 &mat,
|
||||
}
|
||||
}
|
||||
|
||||
static void calc_local_positions(const float4x4 &mat,
|
||||
const Span<float3> positions,
|
||||
const MutableSpan<float3> 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<float3> 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<float> distances = tls.distances;
|
||||
@@ -332,7 +323,7 @@ static void calc_bmesh(const Depsgraph &depsgraph,
|
||||
|
||||
tls.local_positions.resize(positions.size());
|
||||
const MutableSpan<float3> 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<float> distances = tls.distances;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<float3> 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)
|
||||
|
||||
@@ -82,9 +82,6 @@ void translations_from_new_positions(Span<float3> new_positions,
|
||||
Span<float3> old_positions,
|
||||
MutableSpan<float3> translations);
|
||||
|
||||
void transform_positions(Span<float3> src, const float4x4 &transform, MutableSpan<float3> dst);
|
||||
void transform_positions(const float4x4 &transform, MutableSpan<float3> positions);
|
||||
|
||||
/** Gather data from an array aligned with all geometry vertices. */
|
||||
template<typename T> void gather_data_mesh(Span<T> src, Span<int> indices, MutableSpan<T> dst);
|
||||
template<typename T>
|
||||
|
||||
@@ -7553,24 +7553,6 @@ void translations_from_new_positions(const Span<float3> new_positions,
|
||||
}
|
||||
}
|
||||
|
||||
void transform_positions(const Span<float3> src,
|
||||
const float4x4 &transform,
|
||||
const MutableSpan<float3> 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<float3> positions)
|
||||
{
|
||||
for (const int i : positions.index_range()) {
|
||||
positions[i] = math::transform_point(transform, positions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
OffsetIndices<int> create_node_vert_offsets(const Span<bke::pbvh::MeshNode> nodes,
|
||||
const IndexMask &node_mask,
|
||||
Array<int> &node_data)
|
||||
|
||||
@@ -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<float3> src,
|
||||
const float4x4 &transform,
|
||||
MutableSpan<float3> 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<float3> 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<int> dst_corner_verts = all_dst_corner_verts.slice(dst_loop_range);
|
||||
MutableSpan<int> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,15 +38,6 @@ static void translate_positions(MutableSpan<float3> positions, const float3 &tra
|
||||
});
|
||||
}
|
||||
|
||||
static void transform_positions(MutableSpan<float3> 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<float3>(
|
||||
"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<MutableSpan<float3>> 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<MutableSpan<float3>> 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()) {
|
||||
|
||||
@@ -397,11 +397,7 @@ void GreasePencilExporter::foreach_stroke_in_layer(const Object &object,
|
||||
const VArraySpan<ColorGeometry4f> vertex_colors = drawing.vertex_colors();
|
||||
|
||||
Array<float3> 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
|
||||
|
||||
Reference in New Issue
Block a user