[Bf-blender-cvs] [8f33538] master: Cycles code refactor: add motion sampled normals attribute.

Brecht Van Lommel noreply at git.blender.org
Sat Mar 29 15:33:02 CET 2014


Commit: 8f33538fabe9b2485478b7ce0167c15396bdb355
Author: Brecht Van Lommel
Date:   Sat Mar 29 13:03:46 2014 +0100
https://developer.blender.org/rB8f33538fabe9b2485478b7ce0167c15396bdb355

Cycles code refactor: add motion sampled normals attribute.

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

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/scene.cpp

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9e11cc1..ed19fb2 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -601,37 +601,50 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion
 	if(numverts) {
 		/* find attributes */
 		Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+		Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+		Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
 		bool new_attribute = false;
 
 		/* add new attributes if they don't exist already */
 		if(!attr_mP) {
 			attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+			if(attr_N)
+				attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
 
 			new_attribute = true;
 		}
 
 		/* load vertex data from mesh */
 		float3 *mP = attr_mP->data_float3() + time_index*numverts;
+		float3 *mN = (attr_mN)? attr_mN->data_float3() + time_index*numverts: NULL;
 
 		BL::Mesh::vertices_iterator v;
 		int i = 0;
 
-		for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i)
+		for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
 			mP[i] = get_float3(v->co());
+			if(mN)
+				mN[i] = get_float3(v->normal());
+		}
 
 		/* in case of new attribute, we verify if there really was any motion */
 		if(new_attribute) {
 			if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) {
 				/* no motion, remove attributes again */
 				mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+				if(attr_mN)
+					mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
 			}
 			else if(time_index > 0) {
 				/* motion, fill up previous steps that we might have skipped because
 				 * they had no motion, but we need them anyway now */
 				float3 *P = &mesh->verts[0];
+				float3 *N = (attr_N)? attr_N->data_float3(): NULL;
 
-				for(int step = 0; step < time_index; step++)
+				for(int step = 0; step < time_index; step++) {
 					memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
+					memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
+				}
 			}
 		}
 	}
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index f708f01..2590717 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -471,6 +471,7 @@ typedef enum AttributeStandard {
 	ATTR_STD_POSITION_UNDEFORMED,
 	ATTR_STD_POSITION_UNDISPLACED,
 	ATTR_STD_MOTION_VERTEX_POSITION,
+	ATTR_STD_MOTION_VERTEX_NORMAL,
 	ATTR_STD_PARTICLE,
 	ATTR_STD_CURVE_INTERCEPT,
 	ATTR_STD_PTEX_FACE_ID,
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index e730cab..f524a9f 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -165,6 +165,8 @@ const char *Attribute::standard_name(AttributeStandard std)
 		return "undisplaced";
 	else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
 		return "motion_P";
+	else if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
+		return "motion_N";
 	else if(std == ATTR_STD_PARTICLE)
 		return "particle";
 	else if(std == ATTR_STD_CURVE_INTERCEPT)
@@ -275,6 +277,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
 			case ATTR_STD_MOTION_VERTEX_POSITION:
 				attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
 				break;
+			case ATTR_STD_MOTION_VERTEX_NORMAL:
+				attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX_MOTION);
+				break;
 			case ATTR_STD_PTEX_FACE_ID:
 				attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
 				break;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 0d09328..8e2cc97 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -242,6 +242,21 @@ void Mesh::compute_bounds()
 	bounds = bnds;
 }
 
+static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
+{
+	float3 v0 = verts[t.v[0]];
+	float3 v1 = verts[t.v[1]];
+	float3 v2 = verts[t.v[2]];
+
+	float3 norm = cross(v1 - v0, v2 - v0);
+	float normlen = len(norm);
+
+	if(normlen == 0.0f)
+		return make_float3(0.0f, 0.0f, 0.0f);
+
+	return norm / normlen;
+}
+
 void Mesh::add_face_normals()
 {
 	/* don't compute if already there */
@@ -261,17 +276,7 @@ void Mesh::add_face_normals()
 		Triangle *triangles_ptr = &triangles[0];
 
 		for(size_t i = 0; i < triangles_size; i++) {
-			Triangle t = triangles_ptr[i];
-			float3 v0 = verts_ptr[t.v[0]];
-			float3 v1 = verts_ptr[t.v[1]];
-			float3 v2 = verts_ptr[t.v[2]];
-
-			float3 norm = cross(v1 - v0, v2 - v0);
-			float normlen = len(norm);
-			if(normlen == 0.0f)
-				fN[i] = make_float3(0.0f, 0.0f, 0.0f);
-			else
-				fN[i] = norm / normlen;
+			fN[i] = compute_face_normal(triangles_ptr[i], verts_ptr);
 
 			if(flip)
 				fN[i] = -fN[i];
@@ -289,36 +294,69 @@ void Mesh::add_face_normals()
 
 void Mesh::add_vertex_normals()
 {
-	/* don't compute if already there */
-	if(attributes.find(ATTR_STD_VERTEX_NORMAL))
-		return;
-	
-	/* get attributes */
-	Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
-	Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
+	bool flip = transform_negative_scaled;
+	size_t verts_size = verts.size();
+	size_t triangles_size = triangles.size();
 
-	float3 *fN = attr_fN->data_float3();
-	float3 *vN = attr_vN->data_float3();
+	/* static vertex normals */
+	if(!attributes.find(ATTR_STD_VERTEX_NORMAL)) {
+		/* get attributes */
+		Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
+		Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
 
-	/* compute vertex normals */
-	memset(vN, 0, verts.size()*sizeof(float3));
+		float3 *fN = attr_fN->data_float3();
+		float3 *vN = attr_vN->data_float3();
 
-	size_t verts_size = verts.size();
-	size_t triangles_size = triangles.size();
-	bool flip = transform_negative_scaled;
+		/* compute vertex normals */
+		memset(vN, 0, verts.size()*sizeof(float3));
 
-	if(triangles_size) {
-		Triangle *triangles_ptr = &triangles[0];
+		if(triangles_size) {
+			Triangle *triangles_ptr = &triangles[0];
 
-		for(size_t i = 0; i < triangles_size; i++)
-			for(size_t j = 0; j < 3; j++)
-				vN[triangles_ptr[i].v[j]] += fN[i];
+			for(size_t i = 0; i < triangles_size; i++)
+				for(size_t j = 0; j < 3; j++)
+					vN[triangles_ptr[i].v[j]] += fN[i];
+		}
+
+		for(size_t i = 0; i < verts_size; i++) {
+			vN[i] = normalize(vN[i]);
+			if(flip)
+				vN[i] = -vN[i];
+		}
 	}
 
-	for(size_t i = 0; i < verts_size; i++) {
-		vN[i] = normalize(vN[i]);
-		if(flip)
-			vN[i] = -vN[i];
+	/* motion vertex normals */
+	Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+	Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+	if(false && !attr_mN) {
+		/* create attribute */
+		attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+		for(int step = 0; step < motion_steps - 1; step++) {
+			float3 *mP = attr_mP->data_float3() + step*verts.size();
+			float3 *mN = attr_mN->data_float3() + step*verts.size();
+
+			/* compute */
+			memset(mN, 0, verts.size()*sizeof(float3));
+
+			if(triangles_size) {
+				Triangle *triangles_ptr = &triangles[0];
+
+				for(size_t i = 0; i < triangles_size; i++) {
+					for(size_t j = 0; j < 3; j++) {
+						float3 fN = compute_face_normal(triangles_ptr[i], mP);
+						mN[triangles_ptr[i].v[j]] += fN;
+					}
+				}
+			}
+
+			for(size_t i = 0; i < verts_size; i++) {
+				mN[i] = normalize(mN[i]);
+				if(flip)
+					mN[i] = -mN[i];
+			}
+		}
 	}
 }
 
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index f7d2f2d..2ed4efe 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -228,6 +228,8 @@ bool Scene::need_global_attribute(AttributeStandard std)
 		return Pass::contains(film->passes, PASS_UV);
 	if(std == ATTR_STD_MOTION_VERTEX_POSITION)
 		return need_motion() != MOTION_NONE;
+	if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
+		return need_motion() == MOTION_BLUR;
 	
 	return false;
 }




More information about the Bf-blender-cvs mailing list