コード例 #1
0
/* 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);
		}
	}
}
コード例 #2
0
ファイル: deform.c プロジェクト: Brachi/blender
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;
	}
}