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:
authorCampbell Barton <ideasman42@gmail.com>2013-07-22 22:01:27 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-07-22 22:01:27 +0400
commite590abfb87aa3ee14e6946350d55d8960e70dab7 (patch)
tree5ce5e11cc14f64d7ebcdd737e34b8aac34190070 /source/blender/blenkernel/intern/customdata.c
parent90fdaa82195c2eb9b6412ffa8b4f4f70e16a35dc (diff)
optimization:
- halve the number of allocs in layerInterp_mdeformvert list creation. - use direct loop access in emDM_copyLoopArray
Diffstat (limited to 'source/blender/blenkernel/intern/customdata.c')
-rw-r--r--source/blender/blenkernel/intern/customdata.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 92b3c26c91a..d69ec6a9597 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -218,9 +218,16 @@ static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
static void layerInterp_mdeformvert(void **sources, const float *weights,
const float *UNUSED(sub_weights), int count, void *dest)
{
+ /* a single linked list of MDeformWeight's
+ * use this to avoid double allocs (which LinkNode would do) */
+ struct MDeformWeight_Link {
+ struct MDeformWeight_Link *next;
+ MDeformWeight dw;
+ };
+
MDeformVert *dvert = dest;
- LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
- LinkNode *node;
+ struct MDeformWeight_Link *dest_dwlink = NULL;
+ struct MDeformWeight_Link *node;
int i, j, totweight;
if (count <= 0) return;
@@ -238,8 +245,8 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
if (weight == 0.0f)
continue;
- for (node = dest_dw; node; node = node->next) {
- MDeformWeight *tmp_dw = (MDeformWeight *)node->link;
+ for (node = dest_dwlink; node; node = node->next) {
+ MDeformWeight *tmp_dw = &node->dw;
if (tmp_dw->def_nr == dw->def_nr) {
tmp_dw->weight += weight;
@@ -249,11 +256,14 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
/* if this def_nr is not in the list, add it */
if (!node) {
- MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
- "layerInterp_mdeformvert tmp_dw");
- tmp_dw->def_nr = dw->def_nr;
- tmp_dw->weight = weight;
- BLI_linklist_prepend(&dest_dw, tmp_dw);
+ struct MDeformWeight_Link *tmp_dwlink = MEM_mallocN(sizeof(*tmp_dwlink), __func__);
+ tmp_dwlink->dw.def_nr = dw->def_nr;
+ tmp_dwlink->dw.weight = weight;
+
+ /* inline linklist */
+ tmp_dwlink->next = dest_dwlink;
+ dest_dwlink = tmp_dwlink;
+
totweight++;
}
}
@@ -262,20 +272,31 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
/* delay writing to the destination incase dest is in sources */
/* now we know how many unique deform weights there are, so realloc */
- if (dvert->dw) MEM_freeN(dvert->dw);
+ if (dvert->dw && (dvert->totweight == totweight)) {
+ /* pass (fastpath if we don't need to realloc) */
+ }
+ else {
+ if (dvert->dw) {
+ MEM_freeN(dvert->dw);
+ }
+
+ if (totweight) {
+ dvert->dw = MEM_mallocN(sizeof(*dvert->dw) * totweight, __func__);
+ }
+ }
if (totweight) {
- dvert->dw = MEM_mallocN(sizeof(*dvert->dw) * totweight,
- "layerInterp_mdeformvert dvert->dw");
+ struct MDeformWeight_Link *node_next;
dvert->totweight = totweight;
-
- for (i = 0, node = dest_dw; node; node = node->next, ++i)
- dvert->dw[i] = *((MDeformWeight *)node->link);
+ for (i = 0, node = dest_dwlink; node; node = node_next, i++) {
+ node_next = node->next;
+ dvert->dw[i] = node->dw;
+ MEM_freeN(node);
+ }
}
- else
+ else {
memset(dvert, 0, sizeof(*dvert));
-
- BLI_linklist_free(dest_dw, MEM_freeN);
+ }
}
static void layerCopy_tface(const void *source, void *dest, int count)