[Bf-blender-cvs] [99f5993] master: Cycles code refactor: improve vertex motion attribute storage and export.

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


Commit: 99f59930885ed69890967f8864a3aa0626249d86
Author: Brecht Van Lommel
Date:   Sat Mar 29 13:03:46 2014 +0100
https://developer.blender.org/rB99f59930885ed69890967f8864a3aa0626249d86

Cycles code refactor: improve vertex motion attribute storage and export.

This now supports multiple steps and subframe sampling of motion.

There is one difference for object and camera transform motion blur. It still
only supports two steps there, but the transforms are now sampled at subframe
times instead of the previous and next frame and then interpolated/extrapolated.
This will give different render results in some cases but it's more accurate.

Part of the code is from the summer of code project by Gavin Howard, but it has
been significantly rewritten and extended.

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

M	intern/cycles/blender/blender_camera.cpp
M	intern/cycles/blender/blender_curves.cpp
M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_sync.h
M	intern/cycles/kernel/geom/geom_object.h
M	intern/cycles/kernel/kernel_camera.h
M	intern/cycles/kernel/kernel_primitive.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/object.cpp
M	intern/cycles/render/object.h
M	intern/cycles/render/scene.cpp

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

diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 4c6b42a..6bbd410 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -386,7 +386,7 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
 	blender_camera_sync(cam, &bcam, width, height);
 }
 
-void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
+void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
 {
 	Camera *cam = scene->camera;
 
@@ -394,12 +394,14 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
 	tfm = blender_camera_matrix(tfm, cam->type);
 
 	if(tfm != cam->matrix) {
-		if(motion == -1)
+		if(motion_time == -1.0f) {
 			cam->motion.pre = tfm;
-		else
+			cam->use_motion = true;
+		}
+		else if(motion_time == 1.0f) {
 			cam->motion.post = tfm;
-
-		cam->use_motion = true;
+			cam->use_motion = true;
+		}
 	}
 }
 
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 4420a30..22de7b6 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -612,16 +612,23 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
 	}
 }
 
-static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int motion)
+static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int time_index)
 {
+	/* find attribute */
+	Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+	bool new_attribute = false;
+
+	/* add new attribute if it doesn't exist already */
+	if(!attr_mP) {
+		attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+		new_attribute = true;
+	}
+
 	/* export motion vectors for curve keys */
-	AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST;
-	Attribute *attr_motion = mesh->curve_attributes.add(std);
-	float4 *data_motion = attr_motion->data_float4();
-	float4 *current_motion = data_motion;
-	size_t size = mesh->curve_keys.size();
-	size_t i = 0;
+	size_t numkeys = mesh->curve_keys.size();
+	float4 *mP = attr_mP->data_float4() + time_index*numkeys;
 	bool have_motion = false;
+	int i = 0;
 
 	for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
 		if(CData->psys_curvenum[sys] == 0)
@@ -640,16 +647,14 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
 					if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
 						radius = 0.0f;
 
-					*current_motion = float3_to_float4(ickey_loc);
-					current_motion->w = radius;
+					mP[i] = float3_to_float4(ickey_loc);
+					mP[i].w = radius;
 
 					/* unlike mesh coordinates, these tend to be slightly different
 					 * between frames due to particle transforms into/out of object
 					 * space, so we use an epsilon to detect actual changes */
-					if(len_squared(*current_motion - mesh->curve_keys[i]) > 1e-5f*1e-5f)
+					if(len_squared(mP[i] - mesh->curve_keys[i]) > 1e-5f*1e-5f)
 						have_motion = true;
-
-					current_motion++;
 				}
 
 				i++;
@@ -657,8 +662,23 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
 		}
 	}
 
-	if(i != size || !have_motion)
-		mesh->curve_attributes.remove(std);
+	/* in case of new attribute, we verify if there really was any motion */
+	if(new_attribute) {
+		if(i != numkeys || !have_motion) {
+			/* no motion, remove attributes again */
+			mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+		}
+		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 */
+			for(int step = 0; step < time_index; step++) {
+				float4 *mP = attr_mP->data_float4() + step*numkeys;
+
+				for(int key = 0; key < numkeys; key++)
+					mP[key] = mesh->curve_keys[key];
+			}
+		}
+	}
 }
 
 void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *uvdata)
@@ -804,7 +824,7 @@ void BlenderSync::sync_curve_settings()
 		curve_system_manager->tag_update(scene);
 }
 
-void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int motion)
+void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index)
 {
 	if(!motion) {
 		/* Clear stored curve data */
@@ -859,7 +879,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int
 	}
 	else {
 		if(motion)
-			ExportCurveSegmentsMotion(scene, mesh, &CData, motion);
+			ExportCurveSegmentsMotion(scene, mesh, &CData, time_index);
 		else
 			ExportCurveSegments(scene, mesh, &CData);
 	}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index b356537..9e11cc1 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -449,6 +449,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
 	Mesh *mesh;
 
 	if(!mesh_map.sync(&mesh, key)) {
+		
 		/* if transform was applied to mesh, need full update */
 		if(object_updated && mesh->transform_applied);
 		/* test if shaders changed, these can be object level so mesh
@@ -503,7 +504,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
 			}
 
 			if(render_layer.use_hair)
-				sync_curves(mesh, b_mesh, b_ob, 0);
+				sync_curves(mesh, b_mesh, b_ob, false);
 
 			/* free derived mesh */
 			b_data.meshes.remove(b_mesh);
@@ -544,46 +545,103 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
 	return mesh;
 }
 
-void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
+void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time)
 {
-	/* todo: displacement, subdivision */
-	size_t size = mesh->verts.size();
-
-	/* skip objects without deforming modifiers. this is not a totally reliable,
-	 * would need a more extensive check to see which objects are animated */
-	if(!size || !ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview))
-		return;
-
 	/* ensure we only sync instanced meshes once */
+	Mesh *mesh = object->mesh;
+
 	if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
 		return;
 
 	mesh_motion_synced.insert(mesh);
 
+	/* for motion pass always compute, for motion blur it can be disabled */
+	int time_index = 0;
+
+	if(scene->need_motion() == Scene::MOTION_BLUR) {
+		/* see if this mesh needs motion data at this time */
+		vector<float> object_times = object->motion_times();
+		bool found = false;
+
+		foreach(float object_time, object_times) {
+			if(motion_time == object_time) {
+				found = true;
+				break;
+			}
+			else
+				time_index++;
+		}
+
+		if(!found)
+			return;
+	}
+	else {
+		if(motion_time == -1.0f)
+			time_index = 0;
+		else if(motion_time == 1.0f)
+			time_index = 1;
+		else
+			return;
+	}
+
+	/* skip objects without deforming modifiers. this is not totally reliable,
+	 * would need a more extensive check to see which objects are animated */
+	size_t numverts = mesh->verts.size();
+	size_t numkeys = mesh->curve_keys.size();
+
+	if((!numverts && !numkeys) || !ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview))
+		return;
+	
 	/* get derived mesh */
 	BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false);
 
-	if(b_mesh) {
-		BL::Mesh::vertices_iterator v;
-		AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST;
-		Attribute *attr_M = mesh->attributes.add(std);
-		float3 *M = attr_M->data_float3(), *cur_M;
-		size_t i = 0;
+	if(!b_mesh)
+		return;
+	
+	if(numverts) {
+		/* find attributes */
+		Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+		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);
+
+			new_attribute = true;
+		}
+
+		/* load vertex data from mesh */
+		float3 *mP = attr_mP->data_float3() + time_index*numverts;
 
-		for(b_mesh.vertices.begin(v), cur_M = M; v != b_mesh.vertices.end() && i < size; ++v, cur_M++, i++)
-			*cur_M = get_float3(v->co());
+		BL::Mesh::vertices_iterator v;
+		int i = 0;
 
-		/* if number of vertices changed, or if coordinates stayed the same, drop it */
-		if(i != size || memcmp(M, &mesh->verts[0], sizeof(float3)*size) == 0)
-			mesh->attributes.remove(std);
+		for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i)
+			mP[i] = get_float3(v->co());
 
-		/* hair motion */
-		if(render_layer.use_hair)
-			sync_curves(mesh, b_mesh, b_ob, motion);
+		/* 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);
+			}
+			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];
 
-		/* free derived mesh */
-		b_data.meshes.remove(b_mesh);
+				for(int step = 0; step < time_index; step++)
+					memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
+			}
+		}
 	}
+
+	/* hair motion */
+	if(numkeys)
+		sync_curves(mesh, b_mesh, b_ob, true, time_index);
+
+	/* free derived mesh */
+	b_data.meshes.remove(b_mesh);
 }
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 6ffc8c8..f5945a6 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -217,9 +217,11 @@ void BlenderSync::sync_background_light()
 
 /* Object */
 
-Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, bool hide_tris)
+Object *BlenderSync::sync_object(BL::Object b

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list