diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index 2822fca3607..344883866a8 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -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); diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index a72009b9abf..f2bbcf33075 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -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.; + } } ////////////////////////////////////////////////////////////////////// diff --git a/release/ui/buttons_data_modifier.py b/release/ui/buttons_data_modifier.py index ae824e73720..bd39ff1e70e 100644 --- a/release/ui/buttons_data_modifier.py +++ b/release/ui/buttons_data_modifier.py @@ -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() diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 3eec7ec2423..c619c3e25ab 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -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]); diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index e0871e7038a..0c93b5eb56e 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index a4e2c39ecd8..cedbc992dde 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -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)