Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/pointcache.c')
-rw-r--r--source/blender/blenkernel/intern/pointcache.c488
1 files changed, 269 insertions, 219 deletions
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index b1319a81f5d..5295a496d2b 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -48,13 +48,13 @@
#include "WM_api.h"
+#include "BKE_anim.h"
#include "BKE_blender.h"
#include "BKE_cloth.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -88,16 +88,12 @@
#include "BLI_winstuff.h"
#endif
-#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
-/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */
-#include <pthread.h>
-extern pthread_key_t gomp_tls_key;
-static void *thread_tls_data;
-#endif
-
#define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); }
#define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); }
+/* could be made into a pointcache option */
+#define DURIAN_POINTCACHE_LIB_OK 1
+
int ptcache_data_size[] = {
sizeof(int), // BPHYS_DATA_INDEX
3 * sizeof(float), // BPHYS_DATA_LOCATION:
@@ -135,7 +131,7 @@ static int ptcache_write_basic_header(PTCacheFile *pf)
return 1;
}
/* Softbody functions */
-static int ptcache_write_softbody(int index, void *soft_v, void **data)
+static int ptcache_write_softbody(int index, void *soft_v, void **data, int cfra)
{
SoftBody *soft= soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -191,13 +187,13 @@ static void ptcache_interpolate_softbody(int index, void *soft_v, void **data, f
VECCOPY(bp->pos, keys->co);
VECCOPY(bp->vec, keys->vel);
}
-static int ptcache_totpoint_softbody(void *soft_v)
+static int ptcache_totpoint_softbody(void *soft_v, int cfra)
{
SoftBody *soft= soft_v;
return soft->totpoint;
}
/* Particle functions */
-static int ptcache_write_particle(int index, void *psys_v, void **data)
+static int ptcache_write_particle(int index, void *psys_v, void **data, int cfra)
{
ParticleSystem *psys= psys_v;
ParticleData *pa = psys->particles + index;
@@ -205,11 +201,9 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
float times[3] = {pa->time, pa->dietime, pa->lifetime};
int step = psys->pointcache->step;
- if(data[BPHYS_DATA_INDEX]) {
- /* No need to store unborn or died particles */
- if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time)
- return 0;
- }
+ /* No need to store unborn or died particles outside cache step bounds */
+ if(data[BPHYS_DATA_INDEX] && (cfra < pa->time - step || cfra > pa->dietime + step))
+ return 0;
PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index);
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co);
@@ -236,8 +230,14 @@ void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, flo
static void ptcache_read_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float *old_data)
{
ParticleSystem *psys= psys_v;
- ParticleData *pa = psys->particles + index;
- BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
+ ParticleData *pa;
+ BoidParticle *boid;
+
+ if(index >= psys->totpart)
+ return;
+
+ pa = psys->particles + index;
+ boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
if(cfra > pa->state.time)
memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey));
@@ -288,10 +288,19 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
static void ptcache_interpolate_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
{
ParticleSystem *psys= psys_v;
- ParticleData *pa = psys->particles + index;
+ ParticleData *pa;
ParticleKey keys[4];
float dfra;
+ if(index >= psys->totpart)
+ return;
+
+ pa = psys->particles + index;
+
+ /* particle wasn't read from first cache so can't interpolate */
+ if((int)cfra1 < pa->time - psys->pointcache->step || (int)cfra1 > pa->dietime + psys->pointcache->step)
+ return;
+
cfra = MIN2(cfra, pa->dietime);
cfra1 = MIN2(cfra1, pa->dietime);
cfra2 = MIN2(cfra2, pa->dietime);
@@ -338,26 +347,20 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
pa->state.time = cfra;
}
-static int ptcache_totpoint_particle(void *psys_v)
+static int ptcache_totpoint_particle(void *psys_v, int cfra)
{
ParticleSystem *psys = psys_v;
return psys->totpart;
}
-static int ptcache_totwrite_particle(void *psys_v)
+static int ptcache_totwrite_particle(void *psys_v, int cfra)
{
ParticleSystem *psys = psys_v;
+ ParticleData *pa= psys->particles;
+ int p, step = psys->pointcache->step;
int totwrite = 0;
- /* TODO for later */
- //if((psys->part->flag & (PART_UNBORN|PART_DIED))==0) {
- // ParticleData *pa= psys->particles;
- // int p, step = psys->pointcache->step;
-
- // for(p=0; p<psys->totpart; p++,pa++)
- // totwrite += (pa->time - step > pa->state.time || pa->dietime + step > pa->state.time);
- //}
- //else
- totwrite= psys->totpart;
+ for(p=0; p<psys->totpart; p++,pa++)
+ totwrite += (cfra >= pa->time - step && cfra <= pa->dietime + step);
return totwrite;
}
@@ -489,7 +492,7 @@ static int ptcache_totwrite_particle(void *psys_v)
//}
//
/* Cloth functions */
-static int ptcache_write_cloth(int index, void *cloth_v, void **data)
+static int ptcache_write_cloth(int index, void *cloth_v, void **data, int cfra)
{
ClothModifierData *clmd= cloth_v;
Cloth *cloth= clmd->clothObject;
@@ -554,10 +557,10 @@ static void ptcache_interpolate_cloth(int index, void *cloth_v, void **data, flo
/* should vert->xconst be interpolated somehow too? - jahka */
}
-static int ptcache_totpoint_cloth(void *cloth_v)
+static int ptcache_totpoint_cloth(void *cloth_v, int cfra)
{
ClothModifierData *clmd= cloth_v;
- return clmd->clothObject->numverts;
+ return clmd->clothObject ? clmd->clothObject->numverts : 0;
}
/* Creating ID's */
@@ -615,11 +618,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
pid->write_header= ptcache_write_basic_header;
pid->read_header= ptcache_read_basic_header;
- pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY);
-
- /* TODO for later */
- //if((psys->part->flag & (PART_UNBORN|PART_DIED))==0)
- // pid->data_types|= (1<<BPHYS_DATA_INDEX);
+ pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY) | (1<<BPHYS_DATA_INDEX);
if(psys->part->phystype == PART_PHYS_BOIDS)
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION) | (1<<BPHYS_DATA_BOIDS);
@@ -635,7 +634,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
}
/* Smoke functions */
-static int ptcache_totpoint_smoke(void *smoke_v)
+static int ptcache_totpoint_smoke(void *smoke_v, int cfra)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
@@ -648,7 +647,7 @@ static int ptcache_totpoint_smoke(void *smoke_v)
}
/* Smoke functions */
-static int ptcache_totpoint_smoke_turbulence(void *smoke_v)
+static int ptcache_totpoint_smoke_turbulence(void *smoke_v, int cfra)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
@@ -803,31 +802,37 @@ static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigne
int r = 0;
unsigned char compressed = 0;
unsigned int in_len;
+#ifdef WITH_LZO
unsigned int out_len = len;
+ size_t sizeOfIt = 5;
+#endif
unsigned char *in;
unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
- size_t sizeOfIt = 5;
ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
if(compressed) {
ptcache_file_read(pf, &in_len, 1, sizeof(unsigned int));
- in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
- ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
-
+ if(in_len==0) {
+ /* do nothing */
+ }
+ else {
+ in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
+ ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
#ifdef WITH_LZO
- if(compressed == 1)
- r = lzo1x_decompress(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
+ if(compressed == 1)
+ r = lzo1x_decompress_safe(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
#endif
#ifdef WITH_LZMA
- if(compressed == 2)
- {
- size_t leni = in_len, leno = out_len;
- ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
- ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
- r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
- }
+ if(compressed == 2)
+ {
+ size_t leni = in_len, leno = out_len;
+ ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
+ ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
+ r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
+ }
#endif
- MEM_freeN(in);
+ MEM_freeN(in);
+ }
}
else {
ptcache_file_read(pf, result, len, sizeof(unsigned char));
@@ -987,7 +992,7 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *cl
pid->info_types= 0;
}
-void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
+void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
{
PTCacheID *pid;
ParticleSystem *psys;
@@ -1029,6 +1034,23 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
}
}
}
+
+ if(scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) {
+ ListBase *lb_dupli_ob;
+
+ if((lb_dupli_ob=object_duplilist(scene, ob))) {
+ DupliObject *dob;
+ for(dob= lb_dupli_ob->first; dob; dob= dob->next) {
+ ListBase lb_dupli_pid;
+ BKE_ptcache_ids_from_object(&lb_dupli_pid, dob->ob, scene, duplis);
+ addlisttolist(lb, &lb_dupli_pid);
+ if(lb_dupli_pid.first)
+ printf("Adding Dupli\n");
+ }
+
+ free_object_duplilist(lb_dupli_ob); /* does restore */
+ }
+ }
}
@@ -1045,22 +1067,22 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
static int ptcache_path(PTCacheID *pid, char *filename)
{
- Library *lib;
+ Library *lib= (pid)? pid->ob->id.lib: NULL;
+ const char *blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: G.sce;
size_t i;
- lib= (pid)? pid->ob->id.lib: NULL;
-
if(pid->cache->flag & PTCACHE_EXTERNAL) {
strcpy(filename, pid->cache->path);
+
+ if(strncmp(filename, "//", 2)==0)
+ BLI_path_abs(filename, blendfilename);
+
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;
-
- blendfilename= (lib)? lib->filename: G.sce;
- BLI_split_dirfile_basic(blendfilename, NULL, file);
+ BLI_split_dirfile(blendfilename, NULL, file);
i = strlen(file);
/* remove .blend */
@@ -1068,7 +1090,7 @@ static int ptcache_path(PTCacheID *pid, char *filename)
file[i-6] = '\0';
snprintf(filename, MAX_PTCACHE_PATH, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */
- BLI_convertstringcode(filename, blendfilename);
+ BLI_path_abs(filename, blendfilename);
return BLI_add_slash(filename); /* new strlen() */
}
@@ -1137,10 +1159,11 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
FILE *fp = NULL;
char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+#ifndef DURIAN_POINTCACHE_LIB_OK
/* don't allow writing for linked objects */
if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
return NULL;
-
+#endif
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);
@@ -1149,7 +1172,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
if (!BLI_exists(filename)) {
return NULL;
}
- fp = fopen(filename, "rb");
+ fp = fopen(filename, "rb");
} else if (mode==PTCACHE_FILE_WRITE) {
BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
fp = fopen(filename, "wb");
@@ -1158,13 +1181,13 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
fp = fopen(filename, "rb+");
}
- if (!fp)
- return NULL;
+ if (!fp)
+ return NULL;
pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile");
pf->fp= fp;
- return pf;
+ return pf;
}
static void ptcache_file_close(PTCacheFile *pf)
@@ -1266,12 +1289,32 @@ static void ptcache_file_seek_pointers(int index, PTCacheFile *pf)
int i, size=0;
int data_types = pf->data_types;
- for(i=0; i<BPHYS_TOT_DATA; i++)
- size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+ if(data_types & (1<<BPHYS_DATA_INDEX)) {
+ int totpoint;
+ /* The simplest solution is to just write to the very end. This may cause
+ * some data duplication, but since it's on disk it's not so bad. The correct
+ * thing would be to search through the file for the correct index and only
+ * write to the end if it's not found, but this could be quite slow.
+ */
+ fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
+ fread(&totpoint, sizeof(int), 1, pf->fp);
+
+ totpoint++;
+
+ fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
+ fwrite(&totpoint, sizeof(int), 1, pf->fp);
+
+ fseek(pf->fp, 0, SEEK_END);
+ }
+ else {
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+
+ /* size of default header + data up to index */
+ fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
+ }
ptcache_file_init_pointers(pf);
- /* size of default header + data up to index */
- fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
}
void BKE_ptcache_mem_init_pointers(PTCacheMem *pm)
{
@@ -1291,13 +1334,24 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
}
}
-void BKE_ptcache_mem_seek_pointers(int index, PTCacheMem *pm)
+int BKE_ptcache_mem_seek_pointers(int point_index, PTCacheMem *pm)
{
int data_types = pm->data_types;
- int i;
+ int i, index = pm->index_array ? pm->index_array[point_index] - 1 : point_index;
+
+ if(index < 0) {
+ /* Can't give proper location without reallocation, so don't give any location.
+ * Some points will be cached improperly, but this only happens with simulation
+ * steps bigger than cache->step, so the cache has to be recalculated anyways
+ * at some point.
+ */
+ return 0;
+ }
for(i=0; i<BPHYS_TOT_DATA; i++)
pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+
+ return 1;
}
static void ptcache_alloc_data(PTCacheMem *pm)
{
@@ -1310,20 +1364,28 @@ static void ptcache_alloc_data(PTCacheMem *pm)
pm->data[i] = MEM_callocN(totpoint * ptcache_data_size[i], "PTCache Data");
}
}
-static void ptcache_free_data(void *data[])
+static void ptcache_free_data(PTCacheMem *pm)
{
+ void **data = pm->data;
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
if(data[i])
MEM_freeN(data[i]);
}
+
+ if(pm->index_array) {
+ MEM_freeN(pm->index_array);
+ pm->index_array = NULL;
+ }
}
static void ptcache_copy_data(void *from[], void *to[])
{
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
- if(from[i])
+ /* note, durian file 03.4b_comp crashes if to[i] is not tested
+ * its NULL, not sure if this should be fixed elsewhere but for now its needed */
+ if(from[i] && to[i])
memcpy(to[i], from[i], ptcache_data_size[i]);
}
}
@@ -1361,7 +1423,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
int ret = 0, error = 0;
/* nothing to read to */
- if(pid->totpoint(pid->calldata) == 0)
+ if(pid->totpoint(pid->calldata, (int)cfra) == 0)
return 0;
if(pid->cache->flag & PTCACHE_READ_INFO) {
@@ -1462,13 +1524,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf)) {
ptcache_file_init_pointers(pf);
totpoint = pf->totpoint;
- index = pf->data_types & BPHYS_DATA_INDEX ? &pf->data.index : &i;
+ index = pf->data_types & (1<<BPHYS_DATA_INDEX) ? &pf->data.index : &i;
}
}
else {
/* fall back to old cache file format */
use_old = 1;
- totpoint = pid->totpoint(pid->calldata);
+ totpoint = pid->totpoint(pid->calldata, (int) cfra);
}
}
if(pf2) {
@@ -1481,13 +1543,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf2)) {
ptcache_file_init_pointers(pf2);
totpoint2 = pf2->totpoint;
- index2 = pf2->data_types & BPHYS_DATA_INDEX ? &pf2->data.index : &i;
+ index2 = pf2->data_types & (1<<BPHYS_DATA_INDEX) ? &pf2->data.index : &i;
}
}
else {
/* fall back to old cache file format */
use_old = 1;
- totpoint2 = pid->totpoint(pid->calldata);
+ totpoint2 = pid->totpoint(pid->calldata, (int) cfra);
}
}
@@ -1500,7 +1562,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(!error)
{
if(pf && pid->read_stream) {
- if(totpoint != pid->totpoint(pid->calldata))
+ if(totpoint != pid->totpoint(pid->calldata, (int) cfra))
error = 1;
else
{
@@ -1510,7 +1572,8 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
}
- totpoint = MIN2(totpoint, pid->totpoint(pid->calldata));
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint = MIN2(totpoint, pid->totpoint(pid->calldata, (int) cfra));
if(!error)
{
@@ -1539,7 +1602,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(!error)
{
if(pf2 && pid->read_stream) {
- if(totpoint2 != pid->totpoint(pid->calldata))
+ if(totpoint2 != pid->totpoint(pid->calldata, (int) cfra))
error = 1;
else
{
@@ -1549,7 +1612,8 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
}
- totpoint2 = MIN2(totpoint2, pid->totpoint(pid->calldata));
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint2 = MIN2(totpoint2, pid->totpoint(pid->calldata, (int) cfra));
if(!error)
{
@@ -1621,41 +1685,40 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
return (error ? 0 : ret);
}
/* TODO for later */
-//static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
-//{
-// int i, *index;
-//
-// if(pm->index_array) {
-// MEM_freeN(pm->index_array);
-// pm->index_array = NULL;
-// }
-//
-// if(!pm->data[BPHYS_DATA_INDEX])
-// return;
-//
-// pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
-// index = pm->data[BPHYS_DATA_INDEX];
-//
-// for(i=0; i<pm->totpoint; i++, index++)
-// pm->index_array[*index] = i;
-//}
+static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
+{
+ int i, *index;
+
+ if(pm->index_array) {
+ MEM_freeN(pm->index_array);
+ pm->index_array = NULL;
+ }
+
+ if(!pm->data[BPHYS_DATA_INDEX])
+ return;
+
+ pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
+ index = pm->data[BPHYS_DATA_INDEX];
+
+ for(i=0; i<pm->totpoint; i++, index++)
+ pm->index_array[*index] = i + 1;
+}
/* writes cache to disk or memory */
int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
{
PointCache *cache = pid->cache;
PTCacheFile *pf= NULL, *pf2= NULL;
int i;
- int totpoint = pid->totpoint(pid->calldata);
+ int totpoint = pid->totpoint(pid->calldata, cfra);
int add = 0, overwrite = 0;
- if(totpoint == 0 || cfra < 0
- || (cfra ? pid->data_types == 0 : pid->info_types == 0))
+ if(totpoint == 0 || (cfra ? pid->data_types == 0 : pid->info_types == 0))
return 0;
if(cache->flag & PTCACHE_DISK_CACHE) {
- int ofra, efra = cache->endframe;
+ int ofra=0, efra = cache->endframe;
- if(cfra==0)
+ if(cfra==0 && cache->startframe > 0)
add = 1;
/* allways start from scratch on the first frame */
else if(cfra == cache->startframe) {
@@ -1690,7 +1753,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
return 0;
pf->type = pid->type;
- pf->totpoint = cfra ? totpoint : pid->totwrite(pid->calldata);
+ pf->totpoint = cfra ? pid->totwrite(pid->calldata, cfra) : totpoint;
pf->data_types = cfra ? pid->data_types : pid->info_types;
if(!ptcache_file_write_header_begin(pf) || !pid->write_header(pf)) {
@@ -1707,7 +1770,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
else
for(i=0; i<totpoint; i++) {
if(pid->write_elem) {
- int write = pid->write_elem(i, pid->calldata, pf->cur);
+ int write = pid->write_elem(i, pid->calldata, pf->cur, cfra);
if(write) {
if(!ptcache_file_write_data(pf)) {
ptcache_file_close(pf);
@@ -1727,7 +1790,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
pf2->data_types = pid->data_types;
}
ptcache_file_seek_pointers(i, pf2);
- pid->write_elem(i, pid->calldata, pf2->cur);
+ pid->write_elem(i, pid->calldata, pf2->cur, cfra);
if(!ptcache_file_write_data(pf2)) {
ptcache_file_close(pf);
ptcache_file_close(pf2);
@@ -1773,7 +1836,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
- pm->totpoint = pid->totwrite(pid->calldata);
+ pm->totpoint = pid->totwrite(pid->calldata, cfra);
pm->data_types = cfra ? pid->data_types : pid->info_types;
ptcache_alloc_data(pm);
@@ -1781,20 +1844,20 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
for(i=0; i<totpoint; i++) {
if(pid->write_elem) {
- int write = pid->write_elem(i, pid->calldata, pm->cur);
+ int write = pid->write_elem(i, pid->calldata, pm->cur, cfra);
if(write) {
BKE_ptcache_mem_incr_pointers(pm);
/* newly born particles have to be copied to previous cached frame */
if(overwrite && write == 2) {
pm2 = cache->mem_cache.last;
- BKE_ptcache_mem_seek_pointers(i, pm2);
- pid->write_elem(i, pid->calldata, pm2->cur);
+ if(BKE_ptcache_mem_seek_pointers(i, pm2))
+ pid->write_elem(i, pid->calldata, pm2->cur, cfra);
}
}
}
}
- //ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
pm->frame = cfra;
BLI_addtail(&cache->mem_cache, pm);
@@ -1839,9 +1902,11 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
if(!pid->cache || pid->cache->flag & PTCACHE_BAKED)
return;
+#ifndef DURIAN_POINTCACHE_LIB_OK
/* don't allow clearing for linked objects */
if(pid->ob->id.lib)
return;
+#endif
/*if (!G.relbase_valid) return; *//* save blend file before using pointcache */
@@ -1865,7 +1930,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
if (mode == PTCACHE_CLEAR_ALL) {
- pid->cache->last_exact = 0;
+ pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
} else {
@@ -1897,17 +1962,18 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
pm= pid->cache->mem_cache.first;
if(mode == PTCACHE_CLEAR_ALL) {
- pid->cache->last_exact = 0;
+ /*we want startframe if the cache starts before zero*/
+ pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
for(; pm; pm=pm->next)
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
BLI_freelistN(&pid->cache->mem_cache);
} else {
while(pm) {
if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra) ||
(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra) ) {
link = pm;
+ ptcache_free_data(pm);
pm = pm->next;
- ptcache_free_data(link->data);
BLI_freelinkN(&pid->cache->mem_cache, link);
}
else
@@ -1929,7 +1995,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
for(; pm; pm=pm->next) {
if(pm->frame == cfra) {
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
BLI_freelinkN(&pid->cache->mem_cache, pm);
break;
}
@@ -2047,9 +2113,8 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
}
if(reset) {
- cache->flag &= ~(PTCACHE_REDO_NEEDED|PTCACHE_SIMULATION_VALID);
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
if(pid->type == PTCACHE_TYPE_CLOTH)
cloth_free_modifier(pid->ob, pid->calldata);
@@ -2214,11 +2279,8 @@ void BKE_ptcache_free_mem(ListBase *mem_cache)
PTCacheMem *pm = mem_cache->first;
if(pm) {
- for(; pm; pm=pm->next) {
- ptcache_free_data(pm->data);
- if(pm->index_array)
- MEM_freeN(pm->index_array);
- }
+ for(; pm; pm=pm->next)
+ ptcache_free_data(pm);
BLI_freelistN(mem_cache);
}
@@ -2271,38 +2333,6 @@ PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old
/* Baking */
-static int count_quick_cache(Scene *scene, int *quick_step)
-{
- Base *base = scene->base.first;
- PTCacheID *pid;
- ListBase pidlist;
- int autocache_count= 0;
-
- for(base = scene->base.first; base; base = base->next) {
- if(base->object) {
- BKE_ptcache_ids_from_object(&pidlist, base->object);
-
- for(pid=pidlist.first; pid; pid=pid->next) {
- if((pid->cache->flag & PTCACHE_BAKED)
- || (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
- continue;
-
- if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
- if(!autocache_count)
- *quick_step = pid->cache->step;
- else
- *quick_step = MIN2(*quick_step, pid->cache->step);
-
- autocache_count++;
- }
- }
-
- BLI_freelistN(&pidlist);
- }
- }
-
- return autocache_count;
-}
void BKE_ptcache_quick_cache_all(Scene *scene)
{
PTCacheBaker baker;
@@ -2317,9 +2347,9 @@ void BKE_ptcache_quick_cache_all(Scene *scene)
baker.render=0;
baker.anim_init = 0;
baker.scene=scene;
+ baker.quick_step=scene->physics_settings.quick_cache_step;
- if(count_quick_cache(scene, &baker.quick_step))
- BKE_ptcache_make_cache(&baker);
+ BKE_ptcache_make_cache(&baker);
}
/* Simulation thread, no need for interlocks as data written in both threads
@@ -2336,13 +2366,12 @@ typedef struct {
static void *ptcache_make_cache_thread(void *ptr) {
ptcache_make_cache_data *data = (ptcache_make_cache_data*)ptr;
-#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
- // Workaround for Apple gcc 4.2.1 omp vs background thread bug
- pthread_setspecific (gomp_tls_key, thread_tls_data);
-#endif
-
- for(; (*data->cfra_ptr <= data->endframe) && !data->break_operation; *data->cfra_ptr+=data->step)
+ for(; (*data->cfra_ptr <= data->endframe) && !data->break_operation; *data->cfra_ptr+=data->step) {
scene_update_for_newframe(data->scene, data->scene->lay);
+ if(G.background) {
+ printf("bake: frame %d :: %d\n", (int)*data->cfra_ptr, data->endframe);
+ }
+ }
data->thread_ended = TRUE;
return NULL;
@@ -2352,6 +2381,7 @@ static void *ptcache_make_cache_thread(void *ptr) {
void BKE_ptcache_make_cache(PTCacheBaker* baker)
{
Scene *scene = baker->scene;
+ Scene *sce; /* SETLOOPER macro only */
Base *base;
ListBase pidlist;
PTCacheID *pid = baker->pid;
@@ -2377,13 +2407,18 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
/* cache/bake a single object */
cache = pid->cache;
if((cache->flag & PTCACHE_BAKED)==0) {
- if(pid->type==PTCACHE_TYPE_PARTICLES)
- psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe);
+ if(pid->type==PTCACHE_TYPE_PARTICLES) {
+ ParticleSystem *psys= pid->calldata;
+
+ /* a bit confusing, could make this work better in the UI */
+ if(psys->part->type == PART_EMITTER)
+ psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe);
+ }
else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) {
/* get all pids from the object and search for smoke low res */
ListBase pidlist2;
PTCacheID *pid2;
- BKE_ptcache_ids_from_object(&pidlist2, pid->ob);
+ BKE_ptcache_ids_from_object(&pidlist2, pid->ob, scene, MAX_DUPLI_RECUR);
for(pid2=pidlist2.first; pid2; pid2=pid2->next) {
if(pid2->type == PTCACHE_TYPE_SMOKE_DOMAIN)
{
@@ -2416,9 +2451,9 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
cache->flag &= ~PTCACHE_BAKED;
}
}
- else for(base=scene->base.first; base; base= base->next) {
+ else for(SETLOOPER(scene, base)) {
/* cache/bake everything in the scene */
- BKE_ptcache_ids_from_object(&pidlist, base->object);
+ BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
for(pid=pidlist.first; pid; pid=pid->next) {
cache = pid->cache;
@@ -2458,40 +2493,40 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
thread_data.thread_ended = FALSE;
old_progress = -1;
-#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
- // Workaround for Apple gcc 4.2.1 omp vs background thread bug
- thread_tls_data = pthread_getspecific(gomp_tls_key);
-#endif
- BLI_init_threads(&threads, ptcache_make_cache_thread, 1);
- BLI_insert_thread(&threads, (void*)&thread_data);
-
- while (thread_data.thread_ended == FALSE) {
+ if(G.background) {
+ ptcache_make_cache_thread((void*)&thread_data);
+ }
+ else {
+ BLI_init_threads(&threads, ptcache_make_cache_thread, 1);
+ BLI_insert_thread(&threads, (void*)&thread_data);
- if(bake)
- progress = (int)(100.0f * (float)(CFRA - startframe)/(float)(thread_data.endframe-startframe));
- else
- progress = CFRA;
+ while (thread_data.thread_ended == FALSE) {
- /* NOTE: baking should not redraw whole ui as this slows things down */
- if ((baker->progressbar) && (progress != old_progress)) {
- baker->progressbar(baker->progresscontext, progress);
- old_progress = progress;
- }
-
- /* Delay to lessen CPU load from UI thread */
- PIL_sleep_ms(200);
+ if(bake)
+ progress = (int)(100.0f * (float)(CFRA - startframe)/(float)(thread_data.endframe-startframe));
+ else
+ progress = CFRA;
- /* NOTE: breaking baking should leave calculated frames in cache, not clear it */
- if(blender_test_break() && !thread_data.break_operation) {
- thread_data.break_operation = TRUE;
- if (baker->progressend)
- baker->progressend(baker->progresscontext);
- WM_cursor_wait(1);
+ /* NOTE: baking should not redraw whole ui as this slows things down */
+ if ((baker->progressbar) && (progress != old_progress)) {
+ baker->progressbar(baker->progresscontext, progress);
+ old_progress = progress;
+ }
+
+ /* Delay to lessen CPU load from UI thread */
+ PIL_sleep_ms(200);
+
+ /* NOTE: breaking baking should leave calculated frames in cache, not clear it */
+ if(blender_test_break() && !thread_data.break_operation) {
+ thread_data.break_operation = TRUE;
+ if (baker->progressend)
+ baker->progressend(baker->progresscontext);
+ WM_cursor_wait(1);
+ }
}
- }
BLI_end_threads(&threads);
-
+ }
/* clear baking flag */
if(pid) {
cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
@@ -2503,8 +2538,8 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
BKE_ptcache_write_cache(pid, 0);
}
}
- else for(base=scene->base.first; base; base= base->next) {
- BKE_ptcache_ids_from_object(&pidlist, base->object);
+ else for(SETLOOPER(scene, base)) {
+ BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
for(pid=pidlist.first; pid; pid=pid->next) {
/* skip hair particles */
@@ -2587,7 +2622,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
cache->flag |= PTCACHE_DISK_CACHE;
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
MEM_freeN(pm);
ptcache_file_close(pf);
@@ -2597,7 +2632,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
BKE_ptcache_mem_incr_pointers(pm);
}
- //ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
BLI_addtail(&pid->cache->mem_cache, pm);
@@ -2629,7 +2664,8 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
ptcache_file_init_pointers(pf);
if(!ptcache_file_write_header_begin(pf) || !pid->write_header(pf)) {
- printf("Error writing to disk cache\n");
+ if (G.f & G_DEBUG)
+ printf("Error writing to disk cache\n");
cache->flag &= ~PTCACHE_DISK_CACHE;
ptcache_file_close(pf);
@@ -2639,7 +2675,8 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
for(i=0; i<pm->totpoint; i++) {
ptcache_copy_data(pm->cur, pf->cur);
if(!ptcache_file_write_data(pf)) {
- printf("Error writing to disk cache\n");
+ if (G.f & G_DEBUG)
+ printf("Error writing to disk cache\n");
cache->flag &= ~PTCACHE_DISK_CACHE;
ptcache_file_close(pf);
@@ -2655,7 +2692,8 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
BKE_ptcache_write_cache(pid, 0);
}
else
- printf("Error creating disk cache file\n");
+ if (G.f & G_DEBUG)
+ printf("Error creating disk cache file\n");
}
}
void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
@@ -2665,7 +2703,8 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
if (!G.relbase_valid){
cache->flag &= ~PTCACHE_DISK_CACHE;
- printf("File must be saved before using disk cache!\n");
+ if (G.f & G_DEBUG)
+ printf("File must be saved before using disk cache!\n");
return;
}
@@ -2813,16 +2852,14 @@ void BKE_ptcache_update_info(PTCacheID *pid)
}
else {
PTCacheMem *pm = cache->mem_cache.first;
- float framesize = 0.0f, bytes = 0.0f;
- int mb;
-
- if(pm)
- framesize = (float)ptcache_pid_old_elemsize(pid) * (float)pm->totpoint;
+ float bytes = 0.0f;
+ int i, mb;
- for(; pm; pm=pm->next)
+ for(; pm; pm=pm->next) {
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ bytes += pm->data[i] ? MEM_allocN_len(pm->data[i]) : 0.0f;
totframes++;
-
- bytes = totframes * framesize;
+ }
mb = (bytes > 1024.0f * 1024.0f);
@@ -2841,3 +2878,16 @@ void BKE_ptcache_update_info(PTCacheID *pid)
else
sprintf(cache->info, "%s.", mem_info);
}
+
+void BKE_ptcache_validate(PointCache *cache, int framenr)
+{
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe = framenr;
+}
+void BKE_ptcache_invalidate(PointCache *cache)
+{
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe = 0;
+ cache->last_exact = MIN2(cache->startframe, 0);
+}
+