Smoke:
authorDaniel Genrich <daniel.genrich@gmx.net>
Sun, 2 Aug 2009 23:30:44 +0000 (23:30 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Sun, 2 Aug 2009 23:30:44 +0000 (23:30 +0000)
a) fixing domain boundaries
b) fixing flow gui (no more velocity there - taken from particles)
c) Outflow available (deletes smoke from scene)
d) deactivating other noise options for now
e) base for render/preview settings
f) fixing collisions to be working again

intern/smoke/intern/FLUID_3D.cpp
intern/smoke/intern/FLUID_3D_STATIC.cpp
release/ui/buttons_data_modifier.py
source/blender/blenkernel/intern/smoke.c
source/blender/makesdna/DNA_smoke_types.h
source/blender/makesrna/intern/rna_smoke.c

index 2822fca3607c31dc0cbaf0766fb8a2e6de8c8d80..344883866a806017fbfa63ead040e2e9df3c04d0 100644 (file)
@@ -120,29 +120,29 @@ FLUID_3D::FLUID_3D(int *res, int amplify, float *p0, float dt) :
 
        // set side obstacles
   int index;
-  for (int y = 0; y < _yRes; y++)
+  for (int y = 0; y < _yRes; y++) // z
     for (int x = 0; x < _xRes; x++)
     {
       // front slab
       index = x + y * _xRes;
-      if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1;
+      if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1;
 
       // back slab
       index += _totalCells - _slabSize;
-      if(DOMAIN_BC_BACK==1) _obstacles[index] = 1;
+      if(DOMAIN_BC_TOP==1) _obstacles[index] = 1;
     }
-  for (int z = 0; z < _zRes; z++)
+  for (int z = 0; z < _zRes; z++) // y
     for (int x = 0; x < _xRes; x++)
     {
       // bottom slab
       index = x + z * _slabSize;
-      if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1;
+      if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1;
 
       // top slab
       index += _slabSize - _xRes;
-      if(DOMAIN_BC_TOP==1) _obstacles[index] = 1;
+      if(DOMAIN_BC_BACK==1) _obstacles[index] = 1;
     }
-  for (int z = 0; z < _zRes; z++)
+  for (int z = 0; z < _zRes; z++) // x
     for (int y = 0; y < _yRes; y++)
     {
       // left slab
@@ -360,12 +360,12 @@ void FLUID_3D::project()
        if(DOMAIN_BC_LEFT == 0)  setNeumannX(_xVelocity, _res);
        else setZeroX(_xVelocity, _res);
 
-       if(DOMAIN_BC_TOP == 0)   setNeumannY(_yVelocity, _res);
-       else setZeroY(_yVelocity, _res);
-
-       if(DOMAIN_BC_FRONT == 0) setNeumannZ(_zVelocity, _res);
+       if(DOMAIN_BC_TOP == 0)   setNeumannZ(_zVelocity, _res);
        else setZeroZ(_zVelocity, _res);
 
+       if(DOMAIN_BC_FRONT == 0) setNeumannY(_yVelocity, _res);
+       else setZeroY(_yVelocity, _res);
+
        // calculate divergence
        index = _slabSize + _xRes + 1;
        for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
@@ -630,12 +630,12 @@ void FLUID_3D::advectMacCormack()
        if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
        else setZeroX(_xVelocity, res);
 
-       if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
-       else setZeroY(_yVelocity, res);
-
-       if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
+       if(DOMAIN_BC_TOP == 0) copyBorderZ(_zVelocity, res);
        else setZeroZ(_zVelocity, res);
 
+       if(DOMAIN_BC_FRONT == 0) copyBorderY(_yVelocity, res);
+       else setZeroY(_yVelocity, res);
+
        SWAP_POINTERS(_xVelocity, _xVelocityOld);
        SWAP_POINTERS(_yVelocity, _yVelocityOld);
        SWAP_POINTERS(_zVelocity, _zVelocityOld);
@@ -658,12 +658,12 @@ void FLUID_3D::advectMacCormack()
        if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
        else setZeroX(_xVelocity, res);
 
-       if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
-       else setZeroY(_yVelocity, res);
-
-       if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
+       if(DOMAIN_BC_TOP == 0) copyBorderZ(_zVelocity, res);
        else setZeroZ(_zVelocity, res);
 
+       if(DOMAIN_BC_FRONT == 0) copyBorderY(_yVelocity, res);
+       else setZeroY(_yVelocity, res);
+
        setZeroBorder(_density, res);
        setZeroBorder(_heat, res);
 
index a72009b9abf7d0e5b1944a5820c4fdb3a0b2ec84..f2bbcf3307546e188fa506e6a146e92522cba3e5 100644 (file)
@@ -104,26 +104,14 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res)
        for (int z = 0; z < res[2]; z++)
                for (int x = 0; x < res[0]; x++)
                {
-                       // bottom slab
+                       // front slab
                        index = x + z * slabSize;
                        field[index] = field[index + 2 * res[0]];
 
-                       // top slab
+                       // back slab
                        index += slabSize - res[0];
                        field[index] = field[index - 2 * res[0]];
                }
-
-       // fix, force top slab to only allow outwards flux
-       for (int z = 0; z < res[2]; z++)
-               for (int x = 0; x < res[0]; x++)
-               {
-                       // top slab
-                       index = x + z * slabSize;
-                       index += slabSize - res[0];
-                       if(field[index]<0.) field[index] = 0.;
-                       index -= res[0];
-                       if(field[index]<0.) field[index] = 0.;
-               }
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -137,14 +125,26 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res)
        for (int y = 0; y < res[1]; y++)
                for (int x = 0; x < res[0]; x++)
                {
-                       // front slab
+                       // bottom slab
                        index = x + y * res[0];
                        field[index] = field[index + 2 * slabSize];
 
-                       // back slab
+                       // top slab
                        index += totalCells - slabSize;
                        field[index] = field[index - 2 * slabSize];
                }
+
+       // fix, force top slab to only allow outwards flux
+       for (int y = 0; y < res[1]; y++)
+               for (int x = 0; x < res[0]; x++)
+               {
+                       // top slab
+                       index = x + y * res[0];
+                       index += totalCells - slabSize;
+                       if(field[index]<0.) field[index] = 0.;
+                       index -= slabSize;
+                       if(field[index]<0.) field[index] = 0.;
+               }
 }
 
 //////////////////////////////////////////////////////////////////////
index ae824e73720c802f5feb0f1b5f1a5d6229064c68..bd39ff1e70ef730158f08c3550286e9736a686c0 100644 (file)
@@ -376,10 +376,9 @@ class DATA_PT_modifiers(DataButtonsPanel):
                        layout.itemR(md.domain_settings, "coll_group")
                elif md.smoke_type == 'TYPE_FLOW':
                        layout.itemS()
+                       layout.itemR(md.flow_settings, "outflow")
                        layout.itemR(md.flow_settings, "density")
                        layout.itemR(md.flow_settings, "temperature")
-                       layout.itemL(text="Velocity")
-                       layout.row().itemR(md.flow_settings, "velocity", text="")
                        layout.item_pointerR(md.flow_settings, "psys", ob, "particle_systems")
                elif md.smoke_type == 'TYPE_COLL':
                        layout.itemS()
index 3eec7ec24238923d7e6c15b7a1ad55fa0cc3acdc..c619c3e25ab0a0a77df39d3b25113bc624e30123 100644 (file)
@@ -199,7 +199,9 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                        }
                }
 
-               printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
+               // 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]);
 
                // dt max is 0.1
                smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->amplify, smd->domain->p0, smd->domain->p1, 2.5 / FPS);
@@ -222,10 +224,14 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
 
                return 1;
        }
-       else if((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll)
+       else if((smd->type & MOD_SMOKE_TYPE_COLL))
        {
                smd->time = scene->r.cfra;
 
+               // todo: delete this when loading colls work -dg
+               if(!smd->coll)
+                       smokeModifier_createType(smd);
+
                if(!smd->coll->points)
                {
                        // init collision points
@@ -600,7 +606,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
                        smd->domain->eff_group = NULL;
                        smd->domain->fluid_group = NULL;
                        smd->domain->coll_group = NULL;
-                       smd->domain->maxres = 48;
+                       smd->domain->maxres = 32;
                        smd->domain->amplify = 2;
                        smd->domain->omega = 0.5;
                        smd->domain->alpha = -0.001;
@@ -652,7 +658,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
 void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big);
 
 void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
-{
+{      
        if(scene->r.cfra >= smd->time)
                smokeModifier_init(smd, ob, scene, dm);
 
@@ -793,24 +799,49 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
                                                                        // 2. set cell values (heat, density and velocity)
                                                                        index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
                                                                        
-                                                                       heat[index] = sfs->temp;
-                                                                       density[index] = sfs->density;
-                                                                       velocity_x[index] = pa->state.vel[0];
-                                                                       velocity_y[index] = pa->state.vel[1];
-                                                                       velocity_z[index] = pa->state.vel[2];
-
-                                                                       // we need different handling for the high-res feature
-                                                                       if(bigdensity)
+                                                                       if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) // this is inflow
                                                                        {
-                                                                               // init all surrounding cells according to amplification, too
-                                                                               int i, j, k;
-                                                                               for(i = 0; i < smd->domain->amplify; i++)
-                                                                                       for(j = 0; j < smd->domain->amplify; j++)
-                                                                                               for(k = 0; k < smd->domain->amplify; k++)
-                                                                                               {
-                                                                                                       index = smoke_get_index(smd->domain->amplify * cell[0] + i, bigres[0], smd->domain->amplify * cell[1] + j, bigres[1], smd->domain->amplify * cell[2] + k);
-                                                                                                       bigdensity[index] = sfs->density;
-                                                                                               }
+                                                                               heat[index] = sfs->temp;
+                                                                               density[index] = sfs->density;
+                                                                               velocity_x[index] = pa->state.vel[0];
+                                                                               velocity_y[index] = pa->state.vel[1];
+                                                                               velocity_z[index] = pa->state.vel[2];
+
+                                                                               // we need different handling for the high-res feature
+                                                                               if(bigdensity)
+                                                                               {
+                                                                                       // init all surrounding cells according to amplification, too
+                                                                                       int i, j, k;
+                                                                                       for(i = 0; i < smd->domain->amplify; i++)
+                                                                                               for(j = 0; j < smd->domain->amplify; j++)
+                                                                                                       for(k = 0; k < smd->domain->amplify; k++)
+                                                                                                       {
+                                                                                                               index = smoke_get_index(smd->domain->amplify * cell[0] + i, bigres[0], smd->domain->amplify * cell[1] + j, bigres[1], smd->domain->amplify * cell[2] + k);
+                                                                                                               bigdensity[index] = sfs->density;
+                                                                                                       }
+                                                                               }
+                                                                       }
+                                                                       else // outflow
+                                                                       {
+                                                                               heat[index] = 0.f;
+                                                                               density[index] = 0.f;
+                                                                               velocity_x[index] = 0.f;
+                                                                               velocity_y[index] = 0.f;
+                                                                               velocity_z[index] = 0.f;
+
+                                                                               // we need different handling for the high-res feature
+                                                                               if(bigdensity)
+                                                                               {
+                                                                                       // init all surrounding cells according to amplification, too
+                                                                                       int i, j, k;
+                                                                                       for(i = 0; i < smd->domain->amplify; i++)
+                                                                                               for(j = 0; j < smd->domain->amplify; j++)
+                                                                                                       for(k = 0; k < smd->domain->amplify; k++)
+                                                                                                       {
+                                                                                                               index = smoke_get_index(smd->domain->amplify * cell[0] + i, bigres[0], smd->domain->amplify * cell[1] + j, bigres[1], smd->domain->amplify * cell[2] + k);
+                                                                                                               bigdensity[index] = 0.f;
+                                                                                                       }
+                                                                               }
                                                                        }
                                                                }
                                                        }       
@@ -886,7 +917,6 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
                                                        // we got nice collision object
                                                        SmokeCollSettings *scs = smd2->coll;
                                                        int cell[3];
-                                                       int valid = 1;
                                                        size_t index = 0;
                                                        size_t i, j;
                                                        unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
@@ -899,10 +929,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
                                                                // check if cell is valid (in the domain boundary)
                                                                for(j = 0; j < 3; j++)
                                                                        if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
-                                                                               valid = 0;
-                                                               
-                                                               if(!valid)
-                                                                       continue;
+                                                                               continue;
                                                                
                                                                // 2. set cell values (heat, density and velocity)
                                                                index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
index e0871e7038a92b694630e728f4f32e17999744d2..0c93b5eb56e0f1571e4eca15e666c305c59940c0 100644 (file)
@@ -75,17 +75,24 @@ typedef struct SmokeDomainSettings {
        int max_textures;
        short noise; /* noise type: wave, curl, anisotropic */
        short pad2;
-       int pad3;
-       int pad4;
+       int prev_res[3];
+       int prev_maxres;
+       int render_res[3];
+       int render_maxres;
 } SmokeDomainSettings;
 
+
 /* inflow / outflow */
+
+/* type */
+#define MOD_SMOKE_FLOW_TYPE_OUTFLOW (1<<1)
+
 typedef struct SmokeFlowSettings {
        struct SmokeModifierData *smd; /* for fast RNA access */
        struct ParticleSystem *psys;
        float density;
        float temp; /* delta temperature (temp - ambient temp) */
-       float velocity[3];
+       float velocity[3]; /* UNUSED, velocity taken from particles */
        float vgrp_heat_scale[2]; /* min and max scaling for vgroup_heat */
        short vgroup_flow; /* where inflow/outflow happens - red=1=action */
        short vgroup_density;
index a4e2c39ecd8cae89900a4b143ab67d3eaced85b0..cedbc992dde8d0229106943d2446eb5fea857bba 100644 (file)
@@ -118,8 +118,8 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
 
        static EnumPropertyItem prop_noise_type_items[] = {
                                {MOD_SMOKE_NOISEWAVE, "NOISEWAVE", 0, "Wavelet", ""},
-                               {MOD_SMOKE_NOISEFFT, "NOISEFFT", 0, "FFT", ""},
-                               {MOD_SMOKE_NOISECURL, "NOISECURL", 0, "Curl", ""},
+                       /*  {MOD_SMOKE_NOISEFFT, "NOISEFFT", 0, "FFT", ""}, */
+                       /*      {MOD_SMOKE_NOISECURL, "NOISECURL", 0, "Curl", ""}, */
                                {0, NULL, 0, NULL, NULL}};
 
        srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL);
@@ -129,8 +129,8 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "maxres", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "maxres");
-       RNA_def_property_range(prop, 32, 512);
-       RNA_def_property_ui_range(prop, 32, 512, 2, 0);
+       RNA_def_property_range(prop, 24, 512);
+       RNA_def_property_ui_range(prop, 24, 512, 2, 0);
        RNA_def_property_ui_text(prop, "Max Res", "Maximal resolution used in the fluid domain.");
        RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
 
@@ -233,13 +233,10 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Particle Systems", "Particle systems emitted from the object.");
        RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset_dependancy");
 
-       prop= RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VECTOR);
-       RNA_def_property_float_sdna(prop, NULL, "velocity");
-       RNA_def_property_range(prop, -10, 10);
-       RNA_def_property_ui_range(prop, -10, 10, 1, 1);
-       RNA_def_property_ui_text(prop, "Velocity", "");
+       prop= RNA_def_property(srna, "outflow", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "type", MOD_SMOKE_FLOW_TYPE_OUTFLOW);
+       RNA_def_property_ui_text(prop, "Outflow", "Deletes smoke from simulation");
        RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
-
 }
 
 static void rna_def_smoke_coll_settings(BlenderRNA *brna)