[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21810] branches/blender2.5/blender: External cache

Janne Karhu jhkarh at utu.fi
Thu Jul 23 02:19:01 CEST 2009


Revision: 21810
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21810
Author:   jhk
Date:     2009-07-23 02:19:01 +0200 (Thu, 23 Jul 2009)

Log Message:
-----------
External cache

Particle point cache can now be loaded from external files.
- Activated by "external" checkbox in cache panel and giving proper folder path and file name identifier.
- External cache panel has controls for particle emission start, end, lifetime and random lifetime. These should be set according to the external data for correct playback.
- External files should be named "identifier_frame_index.bphys" or "identifier_frame.bphys" where:
	* "identifier" is a freely choseable name.
	* "frame" is the cached frame number.
		** Six digits padded with zeros!, for example "000024".
	* "index" can be used to tell caches with the same identifier apart.
		** Two digits starting from zero.
		** The index and the underscore before are optional. If no index is present the index number in ui should be set to -1.
- Cache file format is pure floating point numbers (in binary, not text!) with each particle's data one after the other with the following data members:
	* 3 floats: particle's location vector
	* 3 floats: particle's velocity vector (per second)
	* 4 floats: particle's rotation quaternion
	* 3 floats: particle's angular velocity vector (per second)
	* 1 float: frame of the actual data (this can be non-integer for particles that are born or die between two integer frames, but otherwise should be the same as the "frame" in the file name)
- Cache files don't have to exist for each frame.
	* Frames without actual data are interpolated from surrounding frames that have data (extrapolation is not supported).
- Cache file formats with extended (or reduced even) data members are in future plans for easier usage.
- Current code only does particles, don't yet know if it's applicable to cloth or sb.
- Known issue: endianness can't yet be handled in any way.

Other changes:

New hard limits for many particle parameters. Some examples:
- Maximum amount of particles: 10M particles :) And before you all go and crash your Blender trying this out remember that this limit is only for those freaks who really have the machine power to handle it. 10M particles alone take around 2.2 Gb of memory / disk space in saved file and each cached frame takes around 0.5 Gb of memory / disk space depending on cache mode.
	* Known issue: To actually use this many particles they most likely need to be allocated in parts as taking hold of a 2.2Gb chunk of memory at once is probably not ok with any operating system.
- Maximum amount of children: 100k children/particle (1T childparticles here we come :D)
- Kink frequency: -100k to 100k half-rotations (really strange the previous limit was only from zero upwards)
- Path draw steps: 10 (power of 2 remember)
- Path render steps: 20 (power of 2 also!! If over 1M segments doesn't get you smooth paths then I think nothing will!)

Modified Paths:
--------------
    branches/blender2.5/blender/release/ui/buttons_particle.py
    branches/blender2.5/blender/source/blender/blenkernel/BKE_pointcache.h
    branches/blender2.5/blender/source/blender/blenkernel/intern/particle_system.c
    branches/blender2.5/blender/source/blender/blenkernel/intern/pointcache.c
    branches/blender2.5/blender/source/blender/makesdna/DNA_object_force.h
    branches/blender2.5/blender/source/blender/makesdna/DNA_particle_types.h
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_object_force.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_particle.c

Modified: branches/blender2.5/blender/release/ui/buttons_particle.py
===================================================================
--- branches/blender2.5/blender/release/ui/buttons_particle.py	2009-07-22 23:27:10 UTC (rev 21809)
+++ branches/blender2.5/blender/release/ui/buttons_particle.py	2009-07-23 00:19:01 UTC (rev 21810)
@@ -86,6 +86,12 @@
 	__idname__= "PARTICLE_PT_emission"
 	__label__ = "Emission"
 	
+	def poll(self, context):
+		if particle_panel_poll(context):
+			return not context.particle_system.point_cache.external
+		else:
+			return False
+	
 	def draw(self, context):
 		layout = self.layout
 
@@ -150,38 +156,61 @@
 		cache = psys.point_cache
 		
 		row = layout.row()
-		row.itemR(cache, "name")
+		row.itemL(text="File Name:")
+		row.itemR(cache, "external")
 		
-		row = layout.row()
-		
-		if cache.baked == True:
-			row.itemO("ptcache.free_bake_particle_system", text="Free Bake")
+		if cache.external:
+			split = layout.split(percentage=0.80)
+			split.itemR(cache, "name", text="")
+			split.itemR(cache, "index", text="")
+			
+			layout.itemL(text="File Path:")
+			layout.itemR(cache, "filepath", text="")
+			
+			layout.itemL(text=cache.info)
+			
+			split = layout.split()
+			
+			col = split.column(align=True)
+			col.itemR(part, "start")
+			col.itemR(part, "end")
+
+			col = split.column(align=True)
+			col.itemR(part, "lifetime")
+			col.itemR(part, "random_lifetime", slider=True)
 		else:
-			row.item_booleanO("ptcache.cache_particle_system", "bake", True, text="Bake")
+			layout.itemR(cache, "name", text="")
+			
+			row = layout.row()
 		
-		subrow = row.row()
-		subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys)
-		subrow.itemO("ptcache.cache_particle_system", text="Calculate to Current Frame")
+			if cache.baked == True:
+				row.itemO("ptcache.free_bake_particle_system", text="Free Bake")
+			else:
+				row.item_booleanO("ptcache.cache_particle_system", "bake", True, text="Bake")
 		
-		row = layout.row()
-		row.enabled = particle_panel_enabled(psys)
-		row.itemO("ptcache.bake_from_particles_cache", text="Current Cache to Bake")
-		row.itemR(cache, "step");
-	
-		row = layout.row()
-		row.enabled = particle_panel_enabled(psys)
-		row.itemR(cache, "quick_cache")
-		row.itemR(cache, "disk_cache")
+			subrow = row.row()
+			subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys)
+			subrow.itemO("ptcache.cache_particle_system", text="Calculate to Current Frame")
+			
+			row = layout.row()
+			row.enabled = particle_panel_enabled(psys)
+			row.itemO("ptcache.bake_from_particles_cache", text="Current Cache to Bake")
+			row.itemR(cache, "step");
 		
-		layout.itemL(text=cache.info)
+			row = layout.row()
+			row.enabled = particle_panel_enabled(psys)
+			row.itemR(cache, "quick_cache")
+			row.itemR(cache, "disk_cache")
 		
-		layout.itemS()
+			layout.itemL(text=cache.info)
+			
+			layout.itemS()
+			
+			row = layout.row()
+			row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
+			row.itemO("ptcache.free_bake_all", text="Free All Bakes")
+			layout.itemO("ptcache.bake_all", text="Update All Dynamics to current frame")
 		
-		row = layout.row()
-		row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
-		row.itemO("ptcache.free_bake_all", text="Free All Bakes")
-		layout.itemO("ptcache.bake_all", text="Update All Dynamics to current frame")
-		
 		# for particles these are figured out automatically
 		#row.itemR(cache, "start_frame")
 		#row.itemR(cache, "end_frame")
@@ -193,7 +222,7 @@
 	def poll(self, context):
 		if particle_panel_poll(context):
 			psys = context.particle_system
-			return psys.settings.physics_type != 'BOIDS'
+			return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
 		else:
 			return False
 
@@ -256,6 +285,12 @@
 class PARTICLE_PT_physics(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_physics"
 	__label__ = "Physics"
+	
+	def poll(self, context):
+		if particle_panel_poll(context):
+			return not context.particle_system.point_cache.external
+		else:
+			return False
 
 	def draw(self, context):
 		layout = self.layout
@@ -399,12 +434,15 @@
 		psys = context.particle_system
 		if psys==None:	return False
 		if psys.settings==None:  return False
+		if psys.point_cache.external: return False
 		return psys.settings.physics_type=='BOIDS'
 	
 	def draw(self, context):
 		boids = context.particle_system.settings.boids
 		layout = self.layout
 		
+		layout.enabled = particle_panel_enabled(psys)
+		
 		# Currently boids can only use the first state so these are commented out for now.
 		#row = layout.row()
 		#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
@@ -764,12 +802,6 @@
 	__label__ = "Effectors"
 	__default_closed__ = True
 	
-	def poll(self, context):
-		psys = context.particle_system
-		if psys==None: return False
-		if psys.settings==None: return False
-		return True;
-	
 	def draw(self, context):
 		layout = self.layout
 

Modified: branches/blender2.5/blender/source/blender/blenkernel/BKE_pointcache.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_pointcache.h	2009-07-22 23:27:10 UTC (rev 21809)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_pointcache.h	2009-07-23 00:19:01 UTC (rev 21810)
@@ -166,4 +166,6 @@
 void BKE_ptcache_make_cache(struct PTCacheBaker* baker);
 void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid);
 
+void BKE_ptcache_load_external(struct PTCacheID *pid);
+
 #endif

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/particle_system.c	2009-07-22 23:27:10 UTC (rev 21809)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/particle_system.c	2009-07-23 00:19:01 UTC (rev 21810)
@@ -3982,7 +3982,8 @@
 		/* update alive status and push events */
 		if(pa->time >= cfra) {
 			pa->alive = pa->time==cfra ? PARS_ALIVE : PARS_UNBORN;
-			reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL);
+			if((psys->pointcache->flag & PTCACHE_EXTERNAL) == 0)
+				reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL);
 		}
 		else if(dietime <= cfra){
 			if(dietime > psys->cfra){
@@ -4303,7 +4304,9 @@
 	oldtotpart = psys->totpart;
 	oldtotchild = psys->totchild;
 
-	if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
+	if(psys->pointcache->flag & PTCACHE_EXTERNAL)
+		totpart = pid.cache->totpoint;
+	else if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
 		totpart = part->grid_res*part->grid_res*part->grid_res;
 	else
 		totpart = psys->part->totpart;

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/pointcache.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/pointcache.c	2009-07-22 23:27:10 UTC (rev 21809)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/pointcache.c	2009-07-23 00:19:01 UTC (rev 21810)
@@ -181,7 +181,11 @@
 
 	lib= (pid)? pid->ob->id.lib: NULL;
 
-	if (G.relbase_valid || lib) {
+	if(pid->cache->flag & PTCACHE_EXTERNAL) {
+		strcpy(filename, pid->cache->path);
+		return BLI_add_slash(filename); /* new strlen() */
+	}
+	else if (G.relbase_valid || lib) {
 		char file[MAX_PTCACHE_PATH]; /* we dont want the dir, only the file */
 		char *blendfilename;
 
@@ -214,14 +218,14 @@
 	filename[0] = '\0';
 	newname = filename;
 	
-	if (!G.relbase_valid) return 0; /* save blend file before using disk pointcache */
+	if (!G.relbase_valid && (pid->cache->flag & PTCACHE_EXTERNAL)==0) return 0; /* save blend file before using disk pointcache */
 	
 	/* start with temp dir */
 	if (do_path) {
 		len = ptcache_path(pid, filename);
 		newname += len;
 	}
-	if(strcmp(pid->cache->name, "")==0) {
+	if(strcmp(pid->cache->name, "")==0 && (pid->cache->flag & PTCACHE_EXTERNAL)==0) {
 		idname = (pid->ob->id.name+2);
 		/* convert chars to hex so they are always a valid filename */
 		while('\0' != *idname) {
@@ -238,7 +242,15 @@
 	}
 
 	if (do_ext) {
-		snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
+		if(pid->cache->flag & PTCACHE_EXTERNAL) {
+			if(pid->cache->index >= 0)
+				snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
+			else
+				snprintf(newname, MAX_PTCACHE_FILE, "_%06d"PTCACHE_EXT, cfra); /* always 6 chars */
+		}
+		else {
+			snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
+		}
 		len += 16;
 	}
 	
@@ -256,7 +268,7 @@
 	if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
 		return NULL;
 
-	if (!G.relbase_valid) return NULL; /* save blend file before using disk pointcache */
+	if (!G.relbase_valid && (pid->cache->flag & PTCACHE_EXTERNAL)==0) return NULL; /* save blend file before using disk pointcache */
 	
 	BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
 
@@ -328,6 +340,21 @@
 	int totframes = 0;
 	char mem_info[64];
 
+	if(cache->flag & PTCACHE_EXTERNAL) {
+		int cfra = cache->startframe;
+
+		for(; cfra<=cache->endframe; cfra++) {
+			if(BKE_ptcache_id_exist(pid, cfra))
+				totframes++;
+		}
+
+		if(totframes)
+			sprintf(cache->info, "%i points read for %i frames", cache->totpoint, totframes);
+		else
+			sprintf(cache->info, "No valid data to read!");
+		return;
+	}
+
 	if(cache->flag & PTCACHE_DISK_CACHE) {
 		int cfra = cache->startframe;
 
@@ -743,7 +770,7 @@
 	char path_full[MAX_PTCACHE_FILE];
 	char ext[MAX_PTCACHE_PATH];
 
-	if(!pid->cache)
+	if(!pid->cache || pid->cache->flag & PTCACHE_BAKED)
 		return;
 
 	/* don't allow clearing for linked objects */
@@ -1408,3 +1435,77 @@
 
 	BKE_ptcache_update_info(pid);
 }
+
+void BKE_ptcache_load_external(PTCacheID *pid)
+{
+	PointCache *cache = pid->cache;
+	int len; /* store the length of the string */
+
+	/* mode is same as fopen's modes */
+	DIR *dir; 
+	struct dirent *de;
+	char path[MAX_PTCACHE_PATH];
+	char filename[MAX_PTCACHE_FILE];
+	char path_full[MAX_PTCACHE_FILE];
+	char ext[MAX_PTCACHE_PATH];
+
+	if(!cache)
+		return;
+
+	cache->startframe = MAXFRAME;
+	cache->endframe = -1;
+	cache->totpoint = 0;
+
+	ptcache_path(pid, path);
+	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list