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();

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to