[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29079] trunk/blender: Some cleanup of particle path drawing logic:

Janne Karhu jhkarh at gmail.com
Sun May 30 16:53:26 CEST 2010


Revision: 29079
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29079
Author:   jhk
Date:     2010-05-30 16:53:26 +0200 (Sun, 30 May 2010)

Log Message:
-----------
Some cleanup of particle path drawing logic:
* Path drawing now works for non hair particles.
* Should fix the following bugs too:
  [#21316] Hair weight drawing is wrong
  [#21923] Consistent Crash When Rendering Particle Scene.
  [#21950] Path rendering option for particles causes crash

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/properties_particle.py
    trunk/blender/source/blender/blenkernel/BKE_particle.h
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/editors/physics/particle_edit.c
    trunk/blender/source/blender/editors/space_view3d/drawobject.c
    trunk/blender/source/blender/render/intern/source/convertblender.c

Modified: trunk/blender/release/scripts/ui/properties_particle.py
===================================================================
--- trunk/blender/release/scripts/ui/properties_particle.py	2010-05-30 14:05:58 UTC (rev 29078)
+++ trunk/blender/release/scripts/ui/properties_particle.py	2010-05-30 14:53:26 UTC (rev 29079)
@@ -705,12 +705,6 @@
             sub = split.column()
             sub.prop(part, "velocity_length")
         elif part.ren_as == 'PATH':
-
-            if part.type != 'HAIR' and part.physics_type != 'KEYED' and (psys.point_cache.baked is False):
-                box = layout.box()
-                box.label(text="Baked or keyed particles needed for correct rendering.")
-                return
-
             sub.prop(part, "render_strand")
             subsub = sub.column()
             subsub.active = (part.render_strand is False)
@@ -862,11 +856,6 @@
 
         path = (part.ren_as == 'PATH' and part.draw_as == 'RENDER') or part.draw_as == 'PATH'
 
-        if path and part.type != 'HAIR' and part.physics_type != 'KEYED' and psys.point_cache.baked is False:
-            box = layout.box()
-            box.label(text="Baked or keyed particles needed for correct drawing.")
-            return
-
         row = layout.row()
         row.prop(part, "display", slider=True)
         if part.draw_as != 'RENDER' or part.ren_as == 'HALO':

Modified: trunk/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_particle.h	2010-05-30 14:05:58 UTC (rev 29078)
+++ trunk/blender/source/blender/blenkernel/BKE_particle.h	2010-05-30 14:53:26 UTC (rev 29079)
@@ -255,9 +255,11 @@
 void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
 
 /* particle_system.c */
+void psys_update_path_cache(struct ParticleSimulationData *sim, float cfra);
 struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
 void psys_count_keyed_targets(struct ParticleSimulationData *sim);
 void psys_update_particle_tree(struct ParticleSystem *psys, float cfra);
+void psys_update_children(struct ParticleSimulationData *sim);
 
 void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
 void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra);

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2010-05-30 14:05:58 UTC (rev 29078)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2010-05-30 14:53:26 UTC (rev 29079)
@@ -433,7 +433,7 @@
 		}
 	}
 }
-static void free_child_path_cache(ParticleSystem *psys)
+void psys_free_child_path_cache(ParticleSystem *psys)
 {
 	psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs);
 	psys->childcache = NULL;
@@ -451,7 +451,7 @@
 		psys->pathcache= NULL;
 		psys->totcached= 0;
 
-		free_child_path_cache(psys);
+		psys_free_child_path_cache(psys);
 	}
 }
 void psys_free_children(ParticleSystem *psys)
@@ -462,7 +462,7 @@
 		psys->totchild=0;
 	}
 
-	free_child_path_cache(psys);
+	psys_free_child_path_cache(psys);
 }
 void psys_free_particles(ParticleSystem *psys)
 {
@@ -1037,6 +1037,7 @@
 	ParticleKey *kkey[2];
 
 	PointCache *cache;
+	PTCacheMem *pm;
 
 	PTCacheEditPoint *epoint;
 	PTCacheEditKey *ekey[2];
@@ -1045,31 +1046,74 @@
 	int bspline;
 } ParticleInterpolationData;
 /* Assumes pointcache->mem_cache exists, so for disk cached particles call psys_make_temp_pointcache() before use */
-static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, int index, float t, ParticleKey *key1, ParticleKey *key2)
+/* It uses ParticleInterpolationData->pm to store the current memory cache frame so it's thread safe. */
+static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, PTCacheMem **cur, int index, float t, ParticleKey *key1, ParticleKey *key2)
 {
-	static PTCacheMem *pm = NULL; /* not thread safe */
+	static PTCacheMem *pm = NULL;
 
 	if(index < 0) { /* initialize */
-		pm = cache->mem_cache.first;
+		*cur = cache->mem_cache.first;
 
-		if(pm)
-			pm = pm->next;
+		if(*cur)
+			*cur = (*cur)->next;
 	}
 	else {
-		if(pm) {
-			while(pm && pm->next && (float)pm->frame < t)
-				pm = pm->next;
+		if(*cur) {
+			while(*cur && (*cur)->next && (float)(*cur)->frame < t)
+				*cur = (*cur)->next;
 
+			pm = *cur;
+
 			BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] - 1 : index, pm->data, (float)pm->frame);
-			BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] - 1 : index, pm->prev->data, (float)pm->prev->frame);
+			if(pm->prev->index_array && pm->prev->index_array[index] == 0)
+				copy_particle_key(key1, key2, 1);
+			else
+				BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] - 1 : index, pm->prev->data, (float)pm->prev->frame);
 		}
 		else if(cache->mem_cache.first) {
-			PTCacheMem *pm2 = cache->mem_cache.first;
-			BKE_ptcache_make_particle_key(key2, pm2->index_array ? pm2->index_array[index] - 1 : index, pm2->data, (float)pm2->frame);
+			pm = cache->mem_cache.first;
+			BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] - 1 : index, pm->data, (float)pm->frame);
 			copy_particle_key(key1, key2, 1);
 		}
 	}
 }
+static int get_pointcache_times_for_particle(PointCache *cache, int index, float *start, float *end)
+{
+	PTCacheMem *pm;
+	int ret = 0;
+
+	for(pm=cache->mem_cache.first; pm; pm=pm->next) {
+		if(pm->index_array) {
+			if(pm->index_array[index]) {
+				*start = pm->frame;
+				ret++;
+				break;
+			}
+		}
+		else {
+			*start = pm->frame;
+			ret++;
+			break;
+		}
+	}
+
+	for(pm=cache->mem_cache.last; pm; pm=pm->prev) {
+		if(pm->index_array) {
+			if(pm->index_array[index]) {
+				*end = pm->frame;
+				ret++;
+				break;
+			}
+		}
+		else {
+			*end = pm->frame;
+			ret++;
+			break;
+		}
+	}
+
+	return ret == 2;
+}
 static void init_particle_interpolation(Object *ob, ParticleSystem *psys, ParticleData *pa, ParticleInterpolationData *pind)
 {
 
@@ -1091,10 +1135,15 @@
 		pind->dietime = (key + pa->totkey - 1)->time;
 	}
 	else if(pind->cache) {
-		get_pointcache_keys_for_time(ob, pind->cache, -1, 0.0f, NULL, NULL);
-
+		float start, end;
+		get_pointcache_keys_for_time(ob, pind->cache, &pind->pm, -1, 0.0f, NULL, NULL);
 		pind->birthtime = pa ? pa->time : pind->cache->startframe;
 		pind->dietime = pa ? pa->dietime : pind->cache->endframe;
+
+		if(get_pointcache_times_for_particle(pind->cache, pa - psys->particles, &start, &end)) {
+			pind->birthtime = MAX2(pind->birthtime, start);
+			pind->dietime = MIN2(pind->dietime, end);
+		}
 	}
 	else {
 		HairKey *key = pa->hair;
@@ -1224,7 +1273,7 @@
 		memcpy(keys + 2, pind->kkey[1], sizeof(ParticleKey));
 	}
 	else if(pind->cache) {
-		get_pointcache_keys_for_time(NULL, pind->cache, p, real_t, keys+1, keys+2);
+		get_pointcache_keys_for_time(NULL, pind->cache, &pind->pm, p, real_t, keys+1, keys+2);
 	}
 	else {
 		hair_to_particle(keys + 1, pind->hkey[0]);
@@ -2672,7 +2721,7 @@
 	}
 	else {
 		/* clear out old and create new empty path cache */
-		free_child_path_cache(sim->psys);
+		psys_free_child_path_cache(sim->psys);
 		sim->psys->childcache= psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx->steps+1);
 		sim->psys->totchildcache = totchild;
 	}
@@ -2743,7 +2792,7 @@
 	int keyed, baked;
 
 	/* we don't have anything valid to create paths from so let's quit here */
-	if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
+	if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache)==0)
 		return;
 
 	if(psys_in_edit_mode(sim->scene, psys))
@@ -2753,7 +2802,7 @@
 	BLI_srandom(psys->seed);
 
 	keyed = psys->flag & PSYS_KEYED;
-	baked = !hair_dm && psys->pointcache->flag & PTCACHE_BAKED;
+	baked = !hair_dm && psys->pointcache->mem_cache.first;
 
 	/* clear out old and create new empty path cache */
 	psys_free_path_cache(psys, psys->edit);
@@ -3148,7 +3197,7 @@
 
 	edit->totcached = totpart;
 
-	if(psys && psys->part->type == PART_HAIR) {
+	if(psys) {
 		ParticleSimulationData sim = {scene, ob, psys, psys_get_modifier(ob, psys), NULL};
 		psys_cache_child_paths(&sim, cfra, 1);
 	}

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-05-30 14:05:58 UTC (rev 29078)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-05-30 14:53:26 UTC (rev 29079)
@@ -3075,66 +3075,18 @@
 /*			Hair								*/
 /************************************************/
 /* check if path cache or children need updating and do it if needed */
-static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
+void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
 {
 	ParticleSystem *psys = sim->psys;
 	ParticleSettings *part = psys->part;
-	ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
-	int distr=0, alloc=0, skip=0;
-
-	if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
-		alloc=1;
-
-	if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
-		distr=1;
-
-	if(distr){
-		if(alloc)
-			realloc_particles(sim, sim->psys->totpart);
-
-		if(get_psys_tot_child(sim->scene, psys)) {
-			/* don't generate children while computing the hair keys */
-			if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
-				distribute_particles(sim, PART_FROM_CHILD);
-
-				if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
-					psys_find_parents(sim);
-			}
-		}
-		else
-			psys_free_children(psys);
-	}
-
-	if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
-		skip = 1; /* only hair, keyed and baked stuff can have paths */
-	else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
-		skip = 1; /* particle visualization must be set as path */
-	else if(!psys->renderdata) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list