[Bf-blender-cvs] [7f5a864] alembic_basic_io: Add support to write normals in the right scope.

Kévin Dietrich noreply at git.blender.org
Tue Jun 21 14:11:10 CEST 2016


Commit: 7f5a8646ef3bccd8ef45fda03920fc3490638b62
Author: Kévin Dietrich
Date:   Tue Jun 21 14:09:45 2016 +0200
Branches: alembic_basic_io
https://developer.blender.org/rB7f5a8646ef3bccd8ef45fda03920fc3490638b62

Add support to write normals in the right scope.

Smooth (loop) normals are written in a kFacevaryingScope whilst vertex
normals are written in a kVertexScope.

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

M	source/blender/alembic/intern/abc_mesh.cc

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

diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index c193196..b5c14df 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -115,7 +115,8 @@ static void get_vertices(DerivedMesh *dm, std::vector<float> &points)
 
 static void get_topology(DerivedMesh *dm,
                          std::vector<int32_t> &poly_verts,
-                         std::vector<int32_t> &loop_counts)
+                         std::vector<int32_t> &loop_counts,
+                         bool &smooth_normal)
 {
 	const int num_poly = dm->getNumPolys(dm);
 	const int num_loops = dm->getNumLoops(dm);
@@ -127,10 +128,13 @@ static void get_topology(DerivedMesh *dm,
 	poly_verts.reserve(num_loops);
 	loop_counts.reserve(num_poly);
 
+	/* NOTE: data needs to be written in the reverse order. */
 	for (int i = 0; i < num_poly; ++i) {
 		MPoly &poly = mpoly[i];
 		loop_counts.push_back(poly.totloop);
 
+		smooth_normal |= ((poly.flag & ME_SMOOTH) != 0);
+
 		MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
 
 		for (int j = 0; j < poly.totloop; ++j, --loop) {
@@ -178,7 +182,21 @@ void get_creases(DerivedMesh *dm,
 	lengths.resize(sharpnesses.size(), 2);
 }
 
-static void get_normals(DerivedMesh *dm, std::vector<float> &normals)
+static void get_vertex_normals(DerivedMesh *dm, std::vector<float> &normals)
+{
+	normals.clear();
+	normals.resize(dm->getNumVerts(dm) * 3);
+
+	MVert *verts = dm->getVertArray(dm);
+	float no[3];
+
+	for (int i = 0, e = dm->getNumVerts(dm); i < e; ++i) {
+		normal_short_to_float_v3(no, verts[i].no);
+		copy_zup_yup(&normals[i * 3], no);
+	}
+}
+
+static void get_loop_normals(DerivedMesh *dm, std::vector<float> &normals)
 {
 	MPoly *mpoly = dm->getPolyArray(dm);
 	MPoly *mp = mpoly;
@@ -188,28 +206,48 @@ static void get_normals(DerivedMesh *dm, std::vector<float> &normals)
 
 	MVert *verts = dm->getVertArray(dm);
 
-	const size_t num_normals = dm->getNumVerts(dm) * 3;
+	const size_t num_normals = dm->getNumLoops(dm) * 3;
+
+	const float (*lnors)[3] = static_cast<float(*)[3]>(dm->getLoopDataArray(dm, CD_NORMAL));
 
 	normals.clear();
 	normals.resize(num_normals);
 
-	for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i, ++mp) {
-		float no[3];
+	unsigned loop_index = 0;
 
-		/* Flat shaded, use common normal for all verts. */
-		if ((mp->flag & ME_SMOOTH) == 0) {
-			BKE_mesh_calc_poly_normal(mp, ml, verts, no);
-		}
+	/* NOTE: data needs to be written in the reverse order. */
 
-		for (int j = 0; j < mp->totloop; ++ml, ++j) {
-			const int index = ml->v;
+	if (lnors) {
+		for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i, ++mp) {
+			ml = mloop + mp->loopstart + (mp->totloop - 1);
 
-			/* Smooth shaded, use individual vert normals. */
-			if (mp->flag & ME_SMOOTH) {
-				normal_short_to_float_v3(no, verts[index].no);
+			for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
+				const int index = ml->v;
+				copy_zup_yup(&normals[loop_index * 3], lnors[index]);
 			}
+		}
+	}
+	else {
+		float no[3];
 
-			copy_zup_yup(&normals[index * 3], no);
+		for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i, ++mp) {
+			ml = mloop + mp->loopstart + (mp->totloop - 1);
+
+			/* Flat shaded, use common normal for all verts. */
+			if ((mp->flag & ME_SMOOTH) == 0) {
+				BKE_mesh_calc_poly_normal(mp, ml - (mp->totloop - 1), verts, no);
+
+				for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
+					copy_zup_yup(&normals[loop_index * 3], no);
+				}
+			}
+			else {
+				/* Smooth shaded, use individual vert normals. */
+				for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
+					normal_short_to_float_v3(no, verts[ml->v].no);
+					copy_zup_yup(&normals[loop_index * 3], no);
+				}
+			}
 		}
 	}
 }
@@ -362,8 +400,10 @@ void AbcMeshWriter::writeMesh(DerivedMesh *dm)
 	std::vector<float> points, normals;
 	std::vector<int32_t> poly_verts, loop_counts;
 
+	bool smooth_normal = false;
+
 	get_vertices(dm, points);
-	get_topology(dm, poly_verts, loop_counts);
+	get_topology(dm, poly_verts, loop_counts, smooth_normal);
 
 	if (m_first_frame) {
 		writeCommonData(dm, m_mesh_schema);
@@ -394,11 +434,16 @@ void AbcMeshWriter::writeMesh(DerivedMesh *dm)
 	}
 
 	if (m_settings.export_normals) {
-		get_normals(dm, normals);
+		if (smooth_normal) {
+			get_loop_normals(dm, normals);
+		}
+		else {
+			get_vertex_normals(dm, normals);
+		}
 
 		ON3fGeomParam::Sample normals_sample;
 		if (!normals.empty()) {
-			normals_sample.setScope(kVertexScope);
+			normals_sample.setScope((smooth_normal) ? kFacevaryingScope : kVertexScope);
 			normals_sample.setVals(
 			            V3fArraySample(
 			                (const Imath::V3f *)&normals.front(),
@@ -430,8 +475,10 @@ void AbcMeshWriter::writeSubD(DerivedMesh *dm)
 	std::vector<int32_t> poly_verts, loop_counts;
 	std::vector<int32_t> crease_indices, crease_lengths;
 
+	bool smooth_normal = false;
+
 	get_vertices(dm, points);
-	get_topology(dm, poly_verts, loop_counts);
+	get_topology(dm, poly_verts, loop_counts, smooth_normal);
 	get_creases(dm, crease_indices, crease_lengths, crease_sharpness);
 
 	if (m_first_frame) {




More information about the Bf-blender-cvs mailing list