diff options
author | Hans Goudey <h.goudey@me.com> | 2022-02-16 19:53:40 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-02-16 19:53:58 +0300 |
commit | 5b73017ddb679bb050fe13e4d9e3e5b04ea559b9 (patch) | |
tree | 4afcb238a3cb27e67a9b8abbccad124702298630 /source/blender/blenkernel/intern/pointcloud.cc | |
parent | 399168f3c13fadb41c9fbec8a1b5c56cb6609343 (diff) |
BLI: Generalize short algorithm for finding bounds
Finding the greatest and/or smallest element in an array is a common
need. This commit refactors the point cloud bounds code added in
6d7dbdbb44f379682 to a more general header in blenlib.
This will allow reusing the algorithm for curves without duplicating it.
Differential Revision: https://developer.blender.org/D14053
Diffstat (limited to 'source/blender/blenkernel/intern/pointcloud.cc')
-rw-r--r-- | source/blender/blenkernel/intern/pointcloud.cc | 67 |
1 files changed, 14 insertions, 53 deletions
diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc index 2a4e0715293..3ee46fc4f15 100644 --- a/source/blender/blenkernel/intern/pointcloud.cc +++ b/source/blender/blenkernel/intern/pointcloud.cc @@ -11,6 +11,7 @@ #include "DNA_object_types.h" #include "DNA_pointcloud_types.h" +#include "BLI_bounds.hh" #include "BLI_index_range.hh" #include "BLI_listbase.h" #include "BLI_math_vec_types.hh" @@ -254,68 +255,28 @@ PointCloud *BKE_pointcloud_new_nomain(const int totpoint) return pointcloud; } -struct MinMaxResult { - float3 min; - float3 max; -}; - -static MinMaxResult min_max_no_radii(Span<float3> positions) +static std::optional<blender::bounds::MinMaxResult<float3>> point_cloud_bounds( + const PointCloud &pointcloud) { - using namespace blender::math; - - return blender::threading::parallel_reduce( - positions.index_range(), - 1024, - MinMaxResult{float3(FLT_MAX), float3(-FLT_MAX)}, - [&](IndexRange range, const MinMaxResult &init) { - MinMaxResult result = init; - for (const int i : range) { - min_max(positions[i], result.min, result.max); - } - return result; - }, - [](const MinMaxResult &a, const MinMaxResult &b) { - return MinMaxResult{min(a.min, b.min), max(a.max, b.max)}; - }); -} - -static MinMaxResult min_max_with_radii(Span<float3> positions, Span<float> radii) -{ - using namespace blender::math; - - return blender::threading::parallel_reduce( - positions.index_range(), - 1024, - MinMaxResult{float3(FLT_MAX), float3(-FLT_MAX)}, - [&](IndexRange range, const MinMaxResult &init) { - MinMaxResult result = init; - for (const int i : range) { - result.min = min(positions[i] - radii[i], result.min); - result.max = max(positions[i] + radii[i], result.max); - } - return result; - }, - [](const MinMaxResult &a, const MinMaxResult &b) { - return MinMaxResult{min(a.min, b.min), max(a.max, b.max)}; - }); + Span<float3> positions{reinterpret_cast<float3 *>(pointcloud.co), pointcloud.totpoint}; + if (pointcloud.radius) { + Span<float> radii{pointcloud.radius, pointcloud.totpoint}; + return blender::bounds::min_max_with_radii(positions, radii); + } + return blender::bounds::min_max(positions); } bool BKE_pointcloud_minmax(const PointCloud *pointcloud, float r_min[3], float r_max[3]) { - using namespace blender::math; + using namespace blender; - if (!pointcloud->totpoint) { + const std::optional<bounds::MinMaxResult<float3>> min_max = point_cloud_bounds(*pointcloud); + if (!min_max) { return false; } - Span<float3> positions{reinterpret_cast<float3 *>(pointcloud->co), pointcloud->totpoint}; - const MinMaxResult min_max = (pointcloud->radius) ? - min_max_with_radii(positions, - {pointcloud->radius, pointcloud->totpoint}) : - min_max_no_radii(positions); - - copy_v3_v3(r_min, min(min_max.min, float3(r_min))); - copy_v3_v3(r_max, max(min_max.max, float3(r_max))); + copy_v3_v3(r_min, math::min(min_max->min, float3(r_min))); + copy_v3_v3(r_max, math::max(min_max->max, float3(r_max))); return true; } |