diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-10-12 21:12:55 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-10-12 21:12:55 +0300 |
commit | cdd727b7ceab5772503b702322e93620b7df651b (patch) | |
tree | b7d7f675a464dfe7bd994aeafaed44f21b73779d /source/blender/blenkernel/intern/key.c | |
parent | ee688e24a766d1352d9eac5b22113b118c227ceb (diff) |
Add functions to compute normals (verts, polys and loops ones) for a given shapekey.
Title says pretty much everything, we now have BKE and RNA funcs to get vertex, poly and
loop normals of a given shapekey.
This will be used e.g. in FBX exporter (shapekeys need normal data too).
Reviewed By: campbellbarton
Differential Revision: https://developer.blender.org/D1510
Diffstat (limited to 'source/blender/blenkernel/intern/key.c')
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 36ba43f1e8a..362f41335d2 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -58,6 +58,7 @@ #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_library.h" +#include "BKE_mesh.h" #include "BKE_editmesh.h" #include "BKE_scene.h" @@ -1799,6 +1800,66 @@ void BKE_keyblock_convert_to_mesh(KeyBlock *kb, Mesh *me) } } +/** + * Computes normals (vertices, polygons and/or loops ones) of given mesh for given shape key. + * + * \param kb the KeyBlock to use to compute normals. + * \param mesh the Mesh to apply keyblock to. + * \param r_vertnors if non-NULL, an array of vectors, same length as number of vertices. + * \param r_polynors if non-NULL, an array of vectors, same length as number of polygons. + * \param r_loopnors if non-NULL, an array of vectors, same length as number of loops. + */ +void BKE_keyblock_mesh_calc_normals( + struct KeyBlock *kb, struct Mesh *mesh, + float (*r_vertnors)[3], float (*r_polynors)[3], float (*r_loopnors)[3]) +{ + /* We use a temp, shallow copy of mesh to work. */ + Mesh me; + bool free_polynors = false; + + if (r_vertnors == NULL && r_polynors == NULL && r_loopnors == NULL) { + return; + } + + me = *mesh; + me.mvert = MEM_dupallocN(mesh->mvert); + CustomData_reset(&me.vdata); + CustomData_reset(&me.edata); + CustomData_reset(&me.pdata); + CustomData_reset(&me.ldata); + CustomData_reset(&me.fdata); + + BKE_keyblock_convert_to_mesh(kb, &me); + + if (r_polynors == NULL && r_loopnors != NULL) { + r_polynors = MEM_mallocN(sizeof(float[3]) * me.totpoly, __func__); + free_polynors = true; + } + BKE_mesh_calc_normals_poly( + me.mvert, r_vertnors, me.totvert, me.mloop, me.mpoly, me.totloop, me.totpoly, r_polynors, false); + + if (r_loopnors) { + short (*clnors)[2] = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); /* May be NULL. */ + + BKE_mesh_normals_loop_split( + me.mvert, me.totvert, me.medge, me.totedge, + me.mloop, r_loopnors, me.totloop, me.mpoly, r_polynors, me.totpoly, + (me.flag & ME_AUTOSMOOTH) != 0, me.smoothresh, NULL, clnors, NULL); + } + + CustomData_free(&me.vdata, me.totvert); + CustomData_free(&me.edata, me.totedge); + CustomData_free(&me.pdata, me.totpoly); + CustomData_free(&me.ldata, me.totloop); + CustomData_free(&me.fdata, me.totface); + MEM_freeN(me.mvert); + + if (free_polynors) { + MEM_freeN(r_polynors); + } +} + + /************************* raw coords ************************/ void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { |