[Bf-blender-cvs] [cdd727b] master: Add functions to compute normals (verts, polys and loops ones) for a given shapekey.

Bastien Montagne noreply at git.blender.org
Mon Oct 12 20:17:52 CEST 2015


Commit: cdd727b7ceab5772503b702322e93620b7df651b
Author: Bastien Montagne
Date:   Mon Oct 12 20:12:55 2015 +0200
Branches: master
https://developer.blender.org/rBcdd727b7ceab5772503b702322e93620b7df651b

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

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

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 d5b3ed4..1edbb45 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -103,6 +103,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 989e5e3..3b86c42 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -2547,7 +2547,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);
 
@@ -2597,7 +2597,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;
@@ -2646,7 +2646,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 36ba43f..362f413 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])
 {
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 8c89a72..b948ed5 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 2fc5350..a65ac51 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -133,7 +133,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 */
@@ -222,18 +222,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++) {
@@ -243,25 +245,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 */
@@ -271,7 +278,9 @@ void BKE_mesh_calc_normals_poly(
 		normal_float_to_short_v3(mv->no, no);
 	}
 
-	MEM_freeN(

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list