/* Applies weights to given vgroup (defgroup), and optionally add/remove vertices from the group. * If dws is not NULL, it must be an array of MDeformWeight pointers of same length as weights (and * defgrp_idx can then have any value). * If indices is not NULL, it must be an array of same length as weights, mapping to the real * vertex index (in case the weight array does not cover the whole vertices...). */ void weightvg_update_vg(MDeformVert *dvert, int defgrp_idx, MDeformWeight **dws, int num, const int *indices, const float *weights, const bool do_add, const float add_thresh, const bool do_rem, const float rem_thresh) { int i; for (i = 0; i < num; i++) { float w = weights[i]; MDeformVert *dv = &dvert[indices ? indices[i] : i]; MDeformWeight *dw = dws ? dws[i] : ((defgrp_idx >= 0) ? defvert_find_index(dv, defgrp_idx) : NULL); /* Never allow weights out of [0.0, 1.0] range. */ CLAMP(w, 0.0f, 1.0f); /* If the vertex is in this vgroup, remove it if needed, or just update it. */ if (dw != NULL) { if (do_rem && w < rem_thresh) { defvert_remove_group(dv, dw); } else { dw->weight = w; } } /* Else, add it if needed! */ else if (do_add && w > add_thresh) { defvert_add_index_notest(dv, defgrp_idx, w); } } }
static void vgroups_datatransfer_interp( const CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, const int count, const float mix_factor) { MDeformVert **data_src = (MDeformVert **)sources; MDeformVert *data_dst = (MDeformVert *)dest; const int idx_src = laymap->data_src_n; const int idx_dst = laymap->data_dst_n; const int mix_mode = laymap->mix_mode; int i, j; MDeformWeight *dw_src; MDeformWeight *dw_dst = defvert_find_index(data_dst, idx_dst); float weight_src = 0.0f, weight_dst = 0.0f; if (sources) { for (i = count; i--;) { for (j = data_src[i]->totweight; j--;) { if ((dw_src = &data_src[i]->dw[j])->def_nr == idx_src) { weight_src += dw_src->weight * weights[i]; break; } } } } if (dw_dst) { weight_dst = dw_dst->weight; } else if (mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD) { return; /* Do not affect destination. */ } weight_src = data_transfer_interp_float_do(mix_mode, weight_dst, weight_src, mix_factor); CLAMP(weight_src, 0.0f, 1.0f); if (!dw_dst) { defvert_add_index_notest(data_dst, idx_dst, weight_src); } else { dw_dst->weight = weight_src; } }