Smoke:
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 14 Sep 2009 00:01:08 +0000 (00:01 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 14 Sep 2009 00:01:08 +0000 (00:01 +0000)
* Totally new try to get cache running
* Didn't try "bake" and such things yet

Hint
* Very verbose yet
* Please do only test new blend files, not old ones!

Please give me feedback on my blog about the old crashers.

intern/smoke/intern/FLUID_3D.cpp
intern/smoke/intern/FLUID_3D.h
intern/smoke/intern/FLUID_3D_STATIC.cpp
intern/smoke/intern/smoke_API.cpp
source/blender/blenkernel/intern/smoke.c

index 7574a0ec16e45083b475d4a3a7b63399451bfae1..8a32eaa2e6824ea32fe389aa3eda7f5f637b48a0 100644 (file)
@@ -182,6 +182,9 @@ void FLUID_3D::initBlenderRNA(float *alpha, float *beta)
 //////////////////////////////////////////////////////////////////////
 void FLUID_3D::step()
 {
+       // addSmokeTestCase(_density, _res);
+       // addSmokeTestCase(_heat, _res);
+       
        // wipe forces
        for (int i = 0; i < _totalCells; i++)
        {
index 9d9e7318204d1b4f2028122b2fc39c007a173532..a7be7f58335d38b4ca5c1704f706df96862b3361 100644 (file)
@@ -47,7 +47,7 @@ class FLUID_3D
                void initVectorNoise(int amplify);
 
                void addSmokeColumn();
-               static void addSmokeTestCase(float* field, Vec3Int res, float value);
+               static void addSmokeTestCase(float* field, Vec3Int res);
 
                void step();
                void addObstacle(OBSTACLE* obstacle);
index 4909c071c3dd3c66dcebfd09b7956501c2b77aaa..2d3ec125c2b95a707c53461ae6064723ef93ef7e 100644 (file)
@@ -44,8 +44,8 @@ void FLUID_3D::addSmokeColumn() {
 // generic static version, so that it can be applied to the
 // WTURBULENCE grid as well
 //////////////////////////////////////////////////////////////////////
-/*
-void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value)
+
+void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res)
 {
        const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res);
        float dx = 1.0f / (float)maxRes;
@@ -57,22 +57,22 @@ void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value)
   float heighMin = 0.05;
   float heighMax = 0.10;
 
-  for (int y = 0; y < res[1]; y++)
-    for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[1]); z++)
+  for (int y = 0; y < res[2]; y++)
+    for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++)
       for (int x = 0; x < res[0]; x++)
       {
         float xLength = x * dx - xTotal * 0.4f;
-        float yLength = y * dx - zTotal * 0.5f;
+        float yLength = y * dx - yTotal * 0.5f;
         float radius = sqrtf(xLength * xLength + yLength * yLength);
 
         if (radius < 0.075f * xTotal)
         {
           int index = x + y * res[0] + z * slabSize;
-          field[index] = value;
+          field[index] = 1.0f;
         }
       }
 }
-*/
+
 
 //////////////////////////////////////////////////////////////////////
 // set x direction to Neumann boundary conditions
@@ -295,12 +295,10 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
        const int xres = res[0];
        const int yres = res[1];
        const int zres = res[2];
-       static int hits = 0;
-       static int total = 0;
        const int slabSize = res[0] * res[1];
 
        // scale dt up to grid resolution
-#if PARALLEL==1 && !_WIN32
+#if PARALLEL==1
 #pragma omp parallel
 #pragma omp for  schedule(static)
 #endif
index 058831dddbbe868975e25c82fa81eb6e9ba336e9..67df6e805d8965c0d1a20b407d8e318af5aeecc2 100644 (file)
@@ -81,8 +81,7 @@ extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr)
 
 extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
 {
-       if(wt) 
-               wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); 
+       wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); 
 }
 
 extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta)
index af79fd74ae8ce7096cec0998fe14ca84484967ca..67744ab56a2878becb5bf9a2252591f05adda4d0 100644 (file)
@@ -167,6 +167,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                // calc other res with max_res provided
                VECSUB(size, max, min);
 
+               printf("size: %f, %f, %f\n", size[0], size[1], size[2]);
+
                // prevent crash when initializing a plane as domain
                if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
                        return 0;
@@ -210,6 +212,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                        }
                }
 
+               printf("smd->domain->dx: %f\n", smd->domain->dx);
+
                // TODO: put in failsafe if res<=0 - dg
 
                // printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
@@ -595,11 +599,6 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd)
                smoke_turbulence_free(smd->domain->wt);
                smd->domain->wt = NULL;
        }
-
-       smd->domain->point_cache[1]->flag &= ~PTCACHE_SIMULATION_VALID;
-       smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
-       smd->domain->point_cache[1]->simframe= 0;
-       smd->domain->point_cache[1]->last_exact= 0;
 }
 
 void smokeModifier_reset(struct SmokeModifierData *smd)
@@ -617,17 +616,15 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
                                smoke_free(smd->domain->fluid);
                                smd->domain->fluid = NULL;
                        }
-                                       
-                       smd->domain->point_cache[0]->flag &= ~PTCACHE_SIMULATION_VALID;
+
                        smd->domain->point_cache[0]->flag |= PTCACHE_OUTDATED;
-                       smd->domain->point_cache[0]->simframe= 0;
-                       smd->domain->point_cache[0]->last_exact= 0;
+                       smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
 
                        smokeModifier_reset_turbulence(smd);
 
                        smd->time = -1;
 
-                       // printf("reset domain end\n");
+                       printf("reset domain end\n");
                }
                else if(smd->flow)
                {
@@ -841,7 +838,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
                                                        else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;                                                                                                                                               
                                                        // VECCOPY(pos, pa->state.co);                                                                  
                                                        // Mat4MulVecfl (ob->imat, pos);                                                                                                                                                
-                                                       // 1. get corresponding cell                                                                    
+                                                       // 1. get corresponding cell    
                                                        get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, pa->state.co, cell, 0);                                                                                                                                    
                                                        // check if cell is valid (in the domain boundary)                                                                      
                                                        for(i = 0; i < 3; i++)                                                                  
@@ -1102,214 +1099,103 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
        }
        else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
        {
+               SmokeDomainSettings *sds = smd->domain;
+               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 startframe, endframe, framenr, badloading = 0;
-               SmokeDomainSettings *sds = smd->domain;
-               float light[3]; 
 
                framenr = scene->r.cfra;
 
-               cache = sds->point_cache[0];
+               printf("time: %d\n", scene->r.cfra);
+
+               if(framenr == smd->time)
+                       return;
 
+               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);
 
-               /* handle continuous simulation with the play button */
-               if(BKE_ptcache_get_continue_physics()) 
-               {
-                       // TODO
-                       return;
-               }
-
                if(framenr < startframe)
-               {
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-                       cache->last_exact= 0;
-
-                       cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache_wt->simframe= 0;
-                       cache_wt->last_exact= 0;
-
-                       // we got back in time, reset smoke in this case (TODO: use cache later)
-                       // smd->time = scene->r.cfra;
-                       // smokeModifier_reset(smd);
-
                        return;
-               }
-               else if(framenr > endframe) 
-               {
-                       framenr = endframe;
 
-                       // we load last valid frame here 
-                       // and don't update the smd->time variable later
-                       badloading = 1;
-               }
+               if(framenr > endframe)
+                       return;
 
-               if(!(cache->flag & PTCACHE_SIMULATION_VALID))
+               if(!smd->domain->fluid)
                {
                        BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
-               }
-               if(sds->wt && !(cache_wt->flag & PTCACHE_SIMULATION_VALID))
-               {
                        BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
                }
 
-               if(smd->time == -1 && framenr!= startframe)
-                       return;
-
                if(!smokeModifier_init(smd, ob, scene, dm))
+               {
+                       printf("bad smokeModifier_init\n");
                        return;
-
-               if(!smd->domain->fluid)
-                               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);
+               printf("cache_result: %d\n", cache_result);
 
                if(cache_result == PTCACHE_READ_EXACT) 
                {
-                       SmokeDomainSettings *sds = smd->domain;
-
                        cache->flag |= PTCACHE_SIMULATION_VALID;
                        cache->simframe= framenr;
-                       sds->v3dnum = framenr;
-
-                       if(!badloading)
-                               smd->time = scene->r.cfra;
 
-                       // check for wt cache
                        if(sds->wt)
                        {
                                cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec);
-                               // printf("cache_result_wt: %d\n", cache_result_wt);
-
-                               // error handling
+                               
                                if(cache_result_wt == PTCACHE_READ_EXACT) 
                                {
                                        cache_wt->flag |= PTCACHE_SIMULATION_VALID;
                                        cache_wt->simframe= framenr;
                                }
-                               else if(cache_result_wt==PTCACHE_READ_OLD) 
-                               {
-                                       BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE);
-                                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
-                               }
-                               else if(ob->id.lib || (cache_wt->flag & PTCACHE_BAKED)) 
-                               {
-                                       // if baked and nothing in cache, do nothing 
-                                       cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
-                                       cache_wt->simframe= 0;
-                                       cache_wt->last_exact= 0;
-                               }
                        }
-
-                       // printf("PTCACHE_READ_EXACT\n");
                        return;
                }
-               else if(cache_result==PTCACHE_READ_OLD) 
-               {
-                       BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
-                       cache->flag |= PTCACHE_SIMULATION_VALID;
-
-                       BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE);
-                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
-               }
-               else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) 
-               {
-                       // if baked and nothing in cache, do nothing 
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-                       cache->last_exact= 0;
-
-                       cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache_wt->simframe= 0;
-                       cache_wt->last_exact= 0;
-               
-                       // printf("PTCACHE_BAKED\n");
-                       return;
-               }
-               /*
-               else if((cache_result==0) && ((startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID || (framenr == smd->time))))
-               {
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-                       cache->last_exact= 0;
-
-                       return;
-               }*/
-
-               // printf("framenr: %d, time: %f\n", framenr, smd->time);
 
-               /* do simulation */
-
-               // low res
-               cache->flag |= PTCACHE_SIMULATION_VALID;
-               cache->simframe= framenr;
-
-               if(sds->wt)
-               {
-                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
-                       cache_wt->simframe= framenr;
-               }
-                               
-               tstart();       
-
-               if(sds->flags & MOD_SMOKE_DISSOLVE)                     
-               {                               
-                       smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);                                                               
-               }
+               tstart();
 
                smoke_calc_domain(scene, ob, smd);
                
                // set new time
                smd->time = scene->r.cfra;
 
-               // frame 1 is start, don't simulate anything
-               if(smd->time == 1)
-               {
-                       // set new time
-                       smd->time = scene->r.cfra;
-
-                       BKE_ptcache_write_cache(&pid, framenr);
-                       if(sds->wt)
-                               BKE_ptcache_write_cache(&pid_wt, framenr);
-
-                       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);
+               /* do simulation */
 
-                       // printf("smd->time: %f\n", smd->time);
-                       return;
-               }
+               // low res
+               cache->flag |= PTCACHE_SIMULATION_VALID;
+               cache->simframe= framenr;
 
                // simulate the actual smoke (c++ code in intern/smoke)
-               smoke_step(sds->fluid, smd->time);
+               if(framenr!=startframe)
+                       smoke_step(sds->fluid, smd->time);
                BKE_ptcache_write_cache(&pid, framenr);
 
                if(sds->wt)
                {
+                       if(framenr!=startframe)
+                               smoke_turbulence_step(sds->wt, sds->fluid);
 
-                       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);
+                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
+                       cache_wt->simframe= framenr;
                        BKE_ptcache_write_cache(&pid_wt, framenr);
                }
 
                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);
-
+               
                tend();
-               // printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
+               printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
        }
 }