static void editvert_mirror_update(Object *ob, EditVert *eve, int def_nr, int index) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); EditVert *eve_mirr; eve_mirr= editmesh_get_x_mirror_vert(ob, em, eve, eve->co, index); if(eve_mirr && eve_mirr != eve) { MDeformVert *dvert_src= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); MDeformVert *dvert_dst= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT); if(dvert_dst) { if(def_nr == -1) { /* all vgroups, add groups where neded */ int *flip_map= defgroup_flip_map(ob, 1); defvert_sync_mapped(dvert_dst, dvert_src, flip_map, 1); MEM_freeN(flip_map); } else { /* single vgroup */ MDeformWeight *dw= defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1)); if(dw) { dw->weight= defvert_find_weight(dvert_src, def_nr); } } } } }
static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, PyObject *value) { if (PyIndex_Check(key)) { int i; i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) { return -1; } if (value) { /* dvert[group_index] = 0.5 */ if (i < 0) { PyErr_SetString(PyExc_KeyError, "BMDeformVert[key] = x: " "weight keys can't be negative"); return -1; } else { MDeformWeight *dw = defvert_verify_index(self->data, i); const float f = PyFloat_AsDouble(value); if (f == -1 && PyErr_Occurred()) { // parsed key not a number PyErr_SetString(PyExc_TypeError, "BMDeformVert[key] = x: " "assigned value not a number"); return -1; } dw->weight = clamp_f(f, 0.0f, 1.0f); } } else { /* del dvert[group_index] */ MDeformWeight *dw = defvert_find_index(self->data, i); if (dw == NULL) { PyErr_SetString(PyExc_KeyError, "del BMDeformVert[key]: " "key not found"); } defvert_remove_group(self->data, dw); } return 0; } else { PyErr_Format(PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name); return -1; } }
/* only sync over matching weights, don't add or remove groups * warning, loop within loop. */ void defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const bool use_verify) { if (dvert_src->totweight && dvert_dst->totweight) { int i; MDeformWeight *dw_src; for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) { MDeformWeight *dw_dst; if (use_verify) dw_dst = defvert_verify_index(dvert_dst, dw_src->def_nr); else dw_dst = defvert_find_index(dvert_dst, dw_src->def_nr); if (dw_dst) { dw_dst->weight = dw_src->weight; } } } }
/* be sure all flip_map values are valid */ void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const int *flip_map, int use_verify) { if(dvert->totweight && dvert_r->totweight) { int i; MDeformWeight *dw; for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) { MDeformWeight *dw_r; if(use_verify) dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]); else dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]); if(dw_r) { dw_r->weight= dw->weight; } } } }
/* be sure all flip_map values are valid */ void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const int *flip_map, const int flip_map_len, const bool use_verify) { if (dvert_src->totweight && dvert_dst->totweight) { int i; MDeformWeight *dw_src; for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) { if (dw_src->def_nr < flip_map_len) { MDeformWeight *dw_dst; if (use_verify) dw_dst = defvert_verify_index(dvert_dst, flip_map[dw_src->def_nr]); else dw_dst = defvert_find_index(dvert_dst, flip_map[dw_src->def_nr]); if (dw_dst) { dw_dst->weight = dw_src->weight; } } } } }
/* 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); if (dw_dst) { dw_dst->weight = 0.0f; } } }
void defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_len) { MDeformWeight *dw, *dw_cpy; float weight; int i, totweight = dvert->totweight; /* copy weights */ for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) { if (dw->def_nr < flip_map_len) { if (flip_map[dw->def_nr] >= 0) { /* error checkers complain of this but we'll never get NULL return */ dw_cpy = defvert_verify_index(dvert, flip_map[dw->def_nr]); dw = &dvert->dw[i]; /* in case array got realloced */ /* distribute weights: if only one of the vertex groups was * assigned this will halve the weights, otherwise it gets * evened out. this keeps it proportional to other groups */ weight = 0.5f * (dw_cpy->weight + dw->weight); dw_cpy->weight = weight; dw->weight = weight; } } } }