#include "BLI_utildefines.h"
- void defgroup_copy_list (ListBase *outbase, ListBase *inbase)
+#include "BLI_cellalloc.h"
+
+
+ void defgroup_copy_list(ListBase *outbase, ListBase *inbase)
{
bDeformGroup *defgroup, *defgroupn;
}
/* copy & overwrite weights */
- void defvert_copy (MDeformVert *dvert_r, const MDeformVert *dvert)
+ void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
{
- if(dvert_r->totweight == dvert->totweight) {
- if(dvert->totweight)
- memcpy(dvert_r->dw, dvert->dw, dvert->totweight * sizeof(MDeformWeight));
+ if (dvert_dst->totweight == dvert_src->totweight) {
+ if (dvert_src->totweight)
+ memcpy(dvert_dst->dw, dvert_src->dw, dvert_src->totweight * sizeof(MDeformWeight));
}
else {
- if(dvert_r->dw)
- BLI_cellalloc_free(dvert_r->dw);
+ if (dvert_dst->dw)
- MEM_freeN(dvert_dst->dw);
++ BLI_cellalloc_free(dvert_dst->dw);
- if(dvert->totweight)
- dvert_r->dw= BLI_cellalloc_dupalloc(dvert->dw);
+ if (dvert_src->totweight)
- dvert_dst->dw= MEM_dupallocN(dvert_src->dw);
++ dvert_dst->dw= BLI_cellalloc_dupalloc(dvert_src->dw);
else
- dvert_r->dw= NULL;
+ dvert_dst->dw= NULL;
+
+ dvert_dst->totweight = dvert_src->totweight;
+ }
+ }
+
+ /* copy an index from one dvert to another
+ * - do nothing if neither are set.
+ * - add destination weight if needed.
+ */
+ void defvert_copy_index(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const int defgroup)
+ {
+ MDeformWeight *dw_src, *dw_dst;
+
+ dw_src= defvert_find_index(dvert_src, defgroup);
+
+ if (dw_src) {
+ /* source is valid, verify destination */
+ dw_dst= defvert_verify_index(dvert_dst, defgroup);
+ dw_dst->weight= dw_src->weight;
+ }
+ else {
+ /* source was NULL, assign zero, could also remove */
+ dw_dst= defvert_find_index(dvert_dst, defgroup);
- dvert_r->totweight = dvert->totweight;
+ if (dw_dst) {
+ dw_dst->weight= 0.0f;
+ }
}
}
/* Ensures that mv has a deform weight entry for the specified defweight group */
/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
- MDeformWeight *defvert_verify_index(MDeformVert *dv, const int defgroup)
+ MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup)
{
- MDeformWeight *newdw;
+ MDeformWeight *dw_new;
/* do this check always, this function is used to check for it */
- if(!dv || defgroup < 0)
+ if (!dvert || defgroup < 0)
return NULL;
- newdw= defvert_find_index(dv, defgroup);
- if(newdw)
- return newdw;
+ dw_new= defvert_find_index(dvert, defgroup);
+ if (dw_new)
+ return dw_new;
- newdw= BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
- if(dv->dw) {
- memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
- BLI_cellalloc_free(dv->dw);
- dw_new= MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
++ dw_new= BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
+ if (dvert->dw) {
+ memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
- MEM_freeN(dvert->dw);
++ BLI_cellalloc_free(dvert->dw);
}
- dv->dw= newdw;
- newdw += dv->totweight;
- newdw->weight= 0.0f;
- newdw->def_nr= defgroup;
+ dvert->dw= dw_new;
+ dw_new += dvert->totweight;
+ dw_new->weight= 0.0f;
+ dw_new->def_nr= defgroup;
/* Group index */
- dv->totweight++;
+ dvert->totweight++;
+
+ return dw_new;
+ }
+
+ /* Removes the given vertex from the vertex group, specified either by its defgrp_idx,
+ * or directly by its MDeformWeight pointer, if dw is not NULL.
+ * WARNING: This function frees the given MDeformWeight, do not use it afterward! */
+ void defvert_remove_index(MDeformVert *dvert, int defgroup, MDeformWeight *dw)
+ {
+ MDeformWeight *dw_new;
+ int i;
+
+ /* Get index of removed MDeformWeight. */
+ if (dw == NULL) {
+ dw = dvert->dw;
+ for (i = dvert->totweight; i > 0; i--, dw++) {
+ if (dw->def_nr == defgroup)
+ break;
+ }
+ i--;
+ }
+ else {
+ i = dw - dvert->dw;
+ /* Security check! */
+ if(i < 0 || i >= dvert->totweight)
+ return;
+ }
- return newdw;
+ dvert->totweight--;
+ /* If there are still other deform weights attached to this vert then remove
+ * this deform weight, and reshuffle the others.
+ */
+ if (dvert->totweight) {
- dw_new = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), __func__);
++ dw_new = BLI_cellalloc_malloc(sizeof(MDeformWeight)*(dvert->totweight), __func__);
+ if (dvert->dw){
+ memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*i);
+ memcpy(dw_new+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
- MEM_freeN(dvert->dw);
++ BLI_cellalloc_free(dvert->dw);
+ }
+ dvert->dw = dw_new;
+ }
+ else {
+ /* If there are no other deform weights left then just remove this one. */
- MEM_freeN(dvert->dw);
++ BLI_cellalloc_free(dvert->dw);
+ dvert->dw = NULL;
+ }
}