[Bf-blender-cvs] [0bef196] master: Fix T38811: Cycles particle ids are inconsistent when using multiple particle systems.

Lukas Tönne noreply at git.blender.org
Tue Feb 25 18:34:06 CET 2014


Commit: 0bef196894abd19903b0741ec6250e0558b4f1a4
Author: Lukas Tönne
Date:   Tue Feb 25 18:29:11 2014 +0100
https://developer.blender.org/rB0bef196894abd19903b0741ec6250e0558b4f1a4

Fix T38811: Cycles particle ids are inconsistent when using multiple particle systems.

Problem is that the particle systems in the cycles database are not
stored in a well-defined order. This means the particle_id for dupli
objects can not simply be assigned using a global running index during
sync.

Now the particle index is assigned locally for each particle system.
When transferring particle data to the device as a single texture, the
particle indices are offset based on the final order of particle systems
in the database.

Reviewers: brecht

Reviewed By: brecht

CC: Andreas80

Differential Revision: https://developer.blender.org/D352

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

M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_particles.cpp
M	intern/cycles/render/object.cpp
M	intern/cycles/render/object.h

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

diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 49da938..2ea0b27 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -433,9 +433,6 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
 	BL::Scene::objects_iterator b_ob;
 	BL::Scene b_sce = b_scene;
 
-	/* global particle index counter */
-	int particle_id = 1;
-
 	bool cancel = false;
 
 	for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
@@ -470,13 +467,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
 
 							/* sync possible particle data, note particle_id
 							 * starts counting at 1, first is dummy particle */
-							if(!motion && object && sync_dupli_particle(*b_ob, *b_dup, object)) {
-								if(particle_id != object->particle_id) {
-									object->particle_id = particle_id;
-									scene->object_manager->tag_update(scene);
-								}
-
-								particle_id++;
+							if(!motion && object) {
+								sync_dupli_particle(*b_ob, *b_dup, object);
 							}
 
 						}
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index ef832ed..5b2782e 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -76,6 +76,11 @@ bool BlenderSync::sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Ob
 
 	psys->particles.push_back(pa);
 
+	if (object->particle_index != psys->particles.size() - 1)
+		scene->object_manager->tag_update(scene);
+	object->particle_system = psys;
+	object->particle_index = psys->particles.size() - 1;
+
 	/* return that this object has particle data */
 	return true;
 }
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 3edb934..b40f361 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -19,6 +19,7 @@
 #include "mesh.h"
 #include "curves.h"
 #include "object.h"
+#include "particles.h"
 #include "scene.h"
 
 #include "util_foreach.h"
@@ -38,7 +39,8 @@ Object::Object()
 	visibility = ~0;
 	random_id = 0;
 	pass_id = 0;
-	particle_id = 0;
+	particle_system = NULL;
+	particle_index = 0;
 	bounds = BoundBox::empty;
 	motion.pre = transform_identity();
 	motion.mid = transform_identity();
@@ -154,6 +156,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
 	float4 *objects_vector = NULL;
 	int i = 0;
 	map<Mesh*, float> surface_area_map;
+	map<ParticleSystem*, int> particle_offset;
 	Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
 	bool have_motion = false;
 	bool have_curves = false;
@@ -162,6 +165,15 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
 	if(need_motion == Scene::MOTION_PASS)
 		objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size());
 
+	/* particle system device offsets
+	 * 0 is dummy particle, index starts at 1
+	 */
+	int numparticles = 1;
+	foreach(ParticleSystem *psys, scene->particle_systems) {
+		particle_offset[psys] = numparticles;
+		numparticles += psys->particles.size();
+	}
+
 	foreach(Object *ob, scene->objects) {
 		Mesh *mesh = ob->mesh;
 		uint flag = 0;
@@ -177,6 +189,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
 		float surface_area = 0.0f;
 		float pass_id = ob->pass_id;
 		float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF);
+		int particle_index = (ob->particle_system)? ob->particle_index + particle_offset[ob->particle_system]: 0;
 
 		if(transform_uniform_scale(tfm, uniform_scale)) {
 			map<Mesh*, float>::iterator it = surface_area_map.find(mesh);
@@ -243,7 +256,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
 
 		memcpy(&objects[offset], &tfm, sizeof(float4)*3);
 		memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
-		objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
+		objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(particle_index));
 
 		if(need_motion == Scene::MOTION_PASS) {
 			/* motion transformations, is world/object space depending if mesh
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 5da85be..31400f3 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -27,6 +27,7 @@ CCL_NAMESPACE_BEGIN
 class Device;
 class DeviceScene;
 class Mesh;
+class ParticleSystem;
 class Progress;
 class Scene;
 struct Transform;
@@ -50,7 +51,8 @@ public:
 	float3 dupli_generated;
 	float2 dupli_uv;
 
-	int particle_id;
+	ParticleSystem *particle_system;
+	int particle_index;
 
 	Object();
 	~Object();




More information about the Bf-blender-cvs mailing list