Add Easy_Weight
to Addons
#47
@ -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]
|
||||
# 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 != 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.")
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user