diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-06-14 15:56:03 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-06-14 16:01:19 +0300 |
commit | 8a1860bd9aecddf611b64e3e842bdc8c76f15cc6 (patch) | |
tree | 52afad79ca08551fa22bb35d082719299f0476ef /source/blender/blenkernel | |
parent | 6bef2559047461794eb3ff27de15f4caf5ddcf1e (diff) |
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.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_editmesh.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editmesh.c | 60 |
2 files changed, 64 insertions, 6 deletions
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) |