Merged changes in the trunk up to revision 30814.

This commit includes r30807, which is equivalent to r30602 in the branch
for fixiing a layout issue.
This commit is contained in:
Tamito Kajiyama 2010-07-28 01:06:47 +00:00
commit 44f5114964
41 changed files with 10326 additions and 8267 deletions

@ -38,11 +38,11 @@ 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_step(struct FLUID_3D *fluid, size_t framenr);
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 fps);
float *smoke_get_density(struct FLUID_3D *fluid);
float *smoke_get_heat(struct FLUID_3D *fluid);

@ -35,23 +35,15 @@
#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);

@ -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;

@ -33,10 +33,10 @@
#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]);
@ -75,9 +75,41 @@ extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z
return x + y * max_x;
}
extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr)
extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr, float fps)
{
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 */
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;
}
/* adapt timestep for different framerates, dt = 0.1 is at 25fps */
dt *= (25.0f / fps);
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 +117,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)

@ -634,7 +634,7 @@ def write(filepath, objects, scene,
# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1):
vgroupsMap[vIdx].append((g.name, vWeight))
for f_index, f in enumerate(faces):
for f, f_index in face_index_pairs:
f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts]
# if f.verts[3] == 0:
@ -646,7 +646,7 @@ def write(filepath, objects, scene,
# f_mat = min(f.mat, len(materialNames)-1)
if faceuv:
tface = me.active_uv_texture.data[face_index_pairs[f_index][1]]
tface = me.active_uv_texture.data[f_index]
f_image = tface.image
f_uv = tface.uv

@ -883,14 +883,12 @@ def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True,
# REMOVE DUMMYVERT, - remove this in the next release when blenders internal are fixed.
# for ob in importedObjects:
# if ob.type == 'MESH':
# # if ob.type=='Mesh':
# me = ob.getData(mesh=1)
# me.verts.delete([me.verts[0],])
# if not APPLY_MATRIX:
# me.transform(ob.matrix_world.copy().invert())
for ob in importedObjects:
if ob.type == 'MESH':
me = ob.data
# me.verts.delete([me.verts[0],]) # XXX, todo
if not APPLY_MATRIX:
me.transform(ob.matrix_world.copy().invert())
# Done DUMMYVERT
"""
@ -1009,15 +1007,19 @@ class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
filepath = StringProperty(name="File Path", description="Filepath used for importing the 3DS file", maxlen= 1024, default= "")
# size_constraint = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
# search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
# apply_matrix = BoolProperty(name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
constrain_size = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0)
search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True)
apply_transform = BoolProperty(name="Apply Transform", description="Workaround for object transformations importing incorrectly", default=False)
def execute(self, context):
load_3ds(self.properties.filepath, context, 0.0, False, False)
load_3ds(self.properties.filepath,
context,
IMPORT_CONSTRAIN_BOUNDS=self.properties.constrain_size,
IMAGE_SEARCH=self.properties.search_images,
APPLY_MATRIX=self.properties.apply_transform)
return {'FINISHED'}
def invoke(self, context, event):

@ -67,7 +67,7 @@ def get_console(console_id):
stdout = io.StringIO()
stderr = io.StringIO()
else:
namespace = {'__builtins__': __builtins__, 'bpy': bpy}
namespace = {"__builtins__": __builtins__, "bpy": bpy, "C": bpy.context}
console = InteractiveConsole(locals=namespace, filename="<blender_console>")
import io
@ -97,10 +97,6 @@ def execute(context):
console, stdout, stderr = get_console(hash(context.region))
# Hack, useful but must add some other way to access
#if "C" not in console.locals:
console.locals["C"] = context
# redirect output
sys.stdout = stdout
sys.stderr = stderr
@ -243,10 +239,6 @@ def banner(context):
add_scrollback("", 'OUTPUT')
sc.prompt = PROMPT
# Add context into the namespace for quick access
console = get_console(hash(context.region))[0]
console.locals["C"] = bpy.context
return {'FINISHED'}

@ -120,6 +120,7 @@ class DATA_PT_display(DataButtonsPanel):
if wide_ui:
col = split.column()
col.prop(arm, "draw_group_colors", text="Colors")
col.prop(ob, "x_ray", text="X-Ray")
col.prop(arm, "delay_deform", text="Delay Refresh")
@ -173,8 +174,6 @@ class DATA_PT_bone_groups(DataButtonsPanel):
# TODO: this panel will soon be depreceated too
class DATA_PT_ghost(DataButtonsPanel):
bl_label = "Ghost"

@ -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,6 +96,7 @@ 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()
@ -102,15 +106,21 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel):
col.label(text="Particle System:")
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:

@ -343,7 +343,7 @@ class RENDER_PT_freestyle_linestyle(RenderButtonsPanel):
sub.prop(modifier, "invert")
if modifier.mapping == "CURVE":
sub.enabled = False
box.template_curve_mapping(modifier, "curve") # FIXME: not properly displayed
box.template_curve_mapping(modifier, "curve")
if modifier.type not in ["ALONG_STROKE"]:
row = box.row(align=True)
row.prop(modifier, "range_min")
@ -367,7 +367,7 @@ class RENDER_PT_freestyle_linestyle(RenderButtonsPanel):
sub.prop(modifier, "invert")
if modifier.mapping == "CURVE":
sub.enabled = False
box.template_curve_mapping(modifier, "curve") # FIXME: not properly displayed
box.template_curve_mapping(modifier, "curve")
if modifier.type not in ["ALONG_STROKE"]:
row = box.row(align=True)
row.prop(modifier, "range_min")

@ -859,6 +859,7 @@ class VIEW3D_PT_tools_brush_tool(PaintPanel):
if context.sculpt_object:
col.prop(brush, "sculpt_tool", expand=False, text="")
col.operator("brush.reset")
elif context.texture_paint_object:
col.prop(brush, "imagepaint_tool", expand=False, text="")
elif context.vertex_paint_object or context.weight_paint_object:

@ -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

@ -44,6 +44,8 @@ struct Brush *copy_brush(struct Brush *brush);
void make_local_brush(struct Brush *brush);
void free_brush(struct Brush *brush);
void brush_reset_sculpt(struct Brush *brush);
/* image icon function */
struct ImBuf *get_brush_icon(struct Brush *brush);

@ -62,25 +62,22 @@
#include "RE_render_ext.h" /* externtex */
#include "RE_shader_ext.h"
/* Datablock add/copy/free/make_local */
Brush *add_brush(const char *name)
static void brush_set_defaults(Brush *brush)
{
Brush *brush;
brush= alloc_libblock(&G.main->brush, ID_BR, name);
brush->blend = 0;
brush->flag = 0;
/* BRUSH SCULPT TOOL SETTINGS */
brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */
brush->size= 35; /* radius of the brush in pixels */
brush->alpha= 0.5f; /* brush strength/intensity probably variable should be renamed? */
brush->autosmooth_factor= 0.0f;
brush->crease_pinch_factor= 0.5f;
brush->sculpt_plane = SCULPT_DISP_DIR_VIEW;
brush->sculpt_plane = SCULPT_DISP_DIR_AREA;
brush->plane_offset= 0.0f; /* how far above or below the plane that is found by averaging the faces */
brush->plane_trim= 0.5f;
brush->clone.alpha= 0.5f;
brush->normal_weight= 0.0f;
brush->flag |= BRUSH_ALPHA_PRESSURE;
/* BRUSH PAINT TOOL SETTINGS */
brush->rgb[0]= 1.0f; /* default rgb color of the brush when painting - white */
@ -102,6 +99,7 @@ Brush *add_brush(const char *name)
default_mtex(&brush->mtex);
brush->texture_sample_bias= 0; /* value to added to texture samples */
brush->texture_overlay_alpha= 33;
/* brush appearance */
@ -112,6 +110,19 @@ Brush *add_brush(const char *name)
brush->sub_col[0]= 0.39; /* subtract mode color is light blue */
brush->sub_col[1]= 0.39;
brush->sub_col[2]= 1.00;
}
/* Datablock add/copy/free/make_local */
Brush *add_brush(const char *name)
{
Brush *brush;
brush= alloc_libblock(&G.main->brush, ID_BR, name);
brush_set_defaults(brush);
brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */
/* the default alpha falloff curve */
brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
@ -212,6 +223,175 @@ void make_local_brush(Brush *brush)
}
}
void brush_debug_print_state(Brush *br)
{
Brush def;
/* create a fake brush and set it to the defaults */
memset(&def, 0, sizeof(Brush));
brush_set_defaults(&def);
#define BR_TEST(field, t) \
if(br->field != def.field) \
printf("br->" #field " = %" #t ";\n", br->field)
#define BR_TEST_FLAG(_f) \
if((br->flag & _f) && !(def.flag & _f)) \
printf("br->flag |= " #_f ";\n"); \
else if(!(br->flag & _f) && (def.flag & _f)) \
printf("br->flag &= ~" #_f ";\n")
/* print out any non-default brush state */
BR_TEST(normal_weight, f);
BR_TEST(blend, d);
BR_TEST(size, d);
/* br->flag */
BR_TEST_FLAG(BRUSH_AIRBRUSH);
BR_TEST_FLAG(BRUSH_TORUS);
BR_TEST_FLAG(BRUSH_ALPHA_PRESSURE);
BR_TEST_FLAG(BRUSH_SIZE_PRESSURE);
BR_TEST_FLAG(BRUSH_JITTER_PRESSURE);
BR_TEST_FLAG(BRUSH_SPACING_PRESSURE);
BR_TEST_FLAG(BRUSH_FIXED_TEX);
BR_TEST_FLAG(BRUSH_RAKE);
BR_TEST_FLAG(BRUSH_ANCHORED);
BR_TEST_FLAG(BRUSH_DIR_IN);
BR_TEST_FLAG(BRUSH_SPACE);
BR_TEST_FLAG(BRUSH_SMOOTH_STROKE);
BR_TEST_FLAG(BRUSH_PERSISTENT);
BR_TEST_FLAG(BRUSH_ACCUMULATE);
BR_TEST_FLAG(BRUSH_LOCK_ALPHA);
BR_TEST_FLAG(BRUSH_ORIGINAL_NORMAL);
BR_TEST_FLAG(BRUSH_OFFSET_PRESSURE);
BR_TEST_FLAG(BRUSH_SPACE_ATTEN);
BR_TEST_FLAG(BRUSH_ADAPTIVE_SPACE);
BR_TEST_FLAG(BRUSH_LOCK_SIZE);
BR_TEST_FLAG(BRUSH_TEXTURE_OVERLAY);
BR_TEST_FLAG(BRUSH_EDGE_TO_EDGE);
BR_TEST_FLAG(BRUSH_RESTORE_MESH);
BR_TEST_FLAG(BRUSH_INVERSE_SMOOTH_PRESSURE);
BR_TEST_FLAG(BRUSH_RANDOM_ROTATION);
BR_TEST_FLAG(BRUSH_PLANE_TRIM);
BR_TEST_FLAG(BRUSH_FRONTFACE);
BR_TEST_FLAG(BRUSH_CUSTOM_ICON);
BR_TEST(jitter, f);
BR_TEST(spacing, d);
BR_TEST(smooth_stroke_radius, d);
BR_TEST(smooth_stroke_factor, f);
BR_TEST(rate, f);
BR_TEST(alpha, f);
BR_TEST(sculpt_plane, d);
BR_TEST(plane_offset, f);
BR_TEST(autosmooth_factor, f);
BR_TEST(crease_pinch_factor, f);
BR_TEST(plane_trim, f);
BR_TEST(texture_sample_bias, f);
BR_TEST(texture_overlay_alpha, d);
BR_TEST(add_col[0], f);
BR_TEST(add_col[1], f);
BR_TEST(add_col[2], f);
BR_TEST(sub_col[0], f);
BR_TEST(sub_col[1], f);
BR_TEST(sub_col[2], f);
printf("\n");
#undef BR_TEST
#undef BR_TEST_FLAG
}
void brush_reset_sculpt(Brush *br)
{
/* enable this to see any non-default
settings used by a brush:
brush_debug_print_state(br);
*/
brush_set_defaults(br);
brush_curve_preset(br, CURVE_PRESET_SMOOTH);
switch(br->sculpt_tool) {
case SCULPT_TOOL_CLAY:
br->flag |= BRUSH_FRONTFACE;
break;
case SCULPT_TOOL_CREASE:
br->flag |= BRUSH_DIR_IN;
br->alpha = 0.25;
break;
case SCULPT_TOOL_FILL:
br->add_col[1] = 1;
br->sub_col[0] = 0.25;
br->sub_col[1] = 1;
break;
case SCULPT_TOOL_FLATTEN:
br->add_col[1] = 1;
br->sub_col[0] = 0.25;
br->sub_col[1] = 1;
break;
case SCULPT_TOOL_INFLATE:
br->add_col[0] = 0.750000;
br->add_col[1] = 0.750000;
br->add_col[2] = 0.750000;
br->sub_col[0] = 0.250000;
br->sub_col[1] = 0.250000;
br->sub_col[2] = 0.250000;
break;
case SCULPT_TOOL_NUDGE:
br->add_col[0] = 0.250000;
br->add_col[1] = 1.000000;
br->add_col[2] = 0.250000;
break;
case SCULPT_TOOL_PINCH:
br->add_col[0] = 0.750000;
br->add_col[1] = 0.750000;
br->add_col[2] = 0.750000;
br->sub_col[0] = 0.250000;
br->sub_col[1] = 0.250000;
br->sub_col[2] = 0.250000;
break;
case SCULPT_TOOL_SCRAPE:
br->add_col[1] = 1.000000;
br->sub_col[0] = 0.250000;
br->sub_col[1] = 1.000000;
break;
case SCULPT_TOOL_ROTATE:
break;
case SCULPT_TOOL_SMOOTH:
br->flag &= ~BRUSH_SPACE_ATTEN;
br->spacing = 5;
br->add_col[0] = 0.750000;
br->add_col[1] = 0.750000;
br->add_col[2] = 0.750000;
break;
case SCULPT_TOOL_GRAB:
case SCULPT_TOOL_SNAKE_HOOK:
case SCULPT_TOOL_THUMB:
br->size = 75;
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE;
br->flag &= ~BRUSH_SPACE_ATTEN;
br->add_col[0] = 0.250000;
br->add_col[1] = 1.000000;
br->add_col[2] = 0.250000;
break;
default:
break;
}
}
/* Library Operations */
int brush_set_nr(Brush **current_brush, int nr, const char *name)

@ -1673,6 +1673,11 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source,
CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
DerivedMesh *dm = &cddm->dm;
/* ensure these are created if they are made on demand */
source->getVertDataArray(source, CD_ORIGINDEX);
source->getEdgeDataArray(source, CD_ORIGINDEX);
source->getFaceDataArray(source, CD_ORIGINDEX);
/* this does a copy of all non mvert/medge/mface layers */
DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);

@ -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,20 @@ 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)
if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO))
{
// init all surrounding cells according to amplification, too
int i, j, k;
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;
}
smoke_turbulence_get_res(smd->domain->wt, bigres);
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 +967,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 +1110,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)
@ -1272,7 +1412,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
{
if(sds->flags & MOD_SMOKE_DISSOLVE)
smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
smoke_step(sds->fluid, smd->time);
smoke_step(sds->fluid, smd->time, scene->r.frs_sec / scene->r.frs_sec_base);
}
// create shadows before writing cache so we get nice shadows for sstartframe, too

@ -126,6 +126,7 @@ MINLINE int compare_v3v3(float a[3], float b[3], float limit);
MINLINE int compare_len_v3v3(float a[3], float b[3], float limit);
MINLINE int compare_v4v4(float a[4], float b[4], float limit);
MINLINE int equals_v4v4(float a[4], float b[4]);
/********************************** Angles ***********************************/
/* - angle with 2 arguments is angle between vector */

@ -409,6 +409,11 @@ MINLINE int equals_v3v3(float *v1, float *v2)
return ((v1[0]==v2[0]) && (v1[1]==v2[1]) && (v1[2]==v2[2]));
}
MINLINE int equals_v4v4(float *v1, float *v2)
{
return ((v1[0]==v2[0]) && (v1[1]==v2[1]) && (v1[2]==v2[2]) && (v1[3]==v2[3]));
}
MINLINE int compare_v3v3(float *v1, float *v2, float limit)
{
if(fabs(v1[0]-v2[0])<limit)

@ -3299,6 +3299,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->msticky= newdataadr(fd, mesh->msticky);
mesh->dvert= newdataadr(fd, mesh->dvert);
/* animdata */
mesh->adt= newdataadr(fd, mesh->adt);
direct_link_animdata(fd, mesh->adt);
@ -11206,6 +11207,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 */
{
}
@ -11823,6 +11878,9 @@ static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
TFace *tf;
int a, i;
if(me->adt)
expand_animdata(fd, mainvar, me->adt);
for(a=0; a<me->totcol; a++) {
expand_doit(fd, mainvar, me->mat[a]);
}

@ -1539,6 +1539,7 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
/* direct data */
if (mesh->id.properties) IDP_WriteProperty(mesh->id.properties, wd);
if (mesh->adt) write_animdata(wd, mesh->adt);
writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat);

File diff suppressed because it is too large Load Diff

@ -28,6 +28,7 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "MEM_guardedalloc.h"
@ -1535,6 +1536,19 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
data->str= MEM_callocN(sizeof(char)*data->maxlen + 1, "textedit str");
ui_get_but_string(but, data->str, data->maxlen);
if(ELEM3(but->type, NUM, NUMABS, NUMSLI)) {
/* XXX: we dont have utf editing yet so for numbers its best to strip out utf chars
* this is so the deg' synbol isnt included in number editing fields: bug 22274 */
int i;
for(i=0; data->str[i]; i++) {
if(!isascii(data->str[i])) {
data->str[i]= '\0';
break;
}
}
}
data->origstr= BLI_strdup(data->str);
data->selextend= 0;
data->selstartx= 0;

@ -756,7 +756,10 @@ static int group_instance_add_exec(bContext *C, wmOperator *op)
ob->transflag |= OB_DUPLIGROUP;
id_lib_extern(&group->id);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
/* works without this except if you try render right after, see: 22027 */
DAG_scene_sort(CTX_data_scene(C));
WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, CTX_data_scene(C));
return OPERATOR_FINISHED;
}

@ -154,6 +154,35 @@ void PAINT_OT_vertex_color_set(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
static int brush_reset_exec(bContext *C, wmOperator *op)
{
Paint *paint = paint_get_active(CTX_data_scene(C));
Brush *brush = paint_brush(paint);
Object *ob = CTX_data_active_object(C);
if(!ob) return OPERATOR_CANCELLED;
if(ob->mode & OB_MODE_SCULPT)
brush_reset_sculpt(brush);
/* TODO: other modes */
return OPERATOR_FINISHED;
}
void BRUSH_OT_reset(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Reset Brush";
ot->description= "Return brush to defaults based on current tool";
ot->idname= "BRUSH_OT_reset";
/* api callbacks */
ot->exec= brush_reset_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
/**************************** registration **********************************/
void ED_operatortypes_paint(void)
@ -162,7 +191,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(BRUSH_OT_add);
WM_operatortype_append(BRUSH_OT_scale_size);
WM_operatortype_append(BRUSH_OT_curve_preset);
WM_operatortype_append(BRUSH_OT_reset);
/* image */
WM_operatortype_append(PAINT_OT_texture_paint_toggle);
@ -175,7 +204,6 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_project_image);
WM_operatortype_append(PAINT_OT_image_from_view);
/* weight */
WM_operatortype_append(PAINT_OT_weight_paint_toggle);
WM_operatortype_append(PAINT_OT_weight_paint_radial_control);

@ -3305,6 +3305,8 @@ static void sculpt_flush_update(bContext *C)
if(mmd)
multires_mark_as_modified(ob);
if(ob->derivedFinal) /* VBO no longer valid */
GPU_drawobject_free(ob->derivedFinal);
if(ss->modifiers_active) {
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);

@ -341,7 +341,6 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
break;
case NC_BRUSH:
buttons_area_redraw(sa, BCONTEXT_TEXTURE);
sbuts->preview= 1;
break;
case NC_TEXTURE:
case NC_IMAGE:

@ -1157,7 +1157,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
c++;
while(linep) {
while(c<linep->len) {
if(linep->format[c] != 'l' && linep->format[c] != '#') {
if(linep->format && linep->format[c] != 'l' && linep->format[c] != '#') {
b= text_check_bracket(linep->line[c]);
if(b==find) {
if(stack==0) {
@ -1183,7 +1183,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
c--;
while(linep) {
while(c>=0) {
if(linep->format[c] != 'l' && linep->format[c] != '#') {
if(linep->format && linep->format[c] != 'l' && linep->format[c] != '#') {
b= text_check_bracket(linep->line[c]);
if(b==find) {
if(stack==0) {

@ -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);

@ -211,6 +211,7 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->far= 500.0f;
v3d->twtype= V3D_MANIP_TRANSLATE;
v3d->around= V3D_CENTROID;
/* header */
ar= MEM_callocN(sizeof(ARegion), "header for view3d");

@ -1798,7 +1798,7 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object
lamp = GPU_lamp_from_blender(scene, ob, par);
if(lamp) {
GPU_lamp_update(lamp, ob->lay, obmat);
GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_VIEW), obmat);
GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
if((ob->lay & v3d->lay) && GPU_lamp_has_shadow_buffer(lamp)) {

@ -219,38 +219,16 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo
if (sms.new_lens != v3d->lens)
changed = 1;
if ((sms.new_ofs[0]!=rv3d->ofs[0]) ||
(sms.new_ofs[1]!=rv3d->ofs[1]) ||
(sms.new_ofs[2]!=rv3d->ofs[2]) )
if (!equals_v3v3(sms.new_ofs, rv3d->ofs))
changed = 1;
if ((sms.new_quat[0]!=rv3d->viewquat[0]) ||
(sms.new_quat[1]!=rv3d->viewquat[1]) ||
(sms.new_quat[2]!=rv3d->viewquat[2]) ||
(sms.new_quat[3]!=rv3d->viewquat[3]) )
if (!equals_v4v4(sms.new_quat, rv3d->viewquat))
changed = 1;
/* The new view is different from the old one
* so animate the view */
if (changed) {
sms.time_allowed= (double)U.smooth_viewtx / 1000.0;
/* if this is view rotation only
* we can decrease the time allowed by
* the angle between quats
* this means small rotations wont lag */
if (quat && !ofs && !dist) {
float vec1[3], vec2[3];
copy_v3_v3(vec1, sms.new_quat);
copy_v3_v3(vec2, sms.orig_quat);
normalize_v3(vec1);
normalize_v3(vec2);
/* scale the time allowed by the rotation */
sms.time_allowed *= angle_normalized_v3v3(vec1, vec2)/(M_PI/2);
}
/* original values */
if (oldcamera) {
sms.orig_dist= rv3d->dist; // below function does weird stuff with it...
@ -269,6 +247,26 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo
rv3d->view= 0;
}
sms.time_allowed= (double)U.smooth_viewtx / 1000.0;
/* if this is view rotation only
* we can decrease the time allowed by
* the angle between quats
* this means small rotations wont lag */
if (quat && !ofs && !dist) {
float vec1[3]={0,0,1}, vec2[3]= {0,0,1};
float q1[4], q2[4];
invert_qt_qt(q1, sms.new_quat);
invert_qt_qt(q2, sms.orig_quat);
mul_qt_v3(q1, vec1);
mul_qt_v3(q2, vec2);
/* scale the time allowed by the rotation */
sms.time_allowed *= angle_v3v3(vec1, vec2) / M_PI; /* 180deg == 1.0 */
}
/* ensure it shows correct */
if(sms.to_camera) rv3d->persp= RV3D_PERSP;

@ -158,7 +158,7 @@ int GPU_lamp_has_shadow_buffer(GPULamp *lamp);
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]);
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4]);
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]);
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
int GPU_lamp_shadow_layer(GPULamp *lamp);

@ -103,7 +103,7 @@ struct GPULamp {
Object *par;
Lamp *la;
int type, mode, lay;
int type, mode, lay, hide;
float dynenergy, dyncol[3];
float energy, col[3];
@ -256,7 +256,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
for(nlink=material->lamps.first; nlink; nlink=nlink->next) {
lamp= nlink->data;
if((lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))) {
if(!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))) {
lamp->dynenergy = lamp->energy;
VECCOPY(lamp->dyncol, lamp->col);
}
@ -1310,11 +1310,12 @@ void GPU_materials_free()
/* Lamps and shadow buffers */
void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4])
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4])
{
float mat[4][4];
lamp->lay = lay;
lamp->hide = hide;
copy_m4_m4(mat, obmat);
normalize_m4(mat);
@ -1355,7 +1356,7 @@ static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l
lamp->col[1]= la->g*lamp->energy;
lamp->col[2]= la->b*lamp->energy;
GPU_lamp_update(lamp, ob->lay, ob->obmat);
GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_VIEW), ob->obmat);
lamp->spotsi= la->spotsize;
if(lamp->mode & LA_HALO)

@ -156,7 +156,10 @@ static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
src->pub.next_input_byte = src->pub.next_input_byte + num_bytes;
if(num_bytes > 0) {
src->pub.next_input_byte = src->pub.next_input_byte + num_bytes;
src->pub.bytes_in_buffer = src->pub.bytes_in_buffer - num_bytes;
}
}

@ -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)
@ -47,6 +47,11 @@
#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;
/*

@ -105,6 +105,7 @@ static void rna_FluidSettings_update_type(Main *bmain, Scene *scene, PointerRNA
psys->part= part;
psys->pointcache= BKE_ptcache_add(&psys->ptcaches);
psys->flag |= PSYS_ENABLED;
sprintf(psys->name, "FluidParticles");
BLI_addtail(&ob->particlesystem,psys);
/* add modifier */

@ -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,31 @@ 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;
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:

@ -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, "Border Collisions", "Selects which domain border will be treated as collision object.");
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)

@ -207,7 +207,9 @@ void BPY_start_python_path(void)
{
static wchar_t py_path_bundle_wchar[FILE_MAX];
/* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */ /* cant use this, on linux gives bug: #23018 */
/* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */
/* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */
utf8towchar(py_path_bundle_wchar, py_path_bundle);
Py_SetPythonHome(py_path_bundle_wchar);

@ -66,7 +66,7 @@ KX_LightObject::~KX_LightObject()
if((lamp = GetGPULamp())) {
float obmat[4][4] = {{0}};
GPU_lamp_update(lamp, 0, obmat);
GPU_lamp_update(lamp, 0, 0, obmat);
}
m_rendertools->RemoveLight(&m_lightobj);
@ -199,7 +199,7 @@ void KX_LightObject::Update()
for(int j=0; j<4; j++, dobmat++)
obmat[i][j] = (float)*dobmat;
GPU_lamp_update(lamp, m_lightobj.m_layer, obmat);
GPU_lamp_update(lamp, m_lightobj.m_layer, 0, obmat);
GPU_lamp_update_colors(lamp, m_lightobj.m_red, m_lightobj.m_green,
m_lightobj.m_blue, m_lightobj.m_energy);
}

@ -91,8 +91,8 @@ void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
void RAS_VAOpenGLRasterizer::Exit()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);