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