Page MenuHome

Edit mode normalize fails to respect locked groups
ClosedPublic

Authored by Nate Rupsis (nrupsis) on Jun 29 2022, 1:24 AM.

Diff Detail

Repository
rB Blender

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Nate Rupsis (nrupsis) retitled this revision from initial mirror fix to WIP: Edit mode normalize fails to respect non deforming groups or locked groups.Jun 29 2022, 1:24 AM

This patch currently breaks mirror normalization


  • only mirror normilized for that vgroup

Okay, dumping my findings here.

Walking down the method call stack: ED_mesh_defvert_mirror_update_em -> editbmesh_get_x_mirror_vert -> mesh_defvert_mirror_update_internal
// object_vgroup.c

(inside mesh_defvert_mirror_update_internal) def_nr is the index of the vertex group (vgroup), and a value of -1 indicates that all vgroups should be mirrored. This doesn't account for locked groups & non deforming groups.

Since it calls out to BKE_object_defgroup_flip_map (a Blender Kernel method) to get the flipped map before syncing, it suggests to me that locked / non-deforming groups aren't being respected from a low level.

Nate Rupsis (nrupsis) planned changes to this revision.Jul 19 2022, 4:32 PM
  • only mirror normilized for that vgroup
  • hacky locked groups work
Campbell Barton (campbellbarton) requested changes to this revision.EditedJul 28 2022, 4:51 AM

Discussed how this might be resolved with Nate and our conclusion was to make a flip_map that excludes locked groups.
At least I think this approach is more general but needs to be tested - along with checking all uses of BKE_object_defgroup_flip_map to check which uses of BKE_object_defgroup_flip_map should include locked groups and which should not - something that should be documented as part of a patch that introduces this distinction.

This revision now requires changes to proceed.Jul 28 2022, 4:51 AM
  • adding new BKE method for only unlocked groups
Campbell Barton (campbellbarton) requested changes to this revision.Aug 2 2022, 6:48 AM
Campbell Barton (campbellbarton) added inline comments.
source/blender/blenkernel/BKE_deform.h
61

Prefer name BKE_object_defgroup_flip_map_unlocked (auto-completes more usefully).

source/blender/blenkernel/intern/deform.c
622–675

This is a reasonable amount of code duplication, suggest to have a static function object_defgroup_unlocked_flip_map_ex(ob, flip_map_len, use_default, use_only_unlocked). Then there there should only need to be minor differences without having to duplicate logic.

If including the unlocked logic in-line complicates things too much, it would also be fine to clear locked groups in a second loop when use_only_unlocked is set. Even though that incurs redundant calculation, this particular function I don't see it causing any differences users are going to notice.

This revision now requires changes to proceed.Aug 2 2022, 6:48 AM

The latest patch fixes the locking of groups. Locked groups will not be normalized.

Daniel Salazar (zanqdo) accepted this revision.EditedAug 4 2022, 12:40 AM
Daniel Salazar (zanqdo) retitled this revision from WIP: Edit mode normalize fails to respect non deforming groups or locked groups to WIP: Edit mode normalize fails to respect locked groups.

Changed the title to make this a smaller patch fixing only the locking groups and separated the non deforming groups issue to a new task T100187

source/blender/blenkernel/BKE_deform.h
61

Was unsure of the name, I like this better. Thanks!

source/blender/blenkernel/intern/deform.c
622–675

I 100% agree there is too much duplication of logic (was throwing this up for some people to test). I do like the idea of abstracting the core logic into its own method. I'll go ahead and do that.

Nate Rupsis (nrupsis) updated this revision to Diff 54510.EditedAug 8 2022, 10:52 PM
  • refactoring BKE_object_defgroup_flip_map/unlocked to share common logic
Nate Rupsis (nrupsis) marked 2 inline comments as done.Aug 8 2022, 10:54 PM
Nate Rupsis (nrupsis) retitled this revision from WIP: Edit mode normalize fails to respect locked groups to Edit mode normalize fails to respect locked groups.Aug 8 2022, 11:36 PM
Campbell Barton (campbellbarton) requested changes to this revision.Aug 9 2022, 5:15 AM

Minor request, otherwise LGTM.

source/blender/blenkernel/intern/deform.c
581

flip_map_len can be passed in as a return argument & calculated in this funciton.

if (use_only_unlocked) {
  /* count unlocked. */
}
else {
  /* use `defbase_tot` */
}

Avoids 2x calls to BLI_listbase_count for the common code-path too (while not a problem, it's not necessary either).

This revision now requires changes to proceed.Aug 9 2022, 5:15 AM
  • removing unneeded BLI_listbase_count calls
This revision is now accepted and ready to land.Aug 10 2022, 5:16 AM
Campbell Barton (campbellbarton) requested changes to this revision.EditedAug 10 2022, 5:34 AM

Checking over the patch and there is infact incorrect logic.

flip_num = BKE_object_defgroup_name_index(ob, name_flip);

if (flip_num != -1) {
  map[defgroup] = flip_num;
  map[flip_num] = defgroup;
}

flip_num uses the full range of defbase_tot.

I think the correct solution here is to keep the map the same size and just not map any groups which are locked. (keep the value -1 if either are locked).


An alternative could be to create a map between both values but this doesn't seem worthwhile.

This revision now requires changes to proceed.Aug 10 2022, 5:34 AM
Nate Rupsis (nrupsis) marked an inline comment as done.

Allocating full map size

Campbell Barton (campbellbarton) requested changes to this revision.Aug 29 2022, 3:30 AM
Campbell Barton (campbellbarton) added inline comments.
source/blender/blenkernel/intern/deform.c
583–594

There is no need to count unlocked groups now as flip_map_len doesn't change anymore for unlocked groups.

589–590

Assigning an allocation to an int should warn, e.g:

source/blender/blenkernel/intern/deform.c: In function ‘object_defgroup_unlocked_flip_map_ex’:
source/blender/blenkernel/intern/deform.c:602:21: warning: initialization of ‘int’ from ‘void *’ makes integer from pointer without a cast [-Wint-conversion]
  602 |   int i, flip_num = MEM_mallocN(*flip_map_len * sizeof(int), __func__);
      |                     ^~~~~~~~~~~
This revision now requires changes to proceed.Aug 29 2022, 3:30 AM
  • cleaning unlocked count code, and fixing compiler warnings
Campbell Barton (campbellbarton) requested changes to this revision.Sep 1 2022, 1:57 AM

Te patch makes some unnecessary changes, besides that think it's fine.

source/blender/blenkernel/intern/deform.c
581

Prefer to keep defbase_tot, accessing the return argument everywhere reads worse and makes the patch noisier.

This revision now requires changes to proceed.Sep 1 2022, 1:57 AM
  • increasing readability
Nate Rupsis (nrupsis) marked 3 inline comments as done.Sep 1 2022, 3:32 AM
This revision is now accepted and ready to land.Sep 7 2022, 2:54 AM
  • Minor changes: remove redundant != 0 use defbase_tot instead of *flip_map_len.
This revision is now accepted and ready to land.Sep 9 2022, 8:02 AM
  • Correct last update (included local commits)