forked from bartvdbraak/blender
optimization:
- halve the number of allocs in layerInterp_mdeformvert list creation. - use direct loop access in emDM_copyLoopArray
This commit is contained in:
parent
90fdaa8219
commit
e590abfb87
@ -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,
|
||||
"layerInterp_mdeformvert dvert->dw");
|
||||
dvert->totweight = totweight;
|
||||
|
||||
for (i = 0, node = dest_dw; node; node = node->next, ++i)
|
||||
dvert->dw[i] = *((MDeformWeight *)node->link);
|
||||
dvert->dw = MEM_mallocN(sizeof(*dvert->dw) * totweight, __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
memset(dvert, 0, sizeof(*dvert));
|
||||
|
||||
BLI_linklist_free(dest_dw, MEM_freeN);
|
||||
if (totweight) {
|
||||
struct MDeformWeight_Link *node_next;
|
||||
dvert->totweight = totweight;
|
||||
for (i = 0, node = dest_dwlink; node; node = node_next, i++) {
|
||||
node_next = node->next;
|
||||
dvert->dw[i] = node->dw;
|
||||
MEM_freeN(node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
memset(dvert, 0, sizeof(*dvert));
|
||||
}
|
||||
}
|
||||
|
||||
static void layerCopy_tface(const void *source, void *dest, int count)
|
||||
|
@ -1420,18 +1420,20 @@ static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
|
||||
{
|
||||
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
|
||||
BMesh *bm = bmdm->em->bm;
|
||||
BMIter iter, liter;
|
||||
BMIter iter;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
|
||||
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BMLoop *l_iter, *l_first;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
|
||||
do {
|
||||
r_loop->v = BM_elem_index_get(l->v);
|
||||
r_loop->e = BM_elem_index_get(l->e);
|
||||
r_loop++;
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user