diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index b85c605f231..6fde16b47f5 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -48,6 +48,7 @@ struct MFace; struct MEdge; struct MVert; struct MDeformVert; +struct MDisps; struct Object; struct CustomData; struct DerivedMesh; @@ -317,6 +318,8 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex( int *r_totloop, int *r_totpoly, struct MLoop **r_mloop, struct MPoly **r_mpoly); +void BKE_mesh_mdisp_flip(struct MDisps *md, const bool use_loop_mdisp_flip); + void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata); void BKE_mesh_polygons_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, int totpoly); diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index fd75a54c1f7..cd463eb3a34 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -3200,6 +3200,46 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData } /** \} */ +/** + * Flip a single MLoop's #MDisps structure, + * low level function to be called from face-flipping code which re-arranged the mdisps themselves. + */ +void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip) +{ + if (UNLIKELY(!md->totdisp || !md->disps)) { + return; + } + + const int sides = (int)sqrt(md->totdisp); + float (*co)[3] = md->disps; + + for (int x = 0; x < sides; x++) { + float *co_a, *co_b; + + for (int y = 0; y < x; y++) { + co_a = co[y * sides + x]; + co_b = co[x * sides + y]; + + swap_v3_v3(co_a, co_b); + SWAP(float, co_a[0], co_a[1]); + SWAP(float, co_b[0], co_b[1]); + + if (use_loop_mdisp_flip) { + co_a[2] *= -1.0f; + co_b[2] *= -1.0f; + } + } + + co_a = co[x * sides + x]; + + SWAP(float, co_a[0], co_a[1]); + + if (use_loop_mdisp_flip) { + co_a[2] *= -1.0f; + } + } +} + /** * Flip (invert winding of) the given \a mpoly, i.e. reverse order of its loops * (keeping the same vertex as 'start point'). diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 86f13e8bd13..f7e709ce9cc 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -37,6 +37,7 @@ #include "BLT_translation.h" #include "BKE_DerivedMesh.h" +#include "BKE_mesh.h" #include "bmesh.h" #include "intern/bmesh_private.h" @@ -1082,42 +1083,8 @@ static bool bm_loop_reverse_loop( l_iter = oldnext; if (cd_loop_mdisp_offset != -1) { - float (*co)[3]; - int x, y, sides; - MDisps *md; - - md = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset); - if (!md->totdisp || !md->disps) - continue; - - sides = (int)sqrt(md->totdisp); - co = md->disps; - - for (x = 0; x < sides; x++) { - float *co_a, *co_b; - - for (y = 0; y < x; y++) { - co_a = co[y * sides + x]; - co_b = co[x * sides + y]; - - swap_v3_v3(co_a, co_b); - SWAP(float, co_a[0], co_a[1]); - SWAP(float, co_b[0], co_b[1]); - - if (use_loop_mdisp_flip) { - co_a[2] *= -1.0f; - co_b[2] *= -1.0f; - } - } - - co_a = co[x * sides + x]; - - SWAP(float, co_a[0], co_a[1]); - - if (use_loop_mdisp_flip) { - co_a[2] *= -1.0f; - } - } + MDisps *md = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset); + BKE_mesh_mdisp_flip(md, use_loop_mdisp_flip); } }