diff options
Diffstat (limited to 'source/blender/blenkernel/intern/deform.c')
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 188 |
1 files changed, 145 insertions, 43 deletions
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 6670c3359d7..7052e0a7d25 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -107,17 +107,37 @@ bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup) return outgroup; } -/* overwrite weights filtered by vgroup_subset +/** + * Overwrite weights filtered by vgroup_subset. * - do nothing if neither are set. * - add destination weight if needed */ -void defvert_copy_subset(MDeformVert *dvert_dst, const MDeformVert *dvert_src, - const bool *vgroup_subset, const int vgroup_tot) +void defvert_copy_subset( + MDeformVert *dvert_dst, const MDeformVert *dvert_src, + const bool *vgroup_subset, const int vgroup_tot) { int defgroup; for (defgroup = 0; defgroup < vgroup_tot; defgroup++) { if (vgroup_subset[defgroup]) { - defvert_copy_index(dvert_dst, dvert_src, defgroup); + defvert_copy_index(dvert_dst, defgroup, dvert_src, defgroup); + } + } +} + +/** + * Overwrite weights filtered by vgroup_subset and with mirroring specified by the flip map + * - do nothing if neither are set. + * - add destination weight if needed + */ +void defvert_mirror_subset( + MDeformVert *dvert_dst, const MDeformVert *dvert_src, + const bool *vgroup_subset, const int vgroup_tot, + const int *flip_map, const int flip_map_len) +{ + int defgroup; + for (defgroup = 0; defgroup < vgroup_tot && defgroup < flip_map_len; defgroup++) { + if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) { + defvert_copy_index(dvert_dst, flip_map[defgroup], dvert_src, defgroup); } } } @@ -141,24 +161,27 @@ void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src) } } -/* copy an index from one dvert to another +/** + * 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) +void defvert_copy_index( + MDeformVert *dvert_dst, const int defgroup_dst, + const MDeformVert *dvert_src, const int defgroup_src) { MDeformWeight *dw_src, *dw_dst; - dw_src = defvert_find_index(dvert_src, defgroup); + dw_src = defvert_find_index(dvert_src, defgroup_src); if (dw_src) { /* source is valid, verify destination */ - dw_dst = defvert_verify_index(dvert_dst, defgroup); + dw_dst = defvert_verify_index(dvert_dst, defgroup_dst); dw_dst->weight = dw_src->weight; } else { /* source was NULL, assign zero, could also remove */ - dw_dst = defvert_find_index(dvert_dst, defgroup); + dw_dst = defvert_find_index(dvert_dst, defgroup_dst); if (dw_dst) { dw_dst->weight = 0.0f; @@ -166,7 +189,8 @@ void defvert_copy_index(MDeformVert *dvert_dst, const MDeformVert *dvert_src, co } } -/* only sync over matching weights, don't add or remove groups +/** + * 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) @@ -186,9 +210,12 @@ void defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const bo } } -/* 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) +/** + * 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; @@ -207,7 +234,9 @@ void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src, } } -/* be sure all flip_map values are valid */ +/** + * be sure all flip_map values are valid + */ void defvert_remap(MDeformVert *dvert, int *map, const int map_len) { MDeformWeight *dw = dvert->dw; @@ -291,10 +320,13 @@ void defvert_normalize(MDeformVert *dvert) } } -/* Same as defvert_normalize() if the locked vgroup is not a member of the subset */ -void defvert_normalize_lock_single(MDeformVert *dvert, - const bool *vgroup_subset, const int vgroup_tot, - const int def_nr_lock) +/** + * Same as defvert_normalize() if the locked vgroup is not a member of the subset + */ +void defvert_normalize_lock_single( + MDeformVert *dvert, + const bool *vgroup_subset, const int vgroup_tot, + const int def_nr_lock) { if (dvert->totweight == 0) { /* nothing */ @@ -345,7 +377,9 @@ void defvert_normalize_lock_single(MDeformVert *dvert, } } -/* Same as defvert_normalize() if no locked vgroup is a member of the subset */ +/** + * Same as defvert_normalize() if no locked vgroup is a member of the subset + */ void defvert_normalize_lock_map( MDeformVert *dvert, const bool *vgroup_subset, const int vgroup_tot, @@ -357,7 +391,7 @@ void defvert_normalize_lock_map( else if (dvert->totweight == 1) { MDeformWeight *dw = dvert->dw; if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { - if (LIKELY(defbase_tot >= 1) && lock_flags[0]) { + if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) { dw->weight = 1.0f; } } @@ -449,7 +483,9 @@ int defgroup_name_index(Object *ob, const char *name) return (name) ? BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) : -1; } -/* note, must be freed */ +/** + * \note caller must free. + */ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default) { int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase); @@ -488,7 +524,9 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default) } } -/* note, must be freed */ +/** + * \note caller must free. + */ int *defgroup_flip_map_single(Object *ob, int *flip_map_len, const bool use_default, int defgroup) { int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase); @@ -573,8 +611,10 @@ static bool is_char_sep(const char c) return ELEM(c, '.', ' ', '-', '_'); } -/* based on BLI_split_dirfile() / os.path.splitext(), "a.b.c" -> ("a.b", ".c") */ - +/** + * based on `BLI_split_dirfile()` / `os.path.splitext()`, + * `"a.b.c"` -> (`"a.b"`, `".c"`). + */ void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char body[MAX_VGROUP_NAME], char suf[MAX_VGROUP_NAME]) { size_t len = BLI_strnlen(string, MAX_VGROUP_NAME); @@ -593,7 +633,9 @@ void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char body[MAX_V memcpy(body, string, len + 1); } -/* "a.b.c" -> ("a.", "b.c") */ +/** + * `"a.b.c"` -> (`"a."`, `"b.c"`) + */ void BKE_deform_split_prefix(const char string[MAX_VGROUP_NAME], char pre[MAX_VGROUP_NAME], char body[MAX_VGROUP_NAME]) { size_t len = BLI_strnlen(string, MAX_VGROUP_NAME); @@ -613,9 +655,13 @@ void BKE_deform_split_prefix(const char string[MAX_VGROUP_NAME], char pre[MAX_VG BLI_strncpy(body, string, len); } -/* finds the best possible flipped name. For renaming; check for unique names afterwards */ -/* if strip_number: removes number extensions - * note: don't use sizeof() for 'name' or 'from_name' */ +/** + * Finds the best possible flipped name. For renaming; check for unique names afterwards. + * + * if strip_number: removes number extensions + * + * \note don't use sizeof() for 'name' or 'from_name'. + */ void BKE_deform_flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], const bool strip_number) { @@ -745,7 +791,8 @@ float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup) return dw ? dw->weight : 0.0f; } -/* take care with this the rationale is: +/** + * Take care with this the rationale is: * - if the object has no vertex group. act like vertex group isn't set and return 1.0, * - if the vertex group exists but the 'defgroup' isn't found on this vertex, _still_ return 0.0 * @@ -779,8 +826,11 @@ MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup) return NULL; } -/* 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 */ +/** + * 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 *dvert, const int defgroup) { MDeformWeight *dw_new; @@ -813,8 +863,11 @@ MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup) /* TODO. merge with code above! */ -/* Adds the given vertex to the specified vertex group, with given weight. - * warning, this does NOT check for existing, assume caller already knows its not there */ +/** + * Adds the given vertex to the specified vertex group, with given weight. + * + * \warning this does NOT check for existing, assume caller already knows its not there. + */ void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight) { MDeformWeight *dw_new; @@ -838,8 +891,11 @@ void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weig } -/* Removes the given vertex from the vertex group. - * WARNING: This function frees the given MDeformWeight, do not use it afterward! */ +/** + * Removes the given vertex from the vertex group. + * + * \warning This function frees the given MDeformWeight, do not use it afterward! + */ void defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw) { if (dvert && dw) { @@ -919,8 +975,45 @@ bool defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_ return true; } + +/** + * \return The representative weight of a multipaint group, used for + * viewport colors and actual painting. + * + * Result equal to sum of weights with auto normalize, and average otherwise. + * Value is not clamped, since painting relies on multiplication being always + * commutative with the collective weight function. + */ +float BKE_defvert_multipaint_collective_weight( + const struct MDeformVert *dv, int defbase_tot, + const bool *defbase_sel, int defbase_tot_sel, bool do_autonormalize) +{ + int i; + float total = 0.0f; + const MDeformWeight *dw = dv->dw; + + for (i = dv->totweight; i != 0; i--, dw++) { + /* in multipaint, get the average if auto normalize is inactive + * get the sum if it is active */ + if (dw->def_nr < defbase_tot) { + if (defbase_sel[dw->def_nr]) { + total += dw->weight; + } + } + } + + if (do_autonormalize == false) { + total /= defbase_tot_sel; + } + + return total; +} + + /* -------------------------------------------------------------------- */ -/* Defvert Array functions */ + +/** \name Defvert Array functions + * \{ */ void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int copycount) { @@ -987,9 +1080,10 @@ void BKE_defvert_extract_vgroup_to_vertweights( } } -/* The following three make basic interpolation, using temp vert_weights array to avoid looking up same weight - * several times. */ - +/** + * The following three make basic interpolation, + * using temp vert_weights array to avoid looking up same weight several times. + */ void BKE_defvert_extract_vgroup_to_edgeweights( MDeformVert *dvert, const int defgroup, const int num_verts, MEdge *edges, const int num_edges, float *r_weights, const bool invert_vgroup) @@ -1065,7 +1159,13 @@ void BKE_defvert_extract_vgroup_to_polyweights( } } -/*********** Data Transfer **********/ +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name Data Transfer + * \{ */ static void vgroups_datatransfer_interp( const CustomDataTransferLayerMap *laymap, void *dest, @@ -1163,7 +1263,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst( } data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights, data_src, data_dst, idx_src, idx_src, - elem_size, 0, 0, 0, vgroups_datatransfer_interp); + elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL); } } break; @@ -1211,7 +1311,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst( data_transfer_layersmapping_add_item( r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights, data_src, data_dst, idx_src, idx_dst, - elem_size, 0, 0, 0, vgroups_datatransfer_interp); + elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL); } } break; @@ -1317,7 +1417,7 @@ bool data_transfer_layersmapping_vgroups( data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights, data_src, data_dst, idx_src, idx_dst, - elem_size, 0, 0, 0, vgroups_datatransfer_interp); + elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL); } } else { @@ -1353,3 +1453,5 @@ bool data_transfer_layersmapping_vgroups( return true; } + +/** \} */ |