Keyed physics refresh:
[blender-staging.git] / source / blender / blenkernel / intern / pointcache.c
1 /**
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22 * Contributor(s): Campbell Barton <ideasman42@gmail.com>
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_ID.h"
36 #include "DNA_cloth_types.h"
37 #include "DNA_modifier_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_object_force.h"
40 #include "DNA_particle_types.h"
41 #include "DNA_scene_types.h"
42
43 #include "BLI_blenlib.h"
44
45 #include "BKE_cloth.h"
46 #include "BKE_depsgraph.h"
47 #include "BKE_global.h"
48 #include "BKE_library.h"
49 #include "BKE_main.h"
50 #include "BKE_modifier.h"
51 #include "BKE_object.h"
52 #include "BKE_particle.h"
53 #include "BKE_pointcache.h"
54 #include "BKE_scene.h"
55 #include "BKE_softbody.h"
56 #include "BKE_utildefines.h"
57
58 #include "BLI_blenlib.h"
59
60 /* needed for directory lookup */
61 #ifndef WIN32
62   #include <dirent.h>
63 #else
64   #include "BLI_winstuff.h"
65 #endif
66
67 /* untitled blend's need getpid for a unique name */
68 #ifdef WIN32
69 #include <process.h>
70 #else
71 #include <unistd.h>
72 #endif
73
74 #ifdef _WIN32
75 #ifndef snprintf
76 #define snprintf _snprintf
77 #endif
78 #endif
79
80 /* Creating ID's */
81
82 void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
83 {
84         ParticleSystemModifierData *psmd;
85         ModifierData *md;
86         int a;
87
88         memset(pid, 0, sizeof(PTCacheID));
89
90         pid->ob= ob;
91         pid->data= sb;
92         pid->type= PTCACHE_TYPE_SOFTBODY;
93         pid->cache= sb->pointcache;
94
95         if(sb->particles) {
96                 psmd= psys_get_modifier(ob, sb->particles);
97                 pid->stack_index= modifiers_indexInObject(ob, (ModifierData*)psmd);
98         }
99         else {
100                 for(a=0, md=ob->modifiers.first; md; md=md->next, a++) {
101                         if(md->type == eModifierType_Softbody) {
102                                 pid->stack_index = a;
103                                 break;
104                         }
105                 }
106         }
107 }
108
109 void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *psys)
110 {
111         ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
112
113         memset(pid, 0, sizeof(PTCacheID));
114
115         pid->ob= ob;
116         pid->data= psys;
117         pid->type= PTCACHE_TYPE_PARTICLES;
118         pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)psmd);
119         pid->cache= psys->pointcache;
120 }
121
122 void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
123 {
124         memset(pid, 0, sizeof(PTCacheID));
125
126         pid->ob= ob;
127         pid->data= clmd;
128         pid->type= PTCACHE_TYPE_CLOTH;
129         pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)clmd);
130         pid->cache= clmd->point_cache;
131 }
132
133 void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
134 {
135         PTCacheID *pid;
136         ParticleSystem *psys;
137         ModifierData *md;
138
139         lb->first= lb->last= NULL;
140
141         if(ob->soft) {
142                 pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
143                 BKE_ptcache_id_from_softbody(pid, ob, ob->soft);
144                 BLI_addtail(lb, pid);
145         }
146
147         for(psys=ob->particlesystem.first; psys; psys=psys->next) {
148                 pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
149                 BKE_ptcache_id_from_particles(pid, ob, psys);
150                 BLI_addtail(lb, pid);
151
152                 if(psys->soft) {
153                         pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
154                         BKE_ptcache_id_from_softbody(pid, ob, psys->soft);
155                         BLI_addtail(lb, pid);
156                 }
157         }
158
159         for(md=ob->modifiers.first; md; md=md->next) {
160                 if(md->type == eModifierType_Cloth) {
161                         pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
162                         BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md);
163                         BLI_addtail(lb, pid);
164                 }
165         }
166 }
167
168 /*      Takes an Object ID and returns a unique name
169         - id: object id
170         - cfra: frame for the cache, can be negative
171         - stack_index: index in the modifier stack. we can have cache for more then one stack_index
172 */
173
174 #define MAX_PTCACHE_PATH FILE_MAX
175 #define MAX_PTCACHE_FILE ((FILE_MAXDIR+FILE_MAXFILE)*2)
176
177 static int ptcache_path(PTCacheID *pid, char *filename)
178 {
179         Library *lib;
180         int i;
181
182         lib= (pid)? pid->ob->id.lib: NULL;
183
184         if (G.relbase_valid || lib) {
185                 char file[MAX_PTCACHE_PATH]; /* we dont want the dir, only the file */
186                 char *blendfilename;
187
188                 blendfilename= (lib)? lib->filename: G.sce;
189
190                 BLI_split_dirfile_basic(blendfilename, NULL, file);
191                 i = strlen(file);
192                 
193                 /* remove .blend */
194                 if (i > 6)
195                         file[i-6] = '\0';
196                 
197                 snprintf(filename, MAX_PTCACHE_PATH, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */
198                 BLI_convertstringcode(filename, blendfilename);
199                 BLI_add_slash(filename);
200                 return strlen(filename);
201         }
202         
203         /* use the temp path. this is weak but better then not using point cache at all */
204         /* btempdir is assumed to exist and ALWAYS has a trailing slash */
205         snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH"%d", btempdir, abs(getpid()));
206         BLI_add_slash(filename);
207         return strlen(filename);
208 }
209
210 static int BKE_ptcache_id_filename(PTCacheID *pid, char *filename, int cfra, short do_path, short do_ext)
211 {
212         int len=0;
213         char *idname;
214         char *newname;
215         filename[0] = '\0';
216         newname = filename;
217         
218         if (!G.relbase_valid) return 0; /* save blend file before using disk pointcache */
219         
220         /* start with temp dir */
221         if (do_path) {
222                 len = ptcache_path(pid, filename);
223                 newname += len;
224         }
225         if(strcmp(pid->cache->name, "")==0) {
226                 idname = (pid->ob->id.name+2);
227                 /* convert chars to hex so they are always a valid filename */
228                 while('\0' != *idname) {
229                         snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
230                         newname+=2;
231                         len += 2;
232                 }
233         }
234         else {
235                 int temp = strlen(pid->cache->name); 
236                 strcpy(newname, pid->cache->name); 
237                 newname+=temp;
238                 len += temp;
239         }
240
241         if (do_ext) {
242                 snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
243                 len += 16;
244         }
245         
246         return len; /* make sure the above string is always 16 chars */
247 }
248
249 /* youll need to close yourself after! */
250 PTCacheFile *BKE_ptcache_file_open(PTCacheID *pid, int mode, int cfra)
251 {
252         PTCacheFile *pf;
253         FILE *fp = NULL;
254         char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
255
256         /* don't allow writing for linked objects */
257         if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
258                 return NULL;
259
260         if (!G.relbase_valid) return NULL; /* save blend file before using disk pointcache */
261         
262         BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
263
264         if (mode==PTCACHE_FILE_READ) {
265                 if (!BLI_exists(filename)) {
266                         return NULL;
267                 }
268                 fp = fopen(filename, "rb");
269         } else if (mode==PTCACHE_FILE_WRITE) {
270                 BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
271                 fp = fopen(filename, "wb");
272         }
273
274         if (!fp)
275                 return NULL;
276         
277         pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile");
278         pf->fp= fp;
279         
280         return pf;
281 }
282
283 void BKE_ptcache_file_close(PTCacheFile *pf)
284 {
285         fclose(pf->fp);
286         MEM_freeN(pf);
287 }
288
289 int BKE_ptcache_file_read_floats(PTCacheFile *pf, float *f, int tot)
290 {
291         return (fread(f, sizeof(float), tot, pf->fp) == tot);
292 }
293
294 int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot)
295 {
296         return (fwrite(f, sizeof(float), tot, pf->fp) == tot);
297 }
298
299 static int ptcache_pid_elemsize(PTCacheID *pid)
300 {
301         if(pid->type==PTCACHE_TYPE_SOFTBODY)
302                 return 0; // TODO
303         else if(pid->type==PTCACHE_TYPE_PARTICLES)
304                 return sizeof(ParticleKey);
305         else if(pid->type==PTCACHE_TYPE_CLOTH)
306                 return 9 * sizeof(float);
307
308         return 0;
309 }
310 static int ptcache_pid_totelem(PTCacheID *pid)
311 {
312         if(pid->type==PTCACHE_TYPE_SOFTBODY)
313                 return 0; // TODO
314         else if(pid->type==PTCACHE_TYPE_PARTICLES) {
315                 ParticleSystem *psys = pid->data;
316                 return psys->totpart;
317         }
318         else if(pid->type==PTCACHE_TYPE_CLOTH) {
319                 ClothModifierData *clmd = pid->data;
320                 return clmd->clothObject->numverts;
321         }
322
323         return 0;
324 }
325
326 void BKE_ptcache_update_info(PTCacheID *pid)
327 {
328         PointCache *cache = pid->cache;
329         int totframes = 0;
330         char mem_info[64];
331
332         if(cache->flag & PTCACHE_DISK_CACHE) {
333                 int cfra = cache->startframe;
334
335                 for(; cfra<=cache->endframe; cfra++) {
336                         if(BKE_ptcache_id_exist(pid, cfra))
337                                 totframes++;
338                 }
339
340                 sprintf(mem_info, "%i frames on disk", totframes);
341         }
342         else {
343                 PTCacheMem *pm = cache->mem_cache.first;                
344                 float framesize = 0.0f, bytes = 0.0f;
345                 int mb;
346
347                 if(pm)
348                         framesize = (float)ptcache_pid_elemsize(pid) * (float)pm->totpoint;
349                 
350                 for(; pm; pm=pm->next)
351                         totframes++;
352
353                 bytes = totframes * framesize;
354
355                 mb = (bytes > 1024.0f * 1024.0f);
356
357                 sprintf(mem_info, "%i frames in memory (%.1f %s)",
358                         totframes,
359                         bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
360                         mb ? "Mb" : "kb");
361         }
362
363         if(cache->flag & PTCACHE_OUTDATED) {
364                 sprintf(cache->info, "%s, cache is outdated!", mem_info);
365         }
366         else if(cache->flag & PTCACHE_FRAMES_SKIPPED) {
367                 sprintf(cache->info, "%s, not exact since frame %i.", mem_info, cache->last_exact);
368         }
369         else
370                 sprintf(cache->info, "%s.", mem_info);
371 }
372 /* reads cache from disk or memory */
373 /* possible to get old or interpolated result */
374 int BKE_ptcache_read_cache(PTCacheReader *reader)
375 {
376         PTCacheID *pid = reader->pid;
377         PTCacheFile *pf=NULL, *pf2=NULL;
378         PTCacheMem *pm=NULL, *pm2=NULL;
379         int totelem = reader->totelem;
380         float cfra = reader->cfra;
381         int cfrai = (int)cfra;
382         int elemsize = ptcache_pid_elemsize(pid);
383         int i, incr = elemsize / sizeof(float);
384         float frs_sec = reader->scene->r.frs_sec;
385         int cfra1=0, cfra2;
386         int ret = 0;
387
388         if(totelem == 0)
389                 return 0;
390
391
392         /* first check if we have the actual frame cached */
393         if(cfra == (float)cfrai) {
394                 if(pid->cache->flag & PTCACHE_DISK_CACHE) {
395                         pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
396                 }
397                 else {
398                         pm = pid->cache->mem_cache.first;
399
400                         for(; pm; pm=pm->next) {
401                                 if(pm->frame == cfrai)
402                                         break;
403                         }
404                 }
405         }
406
407         /* if found, use exact frame */
408         if(pf || pm) {
409                 float *data;
410
411                 if(pm)
412                         data = pm->data;
413                 else
414                         data = MEM_callocN(elemsize, "pointcache read data");
415
416                 for(i=0; i<totelem; i++) {
417                         if(pf) {
418                                 if(!BKE_ptcache_file_read_floats(pf, data, incr)) {
419                                         BKE_ptcache_file_close(pf);
420                                         MEM_freeN(data);
421                                         return 0;
422                                 }
423
424                                 reader->set_elem(i, reader->calldata, data);
425                         }
426                         else {
427                                 reader->set_elem(i, reader->calldata, data);
428                                 data += incr;
429                         }
430                 }
431
432                 if(pf) {
433                         BKE_ptcache_file_close(pf);
434                         pf = NULL;
435                         MEM_freeN(data);
436                 }
437
438                 ret = PTCACHE_READ_EXACT;
439         }
440
441         if(ret)
442                 ;
443         /* no exact cache frame found so try to find cached frames around cfra */
444         else if(pid->cache->flag & PTCACHE_DISK_CACHE) {
445                 pf=NULL;
446                 while(cfrai > pid->cache->startframe && !pf) {
447                         cfrai--;
448                         pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
449                         cfra1 = cfrai;
450                 }
451
452                 if(reader->old_frame)
453                         *(reader->old_frame) = cfrai;
454
455                 cfrai = (int)cfra;
456                 while(cfrai < pid->cache->endframe && !pf2) {
457                         cfrai++;
458                         pf2= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
459                         cfra2 = cfrai;
460                 }
461         }
462         else if(pid->cache->mem_cache.first){
463                 pm = pid->cache->mem_cache.first;
464
465                 while(pm->next && pm->next->frame < cfra)
466                         pm= pm->next;
467
468                 if(pm) {
469                         if(reader->old_frame)
470                                 *(reader->old_frame) = pm->frame;
471                         cfra1 = pm->frame;
472                 }
473
474                 pm2 = pid->cache->mem_cache.last;
475
476                 if(pm2 && pm2->frame < cfra)
477                         pm2 = NULL;
478                 else {
479                         while(pm2->prev && pm2->prev->frame > cfra)
480                                 pm2= pm2->prev;
481
482                         if(pm2)
483                                 cfra2 = pm2->frame;
484                 }
485         }
486
487         if(ret)
488                 ;
489         else if((pf && pf2) || (pm && pm2)) {
490                 /* interpolate from nearest frames if cache isn't outdated */
491                 float *data1, *data2;
492
493                 if(pm) {
494                         data1 = pm->data;
495                         data2 = pm2->data;
496                 }
497                 else {
498                         data1 = MEM_callocN(elemsize, "pointcache read data1");
499                         data2 = MEM_callocN(elemsize, "pointcache read data2");
500                 }
501
502                 for(i=0; i<totelem; i++) {
503                         if(pf && pf2) {
504                                 if(!BKE_ptcache_file_read_floats(pf, data1, incr)) {
505                                         BKE_ptcache_file_close(pf);
506                                         BKE_ptcache_file_close(pf2);
507                                         MEM_freeN(data1);
508                                         MEM_freeN(data2);
509                                         return 0;
510                                 }
511                                 if(!BKE_ptcache_file_read_floats(pf2, data2, incr)) {
512                                         BKE_ptcache_file_close(pf);
513                                         BKE_ptcache_file_close(pf2);
514                                         MEM_freeN(data1);
515                                         MEM_freeN(data2);
516                                         return 0;
517                                 }
518                                 reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
519                         }
520                         else {
521                                 reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
522                                 data1 += incr;
523                                 data2 += incr;
524                         }
525                 }
526
527                 if(pf) {
528                         BKE_ptcache_file_close(pf);
529                         pf = NULL;
530                         BKE_ptcache_file_close(pf2);
531                         pf2 = NULL;
532                         MEM_freeN(data1);
533                         MEM_freeN(data2);
534                 }
535
536                 ret = PTCACHE_READ_INTERPOLATED;
537         }
538         else if(pf || pm) {
539                 /* use last valid cache frame */
540                 float *data;
541
542                 /* don't read cache if allready simulated past cached frame */
543                 if(cfra1 && cfra1 <= pid->cache->simframe) {
544                         if(pf)
545                                 BKE_ptcache_file_close(pf);
546                         if(pf2)
547                                 BKE_ptcache_file_close(pf2);
548
549                         return 0;
550                 }
551
552                 if(pm)
553                         data = pm->data;
554                 else
555                         data = MEM_callocN(elemsize, "pointcache read data");
556
557                 for(i=0; i<totelem; i++) {
558                         if(pf) {
559                                 if(!BKE_ptcache_file_read_floats(pf, data, incr)) {
560                                         BKE_ptcache_file_close(pf);
561                                         if(pf2)
562                                                 BKE_ptcache_file_close(pf2);
563                                         return 0;
564                                 }
565                                 reader->set_elem(i, reader->calldata, data);
566                         }
567                         else {
568                                 reader->set_elem(i, reader->calldata, data);
569                                 data += incr;
570                         }
571                 }
572
573                 if(pf) {
574                         BKE_ptcache_file_close(pf);
575                         pf = NULL;
576                         MEM_freeN(data);
577                 }
578                 if(pf2) {
579                         BKE_ptcache_file_close(pf2);
580                         pf = NULL;
581                 }
582
583                 ret = PTCACHE_READ_OLD;
584         }
585
586         if(pf)
587                 BKE_ptcache_file_close(pf);
588         if(pf2)
589                 BKE_ptcache_file_close(pf2);
590
591         if((pid->cache->flag & PTCACHE_QUICK_CACHE)==0) {
592                 /* clear invalid cache frames so that better stuff can be simulated */
593                 if(pid->cache->flag & PTCACHE_OUTDATED) {
594                         BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, cfra);
595                 }
596                 else if(pid->cache->flag & PTCACHE_FRAMES_SKIPPED) {
597                         if(cfra <= pid->cache->last_exact)
598                                 pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
599
600                         BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfra,pid->cache->last_exact));
601                 }
602         }
603
604         return ret;
605 }
606 /* writes cache to disk or memory */
607 int BKE_ptcache_write_cache(PTCacheWriter *writer)
608 {
609         PointCache *cache = writer->pid->cache;
610         PTCacheFile *pf= NULL;
611         int elemsize = ptcache_pid_elemsize(writer->pid);
612         int i, incr = elemsize / sizeof(float);
613         int add = 0, overwrite = 0;
614         float temp[14];
615
616         if(writer->totelem == 0 || writer->cfra <= 0)
617                 return 0;
618
619         if(cache->flag & PTCACHE_DISK_CACHE) {
620                 int cfra = cache->endframe;
621
622                 /* allways start from scratch on the first frame */
623                 if(writer->cfra == cache->startframe) {
624                         BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
625                         cache->flag &= ~PTCACHE_REDO_NEEDED;
626                         add = 1;
627                 }
628                 else {
629                         int ocfra;
630                         /* find last cached frame */
631                         while(cfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, cfra))
632                                 cfra--;
633
634                         /* find second last cached frame */
635                         ocfra = cfra-1;
636                         while(ocfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, ocfra))
637                                 ocfra--;
638
639                         if(cfra >= cache->startframe && writer->cfra > cfra) {
640                                 if(ocfra >= cache->startframe && cfra - ocfra < cache->step)
641                                         overwrite = 1;
642                                 else
643                                         add = 1;
644                         }
645                 }
646
647                 if(add || overwrite) {
648                         if(overwrite)
649                                 BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_FRAME, cfra);
650
651                         pf = BKE_ptcache_file_open(writer->pid, PTCACHE_FILE_WRITE, writer->cfra);
652                         if(!pf)
653                                 return 0;
654
655                         for(i=0; i<writer->totelem; i++) {
656                                 writer->set_elem(i, writer->calldata, temp);
657                                 BKE_ptcache_file_write_floats(pf, temp, incr);
658                         }
659                 }
660         }
661         else {
662                 PTCacheMem *pm;
663                 PTCacheMem *pm2;
664                 float *pmdata;
665
666                 pm2 = cache->mem_cache.first;
667                 
668                 /* allways start from scratch on the first frame */
669                 if(writer->cfra == cache->startframe) {
670                         BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
671                         cache->flag &= ~PTCACHE_REDO_NEEDED;
672                         add = 1;
673                 }
674                 else {
675                         pm2 = cache->mem_cache.last;
676
677                         if(pm2 && writer->cfra > pm2->frame) {
678                                 if(pm2->prev && pm2->frame - pm2->prev->frame < cache->step)
679                                         overwrite = 1;
680                                 else
681                                         add = 1;
682                         }
683                 }
684
685                 if(overwrite) {
686                         pm = cache->mem_cache.last;
687                         pmdata = pm->data;
688
689                         for(i=0; i<writer->totelem; i++, pmdata+=incr) {
690                                 writer->set_elem(i, writer->calldata, temp);
691                                 memcpy(pmdata, temp, elemsize);
692                         }
693
694                         pm->frame = writer->cfra;
695                 }
696                 else if(add) {
697                         pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
698                         pm->data = MEM_callocN(elemsize * writer->totelem, "Pointcache mem data");
699                         pmdata = pm->data;
700
701                         for(i=0; i<writer->totelem; i++, pmdata+=incr) {
702                                 writer->set_elem(i, writer->calldata, temp);
703                                 memcpy(pmdata, temp, elemsize);
704                         }
705
706                         pm->frame = writer->cfra;
707                         pm->totpoint = writer->totelem;
708
709                         BLI_addtail(&cache->mem_cache, pm);
710                 }
711         }
712
713         if(add || overwrite) {
714                 if(writer->cfra - cache->last_exact == 1
715                         || writer->cfra == cache->startframe) {
716                         cache->last_exact = writer->cfra;
717                         cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
718                 }
719                 else
720                         cache->flag |= PTCACHE_FRAMES_SKIPPED;
721         }
722         
723         if(pf)
724                 BKE_ptcache_file_close(pf);
725
726         BKE_ptcache_update_info(writer->pid);
727
728         return 1;
729 }
730 /* youll need to close yourself after!
731  * mode - PTCACHE_CLEAR_ALL, 
732
733 */
734
735 void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
736 {
737         int len; /* store the length of the string */
738
739         /* mode is same as fopen's modes */
740         DIR *dir; 
741         struct dirent *de;
742         char path[MAX_PTCACHE_PATH];
743         char filename[MAX_PTCACHE_FILE];
744         char path_full[MAX_PTCACHE_FILE];
745         char ext[MAX_PTCACHE_PATH];
746
747         if(!pid->cache)
748                 return;
749
750         /* don't allow clearing for linked objects */
751         if(pid->ob->id.lib)
752                 return;
753
754         /*if (!G.relbase_valid) return; *//* save blend file before using pointcache */
755         
756         /* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */
757         switch (mode) {
758         case PTCACHE_CLEAR_ALL:
759         case PTCACHE_CLEAR_BEFORE:      
760         case PTCACHE_CLEAR_AFTER:
761                 if(pid->cache->flag & PTCACHE_DISK_CACHE) {
762                         ptcache_path(pid, path);
763                         
764                         len = BKE_ptcache_id_filename(pid, filename, cfra, 0, 0); /* no path */
765                         
766                         dir = opendir(path);
767                         if (dir==NULL)
768                                 return;
769
770                         snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
771                         
772                         while ((de = readdir(dir)) != NULL) {
773                                 if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
774                                         if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
775                                                 if (mode == PTCACHE_CLEAR_ALL) {
776                                                         pid->cache->last_exact = 0;
777                                                         BLI_join_dirfile(path_full, path, de->d_name);
778                                                         BLI_delete(path_full, 0, 0);
779                                                 } else {
780                                                         /* read the number of the file */
781                                                         int frame, len2 = strlen(de->d_name);
782                                                         char num[7];
783
784                                                         if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
785                                                                 BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
786                                                                 frame = atoi(num);
787                                                                 
788                                                                 if((mode==PTCACHE_CLEAR_BEFORE && frame < cfra) || 
789                                                                 (mode==PTCACHE_CLEAR_AFTER && frame > cfra)     ) {
790                                                                         
791                                                                         BLI_join_dirfile(path_full, path, de->d_name);
792                                                                         BLI_delete(path_full, 0, 0);
793                                                                 }
794                                                         }
795                                                 }
796                                         }
797                                 }
798                         }
799                         closedir(dir);
800                 }
801                 else {
802                         PTCacheMem *pm= pid->cache->mem_cache.first;
803                         PTCacheMem *link= NULL;
804
805                         if(mode == PTCACHE_CLEAR_ALL) {
806                                 pid->cache->last_exact = 0;
807                                 for(; pm; pm=pm->next)
808                                         MEM_freeN(pm->data);
809                                 BLI_freelistN(&pid->cache->mem_cache);
810                         } else {
811                                 while(pm) {
812                                         if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra)     || 
813                                         (mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra) ) {
814                                                 link = pm;
815                                                 pm = pm->next;
816                                                 MEM_freeN(link->data);
817                                                 BLI_freelinkN(&pid->cache->mem_cache, link);
818                                         }
819                                         else
820                                                 pm = pm->next;
821                                 }
822                         }
823                 }
824                 break;
825                 
826         case PTCACHE_CLEAR_FRAME:
827                 if(pid->cache->flag & PTCACHE_DISK_CACHE) {
828                         if(BKE_ptcache_id_exist(pid, cfra)) {
829                                 BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); /* no path */
830                                 BLI_delete(filename, 0, 0);
831                         }
832                 }
833                 else {
834                         PTCacheMem *pm = pid->cache->mem_cache.first;
835
836                         for(; pm; pm=pm->next) {
837                                 if(pm->frame == cfra) {
838                                         MEM_freeN(pm->data);
839                                         BLI_freelinkN(&pid->cache->mem_cache, pm);
840                                         break;
841                                 }
842                         }
843                 }
844                 break;
845         }
846
847         BKE_ptcache_update_info(pid);
848 }
849
850 int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
851 {
852         if(!pid->cache)
853                 return 0;
854         
855         if(pid->cache->flag & PTCACHE_DISK_CACHE) {
856                 char filename[MAX_PTCACHE_FILE];
857                 
858                 BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
859
860                 return BLI_exists(filename);
861         }
862         else {
863                 PTCacheMem *pm = pid->cache->mem_cache.first;
864
865                 for(; pm; pm=pm->next) {
866                         if(pm->frame==cfra)
867                                 return 1;
868                 }
869                 return 0;
870         }
871 }
872
873 void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
874 {
875         Object *ob;
876         PointCache *cache;
877         float offset, time, nexttime;
878
879         /* TODO: this has to be sorter out once bsystem_time gets redone, */
880         /*       now caches can handle interpolating etc. too - jahka */
881
882         /* time handling for point cache:
883          * - simulation time is scaled by result of bsystem_time
884          * - for offsetting time only time offset is taken into account, since
885          *   that's always the same and can't be animated. a timeoffset which
886          *   varies over time is not simpe to support.
887          * - field and motion blur offsets are currently ignored, proper solution
888          *   is probably to interpolate results from two frames for that ..
889          */
890
891         ob= pid->ob;
892         cache= pid->cache;
893
894         if(timescale) {
895                 time= bsystem_time(scene, ob, cfra, 0.0f);
896                 nexttime= bsystem_time(scene, ob, cfra+1.0f, 0.0f);
897
898                 *timescale= MAX2(nexttime - time, 0.0f);
899         }
900
901         if(startframe && endframe) {
902                 *startframe= cache->startframe;
903                 *endframe= cache->endframe;
904
905                 // XXX ipoflag is depreceated - old animation system stuff
906                 if (/*(ob->ipoflag & OB_OFFS_PARENT) &&*/ (ob->partype & PARSLOW)==0) {
907                         offset= give_timeoffset(ob);
908
909                         *startframe += (int)(offset+0.5f);
910                         *endframe += (int)(offset+0.5f);
911                 }
912         }
913 }
914
915 int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
916 {
917         PointCache *cache;
918         int reset, clear, after;
919
920         if(!pid->cache)
921                 return 0;
922
923         cache= pid->cache;
924         reset= 0;
925         clear= 0;
926         after= 0;
927
928         if(mode == PTCACHE_RESET_DEPSGRAPH) {
929                 if(!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
930                         if(cache->flag & PTCACHE_QUICK_CACHE)
931                                 clear= 1;
932
933                         after= 1;
934                 }
935
936                 cache->flag |= PTCACHE_OUTDATED;
937         }
938         else if(mode == PTCACHE_RESET_BAKED) {
939                 if(!BKE_ptcache_get_continue_physics()) {
940                         reset= 1;
941                         clear= 1;
942                 }
943                 else
944                         cache->flag |= PTCACHE_OUTDATED;
945         }
946         else if(mode == PTCACHE_RESET_OUTDATED) {
947                 reset = 1;
948
949                 if(cache->flag & PTCACHE_OUTDATED)
950                         if(!(cache->flag & PTCACHE_BAKED))
951                                 clear= 1;
952         }
953
954         if(reset) {
955                 cache->flag &= ~(PTCACHE_REDO_NEEDED|PTCACHE_SIMULATION_VALID);
956                 cache->simframe= 0;
957                 cache->last_exact= 0;
958
959                 if(pid->type == PTCACHE_TYPE_CLOTH)
960                         cloth_free_modifier(pid->ob, pid->data);
961                 else if(pid->type == PTCACHE_TYPE_SOFTBODY)
962                         sbFreeSimulation(pid->data);
963                 else if(pid->type == PTCACHE_TYPE_PARTICLES)
964                         psys_reset(pid->data, PSYS_RESET_DEPSGRAPH);
965         }
966         if(clear)
967                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
968         else if(after)
969                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, CFRA);
970
971         return (reset || clear || after);
972 }
973
974 int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
975 {
976         PTCacheID pid;
977         ParticleSystem *psys;
978         ModifierData *md;
979         int reset, skip;
980
981         reset= 0;
982         skip= 0;
983
984         if(ob->soft) {
985                 BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
986                 reset |= BKE_ptcache_id_reset(scene, &pid, mode);
987         }
988
989         for(psys=ob->particlesystem.first; psys; psys=psys->next) {
990                 /* Baked softbody hair has to be checked first, because we don't want to reset */
991                 /* particles or softbody in that case -jahka */
992                 if(psys->soft) {
993                         BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
994                         if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED))) 
995                                 reset |= BKE_ptcache_id_reset(scene, &pid, mode);
996                         else
997                                 skip = 1;
998                 }
999                 else if(psys->recalc & PSYS_RECALC_REDO || psys->recalc & PSYS_RECALC_CHILD)
1000                         skip = 1;
1001
1002                 if(skip == 0) {
1003                         BKE_ptcache_id_from_particles(&pid, ob, psys);
1004                         reset |= BKE_ptcache_id_reset(scene, &pid, mode);
1005                 }
1006         }
1007
1008         for(md=ob->modifiers.first; md; md=md->next) {
1009                 if(md->type == eModifierType_Cloth) {
1010                         BKE_ptcache_id_from_cloth(&pid, ob, (ClothModifierData*)md);
1011                         reset |= BKE_ptcache_id_reset(scene, &pid, mode);
1012                 }
1013         }
1014
1015         return reset;
1016 }
1017
1018 /* Use this when quitting blender, with unsaved files */
1019 void BKE_ptcache_remove(void)
1020 {
1021         char path[MAX_PTCACHE_PATH];
1022         char path_full[MAX_PTCACHE_PATH];
1023         int rmdir = 1;
1024         
1025         ptcache_path(NULL, path);
1026
1027         if (BLI_exist(path)) {
1028                 /* The pointcache dir exists? - remove all pointcache */
1029
1030                 DIR *dir; 
1031                 struct dirent *de;
1032
1033                 dir = opendir(path);
1034                 if (dir==NULL)
1035                         return;
1036                 
1037                 while ((de = readdir(dir)) != NULL) {
1038                         if( strcmp(de->d_name, ".")==0 || strcmp(de->d_name, "..")==0) {
1039                                 /* do nothing */
1040                         } else if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
1041                                 BLI_join_dirfile(path_full, path, de->d_name);
1042                                 BLI_delete(path_full, 0, 0);
1043                         } else {
1044                                 rmdir = 0; /* unknown file, dont remove the dir */
1045                         }
1046                 }
1047
1048                 closedir(dir);
1049         } else { 
1050                 rmdir = 0; /* path dosnt exist  */
1051         }
1052         
1053         if (rmdir) {
1054                 BLI_delete(path, 1, 0);
1055         }
1056 }
1057
1058 /* Continuous Interaction */
1059
1060 static int CONTINUE_PHYSICS = 0;
1061
1062 void BKE_ptcache_set_continue_physics(Scene *scene, int enable)
1063 {
1064         Object *ob;
1065
1066         if(CONTINUE_PHYSICS != enable) {
1067                 CONTINUE_PHYSICS = enable;
1068
1069                 if(CONTINUE_PHYSICS == 0) {
1070                         for(ob=G.main->object.first; ob; ob=ob->id.next)
1071                                 if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
1072                                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1073                 }
1074         }
1075 }
1076
1077 int BKE_ptcache_get_continue_physics()
1078 {
1079         return CONTINUE_PHYSICS;
1080 }
1081
1082 /* Point Cache */
1083
1084 PointCache *BKE_ptcache_add()
1085 {
1086         PointCache *cache;
1087
1088         cache= MEM_callocN(sizeof(PointCache), "PointCache");
1089         cache->startframe= 1;
1090         cache->endframe= 250;
1091         cache->step= 10;
1092
1093         return cache;
1094 }
1095
1096 void BKE_ptcache_free(PointCache *cache)
1097 {
1098         PTCacheMem *pm = cache->mem_cache.first;
1099         if(pm) {
1100                 for(; pm; pm=pm->next)
1101                         MEM_freeN(pm->data);
1102
1103                 BLI_freelistN(&cache->mem_cache);
1104         }
1105
1106         MEM_freeN(cache);
1107 }
1108
1109 PointCache *BKE_ptcache_copy(PointCache *cache)
1110 {
1111         PointCache *ncache;
1112
1113         ncache= MEM_dupallocN(cache);
1114
1115         /* hmm, should these be copied over instead? */
1116         ncache->mem_cache.first = NULL;
1117         ncache->mem_cache.last = NULL;
1118
1119         ncache->flag= 0;
1120         ncache->simframe= 0;
1121
1122         return ncache;
1123 }
1124
1125
1126
1127 /* Baking */
1128 static int count_quick_cache(Scene *scene, int *quick_step)
1129 {
1130         Base *base = scene->base.first;
1131         PTCacheID *pid;
1132         ListBase pidlist;
1133         int autocache_count= 0;
1134
1135         for(base = scene->base.first; base; base = base->next) {
1136                 if(base->object) {
1137                         BKE_ptcache_ids_from_object(&pidlist, base->object);
1138
1139                         for(pid=pidlist.first; pid; pid=pid->next) {
1140                                 if((pid->cache->flag & PTCACHE_BAKED)
1141                                         || (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
1142                                         continue;
1143
1144                                 if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
1145                                         if(!autocache_count)
1146                                                 *quick_step = pid->cache->step;
1147                                         else
1148                                                 *quick_step = MIN2(*quick_step, pid->cache->step);
1149
1150                                         autocache_count++;
1151                                 }
1152                         }
1153
1154                         BLI_freelistN(&pidlist);
1155                 }
1156         }
1157
1158         return autocache_count;
1159 }
1160 void BKE_ptcache_quick_cache_all(Scene *scene)
1161 {
1162         PTCacheBaker baker;
1163
1164         baker.bake=0;
1165         baker.break_data=NULL;
1166         baker.break_test=NULL;
1167         baker.pid=NULL;
1168         baker.progressbar=NULL;
1169         baker.progresscontext=NULL;
1170         baker.render=0;
1171         baker.anim_init = 0;
1172         baker.scene=scene;
1173
1174         if(count_quick_cache(scene, &baker.quick_step))
1175                 BKE_ptcache_make_cache(&baker);
1176 }
1177
1178 /* if bake is not given run simulations to current frame */
1179 void BKE_ptcache_make_cache(PTCacheBaker* baker)
1180 {
1181         Scene *scene = baker->scene;
1182         Base *base;
1183         ListBase pidlist;
1184         PTCacheID *pid = baker->pid;
1185         PointCache *cache;
1186         float frameleno = scene->r.framelen;
1187         int cfrao = CFRA;
1188         int startframe = MAXFRAME;
1189         int endframe = baker->anim_init ? scene->r.sfra : CFRA;
1190         int bake = baker->bake;
1191         int render = baker->render;
1192         int step = baker->quick_step;
1193
1194         G.afbreek = 0;
1195
1196         /* set caches to baking mode and figure out start frame */
1197         if(pid) {
1198                 /* cache/bake a single object */
1199                 cache = pid->cache;
1200                 if((cache->flag & PTCACHE_BAKED)==0) {
1201                         if(pid->type==PTCACHE_TYPE_PARTICLES)
1202                                 psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
1203
1204                         if(bake || cache->flag & PTCACHE_REDO_NEEDED)
1205                                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
1206
1207                         startframe = MAX2(cache->last_exact, cache->startframe);
1208
1209                         if(bake) {
1210                                 endframe = cache->endframe;
1211                                 cache->flag |= PTCACHE_BAKING;
1212                         }
1213                         else {
1214                                 endframe = MIN2(endframe, cache->endframe);
1215                         }
1216
1217                         cache->flag &= ~PTCACHE_BAKED;
1218                 }
1219         }
1220         else for(base=scene->base.first; base; base= base->next) {
1221                 /* cache/bake everything in the scene */
1222                 BKE_ptcache_ids_from_object(&pidlist, base->object);
1223
1224                 for(pid=pidlist.first; pid; pid=pid->next) {
1225                         cache = pid->cache;
1226                         if((cache->flag & PTCACHE_BAKED)==0) {
1227                                 if(pid->type==PTCACHE_TYPE_PARTICLES) {
1228                                         ParticleSystem *psys = (ParticleSystem*)pid->data;
1229                                         /* skip hair & keyed particles */
1230                                         if(psys->part->type == PART_HAIR || psys->part->phystype == PART_PHYS_KEYED)
1231                                                 continue;
1232
1233                                         psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
1234                                 }
1235
1236                                 if((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0)
1237                                         && ((cache->flag & PTCACHE_QUICK_CACHE)==0 || render || bake))
1238                                         BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
1239
1240                                 startframe = MIN2(startframe, cache->startframe);
1241
1242                                 if(bake || render) {
1243                                         cache->flag |= PTCACHE_BAKING;
1244
1245                                         if(bake)
1246                                                 endframe = MAX2(endframe, cache->endframe);
1247                                 }
1248
1249                                 cache->flag &= ~PTCACHE_BAKED;
1250
1251                         }
1252                 }
1253                 BLI_freelistN(&pidlist);
1254         }
1255
1256         CFRA= startframe;
1257         scene->r.framelen = 1.0;
1258
1259         for(; CFRA <= endframe; CFRA+=step) {
1260                 float prog;
1261
1262                 if(bake)
1263                         prog = (int)(100.0 * (float)(CFRA - startframe)/(float)(endframe-startframe));
1264                 else
1265                         prog = CFRA;
1266
1267                 /* NOTE: baking should not redraw whole ui as this slows things down */
1268                 if(baker->progressbar)
1269                         baker->progressbar(baker->progresscontext, prog);
1270                 
1271                 scene_update_for_newframe(scene, scene->lay);
1272
1273                 /* NOTE: breaking baking should leave calculated frames in cache, not clear it */
1274                 if(baker->break_test && baker->break_test(baker->break_data))
1275                         break;
1276         }
1277
1278         /* clear baking flag */
1279         if(pid) {
1280                 cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
1281                 cache->flag |= PTCACHE_SIMULATION_VALID;
1282                 if(bake)
1283                         cache->flag |= PTCACHE_BAKED;
1284         }
1285         else for(base=scene->base.first; base; base= base->next) {
1286                 BKE_ptcache_ids_from_object(&pidlist, base->object);
1287
1288                 for(pid=pidlist.first; pid; pid=pid->next) {
1289                         /* skip hair particles */
1290                         if(pid->type==PTCACHE_TYPE_PARTICLES && ((ParticleSystem*)pid->data)->part->type == PART_HAIR)
1291                                 continue;
1292                 
1293                         cache = pid->cache;
1294
1295                         if(step > 1)
1296                                 cache->flag &= ~(PTCACHE_BAKING|PTCACHE_OUTDATED);
1297                         else
1298                                 cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
1299
1300                         cache->flag |= PTCACHE_SIMULATION_VALID;
1301
1302                         if(bake)
1303                                 cache->flag |= PTCACHE_BAKED;
1304                 }
1305                 BLI_freelistN(&pidlist);
1306         }
1307
1308         scene->r.framelen = frameleno;
1309         CFRA = cfrao;
1310
1311         if(bake) /* already on cfra unless baking */
1312                 scene_update_for_newframe(scene, scene->lay);
1313
1314         /* TODO: call redraw all windows somehow */
1315 }
1316
1317 void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) {
1318         PointCache *cache = pid->cache;
1319         PTCacheFile *pf;
1320         PTCacheMem *pm;
1321         int totelem=0;
1322         int float_count=0;
1323         int tot;
1324         int last_exact = cache->last_exact;
1325
1326         if (!G.relbase_valid){
1327                 cache->flag &= ~PTCACHE_DISK_CACHE;
1328                 printf("File must be saved before using disk cache!\n");
1329                 return;
1330         }
1331
1332         totelem = ptcache_pid_totelem(pid);
1333         float_count = ptcache_pid_elemsize(pid) / sizeof(float);
1334
1335         if(totelem==0 || float_count==0)
1336                 return;
1337
1338         tot = totelem*float_count;
1339
1340         /* MEM -> DISK */
1341         if(cache->flag & PTCACHE_DISK_CACHE) {
1342                 pm = cache->mem_cache.first;
1343
1344                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
1345
1346                 for(; pm; pm=pm->next) {
1347                         pf = BKE_ptcache_file_open(pid, PTCACHE_FILE_WRITE, pm->frame);
1348
1349                         if(pf) {
1350                                 if(fwrite(pm->data, sizeof(float), tot, pf->fp) != tot) {
1351                                         printf("Error writing to disk cache\n");
1352                                         
1353                                         cache->flag &= ~PTCACHE_DISK_CACHE;
1354
1355                                         BKE_ptcache_file_close(pf);
1356                                         return;
1357                                 }
1358                                 BKE_ptcache_file_close(pf);
1359                         }
1360                         else
1361                                 printf("Error creating disk cache file\n");
1362                 }
1363
1364                 cache->flag &= ~PTCACHE_DISK_CACHE;
1365                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
1366                 cache->flag |= PTCACHE_DISK_CACHE;
1367         }
1368         /* DISK -> MEM */
1369         else {
1370                 int cfra;
1371                 int sfra = cache->startframe;
1372                 int efra = cache->endframe;
1373
1374                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
1375
1376                 for(cfra=sfra; cfra <= efra; cfra++) {
1377                         pf = BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfra);
1378
1379                         if(pf) {
1380                                 pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
1381                                 pm->data = MEM_callocN(sizeof(float)*tot, "Pointcache mem data");
1382
1383                                 if(fread(pm->data, sizeof(float), tot, pf->fp)!= tot) {
1384                                         printf("Error reading from disk cache\n");
1385
1386                                         cache->flag |= PTCACHE_DISK_CACHE;
1387
1388                                         MEM_freeN(pm->data);
1389                                         MEM_freeN(pm);
1390                                         BKE_ptcache_file_close(pf);
1391                                         return;
1392                                 }
1393
1394                                 pm->frame = cfra;
1395                                 pm->totpoint = totelem;
1396
1397                                 BLI_addtail(&pid->cache->mem_cache, pm);
1398
1399                                 BKE_ptcache_file_close(pf);
1400                         }
1401                 }
1402
1403                 cache->flag |= PTCACHE_DISK_CACHE;
1404                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
1405                 cache->flag &= ~PTCACHE_DISK_CACHE;
1406         }
1407         
1408         cache->last_exact = last_exact;
1409
1410         BKE_ptcache_update_info(pid);
1411 }