Changeset View
Standalone View
source/blender/blenkernel/intern/object_deform.c
| Context not available. | |||||
| BKE_object_defgroup_remove_all_ex(ob, false); | BKE_object_defgroup_remove_all_ex(ob, false); | ||||
| } | } | ||||
| int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len) | |||||
| { | |||||
| /* Build src to merged mapping of vgroup indices. */ | |||||
campbellbarton: Best do an early exit, if either objects have no groups (`BLI_listbase_is_empty`) | |||||
| if (BLI_listbase_is_empty(&ob_src->defbase) || BLI_listbase_is_empty(&ob_dst->defbase)) { | |||||
| *r_map_len = 0; | |||||
| return NULL; | |||||
| } | |||||
| bDeformGroup *dg_src; | |||||
| *r_map_len = BLI_listbase_count(&ob_src->defbase); | |||||
| int *vgroup_index_map = MEM_malloc_arrayN(*r_map_len, sizeof(*vgroup_index_map), "defgroup index map create"); | |||||
| bool is_vgroup_remap_needed = false; | |||||
| int b; | |||||
| for (dg_src = ob_src->defbase.first, b = 0; dg_src; dg_src = dg_src->next, b++) { | |||||
| vgroup_index_map[b] = defgroup_name_index(ob_dst, dg_src->name); | |||||
| is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[b] != b); | |||||
| } | |||||
| if (!is_vgroup_remap_needed) { | |||||
| MEM_freeN(vgroup_index_map); | |||||
| vgroup_index_map = NULL; | |||||
| *r_map_len = 0; | |||||
| } | |||||
Done Inline Actionsmap can be const, also code style re: * placement. campbellbarton: `map` can be const, also code style re: `*` placement. | |||||
| return vgroup_index_map; | |||||
| } | |||||
| void BKE_object_defgroup_index_map_apply(MDeformVert *dvert, int dvert_len, const int *map, int map_len) | |||||
| { | |||||
| if (map == NULL || map_len <= 0) { | |||||
| return; | |||||
| } | |||||
Done Inline ActionsCan make this a single check by doing: (uint)def_nr < map_len. campbellbarton: Can make this a single check by doing: `(uint)def_nr < map_len`. | |||||
| for (int a = 0; a < dvert_len; a++) { | |||||
| int totweight = dvert[a].totweight; | |||||
| for (int b = 0; b < totweight; b++) { | |||||
| int def_nr = dvert[a].dw[b].def_nr; | |||||
| if ((uint)def_nr < (uint)map_len && map[def_nr] != -1) { /* -1: no remapping */ | |||||
Done Inline ActionsCode style: spaces around operators. campbellbarton: Code style: spaces around operators. | |||||
| dvert[a].dw[b].def_nr = map[def_nr]; | |||||
| } | |||||
| else { | |||||
| /* remove by overwriting with the last element */ | |||||
| dvert[a].dw[b] = dvert[a].dw[totweight - 1]; | |||||
| totweight--; | |||||
| b--; /* repeat the current iteration */ | |||||
| } | |||||
Not Done Inline ActionsI have two questions here:
All this sounds a bit inconsistent to me? Or am I missing something here? mont29: I have two questions here:
1) How could `def_nr` be above `map_len`, since map_len is… | |||||
Not Done Inline Actions1: (I just checked, apparently the Boolean Modifier exhibits the same behavior, maybe some others too.) 2: Foaly: 1:
`def_nr` is //not// guaranteed to be in bounds. I can (in the old code) create a mesh with… | |||||
| } | |||||
| if (totweight != dvert[a].totweight) { /* changed size? realloc! */ | |||||
| if (totweight == 0) { | |||||
Done Inline ActionsIs MEM_reallocN_id the right function for reallocation here? Foaly: Is `MEM_reallocN_id` the right function for reallocation here? | |||||
Done Inline ActionsJust use MEM_reallocN campbellbarton: Just use `MEM_reallocN` | |||||
Done Inline Actionstotweight may now be 0, shouldn’t we rather use MEM_SAFE_FREE in that case? Especially since, given how our guardedalloc works, we’d then alloc a non-zero memory with zero usable space (just control structs)… mont29: `totweight` may now be `0`, shouldn’t we rather use `MEM_SAFE_FREE` in that case? Especially… | |||||
| MEM_SAFE_FREE(dvert[a].dw); | |||||
| } | |||||
| else { | |||||
| dvert[a].dw = MEM_reallocN(dvert[a].dw, sizeof(*dvert[a].dw) * totweight); | |||||
| } | |||||
| dvert[a].totweight = totweight; | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Get MDeformVert vgroup data from given object. Should only be used in Object mode. | * Get MDeformVert vgroup data from given object. Should only be used in Object mode. | ||||
| Context not available. | |||||
Best do an early exit, if either objects have no groups (BLI_listbase_is_empty)