Fixed preconditioned conjugate to some degree but some issues left for stiffness>1000 (disabled therefore). There's also some issue with the springs function (some springs seem to be missing/not created)

This commit is contained in:
Daniel Genrich 2007-12-12 17:33:59 +00:00
parent e9c9bf5bdb
commit 42637b7252
16 changed files with 152 additions and 54 deletions

@ -200,7 +200,6 @@ typedef void ( *CM_COLLISION_SELF ) ( struct ClothModifierData *clmd, int step )
// only one available in the moment // only one available in the moment
typedef enum { typedef enum {
CM_IMPLICIT = 0, CM_IMPLICIT = 0,
CM_VERLET = 1,
} CM_SOLVER_ID; } CM_SOLVER_ID;

@ -44,5 +44,6 @@
int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext); int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext);
FILE * BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index); FILE * BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index);
void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index); void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index);
int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index);
#endif #endif

@ -115,7 +115,6 @@ double tval()
static CM_SOLVER_DEF solvers [] = static CM_SOLVER_DEF solvers [] =
{ {
{ "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
// { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free },
}; };
/* ********** cloth engine ******* */ /* ********** cloth engine ******* */
@ -477,6 +476,7 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
fclose(fp); fclose(fp);
} }
if(clmd->sim_parms->solver_type == 0)
implicit_set_positions(clmd); implicit_set_positions(clmd);
return ret; return ret;
@ -600,6 +600,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
tstart(); tstart();
/* Call the solver. */ /* Call the solver. */
if (solvers [clmd->sim_parms->solver_type].solver) if (solvers [clmd->sim_parms->solver_type].solver)
solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors); solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors);
@ -625,6 +626,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
if(cloth_read_cache(ob, clmd, framenr)) if(cloth_read_cache(ob, clmd, framenr))
cloth_to_object (ob, result, clmd); cloth_to_object (ob, result, clmd);
} }
else
{
cloth_clear_cache(ob, clmd, 0);
}
} }
return result; return result;

@ -241,7 +241,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns
unsigned int i = 0; unsigned int i = 0;
float temp = 0.0; float temp = 0.0;
// schedule(guided, 2) // schedule(guided, 2)
#pragma omp parallel for reduction(+: temp) #pragma omp parallel for reduction(+: temp) private(i)
for(i = 0; i < verts; i++) for(i = 0; i < verts; i++)
{ {
temp += INPR(fLongVectorA[i], fLongVectorB[i]); temp += INPR(fLongVectorA[i], fLongVectorB[i]);
@ -558,6 +558,7 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
mul_fmatrix_S(matrix[i].m, scalar); mul_fmatrix_S(matrix[i].m, scalar);
} }
} }
/* SPARSE SYMMETRIC multiply big matrix with long vector*/ /* SPARSE SYMMETRIC multiply big matrix with long vector*/
/* STATUS: verified */ /* STATUS: verified */
DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
@ -590,6 +591,20 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector
} }
/* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */
/* STATUS: verified */
DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
{
unsigned int i = 0;
for(i = 0; i < from[0].vcount; i++)
{
mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
}
}
/* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/
DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
{ {
@ -983,7 +998,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
sub_lfvector_lfvector(r, lB, r, numverts); sub_lfvector_lfvector(r, lB, r, numverts);
filter(r, S); filter(r, S);
mul_bfmatrix_lfvector(p, Pinv, r); mul_prevfmatrix_lfvector(p, Pinv, r);
filter(p, S); filter(p, S);
deltaNew = dot_lfvector(r, p, numverts); deltaNew = dot_lfvector(r, p, numverts);
@ -1005,7 +1020,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
add_lfvector_lfvectorS(r, r, s, -alpha, numverts); add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
mul_bfmatrix_lfvector(h, Pinv, r); mul_prevfmatrix_lfvector(h, Pinv, r);
filter(h, S); filter(h, S);
deltaOld = deltaNew; deltaOld = deltaNew;
@ -1013,6 +1028,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
deltaNew = dot_lfvector(r, h, numverts); deltaNew = dot_lfvector(r, h, numverts);
add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts); add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
filter(p, S); filter(p, S);
} }
@ -1125,6 +1141,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
} }
/*
if(s->type == CLOTH_SPRING_TYPE_COLLISION) if(s->type == CLOTH_SPRING_TYPE_COLLISION)
{ {
if(length < L) if(length < L)
@ -1135,6 +1152,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
} }
return; return;
} }
*/
// calculate force of structural + shear springs // calculate force of structural + shear springs
if(s->type != CLOTH_SPRING_TYPE_BENDING) if(s->type != CLOTH_SPRING_TYPE_BENDING)
@ -1150,7 +1168,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
VECADD(s->f, s->f, stretch_force); VECADD(s->f, s->f, stretch_force);
// Ascher & Boxman, p.21: Damping only during elonglation // Ascher & Boxman, p.21: Damping only during elonglation
mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * ((INPR(vel,extent)/length))); mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * 0.01 * ((INPR(vel,extent)/length)));
VECADD(s->f, s->f, damping_force); VECADD(s->f, s->f, damping_force);
dfdx_spring_type1(s->dfdx, dir,length,L,k); dfdx_spring_type1(s->dfdx, dir,length,L,k);
@ -1171,12 +1189,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
VECADD(s->f, s->f, bending_force); VECADD(s->f, s->f, bending_force);
if(INPR(bending_force,bending_force) > 0.13*0.13) // if(INPR(bending_force,bending_force) > 0.13*0.13)
{ {
clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
} }
dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); dfdx_spring_type2(s->dfdx, dir,length,L,k, cb);
/*
if(s->ij == 300 || s->kl == 300)
printf("id->F[0]: %f, id->F[1]: %f, id->F[2]: %f\n", s->f[0], s->f[1], s->f[2]);
*/
} }
} }
} }
@ -1306,7 +1329,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
float speed[3] = {0.0f, 0.0f,0.0f}; float speed[3] = {0.0f, 0.0f,0.0f};
float force[3]= {0.0f, 0.0f, 0.0f}; float force[3]= {0.0f, 0.0f, 0.0f};
#pragma omp parallel for private (i) shared(lF) // #pragma omp parallel for private (i) shared(lF)
for(i = 0; i < cloth->numverts; i++) for(i = 0; i < cloth->numverts; i++)
{ {
float vertexnormal[3]={0,0,0}; float vertexnormal[3]={0,0,0};
@ -1363,7 +1386,6 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
} }
clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
} }
void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv)
@ -1375,26 +1397,18 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto
zero_lfvector(dV, numverts); zero_lfvector(dV, numverts);
subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts);
// itstart(); // TODO: unstable with quality=5 + stiffness=7000 + no zero_lfvector()
cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */
// TODO: if anyone finds a way to correct this function => // TODO: unstable with quality=5 + stiffness=7000
// explodes with stiffness = 3000 and 16k verts + pinned at 2 corners
// cg_filtered_pre(dV, A, B, z, S, P, Pinv); // cg_filtered_pre(dV, A, B, z, S, P, Pinv);
// itend();
// printf("cg_filtered calc time: %f\n", (float)itval());
// advance velocities // advance velocities
add_lfvector_lfvector(Vnew, lV, dV, numverts); add_lfvector_lfvector(Vnew, lV, dV, numverts);
del_lfvector(dFdXmV); del_lfvector(dFdXmV);
} }
@ -1418,7 +1432,10 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
// update velocities with constrained velocities from pinned verts // update velocities with constrained velocities from pinned verts
if(verts [i].goal >= SOFTGOALSNAP) if(verts [i].goal >= SOFTGOALSNAP)
{ {
VECSUB(id->V[i], cloth->xconst[i], cloth->xold[i]); float temp[3];
VECSUB(temp, cloth->xconst[i], cloth->xold[i]);
VECSUB(id->z[i], temp, id->V[i]);
// VecMulf(id->V[i], 1.0 / dt); // VecMulf(id->V[i], 1.0 / dt);
} }
} }
@ -1613,6 +1630,8 @@ 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)
@ -2143,7 +2162,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;
/*
if (!(((Cloth *)clmd->clothObject)->tree)) if (!(((Cloth *)clmd->clothObject)->tree))
{ {
printf("No BVH found\n"); printf("No BVH found\n");
@ -2223,7 +2242,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]);
} }
////////////////////////////////////////////// //////////////////////////////////////////////
*/
/* /*
// fill collision list // fill collision list
collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list); collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list);

@ -672,14 +672,12 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i
/* step 2: do it */ /* step 2: do it */
kb= key->block.first; for(kb=key->block.first; kb; kb=kb->next) {
while(kb) {
if(kb!=key->refkey) { if(kb!=key->refkey) {
float icuval= kb->curval; float icuval= kb->curval;
/* only with value, and no difference allowed */ /* only with value, and no difference allowed */
if(icuval!=0.0f && kb->totelem==tot) { if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) {
KeyBlock *refb; KeyBlock *refb;
float weight, *weights= kb->weights; float weight, *weights= kb->weights;
@ -738,7 +736,6 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i
} }
} }
} }
kb= kb->next;
} }
} }
@ -1312,6 +1309,9 @@ int do_ob_key(Object *ob)
if(ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)) { if(ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)) {
KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1); KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1);
if(kb && (kb->flag & KEYBLOCK_MUTE))
kb= key->refkey;
if(kb==NULL) { if(kb==NULL) {
kb= key->block.first; kb= key->block.first;
ob->shapenr= 1; ob->shapenr= 1;

@ -4271,7 +4271,7 @@ void psys_to_softbody(Object *ob, ParticleSystem *psys, int force_recalc)
if((psys->softflag&OB_SB_ENABLE)==0) return; if((psys->softflag&OB_SB_ENABLE)==0) return;
if((ob->recalc&OB_RECALC_TIME)==0) if(ob->recalc && (ob->recalc&OB_RECALC_TIME)==0)
psys->softflag|=OB_SB_REDO; psys->softflag|=OB_SB_REDO;
/* let's replace the object's own softbody with the particle softbody */ /* let's replace the object's own softbody with the particle softbody */

@ -183,3 +183,11 @@ void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index)
return; return;
} }
int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index)
{
char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1);
return BLI_exists(filename);
}

@ -44,7 +44,7 @@ typedef struct KeyBlock {
float pos; float pos;
float curval; float curval;
short type, adrcode, relative, pad1; /* relative == 0 means first key is reference */ short type, adrcode, relative, flag; /* relative == 0 means first key is reference */
int totelem, pad2; int totelem, pad2;
void *data; void *data;
@ -87,5 +87,8 @@ typedef struct Key {
#define KEY_CARDINAL 1 #define KEY_CARDINAL 1
#define KEY_BSPLINE 2 #define KEY_BSPLINE 2
/* keyblock->flag */
#define KEYBLOCK_MUTE 1
#endif #endif

@ -85,6 +85,9 @@ static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **i
min = *val; min = *val;
} }
} }
min = MIN2(0.1, min);
max = MAX2(0.9, max);
mult = 1.0f/(max-min); mult = 1.0f/(max-min);
printf("min %f max %f\n", min, max); printf("min %f max %f\n", min, max);

@ -410,7 +410,6 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
return; return;
} }
} }
efa= efa->next;
} }
} }
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
@ -484,7 +483,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
if(ma) { if(ma) {
ob->actcol= find_material_index(ob, ma); ob->actcol= find_material_index(ob, ma);
if(ob->actcol==0) { if(ob->actcol==0) {
assign_material(ob, ma, ob->totcol); assign_material(ob, ma, ob->totcol+1);
ob->actcol= ob->totcol; ob->actcol= ob->totcol;
} }
} }
@ -2474,15 +2473,17 @@ static void editing_panel_shapes(Object *ob)
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT; if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
uiDefIconButBitS(block, TOG, OB_SHAPE_LOCK, B_LOCKKEY, icon, 10,150,25,20, &ob->shapeflag, 0, 0, 0, 0, "Always show the current Shape for this Object"); uiDefIconButBitS(block, TOG, OB_SHAPE_LOCK, B_LOCKKEY, icon, 10,150,25,20, &ob->shapeflag, 0, 0, 0, 0, "Always show the current Shape for this Object");
if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
uiSetButLock(G.obedit==ob, "Unable to perform in EditMode"); uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 35,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key"); uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
strp= make_key_menu(key, 1); strp= make_key_menu(key, 1);
uiDefButS(block, MENU, B_SETKEY, strp, 55,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices"); uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
MEM_freeN(strp); MEM_freeN(strp);
uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 75,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key"); uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
uiClearButLock(); uiClearButLock();
uiDefBut(block, TEX, B_NAMEKEY, "", 95, 150, 190, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name"); uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key"); uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
uiBlockEndAlign(block); uiBlockEndAlign(block);

@ -3298,6 +3298,7 @@ static void object_softbodies__enable(void *ob_v, void *arg2)
if (!ob->soft) { if (!ob->soft) {
ob->soft= sbNew(); ob->soft= sbNew();
ob->softflag |= OB_SB_GOAL|OB_SB_EDGES; ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
softbody_clear_cache(ob, CFRA);
} }
} }
/* needed so that initial state is cached correctly */ /* needed so that initial state is cached correctly */
@ -3331,6 +3332,7 @@ static void object_softbodies__enable_psys(void *ob_v, void *psys_v)
psys->soft= sbNew(); psys->soft= sbNew();
psys->softflag |= OB_SB_GOAL|OB_SB_EDGES; psys->softflag |= OB_SB_GOAL|OB_SB_EDGES;
psys->soft->particles=psys; psys->soft->particles=psys;
clear_particles_from_cache(ob, psys, CFRA);
} }
psys->softflag |= OB_SB_ENABLE; psys->softflag |= OB_SB_ENABLE;
} }

@ -70,6 +70,8 @@
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_meta_types.h" #include "DNA_meta_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_force.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_particle_types.h" #include "DNA_particle_types.h"
#include "DNA_screen_types.h" #include "DNA_screen_types.h"
@ -101,8 +103,10 @@
#include "BKE_key.h" #include "BKE_key.h"
#include "BKE_main.h" #include "BKE_main.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h" #include "BKE_object.h"
#include "BKE_particle.h" #include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h" #include "BKE_scene.h"
#include "BKE_texture.h" #include "BKE_texture.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
@ -3292,10 +3296,50 @@ static void inner_play_prefetch_shutdown(int mode)
seq_stop_threads(); seq_stop_threads();
} }
static int cached_dynamics(int sfra, int efra)
{
Base *base = G.scene->base.first;
Object *ob;
ModifierData *md;
ParticleSystem *psys;
int i, stack_index, cached=1;
while(base && cached) {
ob = base->object;
if(ob->softflag & OB_SB_ENABLE && ob->soft) {
for(i=0, md=ob->modifiers.first; md; i++, md=md->next) {
if(md->type == eModifierType_Softbody) {
stack_index = i;
break;
}
}
for(i=sfra; i<=efra && cached; i++)
cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,psys));
if(psys->part->type==PART_HAIR) {
if(psys->softflag & OB_SB_ENABLE && psys->soft);
else
stack_index = -1;
}
if(stack_index >= 0)
for(i=sfra; i<=efra && cached; i++)
cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
}
base = base->next;
}
return cached;
}
void inner_play_anim_loop(int init, int mode) void inner_play_anim_loop(int init, int mode)
{ {
ScrArea *sa; ScrArea *sa;
static int last_cfra = -1; static int last_cfra = -1;
static int cached = 0;
/* init */ /* init */
if(init) { if(init) {
@ -3304,7 +3348,7 @@ void inner_play_anim_loop(int init, int mode)
tottime= 0.0; tottime= 0.0;
curmode= mode; curmode= mode;
last_cfra = -1; last_cfra = -1;
cached = cached_dynamics(PSFRA,PEFRA);
return; return;
} }
@ -3380,8 +3424,10 @@ void inner_play_anim_loop(int init, int mode)
CFRA = PSFRA; CFRA = PSFRA;
audiostream_stop(); audiostream_stop();
audiostream_start( CFRA ); audiostream_start( CFRA );
cached = cached_dynamics(PSFRA,PEFRA);
} else { } else {
if (U.mixbufsize if (cached
&& U.mixbufsize
&& (G.scene->audio.flag & AUDIO_SYNC)) { && (G.scene->audio.flag & AUDIO_SYNC)) {
CFRA = audiostream_pos(); CFRA = audiostream_pos();
} else { } else {

@ -625,7 +625,7 @@ void insert_shapekey(Object *ob)
void delete_key(Object *ob) void delete_key(Object *ob)
{ {
KeyBlock *kb; KeyBlock *kb, *rkb;
Key *key; Key *key;
IpoCurve *icu; IpoCurve *icu;
@ -635,6 +635,10 @@ void delete_key(Object *ob)
kb= BLI_findlink(&key->block, ob->shapenr-1); kb= BLI_findlink(&key->block, ob->shapenr-1);
if(kb) { if(kb) {
for(rkb= key->block.first; rkb; rkb= rkb->next)
if(rkb->relative == ob->shapenr-1)
rkb->relative= 0;
BLI_remlink(&key->block, kb); BLI_remlink(&key->block, kb);
key->totkey--; key->totkey--;
if(key->refkey== kb) key->refkey= key->block.first; if(key->refkey== kb) key->refkey= key->block.first;

@ -82,6 +82,7 @@ editmesh_mods.c, UI level access, no geometry changes
#include "BIF_interface.h" #include "BIF_interface.h"
#include "BIF_meshtools.h" #include "BIF_meshtools.h"
#include "BIF_mywindow.h" #include "BIF_mywindow.h"
#include "BIF_previewrender.h"
#include "BIF_resources.h" #include "BIF_resources.h"
#include "BIF_screen.h" #include "BIF_screen.h"
#include "BIF_space.h" #include "BIF_space.h"
@ -2126,6 +2127,12 @@ void mouse_mesh(void)
allqueue(REDRAWIMAGE, 0); allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWBUTSEDIT, 0); /* for the texture face panel */ allqueue(REDRAWBUTSEDIT, 0); /* for the texture face panel */
} }
if (efa && efa->mat_nr != G.obedit->actcol-1) {
G.obedit->actcol= efa->mat_nr+1;
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSSHADING, 0);
BIF_preview_changed(ID_MA);
}
} }
rightmouse_transform(); rightmouse_transform();

@ -1703,10 +1703,10 @@ static int remove_tagged_elements(Object *ob, ParticleSystem *psys)
} }
} }
MEM_freeN(psys->particles); if(psys->particles) MEM_freeN(psys->particles);
psys->particles = new_pars; psys->particles = new_pars;
MEM_freeN(edit->keys); if(edit->keys) MEM_freeN(edit->keys);
edit->keys = new_keys; edit->keys = new_keys;
if(edit->mirror_cache) { if(edit->mirror_cache) {
@ -2256,10 +2256,10 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
memcpy(new_keys, edit->keys, totpart * sizeof(ParticleEditKey*)); memcpy(new_keys, edit->keys, totpart * sizeof(ParticleEditKey*));
/* change old arrays to new ones */ /* change old arrays to new ones */
MEM_freeN(psys->particles); if(psys->particles) MEM_freeN(psys->particles);
psys->particles = new_pars; psys->particles = new_pars;
MEM_freeN(edit->keys); if(edit->keys) MEM_freeN(edit->keys);
edit->keys = new_keys; edit->keys = new_keys;
if(edit->mirror_cache) { if(edit->mirror_cache) {
@ -2267,8 +2267,6 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
edit->mirror_cache = NULL; edit->mirror_cache = NULL;
} }
psys->totpart = newtotpart;
/* create tree for interpolation */ /* create tree for interpolation */
if(pset->flag & PE_INTERPOLATE_ADDED && psys->totpart){ if(pset->flag & PE_INTERPOLATE_ADDED && psys->totpart){
tree=BLI_kdtree_new(psys->totpart); tree=BLI_kdtree_new(psys->totpart);
@ -2281,6 +2279,8 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
BLI_kdtree_balance(tree); BLI_kdtree_balance(tree);
} }
psys->totpart = newtotpart;
/* create new elements */ /* create new elements */
pa = psys->particles + totpart; pa = psys->particles + totpart;
key = edit->keys + totpart; key = edit->keys + totpart;
@ -2691,10 +2691,10 @@ void PE_mirror_x(int tagged)
memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData)); memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData));
memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*)); memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*));
MEM_freeN(psys->particles); if(psys->particles) MEM_freeN(psys->particles);
psys->particles= new_pars; psys->particles= new_pars;
MEM_freeN(edit->keys); if(edit->keys) MEM_freeN(edit->keys);
edit->keys= new_keys; edit->keys= new_keys;
if(edit->mirror_cache) { if(edit->mirror_cache) {