Commit: 8c5c083acc7acf00a12bf0a4e80b77ac5853efa7
Author: Bastien Montagne
Date:   Mon Sep 7 20:11:58 2015 +0200
Branches: shapekeys-normals
https://developer.blender.org/rB8c5c083acc7acf00a12bf0a4e80b77ac5853efa7

Add functions to compute normals (verts, polys and loops ones) for a given 
shapekey.

This is needed to address T46019...

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

M       source/blender/blenkernel/BKE_key.h
M       source/blender/blenkernel/BKE_mesh.h
M       source/blender/blenkernel/intern/cdderivedmesh.c
M       source/blender/blenkernel/intern/data_transfer.c
M       source/blender/blenkernel/intern/key.c
M       source/blender/blenkernel/intern/mesh.c
M       source/blender/blenkernel/intern/mesh_evaluate.c
M       source/blender/blenkernel/intern/mesh_remap.c
M       source/blender/makesrna/intern/rna_key.c
M       source/blender/makesrna/intern/rna_mesh_api.c
M       source/blender/modifiers/intern/MOD_normal_edit.c
M       source/blender/modifiers/intern/MOD_solidify.c

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

diff --git a/source/blender/blenkernel/BKE_key.h 
b/source/blender/blenkernel/BKE_key.h
index abe1228..7496e36 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -101,6 +101,8 @@ void    BKE_keyblock_convert_to_curve(struct KeyBlock *kb, 
struct Curve  *cu, st
 void    BKE_keyblock_update_from_mesh(struct Mesh *me, struct KeyBlock *kb);
 void    BKE_keyblock_convert_from_mesh(struct Mesh *me, struct KeyBlock *kb);
 void    BKE_keyblock_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me);
+void    BKE_keyblock_mesh_calc_normals(
+        struct KeyBlock *kb, struct Mesh *mesh, float (*r_vertnors)[3], float 
(*r_polynors)[3], float (*r_loopnors)[3]);
 
 void    BKE_keyblock_update_from_vertcos(struct Object *ob, struct KeyBlock 
*kb, float (*vertCos)[3]);
 void    BKE_keyblock_convert_from_vertcos(struct Object *ob, struct KeyBlock 
*kb, float (*vertCos)[3]);
diff --git a/source/blender/blenkernel/BKE_mesh.h 
b/source/blender/blenkernel/BKE_mesh.h
index a27688c..5bd8931 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -170,7 +170,7 @@ void BKE_mesh_calc_normals_mapping_ex(
         const struct MFace *mfaces, int numFaces, const int *origIndexFace, 
float (*r_faceNors)[3],
         const bool only_face_normals);
 void BKE_mesh_calc_normals_poly(
-        struct MVert *mverts, int numVerts,
+        struct MVert *mverts, float (*r_vertnors)[3], int numVerts,
         const struct MLoop *mloop, const struct MPoly *mpolys,
         int numLoops, int numPolys, float (*r_polyNors)[3],
         const bool only_face_normals);
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c 
b/source/blender/blenkernel/intern/cdderivedmesh.c
index c3168c0..26dad66 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -2530,7 +2530,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const 
bool only_face_normals)
 
        /* calculate face normals */
        BKE_mesh_calc_normals_poly(
-               cddm->mvert, dm->numVertData, CDDM_get_loops(dm), 
CDDM_get_polys(dm),
+               cddm->mvert, NULL, dm->numVertData, CDDM_get_loops(dm), 
CDDM_get_polys(dm),
                dm->numLoopData, dm->numPolyData, face_nors,
                only_face_normals);
 
@@ -2580,7 +2580,7 @@ void CDDM_calc_normals(DerivedMesh *dm)
        /* we don't want to overwrite any referenced layers */
        cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, 
CD_MVERT, dm->numVertData);
 
-       BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, 
CDDM_get_loops(dm), CDDM_get_polys(dm),
+       BKE_mesh_calc_normals_poly(cddm->mvert, NULL, dm->numVertData, 
CDDM_get_loops(dm), CDDM_get_polys(dm),
                                   dm->numLoopData, dm->numPolyData, NULL, 
false);
 
        cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
@@ -2629,7 +2629,7 @@ void CDDM_calc_loop_normals_spacearr(
        if (!pnors) {
                pnors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, 
numPolys);
        }
-       BKE_mesh_calc_normals_poly(mverts, numVerts, mloops, mpolys, numLoops, 
numPolys, pnors,
+       BKE_mesh_calc_normals_poly(mverts, NULL, numVerts, mloops, mpolys, 
numLoops, numPolys, pnors,
                                   (dm->dirty & DM_DIRTY_NORMALS) ? false : 
true);
 
        dm->dirty &= ~DM_DIRTY_NORMALS;
diff --git a/source/blender/blenkernel/intern/data_transfer.c 
b/source/blender/blenkernel/intern/data_transfer.c
index 53b6f4a..28aaec8 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -291,7 +291,7 @@ static void data_transfer_dtdata_type_preprocess(
                                        poly_nors_dst = 
CustomData_add_layer(pdata_dst, CD_NORMAL, CD_CALLOC, NULL, num_polys_dst);
                                        CustomData_set_layer_flag(pdata_dst, 
CD_NORMAL, CD_FLAG_TEMPORARY);
                                }
-                               BKE_mesh_calc_normals_poly(verts_dst, 
num_verts_dst, loops_dst, polys_dst,
+                               BKE_mesh_calc_normals_poly(verts_dst, NULL, 
num_verts_dst, loops_dst, polys_dst,
                                                           num_loops_dst, 
num_polys_dst, poly_nors_dst, true);
                        }
                        /* Cache loop nors into a temp CDLayer. */
diff --git a/source/blender/blenkernel/intern/key.c 
b/source/blender/blenkernel/intern/key.c
index b591dc1..6b2488f 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"
 
@@ -1774,6 +1775,67 @@ 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 = MEM_dupallocN(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);
+       MEM_freeN(me);
+
+       if (free_polynors) {
+               MEM_freeN(r_polynors);
+       }
+}
+
+
 /************************* raw coords ************************/
 void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, float 
(*vertCos)[3])
 {
diff --git a/source/blender/blenkernel/intern/mesh.c 
b/source/blender/blenkernel/intern/mesh.c
index f85e54a..e783dfe 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2199,8 +2199,9 @@ void BKE_mesh_calc_normals_split(Mesh *mesh)
        }
        else {
                polynors = MEM_mallocN(sizeof(float[3]) * mesh->totpoly, 
__func__);
-               BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert, 
mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
-                                          polynors, false);
+               BKE_mesh_calc_normals_poly(
+                           mesh->mvert, NULL, mesh->totvert,
+                           mesh->mloop, mesh->mpoly, mesh->totloop, 
mesh->totpoly, polynors, false);
                free_polynors = true;
        }
 
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c 
b/source/blender/blenkernel/intern/mesh_evaluate.c
index e8c7107..225ee55 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -132,7 +132,7 @@ void BKE_mesh_calc_normals_mapping_ex(
        if (only_face_normals == false) {
                /* vertex normals are optional, they require some extra 
calculations,
                 * so make them optional */
-               BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, 
numLoops, numPolys, pnors, false);
+               BKE_mesh_calc_normals_poly(mverts, NULL, numVerts, mloop, 
mpolys, numLoops, numPolys, pnors, false);
        }
        else {
                /* only calc poly normals */
@@ -221,18 +221,20 @@ static void mesh_calc_normals_poly_accum(
 }
 
 void BKE_mesh_calc_normals_poly(
-        MVert *mverts, int numVerts,
+        MVert *mverts, float (*r_vertnors)[3], int numVerts,
         const MLoop *mloop, const MPoly *mpolys,
         int UNUSED(numLoops), int numPolys, float (*r_polynors)[3],
         const bool only_face_normals)
 {
        float (*pnors)[3] = r_polynors;
-       float (*tnorms)[3];
+       float (*vnors)[3] = r_vertnors;
+       bool free_vnors = false;
        int i;
        const MPoly *mp;
 
        if (only_face_normals) {
                BLI_assert((pnors != NULL) || (numPolys == 0));
+               BLI_assert(r_vertnors == NULL);
 
 #pragma omp parallel for if (numPolys > BKE_MESH_OMP_LIMIT)
                for (i = 0; i < numPolys; i++) {
@@ -242,25 +244,30 @@ void BKE_mesh_calc_normals_poly(
        }
 
        /* first go through and calculate normals for all the polys */
-       tnorms = MEM_callocN(sizeof(*tnorms) * (size_t)numVerts, __func__);
+       if (vnors == NULL) {
+               vnors = MEM_callocN(sizeof(*vnors) * (size_t)numVerts, 
__func__);
+               free_vnors = true;
+       }
+       else {
+               memset(vnors, 0, sizeof(*vnors) * (size_t)numVerts);
+       }
 
+       mp = mpolys;
        if (pnors) {
-               mp = mpolys;
                for (i = 0; i < numPolys; i++, mp++) {
-                       mesh_calc_normals_poly_accum(mp, mloop + mp->loopstart, 
mverts, pnors[i], tnorms);
+                       mesh_calc_normals_poly_accum(mp, mloop + mp->loopstart, 
mverts, pnors[i], vnors);
                }
        }
        else {
                float tpnor[3];  /* temp poly normal */
-               mp = mpolys;
                for (i = 0; i < numPolys; i++, mp++) {
-                       mesh_calc_normals_poly_accum(mp, mloop + mp->loopstart, 
mverts, tpnor, tnorms);
+                       mesh_calc_normals_poly_accum(mp, mloop + mp->loopstart, 
mverts, tpnor, vnors);
                }
        }
 
        for (i = 0; i < numVerts; i++) {
                MVert *mv = &mverts[i];
-               float *no = tnorms[i];
+               float *no = vnors[i];
 
                if (UNLIKELY(normalize_v3(no) == 0.0f)) {
                        /* following Mesh convention; we use vertex coordinate 
itself for normal in this case */
@@ -270,7 +277,9 @@ void BKE_mesh_calc_normals_

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to