Smoke Patch + additions: a) Applying patch #22765 by Miika Hämäläinen (domain border...
authorDaniel Genrich <daniel.genrich@gmx.net>
Tue, 27 Jul 2010 14:53:20 +0000 (14:53 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Tue, 27 Jul 2010 14:53:20 +0000 (14:53 +0000)
12 files changed:
intern/smoke/extern/smoke_API.h
intern/smoke/intern/FLUID_3D.cpp
intern/smoke/intern/FLUID_3D.h
intern/smoke/intern/smoke_API.cpp
release/scripts/ui/properties_physics_smoke.py
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/smoke.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_view3d/drawvolume.c
source/blender/makesdna/DNA_smoke_types.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_smoke.c

index 3e296fd7c9031a1cb8c6a90fbc5af1f8b3d7d050..d1012eef76ebbe6f3ed5ac45c1d35d14f2718366 100644 (file)
@@ -38,10 +38,10 @@ struct FLUID_3D;
 void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles);
 
 // low res
-struct FLUID_3D *smoke_init(int *res, float *p0, float dt);
+struct FLUID_3D *smoke_init(int *res, float *p0);
 void smoke_free(struct FLUID_3D *fluid);
 
-void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta);
+void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli);
 void smoke_step(struct FLUID_3D *fluid, size_t framenr);
 
 float *smoke_get_density(struct FLUID_3D *fluid);
index 4ac960b5ef07ead3f23ce2cb3d7f48eb777692b9..05fbb918d248d8fcfbd437dcd66571b256ba7a25 100644 (file)
 #include <omp.h>
 #endif // PARALLEL 
 
-// boundary conditions of the fluid domain
-#define DOMAIN_BC_FRONT  0 // z
-#define DOMAIN_BC_TOP    1 // y
-#define DOMAIN_BC_LEFT   1 // x
-#define DOMAIN_BC_BACK   DOMAIN_BC_FRONT
-#define DOMAIN_BC_BOTTOM DOMAIN_BC_TOP
-#define DOMAIN_BC_RIGHT  DOMAIN_BC_LEFT
-
 //////////////////////////////////////////////////////////////////////
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 
-FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
-       _xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f), _dt(dt)
+FLUID_3D::FLUID_3D(int *res, float *p0) :
+       _xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f)
 {
        // set simulation consts
-       // _dt = dt; // 0.10
+       _dt = DT_DEFAULT;       // just in case. set in step from a RNA factor
        
        // start point of array
        _p0[0] = p0[0];
@@ -61,7 +53,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
        _iterations = 100;
        _tempAmb = 0; 
        _heatDiffusion = 1e-3;
-       _vorticityEps = 2.0;
        _totalTime = 0.0f;
        _totalSteps = 0;
        _res = Vec3Int(_xRes,_yRes,_zRes);
@@ -77,9 +68,9 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
        
        // scale the constants according to the refinement of the grid
        _dx = 1.0f / (float)_maxRes;
-       float scaling = 64.0f / _maxRes;
-       scaling = (scaling < 1.0f) ? 1.0f : scaling;
-       _vorticityEps /= scaling;
+       _constantScaling = 64.0f / _maxRes;
+       _constantScaling = (_constantScaling < 1.0f) ? 1.0f : _constantScaling;
+       _vorticityEps = 2.0f / _constantScaling; // Just in case set a default value
 
        // allocate arrays
        _totalCells   = _xRes * _yRes * _zRes;
@@ -126,30 +117,42 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
                _obstacles[x]    = false;
        }
 
+       // boundary conditions of the fluid domain
+       // set default values -> vertically non-colliding
+       _domainBcFront = true;
+       _domainBcTop = false;
+       _domainBcLeft = true;
+       _domainBcBack = _domainBcFront;
+       _domainBcBottom = _domainBcTop;
+       _domainBcRight  = _domainBcLeft;
+
+       _colloPrev = 1; // default value
+
+
        // set side obstacles
        int index;
        for (int y = 0; y < _yRes; y++)
        for (int x = 0; x < _xRes; x++)
        {
-               // front slab
+               // bottom slab
                index = x + y * _xRes;
-               if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1;
+               if(_domainBcBottom==1) _obstacles[index] = 1;
 
-               // back slab
+               // top slab
                index += _totalCells - _slabSize;
-               if(DOMAIN_BC_BACK==1) _obstacles[index] = 1;
+               if(_domainBcTop==1) _obstacles[index] = 1;
        }
 
        for (int z = 0; z < _zRes; z++)
        for (int x = 0; x < _xRes; x++)
        {
-               // bottom slab
+               // front slab
                index = x + z * _slabSize;
-               if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1;
+               if(_domainBcFront==1) _obstacles[index] = 1;
 
-               // top slab
+               // back slab
                index += _slabSize - _xRes;
-               if(DOMAIN_BC_TOP==1) _obstacles[index] = 1;
+               if(_domainBcBack==1) _obstacles[index] = 1;
        }
 
        for (int z = 0; z < _zRes; z++)
@@ -157,12 +160,13 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
        {
                // left slab
                index = y * _xRes + z * _slabSize;
-               if(DOMAIN_BC_LEFT==1) _obstacles[index] = 1;
+               if(_domainBcLeft==1) _obstacles[index] = 1;
 
                // right slab
                index += _xRes - 1;
-               if(DOMAIN_BC_RIGHT==1) _obstacles[index] = 1;
+               if(_domainBcRight==1) _obstacles[index] = 1;
        }
+
 }
 
 FLUID_3D::~FLUID_3D()
@@ -193,17 +197,32 @@ FLUID_3D::~FLUID_3D()
 }
 
 // init direct access functions from blender
-void FLUID_3D::initBlenderRNA(float *alpha, float *beta)
+void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision)
 {
        _alpha = alpha;
        _beta = beta;
+       _dtFactor = dt_factor;
+       _vorticityRNA = vorticity;
+       _borderColli = borderCollision;
 }
 
 //////////////////////////////////////////////////////////////////////
 // step simulation once
 //////////////////////////////////////////////////////////////////////
-void FLUID_3D::step()
+void FLUID_3D::step(float dt)
 {
+       // If border rules have been changed
+       if (_colloPrev != *_borderColli) {
+               setBorderCollisions();
+       }
+
+
+       // set delta time by dt_factor
+       _dt = (*_dtFactor) * dt;
+       // set vorticity from RNA value
+       _vorticityEps = (*_vorticityRNA)/_constantScaling;
+
+
 #if PARALLEL==1
        int threadval = 1;
        threadval = omp_get_max_threads();
@@ -246,6 +265,13 @@ void FLUID_3D::step()
        #pragma omp single
        {
 #endif
+       /*
+       * addForce() changed Temp values to preserve thread safety
+       * (previous functions in per thread loop still needed
+       *  original velocity data)
+       *
+       * So swap temp values to velocity
+       */
        SWAP_POINTERS(_xVelocity, _xVelocityTemp);
        SWAP_POINTERS(_yVelocity, _yVelocityTemp);
        SWAP_POINTERS(_zVelocity, _zVelocityTemp);
@@ -276,6 +302,10 @@ void FLUID_3D::step()
        #pragma omp single
        {
 #endif
+       /*
+       * For thread safety use "Old" to read
+       * "current" values but still allow changing values.
+       */
        SWAP_POINTERS(_xVelocity, _xVelocityOld);
        SWAP_POINTERS(_yVelocity, _yVelocityOld);
        SWAP_POINTERS(_zVelocity, _zVelocityOld);
@@ -334,6 +364,10 @@ void FLUID_3D::step()
        }
 #endif
 
+       /*
+       * swap final velocity back to Velocity array
+       * from temp xForce storage
+       */
        SWAP_POINTERS(_xVelocity, _xForce);
        SWAP_POINTERS(_yVelocity, _yForce);
        SWAP_POINTERS(_zVelocity, _zForce);
@@ -351,6 +385,88 @@ void FLUID_3D::step()
 
 }
 
+
+// Set border collision model from RNA setting
+
+void FLUID_3D::setBorderCollisions() {
+
+
+       _colloPrev = *_borderColli;             // saving the current value
+
+       // boundary conditions of the fluid domain
+       if (_colloPrev == 0)
+       {
+               // No collisions
+               _domainBcFront = false;
+               _domainBcTop = false;
+               _domainBcLeft = false;
+       }
+       else if (_colloPrev == 2)
+       {
+               // Collide with all sides
+               _domainBcFront = true;
+               _domainBcTop = true;
+               _domainBcLeft = true;
+       }
+       else
+       {
+               // Default values: Collide with "walls", but not top and bottom
+               _domainBcFront = true;
+               _domainBcTop = false;
+               _domainBcLeft = true;
+       }
+
+       _domainBcBack = _domainBcFront;
+       _domainBcBottom = _domainBcTop;
+       _domainBcRight  = _domainBcLeft;
+
+
+
+       // set side obstacles
+       int index;
+       for (int y = 0; y < _yRes; y++)
+       for (int x = 0; x < _xRes; x++)
+       {
+               // front slab
+               index = x + y * _xRes;
+               if(_domainBcBottom==1) _obstacles[index] = 1;
+               else _obstacles[index] = 0;
+
+               // back slab
+               index += _totalCells - _slabSize;
+               if(_domainBcTop==1) _obstacles[index] = 1;
+               else _obstacles[index] = 0;
+       }
+
+       for (int z = 0; z < _zRes; z++)
+       for (int x = 0; x < _xRes; x++)
+       {
+               // bottom slab
+               index = x + z * _slabSize;
+               if(_domainBcFront==1) _obstacles[index] = 1;
+               else _obstacles[index] = 0;
+
+               // top slab
+               index += _slabSize - _xRes;
+               if(_domainBcBack==1) _obstacles[index] = 1;
+               else _obstacles[index] = 0;
+       }
+
+       for (int z = 0; z < _zRes; z++)
+       for (int y = 0; y < _yRes; y++)
+       {
+               // left slab
+               index = y * _xRes + z * _slabSize;
+               if(_domainBcLeft==1) _obstacles[index] = 1;
+               else _obstacles[index] = 0;
+
+               // right slab
+               index += _xRes - 1;
+               if(_domainBcRight==1) _obstacles[index] = 1;
+               else _obstacles[index] = 0;
+       }
+}
+
 //////////////////////////////////////////////////////////////////////
 // helper function to dampen co-located grid artifacts of given arrays in intervals
 // (only needed for velocity, strength (w) depends on testcase...
@@ -428,6 +544,10 @@ void FLUID_3D::artificialDampingExactSL(int pos) {
                        for (y = 1; y < _res[1]-1; y++)
                                for (x = 1+(y+z)%2; x < _res[0]-1; x+=2) {
                                        index = x + y*_res[0] + posslab;
+                                       /*
+                                       * Uses xForce as temporary storage to allow other threads to read
+                                       * old values from xVelocityTemp
+                                       */
                                        _xForce[index] = (1-w)*_xVelocityTemp[index] + 1./6. * w*(
                                                        _xVelocityTemp[index+1] + _xVelocityTemp[index-1] +
                                                        _xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] +
@@ -450,6 +570,11 @@ void FLUID_3D::artificialDampingExactSL(int pos) {
                        for (y = 1; y < _res[1]-1; y++)
                                for (x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) {
                                        index = x + y*_res[0] + posslab;
+
+                                       /*
+                                       * Uses xForce as temporary storage to allow other threads to read
+                                       * old values from xVelocityTemp
+                                       */
                                        _xForce[index] = (1-w)*_xVelocityTemp[index] + 1./6. * w*(
                                                        _xVelocityTemp[index+1] + _xVelocityTemp[index-1] +
                                                        _xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] +
@@ -661,13 +786,13 @@ void FLUID_3D::project()
        setObstacleBoundaries(_pressure, 0, _zRes);
        
        // copy out the boundaries
-       if(DOMAIN_BC_LEFT == 0)  setNeumannX(_xVelocity, _res, 0, _zRes);
+       if(_domainBcLeft == 0)  setNeumannX(_xVelocity, _res, 0, _zRes);
        else setZeroX(_xVelocity, _res, 0, _zRes); 
 
-       if(DOMAIN_BC_TOP == 0)   setNeumannY(_yVelocity, _res, 0, _zRes);
+       if(_domainBcFront == 0)   setNeumannY(_yVelocity, _res, 0, _zRes);
        else setZeroY(_yVelocity, _res, 0, _zRes); 
 
-       if(DOMAIN_BC_FRONT == 0) setNeumannZ(_zVelocity, _res, 0, _zRes);
+       if(_domainBcTop == 0) setNeumannZ(_zVelocity, _res, 0, _zRes);
        else setZeroZ(_zVelocity, _res, 0, _zRes);
 
        // calculate divergence
@@ -1060,13 +1185,13 @@ void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd)
 {
        Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
 
-       if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocityOld, res, zBegin, zEnd);
+       if(_domainBcLeft == 0) copyBorderX(_xVelocityOld, res, zBegin, zEnd);
        else setZeroX(_xVelocityOld, res, zBegin, zEnd);
 
-       if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocityOld, res, zBegin, zEnd);
+       if(_domainBcFront == 0) copyBorderY(_yVelocityOld, res, zBegin, zEnd);
        else setZeroY(_yVelocityOld, res, zBegin, zEnd); 
 
-       if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocityOld, res, zBegin, zEnd);
+       if(_domainBcTop == 0) copyBorderZ(_zVelocityOld, res, zBegin, zEnd);
        else setZeroZ(_zVelocityOld, res, zBegin, zEnd);
 }
 
@@ -1114,13 +1239,13 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd)
        advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocityTemp, _yVelocity, t1, res, _obstacles, zBegin, zEnd);
        advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocityTemp, _zVelocity, t1, res, _obstacles, zBegin, zEnd);
 
-       if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocityTemp, res, zBegin, zEnd);
+       if(_domainBcLeft == 0) copyBorderX(_xVelocityTemp, res, zBegin, zEnd);
        else setZeroX(_xVelocityTemp, res, zBegin, zEnd);                               
 
-       if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocityTemp, res, zBegin, zEnd);
+       if(_domainBcFront == 0) copyBorderY(_yVelocityTemp, res, zBegin, zEnd);
        else setZeroY(_yVelocityTemp, res, zBegin, zEnd); 
 
-       if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd);
+       if(_domainBcTop == 0) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd);
        else setZeroZ(_zVelocityTemp, res, zBegin, zEnd);
 
        setZeroBorder(_density, res, zBegin, zEnd);
index 6ca50b2c03207c710065af3305911aabb2ae210c..c244180ee57e783f9f50456d7a0aeea10b342a32 100644 (file)
@@ -36,6 +36,9 @@
 // #include "WTURBULENCE.h"
 #include "VEC3.h"
 
+// timestep default value for nice appearance
+#define DT_DEFAULT 0.1f;
+
 using namespace std;
 using namespace BasicVector;
 class WTURBULENCE;
@@ -43,11 +46,11 @@ class WTURBULENCE;
 class FLUID_3D  
 {
        public:
-               FLUID_3D(int *res, /* int amplify, */ float *p0, float dt);
+               FLUID_3D(int *res, /* int amplify, */ float *p0);
                FLUID_3D() {};
                virtual ~FLUID_3D();
 
-               void initBlenderRNA(float *alpha, float *beta);
+               void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli);
                
                // create & allocate vector noise advection 
                void initVectorNoise(int amplify);
@@ -55,7 +58,7 @@ class FLUID_3D
                void addSmokeColumn();
                static void addSmokeTestCase(float* field, Vec3Int res);
 
-               void step();
+               void step(float dt);
                void addObstacle(OBSTACLE* obstacle);
 
                const float* xVelocity() { return _xVelocity; }; 
@@ -111,11 +114,25 @@ class FLUID_3D
 
                // simulation constants
                float _dt;
+               float *_dtFactor;
                float _vorticityEps;
                float _heatDiffusion;
+               float *_vorticityRNA;   // RNA-pointer.
                float *_alpha; // for the buoyancy density term <-- as pointer to get blender RNA in here
                float *_beta; // was _buoyancy <-- as pointer to get blender RNA in here
                float _tempAmb; /* ambient temperature */
+               float _constantScaling;
+
+               bool _domainBcFront;  // z
+               bool _domainBcTop;    // y
+               bool _domainBcLeft;   // x
+               bool _domainBcBack;   // DOMAIN_BC_FRONT
+               bool _domainBcBottom; // DOMAIN_BC_TOP
+               bool _domainBcRight;  // DOMAIN_BC_LEFT
+               int *_borderColli; // border collision rules <-- as pointer to get blender RNA in here
+               int _colloPrev;         // To track whether value has been changed (to not
+                                                       // have to recalibrate borders if nothing has changed
+               void setBorderCollisions();
 
                // WTURBULENCE object, if active
                // WTURBULENCE* _wTurbulence;
index 427f4d53171cc463f3890452d96bd1ff4e370359..23c12c1701467c672c3d7795a469ec5c05e59d3f 100644 (file)
 #include <math.h>
 
 // y in smoke is z in blender
-extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dt)
+extern "C" FLUID_3D *smoke_init(int *res, float *p0)
 {
        // smoke lib uses y as top-bottom/vertical axis where blender uses z
-       FLUID_3D *fluid = new FLUID_3D(res, p0, dt);
+       FLUID_3D *fluid = new FLUID_3D(res, p0);
 
        // printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]);
 
@@ -77,7 +77,36 @@ extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z
 
 extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr)
 {
-       fluid->step();
+       /* stability values copied from wturbulence.cpp */
+       const int maxSubSteps = 25;
+       const float maxVel = 0.5f; /* TODO: maybe 0.5 is still too high, please confirm! -dg */
+
+       const float dt = DT_DEFAULT;
+       float maxVelMag = 0.0f;
+       int totalSubsteps;
+       int substep = 0;
+       float dtSubdiv;
+
+       /* get max velocity and lower the dt value if it is too high */
+       size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
+
+       for(size_t i = 0; i < size; i++)
+       {
+               float vtemp = (fluid->_xVelocity[i]*fluid->_xVelocity[i]+fluid->_yVelocity[i]*fluid->_yVelocity[i]+fluid->_zVelocity[i]*fluid->_zVelocity[i]);
+               if(vtemp > maxVelMag)
+                       maxVelMag = vtemp;
+       }
+
+       maxVelMag = sqrt(maxVelMag) * dt * (*(fluid->_dtFactor));
+       totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */
+       totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
+       totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
+       dtSubdiv = (float)dt / (float)totalSubsteps;
+
+       // printf("totalSubsteps: %d, maxVelMag: %f, dt: %f\n", totalSubsteps, maxVelMag, dt);
+
+       for(substep = 0; substep < totalSubsteps; substep++)
+               fluid->step(dtSubdiv);
 }
 
 extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
@@ -85,9 +114,9 @@ extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
        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)
+extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli)
 {
-       fluid->initBlenderRNA(alpha, beta);
+       fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli);
 }
 
 extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
index c5357c515deae58a07275b93db6f2fad4bc8ac95..ffc9caec9794186d52ae0684aa814e91bda824ae 100644 (file)
@@ -78,14 +78,17 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel):
                 col = split.column()
                 col.label(text="Resolution:")
                 col.prop(domain, "maxres", text="Divisions")
-                col.label(text="Particle:")
-                col.prop(domain, "initial_velocity", text="Initial Velocity")
+                col.label(text="Time:")
+                col.prop(domain, "time_scale", text="Scale")
+                col.label(text="Border Collisions:")
+                col.prop(domain, "smoke_domain_colli", text="")
 
                 if wide_ui:
                     col = split.column()
                 col.label(text="Behavior:")
                 col.prop(domain, "alpha")
                 col.prop(domain, "beta")
+                col.prop(domain, "vorticity")
                 col.prop(domain, "dissolve_smoke", text="Dissolve")
                 sub = col.column()
                 sub.active = domain.dissolve_smoke
@@ -93,24 +96,31 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel):
                 sub.prop(domain, "dissolve_smoke_log", text="Slow")
 
             elif md.smoke_type == 'FLOW':
+    
                 flow = md.flow_settings
 
                 split = layout.split()
 
                 col = split.column()
                 col.prop(flow, "outflow")
-                col.label(text="Particle System:")
+                col.label(text="Particle:")
                 col.prop_object(flow, "psys", ob, "particle_systems", text="")
 
-                if md.flow_settings.outflow:
-                    if wide_ui:
-                        col = split.column()
-                else:
-                    if wide_ui:
-                        col = split.column()
-                    col.label(text="Behavior:")
-                    col.prop(flow, "temperature")
-                    col.prop(flow, "density")
+                sub = col.column()
+                sub.active = not md.flow_settings.outflow
+
+                sub.prop(flow, "initial_velocity", text="Initial Velocity")
+                sub = sub.column()
+                sub.active = flow.initial_velocity
+                sub.prop(flow, "velocity_multiplier", text="Multiplier")
+
+                if wide_ui:
+                    sub = split.column()
+                sub.active = not md.flow_settings.outflow
+                sub.label(text="Behavior:")
+                sub.prop(flow, "temperature")
+                sub.prop(flow, "density")
+                sub.prop(flow, "absolute")
 
             #elif md.smoke_type == 'COLLISION':
             #  layout.separator()
@@ -191,6 +201,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel):
         col = split.column()
         col.label(text="Resolution:")
         col.prop(md, "amplify", text="Divisions")
+        col.prop(md, "smoothemitter")
         col.prop(md, "viewhighres")
 
         if wide_ui:
index 4e299accffcec26374c05e402b44c1961e4613f6..189cd61d5a8c7901a93ae639ce4b4be91b7b5b6b 100644 (file)
@@ -45,7 +45,7 @@ struct Scene;
 struct Main;
 
 #define BLENDER_VERSION                        253
-#define BLENDER_SUBVERSION             0
+#define BLENDER_SUBVERSION             1
 
 #define BLENDER_MINVERSION             250
 #define BLENDER_MINSUBVERSION  0
index 7424026354a0cc10da034b7e7470efeff648b5c9..193512b11dc601e4d2de3f6c4e88b02e81ab03c3 100644 (file)
@@ -220,7 +220,7 @@ 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]);
                // dt max is 0.1
-               smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, 0.1);
+               smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0);
                smd->time = scene->r.cfra;
 
                if(smd->domain->flags & MOD_SMOKE_HIGHRES)
@@ -237,7 +237,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                if(!smd->domain->shadow)
                        smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow");
 
-               smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta));
+               smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta), &(smd->domain->time_scale), &(smd->domain->vorticity), &(smd->domain->border_collisions));
 
                if(smd->domain->wt)     
                {
@@ -713,12 +713,16 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
                        smd->domain->omega = 1.0;                       
                        smd->domain->alpha = -0.001;
                        smd->domain->beta = 0.1;
-                       smd->domain->flags = MOD_SMOKE_DISSOLVE_LOG;
+                       smd->domain->time_scale = 1.0;
+                       smd->domain->vorticity = 2.0;
+                       smd->domain->border_collisions = 1;             // vertically non-colliding
+                       smd->domain->flags = MOD_SMOKE_DISSOLVE_LOG | MOD_SMOKE_HIGH_SMOOTH;
                        smd->domain->strength = 2.0;
                        smd->domain->noise = MOD_SMOKE_NOISEWAVE;
                        smd->domain->diss_speed = 5;
-                       // init view3d buffer
-                       smd->domain->viewsettings = 0;
+                       // init 3dview buffer
+
+                       smd->domain->viewsettings = MOD_SMOKE_VIEW_SHOWBIG;
                        smd->domain->effector_weights = BKE_add_effector_weights(NULL);
                }
                else if(smd->type & MOD_SMOKE_TYPE_FLOW)
@@ -733,6 +737,8 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
                        /* set some standard values */
                        smd->flow->density = 1.0;
                        smd->flow->temp = 1.0;
+                       smd->flow->flags = MOD_SMOKE_FLOW_ABSOLUTE;
+                       smd->flow->vel_multi = 1.0;
 
                        smd->flow->psys = NULL;
 
@@ -862,7 +868,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
                                        {
                                                ParticleSystem *psys = sfs->psys;
                                                ParticleSettings *part=psys->part;
-                                               ParticleData *pa = NULL;                                                                
+                                               ParticleData *pa = NULL;                                                        
                                                int p = 0;                                                              
                                                float *density = smoke_get_density(sds->fluid);                                                         
                                                float *bigdensity = smoke_turbulence_get_density(sds->wt);                                                              
@@ -871,7 +877,27 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
                                                float *velocity_y = smoke_get_velocity_y(sds->fluid);                                                           
                                                float *velocity_z = smoke_get_velocity_z(sds->fluid);                                                           
                                                unsigned char *obstacle = smoke_get_obstacle(sds->fluid);                                                               
-                                               int bigres[3];  
+                                               int bigres[3];
+                                               short absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE);
+                                               short high_emission_smoothing = bigdensity ? (smd->domain->flags & MOD_SMOKE_HIGH_SMOOTH) : 0;
+
+                                               /*
+                                               * A temporary volume map used to store whole emissive
+                                               * area to be added to smoke density and interpolated
+                                               * for high resolution smoke.
+                                               */
+                                               float *temp_emission_map = NULL;
+
+                                               // initialize temp emission map
+                                               if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW))
+                                               {
+                                                       int i;
+                                                       temp_emission_map = MEM_callocN(sizeof(float) * sds->res[0]*sds->res[1]*sds->res[2], "SmokeTempEmission");
+                                                       // set whole volume to 0.0f
+                                                       for (i=0; i<sds->res[0]*sds->res[1]*sds->res[2]; i++) {
+                                                               temp_emission_map[i] = 0.0f;
+                                                       }
+                                               }
                                                                                                                
                                                // mostly copied from particle code                                                             
                                                for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)                                                                
@@ -905,33 +931,21 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
                                                                // heat[index] += sfs->temp * 0.1;                                                                              
                                                                // density[index] += sfs->density * 0.1;
                                                                heat[index] = sfs->temp;
-                                                               density[index] = sfs->density;
+                                                               
+                                                               // Add emitter density to temp emission map
+                                                               temp_emission_map[index] = sfs->density;
 
 
                                                                // Uses particle velocity as initial velocity for smoke
-                                                               if(smd->domain->flags & MOD_SMOKE_INITVELOCITY) {
-                                                               velocity_x[index] = pa->state.vel[0];
-                                                               velocity_y[index] = pa->state.vel[1];
-                                                               velocity_z[index] = pa->state.vel[2];                                                                           
-                                                               }                                                                               
-                                                               
-                                                               // obstacle[index] |= 2;
-                                                               // we need different handling for the high-res feature
-                                                               if(bigdensity)
-                                                               {
-                                                                       // init all surrounding cells according to amplification, too
-                                                                       int i, j, k;
+                                                               if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) {
 
-                                                                       smoke_turbulence_get_res(smd->domain->wt, bigres);
+                                                                       velocity_x[index] = pa->state.vel[0]*sfs->vel_multi;
+                                                                       velocity_y[index] = pa->state.vel[1]*sfs->vel_multi;
+                                                                       velocity_z[index] = pa->state.vel[2]*sfs->vel_multi;
+
+                                                               }                                                                               
+                                                       
 
-                                                                       for(i = 0; i < smd->domain->amplify + 1; i++)
-                                                                               for(j = 0; j < smd->domain->amplify + 1; j++)
-                                                                                       for(k = 0; k < smd->domain->amplify + 1; k++)                                                                                                   
-                                                                                       {                                                                                                               
-                                                                                               index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);                                                                                                               
-                                                                                               bigdensity[index] = sfs->density;                                                                                                       
-                                                                                       }                                                                               
-                                                               }                                                                       
                                                        }                                                                       
                                                        else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow                                                                     
                                                        {                                                                               
@@ -954,9 +968,136 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
                                                                                                index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);                                                                                                               
                                                                                                bigdensity[index] = 0.f;                                                                                                        
                                                                                        }                                                                               
-                                                               }                                                                       
-                                                       }       // particles loop                                                       
-                                       }                                                       
+                                                               }
+                                                       }
+                                                       }       // particles loop
+
+
+                                                       // apply emission values
+                                                       if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) {
+
+                                                               // initialize variables
+                                                               int ii, jj, kk, x, y, z, block_size;
+                                                               size_t index, index_big;
+
+                                                               smoke_turbulence_get_res(smd->domain->wt, bigres);
+                                                               block_size = smd->domain->amplify + 1;  // high res block size
+
+
+                                                                       // loop through every low res cell
+                                                                       for(x = 0; x < sds->res[0]; x++)
+                                                                               for(y = 0; y < sds->res[1]; y++)
+                                                                                       for(z = 0; z < sds->res[2]; z++)                                                                                                        
+                                                                                       {
+
+                                                                                               // neighbour cell emission densities (for high resolution smoke smooth interpolation)
+                                                                                               float c000, c001, c010, c011,  c100, c101, c110, c111;
+
+                                                                                               c000 = (x>0 && y>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z-1)] : 0;
+                                                                                               c001 = (x>0 && y>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z)] : 0;
+                                                                                               c010 = (x>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z-1)] : 0;
+                                                                                               c011 = (x>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z)] : 0;
+
+                                                                                               c100 = (y>0 && z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z-1)] : 0;
+                                                                                               c101 = (y>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z)] : 0;
+                                                                                               c110 = (z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z-1)] : 0;
+                                                                                               c111 = temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z)];                   // this cell
+
+
+
+                                                                                               // get cell index
+                                                                                               index = smoke_get_index(x, sds->res[0], y, sds->res[1], z);
+
+                                                                                               // add emission to low resolution density
+                                                                                               if (absolute_flow) {if (temp_emission_map[index]>0) density[index] = temp_emission_map[index];}
+                                                                                               else {
+                                                                                                       density[index] += temp_emission_map[index];
+                                                                                                       if (density[index]>1) density[index]=1.0f;
+                                                                                               }
+
+                                                                                               smoke_turbulence_get_res(smd->domain->wt, bigres);
+
+
+
+                                                                                               /*
+                                                                                               loop through high res blocks if high res enabled
+                                                                                               */
+                                                                                               if (bigdensity)
+                                                                                               for(ii = 0; ii < block_size; ii++)
+                                                                                                       for(jj = 0; jj < block_size; jj++)
+                                                                                                               for(kk = 0; kk < block_size; kk++)                                                                                                      
+                                                                                                               {
+
+                                                                                                               float fx,fy,fz, interpolated_value;
+                                                                                                               int shift_x, shift_y, shift_z;
+
+
+                                                                                                               /*
+                                                                                                               * Do volume interpolation if emitter smoothing
+                                                                                                               * is enabled
+                                                                                                               */
+                                                                                                               if (high_emission_smoothing) {
+                                                                                                                       // convert block position to relative
+                                                                                                                       // for interpolation smoothing
+                                                                                                                       fx = (float)ii/block_size + 0.5f/block_size;
+                                                                                                                       fy = (float)jj/block_size + 0.5f/block_size;
+                                                                                                                       fz = (float)kk/block_size + 0.5f/block_size;
+
+                                                                                                                       // calculate trilinear interpolation
+                                                                                                                       interpolated_value = c000 * (1-fx) * (1-fy) * (1-fz) +
+                                                                                                                       c100 * fx * (1-fy) * (1-fz) +
+                                                                                                                       c010 * (1-fx) * fy * (1-fz) +
+                                                                                                                       c001 * (1-fx) * (1-fy) * fz +
+                                                                                                                       c101 * fx * (1-fy) * fz +
+                                                                                                                       c011 * (1-fx) * fy * fz +
+                                                                                                                       c110 * fx * fy * (1-fz) +
+                                                                                                                       c111 * fx * fy * fz;
+
+
+                                                                                                                       // add some contrast / sharpness
+                                                                                                                       // depending on hi-res block size
+
+                                                                                                                       interpolated_value = (interpolated_value-0.4f*sfs->density)*(block_size/2) + 0.4f*sfs->density;
+                                                                                                                       if (interpolated_value<0.0f) interpolated_value = 0.0f;
+                                                                                                                       if (interpolated_value>1.0f) interpolated_value = 1.0f;
+
+                                                                                                                       // shift smoke block index
+                                                                                                                       // (because pixel center is actually
+                                                                                                                       // in halfway of the low res block)
+                                                                                                                       shift_x = (x < 1) ? 0 : block_size/2;
+                                                                                                                       shift_y = (y < 1) ? 0 : block_size/2;
+                                                                                                                       shift_z = (z < 1) ? 0 : block_size/2;
+                                                                                                               }
+                                                                                                               else {
+                                                                                                                       // without interpolation use same low resolution
+                                                                                                                       // block value for all hi-res blocks
+                                                                                                                       interpolated_value = c111;
+                                                                                                                       shift_x = 0;
+                                                                                                                       shift_y = 0;
+                                                                                                                       shift_z = 0;
+                                                                                                               }
+
+                                                                                                               // get shifted index for current high resolution block
+                                                                                                               index_big = smoke_get_index(block_size * x + ii - shift_x, bigres[0], block_size * y + jj - shift_y, bigres[1], block_size * z + kk - shift_z);                                                                                                         
+                                                                                                               
+                                                                                                               // add emission data to high resolution density
+                                                                                                               if (absolute_flow) {if (interpolated_value > 0) bigdensity[index_big] = interpolated_value;}
+                                                                                                               else {
+                                                                                                                       bigdensity[index_big] += interpolated_value;
+                                                                                                                       if (bigdensity[index_big]>1) bigdensity[index_big]=1.0f;
+                                                                                                               }
+
+                                                                                                               } // end of hires loop
+
+                                                                       }       // end of low res loop
+
+                                                               // free temporary emission map
+                                                       if (temp_emission_map) MEM_freeN(temp_emission_map);
+
+                                                       }       // end emission
+
+
+                                                                               
                                }                                                       
                                else                                                    
                                {                                                               
@@ -970,7 +1111,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
 
                                                BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
                                        }*/                                                     
-                               }                                               
+                               }
                        }                                               
                }
                        if(sds->fluid_group)
index 71a9fc2e8447922f3af325d8d899cd49f2b147a8..3227d4b25bb14284b8b4e7e361ea1d150c5f344e 100644 (file)
@@ -11066,6 +11066,60 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+       if (main->versionfile < 253 || (main->versionfile == 253 && main->subversionfile < 1))
+               {
+                       Object *ob;
+
+                       for(ob = main->object.first; ob; ob = ob->id.next) {
+                               ModifierData *md;
+                               for(md= ob->modifiers.first; md; md= md->next) {
+                                       if (md->type == eModifierType_Smoke) {
+                                               SmokeModifierData *smd = (SmokeModifierData *)md;
+
+                                               if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+                                               {
+                                                       GroupObject *go = NULL;
+                                                       Base *base = NULL;
+                                                       Scene *scene = NULL;
+
+                                                       smd->domain->vorticity = 2.0f;
+                                                       smd->domain->time_scale = 1.0f;
+
+                                                       if(!(smd->domain->flags & (1<<4)))
+                                                               continue;
+
+                                                       /* delete old MOD_SMOKE_INITVELOCITY flag */
+                                                       smd->domain->flags &= ~(1<<4);
+
+                                                       /* for now just add it to all flow objects in the scene */
+                                                       {
+                                                               Object *ob2;
+                                                               for(ob2 = main->object.first; ob2; ob2 = ob2->id.next) {
+                                                                       ModifierData *md2;
+                                                                       for(md2= ob2->modifiers.first; md2; md2= md2->next) {
+                                                                               if (md2->type == eModifierType_Smoke) {
+                                                                                       SmokeModifierData *smd2 = (SmokeModifierData *)md2;
+
+                                                                                       if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
+                                                                                       {
+                                                                                               smd2->flow->flags |= MOD_SMOKE_FLOW_INITVELOCITY;
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+
+                                               }
+                                               else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow)
+                                               {
+                                                       smd->flow->vel_multi = 1.0f;
+                                               }
+
+                                       }
+                               }
+                       }
+               }
+
        /* put compatibility code here until next subversion bump */
        {
        }
index 420f2d77fed35a80c525cb0140db326205088ae9..79b22f41e30648c5f762642028958cc36aca6d2a 100644 (file)
@@ -450,7 +450,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture
        }
 
        tend();
-       printf ( "Draw Time: %f\n",( float ) tval() );
+       // printf ( "Draw Time: %f\n",( float ) tval() );
 
        if(tex_shadow)
                GPU_texture_unbind(tex_shadow);
index 46e5c10be3b664d282beb494530e698a1493f632..b8be51b378f4e0b5665f7d54dec1a47c8c5c6b23 100644 (file)
@@ -33,8 +33,8 @@
 #define MOD_SMOKE_HIGHRES (1<<1) /* enable high resolution */
 #define MOD_SMOKE_DISSOLVE (1<<2) /* let smoke dissolve */
 #define MOD_SMOKE_DISSOLVE_LOG (1<<3) /* using 1/x for dissolve */
-#define MOD_SMOKE_INITVELOCITY (1<<4) /* passes particles speed to
-                                                                                the smoke*/
+
+#define MOD_SMOKE_HIGH_SMOOTH (1<<5) /* smoothens high res emission*/
 
 /* noise */
 #define MOD_SMOKE_NOISEWAVE (1<<0)
 #define SM_CACHE_LIGHT         0
 #define SM_CACHE_HEAVY         1
 
+/* domain border collision */
+#define SM_BORDER_OPEN         0
+#define SM_BORDER_VERTICAL     1
+#define SM_BORDER_CLOSED       2
+
 typedef struct SmokeDomainSettings {
        struct SmokeModifierData *smd; /* for fast RNA access */
        struct FLUID_3D *fluid;
@@ -84,6 +89,10 @@ typedef struct SmokeDomainSettings {
        struct PointCache *point_cache[2];      /* definition is in DNA_object_force.h */
        struct ListBase ptcaches[2];
        struct EffectorWeights *effector_weights;
+       int border_collisions;  /* How domain border collisions are handled */
+       float time_scale;
+       float vorticity;
+       int pad2;
 } SmokeDomainSettings;
 
 
@@ -92,18 +101,25 @@ typedef struct SmokeDomainSettings {
 /* type */
 #define MOD_SMOKE_FLOW_TYPE_OUTFLOW (1<<1)
 
+/* flags */
+#define MOD_SMOKE_FLOW_ABSOLUTE (1<<1) /*old style emission*/
+#define MOD_SMOKE_FLOW_INITVELOCITY (1<<2) /* passes particles speed to
+                                                                                the smoke*/
+
+
 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]; /* UNUSED, velocity taken from particles */
+       float velocity[2]; /* UNUSED, velocity taken from particles */
+       float vel_multi; // Multiplier for particle velocity
        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;
        short vgroup_heat;
        short type; /* inflow =0 or outflow = 1 */
-       int pad;
+       int flags; /* absolute emission etc*/
 } SmokeFlowSettings;
 
 /*
index dfd9c2f434c15a1bce62adbb4b0f7e2a8d809727..dcf20a3531d7aa846f8e99f8c27d11c019871876 100644 (file)
@@ -87,10 +87,15 @@ EnumPropertyItem modifier_type_items[] ={
 
 #ifdef RNA_RUNTIME
 
+#include "DNA_particle_types.h"
+#include "DNA_smoke_types.h"
+
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_library.h"
 #include "BKE_modifier.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
 
 static void rna_UVProject_projectors_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
@@ -216,6 +221,9 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
        SmokeModifierData *smd= (SmokeModifierData *)ptr->data;
        Object *ob= (Object*)ptr->id.data;
+       ParticleSystemModifierData *psmd = NULL;
+       ParticleSystem *psys = NULL;
+       ParticleSettings *part = NULL;
 
        // nothing changed
        if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
@@ -226,9 +234,32 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr)
 
        switch (smd->type) {
                case MOD_SMOKE_TYPE_DOMAIN:
-                       ob->dt = OB_WIRE;
+                       ob->dt = OB_BOUNDBOX;
                        break;
                case MOD_SMOKE_TYPE_FLOW:
+                       for(psys=ob->particlesystem.first; psys; psys=psys->next)
+                               if(psys->part->type == PART_EMITTER)
+                                       break;
+                       if(ob->type == OB_MESH && !psys) {
+                               /* add particle system */
+                               psmd = object_add_particle_system(scene, ob, NULL);
+                               if(psmd)
+                               {
+                                       psys = psmd->psys;
+                                       part = psys->part;
+                                       part->flag |= PART_UNBORN;
+                                       part->lifetime = 1.0f;
+                                       part->sta = 1.0f;
+                                       part->end = 250.0f;
+                                       part->ren_as = PART_DRAW_NOT;
+                                       part->phystype = PART_PHYS_NO;
+                                       sprintf(psys->name, "SmokeParticles");
+                                       psys->recalc |= (PSYS_RECALC_RESET|PSYS_RECALC_PHYS);
+                                       DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA);
+                               }
+                       }
+                       if(smd->flow)
+                               smd->flow->psys = psys;
                case MOD_SMOKE_TYPE_COLL:
                case 0:
                default:
index d4ff98e97014a25884af2e5ee58886f5b08096e0..56049ea15ce4d64841d34f08b68395fb84045df3 100644 (file)
@@ -120,6 +120,12 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
                {SM_CACHE_HEAVY, "CACHEHEAVY", 0, "Heavy", "Effective but slow compression"},
                {0, NULL, 0, NULL, NULL}};
 
+       static EnumPropertyItem smoke_domain_colli_items[] = {
+               {SM_BORDER_OPEN, "BORDEROPEN", 0, "Open", "Smoke doesn't collide with any border"},
+               {SM_BORDER_VERTICAL, "BORDERVERTICAL", 0, "Vertically Open", "Smoke doesn't collide with top and bottom sides"},
+               {SM_BORDER_CLOSED, "BORDERCLOSED", 0, "Collide All", "Smoke collides with every side"},
+               {0, NULL, 0, NULL, NULL}};
+
        srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL);
        RNA_def_struct_ui_text(srna, "Domain Settings", "Smoke domain settings");
        RNA_def_struct_sdna(srna, "SmokeDomainSettings");
@@ -192,8 +198,8 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "strength");
-       RNA_def_property_range(prop, 1.0, 10.0);
-       RNA_def_property_ui_range(prop, 1.0, 10.0, 1, 2);
+       RNA_def_property_range(prop, 0.0, 10.0);
+       RNA_def_property_ui_range(prop, 0.0, 10.0, 1, 2);
        RNA_def_property_ui_text(prop, "Strength", "Strength of wavelet noise");
        RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
 
@@ -204,11 +210,6 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed");
        RNA_def_property_update(prop, 0, NULL);
 
-       prop= RNA_def_property(srna, "initial_velocity", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_INITVELOCITY);
-       RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke inherits it's velocity from the emitter particle");
-       RNA_def_property_update(prop, 0, NULL);
-
        prop= RNA_def_property(srna, "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");
@@ -241,12 +242,36 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
        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, "smoke_domain_colli", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "border_collisions");
+       RNA_def_property_enum_items(prop, smoke_domain_colli_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, "effector_weights", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "EffectorWeights");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Effector Weights", "");
 
+       prop= RNA_def_property(srna, "smoothemitter", 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);
+
+       prop= RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "time_scale");
+       RNA_def_property_range(prop, 0.2, 1.5);
+       RNA_def_property_ui_range(prop, 0.2, 1.5, 0.02, 5);
+       RNA_def_property_ui_text(prop, "Time Scale", "Adjust simulation speed.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
+
+       prop= RNA_def_property(srna, "vorticity", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "vorticity");
+       RNA_def_property_range(prop, 0.01, 4.0);
+       RNA_def_property_ui_range(prop, 0.01, 4.0, 0.02, 5);
+       RNA_def_property_ui_text(prop, "Vorticity", "Amount of turbulence/rotation in fluid.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
+
 }
 
 static void rna_def_smoke_flow_settings(BlenderRNA *brna)
@@ -284,6 +309,23 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna)
        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, 0, NULL);
+
+       prop= RNA_def_property(srna, "absolute", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_ABSOLUTE);
+       RNA_def_property_ui_text(prop, "Absolute Density", "Only allows given density value in emitter area.");
+       RNA_def_property_update(prop, 0, NULL);
+
+       prop= RNA_def_property(srna, "initial_velocity", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_INITVELOCITY);
+       RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke inherits it's velocity from the emitter particle");
+       RNA_def_property_update(prop, 0, NULL);
+
+       prop= RNA_def_property(srna, "velocity_multiplier", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "vel_multi");
+       RNA_def_property_range(prop, -2.0, 2.0);
+       RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5);
+       RNA_def_property_ui_text(prop, "Multiplier", "Multiplier to adjust velocity passed to smoke");
+       RNA_def_property_update(prop, 0, NULL);
 }
 
 static void rna_def_smoke_coll_settings(BlenderRNA *brna)