diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-18 19:00:32 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-18 19:00:32 +0400 |
commit | 497ea5f306a802a3f7aaddd1300d29613eba64af (patch) | |
tree | d42ccf4f8a2191d8b4af7d8407444c975cce930c /intern/cycles | |
parent | c4b46f119c0cf85c25b825e9989dc0d4748cb64d (diff) |
Fix #32912: cycles crash with dead particles, actual crash was caused by an
inconsistency in the particle system code, using <= and <. Also tightened up
checks on cycles side to avoid other potential crashes.
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/blender/blender_particles.cpp | 93 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 1 |
4 files changed, 47 insertions, 61 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 2c32c8ad83f..6de2b0f08fa 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -24,6 +24,7 @@ #include "object.h" #include "scene.h" #include "nodes.h" +#include "particles.h" #include "shader.h" #include "blender_sync.h" @@ -307,6 +308,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) mesh_map.pre_sync(); object_map.pre_sync(); mesh_synced.clear(); + particle_system_map.pre_sync(); } /* object loop */ @@ -362,11 +364,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) object_free_duplilist(*b_ob); } - /* check if we should render or hide particle emitter */ + + /* sync particles and check if we should render or hide particle emitter */ BL::Object::particle_systems_iterator b_psys; - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) + for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { + if(!motion) + sync_particles(*b_ob, *b_psys); + if(b_psys->settings().use_render_emitter()) hide = false; + } if(!hide) { /* object itself */ @@ -393,6 +400,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) scene->mesh_manager->tag_update(scene); if(object_map.post_sync()) scene->object_manager->tag_update(scene); + if(particle_system_map.post_sync()) + scene->particle_system_manager->tag_update(scene); mesh_synced.clear(); } } diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index f309960fc55..c4c6d2f79a3 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -51,7 +51,7 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_PATH: { /* for strand rendering */ BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob.data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } break; @@ -60,10 +60,10 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_OBJECT: { BL::Object b_dupli_ob = b_psys.settings().dupli_object(); - if (b_dupli_ob) { + if(b_dupli_ob) { BL::ID key = (BKE_object_is_modified(b_dupli_ob))? b_dupli_ob: b_dupli_ob.data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } } @@ -72,12 +72,12 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_GROUP: { BL::Group b_dupli_group = b_psys.settings().dupli_group(); - if (b_dupli_group) { + if(b_dupli_group) { BL::Group::objects_iterator b_gob; for (b_dupli_group.objects.begin(b_gob); b_gob != b_dupli_group.objects.end(); ++b_gob) { BL::ID key = (BKE_object_is_modified(*b_gob))? *b_gob: b_gob->data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } } @@ -109,38 +109,43 @@ static bool use_particle_system(BL::ParticleSystem b_psys) return true; } -static bool use_particle(BL::Particle b_pa) +static bool use_particle(BL::Particle b_pa, bool preview, bool show_unborn, bool use_dead) { - return b_pa.is_exist() && b_pa.is_visible() && - (b_pa.alive_state()==BL::Particle::alive_state_ALIVE || b_pa.alive_state()==BL::Particle::alive_state_DYING); + return b_pa.is_exist() && (!preview || b_pa.is_visible()) && + (b_pa.alive_state() != BL::Particle::alive_state_UNBORN || show_unborn) && + (b_pa.alive_state() != BL::Particle::alive_state_DEAD || use_dead); } -static int psys_count_particles(BL::ParticleSystem b_psys) +static int psys_count_particles(BL::ParticleSystem b_psys, bool preview) { - int tot = 0; BL::ParticleSystem::particles_iterator b_pa; - for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) { - if(use_particle(*b_pa)) - ++tot; - } - return tot; + bool show_unborn = b_psys.settings().show_unborn(); + bool use_dead = b_psys.settings().use_dead(); + int num = 0; + + for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) + if(use_particle(*b_pa, preview, show_unborn, use_dead)) + ++num; + + return num; } int BlenderSync::object_count_particles(BL::Object b_ob) { - int tot = 0; BL::Object::particle_systems_iterator b_psys; - for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) { - if (use_particle_system(*b_psys)) - tot += psys_count_particles(*b_psys); - } - return tot; + int num = 0; + + for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) + if(use_particle_system(*b_psys)) + num += psys_count_particles(*b_psys, preview); + + return num; } void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) { /* depending on settings the psys may not even be rendered */ - if (!use_particle_system(b_psys)) + if(!use_particle_system(b_psys)) return; /* key to lookup particle system */ @@ -155,15 +160,19 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) bool need_update = psys_need_update(b_psys); - if (object_updated || need_update) { - int tot = psys_count_particles(b_psys); + if(object_updated || need_update) { + bool show_unborn = b_psys.settings().show_unborn(); + bool use_dead = b_psys.settings().use_dead(); + + int num = psys_count_particles(b_psys, preview); psys->particles.clear(); - psys->particles.reserve(tot); + psys->particles.reserve(num); - int index = 0; BL::ParticleSystem::particles_iterator b_pa; + int index = 0; + for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) { - if(use_particle(*b_pa)) { + if(use_particle(*b_pa, preview, show_unborn, use_dead)) { Particle pa; pa.index = index; @@ -185,34 +194,4 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) } } -void BlenderSync::sync_particle_systems() -{ - /* layer data */ - uint scene_layer = render_layer.scene_layer; - - particle_system_map.pre_sync(); - - /* object loop */ - BL::Scene::objects_iterator b_ob; - BL::Scene b_sce = b_scene; - - for(; b_sce; b_sce = b_sce.background_set()) { - for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) { - bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render(); - uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), render_layer.use_localview, object_is_light(*b_ob)); - hide = hide || !(ob_layer & scene_layer); - - if(!hide) { - BL::Object::particle_systems_iterator b_psys; - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) - sync_particles(*b_ob, *b_psys); - } - } - } - - /* handle removed data and modified pointers */ - if(particle_system_map.post_sync()) - scene->particle_system_manager->tag_update(scene); -} - CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 6c63872333d..24a561116ec 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -142,7 +142,6 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const sync_film(); sync_shaders(); sync_objects(b_v3d); - sync_particle_systems(); sync_motion(b_v3d, b_override); } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index d7fcb014931..36cd5e684a7 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -77,7 +77,6 @@ private: void sync_world(); void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer); void sync_shaders(); - void sync_particle_systems(); void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated); |