Add Easy_Weight to Addons #47

Merged
Nick Alberelli merged 48 commits from feature/easy_weights into main 2023-05-17 22:13:57 +02:00
Showing only changes of commit 848de51d46 - Show all commits

View File

@ -1,4 +1,4 @@
from typing import List, Tuple
from typing import List
import bpy, sys
from bpy.props import IntProperty, CollectionProperty, PointerProperty, StringProperty, BoolProperty
@ -8,6 +8,7 @@ import itertools
import bmesh
from .vertex_group_operators import get_deforming_armature, get_deforming_vgroups
from .utils.naming import flip_name
"""
This module creates a workflow for hunting down and cleaning up rogue weights in the most efficient way possible.
@ -120,6 +121,24 @@ def select_vertices(mesh: Mesh, vert_indicies: List[int]):
for vi in vert_indicies:
mesh.vertices[vi].select = True
def update_active_islands_index(obj):
"""Make sure the active entry is visible, keep incrementing index until that is the case."""
new_active_index = obj.active_islands_index + 1
looped = False
while True:
if new_active_index >= len(obj.island_groups):
new_active_index = 0
if looped:
break
looped = True
island_group = obj.island_groups[new_active_index]
if len(island_group.islands) < 2 or \
len(island_group.islands) == island_group.num_expected_islands:
new_active_index += 1
continue
break
obj.active_islands_index = new_active_index
class MarkIslandsAsOkay(Operator):
"""Mark this number of vertex islands to be the intended amount. Vertex group will be hidden from the list until this number changes"""
bl_idname = "object.set_expected_island_count"
@ -133,7 +152,6 @@ class MarkIslandsAsOkay(Operator):
)
def execute(self, context):
rig = context.pose_object
obj = context.object
mesh = obj.data
org_mode = obj.mode
@ -157,6 +175,7 @@ class MarkIslandsAsOkay(Operator):
return {'FINISHED'}
island_group.num_expected_islands = new_num_islands
update_active_islands_index(obj)
return {'FINISHED'}
class FocusSmallestIsland(Operator):
@ -189,22 +208,32 @@ class FocusSmallestIsland(Operator):
assert self.vgroup in obj.vertex_groups, f"Vertex Group {self.vgroup} not found in object {obj.name}, aborting."
if self.vgroup in obj.island_groups:
# Update existing island data first
island_group = obj.island_groups[self.vgroup]
vgroup = obj.vertex_groups[self.vgroup]
bpy.ops.object.mode_set(mode='EDIT')
vert_index_map = build_vert_index_map(mesh)
bpy.ops.object.mode_set(mode=org_mode)
org_num_islands = len(island_group.islands)
island_group = update_vgroup_islands(mesh, vgroup, vert_index_map, obj.island_groups, island_group)
new_num_islands = len(island_group.islands)
if new_num_islands != org_num_islands:
if new_num_islands == 1:
self.report({'INFO'}, f"Vertex group is now a single island, hidden from list.")
return {'FINISHED'}
self.report({'INFO'}, f"Vertex group island count changed from {org_num_islands} to {new_num_islands}. Click again to focus smallest island.")
return {'FINISHED'}
# Also update the opposite side vertex group
vgroup_names = [self.vgroup]
flipped = flip_name(self.vgroup)
if flipped != self.vgroup:
vgroup_names.append(flipped)
bpy.ops.object.mode_set(mode='EDIT')
vert_index_map = build_vert_index_map(mesh)
bpy.ops.object.mode_set(mode=org_mode)
hid_islands = False
for vg_name in vgroup_names:
if vg_name in obj.island_groups:
# Update existing island data first
island_group = obj.island_groups[vg_name]
vgroup = obj.vertex_groups[vg_name]
org_num_islands = len(island_group.islands)
island_group = update_vgroup_islands(mesh, vgroup, vert_index_map, obj.island_groups, island_group)
new_num_islands = len(island_group.islands)
if new_num_islands < 2:
hid_islands = True
self.report({'INFO'}, f"Vertex group {vg_name} no longer has multiple islands, hidden from list.")
if hid_islands:
update_active_islands_index(obj)
return {'FINISHED'}
# self.report({'INFO'}, f"Vertex group island count changed from {org_num_islands} to {new_num_islands}. Click again to focus smallest island.")
# return {'FINISHED'}
if org_mode != 'EDIT':
bpy.ops.object.mode_set(mode='EDIT')
@ -234,6 +263,15 @@ class FocusSmallestIsland(Operator):
if self.enter_wp and org_mode != 'WEIGHT_PAINT':
bpy.ops.object.weight_paint_toggle()
# Select the bone
if context.mode == 'PAINT_WEIGHT':
rig = context.pose_object
if rig:
for pb in rig.pose.bones:
pb.bone.select = False
if self.vgroup in rig.pose.bones:
rig.pose.bones[self.vgroup].bone.select = True
mesh.use_paint_mask_vertex = True
return {'FINISHED'}
@ -301,8 +339,6 @@ class EASYWEIGHT_UL_weight_island_groups(UIList):
def filter_items(self, context, data, propname):
flt_flags = []
flt_neworder = []
list_items = getattr(data, propname)
island_groups = getattr(data, propname)
helper_funcs = bpy.types.UI_UL_list