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 import bpy, sys
from bpy.props import IntProperty, CollectionProperty, PointerProperty, StringProperty, BoolProperty from bpy.props import IntProperty, CollectionProperty, PointerProperty, StringProperty, BoolProperty
@ -8,6 +8,7 @@ import itertools
import bmesh import bmesh
from .vertex_group_operators import get_deforming_armature, get_deforming_vgroups 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. 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: for vi in vert_indicies:
mesh.vertices[vi].select = True 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): 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""" """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" bl_idname = "object.set_expected_island_count"
@ -133,7 +152,6 @@ class MarkIslandsAsOkay(Operator):
) )
def execute(self, context): def execute(self, context):
rig = context.pose_object
obj = context.object obj = context.object
mesh = obj.data mesh = obj.data
org_mode = obj.mode org_mode = obj.mode
@ -157,6 +175,7 @@ class MarkIslandsAsOkay(Operator):
return {'FINISHED'} return {'FINISHED'}
island_group.num_expected_islands = new_num_islands island_group.num_expected_islands = new_num_islands
update_active_islands_index(obj)
return {'FINISHED'} return {'FINISHED'}
class FocusSmallestIsland(Operator): 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." 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: # Also update the opposite side vertex group
# Update existing island data first vgroup_names = [self.vgroup]
island_group = obj.island_groups[self.vgroup] flipped = flip_name(self.vgroup)
vgroup = obj.vertex_groups[self.vgroup] if flipped != self.vgroup:
bpy.ops.object.mode_set(mode='EDIT') vgroup_names.append(flipped)
vert_index_map = build_vert_index_map(mesh)
bpy.ops.object.mode_set(mode=org_mode) bpy.ops.object.mode_set(mode='EDIT')
org_num_islands = len(island_group.islands) vert_index_map = build_vert_index_map(mesh)
island_group = update_vgroup_islands(mesh, vgroup, vert_index_map, obj.island_groups, island_group) bpy.ops.object.mode_set(mode=org_mode)
new_num_islands = len(island_group.islands) hid_islands = False
if new_num_islands != org_num_islands: for vg_name in vgroup_names:
if new_num_islands == 1: if vg_name in obj.island_groups:
self.report({'INFO'}, f"Vertex group is now a single island, hidden from list.") # Update existing island data first
return {'FINISHED'} island_group = obj.island_groups[vg_name]
self.report({'INFO'}, f"Vertex group island count changed from {org_num_islands} to {new_num_islands}. Click again to focus smallest island.") vgroup = obj.vertex_groups[vg_name]
return {'FINISHED'} 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': if org_mode != 'EDIT':
bpy.ops.object.mode_set(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': if self.enter_wp and org_mode != 'WEIGHT_PAINT':
bpy.ops.object.weight_paint_toggle() 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 mesh.use_paint_mask_vertex = True
return {'FINISHED'} return {'FINISHED'}
@ -301,8 +339,6 @@ class EASYWEIGHT_UL_weight_island_groups(UIList):
def filter_items(self, context, data, propname): def filter_items(self, context, data, propname):
flt_flags = [] flt_flags = []
flt_neworder = [] flt_neworder = []
list_items = getattr(data, propname)
island_groups = getattr(data, propname) island_groups = getattr(data, propname)
helper_funcs = bpy.types.UI_UL_list helper_funcs = bpy.types.UI_UL_list