## Script Description
This Blender Python script is designed to rename selected bones in an armature and update corresponding vertex group names in mesh objects with an armature modifier. The script automatically renames bones based on their base names while filling in numerical gaps in the bone names. The script can handle multiple base names and ensures that the vertex groups in mesh objects are updated to match the new bone names.
## Usage Instructions
1. Open Blender and switch to the “Scripting” workspace.
2. Create a new text file in the text editor and copy the script into it.
3. In the “3D Viewport,” select an armature object and switch to Edit mode (Tab key).
4. Select the bones you wish to rename. You can select multiple bones with different base names.
5. Run the script by clicking the “Run Script” button in the text editor or by pressing Alt+P with the mouse cursor in the text editor.
6. The selected bones will be renamed based on their base names, and any numerical gaps in the bone names will be filled in. Bones with the same base name will be numbered sequentially starting from 0 (e.g., “Bone”, “Bone.001”, “Bone.002”).
7. The script will also update the names of corresponding vertex groups in any mesh objects that have an armature modifier set to the target armature.
## Note
- The script must be run in Edit mode with at least one bone selected in the armature.
- The script will raise an exception with an error message if the active object is not an armature, if not in Edit mode, or if no bones are selected.
- The script handles multiple base names, so you can select bones with different base names, and the script will group and rename them accordingly.
- It is recommended to save your work before running the script, as renaming bones and vertex groups can affect rigging and animations.
## Source
```python
import bpy
from collections import defaultdict
# Get the active object (should be an armature in Edit mode)
armature = bpy.context.active_object
# Ensure that the active object is an armature and we are in Edit mode
if not armature or armature.type != 'ARMATURE' or bpy.context.mode != 'EDIT_ARMATURE':
raise Exception("Please select an armature and switch to Edit mode.")
# Get the selected bones
selected_bones = [b for b in armature.data.edit_bones if b.select]
# Ensure that at least one bone is selected
if not selected_bones:
raise Exception("Please select at least one bone.")
# Group the selected bones based on their base names
bone_groups = defaultdict(list)
for bone in selected_bones:
base_name = bone.name.rstrip('0123456789.')
bone_groups[base_name].append(bone)
# Create a dictionary to store the mapping between old bone names and new bone names
bone_name_mapping = {}
# Iterate through each group of bones with the same base name
for base_name, bones in bone_groups.items():
# Sort the bones in the group by their names
bones.sort(key=lambda b: b.name)
# Rename the bones and build the mapping
for i, bone in enumerate(bones):
old_name = bone.name
new_name = f"{base_name}.{i:03d}" if i > 0 else base_name
bone.name = new_name
bone_name_mapping[old_name] = new_name
# Switch to Object mode to update vertex groups
bpy.ops.object.mode_set(mode='OBJECT')
# Iterate through all mesh objects and update vertex groups
for obj in bpy.context.scene.objects:
# Check if the object has an Armature modifier with the target armature
armature_modifiers = [mod for mod in obj.modifiers if mod.type == 'ARMATURE' and mod.object == armature]
if armature_modifiers and obj.type == 'MESH':
# Update the names of the vertex groups based on the bone name mapping
for group in obj.vertex_groups:
# Check if the vertex group name matches any old bone name
if group.name in bone_name_mapping:
# Rename the vertex group based on the new bone name
group.name = bone_name_mapping[group.name]
# Switch back to Edit mode
bpy.ops.object.mode_set(mode='EDIT')
```