Commit: 8a1860bd9aecddf611b64e3e842bdc8c76f15cc6
Author: Campbell Barton
Date:   Mon Jun 14 22:56:03 2021 +1000
Branches: master
https://developer.blender.org/rB8a1860bd9aecddf611b64e3e842bdc8c76f15cc6

BMesh: support face-normal calculation in normal & looptri functions

Support calculating face normals when tessellating. When this is done
before updating vertex normals it gives ~20% performance improvement.

Now vertex normal calculation only needs to perform a single pass on the
mesh vertices when called after tessellation.

Extended versions of normal & looptri update functions have been added:

- BM_mesh_calc_tessellation_ex
- BM_mesh_normals_update_ex

Most callers don't need to be aware of this detail by using:

- BKE_editmesh_looptri_and_normals_calc
- BKE_editmesh_looptri_and_normals_calc_with_partial

- EDBM_update also takes advantage of this,
  where calling EDBM_update with calc_looptri & calc_normals
  enabled uses the faster normal updating logic.

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

M       source/blender/blenkernel/BKE_editmesh.h
M       source/blender/blenkernel/intern/editmesh.c
M       source/blender/bmesh/intern/bmesh_mesh_normals.c
M       source/blender/bmesh/intern/bmesh_mesh_normals.h
M       source/blender/bmesh/intern/bmesh_mesh_tessellate.c
M       source/blender/bmesh/intern/bmesh_mesh_tessellate.h
M       source/blender/editors/include/ED_mesh.h
M       source/blender/editors/mesh/editmesh_utils.c
M       source/blender/editors/object/object_edit.c
M       source/blender/editors/object/object_hook.c
M       source/blender/editors/object/object_relations.c
M       source/blender/editors/transform/transform_convert_mesh.c
M       source/blender/editors/transform/transform_convert_mesh_skin.c
M       source/blender/makesrna/intern/rna_object.c

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

diff --git a/source/blender/blenkernel/BKE_editmesh.h 
b/source/blender/blenkernel/BKE_editmesh.h
index 3a1eedfd807..075a9bc0eac 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -34,6 +34,7 @@ extern "C" {
 struct BMLoop;
 struct BMesh;
 struct BMPartialUpdate;
+struct BMeshCalcTessellation_Params;
 struct BoundBox;
 struct Depsgraph;
 struct Mesh;
@@ -85,8 +86,17 @@ typedef struct BMEditMesh {
 } BMEditMesh;
 
 /* editmesh.c */
+void BKE_editmesh_looptri_calc_ex(BMEditMesh *em,
+                                  const struct BMeshCalcTessellation_Params 
*params);
 void BKE_editmesh_looptri_calc(BMEditMesh *em);
+void BKE_editmesh_looptri_calc_with_partial_ex(BMEditMesh *em,
+                                               struct BMPartialUpdate *bmpinfo,
+                                               const struct 
BMeshCalcTessellation_Params *params);
 void BKE_editmesh_looptri_calc_with_partial(BMEditMesh *em, struct 
BMPartialUpdate *bmpinfo);
+void BKE_editmesh_looptri_and_normals_calc_with_partial(BMEditMesh *em,
+                                                        struct BMPartialUpdate 
*bmpinfo);
+
+void BKE_editmesh_looptri_and_normals_calc(BMEditMesh *em);
 
 BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate);
 BMEditMesh *BKE_editmesh_copy(BMEditMesh *em);
diff --git a/source/blender/blenkernel/intern/editmesh.c 
b/source/blender/blenkernel/intern/editmesh.c
index 472de1f3c77..b908df267c4 100644
--- a/source/blender/blenkernel/intern/editmesh.c
+++ b/source/blender/blenkernel/intern/editmesh.c
@@ -96,7 +96,8 @@ BMEditMesh *BKE_editmesh_from_object(Object *ob)
   return ((Mesh *)ob->data)->edit_mesh;
 }
 
-static void editmesh_tessface_calc_intern(BMEditMesh *em)
+static void editmesh_tessface_calc_intern(BMEditMesh *em,
+                                          const struct 
BMeshCalcTessellation_Params *params)
 {
   /* allocating space before calculating the tessellation */
 
@@ -130,12 +131,13 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em)
   em->tottri = looptris_tot;
 
   /* after allocating the em->looptris, we're ready to tessellate */
-  BM_mesh_calc_tessellation(em->bm, em->looptris);
+  BM_mesh_calc_tessellation_ex(em->bm, em->looptris, params);
 }
 
-void BKE_editmesh_looptri_calc(BMEditMesh *em)
+void BKE_editmesh_looptri_calc_ex(BMEditMesh *em,
+                                  const struct BMeshCalcTessellation_Params 
*params)
 {
-  editmesh_tessface_calc_intern(em);
+  editmesh_tessface_calc_intern(em, params);
 
   /* commented because editbmesh_build_data() ensures we get tessfaces */
 #if 0
@@ -149,12 +151,58 @@ void BKE_editmesh_looptri_calc(BMEditMesh *em)
 #endif
 }
 
-void BKE_editmesh_looptri_calc_with_partial(BMEditMesh *em, struct 
BMPartialUpdate *bmpinfo)
+void BKE_editmesh_looptri_calc(BMEditMesh *em)
+{
+  BKE_editmesh_looptri_calc_ex(em,
+                               &(const struct BMeshCalcTessellation_Params){
+                                   .face_normals = false,
+                               });
+}
+
+/**
+ * Performing the face normal calculation at the same time as tessellation
+ * gives a reasonable performance boost (approx ~20% faster).
+ */
+void BKE_editmesh_looptri_and_normals_calc(BMEditMesh *em)
+{
+  BKE_editmesh_looptri_calc_ex(em,
+                               &(const struct BMeshCalcTessellation_Params){
+                                   .face_normals = true,
+                               });
+  BM_mesh_normals_update_ex(em->bm,
+                            &(const struct BMeshNormalsUpdate_Params){
+                                .face_normals = false,
+                            });
+}
+
+void BKE_editmesh_looptri_calc_with_partial_ex(BMEditMesh *em,
+                                               struct BMPartialUpdate *bmpinfo,
+                                               const struct 
BMeshCalcTessellation_Params *params)
 {
   BLI_assert(em->tottri == poly_to_tri_count(em->bm->totface, 
em->bm->totloop));
   BLI_assert(em->looptris != NULL);
 
-  BM_mesh_calc_tessellation_with_partial(em->bm, em->looptris, bmpinfo);
+  BM_mesh_calc_tessellation_with_partial_ex(em->bm, em->looptris, bmpinfo, 
params);
+}
+
+void BKE_editmesh_looptri_calc_with_partial(BMEditMesh *em, struct 
BMPartialUpdate *bmpinfo)
+{
+  BKE_editmesh_looptri_calc_with_partial_ex(em, bmpinfo, false);
+}
+
+void BKE_editmesh_looptri_and_normals_calc_with_partial(BMEditMesh *em,
+                                                        struct BMPartialUpdate 
*bmpinfo)
+{
+  BKE_editmesh_looptri_calc_with_partial_ex(em,
+                                            bmpinfo,
+                                            &(const struct 
BMeshCalcTessellation_Params){
+                                                .face_normals = true,
+                                            });
+  BM_mesh_normals_update_with_partial_ex(em->bm,
+                                         bmpinfo,
+                                         &(const struct 
BMeshNormalsUpdate_Params){
+                                             .face_normals = false,
+                                         });
 }
 
 void BKE_editmesh_free_derivedmesh(BMEditMesh *em)
diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.c 
b/source/blender/bmesh/intern/bmesh_mesh_normals.c
index bf30f3a52e1..bddd3da98b7 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_normals.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_normals.c
@@ -240,19 +240,29 @@ static void bm_face_calc_normals_cb(void 
*UNUSED(userdata),
  *
  * Updates the normals of a mesh.
  */
-void BM_mesh_normals_update(BMesh *bm)
+void BM_mesh_normals_update_ex(BMesh *bm, const struct 
BMeshNormalsUpdate_Params *params)
 {
-  /* Calculate all face normals. */
-  TaskParallelSettings settings;
-  BLI_parallel_mempool_settings_defaults(&settings);
-  settings.use_threading = bm->totedge >= BM_OMP_LIMIT;
+  if (params->face_normals) {
+    /* Calculate all face normals. */
+    TaskParallelSettings settings;
+    BLI_parallel_mempool_settings_defaults(&settings);
+    settings.use_threading = bm->totedge >= BM_OMP_LIMIT;
 
-  BM_iter_parallel(bm, BM_FACES_OF_MESH, bm_face_calc_normals_cb, NULL, 
&settings);
+    BM_iter_parallel(bm, BM_FACES_OF_MESH, bm_face_calc_normals_cb, NULL, 
&settings);
+  }
 
   /* Add weighted face normals to vertices, and normalize vert normals. */
   bm_mesh_verts_calc_normals(bm, NULL, NULL, NULL);
 }
 
+void BM_mesh_normals_update(BMesh *bm)
+{
+  BM_mesh_normals_update_ex(bm,
+                            &(const struct BMeshNormalsUpdate_Params){
+                                .face_normals = true,
+                            });
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -277,7 +287,9 @@ static void bm_partial_verts_parallel_range_calc_normal_cb(
  * A version of #BM_mesh_normals_update that updates a subset of geometry,
  * used to avoid the overhead of updating everything.
  */
-void BM_mesh_normals_update_with_partial(BMesh *UNUSED(bm), const 
BMPartialUpdate *bmpinfo)
+void BM_mesh_normals_update_with_partial_ex(BMesh *UNUSED(bm),
+                                            const BMPartialUpdate *bmpinfo,
+                                            const struct 
BMeshNormalsUpdate_Params *params)
 {
   BLI_assert(bmpinfo->params.do_normals);
 
@@ -290,14 +302,25 @@ void BM_mesh_normals_update_with_partial(BMesh 
*UNUSED(bm), const BMPartialUpdat
   BLI_parallel_range_settings_defaults(&settings);
 
   /* Faces. */
-  BLI_task_parallel_range(
-      0, faces_len, faces, bm_partial_faces_parallel_range_calc_normals_cb, 
&settings);
+  if (params->face_normals) {
+    BLI_task_parallel_range(
+        0, faces_len, faces, bm_partial_faces_parallel_range_calc_normals_cb, 
&settings);
+  }
 
   /* Verts. */
   BLI_task_parallel_range(
       0, verts_len, verts, bm_partial_verts_parallel_range_calc_normal_cb, 
&settings);
 }
 
+void BM_mesh_normals_update_with_partial(BMesh *bm, const BMPartialUpdate 
*bmpinfo)
+{
+  BM_mesh_normals_update_with_partial_ex(bm,
+                                         bmpinfo,
+                                         &(const struct 
BMeshNormalsUpdate_Params){
+                                             .face_normals = true,
+                                         });
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.h 
b/source/blender/bmesh/intern/bmesh_mesh_normals.h
index 41191340e9e..ecd627d4bfe 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_normals.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_normals.h
@@ -22,7 +22,19 @@
 
 #include "bmesh_class.h"
 
+struct BMeshNormalsUpdate_Params {
+  /**
+   * When calculating tessellation as well as normals, tessellate & calculate 
face normals
+   * for improved performance. See #BMeshCalcTessellation_Params
+   */
+  bool face_normals;
+};
+
+void BM_mesh_normals_update_ex(BMesh *bm, const struct 
BMeshNormalsUpdate_Params *param);
 void BM_mesh_normals_update(BMesh *bm);
+void BM_mesh_normals_update_with_partial_ex(BMesh *bm,
+                                            const struct BMPartialUpdate 
*bmpinfo,
+                                            const struct 
BMeshNormalsUpdate_Params *param);
 void BM_mesh_normals_update_with_partial(BMesh *bm, const struct 
BMPartialUpdate *bmpinfo);
 
 void BM_verts_calc_normal_vcos(BMesh *bm,
diff --git a/source/blender/bmesh/intern/bmesh_mesh_tessellate.c 
b/source/blender/bmesh/intern/bmesh_mesh_tessellate.c
index 7a95e52ce25..4092ad22ef9 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_tessellate.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_tessellate.c
@@ -50,9 +50,13 @@
 /** \name Default Mesh Tessellation
  * \{ */
 
-static int mesh_calc_tessellation_for_face(BMLoop *(*looptris)[3],
-                                           BMFace *efa,
-                                           MemArena **pf_arena_p)
+/**
+ * \param face_normal: This will be optimized out as a constant.
+ */
+BLI_INLINE int mesh_calc_tessellation_for_face_impl(BMLoop *(*looptris)[3],
+                         

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to