## Description
This script is designed for use in Blender. It deletes bones from a selected armature based on the following criteria: the bones do not have corresponding vertex groups in any mesh that is rigged to the armature, and they do not have any descendant bones that have corresponding vertex groups. As a result, only bones that are not used for mesh deformation and do not have used descendants are removed.
## Directions
1. Open Blender and load the scene that contains the armature you want to modify.
2. In Object mode, select the armature from which you want to delete the unused bones.
3. Open the Scripting workspace or the Text Editor in Blender.
4. Create a new text file and paste the script into it.
5. Click the “Run Script” button or press Alt + P to execute the script.
6. The script will automatically delete the unused bones from the selected armature.
Note: Before running the script, it is recommended to save a backup copy of your Blender file in case you need to revert any changes.
## Source
```python
import bpy
# Check if the selected object is an armature
selected_obj = bpy.context.active_object
if selected_obj is None or selected_obj.type != 'ARMATURE':
raise Exception("Please select an armature.")
# Retrieve the selected armature object
armature = selected_obj
# Find all armature meshes
armature_meshes = [
obj for obj in bpy.context.scene.objects
if obj.type == 'MESH' and any(mod.type == 'ARMATURE' and mod.object == armature for mod in obj.modifiers)
]
# Store the current mode so we can restore it later
original_mode = bpy.context.mode
# Switch to Edit mode to work with EditBone objects
bpy.ops.object.mode_set(mode='EDIT')
# Initialize a set of bones to delete with all EditBone objects in the armature
bones_to_delete = set(armature.data.edit_bones)
# Iterate through vertex groups and remove corresponding bones from bones_to_delete
for mesh in armature_meshes:
for vgroup in mesh.vertex_groups:
# Remove bone from bones_to_delete and remove its ancestors
current_bone = armature.data.edit_bones.get(vgroup.name)
while current_bone and current_bone in bones_to_delete:
bones_to_delete.remove(current_bone)
current_bone = current_bone.parent
# Delete bones in the bones_to_delete set
for bone in bones_to_delete:
armature.data.edit_bones.remove(bone)
# Restore the original mode
bpy.ops.object.mode_set(mode=original_mode)
```