Smoke now uses only one point cache where both normal and high resolution smoke are...
authorJanne Karhu <jhkarh@gmail.com>
Tue, 30 Nov 2010 21:31:18 +0000 (21:31 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Tue, 30 Nov 2010 21:31:18 +0000 (21:31 +0000)
* Separate caches were causing quite a lot of problems both in principle and practice.
* For example it doesn't really make sense to have different frame ranges for normal and high resolution smoke, but this was fully possible before.
* Also to fully bake the smoke you had to do a "Bake All Dynamics", which completely defeats the whole point of the feature!
* As a result of this change the smoke cache usage is much much simpler and less error prone.
* This is quite a big change, but hopefully there should be less rather than more problems as a result :)

Some other related changes:
* Changing the cache name now works for disk caches properly too, it now just renames the cache files so should be faster too!
* Smoke is now always forced to disk cache with step 1 on file load as there were some strange cases where smoke was trying to use memory cache.
* Disabled smoke debug prints from console.
* Disabled changing smoke parameters when smoke is baked.

Note to users: The unfortunate side effect of this is that old high resolution simulations have to be baked again, but in return you get much better and more logical functionality. Sorry none the less!

release/scripts/ui/properties_physics_smoke.py
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/smoke.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/DNA_smoke_types.h
source/blender/makesrna/intern/rna_object_force.c
source/blender/makesrna/intern/rna_smoke.c

index 4721eddbf37e97a34d2b32d8d42bb60e2120546f..3d74804d86ae31931fdca6ddef5a8f2b4e9ba945 100644 (file)
@@ -69,6 +69,8 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, bpy.types.Panel):
 
                 split = layout.split()
 
+                split.enabled = not domain.point_cache.is_baked
+
                 col = split.column()
                 col.label(text="Resolution:")
                 col.prop(domain, "resolution_max", text="Divisions")
@@ -146,27 +148,6 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, bpy.types.Panel):
         col.prop(group, "collision_group", text="")
 
 
-class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, bpy.types.Panel):
-    bl_label = "Smoke Cache"
-    bl_options = {'DEFAULT_CLOSED'}
-
-    @classmethod
-    def poll(cls, context):
-        md = context.smoke
-        return md and (md.smoke_type == 'DOMAIN')
-
-    def draw(self, context):
-        layout = self.layout
-
-        md = context.smoke.domain_settings
-        cache = md.point_cache_low
-
-        layout.label(text="Compression:")
-        layout.prop(md, "point_cache_compress_type", expand=True)
-
-        point_cache_ui(self, context, cache, (cache.is_baked is False), 'SMOKE')
-
-
 class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, bpy.types.Panel):
     bl_label = "Smoke High Resolution"
     bl_options = {'DEFAULT_CLOSED'}
@@ -179,6 +160,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, bpy.types.Panel):
     def draw_header(self, context):
         md = context.smoke.domain_settings
 
+        self.layout.enabled = not md.point_cache.is_baked
         self.layout.prop(md, "use_high_resolution", text="")
 
     def draw(self, context):
@@ -189,36 +171,38 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, bpy.types.Panel):
         layout.active = md.use_high_resolution
 
         split = layout.split()
+        split.enabled = not md.point_cache.is_baked
 
         col = split.column()
         col.label(text="Resolution:")
         col.prop(md, "amplify", text="Divisions")
         col.prop(md, "smooth_emitter")
-        col.prop(md, "show_high_resolution")
 
         col = split.column()
         col.label(text="Noise Method:")
         col.row().prop(md, "noise_type", text="")
         col.prop(md, "strength")
 
+        layout.prop(md, "show_high_resolution")
+
 
-class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel, bpy.types.Panel):
-    bl_label = "Smoke High Resolution Cache"
+class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, bpy.types.Panel):
+    bl_label = "Smoke Cache"
     bl_options = {'DEFAULT_CLOSED'}
 
     @classmethod
     def poll(cls, context):
         md = context.smoke
-        return md and (md.smoke_type == 'DOMAIN') and md.domain_settings.use_high_resolution
+        return md and (md.smoke_type == 'DOMAIN')
 
     def draw(self, context):
         layout = self.layout
 
         md = context.smoke.domain_settings
-        cache = md.point_cache_high
+        cache = md.point_cache
 
         layout.label(text="Compression:")
-        layout.prop(md, "point_cache_compress_high_type", expand=True)
+        layout.prop(md, "point_cache_compress_type", expand=True)
 
         point_cache_ui(self, context, cache, (cache.is_baked is False), 'SMOKE')
 
index 52536e10e565b7d1bf965f54200561601ccf9f62..aba22df0fe3a4522868048d464d5892eaac4082a 100644 (file)
@@ -32,6 +32,7 @@
 #include "DNA_ID.h"
 #include "DNA_object_force.h"
 #include "DNA_boid_types.h"
+#include <stdio.h> /* for FILE */
 
 /* Point cache clearing option, for BKE_ptcache_id_clear, before
  * and after are non inclusive (they wont remove the cfra) */
@@ -234,7 +235,6 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct Soft
 void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
 void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd);
 void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd);
-void BKE_ptcache_id_from_smoke_turbulence(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd);
 
 void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis);
 
@@ -300,6 +300,9 @@ void BKE_ptcache_mem_to_disk(struct PTCacheID *pid);
 /* Convert disk cache to memory cache and vice versa. Clears the cache that was converted. */
 void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid);
 
+/* Rename all disk cache files with a new name. Doesn't touch the actual content of the files. */
+void BKE_ptcache_disk_cache_rename(struct PTCacheID *pid, char *from, char *to);
+
 /* Loads simulation from external (disk) cache files. */
 void BKE_ptcache_load_external(struct PTCacheID *pid);
 
index 4d22b22ae319621fee782f82c87f9a284c2a04b9..440a3136108301c5fff57f7ce0e9a5b1d021f3a8 100644 (file)
@@ -725,6 +725,7 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
 {      
        SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
        SmokeDomainSettings *sds = smd->domain;
+       int ret = 0;
        
        if(sds->fluid) {
                size_t res = sds->res[0]*sds->res[1]*sds->res[2];
@@ -755,16 +756,9 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
 
                MEM_freeN(out);
                
-               return 1;
+               ret = 1;
        }
-       return 0;
-}
 
-static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
-{
-       SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
-       SmokeDomainSettings *sds = smd->domain;
-       
        if(sds->wt) {
                int res_big_array[3];
                int res_big;
@@ -796,11 +790,13 @@ static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
                ptcache_compress_write(pf, (unsigned char *)tcw, in_len, out, mode);
                MEM_freeN(out);
                
-               return 1;
+               ret = 1;
        }
-       return 0;
+
+       return ret;
 }
 
+
 // forward decleration
 static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, int size);
 
@@ -877,33 +873,27 @@ static void ptcache_read_smoke(PTCacheFile *pf, void *smoke_v)
                ptcache_compress_read(pf, (unsigned char*)obstacles, (unsigned int)res);
                ptcache_file_read(pf, &dt, 1, sizeof(float));
                ptcache_file_read(pf, &dx, 1, sizeof(float));
-       }
-}
 
-static void ptcache_read_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
-{
-       SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
-       SmokeDomainSettings *sds = smd->domain;
-       
-       if(sds->fluid) {
-               int res = sds->res[0]*sds->res[1]*sds->res[2];
-               int res_big, res_big_array[3];
-               float *dens, *densold, *tcu, *tcv, *tcw;
-               unsigned int out_len = sizeof(float)*(unsigned int)res;
-               unsigned int out_len_big;
+               if(pf->data_types & (1<<BPHYS_DATA_SMOKE_HIGH) && sds->wt) {
+                       int res = sds->res[0]*sds->res[1]*sds->res[2];
+                       int res_big, res_big_array[3];
+                       float *dens, *densold, *tcu, *tcv, *tcw;
+                       unsigned int out_len = sizeof(float)*(unsigned int)res;
+                       unsigned int out_len_big;
 
-               smoke_turbulence_get_res(sds->wt, res_big_array);
-               res_big = res_big_array[0]*res_big_array[1]*res_big_array[2];
-               out_len_big = sizeof(float) * (unsigned int)res_big;
+                       smoke_turbulence_get_res(sds->wt, res_big_array);
+                       res_big = res_big_array[0]*res_big_array[1]*res_big_array[2];
+                       out_len_big = sizeof(float) * (unsigned int)res_big;
 
-               smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
+                       smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
 
-               ptcache_compress_read(pf, (unsigned char*)dens, out_len_big);
-               ptcache_compress_read(pf, (unsigned char*)densold, out_len_big);
+                       ptcache_compress_read(pf, (unsigned char*)dens, out_len_big);
+                       ptcache_compress_read(pf, (unsigned char*)densold, out_len_big);
 
-               ptcache_compress_read(pf, (unsigned char*)tcu, out_len);
-               ptcache_compress_read(pf, (unsigned char*)tcv, out_len);
-               ptcache_compress_read(pf, (unsigned char*)tcw, out_len);                
+                       ptcache_compress_read(pf, (unsigned char*)tcu, out_len);
+                       ptcache_compress_read(pf, (unsigned char*)tcv, out_len);
+                       ptcache_compress_read(pf, (unsigned char*)tcw, out_len);
+               }
        }
 }
 
@@ -936,41 +926,13 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
        pid->write_header= ptcache_write_basic_header;
        pid->read_header= ptcache_read_basic_header;
 
-       pid->data_types= (1<<BPHYS_DATA_LOCATION); // bogus values to make pointcache happy
+       pid->data_types= 0;
        pid->info_types= 0;
-}
 
-void BKE_ptcache_id_from_smoke_turbulence(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd)
-{
-       SmokeDomainSettings *sds = smd->domain;
-
-       memset(pid, 0, sizeof(PTCacheID));
-
-       pid->ob= ob;
-       pid->calldata= smd;
-       
-       pid->type= PTCACHE_TYPE_SMOKE_HIGHRES;
-       pid->stack_index= sds->point_cache[1]->index;
-
-       pid->cache= sds->point_cache[1];
-       pid->cache_ptr= &sds->point_cache[1];
-       pid->ptcaches= &sds->ptcaches[1];
-
-       pid->totpoint= pid->totwrite= ptcache_totpoint_smoke_turbulence;
-
-       pid->write_elem= NULL;
-       pid->read_elem= NULL;
-
-       pid->read_stream = ptcache_read_smoke_turbulence;
-       pid->write_stream = ptcache_write_smoke_turbulence;
-       
-       pid->interpolate_elem= NULL;
-
-       pid->write_header= ptcache_write_basic_header;
-       pid->read_header= ptcache_read_basic_header;
-
-       pid->data_types= (1<<BPHYS_DATA_LOCATION); // bogus values tot make pointcache happy
-       pid->info_types= 0;
+       if(sds->fluid)
+               pid->data_types |= (1<<BPHYS_DATA_SMOKE_LOW);
+       if(sds->wt)
+               pid->data_types |= (1<<BPHYS_DATA_SMOKE_HIGH);
 }
 
 void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
@@ -1046,10 +1008,6 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
                                pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
                                BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md);
                                BLI_addtail(lb, pid);
-
-                               pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
-                               BKE_ptcache_id_from_smoke_turbulence(pid, ob, (SmokeModifierData*)md);
-                               BLI_addtail(lb, pid);
                        }
                }
        }
@@ -2289,9 +2247,6 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
                        {
                                BKE_ptcache_id_from_smoke(&pid, ob, (SmokeModifierData*)md);
                                reset |= BKE_ptcache_id_reset(scene, &pid, mode);
-
-                               BKE_ptcache_id_from_smoke_turbulence(&pid, ob, (SmokeModifierData*)md);
-                               reset |= BKE_ptcache_id_reset(scene, &pid, mode);
                        }
                }
        }
@@ -2841,6 +2796,61 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
        BKE_ptcache_update_info(pid);
 }
 
+void BKE_ptcache_disk_cache_rename(PTCacheID *pid, char *from, char *to)
+{
+       char old_name[80];
+       int len; /* store the length of the string */
+       /* mode is same as fopen's modes */
+       DIR *dir; 
+       struct dirent *de;
+       char path[MAX_PTCACHE_PATH];
+       char old_filename[MAX_PTCACHE_FILE];
+       char new_path_full[MAX_PTCACHE_FILE];
+       char old_path_full[MAX_PTCACHE_FILE];
+       char ext[MAX_PTCACHE_PATH];
+
+       /* save old name */
+       strcpy(old_name, pid->cache->name);
+
+       /* get "from" filename */
+       strcpy(pid->cache->name, from);
+
+       len = BKE_ptcache_id_filename(pid, old_filename, 0, 0, 0); /* no path */
+
+       ptcache_path(pid, path);
+       dir = opendir(path);
+       if(dir==NULL) {
+               strcpy(pid->cache->name, old_name);
+               return;
+       }
+
+       snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
+
+       /* put new name into cache */
+       strcpy(pid->cache->name, to);
+
+       while ((de = readdir(dir)) != NULL) {
+               if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
+                       if (strncmp(old_filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+                               /* read the number of the file */
+                               int frame, len2 = (int)strlen(de->d_name);
+                               char num[7];
+
+                               if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
+                                       BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
+                                       frame = atoi(num);
+
+                                       BLI_join_dirfile(old_path_full, path, de->d_name);
+                                       BKE_ptcache_id_filename(pid, new_path_full, frame, 1, 1);
+                                       BLI_rename(old_path_full, new_path_full);
+                               }
+                       }
+               }
+       }
+
+       strcpy(pid->cache->name, old_name);
+}
+
 void BKE_ptcache_load_external(PTCacheID *pid)
 {
        /*todo*/
@@ -2965,14 +2975,25 @@ void BKE_ptcache_update_info(PTCacheID *pid)
        }
 
        if(cache->flag & PTCACHE_DISK_CACHE) {
-               int cfra = cache->startframe;
+               if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
+               {
+                       int totpoint = pid->totpoint(pid->calldata, 0);
 
-               for(; cfra<=cache->endframe; cfra++) {
-                       if(BKE_ptcache_id_exist(pid, cfra))
-                               totframes++;
+                       if(cache->totpoint > totpoint)
+                               sprintf(mem_info, "%i cells + High Resolution cached", totpoint);
+                       else
+                               sprintf(mem_info, "%i cells cached");
                }
+               else {
+                       int cfra = cache->startframe;
 
-               sprintf(mem_info, "%i frames on disk", totframes);
+                       for(; cfra<=cache->endframe; cfra++) {
+                               if(BKE_ptcache_id_exist(pid, cfra))
+                                       totframes++;
+                       }
+
+                       sprintf(mem_info, "%i frames on disk", totframes);
+               }
        }
        else {
                PTCacheMem *pm = cache->mem_cache.first;                
index 8822d0cb4c9cf52db59e151d58409115bf29a76d..8fd9c48cc611820c959ec9199cc390f529eb24cf 100644 (file)
@@ -554,8 +554,6 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd)
 
                BKE_ptcache_free_list(&(smd->domain->ptcaches[0]));
                smd->domain->point_cache[0] = NULL;
-               BKE_ptcache_free_list(&(smd->domain->ptcaches[1]));
-               smd->domain->point_cache[1] = NULL;
 
                MEM_freeN(smd->domain);
                smd->domain = NULL;
@@ -695,10 +693,9 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
                        smd->domain->point_cache[0]->flag |= PTCACHE_DISK_CACHE;
                        smd->domain->point_cache[0]->step = 1;
 
-                       smd->domain->point_cache[1] = BKE_ptcache_add(&(smd->domain->ptcaches[1]));
-                       smd->domain->point_cache[1]->flag |= PTCACHE_DISK_CACHE;
-                       smd->domain->point_cache[1]->step = 1;
-
+                       /* Deprecated */
+                       smd->domain->point_cache[1] = NULL;
+                       smd->domain->ptcaches[1].first = smd->domain->ptcaches[1].last = NULL;
                        /* set some standard values */
                        smd->domain->fluid = NULL;
                        smd->domain->wt = NULL;                 
@@ -1323,35 +1320,22 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
                float light[3]; 
                PointCache *cache = NULL;
                PTCacheID pid;
-               PointCache *cache_wt = NULL;
-               PTCacheID pid_wt;
                int startframe, endframe, framenr;
                float timescale;
-               int cache_result = 0, cache_result_wt = 0;
-               int did_init = 0;
 
                framenr = scene->r.cfra;
 
-               printf("time: %d\n", scene->r.cfra);
+               //printf("time: %d\n", scene->r.cfra);
 
                cache = sds->point_cache[0];
                BKE_ptcache_id_from_smoke(&pid, ob, smd);
                BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
 
-               cache_wt = sds->point_cache[1];
-               BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);
-
                if(!smd->domain->fluid || framenr == startframe)
                {
                        BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
                        BKE_ptcache_validate(cache, framenr);
                        cache->flag &= ~PTCACHE_REDO_NEEDED;
-
-                       BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
-                       if(cache_wt) {
-                               BKE_ptcache_validate(cache_wt, framenr);
-                               cache_wt->flag &= ~PTCACHE_REDO_NEEDED;
-                       }
                }
 
                if(!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD)==0 && (cache->flag & PTCACHE_BAKED)==0)
@@ -1359,11 +1343,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
 
                smd->domain->flags &= ~MOD_SMOKE_FILE_LOAD;
 
-               if(framenr < startframe)
-                       framenr = startframe;
-
-               if(framenr > endframe)
-                       framenr = endframe;
+               CLAMP(framenr, startframe, endframe);
 
                /* If already viewing a pre/after frame, no need to reload */
                if ((smd->time == framenr) && (framenr != scene->r.cfra))
@@ -1371,42 +1351,21 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
 
                // printf("startframe: %d, framenr: %d\n", startframe, framenr);
 
-               if(!(did_init = smokeModifier_init(smd, ob, scene, dm)))
+               if(smokeModifier_init(smd, ob, scene, dm)==0)
                {
                        printf("bad smokeModifier_init\n");
                        return;
                }
 
                /* try to read from cache */
-               cache_result =  BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
-               // printf("cache_result: %d\n", cache_result);
-
-               if(cache_result == PTCACHE_READ_EXACT) 
-               {
+               if(BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec) == PTCACHE_READ_EXACT) {
                        BKE_ptcache_validate(cache, framenr);
                        smd->time = framenr;
-
-                       if(sds->wt)
-                       {
-                               cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec);
-                               
-                               if(cache_result_wt == PTCACHE_READ_EXACT) 
-                               {
-                                       BKE_ptcache_validate(cache_wt, framenr);
-
-                                       return;
-                               }
-                               else
-                               {
-                                       ; /* don't return in the case we only got low res cache but no high res cache */
-                                       /* we still need to calculate the high res cache */
-                               }
-                       }
-                       else
-                               return;
+                       return;
                }
+               
                /* only calculate something when we advanced a single frame */
-               else if(framenr != (int)smd->time+1)
+               if(framenr != (int)smd->time+1)
                        return;
 
                /* don't simulate if viewing start frame, but scene frame is not real start frame */
@@ -1418,15 +1377,19 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
                smoke_calc_domain(scene, ob, smd);
 
                /* if on second frame, write cache for first frame */
-               /* this needs to be done for smoke too so that pointcache works properly */
                if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) {
                        // create shadows straight after domain initialization so we get nice shadows for startframe, too
                        if(get_lamp(scene, light))
                                smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
 
-                       BKE_ptcache_write_cache(&pid, startframe);
                        if(sds->wt)
-                               BKE_ptcache_write_cache(&pid_wt, startframe);
+                       {
+                               if(sds->flags & MOD_SMOKE_DISSOLVE)
+                                       smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
+                               smoke_turbulence_step(sds->wt, sds->fluid);
+                       }
+
+                       BKE_ptcache_write_cache(&pid, startframe);
                }
                
                // set new time
@@ -1444,39 +1407,24 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
                                smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
                        smoke_step(sds->fluid, smd->time, scene->r.frs_sec / scene->r.frs_sec_base);
                }
-               else
-               {
-                       /* Smoke did not load cache and was not reset but we're on startframe */
-                       /* So now reinit the smoke since it was not done yet */
-                       if(did_init == 2)
-                       {
-                               smokeModifier_reset(smd);
-                               smokeModifier_init(smd, ob, scene, dm);
-                       }
-               }
 
                // create shadows before writing cache so they get stored
                if(get_lamp(scene, light))
                        smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
-       
-               BKE_ptcache_validate(cache, framenr);
-               BKE_ptcache_write_cache(&pid, framenr);
 
                if(sds->wt)
                {
-                       if(framenr!=startframe)
-                       {
-                               if(sds->flags & MOD_SMOKE_DISSOLVE)
-                                       smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
-                               smoke_turbulence_step(sds->wt, sds->fluid);
-                       }
-
-                       BKE_ptcache_validate(cache_wt, framenr);
-                       BKE_ptcache_write_cache(&pid_wt, framenr);
+                       if(sds->flags & MOD_SMOKE_DISSOLVE)
+                               smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
+                       smoke_turbulence_step(sds->wt, sds->fluid);
                }
+       
+               BKE_ptcache_validate(cache, framenr);
+               if(framenr != startframe)
+                       BKE_ptcache_write_cache(&pid, framenr);
 
                tend();
-               printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
+               //printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
        }
 }
 
index 419ef90ab3a49f908bad1e8e70fc516ddad4e4e2..fcff021092dda284063345bfa1b3e051f99c3646 100644 (file)
@@ -2947,14 +2947,19 @@ static void direct_link_pointcache(FileData *fd, PointCache *cache)
        cache->cached_frames= NULL;
 }
 
-static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointCache **ocache)
+static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointCache **ocache, int force_disk)
 {
        PointCache *cache;
 
        if(ptcaches->first) {
                link_list(fd, ptcaches);
-               for(cache=ptcaches->first; cache; cache=cache->next)
+               for(cache=ptcaches->first; cache; cache=cache->next) {
                        direct_link_pointcache(fd, cache);
+                       if(force_disk) {
+                               cache->flag |= PTCACHE_DISK_CACHE;
+                               cache->step = 1;
+                       }
+               }
 
                *ocache = newdataadr(fd, *ocache);
        }
@@ -2962,6 +2967,10 @@ static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointC
                /* old "single" caches need to be linked too */
                *ocache = newdataadr(fd, *ocache);
                direct_link_pointcache(fd, *ocache);
+               if(force_disk) {
+                       (*ocache)->flag |= PTCACHE_DISK_CACHE;
+                       cache->step = 1;
+               }
 
                ptcaches->first = ptcaches->last = *ocache;
        }
@@ -3150,7 +3159,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                psys->pdd = NULL;
                psys->renderdata = NULL;
                
-               direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache);
+               direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache, 0);
 
                if(psys->clmd) {
                        psys->clmd = newdataadr(fd, psys->clmd);
@@ -3757,7 +3766,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
                        clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
 
-                       direct_link_pointcache_list(fd, &clmd->ptcaches, &clmd->point_cache);
+                       direct_link_pointcache_list(fd, &clmd->ptcaches, &clmd->point_cache, 0);
                        
                        if(clmd->sim_parms) {
                                if(clmd->sim_parms->presets > 10)
@@ -3799,8 +3808,14 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                if(!smd->domain->effector_weights)
                                        smd->domain->effector_weights = BKE_add_effector_weights(NULL);
 
-                               direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]));
-                               direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1]));
+                               direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]), 1);
+
+                               /* Smoke uses only one cache from now on, so store pointer convert */
+                               if(smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) {
+                                       printf("High resolution smoke cache not available due to pointcache update. Please reset the simulation.\n");
+                                       smd->domain->ptcaches[1].first = smd->domain->ptcaches[1].first = NULL;
+                                       smd->domain->point_cache[1] = NULL;
+                               }
                        }
                        else if(smd->type==MOD_SMOKE_TYPE_FLOW)
                        {
@@ -4034,7 +4049,7 @@ static void direct_link_object(FileData *fd, Object *ob)
                if(!sb->effector_weights)
                        sb->effector_weights = BKE_add_effector_weights(NULL);
 
-               direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache);
+               direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache, 0);
        }
        ob->bsoft= newdataadr(fd, ob->bsoft);
        ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
index d07db66cb0f2a9dfd5bbff242a439e19b07553ec..4515a6c05a3bd32b6ee8ebf62f7cc2bcb1d3ec35 100644 (file)
@@ -129,7 +129,9 @@ typedef struct EffectorWeights {
 */
 #define BPHYS_DATA_INDEX               0
 #define BPHYS_DATA_LOCATION            1
+#define BPHYS_DATA_SMOKE_LOW   1
 #define BPHYS_DATA_VELOCITY            2
+#define BPHYS_DATA_SMOKE_HIGH  2
 #define BPHYS_DATA_ROTATION            3
 #define BPHYS_DATA_AVELOCITY   4       /* used for particles */
 #define BPHYS_DATA_XCONST              4       /* used for cloth */
index 95b6505529bf8651a997b099251ca8a08baaf528..0482c19e18989a274ba205c04accd0493075ef94 100644 (file)
@@ -87,6 +87,8 @@ typedef struct SmokeDomainSettings {
        int v3dnum;
        int cache_comp;
        int cache_high_comp;
+
+       /* Smoke uses only one cache from now on (index [0]), but keeping the array for now for reading old files. */
        struct PointCache *point_cache[2];      /* definition is in DNA_object_force.h */
        struct ListBase ptcaches[2];
        struct EffectorWeights *effector_weights;
index a28e0b32eae5b7f02397c58d9a75593bcbbf0421..cdcc57bde1202d07cd9611bf054c9b38a0be9f94 100644 (file)
@@ -117,8 +117,12 @@ static void rna_Cache_change(Main *bmain, Scene *scene, PointerRNA *ptr)
                        break;
        }
 
-       if(pid)
+       if(pid) {
+               /* Just make sure this wasn't changed. */
+               if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
+                       cache->step = 1;
                BKE_ptcache_update_info(pid);
+       }
 
        BLI_freelistN(&pidlist);
 }
@@ -140,8 +144,11 @@ static void rna_Cache_toggle_disk_cache(Main *bmain, Scene *scene, PointerRNA *p
                        break;
        }
 
-       if(pid)
+       /* smoke can only use disk cache */
+       if(pid && pid->type != PTCACHE_TYPE_SMOKE_DOMAIN)
                BKE_ptcache_toggle_disk_cache(pid);
+       else
+               cache->flag ^= PTCACHE_DISK_CACHE;
 
        BLI_freelistN(&pidlist);
 }
@@ -153,7 +160,6 @@ static void rna_Cache_idname_change(Main *bmain, Scene *scene, PointerRNA *ptr)
        PTCacheID *pid = NULL, *pid2= NULL;
        ListBase pidlist;
        int new_name = 1;
-       char name[80];
 
        if(!ob)
                return;
@@ -188,19 +194,13 @@ static void rna_Cache_idname_change(Main *bmain, Scene *scene, PointerRNA *ptr)
 
                if(new_name) {
                        if(pid2 && cache->flag & PTCACHE_DISK_CACHE) {
-                               /* TODO: change to simple file rename */
-                               strcpy(name, cache->name);
-                               strcpy(cache->name, cache->prev_name);
-
-                               cache->flag &= ~PTCACHE_DISK_CACHE;
-
-                               BKE_ptcache_toggle_disk_cache(pid2);
-
-                               strcpy(cache->name, name);
+                               char old_name[80];
+                               char new_name[80];
 
-                               cache->flag |= PTCACHE_DISK_CACHE;
+                               strcpy(old_name, cache->prev_name);
+                               strcpy(new_name, cache->name);
 
-                               BKE_ptcache_toggle_disk_cache(pid2);
+                               BKE_ptcache_disk_cache_rename(pid2, old_name, new_name);
                        }
 
                        strcpy(cache->prev_name, cache->name);
index 0638667ad28d0389806760399ea300cf0c5a2e94..cdc80cfa176ffb489374ca3eadc5b6a943287aab 100644 (file)
@@ -65,10 +65,8 @@ static void rna_Smoke_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
 
        smokeModifier_reset(settings->smd);
 
-       if(settings->smd && settings->smd->domain) {
+       if(settings->smd && settings->smd->domain)
                settings->point_cache[0]->flag |= PTCACHE_OUTDATED;
-               settings->point_cache[1]->flag |= PTCACHE_OUTDATED;
-       }
 
        rna_Smoke_update(bmain, scene, ptr);
 }
@@ -79,10 +77,8 @@ static void rna_Smoke_reset_dependancy(Main *bmain, Scene *scene, PointerRNA *pt
 
        smokeModifier_reset(settings->smd);
 
-       if(settings->smd && settings->smd->domain) {
+       if(settings->smd && settings->smd->domain)
                settings->smd->domain->point_cache[0]->flag |= PTCACHE_OUTDATED;
-               settings->smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
-       }
 
        rna_Smoke_dependency_update(bmain, scene, ptr);
 }
@@ -219,40 +215,29 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
        RNA_def_property_range(prop, 1.0, 10000.0);
        RNA_def_property_ui_range(prop, 1.0, 10000.0, 1, 0);
        RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed");
-       RNA_def_property_update(prop, 0, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
 
        prop= RNA_def_property(srna, "use_dissolve_smoke", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE);
        RNA_def_property_ui_text(prop, "Dissolve Smoke", "Enable smoke to disappear over time");
-       RNA_def_property_update(prop, 0, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
 
        prop= RNA_def_property(srna, "use_dissolve_smoke_log", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE_LOG);
        RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x ");
-       RNA_def_property_update(prop, 0, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
 
-       prop= RNA_def_property(srna, "point_cache_low", PROP_POINTER, PROP_NONE);
+       prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
        RNA_def_property_flag(prop, PROP_NEVER_NULL);
        RNA_def_property_pointer_sdna(prop, NULL, "point_cache[0]");
        RNA_def_property_ui_text(prop, "Point Cache", "");
 
-       prop= RNA_def_property(srna, "point_cache_high", PROP_POINTER, PROP_NONE);
-       RNA_def_property_flag(prop, PROP_NEVER_NULL);
-       RNA_def_property_pointer_sdna(prop, NULL, "point_cache[1]");
-       RNA_def_property_ui_text(prop, "Point Cache", "");
-
        prop= RNA_def_property(srna, "point_cache_compress_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "cache_comp");
        RNA_def_property_enum_items(prop, smoke_cache_comp_items);
        RNA_def_property_ui_text(prop, "Cache Compression", "Compression method to be used");
        RNA_def_property_update(prop, 0, NULL);
 
-       prop= RNA_def_property(srna, "point_cache_compress_high_type", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "cache_high_comp");
-       RNA_def_property_enum_items(prop, smoke_cache_comp_items);
-       RNA_def_property_ui_text(prop, "Cache Compression", "Compression method to be used");
-       RNA_def_property_update(prop, 0, NULL);
-
        prop= RNA_def_property(srna, "collision_extents", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "border_collisions");
        RNA_def_property_enum_items(prop, smoke_domain_colli_items);
@@ -267,7 +252,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
        prop= RNA_def_property(srna, "smooth_emitter", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGH_SMOOTH);
        RNA_def_property_ui_text(prop, "Smooth Emitter", "Smoothens emitted smoke to avoid blockiness.");
-       RNA_def_property_update(prop, 0, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
 
        prop= RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "time_scale");