[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51408] trunk/blender: Fix #32912: cycles crash with dead particles, actual crash was caused by an

Brecht Van Lommel brechtvanlommel at pandora.be
Thu Oct 18 17:00:32 CEST 2012


Revision: 51408
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51408
Author:   blendix
Date:     2012-10-18 15:00:32 +0000 (Thu, 18 Oct 2012)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/blender_object.cpp
    trunk/blender/intern/cycles/blender/blender_particles.cpp
    trunk/blender/intern/cycles/blender/blender_sync.cpp
    trunk/blender/intern/cycles/blender/blender_sync.h
    trunk/blender/source/blender/blenkernel/intern/particle.c

Modified: trunk/blender/intern/cycles/blender/blender_object.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_object.cpp	2012-10-18 14:23:04 UTC (rev 51407)
+++ trunk/blender/intern/cycles/blender/blender_object.cpp	2012-10-18 15:00:32 UTC (rev 51408)
@@ -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 @@
 		mesh_map.pre_sync();
 		object_map.pre_sync();
 		mesh_synced.clear();
+		particle_system_map.pre_sync();
 	}
 
 	/* object loop */
@@ -362,11 +364,16 @@
 					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 @@
 			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();
 	}
 }

Modified: trunk/blender/intern/cycles/blender/blender_particles.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_particles.cpp	2012-10-18 14:23:04 UTC (rev 51407)
+++ trunk/blender/intern/cycles/blender/blender_particles.cpp	2012-10-18 15:00:32 UTC (rev 51408)
@@ -51,7 +51,7 @@
 		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 @@
 		
 		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 @@
 		
 		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 @@
 	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 @@
 	
 	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_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

Modified: trunk/blender/intern/cycles/blender/blender_sync.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_sync.cpp	2012-10-18 14:23:04 UTC (rev 51407)
+++ trunk/blender/intern/cycles/blender/blender_sync.cpp	2012-10-18 15:00:32 UTC (rev 51408)
@@ -142,7 +142,6 @@
 	sync_film();
 	sync_shaders();
 	sync_objects(b_v3d);
-	sync_particle_systems();
 	sync_motion(b_v3d, b_override);
 }
 

Modified: trunk/blender/intern/cycles/blender/blender_sync.h
===================================================================
--- trunk/blender/intern/cycles/blender/blender_sync.h	2012-10-18 14:23:04 UTC (rev 51407)
+++ trunk/blender/intern/cycles/blender/blender_sync.h	2012-10-18 15:00:32 UTC (rev 51408)
@@ -77,7 +77,6 @@
 	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);

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2012-10-18 14:23:04 UTC (rev 51407)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2012-10-18 15:00:32 UTC (rev 51408)
@@ -4320,7 +4320,7 @@
 	if (pa) {
 		if (!always) {
 			if ((cfra < pa->time    && (part->flag & PART_UNBORN) == 0) ||
-			    (cfra > pa->dietime && (part->flag & PART_DIED)   == 0))
+			    (cfra >= pa->dietime && (part->flag & PART_DIED)  == 0))
 			{
 				return 0;
 			}




More information about the Bf-blender-cvs mailing list