Some User UI changes: a) Don't ask the user anymore if he wants to overwrite the file when he's doing a simple ctrl-s/ctrl-w; b) Ask for saving on exit when a file has changed, ontheless quit.blend is saved anyway. --> All branch changes, not likely to go into trunk

This commit is contained in:
Daniel Genrich 2007-12-18 16:54:12 +00:00
parent cf59579d44
commit 3bf1536f5e
13 changed files with 3551 additions and 2093 deletions

@ -70,6 +70,7 @@ extern void BKE_reset_undo(void);
extern char *BKE_undo_menu_string(void); extern char *BKE_undo_menu_string(void);
extern void BKE_undo_number(int nr); extern void BKE_undo_number(int nr);
extern void BKE_undo_save_quit(void); extern void BKE_undo_save_quit(void);
extern int BKE_undo_there(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -60,6 +60,18 @@ struct ClothModifierData;
#define CLOTH_MAX_THREAD 2 #define CLOTH_MAX_THREAD 2
typedef struct fc
{
float *d, *d0; // density
float *T, *T0; // temperature
float *u, *u0; // velocity in x direction
float *v, *v0; // velocity in y direction
float *w, *w0; // velocity in z direction
} fc;
fc *f_init(void);
void f_free(fc *m_fc);
void step(fc *m_fc, float dt);
typedef struct ClothVertex { typedef struct ClothVertex {
int flags; /* General flags per vertex. */ int flags; /* General flags per vertex. */
@ -69,6 +81,7 @@ typedef struct ClothVertex {
unsigned int impulse_count; /* same as above */ unsigned int impulse_count; /* same as above */
float collball; float collball;
char octantflag; char octantflag;
float weight;
} ClothVertex; } ClothVertex;
typedef struct ClothSpring { typedef struct ClothSpring {
@ -104,6 +117,7 @@ typedef struct Cloth {
float (*v)[4]; /* the current velocity of all vertices */ float (*v)[4]; /* the current velocity of all vertices */
float (*current_v)[3]; float (*current_v)[3];
float (*xconst)[3]; float (*xconst)[3];
struct fc *m_fc;
} Cloth; } Cloth;
/* goal defines */ /* goal defines */

@ -85,6 +85,7 @@
#include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature #include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
#include "BKE_utildefines.h" // O_BINARY FALSE #include "BKE_utildefines.h" // O_BINARY FALSE
#include "BIF_mainqueue.h" // mainqenter for onload script #include "BIF_mainqueue.h" // mainqenter for onload script
#include "BIF_toolbox.h"
#include "mydevice.h" #include "mydevice.h"
#include "nla.h" #include "nla.h"
#include "blendef.h" #include "blendef.h"
@ -617,6 +618,10 @@ void BKE_write_undo(char *name)
success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err); success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
} }
/* signals "file needs save" on exit */
if(curundo!=NULL && curundo->prev!=NULL)
U.uiflag |= USER_UNDOSAVE;
} }
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ /* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */

@ -78,6 +78,22 @@
#include "BIF_space.h" #include "BIF_space.h"
#include "mydevice.h" #include "mydevice.h"
#ifdef WIN32
#include <windows.h>
#endif // WIN32
#ifdef __APPLE__
#define GL_GLEXT_LEGACY 1
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#if defined(__sun__) && !defined(__sparc__)
#include <mesa/glu.h>
#else
#include <GL/glu.h>
#endif
#endif
#ifdef _WIN32 #ifdef _WIN32
void tstart ( void ) void tstart ( void )
{} {}
@ -482,6 +498,309 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
return ret; return ret;
} }
#define AMBIENT 50
#define DECAY 0.04f
#define ALMOST_EQUAL(a, b) ((fabs(a-b)<0.00001f)?1:0)
// cube vertices
GLfloat cv[][3] = {
{1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
{1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
};
// edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
float edges[12][2][3] = {
{{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
{{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
{{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}
};
void light_ray(unsigned char* _texture_data, int _ray_templ[4096][3], int x, int y, int z, int n, float decay)
{
int xx = x, yy = y, zz = z, i = 0;
int offset;
int l = 255;
float d;
do {
offset = ((((zz*n) + yy)*n + xx) << 2);
if (_texture_data[offset + 2] > 0)
_texture_data[offset + 2] = (unsigned char) ((_texture_data[offset + 2] + l)*0.5f);
else
_texture_data[offset + 2] = (unsigned char) l;
d = _texture_data[offset+1];
if (l > AMBIENT) {
l -= d*decay;
if (l < AMBIENT)
l = AMBIENT;
}
i++;
xx = x + _ray_templ[i][0];
yy = y + _ray_templ[i][1];
zz = z + _ray_templ[i][2];
} while ((xx>=0)&&(xx<n)&&(yy>=0)&&(yy<n)&&(zz>=0)&&(zz<n));
}
void cast_light(unsigned char* _texture_data, int _ray_templ[4096][3], float *_light_dir, int n /*edgelen*/)
{
int i,j;
int sx = (_light_dir[0]>0) ? 0 : n-1;
int sy = (_light_dir[1]>0) ? 0 : n-1;
int sz = (_light_dir[2]>0) ? 0 : n-1;
float decay = 1.0f/(n*DECAY);
for (i=0; i<n; i++)
for (j=0; j<n; j++) {
if (!ALMOST_EQUAL(_light_dir[0], 0))
light_ray(_texture_data, _ray_templ, sx,i,j,n,decay);
if (!ALMOST_EQUAL(_light_dir[1], 0))
light_ray(_texture_data, _ray_templ, i,sy,j,n,decay);
if (!ALMOST_EQUAL(_light_dir[2], 0))
light_ray(_texture_data, _ray_templ, i,j,sz,n,decay);
}
}
void gen_ray_templ(int _ray_templ[4096][3], float *_light_dir, int edgelen)
{
float fx = 0.0f, fy = 0.0f, fz = 0.0f;
int x = 0, y = 0, z = 0;
float lx = _light_dir[0] + 0.000001f, ly = _light_dir[1] + 0.000001f, lz = _light_dir[2] + 0.000001f;
int xinc = (lx > 0) ? 1 : -1;
int yinc = (ly > 0) ? 1 : -1;
int zinc = (lz > 0) ? 1 : -1;
float tx, ty, tz;
int i = 1;
int len = 0;
int maxlen = 3*edgelen*edgelen;
_ray_templ[0][0] = _ray_templ[0][2] = _ray_templ[0][2] = 0;
while (len <= maxlen)
{
// fx + t*lx = (x+1) -> t = (x+1-fx)/lx
tx = (x+xinc-fx)/lx;
ty = (y+yinc-fy)/ly;
tz = (z+zinc-fz)/lz;
if ((tx<=ty)&&(tx<=tz)) {
_ray_templ[i][0] = _ray_templ[i-1][0] + xinc;
x =+ xinc;
fx = x;
if (ALMOST_EQUAL(ty,tx)) {
_ray_templ[i][1] = _ray_templ[i-1][1] + yinc;
y += yinc;
fy = y;
} else {
_ray_templ[i][1] = _ray_templ[i-1][1];
fy += tx*ly;
}
if (ALMOST_EQUAL(tz,tx)) {
_ray_templ[i][2] = _ray_templ[i-1][2] + zinc;
z += zinc;
fz = z;
} else {
_ray_templ[i][2] = _ray_templ[i-1][2];
fz += tx*lz;
}
} else if ((ty<tx)&&(ty<=tz)) {
_ray_templ[i][0] = _ray_templ[i-1][0];
fx += ty*lx;
_ray_templ[i][1] = _ray_templ[i-1][1] + yinc;
y += yinc;
fy = y;
if (ALMOST_EQUAL(tz,ty)) {
_ray_templ[i][2] = _ray_templ[i-1][2] + zinc;
z += zinc;
fz = z;
} else {
_ray_templ[i][2] = _ray_templ[i-1][2];
fz += ty*lz;
}
} else {
// assert((tz<tx)&&(tz<ty));
if((tz<tx)&&(tz<ty))
break;
_ray_templ[i][0] = _ray_templ[i-1][0];
fx += tz*lx;
_ray_templ[i][1] = _ray_templ[i-1][1];
fy += tz*ly;
_ray_templ[i][2] = _ray_templ[i-1][2] + zinc;
z += zinc;
fz = z;
}
len = _ray_templ[i][0]*_ray_templ[i][0]
+ _ray_templ[i][1]*_ray_templ[i][1]
+ _ray_templ[i][2]*_ray_templ[i][2];
i++;
}
}
/*
int intersect_edges(float ret[12][3], float a, float b, float c, float d)
{
int i;
float t;
Vec3 p;
int num = 0;
for (i=0; i<12; i++) {
t = -(a*edges[i][0][0] + b*edges[i][0][1] + c*edges[i][0][2] + d)
/ (a*edges[i][1][0] + b*edges[i][1][1] + c*edges[i][1][2]);
if ((t>0)&&(t<2)) {
ret[num][0] = edges[i][0][0] + edges[i][1][0]*t;
ret[num][1] = edges[i][0][1] + edges[i][1][1]*t;
ret[num][2] = edges[i][0][2] + edges[i][1][2]*t;
num++;
}
}
return num;
}
void draw_slices(float m[][4])
{
int i;
Vec3 viewdir(m[0][2], m[1][2], m[2][2]);
viewdir.Normalize();
// find cube vertex that is closest to the viewer
for (i=0; i<8; i++) {
float x = cv[i][0] + viewdir[0];
float y = cv[i][1] + viewdir[1];
float z = cv[i][2] + viewdir[2];
if ((x>=-1.0f)&&(x<=1.0f)
&&(y>=-1.0f)&&(y<=1.0f)
&&(z>=-1.0f)&&(z<=1.0f))
{
break;
}
}
if(i != 8) return;
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDisable(GL_DEPTH_TEST);
// our slices are defined by the plane equation a*x + b*y +c*z + d = 0
// (a,b,c), the plane normal, are given by viewdir
// d is the parameter along the view direction. the first d is given by
// inserting previously found vertex into the plane equation
float d0 = -(viewdir[0]*cv[i][0] + viewdir[1]*cv[i][1] + viewdir[2]*cv[i][2]);
float dd = 2*d0/64.0f;
int n = 0;
for (float d = -d0; d < d0; d += dd) {
// intersect_edges returns the intersection points of all cube edges with
// the given plane that lie within the cube
float pt[12][3];
int num = intersect_edges(pt, viewdir[0], viewdir[1], viewdir[2], d);
if (num > 2) {
// sort points to get a convex polygon
// std::sort(pt.begin()+1, pt.end(), Convexcomp(pt[0], viewdir));
int shuffled = 1;
while(shuffled)
{
int j;
shuffled = 0;
for(j = 0; j < num-1; j++)
{
// Vec3 va = a-p0, vb = b-p0;
// return dot(up, cross(va, vb)) >= 0;
float va[3], vb[3], vc[3];
VECSUB(va, pt[j], pt[0]);
VECSUB(vb, pt[j+1], pt[0]);
Crossf(vc, va, vb);
if(INPR(viewdir, vc)>= 0)
{
float temp[3];
VECCOPY(temp, pt[j]);
VECCOPY(pt[j], pt[j+1]);
VECCOPY(pt[j+1], temp);
shuffled = 1;
}
}
}
glEnable(GL_TEXTURE_3D);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _prog[0]);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_3D, _txt[0]);
glBegin(GL_POLYGON);
for (i=0; i<num; i++){
glColor3f(1.0, 1.0, 1.0);
glTexCoord3d((pt[i][0]+1.0)/2.0, (-pt[i][1]+1)/2.0, (pt[i][2]+1.0)/2.0);
glVertex3f(pt[i][0], pt[i][1], pt[i][2]);
}
glEnd();
}
n++;
}
}
void draw(void)
{
int i;
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, -_dist, 0, 0, 0, 0, 1, 0);
float m[4][4];
build_rotmatrix(m, _quat);
glMultMatrixf(&m[0][0]);
if (_draw_cube)
draw_cube();
draw_slices(m, _draw_slice_outline);
if (_dispstring != NULL) {
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(_ortho_m);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_3D);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
glColor4f(1.0, 1.0, 1.0, 1.0);
glRasterPos2i(-_sx/2 + 10, _sy/2 - 15);
print_string(_dispstring);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(_persp_m);
glMatrixMode(GL_MODELVIEW);
}
}*/
/************************************************ /************************************************
* clothModifier_do - main simulation function * clothModifier_do - main simulation function
************************************************/ ************************************************/
@ -500,6 +819,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
ListBase *effectors = NULL; ListBase *effectors = NULL;
float deltaTime = current_time - clmd->sim_parms->sim_time; float deltaTime = current_time - clmd->sim_parms->sim_time;
unsigned char* _texture_data=NULL;
float _light_dir[3];
int _ray_templ[4096][3];
clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec); clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec);
@ -577,7 +899,14 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
cloth = clmd->clothObject; cloth = clmd->clothObject;
} }
/*
deltaTime = 0;
while( deltaTime < 1.0)
{
step(cloth->m_fc, 0.1);
deltaTime+=0.1;
}
*/
clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type; clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type;
// Insure we have a clmd->clothObject, in case allocation failed. // Insure we have a clmd->clothObject, in case allocation failed.
@ -632,6 +961,34 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
} }
} }
cloth = clmd->clothObject;
/*
if(cloth)
{
if (_texture_data == NULL)
_texture_data = (unsigned char*) malloc((30+2)*(30+2)*(30+2)*4);
for (i=0; i<(30+2)*(30+2)*(30+2); i++) {
_texture_data[(i<<2)] = (unsigned char) (cloth->m_fc->T[i] * 255.0f);
_texture_data[(i<<2)+1] = (unsigned char) (cloth->m_fc->d[i] * 255.0f);
_texture_data[(i<<2)+2] = 0;
_texture_data[(i<<2)+3] = 255;
}
// from ligth constructor
_light_dir[0] = -1.0f;
_light_dir[1] = 0.5f;
_light_dir[2] = 0.0f;
gen_ray_templ(_ray_templ, _light_dir, 30 + 2);
cast_light(_texture_data, _ray_templ, _light_dir, 30+2);
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, _texture_data);
free(_texture_data);
}
*/
return result; return result;
} }
@ -653,6 +1010,8 @@ void cloth_free_modifier (ClothModifierData *clmd)
if (cloth) if (cloth)
{ {
f_free(cloth->m_fc);
// If our solver provides a free function, call it // If our solver provides a free function, call it
if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free)
{ {
@ -834,6 +1193,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
unsigned int numverts = dm->getNumVerts(dm); unsigned int numverts = dm->getNumVerts(dm);
MVert *mvert = CDDM_get_verts(dm); MVert *mvert = CDDM_get_verts(dm);
float tnull[3] = {0,0,0}; float tnull[3] = {0,0,0};
Cloth *cloth = NULL;
/* If we have a clothObject, free it. */ /* If we have a clothObject, free it. */
if (clmd->clothObject != NULL) if (clmd->clothObject != NULL)
@ -852,6 +1212,10 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
return 0; return 0;
} }
cloth = clmd->clothObject;
cloth->m_fc = f_init();
switch (ob->type) switch (ob->type)
{ {
case OB_MESH: case OB_MESH:
@ -1228,3 +1592,333 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
* SPRING NETWORK BUILDING IMPLEMENTATION END * SPRING NETWORK BUILDING IMPLEMENTATION END
***************************************************************************************/ ***************************************************************************************/
#define F_ITER 20
#define m_diffusion 0.00001f
#define m_viscosity 0.000f
#define m_buoyancy 1.5f
#define m_cooling 1.0f
#define m_vc_eps 4.0f
#define GRID_SIZE 30
#define SIZE ((GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2))
#define _I(x,y,z) (((z)<<10)+((y)<<5)+x)
#define SWAPFPTR(x,y) {float *t=x;x=y;y=t;}
float buffers[10][SIZE];
float sd[SIZE], su[SIZE], sv[SIZE], sw[SIZE], sT[SIZE];
// nothing to do in this mode
// add code for 2nd mode
void set_bnd(int b, float* x, int N)
{
}
void lin_solve(int b, float *x, float *x0, float a, float c, int N)
{
float cRecip = 1.0 / c;
int i, j, k, l;
for (l=0; l<F_ITER; l++)
{
for (k=1; k<=N; k++)
{
for (j=1; j<=N; j++)
{
for (i=1; i<=N; i++)
{
x[_I(i,j,k)] = (x0[_I(i,j,k)] + a*(
x[_I(i-1,j,k)]+x[_I(i+1,j,k)]+
x[_I(i,j-1,k)]+x[_I(i,j+1,k)]+
x[_I(i,j,k-1)]+x[_I(i,j,k+1)]))*cRecip;
}
}
}
set_bnd(b, x, N);
}
}
void add_source(float* src, float *dst, float dt, int N)
{
int i, size=(N+2)*(N+2)*(N+2);
for (i=0; i<size; i++)
dst[i] += src[i]*dt;
}
void add_buoyancy(float *v, float* T, float dt, float buoyancy, int N)
{
int i, size=(N+2)*(N+2)*(N+2);
for (i=0; i<size; i++)
v[i] += -T[i]*buoyancy*dt;
}
void diffuse(int b, float* x0, float* x, float diff, float dt, int N)
{
float a=dt*diff*N*N*N;
lin_solve(b, x, x0, a, 1 + 6 * a, N);
}
void advect(int b, float* x0, float* x, float* uu, float* vv, float* ww, float dt, int N)
{
int i, j, k, i0, j0, k0, i1, j1, k1;
float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1;
float xx, yy, zz, dt0;
dt0 = dt*N;
for (k=1; k<=N; k++)
{
for (j=1; j<=N; j++)
{
for (i=1; i<=N; i++)
{
xx = i-dt0*uu[_I(i,j,k)];
yy = j-dt0*vv[_I(i,j,k)];
zz = k-dt0*ww[_I(i,j,k)];
if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1;
if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1;
if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1;
sx1 = xx-i0; sx0 = 1-sx1;
sy1 = yy-j0; sy0 = 1-sy1;
sz1 = zz-k0; sz0 = 1-sz1;
v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]);
v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]);
x[_I(i,j,k)] = sz0*v0 + sz1*v1;
}
}
}
set_bnd(b,x, N);
}
void advect_cool(int b, float* x0, float* x, float* y0, float* y, float* uu, float* vv, float* ww, float dt, float cooling, int N)
{
int i, j, k, i0, j0, k0, i1, j1, k1;
float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1;
float xx, yy, zz, dt0, c0;
dt0 = dt*N;
c0 = 1.0f - cooling*dt;
for (k=1; k<=N; k++)
{
for (j=1; j<=N; j++)
{
for (i=1; i<=N; i++)
{
xx = i-dt0*uu[_I(i,j,k)];
yy = j-dt0*vv[_I(i,j,k)];
zz = k-dt0*ww[_I(i,j,k)];
if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1;
if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1;
if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1;
sx1 = xx-i0; sx0 = 1-sx1;
sy1 = yy-j0; sy0 = 1-sy1;
sz1 = zz-k0; sz0 = 1-sz1;
v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]);
v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]);
x[_I(i,j,k)] = sz0*v0 + sz1*v1;
v0 = sx0*(sy0*y0[_I(i0,j0,k0)]+sy1*y0[_I(i0,j1,k0)])+sx1*(sy0*y0[_I(i1,j0,k0)]+sy1*y0[_I(i1,j1,k0)]);
v1 = sx0*(sy0*y0[_I(i0,j0,k1)]+sy1*y0[_I(i0,j1,k1)])+sx1*(sy0*y0[_I(i1,j0,k1)]+sy1*y0[_I(i1,j1,k1)]);
y[_I(i,j,k)] = (sz0*v0 + sz1*v1)*c0;
}
}
}
set_bnd(b,x, N);
set_bnd(b,y, N);
}
void fproject(float* u, float* u0, float* v, float* v0, float* w, float* w0, int N)
{
float* p = u0; float* div = v0; // temporary buffers, use old velocity buffers
int i, j, k;
float h;
h = 1.0f/N;
for (k=1; k<=N; k++) {
for (j=1; j<=N; j++) {
for (i=1; i<=N; i++) {
div[_I(i,j,k)] = -h*(
u[_I(i+1,j,k)]-u[_I(i-1,j,k)]+
v[_I(i,j+1,k)]-v[_I(i,j-1,k)]+
w[_I(i,j,k+1)]-w[_I(i,j,k-1)])*0.5;
p[_I(i,j,k)] = 0;
}
}
}
set_bnd(0, div, N);
set_bnd(0, p, N);
lin_solve(0, p, div, 1, 6, N);
for (k=1; k<=N; k++) {
for (j=1; j<=N; j++) {
for (i=1; i<=N; i++) {
u[_I(i,j,k)] -= (p[_I(i+1,j,k)]-p[_I(i-1,j,k)])*0.5*N;
v[_I(i,j,k)] -= (p[_I(i,j+1,k)]-p[_I(i,j-1,k)])*0.5*N;
w[_I(i,j,k)] -= (p[_I(i,j,k+1)]-p[_I(i,j,k-1)])*0.5*N;
}
}
}
set_bnd(1, u, N);
set_bnd(2, v, N);
set_bnd(3, w, N);
}
void vorticity_confinement(float *T0, float* u, float* u0, float* v, float* v0, float* w, float* w0, float dt, float vc_eps, int N)
{
int i,j,k,ijk;
float *curlx = u0, *curly = v0, *curlz=w0, *curl=T0; // temp buffers
float dt0 = dt * vc_eps;
float x,y,z;
for (k=1; k<N; k++) {
for (j=1; j<N; j++) {
for (i=1; i<N; i++) {
ijk = _I(i,j,k);
// curlx = dw/dy - dv/dz
x = curlx[ijk] = (w[_I(i,j+1,k)] - w[_I(i,j-1,k)]) * 0.5f -
(v[_I(i,j,k+1)] - v[_I(i,j,k-1)]) * 0.5f;
// curly = du/dz - dw/dx
y = curly[ijk] = (u[_I(i,j,k+1)] - u[_I(i,j,k-1)]) * 0.5f -
(w[_I(i+1,j,k)] - w[_I(i-1,j,k)]) * 0.5f;
// curlz = dv/dx - du/dy
z = curlz[ijk] = (v[_I(i+1,j,k)] - v[_I(i-1,j,k)]) * 0.5f -
(u[_I(i,j+1,k)] - u[_I(i,j-1,k)]) * 0.5f;
// curl = |curl|
curl[ijk] = sqrtf(x*x+y*y+z*z);
}
}
}
for (k=1; k<N; k++) {
for (j=1; j<N; j++) {
for (i=1; i<N; i++) {
float Nx = (curl[_I(i+1,j,k)] - curl[_I(i-1,j,k)]) * 0.5f;
float Ny = (curl[_I(i,j+1,k)] - curl[_I(i,j-1,k)]) * 0.5f;
float Nz = (curl[_I(i,j,k+1)] - curl[_I(i,j,k-1)]) * 0.5f;
float len1 = 1.0f/(sqrtf(Nx*Nx+Ny*Ny+Nz*Nz)+0.0000001f);
ijk = _I(i,j,k);
Nx *= len1;
Ny *= len1;
Nz *= len1;
u[ijk] += (Ny*curlz[ijk] - Nz*curly[ijk]) * dt0;
v[ijk] += (Nz*curlx[ijk] - Nx*curlz[ijk]) * dt0;
w[ijk] += (Nx*curly[ijk] - Ny*curlx[ijk]) * dt0;
}
}
}
}
#define DIFFUSE
#define ADVECT
void vel_step(float *su, float *sv, float *sw, float* u, float* u0, float* v, float* v0, float* w, float* w0, float *T, float *T0, float dt, int N)
{
add_source(su, u, dt, N);
add_source(sv, v, dt, N);
add_source(sw, w, dt, N);
// external force
add_buoyancy(v, T, dt, m_buoyancy, N); // better is using gravity normal vector instead of v
vorticity_confinement(T0, u, u0, v, v0, w, w0, dt, m_vc_eps, N);
#ifdef DIFFUSE
SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w);
diffuse(1, u0, u, m_viscosity, dt, N);
diffuse(2, v0, v, m_viscosity, dt, N);
diffuse(3, w0, w, m_viscosity, dt, N);
fproject(u, u0, v, v0, w, w0, N);
#endif
#ifdef ADVECT
SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w);
advect(1, u0, u, u0, v0, w0, dt, N);
advect(2, v0, v, u0, v0, w0, dt, N);
advect(3, w0, w, u0, v0, w0, dt, N);
fproject(u, u0, v, v0, w, w0, N);
#endif
}
void dens_step(float *sd, float *d, float *d0, float *u, float *v, float *w, float dt, int N)
{
add_source(sd, d, dt, N);
#ifdef DIFFUSE
SWAPFPTR(d0, d);
diffuse(0, d0, d, m_diffusion, dt, N);
#endif
#ifdef ADVECT
SWAPFPTR(d0, d);
advect(0, d0, d, u, v, w, dt, N);
#endif
}
void dens_temp_step(float *sd, float *sT, float *T, float *T0, float *d, float *d0, float *u, float *v, float *w, float dt, int N)
{
add_source(sd, d, dt, N);
add_source(sT, T, dt, N);
SWAPFPTR(d0, d);
diffuse(0, d0, d, m_diffusion, dt, N);
SWAPFPTR(d0, d);
SWAPFPTR(T0, T);
advect_cool(0, d0, d, T0, T, u, v, w, dt, m_cooling, N);
}
void step(fc *m_fc, float dt)
{
vel_step(su, sv, sw, m_fc->u, m_fc->u0, m_fc->v, m_fc->v0, m_fc->w, m_fc->w0, m_fc->T, m_fc->T0, dt, GRID_SIZE);
dens_temp_step(sd, sT, m_fc->T, m_fc->T0, m_fc->d, m_fc->d0, m_fc->u, m_fc->v, m_fc->w, dt, GRID_SIZE);
}
void clear_buffer(float* x)
{
int i;
for (i=0; i<SIZE; i++) {
x[i] = 0.0f;
}
}
void clear_sources(float *sd, float *su, float *sv)
{
int i;
for (i=0; i<SIZE; i++) {
sd[i] = su[i] = sv[i] = 0.0f;
}
}
fc *f_init(void)
{
int i;
int size;
fc *m_fc = MEM_callocN(sizeof(fc),
"f_c");
for (i=0; i<10; i++)
clear_buffer(buffers[i]);
i=0;
m_fc->d=buffers[i++]; m_fc->d0=buffers[i++];
m_fc->T=buffers[i++]; m_fc->T0=buffers[i++];
m_fc->u=buffers[i++]; m_fc->u0=buffers[i++];
m_fc->v=buffers[i++]; m_fc->v0=buffers[i++];
m_fc->w=buffers[i++]; m_fc->w0=buffers[i++];
clear_sources(sd, su, sv);
size=(GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2);
for (i=0; i<size; i++)
m_fc->v[i] = -0.5f;
return m_fc;
}
void f_free(fc *m_fc)
{
if(m_fc)
MEM_freeN(m_fc);
}

@ -1630,12 +1630,13 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod
float magrelVel = 0.0; float magrelVel = 0.0;
float epsilon = clmd->coll_parms->epsilon; float epsilon = clmd->coll_parms->epsilon;
return 0;
cloth1 = clmd->clothObject; cloth1 = clmd->clothObject;
if(!collpair) if(!collpair)
{
return 0; return 0;
}
// TODO: check distance & calc normal // TODO: check distance & calc normal
// calc distance + normal // calc distance + normal
@ -1650,9 +1651,12 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod
if (collpair->distance > (epsilon + ALMOST_ZERO)) if (collpair->distance > (epsilon + ALMOST_ZERO))
{ {
printf("collpair->distance > (epsilon + ALMOST_ZERO)\n");
return 0; return 0;
} }
printf("IN1\n");
// compute barycentric coordinates for both collision points // compute barycentric coordinates for both collision points
collisions_compute_barycentric (collpair->pa, collisions_compute_barycentric (collpair->pa,
cloth1->current_xold[collpair->point_indexA[0]], cloth1->current_xold[collpair->point_indexA[0]],
@ -1683,6 +1687,8 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod
// If v_n_mag < 0 the edges are approaching each other. // If v_n_mag < 0 the edges are approaching each other.
if ( magrelVel < -ALMOST_ZERO ) if ( magrelVel < -ALMOST_ZERO )
{ {
printf("magrelVel < -ALMOST_ZERO\n");
// Calculate Impulse magnitude to stop all motion in normal direction. // Calculate Impulse magnitude to stop all motion in normal direction.
// const double I_mag = v_n_mag / (1/m1 + 1/m2); // const double I_mag = v_n_mag / (1/m1 + 1/m2);
float magnitude_i = magrelVel / 2.0f; // TODO implement masses float magnitude_i = magrelVel / 2.0f; // TODO implement masses
@ -2162,6 +2168,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
int collisions = 0, count = 0; int collisions = 0, count = 0;
float (*current_x)[3]; float (*current_x)[3];
Implicit_Data *id = NULL; Implicit_Data *id = NULL;
int ret = 0;
if (!(((Cloth *)clmd->clothObject)->tree)) if (!(((Cloth *)clmd->clothObject)->tree))
{ {
@ -2234,6 +2241,24 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
} }
} }
// vertex weight = 2
for(i = 0; i < cloth->numverts; i++)
if ((cloth->verts[i].impulse_count > 0) && !(cloth->verts[i].flags & CVERT_FLAG_PINNED))
{
printf("applying impulse\n");
VECADDS(cloth->current_v[i], cloth->current_v[i], cloth->verts[i].impulse, 1.0 / (cloth->verts[i].impulse_count * 2.0));
// reset
cloth->verts[i].impulse_count = 0;
cloth->verts[i].impulse[0] = 0.0;
cloth->verts[i].impulse[1] = 0.0;
cloth->verts[i].impulse[2] = 0.0;
ret = 1;
}
////////////////////////////////////////////// //////////////////////////////////////////////
// update velocities + positions // update velocities + positions
////////////////////////////////////////////// //////////////////////////////////////////////
@ -2243,78 +2268,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
} }
////////////////////////////////////////////// //////////////////////////////////////////////
/*
// fill collision list
collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list);
// call static collision response
// free collision list
if(collision_list)
{
LinkNode *search = collision_list;
while(search)
{
float distance = 0;
float mindistance = cloth->selftree->epsilon;
CollisionPair *collpair = (CollisionPair *)search->link;
// get distance of faces
distance = plNearestPoints(
cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[2]], collpair->pa,collpair->pb,collpair->vector);
if(distance < mindistance)
{
///////////////////////////////////////////
// TODO: take velocity of the collision points into account!
///////////////////////////////////////////
float correction = mindistance - distance;
float temp[3];
VECCOPY(temp, collpair->vector);
Normalize(temp);
VecMulf(temp, -correction*0.5);
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[0]].goal >= SOFTGOALSNAP)))
VECSUB(cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[0]], temp);
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[1]].goal >= SOFTGOALSNAP)))
VECSUB(cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[1]], temp);
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[2]].goal >= SOFTGOALSNAP)))
VECSUB(cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexA[2]], temp);
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[0]].goal >= SOFTGOALSNAP)))
VECSUB(cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[0]], temp);
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[1]].goal >= SOFTGOALSNAP)))
VECSUB(cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[1]], temp);
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[2]].goal >= SOFTGOALSNAP)))
VECSUB(cloth->current_x[collpair->point_indexB[2]], cloth->current_x[collpair->point_indexB[2]], temp);
collisions = 1;
}
}
search = collision_list;
while(search)
{
CollisionPair *coll_pair = search->link;
MEM_freeN(coll_pair);
search = search->next;
}
BLI_linklist_free(collision_list,NULL);
collision_list = NULL;
}
*/
// Test on *simple* selfcollisions // Test on *simple* selfcollisions
collisions = 1; collisions = 1;
count = 0; count = 0;
@ -2409,5 +2363,5 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
*/ */
////////////////////////////////////////////// //////////////////////////////////////////////
return 0; return ret;
} }

@ -915,6 +915,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
// of list are horrible slow! // of list are horrible slow!
BLI_linklist_prepend(&collision_list[0], collpair); BLI_linklist_prepend(&collision_list[0], collpair);
} }
return 1; return 1;
} }
else else

@ -5187,6 +5187,8 @@ static void collisionModifier_deformVerts(
// recalc static bounding boxes // recalc static bounding boxes
bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
printf("bvh_update_from_mvert\n");
} }
collmd->time = current_time; collmd->time = current_time;

@ -259,6 +259,7 @@ extern UserDef U; /* from usiblender.c !!!! */
#define USER_KEYINSERTNEED (1 << 19) #define USER_KEYINSERTNEED (1 << 19)
#define USER_ZOOM_TO_MOUSEPOS (1 << 20) #define USER_ZOOM_TO_MOUSEPOS (1 << 20)
#define USER_SHOW_FPS (1 << 21) #define USER_SHOW_FPS (1 << 21)
#define USER_UNDOSAVE (1 << 22) // flag to signal a write_undo() call after a save (save on exit needed then)
/* transopts */ /* transopts */

File diff suppressed because it is too large Load Diff

@ -78,7 +78,6 @@
#include "BIF_usiblender.h" #include "BIF_usiblender.h"
#include "BIF_writeimage.h" #include "BIF_writeimage.h"
#include "BIF_drawscene.h" #include "BIF_drawscene.h"
#ifdef WITH_VERSE #ifdef WITH_VERSE
#include "BIF_verse.h" #include "BIF_verse.h"
#endif #endif
@ -830,6 +829,8 @@ static void do_info_filemenu(void *arg, int event)
if (untitled(dir)) { if (untitled(dir)) {
activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file); activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file);
} else { } else {
/* do NOT ask everytime for overwriting... */
G.save_over = 1;
BIF_write_file(dir); BIF_write_file(dir);
free_filesel_spec(dir); free_filesel_spec(dir);
} }

@ -831,6 +831,8 @@ int blenderqread(unsigned short event, short val)
if (untitled(dir)) { if (untitled(dir)) {
activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file); activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
} else { } else {
/* do NOT ask everytime for overwriting... */
G.save_over = 1;
BIF_write_file(dir); BIF_write_file(dir);
free_filesel_spec(dir); free_filesel_spec(dir);
} }
@ -931,6 +933,8 @@ int blenderqread(unsigned short event, short val)
if (untitled(dir)) { if (untitled(dir)) {
activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file); activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
} else { } else {
/* do NOT ask everytime for overwriting... */
G.save_over = 1;
BIF_write_file(dir); BIF_write_file(dir);
free_filesel_spec(dir); free_filesel_spec(dir);
} }

@ -169,6 +169,28 @@ void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
/* this va_ stuff allows printf() style codes in these menus */ /* this va_ stuff allows printf() style codes in these menus */
static int vconfirm_choice(char *title, char *itemfmt, va_list ap)
{
char *s, buf[512];
s= buf;
if (title) s+= sprintf(s, "%s%%t|", title);
vsprintf(s, itemfmt, ap);
return (pupmenu(buf));
}
int confirm_choice(char *title, char *itemfmt, ...)
{
va_list ap;
int ret;
va_start(ap, itemfmt);
ret= vconfirm_choice(title, itemfmt, ap);
va_end(ap);
return ret;
}
static int vconfirm(char *title, char *itemfmt, va_list ap) static int vconfirm(char *title, char *itemfmt, va_list ap)
{ {
char *s, buf[512]; char *s, buf[512];

@ -110,6 +110,7 @@
#include "BIF_resources.h" #include "BIF_resources.h"
#include "BIF_screen.h" #include "BIF_screen.h"
#include "BIF_space.h" #include "BIF_space.h"
#include "BIF_toets.h"
#include "BIF_toolbox.h" #include "BIF_toolbox.h"
#include "BIF_cursors.h" #include "BIF_cursors.h"
@ -793,7 +794,7 @@ void BIF_write_file(char *target)
strcpy(di, target); strcpy(di, target);
} }
if (BLI_exists(di)) { if (BLI_exists(di) && !G.save_over) {
if(!saveover(di)) if(!saveover(di))
return; return;
} }
@ -824,10 +825,14 @@ void BIF_write_file(char *target)
G.save_over = 1; G.save_over = 1;
writeBlog(); writeBlog();
} else { } else {
error("%s", err); error("%s", err);
} }
/* CLEARS signal: "file needs save" on exit */
U.uiflag &= ~USER_UNDOSAVE;
waitcursor(0); waitcursor(0);
} }
@ -927,6 +932,41 @@ void BIF_init(void)
BLI_strncpy(G.lib, G.sce, FILE_MAX); BLI_strncpy(G.lib, G.sce, FILE_MAX);
} }
int exit_save_question(void)
{
char dir[FILE_MAXDIR];
int ret = 0;
/* just go on if no undo there */
/* better check necessary --> some flag */
if(!(U.uiflag & USER_UNDOSAVE))
return 1;
/* do sweet question here */
ret = confirm_choice("Warning: Unsaved changes", "Do you want to save your changes before exit?");
if(ret==1)
{
/* copyied from header_info.c */
strcpy(dir, G.sce);
if (untitled(dir)) {
activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file);
} else {
/* do NOT ask everytime for overwriting... */
G.save_over = 1;
BIF_write_file(dir);
free_filesel_spec(dir);
}
return 1;
}
else
{
/* cancel, ok, continue button available */
}
return 1;
}
/***/ /***/
extern ListBase editNurb; extern ListBase editNurb;
@ -935,6 +975,14 @@ extern ListBase editelems;
void exit_usiblender(void) void exit_usiblender(void)
{ {
struct TmpFont *tf; struct TmpFont *tf;
/* ask for save before exit */
if(!exit_save_question())
{
/* user pressed 'cancel' */
return;
}
tf= G.ttfdata.first; tf= G.ttfdata.first;
while(tf) while(tf)
{ {