diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-02-28 17:29:56 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-02-28 17:29:56 +0300 |
commit | 877f44162853664791f0ff4fa93f856384d0eed7 (patch) | |
tree | ed924b94bebd5cec0ad5455b7e90d481b63ad80a /source/blender/blenkernel/intern/mesh_evaluate.c | |
parent | ea76ec2866d11156b689287f4190dfe4e79314b2 (diff) |
BKE_mesh: add polygon flipping tools.
Those new functions invert the winding of polygons, effectively inverting their normals.
A helper was also added to allow swapping two items in customdata layers.
Being able to invert normals outside of BMesh area is very important in several places,
like IO scripts or customnormals modifiers...
Reviewers: campbellbarton
Differential Revision: https://developer.blender.org/D1814
Diffstat (limited to 'source/blender/blenkernel/intern/mesh_evaluate.c')
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index e3b9b21f341..9fdd541813a 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -3200,6 +3200,57 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData } /** \} */ +/** + * Flip (invert winding of) the given \a mpoly, i.e. reverse order of its loops + * (keeping the same vertex as 'start point'). + * + * \param mpoly the polygon to flip. + * \param mloop the full loops array. + * \param ldata the loops custom data. + */ +void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata) +{ + int loopstart = mpoly->loopstart; + int loopend = loopstart + mpoly->totloop - 1; + const bool loops_in_ldata = (CustomData_get_layer(ldata, CD_MLOOP) == mloop); + + /* Note that we keep same start vertex for flipped face. */ + + /* We also have to update loops' edge + * (they ell get ther original 'other edge', that is, the original edge of their original previous loop)... */ + unsigned int prev_edge_index = mloop[loopstart].e; + mloop[loopstart].e = mloop[loopend].e; + + for (loopstart++; loopend > loopstart; loopstart++, loopend--) { + mloop[loopend].e = mloop[loopend - 1].e; + SWAP(unsigned int, mloop[loopstart].e, prev_edge_index); + + if (!loops_in_ldata) { + SWAP(MLoop, mloop[loopstart], mloop[loopend]); + } + CustomData_swap(ldata, loopstart, loopend); + } + /* Even if we did not swap the other 'pivot' loop, we need to set its swapped edge. */ + if (loopstart == loopend) { + mloop[loopstart].e = prev_edge_index; + } +} + +/** + * Flip (invert winding of) all polygons (used to inverse their normals). + * + * \note Invalidates tessalation, caller must handle that. + */ +void BKE_mesh_polygons_flip( + MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly) +{ + MPoly *mp; + int i; + + for (mp = mpoly, i = 0; i < totpoly; mp++, i++) { + BKE_mesh_polygon_flip(mp, mloop, ldata); + } +} /* -------------------------------------------------------------------- */ |