[Bf-blender-cvs] [0d7d8c73cf5] master: Mesh: Use cached looptris in draw cache extraction

Hans Goudey noreply at git.blender.org
Fri Sep 23 15:26:32 CEST 2022


Commit: 0d7d8c73cf5c5c5f05c6a56951e4e5cd24871c12
Author: Hans Goudey
Date:   Fri Sep 23 08:23:35 2022 -0500
Branches: master
https://developer.blender.org/rB0d7d8c73cf5c5c5f05c6a56951e4e5cd24871c12

Mesh: Use cached looptris in draw cache extraction

The mesh's triangulation cache is often created for other operations
besides the drawing code, but during the mesh draw cache extraction
it is recalculated on every single time. It is simpler and faster to use
the existing MLoopTri array. It can also save memory if the cache
already exists by avoiding allocating a duplicate array. For a 4 million
face quad mesh, that is already 128 MB.

Also use face normals for mesh triangulation if they aren't dirty,
which should provide a general speedup when they're both necessary.

Recently 54182e4925de made this more reliable, since the triangulation
cache is invalidated properly when the mesh is deformed.

Fixes T98073

Differential Revision: https://developer.blender.org/D15550

===================================================================

M	source/blender/blenkernel/intern/mesh_runtime.cc
M	source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh.hh

===================================================================

diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc
index 4b6433edd5a..d7a0b73298e 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.cc
+++ b/source/blender/blenkernel/intern/mesh_runtime.cc
@@ -154,12 +154,23 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
   const Span<MPoly> polys = mesh->polys();
   const Span<MLoop> loops = mesh->loops();
 
-  BKE_mesh_recalc_looptri(loops.data(),
-                          polys.data(),
-                          verts.data(),
-                          mesh->totloop,
-                          mesh->totpoly,
-                          mesh->runtime.looptris.array_wip);
+  if (BKE_mesh_poly_normals_are_dirty(mesh)) {
+    BKE_mesh_recalc_looptri_with_normals(loops.data(),
+                                         polys.data(),
+                                         verts.data(),
+                                         mesh->totloop,
+                                         mesh->totpoly,
+                                         mesh->runtime.looptris.array_wip,
+                                         BKE_mesh_poly_normals_ensure(mesh));
+  }
+  else {
+    BKE_mesh_recalc_looptri(loops.data(),
+                            polys.data(),
+                            verts.data(),
+                            mesh->totloop,
+                            mesh->totpoly,
+                            mesh->runtime.looptris.array_wip);
+  }
 
   BLI_assert(mesh->runtime.looptris.array == nullptr);
   atomic_cas_ptr((void **)&mesh->runtime.looptris.array,
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
index eea19cbebf3..2fc54da774d 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
@@ -18,6 +18,7 @@
 #include "BKE_editmesh.h"
 #include "BKE_editmesh_cache.h"
 #include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
 
 #include "GPU_batch.h"
 
@@ -329,28 +330,10 @@ void mesh_render_data_update_looptris(MeshRenderData *mr,
                                       const eMRIterType iter_type,
                                       const eMRDataType data_flag)
 {
-  Mesh *me = mr->me;
   if (mr->extract_type != MR_EXTRACT_BMESH) {
     /* Mesh */
     if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
-      /* NOTE(@campbellbarton): It's possible to skip allocating tessellation,
-       * the tessellation can be calculated as part of the iterator, see: P2188.
-       * The overall advantage is small (around 1%), so keep this as-is. */
-      mr->mlooptri = static_cast<MLoopTri *>(
-          MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI"));
-      if (mr->poly_normals != nullptr) {
-        BKE_mesh_recalc_looptri_with_normals(mr->mloop,
-                                             mr->mpoly,
-                                             mr->mvert,
-                                             me->totloop,
-                                             me->totpoly,
-                                             mr->mlooptri,
-                                             mr->poly_normals);
-      }
-      else {
-        BKE_mesh_recalc_looptri(
-            mr->mloop, mr->mpoly, mr->mvert, me->totloop, me->totpoly, mr->mlooptri);
-      }
+      mr->mlooptri = BKE_mesh_runtime_looptri_ensure(mr->me);
     }
   }
   else {
@@ -605,7 +588,6 @@ MeshRenderData *mesh_render_data_create(Object *object,
 
 void mesh_render_data_free(MeshRenderData *mr)
 {
-  MEM_SAFE_FREE(mr->mlooptri);
   MEM_SAFE_FREE(mr->loop_normals);
 
   /* Loose geometry are owned by #MeshBufferCache. */
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
index 10b94291e35..2a8b7332cc5 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
@@ -78,8 +78,8 @@ struct MeshRenderData {
   BMEdge *eed_act;
   BMFace *efa_act;
   BMFace *efa_act_uv;
-  /* Data created on-demand (usually not for #BMesh based data). */
-  MLoopTri *mlooptri;
+  /* The triangulation of #Mesh polygons, owned by the mesh. */
+  const MLoopTri *mlooptri;
   const int *material_indices;
   const float (*vert_normals)[3];
   const float (*poly_normals)[3];



More information about the Bf-blender-cvs mailing list