Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2010-04-04 23:50:22 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2010-04-04 23:50:22 +0400
commitf9e2f6acd761492c52500bf72e32a4ad5a33757b (patch)
treedf44ac89101bf0be263a8d53623c9302dca5e59c /source/blender/blenkernel
parent65b2ef5b15ae56758f7097df98dbce9ba3fe1454 (diff)
parent687c752b75bc488b2de5a4186ba2398b31dbb46e (diff)
Merged changes in the trunk up to revision 27992.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_action.h3
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/BKE_library.h2
-rw-r--r--source/blender/blenkernel/BKE_nla.h2
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h2
-rw-r--r--source/blender/blenkernel/BKE_scene.h5
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c166
-rw-r--r--source/blender/blenkernel/intern/action.c24
-rw-r--r--source/blender/blenkernel/intern/anim.c14
-rw-r--r--source/blender/blenkernel/intern/cloth.c40
-rw-r--r--source/blender/blenkernel/intern/curve.c72
-rw-r--r--source/blender/blenkernel/intern/customdata.c16
-rw-r--r--source/blender/blenkernel/intern/displist.c66
-rw-r--r--source/blender/blenkernel/intern/image.c32
-rw-r--r--source/blender/blenkernel/intern/library.c26
-rw-r--r--source/blender/blenkernel/intern/material.c67
-rw-r--r--source/blender/blenkernel/intern/mesh.c50
-rw-r--r--source/blender/blenkernel/intern/modifier.c127
-rw-r--r--source/blender/blenkernel/intern/nla.c65
-rw-r--r--source/blender/blenkernel/intern/node.c2
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenkernel/intern/particle.c7
-rw-r--r--source/blender/blenkernel/intern/particle_system.c178
-rw-r--r--source/blender/blenkernel/intern/pointcache.c48
-rw-r--r--source/blender/blenkernel/intern/scene.c62
-rw-r--r--source/blender/blenkernel/intern/sequencer.c20
-rw-r--r--source/blender/blenkernel/intern/smoke.c19
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);