diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-04-04 23:50:22 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-04-04 23:50:22 +0400 |
commit | f9e2f6acd761492c52500bf72e32a4ad5a33757b (patch) | |
tree | df44ac89101bf0be263a8d53623c9302dca5e59c /source/blender/blenkernel | |
parent | 65b2ef5b15ae56758f7097df98dbce9ba3fe1454 (diff) | |
parent | 687c752b75bc488b2de5a4186ba2398b31dbb46e (diff) |
Merged changes in the trunk up to revision 27992.
Diffstat (limited to 'source/blender/blenkernel')
28 files changed, 803 insertions, 318 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 214b5a32cd6..4d3f000c863 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -105,6 +105,9 @@ struct bActionGroup *get_active_actiongroup(struct bAction *act); /* Make the given Action Group the active one */ void set_active_action_group(struct bAction *act, struct bActionGroup *agrp, short select); +/* Add a new action group with the given name to the action */ +struct bActionGroup *action_groups_add_new(struct bAction *act, const char name[]); + /* Add given channel into (active) group */ void action_groups_add_channel(struct bAction *act, struct bActionGroup *agrp, struct FCurve *fcurve); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 8865757b85a..64c5823f06f 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -45,7 +45,7 @@ struct Scene; struct Main; #define BLENDER_VERSION 252 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 4 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index a8a0d7daa89..d8b3fcfd0bb 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -126,6 +126,7 @@ typedef struct ClothVertex float mass; /* mass / weight of the vertex */ float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ + float *xrest; /* temporary valid for building springs */ unsigned int impulse_count; /* same as above */ float avg_spring_len; /* average length of connected springs */ float struct_stiff; @@ -240,6 +241,7 @@ void cloth_init ( ClothModifierData *clmd ); DerivedMesh *clothModifier_do ( ClothModifierData *clmd, struct Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc ); void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); +int cloth_uses_vgroup(ClothModifierData *clmd); // needed for collision.c void bvhtree_update_from_cloth ( ClothModifierData *clmd, int moving ); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 454666566dc..cb61a08f3ba 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -53,7 +53,7 @@ int id_unlink(struct ID *id, int test); int new_id(struct ListBase *lb, struct ID *id, const char *name); -struct ListBase *wich_libbase(struct Main *mainlib, short type); +struct ListBase *which_libbase(struct Main *mainlib, short type); #define MAX_LIBARRAY 40 int set_listbasepointers(struct Main *main, struct ListBase **lb); diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 5b842965225..30bce613dbe 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -77,6 +77,8 @@ void BKE_nlatrack_sort_strips(struct NlaTrack *nlt); short BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip); +short BKE_nlatrack_get_bounds(struct NlaTrack *nlt, float bounds[2]); + /* ............ */ struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt); diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 55f11e1066b..170965a223a 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -236,7 +236,7 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothMo void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd); void BKE_ptcache_id_from_smoke_turbulence(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd); -void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob); +void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis); /***************** Global funcs ****************************/ void BKE_ptcache_remove(void); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 09fb705dd70..090979b33e9 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -47,9 +47,8 @@ struct Main; #define SCE_COPY_LINK_DATA 2 #define SCE_COPY_FULL 3 -/* note; doesn't work when scene is empty */ -#define SETLOOPER(s, b) sce= s, b= (Base*)sce->base.first; b; b= (Base*)(b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL) - +#define SETLOOPER(s, b) sce= s, b= _setlooper_base_step(&sce, NULL); b; b= _setlooper_base_step(&sce, b) +struct Base *_setlooper_base_step(struct Scene **sce, struct Base *base); void free_avicodecdata(struct AviCodecData *acd); void free_qtcodecdata(struct QuicktimeCodecData *acd); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 9d15ac3f348..f4e3a60803e 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_cloth_types.h" #include "DNA_key_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -49,6 +50,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_displist.h" +#include "BKE_key.h" #include "BKE_modifier.h" #include "BKE_mesh.h" #include "BKE_object.h" @@ -1450,55 +1452,88 @@ static float *get_editmesh_orco_verts(EditMesh *em) /* orco custom data layer */ -static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em) +static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free) +{ + *free= 0; + + if(layer == CD_ORCO) { + /* get original coordinates */ + *free= 1; + + if(em) + return (float(*)[3])get_editmesh_orco_verts(em); + else + return (float(*)[3])get_mesh_orco_verts(ob); + } + else if(layer == CD_CLOTH_ORCO) { + /* apply shape key for cloth, this should really be solved + by a more flexible customdata system, but not simple */ + if(!em) { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest); + + if(kb->data) + return kb->data; + } + + return NULL; + } + + return NULL; +} + +static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer) { DerivedMesh *dm; float (*orco)[3]; + int free; - if(em) { - dm= CDDM_from_editmesh(em, me); - orco= (float(*)[3])get_editmesh_orco_verts(em); - } - else { - dm= CDDM_from_mesh(me, ob); - orco= (float(*)[3])get_mesh_orco_verts(ob); + if(em) dm= CDDM_from_editmesh(em, me); + else dm= CDDM_from_mesh(me, ob); + + orco= get_orco_coords_dm(ob, em, layer, &free); + + if(orco) { + CDDM_apply_vert_coords(dm, orco); + if(free) MEM_freeN(orco); } - CDDM_apply_vert_coords(dm, orco); CDDM_calc_normals(dm); - MEM_freeN(orco); return dm; } -static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm) +static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer) { float (*orco)[3], (*layerorco)[3]; - int totvert; + int totvert, free; totvert= dm->getNumVerts(dm); if(orcodm) { orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco"); + free= 1; if(orcodm->getNumVerts(orcodm) == totvert) orcodm->getVertCos(orcodm, orco); else dm->getVertCos(dm, orco); } - else { - if(em) orco= (float(*)[3])get_editmesh_orco_verts(em); - else orco= (float(*)[3])get_mesh_orco_verts(ob); - } + else + orco= get_orco_coords_dm(ob, em, layer, &free); - transform_mesh_orco_verts(ob->data, orco, totvert, 0); + if(orco) { + if(layer == CD_ORCO) + transform_mesh_orco_verts(ob->data, orco, totvert, 0); + + if(!(layerorco = DM_get_vert_data_layer(dm, layer))) { + DM_add_vert_layer(dm, layer, CD_CALLOC, NULL); + layerorco = DM_get_vert_data_layer(dm, layer); + } - if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) { - memcpy(layerorco, orco, sizeof(float)*totvert); - MEM_freeN(orco); + memcpy(layerorco, orco, sizeof(float)*3*totvert); + if(free) MEM_freeN(orco); } - else - DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); } /* weight paint colors */ @@ -1604,9 +1639,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos Mesh *me = ob->data; ModifierData *firstmd, *md; LinkNode *datamasks, *curr; - CustomDataMask mask; + CustomDataMask mask, nextmask; float (*deformedVerts)[3] = NULL; - DerivedMesh *dm, *orcodm, *finaldm; + DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm; int numVerts = me->totvert; int required_mode; @@ -1679,6 +1714,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos */ dm = NULL; orcodm = NULL; + clothorcodm = NULL; for(;md; md = md->next, curr = curr->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1695,11 +1731,13 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; /* add an orco layer if needed by this modifier */ - if(dm && mti->requiredDataMask) { + if(mti->requiredDataMask) mask = mti->requiredDataMask(ob, md); - if(mask & CD_MASK_ORCO) - add_orco_dm(ob, NULL, dm, orcodm); - } + else + mask = 0; + + if(dm && (mask & CD_MASK_ORCO)) + add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO); /* How to apply modifier depends on (a) what we already have as * a result of previous modifiers (could be a DerivedMesh or just @@ -1766,26 +1804,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } } - /* create an orco derivedmesh in parallel */ - mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); - if(mask & CD_MASK_ORCO) { - if(!orcodm) - orcodm= create_orco_dm(ob, me, NULL); - - mask &= ~CD_MASK_ORCO; - DM_set_only_copy(orcodm, mask); - ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0); - - if(ndm) { - /* if the modifier returned a new dm, release the old one */ - if(orcodm && orcodm != ndm) orcodm->release(orcodm); - orcodm = ndm; - } - } - + /* determine which data layers are needed by following modifiers */ + if(curr->next) + nextmask= (CustomDataMask)GET_INT_FROM_POINTER(curr->next->link); + else + nextmask= dataMask; + /* set the DerivedMesh to only copy needed data */ + mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); DM_set_only_copy(dm, mask); + /* add cloth rest shape key if need */ + if(mask & CD_MASK_CLOTH_ORCO) + add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO); + /* add an origspace layer if needed */ if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE) if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) @@ -1806,6 +1838,38 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos deformedVerts = NULL; } } + + /* create an orco derivedmesh in parallel */ + if(nextmask & CD_MASK_ORCO) { + if(!orcodm) + orcodm= create_orco_dm(ob, me, NULL, CD_ORCO); + + nextmask &= ~CD_MASK_ORCO; + DM_set_only_copy(orcodm, nextmask); + ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0); + + if(ndm) { + /* if the modifier returned a new dm, release the old one */ + if(orcodm && orcodm != ndm) orcodm->release(orcodm); + orcodm = ndm; + } + } + + /* create cloth orco derivedmesh in parallel */ + if(nextmask & CD_MASK_CLOTH_ORCO) { + if(!clothorcodm) + clothorcodm= create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO); + + nextmask &= ~CD_MASK_CLOTH_ORCO; + DM_set_only_copy(clothorcodm, nextmask); + ndm = mti->applyModifier(md, ob, clothorcodm, useRenderParams, 0); + + if(ndm) { + /* if the modifier returned a new dm, release the old one */ + if(clothorcodm && clothorcodm != ndm) clothorcodm->release(clothorcodm); + clothorcodm = ndm; + } + } } /* grab modifiers until index i */ @@ -1846,16 +1910,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* add an orco layer if needed */ if(dataMask & CD_MASK_ORCO) { - add_orco_dm(ob, NULL, finaldm, orcodm); + add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO); if(deform_r && *deform_r) - add_orco_dm(ob, NULL, *deform_r, NULL); + add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO); } *final_r = finaldm; if(orcodm) orcodm->release(orcodm); + if(clothorcodm) + clothorcodm->release(clothorcodm); if(deformedVerts && deformedVerts != inputVertexCos) MEM_freeN(deformedVerts); @@ -1930,7 +1996,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri if(dm && mti->requiredDataMask) { mask = mti->requiredDataMask(ob, md); if(mask & CD_MASK_ORCO) - add_orco_dm(ob, em, dm, orcodm); + add_orco_dm(ob, em, dm, orcodm, CD_ORCO); } /* How to apply modifier depends on (a) what we already have as @@ -1987,7 +2053,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); if(mask & CD_MASK_ORCO) { if(!orcodm) - orcodm= create_orco_dm(ob, ob->data, em); + orcodm= create_orco_dm(ob, ob->data, em, CD_ORCO); mask &= ~CD_MASK_ORCO; DM_set_only_copy(orcodm, mask); @@ -2060,7 +2126,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri /* add an orco layer if needed */ if(dataMask & CD_MASK_ORCO) - add_orco_dm(ob, em, *final_r, orcodm); + add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO); if(orcodm) orcodm->release(orcodm); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 2d52d6061b9..365ac2371b8 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -238,6 +238,30 @@ void set_active_action_group (bAction *act, bActionGroup *agrp, short select) } } +/* Add a new action group with the given name to the action */ +bActionGroup *action_groups_add_new (bAction *act, const char name[]) +{ + bActionGroup *agrp; + + /* sanity check: must have action and name */ + if (ELEM(NULL, act, name)) + return NULL; + + /* allocate a new one */ + agrp = MEM_callocN(sizeof(bActionGroup), "bActionGroup"); + + /* make it selected, with default name */ + agrp->flag = AGRP_SELECTED; + strncpy(agrp->name, name[0] ? name : "Group", sizeof(agrp->name)); + + /* add to action, and validate */ + BLI_addtail(&act->groups, agrp); + BLI_uniquename(&act->groups, agrp, "Group", '.', offsetof(bActionGroup, name), sizeof(agrp->name)); + + /* return the new group */ + return agrp; +} + /* Add given channel into (active) group * - assumes that channel is not linked to anything anymore * - always adds at the end of the group diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 1465f4550f5..b687062fe15 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -837,7 +837,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl /* mballs have a different dupli handling */ if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ - if(par->mode & OB_MODE_EDIT) { + if(me->edit_mesh) { dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd); } else { @@ -1048,7 +1048,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa else go= go->next; /* group loop */ } - if(par->mode & OB_MODE_EDIT) { + if(em) { MEM_freeN(mface); MEM_freeN(mvert); } @@ -1073,7 +1073,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p ParticleCacheKey *cache; float ctime, pa_time, scale = 1.0f; float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size=0.0; - float (*obmat)[4], (*oldobmat)[4], recurs_mat[4][4]; + float (*obmat)[4], (*oldobmat)[4]; int lay, a, b, counter, hair = 0; int totpart, totchild, totgroup=0, pa_num; @@ -1090,10 +1090,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if(!psys_check_enabled(par, psys)) return; - /* particles are already in world space, don't want the object mat twice */ - if(par_space_mat) - mul_m4_m4m4(recurs_mat, psys->imat, par_space_mat); - ctime = bsystem_time(scene, par, (float)scene->r.cfra, 0.0); totpart = psys->totpart; @@ -1237,7 +1233,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p mul_m4_m4m4(tmat, oblist[b]->obmat, pamat); mul_mat3_m4_fl(tmat, size*scale); if(par_space_mat) - mul_m4_m4m4(mat, tmat, recurs_mat); + mul_m4_m4m4(mat, tmat, par_space_mat); else copy_m4_m4(mat, tmat); @@ -1263,7 +1259,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p VECADD(tmat[3], tmat[3], vec); if(par_space_mat) - mul_m4_m4m4(mat, tmat, recurs_mat); + mul_m4_m4m4(mat, tmat, par_space_mat); else copy_m4_m4(mat, tmat); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 33fe6212cd2..2b11c4bdfa0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -721,6 +721,15 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh * } +int cloth_uses_vgroup(ClothModifierData *clmd) +{ + return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || + (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && + ((clmd->sim_parms->vgroup_mass>0) || + (clmd->sim_parms->vgroup_struct>0)|| + (clmd->sim_parms->vgroup_bend>0))); +} + /** * cloth_apply_vgroup - applies a vertex group as specified by type * @@ -744,11 +753,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) verts = clothObj->verts; - if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || - (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && - ((clmd->sim_parms->vgroup_mass>0) || - (clmd->sim_parms->vgroup_struct>0)|| - (clmd->sim_parms->vgroup_bend>0))) + if (cloth_uses_vgroup(clmd)) { for ( i = 0; i < numverts; i++, verts++ ) { @@ -805,6 +810,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d int i = 0; MVert *mvert = NULL; ClothVertex *verts = NULL; + float (*shapekey_rest)[3]= NULL; float tnull[3] = {0,0,0}; Cloth *cloth = NULL; float maxdist = 0; @@ -842,7 +848,11 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->springs = NULL; clmd->clothObject->numsprings = -1; + if( clmd->sim_parms->shapekey_rest ) + shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO ); + mvert = dm->getVertArray ( dm ); + verts = clmd->clothObject->verts; // set initial values @@ -850,8 +860,16 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d { if(first) { - VECCOPY ( verts->x, mvert[i].co ); + copy_v3_v3( verts->x, mvert[i].co ); + mul_m4_v3( ob->obmat, verts->x ); + + if( shapekey_rest ) { + verts->xrest= shapekey_rest[i]; + mul_m4_v3( ob->obmat, verts->xrest ); + } + else + verts->xrest = verts->x; } /* no GUI interface yet */ @@ -1070,7 +1088,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { spring->ij = MIN2(medge[i].v1, medge[i].v2); spring->kl = MAX2(medge[i].v2, medge[i].v1); - VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); spring->restlen = sqrt ( INPR ( temp, temp ) ); clmd->sim_parms->avg_spring_len += spring->restlen; cloth->verts[spring->ij].avg_spring_len += spring->restlen; @@ -1116,7 +1134,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = MIN2(mface[i].v1, mface[i].v3); spring->kl = MAX2(mface[i].v3, mface[i].v1); - VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; @@ -1139,7 +1157,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = MIN2(mface[i].v2, mface[i].v4); spring->kl = MAX2(mface[i].v4, mface[i].v2); - VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; @@ -1181,7 +1199,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = MIN2(tspring2->ij, index2); spring->kl = MAX2(tspring2->ij, index2); - VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; @@ -1221,7 +1239,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = tspring2->ij; spring->kl = tspring->kl; - VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 9087a7ec4f2..c87495d499e 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1227,49 +1227,47 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender) /* if a font object is being edited, then do nothing */ // XXX if( ob == obedit && ob->type == OB_FONT ) return; - if(cu->bevobj && cu->bevobj!=ob) { - if(cu->bevobj->type==OB_CURVE) { - bevcu= cu->bevobj->data; - if(bevcu->ext1==0.0 && bevcu->ext2==0.0) { - ListBase bevdisp= {NULL, NULL}; - facx= cu->bevobj->size[0]; - facy= cu->bevobj->size[1]; - - if (forRender) { - makeDispListCurveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, 0); - dl= bevdisp.first; - } else { + if(cu->bevobj) { + bevcu= cu->bevobj->data; + if(bevcu->ext1==0.0 && bevcu->ext2==0.0) { + ListBase bevdisp= {NULL, NULL}; + facx= cu->bevobj->size[0]; + facy= cu->bevobj->size[1]; + + if (forRender) { + makeDispListCurveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, 0); + dl= bevdisp.first; + } else { + dl= bevcu->disp.first; + if(dl==0) { + makeDispListCurveTypes(scene, cu->bevobj, 0); dl= bevcu->disp.first; - if(dl==0) { - makeDispListCurveTypes(scene, cu->bevobj, 0); - dl= bevcu->disp.first; - } } + } - while(dl) { - if ELEM(dl->type, DL_POLY, DL_SEGM) { - dlnew= MEM_mallocN(sizeof(DispList), "makebevelcurve1"); - *dlnew= *dl; - dlnew->verts= MEM_mallocN(3*sizeof(float)*dl->parts*dl->nr, "makebevelcurve1"); - memcpy(dlnew->verts, dl->verts, 3*sizeof(float)*dl->parts*dl->nr); - - if(dlnew->type==DL_SEGM) dlnew->flag |= (DL_FRONT_CURVE|DL_BACK_CURVE); - - BLI_addtail(disp, dlnew); - fp= dlnew->verts; - nr= dlnew->parts*dlnew->nr; - while(nr--) { - fp[2]= fp[1]*facy; - fp[1]= -fp[0]*facx; - fp[0]= 0.0; - fp+= 3; - } + while(dl) { + if ELEM(dl->type, DL_POLY, DL_SEGM) { + dlnew= MEM_mallocN(sizeof(DispList), "makebevelcurve1"); + *dlnew= *dl; + dlnew->verts= MEM_mallocN(3*sizeof(float)*dl->parts*dl->nr, "makebevelcurve1"); + memcpy(dlnew->verts, dl->verts, 3*sizeof(float)*dl->parts*dl->nr); + + if(dlnew->type==DL_SEGM) dlnew->flag |= (DL_FRONT_CURVE|DL_BACK_CURVE); + + BLI_addtail(disp, dlnew); + fp= dlnew->verts; + nr= dlnew->parts*dlnew->nr; + while(nr--) { + fp[2]= fp[1]*facy; + fp[1]= -fp[0]*facx; + fp[0]= 0.0; + fp+= 3; } - dl= dl->next; } - - freedisplist(&bevdisp); + dl= dl->next; } + + freedisplist(&bevdisp); } } else if(cu->ext1==0.0 && cu->ext2==0.0) { diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index a755170aae6..0afb9a450dd 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -794,13 +794,14 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { layerSwap_mcol, layerDefault_mcol}, {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, + {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", - "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol"}; + "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDClothOrco"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; @@ -813,7 +814,7 @@ const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS; const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | - CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | + CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL; const CustomDataMask CD_MASK_BMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; @@ -847,7 +848,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, { const LayerTypeInfo *typeInfo; CustomDataLayer *layer, *newlayer; - int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0; + int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0; for(i = 0; i < source->totlayer; ++i) { layer = &source->layers[i]; @@ -862,15 +863,16 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, lastclone = layer->active_clone; lastmask = layer->active_mask; lasttype = type; + lastflag = layer->flag; } else number++; - if(layer->flag & CD_FLAG_NOCOPY) continue; + if(lastflag & CD_FLAG_NOCOPY) continue; else if(!((int)mask & (int)(1 << (int)type))) continue; else if(number < CustomData_number_of_layers(dest, type)) continue; - if((alloctype == CD_ASSIGN) && (layer->flag & CD_FLAG_NOFREE)) + if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE)) newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE, layer->data, totelem, layer->name); else @@ -882,6 +884,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, newlayer->active_rnd = lastrender; newlayer->active_clone = lastclone; newlayer->active_mask = lastmask; + newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY); } } } @@ -891,6 +894,9 @@ void CustomData_copy(const struct CustomData *source, struct CustomData *dest, { memset(dest, 0, sizeof(*dest)); + if(source->external) + dest->external= MEM_dupallocN(source->external); + CustomData_merge(source, dest, mask, alloctype, totelem); } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 487ecb810d4..c65fac7d474 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1580,21 +1580,24 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, if(forRender || nu->hide==0) { if(nu->pntsv==1) { len= SEGMENTSU(nu)*nu->resolu; - + dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); - + BLI_addtail(dispbase, dl); dl->parts= 1; dl->nr= len; dl->col= nu->mat_nr; dl->charidx= nu->charidx; - dl->rt= nu->flag; - + + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt= nu->flag & ~CU_2D; + data= dl->verts; if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; - + makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float)); } else { @@ -1606,11 +1609,14 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, dl->col= nu->mat_nr; dl->charidx= nu->charidx; - dl->rt= nu->flag; - + + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt= nu->flag & ~CU_2D; + data= dl->verts; dl->type= DL_SURF; - + dl->parts= (nu->pntsu*nu->resolu); /* in reverse, because makeNurbfaces works that way */ dl->nr= (nu->pntsv*nu->resolv); if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */ @@ -1651,6 +1657,15 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba float (*deformedVerts)[3]; int numVerts; + /* Bevel and taper objects should always be curves */ + if (cu->bevobj && cu->bevobj->type != OB_CURVE) { + cu->bevobj = NULL; + } + + if (cu->taperobj && cu->taperobj->type != OB_CURVE) { + cu->taperobj = NULL; + } + if(cu->editnurb) nubase= cu->editnurb; else @@ -1683,26 +1698,29 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba float *fp1, *data; BevPoint *bevp; int a,b; - + if (bl->nr) { /* blank bevel lists can happen */ - + /* exception handling; curve without bevel or extrude, with width correction */ if(dlbev.first==NULL) { dl= MEM_callocN(sizeof(DispList), "makeDispListbev"); dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts"); BLI_addtail(dispbase, dl); - + if(bl->poly!= -1) dl->type= DL_POLY; else dl->type= DL_SEGM; - + if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE); - + dl->parts= 1; dl->nr= bl->nr; dl->col= nu->mat_nr; dl->charidx= nu->charidx; - dl->rt= nu->flag; - + + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt= nu->flag & ~CU_2D; + a= dl->nr; bevp= (BevPoint *)(bl+1); data= dl->verts; @@ -1716,10 +1734,10 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } else { DispList *dlb; - + for (dlb=dlbev.first; dlb; dlb=dlb->next) { - /* for each part of the bevel use a separate displblock */ + /* for each part of the bevel use a separate displblock */ dl= MEM_callocN(sizeof(DispList), "makeDispListbev1"); dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts"); BLI_addtail(dispbase, dl); @@ -1734,11 +1752,15 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba dl->nr= dlb->nr; dl->col= nu->mat_nr; dl->charidx= nu->charidx; - dl->rt= nu->flag; + + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt= nu->flag & ~CU_2D; + dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2"); bevp= (BevPoint *)(bl+1); - /* for each point of poly make a bevel piece */ + /* for each point of poly make a bevel piece */ bevp= (BevPoint *)(bl+1); for(a=0; a<bl->nr; a++,bevp++) { float fac=1.0; @@ -1748,7 +1770,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } else { fac = calc_taper(scene, cu->taperobj, a, bl->nr); } - + if (bevp->split_tag) { dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F); } @@ -1762,9 +1784,9 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba vec[0]= fp1[1]+widfac; vec[1]= fp1[2]; vec[2]= 0.0; - + mul_qt_v3(bevp->quat, vec); - + data[0]= bevp->vec[0] + fac*vec[0]; data[1]= bevp->vec[1] + fac*vec[1]; data[2]= bevp->vec[2] + fac*vec[2]; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 2d582157233..63bfbc3d093 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1894,13 +1894,16 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ memset(&rres, 0, sizeof(RenderResult)); if(!(rres.rectx > 0 && rres.recty > 0)) { - RE_ReleaseResultImage(re); + if(from_render) + RE_ReleaseResultImage(re); return NULL; } /* release is done in BKE_image_release_ibuf using lock_r */ - if(from_render) + if(from_render) { + BLI_lock_thread(LOCK_VIEWER); *lock_r= re; + } /* this gives active layer, composite or seqence result */ rect= (unsigned int *)rres.rect32; @@ -1909,9 +1912,9 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ dither= iuser->scene->r.dither_intensity; /* get compo/seq result by default */ - if(rres.rectf && layer==0); + if(rres.compo_seq && layer==0); else if(rres.layers.first) { - RenderLayer *rl= BLI_findlink(&rres.layers, layer-(rres.rectf?1:0)); + RenderLayer *rl= BLI_findlink(&rres.layers, layer-(rres.compo_seq?1:0)); if(rl) { RenderPass *rpass; @@ -1934,6 +1937,9 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ } } + if(!(rectf || rect)) + return NULL; + ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0); /* make ibuf if needed, and initialize it */ @@ -1942,17 +1948,12 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); } - if(!(rectf || rect)) - return ibuf; - ibuf->x= rres.rectx; ibuf->y= rres.recty; - if(ibuf->rect_float!=rectf || rect) { /* ensure correct redraw */ - BLI_lock_thread(LOCK_CUSTOM1); + if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */ imb_freerectImBuf(ibuf); - BLI_unlock_thread(LOCK_CUSTOM1); - } + if(rect) ibuf->rect= rect; @@ -1991,7 +1992,7 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame if(ima->lastframe != frame) ima->tpageflag |= IMA_TPAGE_REFRESH; ima->lastframe = frame; - } + } else if(ima->type==IMA_TYPE_MULTILAYER) { frame= iuser?iuser->framenr:ima->lastframe; index= iuser?iuser->multi_index:IMA_NO_INDEX; @@ -2155,10 +2156,13 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) void BKE_image_release_ibuf(Image *ima, void *lock) { /* for getting image during threaded render / compositing, need to release */ - if(lock == ima) + if(lock == ima) { BLI_unlock_thread(LOCK_VIEWER); /* viewer image */ - else if(lock) + } + else if(lock) { RE_ReleaseResultImage(lock); /* render result */ + BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */ + } } ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index bea641d2140..8605cf51b68 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -347,7 +347,7 @@ int id_unlink(ID *id, int test) if(id->us == 0) { if(test) return 1; - lb= wich_libbase(mainlib, GS(id->name)); + lb= which_libbase(mainlib, GS(id->name)); free_libblock(lb, id); return 1; @@ -356,7 +356,7 @@ int id_unlink(ID *id, int test) return 0; } -ListBase *wich_libbase(Main *mainlib, short type) +ListBase *which_libbase(Main *mainlib, short type) { switch( type ) { case ID_SCE: @@ -658,7 +658,7 @@ void *copy_libblock(void *rt) id= rt; - lb= wich_libbase(G.main, GS(id->name)); + lb= which_libbase(G.main, GS(id->name)); idn= alloc_libblock(lb, GS(id->name), id->name+2); if(idn==NULL) { @@ -867,7 +867,7 @@ void free_main(Main *mainvar) ID *find_id(char *type, char *name) /* type: "OB" or "MA" etc */ { - ListBase *lb= wich_libbase(G.main, GS(type)); + ListBase *lb= which_libbase(G.main, GS(type)); return BLI_findstring(lb, name, offsetof(ID, name) + 2); } @@ -1175,7 +1175,7 @@ int new_id(ListBase *lb, ID *id, const char *tname) if(id->lib) return 0; /* if no libdata given, look up based on ID */ - if(lb==NULL) lb= wich_libbase(G.main, GS(id->name)); + if(lb==NULL) lb= which_libbase(G.main, GS(id->name)); /* if no name given, use name of current ID * else make a copy (tname args can be const) */ @@ -1236,11 +1236,17 @@ static void image_fix_relative_path(Image *ima) #define LIBTAG(a) if(a && a->id.lib) {a->id.flag &=~LIB_INDIRECT; a->id.flag |= LIB_EXTERN;} -static void lib_indirect_test_id(ID *id) +static void lib_indirect_test_id(ID *id, Library *lib) { - if(id->lib) + if(id->lib) { + /* datablocks that were indirectly related are now direct links + * without this, appending data that has a link to other data will fail to write */ + if(lib && id->lib->parent == lib) { + id_lib_extern(id); + } return; + } if(GS(id->name)==ID_OB) { Object *ob= (Object *)id; @@ -1336,7 +1342,7 @@ void all_local(Library *lib, int untagged_only) a= set_listbasepointers(G.main, lbarray); while(a--) { for(id= lbarray[a]->first; id; id=id->next) - lib_indirect_test_id(id); + lib_indirect_test_id(id, lib); } } @@ -1348,7 +1354,7 @@ void test_idbutton(char *name) ID *idtest; - lb= wich_libbase(G.main, GS(name-2) ); + lb= which_libbase(G.main, GS(name-2) ); if(lb==0) return; /* search for id */ @@ -1383,7 +1389,7 @@ void rename_id(ID *id, char *name) ListBase *lb; strncpy(id->name+2, name, 21); - lb= wich_libbase(G.main, GS(id->name) ); + lb= which_libbase(G.main, GS(id->name) ); new_id(lb, id, name); } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 6d1f9d1d1bf..1aa68bb832f 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1346,70 +1346,3 @@ void paste_matcopybuf(Material *ma) scrarea_queue_winredraw(curarea); */ } - - -static short mtexcopied=0; /* must be reset on file load */ -static MTex mtexcopybuf; - -void clear_mat_mtex_copybuf(void) -{ /* use for file reload */ - mtexcopied= 0; -} - -void copy_mat_mtex_copybuf(ID *id) -{ - MTex **mtex= NULL; - - switch(GS(id->name)) { - case ID_MA: - mtex= &(((Material *)id)->mtex[(int)((Material *)id)->texact]); - break; - case ID_LA: - // la->mtex[(int)la->texact] // TODO - break; - case ID_WO: - // mtex= wrld->mtex[(int)wrld->texact]; // TODO - break; - } - - if(mtex && *mtex) { - memcpy(&mtexcopybuf, *mtex, sizeof(MTex)); - mtexcopied= 1; - } - else { - mtexcopied= 0; - } -} - -void paste_mat_mtex_copybuf(ID *id) -{ - MTex **mtex= NULL; - - if(mtexcopied == 0 || mtexcopybuf.tex==NULL) - return; - - switch(GS(id->name)) { - case ID_MA: - mtex= &(((Material *)id)->mtex[(int)((Material *)id)->texact]); - break; - case ID_LA: - // la->mtex[(int)la->texact] // TODO - break; - case ID_WO: - // mtex= wrld->mtex[(int)wrld->texact]; // TODO - break; - } - - if(mtex) { - if(*mtex==NULL) { - *mtex= MEM_mallocN(sizeof(MTex), "mtex copy"); - } - else if((*mtex)->tex) { - (*mtex)->tex->id.us--; - } - - memcpy(*mtex, &mtexcopybuf, sizeof(MTex)); - - id_us_plus((ID *)mtexcopybuf.tex); - } -} diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 543895a5973..9e8767406b1 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -629,6 +629,12 @@ static void make_edges_mdata(MVert *allvert, MFace *allface, int totvert, int to medge->v2= ed->v2; if(old==0 || ed->is_draw) medge->flag= ME_EDGEDRAW|ME_EDGERENDER; if(ed->is_loose) medge->flag|= ME_LOOSEEDGE; + + /* order is swapped so extruding this edge as a surface wont flip face normals + * with cyclic curves */ + if(ed->v1+1 != ed->v2) { + SWAP(int, medge->v1, medge->v2); + } medge++; } else { @@ -768,11 +774,8 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int totvlak+= dl->parts*(dl->nr-1); } else if(dl->type==DL_POLY) { - /* cyclic polys are filled. except when 3D */ - if(cu->flag & CU_3D) { - totvert+= dl->parts*dl->nr; - totvlak+= dl->parts*dl->nr; - } + totvert+= dl->parts*dl->nr; + totvlak+= dl->parts*dl->nr; } else if(dl->type==DL_SURF) { totvert+= dl->parts*dl->nr; @@ -824,27 +827,24 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int } else if(dl->type==DL_POLY) { - /* 3d polys are not filled */ - if(cu->flag & CU_3D) { - startvert= vertcount; - a= dl->parts*dl->nr; - data= dl->verts; - while(a--) { - VECCOPY(mvert->co, data); - data+=3; - vertcount++; - mvert++; - } + startvert= vertcount; + a= dl->parts*dl->nr; + data= dl->verts; + while(a--) { + VECCOPY(mvert->co, data); + data+=3; + vertcount++; + mvert++; + } - for(a=0; a<dl->parts; a++) { - ofs= a*dl->nr; - for(b=0; b<dl->nr; b++) { - mface->v1= startvert+ofs+b; - if(b==dl->nr-1) mface->v2= startvert+ofs; - else mface->v2= startvert+ofs+b+1; - if(smooth) mface->flag |= ME_SMOOTH; - mface++; - } + for(a=0; a<dl->parts; a++) { + ofs= a*dl->nr; + for(b=0; b<dl->nr; b++) { + mface->v1= startvert+ofs+b; + if(b==dl->nr-1) mface->v2= startvert+ofs; + else mface->v2= startvert+ofs+b+1; + if(smooth) mface->flag |= ME_SMOOTH; + mface++; } } } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 96877a9ae9e..76e49c0726b 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -3606,6 +3606,7 @@ static void uvprojectModifier_initData(ModifierData *md) umd->flags = 0; umd->num_projectors = 1; umd->aspectx = umd->aspecty = 1.0f; + umd->scalex = umd->scaley = 1.0f; } static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target) @@ -3621,6 +3622,8 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target) tumd->num_projectors = umd->num_projectors; tumd->aspectx = umd->aspectx; tumd->aspecty = umd->aspecty; + tumd->scalex = umd->scalex; + tumd->scaley = umd->scaley; } static CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md) @@ -3692,6 +3695,8 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, char uvname[32]; float aspx= umd->aspectx ? umd->aspectx : 1.0f; float aspy= umd->aspecty ? umd->aspecty : 1.0f; + float scax= umd->scalex ? umd->scalex : 1.0f; + float scay= umd->scaley ? umd->scaley : 1.0f; int free_uci= 0; aspect = aspx / aspy; @@ -3829,6 +3834,22 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci); if(mf->v3) project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci); + + if(scax != 1.0f) { + tface->uv[0][0] = ((tface->uv[0][0] - 0.5f) * scax) + 0.5f; + tface->uv[1][0] = ((tface->uv[1][0] - 0.5f) * scax) + 0.5f; + tface->uv[2][0] = ((tface->uv[2][0] - 0.5f) * scax) + 0.5f; + if(mf->v3) + tface->uv[3][0] = ((tface->uv[3][0] - 0.5f) * scax) + 0.5f; + } + + if(scay != 1.0f) { + tface->uv[0][1] = ((tface->uv[0][1] - 0.5f) * scay) + 0.5f; + tface->uv[1][1] = ((tface->uv[1][1] - 0.5f) * scay) + 0.5f; + tface->uv[2][1] = ((tface->uv[2][1] - 0.5f) * scay) + 0.5f; + if(mf->v3) + tface->uv[3][1] = ((tface->uv[3][1] - 0.5f) * scay) + 0.5f; + } } else { /* apply transformed coords as UVs */ @@ -5697,6 +5718,7 @@ static void solidifyModifier_copyData(ModifierData *md, ModifierData *target) SolidifyModifierData *smd = (SolidifyModifierData*) md; SolidifyModifierData *tsmd = (SolidifyModifierData*) target; tsmd->offset = smd->offset; + tsmd->offset_fac = smd->offset_fac; tsmd->crease_inner = smd->crease_inner; tsmd->crease_outer = smd->crease_outer; tsmd->crease_rim = smd->crease_rim; @@ -5734,6 +5756,19 @@ static DerivedMesh *solidifyModifier_applyModifier(ModifierData *md, float (*vert_nors)[3]= NULL; + float ofs_orig= - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); + float ofs_new= smd->offset - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); + + /* weights */ + MDeformVert *dvert= NULL, *dv= NULL; + int defgrp_index= -1; + int defgrp_invert = ((smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0); + + defgrp_index= defgroup_name_index(ob, smd->defgrp_name); + + if (defgrp_index >= 0) + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + orig_mface = dm->getFaceArray(dm); orig_medge = dm->getEdgeArray(dm); orig_mvert = dm->getVertArray(dm); @@ -5758,7 +5793,8 @@ static DerivedMesh *solidifyModifier_applyModifier(ModifierData *md, #define ADD_EDGE_USER(_v1, _v2, edge_ord) \ eidx= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, _v1, _v2)); \ if(edge_users[eidx] == INVALID_UNUSED) { \ - edge_users[eidx]= (_v1 < _v2) ? i:(i+numFaces); \ + ed= orig_medge + eidx; \ + edge_users[eidx]= (_v1 < _v2) == (ed->v1 < ed->v2) ? i:(i+numFaces); \ edge_order[eidx]= edge_ord; \ } else { \ edge_users[eidx]= INVALID_PAIR; \ @@ -5866,16 +5902,38 @@ static DerivedMesh *solidifyModifier_applyModifier(ModifierData *md, if((smd->flag & MOD_SOLIDIFY_EVEN) == 0) { /* no even thickness, very simple */ - float scalar_short = smd->offset / 32767.0f; - - if(smd->offset < 0.0f) mv= mvert+numVerts; - else mv= mvert; + float scalar_short; + float scalar_short_vgroup; + + + if(ofs_new != 0.0f) { + scalar_short= scalar_short_vgroup= ofs_new / 32767.0f; + mv= mvert + ((ofs_new >= ofs_orig) ? 0 : numVerts); + dv= dvert; + for(i=0; i<numVerts; i++, mv++) { + if(dv) { + if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index)); + else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index); + dv++; + } + VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup); + } + } - for(i=0; i<numVerts; i++, mv++) { - mv->co[0] += mv->no[0] * scalar_short; - mv->co[1] += mv->no[1] * scalar_short; - mv->co[2] += mv->no[2] * scalar_short; + if(ofs_orig != 0.0f) { + scalar_short= scalar_short_vgroup= ofs_orig / 32767.0f; + mv= mvert + ((ofs_new >= ofs_orig) ? numVerts : 0); /* same as above but swapped, intentional use of 'ofs_new' */ + dv= dvert; + for(i=0; i<numVerts; i++, mv++) { + if(dv) { + if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index)); + else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index); + dv++; + } + VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup); + } } + } else { /* make a face normal layer if not present */ @@ -5927,12 +5985,38 @@ static DerivedMesh *solidifyModifier_applyModifier(ModifierData *md, } } - if(smd->offset < 0.0f) mv= mvert+numVerts; - else mv= mvert; + /* vertex group support */ + if(dvert) { + dv= dvert; + if(defgrp_invert) { + for(i=0; i<numVerts; i++, dv++) { + vert_angles[i] *= (1.0f - defvert_find_weight(dv, defgrp_index)); + } + } + else { + for(i=0; i<numVerts; i++, dv++) { + vert_angles[i] *= defvert_find_weight(dv, defgrp_index); + } + } + } + + if(ofs_new) { + mv= mvert + ((ofs_new >= ofs_orig) ? 0 : numVerts); + + for(i=0; i<numVerts; i++, mv++) { + if(vert_accum[i]) { /* zero if unselected */ + madd_v3_v3fl(mv->co, vert_nors[i], ofs_new * (vert_angles[i] / vert_accum[i])); + } + } + } - for(i=0; i<numVerts; i++, mv++) { - if(vert_accum[i]) { /* zero if unselected */ - madd_v3_v3fl(mv->co, vert_nors[i], smd->offset * (vert_angles[i] / vert_accum[i])); + if(ofs_orig) { + mv= mvert + ((ofs_new >= ofs_orig) ? numVerts : 0); /* same as above but swapped, intentional use of 'ofs_new' */ + + for(i=0; i<numVerts; i++, mv++) { + if(vert_accum[i]) { /* zero if unselected */ + madd_v3_v3fl(mv->co, vert_nors[i], ofs_orig * (vert_angles[i] / vert_accum[i])); + } } } @@ -6489,7 +6573,7 @@ static DerivedMesh *screwModifier_applyModifier(ModifierData *md, Object *ob, ed_loop_flip= 1; } else { - /* not so simple to work out wich edge is higher */ + /* not so simple to work out which edge is higher */ sub_v3_v3v3(tmp_vec1, tmpf1, vc_tmp->co); sub_v3_v3v3(tmp_vec1, tmpf2, vc_tmp->co); normalize_v3(tmp_vec1); @@ -6978,9 +7062,13 @@ static void clothModifier_updateDepgraph( static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = 0; + ClothModifierData *clmd = (ClothModifierData*)md; - /* ask for vertexgroups if we need them */ - dataMask |= (1 << CD_MDEFORMVERT); + if(cloth_uses_vgroup(clmd)) + dataMask |= (1 << CD_MDEFORMVERT); + + if(clmd->sim_parms->shapekey_rest != 0) + dataMask |= (1 << CD_CLOTH_ORCO); return dataMask; } @@ -7917,10 +8005,11 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd, MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); float val; if(dvert){ - for(i=0; i<totvert; i++){ + int defgrp_index= emd->vgroup-1; + for(i=0; i<totvert; i++, dvert++){ val = BLI_frand(); val = (1.0f-emd->protect)*val + emd->protect*0.5f; - if(val < defvert_find_weight(dvert+i,emd->vgroup-1)) + if(val < defvert_find_weight(dvert, defgrp_index)) vertpa[i] = -1; } } diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 4af007a5f91..ab2a6f713cb 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -39,10 +39,12 @@ #include "BLI_ghash.h" #include "DNA_anim_types.h" +#include "DNA_scene_types.h" #include "BKE_action.h" #include "BKE_fcurve.h" #include "BKE_nla.h" +#include "BKE_global.h" #include "BKE_library.h" #include "BKE_utildefines.h" @@ -828,8 +830,8 @@ void BKE_nlameta_flush_transforms (NlaStrip *mstrip) strip->end= nEnd; RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &ptr); - RNA_float_set(&ptr, "start_frame", nStart); - RNA_float_set(&ptr, "end_frame", nEnd); + RNA_float_set(&ptr, "frame_start", nStart); + RNA_float_set(&ptr, "frame_end", nEnd); } else { /* just apply the changes in offset to both ends of the strip */ @@ -956,6 +958,35 @@ short BKE_nlatrack_add_strip (NlaTrack *nlt, NlaStrip *strip) return BKE_nlastrips_add_strip(&nlt->strips, strip); } +/* Get the extents of the given NLA-Track including gaps between strips, + * returning whether this succeeded or not + */ +short BKE_nlatrack_get_bounds (NlaTrack *nlt, float bounds[2]) +{ + NlaStrip *strip; + + /* initialise bounds */ + if (bounds) + bounds[0] = bounds[1] = 0.0f; + else + return 0; + + /* sanity checks */ + if ELEM(NULL, nlt, nlt->strips.first) + return 0; + + /* lower bound is first strip's start frame */ + strip = nlt->strips.first; + bounds[0] = strip->start; + + /* upper bound is last strip's end frame */ + strip = nlt->strips.last; + bounds[1] = strip->end; + + /* done */ + return 1; +} + /* NLA Strips -------------------------------------- */ /* Find the active NLA-strip within the given track */ @@ -1474,7 +1505,10 @@ short BKE_nla_tweakmode_enter (AnimData *adt) } } if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) { - printf("NLA tweakmode enter - neither active requirement found \n"); + if (G.f & G_DEBUG) { + printf("NLA tweakmode enter - neither active requirement found \n"); + printf("\tactiveTrack = %p, activeStrip = %p \n", activeTrack, activeStrip); + } return 0; } @@ -1553,4 +1587,29 @@ void BKE_nla_tweakmode_exit (AnimData *adt) adt->flag &= ~ADT_NLA_EDIT_ON; } +/* Baking Tools ------------------------------------------- */ + +void BKE_nla_bake (Scene *scene, ID *id, AnimData *adt, int flag) +{ + + /* verify that data is valid + * 1) Scene and AnimData must be provided + * 2) there must be tracks to merge... + */ + if ELEM3(NULL, scene, adt, adt->nla_tracks.first) + return; + + /* if animdata currently has an action, 'push down' this onto the stack first */ + if (adt->action) + BKE_nla_action_pushdown(adt); + + /* get range of motion to bake, and the channels involved... */ + + /* temporarily mute the action, and start keying to it */ + + /* start keying... */ + + /* unmute the action */ +} + /* *************************************************** */ diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 5bd9694e768..9ff7f1f2982 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2573,6 +2573,8 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) for(sock= node->outputs.first; sock; sock= sock->next) { sock->new_sock->ns.data= sock->ns.data; + compbuf_set_node(sock->new_sock->ns.data, node->new_node); + sock->ns.data= NULL; sock->new_sock->new_sock= sock; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index bb7c77408ac..ac679adb9c1 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2502,7 +2502,7 @@ void object_handle_update(Scene *scene, Object *ob) BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS); // here was vieweditdatamask? XXX - if(ob->mode & OB_MODE_EDIT) { + if(em) { makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH); BKE_mesh_end_editmesh(ob->data, em); } else diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index bd9e041dab4..7ad65820bbe 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -355,6 +355,12 @@ int psys_uses_gravity(ParticleSimulationData *sim) /************************************************/ /* Freeing stuff */ /************************************************/ +void fluid_free_settings(SPHFluidSettings *fluid) +{ + if(fluid) + MEM_freeN(fluid); +} + void psys_free_settings(ParticleSettings *part) { BKE_free_animdata(&part->id); @@ -367,6 +373,7 @@ void psys_free_settings(ParticleSettings *part) BLI_freelistN(&part->dupliweights); boid_free_settings(part->boids); + fluid_free_settings(part->fluid); } void free_hair(Object *ob, ParticleSystem *psys, int dynamics) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index a8446c0009f..aa48336247c 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -24,7 +24,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn. * * ***** END GPL LICENSE BLOCK ***** */ @@ -2270,6 +2270,137 @@ static void psys_update_effectors(ParticleSimulationData *sim) precalc_guides(sim, sim->psys->effectors); } +/************************************************* + SPH fluid physics + + In theory, there could be unlimited implementation + of SPH simulators +**************************************************/ +void particle_fluidsim(ParticleSystem *psys, ParticleData *pa, ParticleSettings *part, ParticleSimulationData *sim, float dfra, float cfra, float mass){ +/**************************************************************************************************************** +* This code uses in some parts adapted algorithms from the pseduo code as outlined in the Research paper +* Titled: Particle-based Viscoelastic Fluid Simulation. +* Authors: Simon Clavet, Philippe Beaudoin and Pierre Poulin +* +* Website: http://www.iro.umontreal.ca/labs/infographie/papers/Clavet-2005-PVFS/ +* Presented at Siggraph, (2005) +* +*****************************************************************************************************************/ + KDTree *tree = psys->tree; + KDTreeNearest *ptn = NULL; + + SPHFluidSettings *fluid = part->fluid; + ParticleData *second_particle; + + float start[3], end[3], v[3]; + float temp[3]; + float q, radius, D; + float p, pnear, pressure_near, pressure; + float dtime = dfra * psys_get_timestep(sim); + float omega = fluid->viscosity_omega; + float beta = fluid->viscosity_omega; + float massfactor = 1.0f/mass; + int n, neighbours; + + + radius = fluid->radius; + + VECCOPY(start, pa->prev_state.co); + VECCOPY(end, pa->state.co); + + sub_v3_v3v3(v, end, start); + mul_v3_fl(v, 1.f/dtime); + + neighbours = BLI_kdtree_range_search(tree, radius, start, NULL, &ptn); + + /* use ptn[n].co to store relative direction */ + for(n=1; n<neighbours; n++) { + sub_v3_v3(ptn[n].co, start); + normalize_v3(ptn[n].co); + } + + /* Viscosity - Algorithm 5 */ + if (omega > 0.f || beta > 0.f) { + float u, I; + + for(n=1; n<neighbours; n++) { + second_particle = psys->particles + ptn[n].index; + q = ptn[n].dist/radius; + + sub_v3_v3v3(temp, v, second_particle->prev_state.vel); + + u = dot_v3v3(ptn[n].co, temp); + + if (u > 0){ + I = dtime * ((1-q) * (omega * u + beta * u*u)) * 0.5f; + madd_v3_v3fl(v, ptn[n].co, -I * massfactor); + } + } + } + + /* Hooke's spring force */ + if (fluid->spring_k > 0.f) { + float D, L = fluid->rest_length; + for(n=1; n<neighbours; n++) { + /* L is a factor of radius */ + D = dtime * 10.f * fluid->spring_k * (1.f - L) * (L - ptn[n].dist/radius); + madd_v3_v3fl(v, ptn[n].co, -D * massfactor); + } + } + /* Update particle position */ + VECADDFAC(end, start, v, dtime); + + /* Double Density Relaxation - Algorithm 2 */ + p = 0; + pnear = 0; + for(n=1; n<neighbours; n++) { + q = ptn[n].dist/radius; + p += ((1-q)*(1-q)); + pnear += ((1-q)*(1-q)*(1-q)); + } + p *= part->mass; + pnear *= part->mass; + pressure = fluid->stiffness_k * (p - fluid->rest_density); + pressure_near = fluid->stiffness_knear * pnear; + + for(n=1; n<neighbours; n++) { + q = ptn[n].dist/radius; + + D = dtime * dtime * (pressure*(1-q) + pressure_near*(1-q)*(1-q))* 0.5f; + madd_v3_v3fl(end, ptn[n].co, -D * massfactor); + } + + /* Artificial buoyancy force in negative gravity direction */ + if (fluid->buoyancy >= 0.f && psys_uses_gravity(sim)) { + float B = -dtime * dtime * fluid->buoyancy * (p - fluid->rest_density) * 0.5f; + madd_v3_v3fl(end, sim->scene->physics_settings.gravity, -B * massfactor); + } + + /* apply final result and recalculate velocity */ + VECCOPY(pa->state.co, end); + sub_v3_v3v3(pa->state.vel, end, start); + mul_v3_fl(pa->state.vel, 1.f/dtime); + + if(ptn){ MEM_freeN(ptn); ptn=NULL;} +} + +static void apply_particle_fluidsim(ParticleSystem *psys, ParticleData *pa, ParticleSettings *part, ParticleSimulationData *sim, float dfra, float cfra){ + ParticleTarget *pt; + float dtime = dfra*psys_get_timestep(sim); + float particle_mass = part->mass; + + particle_fluidsim(psys, pa, part, sim, dfra, cfra, particle_mass); + + /*----check other SPH systems (Multifluids) , each fluid has its own parameters---*/ + for(pt=sim->psys->targets.first; pt; pt=pt->next) { + ParticleSystem *epsys = psys_get_target_system(sim->ob, pt); + + if(epsys) + particle_fluidsim(epsys, pa, epsys->part, sim, dfra, cfra, particle_mass); + } + /*----------------------------------------------------------------*/ +} + /************************************************/ /* Newtonian physics */ /************************************************/ @@ -2799,7 +2930,7 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo deflections=max_deflections; } else { - float nor_vec[3], tan_vec[3], tan_vel[3], vel[3]; + float nor_vec[3], tan_vec[3], tan_vel[3]; float damp, frict; float inp, inp_v; @@ -3248,6 +3379,14 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra); } } + else if(part->phystype==PART_PHYS_FLUID){ + ParticleTarget *pt = psys->targets.first; + psys_update_particle_tree(psys, cfra); + + for(; pt; pt=pt->next) { /* Updating others systems particle tree for fluid-fluid interaction */ + if(pt->ob) psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra); + } + } /* main loop: calculate physics for all particles */ LOOP_SHOWN_PARTICLES { @@ -3318,6 +3457,22 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) } break; } + case PART_PHYS_FLUID: + { + /* do global forces & effectors */ + apply_particle_forces(sim, p, pa_dfra, cfra); + + /* do fluid sim */ + apply_particle_fluidsim(psys, pa, part, sim, pa_dfra, cfra); + + /* deflection */ + if(sim->colliders) + deflect_particle(sim, p, pa_dfra, cfra); + + /* rotations, SPH particles are not physical particles, just interpolation particles, thus rotation has not a direct sense for them */ + rotate_particle(part, pa, pa_dfra, timestep); + break; + } } if(pa->alive == PARS_DYING){ @@ -3727,6 +3882,21 @@ void psys_check_boid_data(ParticleSystem *psys) pa->boid = NULL; } } + +static void fluid_default_settings(ParticleSettings *part){ + SPHFluidSettings *fluid = part->fluid; + + fluid->radius = 0.5f; + fluid->spring_k = 0.f; + fluid->rest_length = 0.5f; + fluid->viscosity_omega = 2.f; + fluid->viscosity_beta = 0.f; + fluid->stiffness_k = 0.1f; + fluid->stiffness_knear = 0.05f; + fluid->rest_density = 10.f; + fluid->buoyancy = 0.f; +} + static void psys_changed_physics(ParticleSimulationData *sim) { ParticleSettings *part = sim->psys->part; @@ -3756,6 +3926,10 @@ static void psys_changed_physics(ParticleSimulationData *sim) state->flag |= BOIDSTATE_CURRENT; BLI_addtail(&part->boids->states, state); } + else if(part->phystype == PART_PHYS_FLUID && part->fluid == NULL) { + part->fluid = MEM_callocN(sizeof(SPHFluidSettings), "SPH Fluid Settings"); + fluid_default_settings(part); + } psys_check_boid_data(sim->psys); } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index cbe294f1347..807e25955a7 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -48,6 +48,7 @@ #include "WM_api.h" +#include "BKE_anim.h" #include "BKE_blender.h" #include "BKE_cloth.h" #include "BKE_depsgraph.h" @@ -90,6 +91,9 @@ #define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); } #define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); } +/* could be made into a pointcache option */ +#define DURIAN_POINTCACHE_LIB_OK 1 + int ptcache_data_size[] = { sizeof(int), // BPHYS_DATA_INDEX 3 * sizeof(float), // BPHYS_DATA_LOCATION: @@ -556,7 +560,7 @@ static void ptcache_interpolate_cloth(int index, void *cloth_v, void **data, flo static int ptcache_totpoint_cloth(void *cloth_v, int cfra) { ClothModifierData *clmd= cloth_v; - return clmd->clothObject->numverts; + return clmd->clothObject ? clmd->clothObject->numverts : 0; } /* Creating ID's */ @@ -982,7 +986,7 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *cl pid->info_types= 0; } -void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) +void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis) { PTCacheID *pid; ParticleSystem *psys; @@ -1024,6 +1028,23 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) } } } + + if(scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) { + ListBase *lb_dupli_ob; + + if((lb_dupli_ob=object_duplilist(scene, ob))) { + DupliObject *dob; + for(dob= lb_dupli_ob->first; dob; dob= dob->next) { + ListBase lb_dupli_pid; + BKE_ptcache_ids_from_object(&lb_dupli_pid, dob->ob, scene, duplis); + addlisttolist(lb, &lb_dupli_pid); + if(lb_dupli_pid.first) + printf("Adding Dupli\n"); + } + + free_object_duplilist(lb_dupli_ob); /* does restore */ + } + } } @@ -1132,10 +1153,11 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra) FILE *fp = NULL; char filename[(FILE_MAXDIR+FILE_MAXFILE)*2]; +#ifndef DURIAN_POINTCACHE_LIB_OK /* don't allow writing for linked objects */ if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE) return NULL; - +#endif if (!G.relbase_valid && (pid->cache->flag & PTCACHE_EXTERNAL)==0) return NULL; /* save blend file before using disk pointcache */ BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); @@ -1873,9 +1895,11 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra) if(!pid->cache || pid->cache->flag & PTCACHE_BAKED) return; +#ifndef DURIAN_POINTCACHE_LIB_OK /* don't allow clearing for linked objects */ if(pid->ob->id.lib) return; +#endif /*if (!G.relbase_valid) return; *//* save blend file before using pointcache */ @@ -2303,14 +2327,15 @@ PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old /* Baking */ static int count_quick_cache(Scene *scene, int *quick_step) { - Base *base = scene->base.first; + Base *base; PTCacheID *pid; ListBase pidlist; int autocache_count= 0; + Scene *sce; /* for macro only */ - for(base = scene->base.first; base; base = base->next) { + for(SETLOOPER(scene, base)) { if(base->object) { - BKE_ptcache_ids_from_object(&pidlist, base->object); + BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if((pid->cache->flag & PTCACHE_BAKED) @@ -2377,6 +2402,7 @@ static void *ptcache_make_cache_thread(void *ptr) { void BKE_ptcache_make_cache(PTCacheBaker* baker) { Scene *scene = baker->scene; + Scene *sce; /* SETLOOPER macro only */ Base *base; ListBase pidlist; PTCacheID *pid = baker->pid; @@ -2408,7 +2434,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) /* get all pids from the object and search for smoke low res */ ListBase pidlist2; PTCacheID *pid2; - BKE_ptcache_ids_from_object(&pidlist2, pid->ob); + BKE_ptcache_ids_from_object(&pidlist2, pid->ob, scene, MAX_DUPLI_RECUR); for(pid2=pidlist2.first; pid2; pid2=pid2->next) { if(pid2->type == PTCACHE_TYPE_SMOKE_DOMAIN) { @@ -2441,9 +2467,9 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) cache->flag &= ~PTCACHE_BAKED; } } - else for(base=scene->base.first; base; base= base->next) { + for(SETLOOPER(scene, base)) { /* cache/bake everything in the scene */ - BKE_ptcache_ids_from_object(&pidlist, base->object); + BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { cache = pid->cache; @@ -2524,8 +2550,8 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) BKE_ptcache_write_cache(pid, 0); } } - else for(base=scene->base.first; base; base= base->next) { - BKE_ptcache_ids_from_object(&pidlist, base->object); + else for(SETLOOPER(scene, base)) { + BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { /* skip hair particles */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b8d8cd0dc8f..d1edeb8322b 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -898,15 +898,20 @@ float frame_to_float (Scene *scene, int cfra) /* see also bsystem_time in objec return ctime; } -static void scene_update_newframe(Scene *sce, unsigned int lay) +static void scene_update_newframe(Scene *scene, int cfra, unsigned int lay) { Base *base; Object *ob; + int cfra_back= scene->r.cfra; + scene->r.cfra= cfra; - for(base= sce->base.first; base; base= base->next) { + for(base= scene->base.first; base; base= base->next) { ob= base->object; - object_handle_update(sce, ob); // bke_object.h + object_handle_update(scene, ob); // bke_object.h + + if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) + group_handle_recalc_and_update(scene, ob, ob->dup_group); /* only update layer when an ipo */ // XXX old animation system @@ -914,6 +919,8 @@ static void scene_update_newframe(Scene *sce, unsigned int lay) // base->lay= ob->lay; //} } + + scene->r.cfra= cfra_back; } /* this is called in main loop, doing tagged updates before redraw */ @@ -921,6 +928,7 @@ void scene_update_tagged(Scene *scene) { Scene *sce; Base *base; + Object *ob; float ctime = frame_to_float(scene, scene->r.cfra); /* update all objects: drivers, matrices, displists, etc. flags set @@ -929,12 +937,23 @@ void scene_update_tagged(Scene *scene) /* sets first, we allow per definition current scene to have dependencies on sets, but not the other way around. */ if(scene->set) { - for(SETLOOPER(scene->set, base)) - object_handle_update(scene, base->object); + for(SETLOOPER(scene->set, base)) { + ob= base->object; + + object_handle_update(scene, ob); + + if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) + group_handle_recalc_and_update(scene, ob, ob->dup_group); + } } for(base= scene->base.first; base; base= base->next) { - object_handle_update(scene, base->object); + ob= base->object; + + object_handle_update(scene, ob); + + if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) + group_handle_recalc_and_update(scene, ob, ob->dup_group); } /* recalc scene animation data here (for sequencer) */ @@ -945,6 +964,7 @@ void scene_update_tagged(Scene *scene) BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, 0); } + /* XXX - this is called far to often, should be made apart of the depgraph */ BKE_ptcache_quick_cache_all(scene); /* in the future this should handle updates for all datablocks, not @@ -981,10 +1001,11 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay) /* sets first, we allow per definition current scene to have dependencies on sets */ - for(sce_iter= sce->set; sce_iter; sce_iter= sce_iter->set) - scene_update_newframe(sce_iter, lay); + for(sce_iter= sce->set; sce_iter; sce_iter= sce_iter->set) { + scene_update_newframe(sce_iter, sce->r.cfra, lay); + } - scene_update_newframe(sce, lay); + scene_update_newframe(sce, sce->r.cfra, lay); } /* return default layer, also used to patch old files */ @@ -1039,3 +1060,26 @@ float get_render_aosss_error(RenderData *r, float error) return error; } +/* helper function for the SETLOOPER macro */ +Base *_setlooper_base_step(Scene **sce, Base *base) +{ + if(base && base->next) { + /* common case, step to the next */ + return base->next; + } + else if(base==NULL && (*sce)->base.first) { + /* first time looping, return the scenes first base */ + return (Base *)(*sce)->base.first; + } + else { + /* reached the end, get the next base in the set */ + while((*sce= (*sce)->set)) { + base= (Base *)(*sce)->base.first; + if(base) { + return base; + } + } + } + + return NULL; +} diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 913ec3d4cae..790087334c6 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1750,19 +1750,15 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf if(seq->flag & SEQ_MAKE_FLOAT) { if (!se->ibuf->rect_float) { - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) { - IMB_float_from_rect(se->ibuf); - } else { - int profile = IB_PROFILE_NONE; - - /* no color management: - * don't disturb the existing profiles */ - SWAP(int, se->ibuf->profile, profile); + int profile = IB_PROFILE_NONE; + + /* no color management: + * don't disturb the existing profiles */ + SWAP(int, se->ibuf->profile, profile); - IMB_float_from_rect(se->ibuf); - - SWAP(int, se->ibuf->profile, profile); - } + IMB_float_from_rect(se->ibuf); + + SWAP(int, se->ibuf->profile, profile); } if (se->ibuf->rect) { imb_freerectImBuf(se->ibuf); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 00e81063760..aa513ab0fb7 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1156,10 +1156,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM framenr = scene->r.cfra; - // printf("time: %d\n", scene->r.cfra); - - if(framenr == smd->time) - return; + printf("time: %d\n", scene->r.cfra); cache = sds->point_cache[0]; BKE_ptcache_id_from_smoke(&pid, ob, smd); @@ -1206,11 +1203,23 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM if(cache_result_wt == PTCACHE_READ_EXACT) { BKE_ptcache_validate(cache_wt, framenr); + + return; + } + else + { + ; /* don't return in the case we only got low res cache but no high res cache */ + /* we still need to calculate the high res cache */ } } - return; + else + return; } + /* only calculate something when we advanced a frame */ + if(framenr == smd->time) + return; + tstart(); smoke_calc_domain(scene, ob, smd); |