Fixes
This commit is contained in:
+6
-3
@@ -469,7 +469,7 @@ def transfer_vertex_weights(context: Context, obj: bpy.types.Object, source_grou
|
|||||||
modifier = obj.modifiers.new(name="merge_weights", type="VERTEX_WEIGHT_MIX")
|
modifier = obj.modifiers.new(name="merge_weights", type="VERTEX_WEIGHT_MIX")
|
||||||
modifier.show_viewport = True
|
modifier.show_viewport = True
|
||||||
modifier.show_render = True
|
modifier.show_render = True
|
||||||
modifier.mix_set = 'B' # Replace weights in A with weights from B
|
modifier.mix_set = 'B'
|
||||||
modifier.vertex_group_a = target_group
|
modifier.vertex_group_a = target_group
|
||||||
modifier.vertex_group_b = source_group
|
modifier.vertex_group_b = source_group
|
||||||
modifier.mask_constant = 1.0
|
modifier.mask_constant = 1.0
|
||||||
@@ -482,11 +482,12 @@ def transfer_vertex_weights(context: Context, obj: bpy.types.Object, source_grou
|
|||||||
obj.select_set(True)
|
obj.select_set(True)
|
||||||
context.view_layer.objects.active = obj
|
context.view_layer.objects.active = obj
|
||||||
|
|
||||||
# Move modifier to the top of the stack if necessary
|
# Move modifier to the top of the stack
|
||||||
if len(obj.modifiers) > 1:
|
if len(obj.modifiers) > 1:
|
||||||
obj.modifiers.move(obj.modifiers.find(modifier.name), 0)
|
obj.modifiers.move(obj.modifiers.find(modifier.name), 0)
|
||||||
|
|
||||||
# Apply modifier
|
# Apply modifier with correct syntax
|
||||||
|
with context.temp_override(active_object=obj):
|
||||||
bpy.ops.object.modifier_apply(modifier=modifier.name)
|
bpy.ops.object.modifier_apply(modifier=modifier.name)
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
@@ -495,3 +496,5 @@ def transfer_vertex_weights(context: Context, obj: bpy.types.Object, source_grou
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class AvatarToolkit_OT_RemoveZeroWeightBones(Operator):
|
|||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
bpy.ops.object.select_all(action='DESELECT')
|
bpy.ops.object.select_all(action='DESELECT')
|
||||||
|
|
||||||
# Store initial transforms
|
# Modify the initial transforms collection section to include all bones:
|
||||||
initial_transforms = {}
|
initial_transforms = {}
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
for bone in armature.data.edit_bones:
|
for bone in armature.data.edit_bones:
|
||||||
@@ -156,14 +156,14 @@ class AvatarToolkit_OT_RemoveZeroWeightBones(Operator):
|
|||||||
'matrix': bone.matrix.copy(),
|
'matrix': bone.matrix.copy(),
|
||||||
'parent': bone.parent.name if bone.parent else None
|
'parent': bone.parent.name if bone.parent else None
|
||||||
}
|
}
|
||||||
# Add end bones to transforms
|
# Handle any child bones including _end bones
|
||||||
if bone.name.endswith('_end'):
|
for child in bone.children:
|
||||||
initial_transforms[bone.name] = {
|
initial_transforms[child.name] = {
|
||||||
'head': bone.head.copy(),
|
'head': child.head.copy(),
|
||||||
'tail': bone.tail.copy(),
|
'tail': child.tail.copy(),
|
||||||
'roll': bone.roll,
|
'roll': child.roll,
|
||||||
'matrix': bone.matrix.copy(),
|
'matrix': child.matrix.copy(),
|
||||||
'parent': bone.parent.name if bone.parent else None
|
'parent': child.parent.name if child.parent else None
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get weighted bones
|
# Get weighted bones
|
||||||
@@ -300,14 +300,19 @@ class AvatarToolkit_OT_MergeBonesToParents(Operator):
|
|||||||
|
|
||||||
def execute(self, context: Context) -> set[str]:
|
def execute(self, context: Context) -> set[str]:
|
||||||
prev_mode = context.mode
|
prev_mode = context.mode
|
||||||
|
armature = common.get_selected_armature(context)
|
||||||
|
|
||||||
# Map 'EDIT_ARMATURE' to 'EDIT' for bpy.ops.object.mode_set
|
# Map 'EDIT_ARMATURE' to 'EDIT' for bpy.ops.object.mode_set
|
||||||
if prev_mode == 'EDIT_ARMATURE':
|
if prev_mode == 'EDIT_ARMATURE':
|
||||||
prev_mode = 'EDIT'
|
prev_mode = 'EDIT'
|
||||||
|
|
||||||
# Switch to Edit Mode
|
# Set active object and mode
|
||||||
|
context.view_layer.objects.active = armature
|
||||||
|
bpy.ops.object.select_all(action='DESELECT')
|
||||||
|
armature.select_set(True)
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
armature_data: Armature = context.view_layer.objects.active.data
|
|
||||||
|
armature_data: Armature = armature.data
|
||||||
|
|
||||||
# Get selected bones in Edit Mode
|
# Get selected bones in Edit Mode
|
||||||
selected_bones = context.selected_editable_bones
|
selected_bones = context.selected_editable_bones
|
||||||
@@ -322,13 +327,16 @@ class AvatarToolkit_OT_MergeBonesToParents(Operator):
|
|||||||
bone = armature_data.edit_bones.get(bone_name)
|
bone = armature_data.edit_bones.get(bone_name)
|
||||||
if bone and bone.parent:
|
if bone and bone.parent:
|
||||||
# Transfer weights from bone to its parent
|
# Transfer weights from bone to its parent
|
||||||
|
context.view_layer.objects.active = obj
|
||||||
common.transfer_vertex_weights(
|
common.transfer_vertex_weights(
|
||||||
context=context,
|
context=context,
|
||||||
obj=obj,
|
obj=obj,
|
||||||
source_group=bone_name,
|
source_group=bone_name,
|
||||||
target_group=bone.parent.name
|
target_group=bone.parent.name
|
||||||
)
|
)
|
||||||
# Ensure we're in Edit Mode after transfer
|
# Return to armature edit mode
|
||||||
|
context.view_layer.objects.active = armature
|
||||||
|
armature.select_set(True)
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
else:
|
else:
|
||||||
self.report({'WARNING'}, f"Bone '{bone_name}' has no parent or not found; skipping")
|
self.report({'WARNING'}, f"Bone '{bone_name}' has no parent or not found; skipping")
|
||||||
@@ -347,10 +355,11 @@ class AvatarToolkit_OT_MergeBonesToParents(Operator):
|
|||||||
self.report({'WARNING'}, f"Bone '{bone_name}' not found in armature; cannot delete")
|
self.report({'WARNING'}, f"Bone '{bone_name}' not found in armature; cannot delete")
|
||||||
|
|
||||||
# Return to previous mode
|
# Return to previous mode
|
||||||
|
context.view_layer.objects.active = armature
|
||||||
|
armature.select_set(True)
|
||||||
bpy.ops.object.mode_set(mode=prev_mode)
|
bpy.ops.object.mode_set(mode=prev_mode)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class AvatarToolkit_OT_MergeArmatures(Operator):
|
class AvatarToolkit_OT_MergeArmatures(Operator):
|
||||||
bl_idname = "avatar_toolkit.merge_armatures"
|
bl_idname = "avatar_toolkit.merge_armatures"
|
||||||
bl_label = t("MergeArmature.merge_armatures.label")
|
bl_label = t("MergeArmature.merge_armatures.label")
|
||||||
@@ -362,7 +371,6 @@ class AvatarToolkit_OT_MergeArmatures(Operator):
|
|||||||
return (common.get_selected_armature(context) is not None) and (common.get_merge_armature_source(context) is not None)
|
return (common.get_selected_armature(context) is not None) and (common.get_merge_armature_source(context) is not None)
|
||||||
|
|
||||||
def make_active(self, obj: bpy.types.Object, context: Context):
|
def make_active(self, obj: bpy.types.Object, context: Context):
|
||||||
context.view_layer.objects.active = obj
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
bpy.ops.object.select_all(action='DESELECT')
|
bpy.ops.object.select_all(action='DESELECT')
|
||||||
context.view_layer.objects.active = obj
|
context.view_layer.objects.active = obj
|
||||||
|
|||||||
Reference in New Issue
Block a user