gameObject -> blenderObject mapping was being created but wasnt needed.
[blender.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_softbody.h"
55 #include "BKE_utildefines.h"
56
57 #include "blendef.h"
58
59 /* needed for directory lookup */
60 #ifndef WIN32
61   #include <dirent.h>
62 #else
63   #include "BLI_winstuff.h"
64 #endif
65
66 /* untitled blend's need getpid for a unique name */
67 #ifdef WIN32
68 #include <process.h>
69 #else
70 #include <unistd.h>
71 #endif
72
73 #ifdef _WIN32
74 #ifndef snprintf
75 #define snprintf _snprintf
76 #endif
77 #endif
78
79 /* Creating ID's */
80
81 void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
82 {
83         ParticleSystemModifierData *psmd;
84         ModifierData *md;
85         int a;
86
87         memset(pid, 0, sizeof(PTCacheID));
88
89         pid->ob= ob;
90         pid->data= sb;
91         pid->type= PTCACHE_TYPE_SOFTBODY;
92         pid->cache= sb->pointcache;
93
94         if(sb->particles) {
95                 psmd= psys_get_modifier(ob, sb->particles);
96                 pid->stack_index= modifiers_indexInObject(ob, (ModifierData*)psmd);
97         }
98         else {
99                 for(a=0, md=ob->modifiers.first; md; md=md->next, a++) {
100                         if(md->type == eModifierType_Softbody) {
101                                 pid->stack_index = a;
102                                 break;
103                         }
104                 }
105         }
106 }
107
108 void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *psys)
109 {
110         ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
111
112         memset(pid, 0, sizeof(PTCacheID));
113
114         pid->ob= ob;
115         pid->data= psys;
116         pid->type= PTCACHE_TYPE_PARTICLES;
117         pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)psmd);
118         pid->cache= psys->pointcache;
119 }
120
121 void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
122 {
123         memset(pid, 0, sizeof(PTCacheID));
124
125         pid->ob= ob;
126         pid->data= clmd;
127         pid->type= PTCACHE_TYPE_CLOTH;
128         pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)clmd);
129         pid->cache= clmd->point_cache;
130 }
131
132 void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
133 {
134         PTCacheID *pid;
135         ParticleSystem *psys;
136         ModifierData *md;
137
138         lb->first= lb->last= NULL;
139
140         if(ob->soft) {
141                 pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
142                 BKE_ptcache_id_from_softbody(pid, ob, ob->soft);
143                 BLI_addtail(lb, pid);
144         }
145
146         for(psys=ob->particlesystem.first; psys; psys=psys->next) {
147                 pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
148                 BKE_ptcache_id_from_particles(pid, ob, psys);
149                 BLI_addtail(lb, pid);
150
151                 if(psys->soft) {
152                         pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
153                         BKE_ptcache_id_from_softbody(pid, ob, psys->soft);
154                         BLI_addtail(lb, pid);
155                 }
156         }
157
158         for(md=ob->modifiers.first; md; md=md->next) {
159                 if(md->type == eModifierType_Cloth) {
160                         pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
161                         BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md);
162                         BLI_addtail(lb, pid);
163                 }
164         }
165 }
166
167 /*      Takes an Object ID and returns a unique name
168         - id: object id
169         - cfra: frame for the cache, can be negative
170         - stack_index: index in the modifier stack. we can have cache for more then one stack_index
171 */
172
173 #define MAX_PTCACHE_PATH FILE_MAX
174 #define MAX_PTCACHE_FILE ((FILE_MAXDIR+FILE_MAXFILE)*2)
175
176 static int ptcache_path(PTCacheID *pid, char *filename)
177 {
178         Library *lib;
179         int i;
180
181         lib= (pid)? pid->ob->id.lib: NULL;
182
183         if (G.relbase_valid || lib) {
184                 char file[MAX_PTCACHE_PATH]; /* we dont want the dir, only the file */
185                 char *blendfilename;
186
187                 blendfilename= (lib)? lib->filename: G.sce;
188
189                 BLI_split_dirfile_basic(blendfilename, NULL, file);
190                 i = strlen(file);
191                 
192                 /* remove .blend */
193                 if (i > 6)
194                         file[i-6] = '\0';
195                 
196                 snprintf(filename, MAX_PTCACHE_PATH, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */
197                 BLI_convertstringcode(filename, blendfilename);
198                 BLI_add_slash(filename);
199                 return strlen(filename);
200         }
201         
202         /* use the temp path. this is weak but better then not using point cache at all */
203         /* btempdir is assumed to exist and ALWAYS has a trailing slash */
204         snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH"%d", btempdir, abs(getpid()));
205         BLI_add_slash(filename);
206         return strlen(filename);
207 }
208
209 static int BKE_ptcache_id_filename(PTCacheID *pid, char *filename, int cfra, short do_path, short do_ext)
210 {
211         int len=0;
212         char *idname;
213         char *newname;
214         filename[0] = '\0';
215         newname = filename;
216         
217         /*if (!G.relbase_valid) return 0; *//* save blend file before using pointcache */
218         
219         /* start with temp dir */
220         if (do_path) {
221                 len = ptcache_path(pid, filename);
222                 newname += len;
223         }
224         idname = (pid->ob->id.name+2);
225         /* convert chars to hex so they are always a valid filename */
226         while('\0' != *idname) {
227                 snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
228                 newname+=2;
229                 len += 2;
230         }
231         
232         if (do_ext) {
233                 snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
234                 len += 16;
235         }
236         
237         return len; /* make sure the above string is always 16 chars */
238 }
239
240 /* youll need to close yourself after! */
241 PTCacheFile *BKE_ptcache_file_open(PTCacheID *pid, int mode, int cfra)
242 {
243         PTCacheFile *pf;
244         FILE *fp = NULL;
245         char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
246
247         /* don't allow writing for linked objects */
248         if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
249                 return NULL;
250
251         /*if (!G.relbase_valid) return NULL; *//* save blend file before using pointcache */
252         
253         BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
254
255         if (mode==PTCACHE_FILE_READ) {
256                 if (!BLI_exists(filename)) {
257                         return NULL;
258                 }
259                 fp = fopen(filename, "rb");
260         } else if (mode==PTCACHE_FILE_WRITE) {
261                 BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
262                 fp = fopen(filename, "wb");
263         }
264
265         if (!fp)
266                 return NULL;
267         
268         pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile");
269         pf->fp= fp;
270         
271         return pf;
272 }
273
274 void BKE_ptcache_file_close(PTCacheFile *pf)
275 {
276         fclose(pf->fp);
277         MEM_freeN(pf);
278 }
279
280 int BKE_ptcache_file_read_floats(PTCacheFile *pf, float *f, int tot)
281 {
282         return (fread(f, sizeof(float), tot, pf->fp) == tot);
283 }
284
285 int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot)
286 {
287         return (fwrite(f, sizeof(float), tot, pf->fp) == tot);
288 }
289
290 /* youll need to close yourself after!
291  * mode - PTCACHE_CLEAR_ALL, 
292
293 */
294
295 void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
296 {
297         int len; /* store the length of the string */
298
299         /* mode is same as fopen's modes */
300         DIR *dir; 
301         struct dirent *de;
302         char path[MAX_PTCACHE_PATH];
303         char filename[MAX_PTCACHE_FILE];
304         char path_full[MAX_PTCACHE_FILE];
305         char ext[MAX_PTCACHE_PATH];
306
307         if(!pid->cache)
308                 return;
309
310         /* don't allow clearing for linked objects */
311         if(pid->ob->id.lib)
312                 return;
313
314         /*if (!G.relbase_valid) return; *//* save blend file before using pointcache */
315         
316         /* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */
317         switch (mode) {
318         case PTCACHE_CLEAR_ALL:
319         case PTCACHE_CLEAR_BEFORE:      
320         case PTCACHE_CLEAR_AFTER:
321                 ptcache_path(pid, path);
322                 
323                 len = BKE_ptcache_id_filename(pid, filename, cfra, 0, 0); /* no path */
324                 
325                 dir = opendir(path);
326                 if (dir==NULL)
327                         return;
328
329                 snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
330                 
331                 while ((de = readdir(dir)) != NULL) {
332                         if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
333                                 if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
334                                         if (mode == PTCACHE_CLEAR_ALL) {
335                                                 BLI_join_dirfile(path_full, path, de->d_name);
336                                                 BLI_delete(path_full, 0, 0);
337                                         } else {
338                                                 /* read the number of the file */
339                                                 int frame, len2 = strlen(de->d_name);
340                                                 char num[7];
341
342                                                 if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
343                                                         BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
344                                                         frame = atoi(num);
345                                                         
346                                                         if((mode==PTCACHE_CLEAR_BEFORE && frame < cfra) || 
347                                                            (mode==PTCACHE_CLEAR_AFTER && frame > cfra)  ) {
348                                                                 
349                                                                 BLI_join_dirfile(path_full, path, de->d_name);
350                                                                 BLI_delete(path_full, 0, 0);
351                                                         }
352                                                 }
353                                         }
354                                 }
355                         }
356                 }
357                 closedir(dir);
358                 break;
359                 
360         case PTCACHE_CLEAR_FRAME:
361                 len = BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); /* no path */
362                 BLI_delete(filename, 0, 0);
363                 break;
364         }
365 }
366
367 int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
368 {
369         char filename[MAX_PTCACHE_FILE];
370
371         if(!pid->cache)
372                 return 0;
373         
374         BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
375
376         return BLI_exists(filename);
377 }
378
379 void BKE_ptcache_id_time(PTCacheID *pid, float cfra, int *startframe, int *endframe, float *timescale)
380 {
381         Object *ob;
382         PointCache *cache;
383         float offset, time, nexttime;
384
385         /* time handling for point cache:
386          * - simulation time is scaled by result of bsystem_time
387          * - for offsetting time only time offset is taken into account, since
388          *   that's always the same and can't be animated. a timeoffset which
389          *   varies over time is not simpe to support.
390          * - field and motion blur offsets are currently ignored, proper solution
391          *   is probably to interpolate results from two frames for that ..
392          */
393
394         ob= pid->ob;
395         cache= pid->cache;
396
397         if(timescale) {
398                 time= bsystem_time(ob, cfra, 0.0f);
399                 nexttime= bsystem_time(ob, cfra+1.0f, 0.0f);
400
401                 *timescale= MAX2(nexttime - time, 0.0f);
402         }
403
404         if(startframe && endframe) {
405                 *startframe= cache->startframe;
406                 *endframe= cache->endframe;
407
408                 if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0) {
409                         offset= give_timeoffset(ob);
410
411                         *startframe += (int)(offset+0.5f);
412                         *endframe += (int)(offset+0.5f);
413                 }
414         }
415 }
416
417 int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
418 {
419         PointCache *cache;
420         int reset, clear;
421
422         if(!pid->cache)
423                 return 0;
424
425         cache= pid->cache;
426         reset= 0;
427         clear= 0;
428
429         if(mode == PTCACHE_RESET_DEPSGRAPH) {
430                 if(!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
431                         reset= 1;
432                         clear= 1;
433                 }
434                 else
435                         cache->flag |= PTCACHE_OUTDATED;
436         }
437         else if(mode == PTCACHE_RESET_BAKED) {
438                 if(!BKE_ptcache_get_continue_physics()) {
439                         reset= 1;
440                         clear= 1;
441                 }
442                 else
443                         cache->flag |= PTCACHE_OUTDATED;
444         }
445         else if(mode == PTCACHE_RESET_OUTDATED) {
446                 reset = 1;
447
448                 if(cache->flag & PTCACHE_OUTDATED)
449                         if(!(cache->flag & PTCACHE_BAKED))
450                                 clear= 1;
451         }
452
453         if(reset) {
454                 cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_SIMULATION_VALID);
455                 cache->simframe= 0;
456
457                 if(pid->type == PTCACHE_TYPE_CLOTH)
458                         cloth_free_modifier(pid->ob, pid->data);
459                 else if(pid->type == PTCACHE_TYPE_SOFTBODY)
460                         sbFreeSimulation(pid->data);
461                 else if(pid->type == PTCACHE_TYPE_PARTICLES)
462                         psys_reset(pid->data, PSYS_RESET_DEPSGRAPH);
463         }
464         if(clear)
465                 BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
466
467         return (reset || clear);
468 }
469
470 int BKE_ptcache_object_reset(Object *ob, int mode)
471 {
472         PTCacheID pid;
473         ParticleSystem *psys;
474         ModifierData *md;
475         int reset, skip;
476
477         reset= 0;
478         skip= 0;
479
480         if(ob->soft) {
481                 BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
482                 reset |= BKE_ptcache_id_reset(&pid, mode);
483         }
484
485         for(psys=ob->particlesystem.first; psys; psys=psys->next) {
486                 /* Baked softbody hair has to be checked first, because we don't want to reset */
487                 /* particles or softbody in that case -jahka */
488                 if(psys->soft) {
489                         BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
490                         if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED))) 
491                                 reset |= BKE_ptcache_id_reset(&pid, mode);
492                         else
493                                 skip = 1;
494                 }
495
496                 if(skip == 0) {
497                         BKE_ptcache_id_from_particles(&pid, ob, psys);
498                         reset |= BKE_ptcache_id_reset(&pid, mode);
499                 }
500         }
501
502         for(md=ob->modifiers.first; md; md=md->next) {
503                 if(md->type == eModifierType_Cloth) {
504                         BKE_ptcache_id_from_cloth(&pid, ob, (ClothModifierData*)md);
505                         reset |= BKE_ptcache_id_reset(&pid, mode);
506                 }
507         }
508
509         return reset;
510 }
511
512 /* Use this when quitting blender, with unsaved files */
513 void BKE_ptcache_remove(void)
514 {
515         char path[MAX_PTCACHE_PATH];
516         char path_full[MAX_PTCACHE_PATH];
517         int rmdir = 1;
518         
519         ptcache_path(NULL, path);
520
521         if (BLI_exist(path)) {
522                 /* The pointcache dir exists? - remove all pointcache */
523
524                 DIR *dir; 
525                 struct dirent *de;
526
527                 dir = opendir(path);
528                 if (dir==NULL)
529                         return;
530                 
531                 while ((de = readdir(dir)) != NULL) {
532                         if( strcmp(de->d_name, ".")==0 || strcmp(de->d_name, "..")==0) {
533                                 /* do nothing */
534                         } else if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
535                                 BLI_join_dirfile(path_full, path, de->d_name);
536                                 BLI_delete(path_full, 0, 0);
537                         } else {
538                                 rmdir = 0; /* unknown file, dont remove the dir */
539                         }
540                 }
541
542                 closedir(dir);
543         } else { 
544                 rmdir = 0; /* path dosnt exist  */
545         }
546         
547         if (rmdir) {
548                 BLI_delete(path, 1, 0);
549         }
550 }
551
552 /* Continuous Interaction */
553
554 static int CONTINUE_PHYSICS = 0;
555
556 void BKE_ptcache_set_continue_physics(int enable)
557 {
558         Object *ob;
559
560         if(CONTINUE_PHYSICS != enable) {
561                 CONTINUE_PHYSICS = enable;
562
563                 if(CONTINUE_PHYSICS == 0) {
564                         for(ob=G.main->object.first; ob; ob=ob->id.next)
565                                 if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_OUTDATED))
566                                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
567                 }
568         }
569 }
570
571 int BKE_ptcache_get_continue_physics()
572 {
573         return CONTINUE_PHYSICS;
574 }
575
576 /* Point Cache */
577
578 PointCache *BKE_ptcache_add()
579 {
580         PointCache *cache;
581
582         cache= MEM_callocN(sizeof(PointCache), "PointCache");
583         cache->startframe= 1;
584         cache->endframe= 250;
585
586         return cache;
587 }
588
589 void BKE_ptcache_free(PointCache *cache)
590 {
591         MEM_freeN(cache);
592 }
593
594 PointCache *BKE_ptcache_copy(PointCache *cache)
595 {
596         PointCache *ncache;
597
598         ncache= MEM_dupallocN(cache);
599
600         ncache->flag= 0;
601         ncache->simframe= 0;
602
603         return ncache;
604 }
605