diff options
author | Hans Goudey <h.goudey@me.com> | 2021-12-22 20:04:03 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-12-22 20:04:03 +0300 |
commit | 6a71b2af66cf10556b21361cc609d54e45be5e3b (patch) | |
tree | 24997a97577fe287f008e5be532610ef88b35ac4 /source/blender/blenkernel/intern | |
parent | 3579a9e0fcf2f1d8adf0fca17ad829d1b1375d1e (diff) |
Mesh: Parallelize bounding box calculation (WIP)
This replaces the single-threaded calculation of mesh min and max
positions with a `parallel_reduce` loop. Since the bounding box
of a mesh is retrieved quite often (at the end of each evaluation,
currently 2(?!) times when leaving edit mode, etc.), this makes for a
quite noticeable speedup actually.
On my Ryzen 3700x and a 4.2 million vertex mesh, I observed
a 4.4x performance increase, from 14 ms to 4.4 ms.
I added some methods to `float3` so they would be inlined, but
they're also a nice addition, since they're used often anyway.
Differential Revision: https://developer.blender.org/D13572
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/mesh.cc | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 05aa9111fa3..334ec0c5423 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -36,13 +36,16 @@ #include "BLI_bitmap.h" #include "BLI_edgehash.h" #include "BLI_endian_switch.h" +#include "BLI_float3.hh" #include "BLI_ghash.h" #include "BLI_hash.h" +#include "BLI_index_range.hh" #include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_memarena.h" #include "BLI_string.h" +#include "BLI_task.hh" #include "BLI_utildefines.h" #include "BLT_translation.h" @@ -1577,13 +1580,35 @@ void BKE_mesh_looptri_get_real_edges(const Mesh *mesh, const MLoopTri *looptri, bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3]) { - int i = me->totvert; - MVert *mvert; - for (mvert = me->mvert; i--; mvert++) { - minmax_v3v3_v3(r_min, r_max, mvert->co); + using namespace blender; + if (me->totvert == 0) { + return false; } - return (me->totvert != 0); + struct Result { + float3 min; + float3 max; + }; + + const Result minmax = threading::parallel_reduce( + IndexRange(me->totvert), + 1024, + Result{float3(FLT_MAX), float3(-FLT_MAX)}, + [&](IndexRange range, const Result &init) { + Result result = init; + for (const int i : range) { + float3::min_max(me->mvert[i].co, result.min, result.max); + } + return result; + }, + [](const Result &a, const Result &b) { + return Result{float3::min(a.min, b.min), float3::max(a.max, b.max)}; + }); + + copy_v3_v3(r_min, float3::min(minmax.min, r_min)); + copy_v3_v3(r_max, float3::max(minmax.max, r_max)); + + return true; } void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) |