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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_key.h12
-rw-r--r--source/blender/blenkernel/intern/key.c114
-rw-r--r--source/blender/editors/mesh/meshtools.c1
-rw-r--r--source/blender/makesdna/DNA_key_types.h1
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.cpp12
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp57
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h3
7 files changed, 102 insertions, 98 deletions
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index de60d316426..19264feaf48 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -41,6 +41,7 @@ struct Object;
struct Scene;
struct Lattice;
struct Mesh;
+struct WeightsArrayCache;
/* Kernel prototypes */
#ifdef __cplusplus
@@ -73,8 +74,17 @@ struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index);
struct KeyBlock *BKE_keyblock_find_name(struct Key *key, const char name[]);
void BKE_keyblock_copy_settings(struct KeyBlock *kb_dst, const struct KeyBlock *kb_src);
char *BKE_keyblock_curval_rnapath_get(struct Key *key, struct KeyBlock *kb);
+
// needed for the GE
-void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, const int mode);
+typedef struct WeightsArrayCache {
+ int num_defgroup_weights;
+ float **defgroup_weights;
+} WeightsArrayCache;
+
+float **BKE_keyblock_get_per_block_weights(struct Object *ob, struct Key *key, struct WeightsArrayCache *cache);
+void BKE_keyblock_free_per_block_weights(struct Key *key, float **per_keyblock_weights, struct WeightsArrayCache *cache);
+void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb,
+ float **per_keyblock_weights, const int mode);
/* conversion functions */
void BKE_key_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index d2d2cb1c2d0..aaac17ac1ed 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -734,12 +734,13 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const
}
}
-void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, const int mode)
+void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb,
+ float **per_keyblock_weights, const int mode)
{
KeyBlock *kb;
int *ofsp, ofs[3], elemsize, b;
char *cp, *poin, *reffrom, *from, elemstr[8];
- int poinsize;
+ int poinsize, keyblock_index;
/* currently always 0, in future key_pointer_size may assign */
ofs[1] = 0;
@@ -763,14 +764,14 @@ void BKE_key_evaluate_relative(const int start, int end, const int tot, char *ba
/* step 2: do it */
- for (kb = key->block.first; kb; kb = kb->next) {
+ for (kb = key->block.first, keyblock_index = 0; kb; kb = kb->next, keyblock_index++) {
if (kb != key->refkey) {
float icuval = kb->curval;
/* only with value, and no difference allowed */
if (!(kb->flag & KEYBLOCK_MUTE) && icuval != 0.0f && kb->totelem == tot) {
KeyBlock *refb;
- float weight, *weights = kb->weights;
+ float weight, *weights = per_keyblock_weights ? per_keyblock_weights[keyblock_index] : NULL;
char *freefrom = NULL, *freereffrom = NULL;
/* reference now can be any block */
@@ -1058,7 +1059,7 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (freek4) MEM_freeN(freek4);
}
-static float *get_weights_array(Object *ob, char *vgroup)
+static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cache)
{
MDeformVert *dvert = NULL;
BMEditMesh *em = NULL;
@@ -1091,7 +1092,21 @@ static float *get_weights_array(Object *ob, char *vgroup)
if (defgrp_index != -1) {
float *weights;
int i;
-
+
+ if (cache) {
+ if (cache->defgroup_weights == NULL) {
+ int num_defgroup = BLI_countlist(&ob->defbase);
+ cache->defgroup_weights =
+ MEM_callocN(sizeof(*cache->defgroup_weights) * num_defgroup,
+ "cached defgroup weights");
+ cache->num_defgroup_weights = num_defgroup;
+ }
+
+ if (cache->defgroup_weights[defgrp_index]) {
+ return cache->defgroup_weights[defgrp_index];
+ }
+ }
+
weights = MEM_mallocN(totvert * sizeof(float), "weights");
if (em) {
@@ -1107,11 +1122,61 @@ static float *get_weights_array(Object *ob, char *vgroup)
}
}
+ if (cache) {
+ cache->defgroup_weights[defgrp_index] = weights;
+ }
+
return weights;
}
return NULL;
}
+float **BKE_keyblock_get_per_block_weights(Object *ob, Key *key, WeightsArrayCache *cache)
+{
+ KeyBlock *keyblock;
+ float **per_keyblock_weights;
+ int keyblock_index;
+
+ per_keyblock_weights =
+ MEM_mallocN(sizeof(*per_keyblock_weights) * key->totkey,
+ "per keyblock weights");
+
+ for (keyblock = key->block.first, keyblock_index = 0;
+ keyblock;
+ keyblock = keyblock->next, keyblock_index++)
+ {
+ per_keyblock_weights[keyblock_index] = get_weights_array(ob, keyblock->vgroup, cache);
+ }
+
+ return per_keyblock_weights;
+}
+
+void BKE_keyblock_free_per_block_weights(Key *key, float **per_keyblock_weights, WeightsArrayCache *cache)
+{
+ int a;
+
+ if (cache) {
+ if (cache->num_defgroup_weights) {
+ for (a = 0; a < cache->num_defgroup_weights; a++) {
+ if (cache->defgroup_weights[a]) {
+ MEM_freeN(cache->defgroup_weights[a]);
+ }
+ }
+ MEM_freeN(cache->defgroup_weights);
+ }
+ cache->defgroup_weights = NULL;
+ }
+ else {
+ for (a = 0; a < key->totkey; a++) {
+ if (per_keyblock_weights[a]) {
+ MEM_freeN(per_keyblock_weights[a]);
+ }
+ }
+ }
+
+ MEM_freeN(per_keyblock_weights);
+}
+
static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int tot)
{
KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
@@ -1144,17 +1209,11 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int
}
else {
if (key->type == KEY_RELATIVE) {
- KeyBlock *kb;
- for (kb = key->block.first; kb; kb = kb->next) {
- kb->weights = get_weights_array(ob, kb->vgroup);
- }
-
- BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, KEY_MODE_DUMMY);
-
- for (kb = key->block.first; kb; kb = kb->next) {
- if (kb->weights) MEM_freeN(kb->weights);
- kb->weights = NULL;
- }
+ WeightsArrayCache cache = {0, NULL};
+ float **per_keyblock_weights;
+ per_keyblock_weights = BKE_keyblock_get_per_block_weights(ob, key, &cache);
+ BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
+ BKE_keyblock_free_per_block_weights(key, per_keyblock_weights, &cache);
}
else {
const float ctime_scaled = key->ctime / 100.0f;
@@ -1197,11 +1256,11 @@ static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const
for (a = 0, nu = cu->nurb.first; nu; nu = nu->next, a += step) {
if (nu->bp) {
step = nu->pntsu * nu->pntsv;
- BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, KEY_MODE_BPOINT);
+ BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, NULL, KEY_MODE_BPOINT);
}
else if (nu->bezt) {
step = 3 * nu->pntsu;
- BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, KEY_MODE_BEZTRIPLE);
+ BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, NULL, KEY_MODE_BEZTRIPLE);
}
else {
step = 0;
@@ -1315,17 +1374,10 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int
}
else {
if (key->type == KEY_RELATIVE) {
- KeyBlock *kb;
-
- for (kb = key->block.first; kb; kb = kb->next)
- kb->weights = get_weights_array(ob, kb->vgroup);
-
- BKE_key_evaluate_relative(0, tot, tot, out, key, actkb, KEY_MODE_DUMMY);
-
- for (kb = key->block.first; kb; kb = kb->next) {
- if (kb->weights) MEM_freeN(kb->weights);
- kb->weights = NULL;
- }
+ float **per_keyblock_weights;
+ per_keyblock_weights = BKE_keyblock_get_per_block_weights(ob, key, NULL);
+ BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
+ BKE_keyblock_free_per_block_weights(key, per_keyblock_weights, NULL);
}
else {
const float ctime_scaled = key->ctime / 100.0f;
@@ -1415,7 +1467,7 @@ float *BKE_key_evaluate_object_ex(Scene *scene, Object *ob, int *r_totelem,
}
if (OB_TYPE_SUPPORT_VGROUP(ob->type)) {
- float *weights = get_weights_array(ob, kb->vgroup);
+ float *weights = get_weights_array(ob, kb->vgroup, NULL);
cp_key(0, tot, tot, out, key, actkb, kb, weights, 0);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index d012a8ac656..4ae48b99bb8 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -178,7 +178,6 @@ int join_mesh_exec(bContext *C, wmOperator *op)
if (kb->data) MEM_freeN(kb->data);
kb->data = MEM_callocN(sizeof(float) * 3 * totvert, "join_shapekey");
kb->totelem = totvert;
- kb->weights = NULL;
}
}
else if (haskey) {
diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h
index 0a09a82b2bb..f5ce3c8d8c1 100644
--- a/source/blender/makesdna/DNA_key_types.h
+++ b/source/blender/makesdna/DNA_key_types.h
@@ -60,7 +60,6 @@ typedef struct KeyBlock {
int uid; /* for meshes only, match the unique number with the customdata layer */
void *data; /* array of shape key values, size is (Key->elemsize * KeyBlock->totelem) */
- float *weights; /* store an aligned array of weights from 'vgroup' */
char name[64]; /* MAX_NAME (unique name, user assigned) */
char vgroup[64]; /* MAX_VGROUP_NAME (optional vertex group), array gets allocated into 'weights' when set */
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp
index 59cf10d326a..5aec3c9e965 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.cpp
+++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp
@@ -159,16 +159,20 @@ bool BL_ShapeDeformer::Update(void)
/* the key coefficient have been set already, we just need to blend the keys */
Object* blendobj = m_gameobj->GetBlendObject();
- // make sure the vertex weight cache is in line with this object
- m_pMeshObject->CheckWeightCache(blendobj);
-
/* we will blend the key directly in m_transverts array: it is used by armature as the start position */
/* m_key can be NULL in case of Modifier deformer */
if (m_key) {
+ WeightsArrayCache cache = {0, NULL};
+ float **per_keyblock_weights;
+
/* store verts locally */
VerifyStorage();
- BKE_key_evaluate_relative(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts, m_key, NULL, 0); /* last arg is ignored */
+ per_keyblock_weights = BKE_keyblock_get_per_block_weights(blendobj, m_key, &cache);
+ BKE_key_evaluate_relative(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts,
+ m_key, NULL, per_keyblock_weights, 0); /* last arg is ignored */
+ BKE_keyblock_free_per_block_weights(m_key, per_keyblock_weights, &cache);
+
m_bDynamic = true;
}
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 2af71c5efa9..92f134c1702 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -125,17 +125,6 @@ RAS_MeshObject::~RAS_MeshObject()
{
vector<RAS_Polygon*>::iterator it;
- if (m_mesh && m_mesh->key)
- {
- KeyBlock *kb;
- // remove the weight cache to avoid memory leak
- for (kb = (KeyBlock *)m_mesh->key->block.first; kb; kb = (KeyBlock *)kb->next) {
- if (kb->weights)
- MEM_freeN(kb->weights);
- kb->weights= NULL;
- }
- }
-
for (it=m_Polygons.begin(); it!=m_Polygons.end(); it++)
delete (*it);
@@ -571,49 +560,3 @@ static int get_def_index(Object* ob, const char* vgroup)
return -1;
}
-
-void RAS_MeshObject::CheckWeightCache(Object* obj)
-{
- KeyBlock *kb;
- int kbindex, defindex;
- MDeformVert *dv= NULL;
- int totvert, i;
- float *weights;
-
- if (!m_mesh->key)
- return;
-
- for (kbindex = 0, kb = (KeyBlock *)m_mesh->key->block.first; kb; kb = kb->next, kbindex++)
- {
- // first check the cases where the weight must be cleared
- if (kb->vgroup[0] == 0 ||
- m_mesh->dvert == NULL ||
- (defindex = get_def_index(obj, kb->vgroup)) == -1) {
- if (kb->weights) {
- MEM_freeN(kb->weights);
- kb->weights = NULL;
- }
- m_cacheWeightIndex[kbindex] = -1;
- } else if (m_cacheWeightIndex[kbindex] != defindex) {
- // a weight array is required but the cache is not matching
- if (kb->weights) {
- MEM_freeN(kb->weights);
- kb->weights = NULL;
- }
-
- dv= m_mesh->dvert;
- totvert= m_mesh->totvert;
-
- weights= (float*)MEM_mallocN(totvert*sizeof(float), "weights");
-
- for (i=0; i < totvert; i++, dv++) {
- weights[i] = defvert_find_weight(dv, defindex);
- }
-
- kb->weights = weights;
- m_cacheWeightIndex[kbindex] = defindex;
- }
- }
-}
-
-
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index d77d0483024..e5ae78d006e 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -83,9 +83,6 @@ public:
virtual ~RAS_MeshObject();
- // for shape keys,
- void CheckWeightCache(struct Object* obj);
-
/* materials */
int NumMaterials();
const STR_String& GetMaterialName(unsigned int matid);