You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blender脚本开发:顶点位置复制、轴镜像及权重同步

Solution: Blender Script to Mirror Vertex Position & Weights Without Breaking Symmetry

Oh man, I feel your pain—there's nothing worse than fixing a tiny symmetry break on a weighted model only to have Blender's built-in Symmetrize trash your painted weights or leave duplicate vertices. Manually copying coordinates one by one is such a slog, so let's build a script that solves this exactly how you need it.

Here's a script that copies the active vertex's position to your selected vertices, mirrors it across your chosen axis, and even handles mirroring vertex weights (including matching left/right weight groups if you use suffixes like .L/.R):

import bpy
import bmesh

# Configure these to match your project
MIRROR_AXIS = 'X'  # Choose 'X', 'Y', or 'Z' for your symmetry axis
USE_SIDE_SUFFIXES = True  # Set to False if your weight groups don't use left/right suffixes
SUFFIX_LEFT = '.L'
SUFFIX_RIGHT = '.R'

def mirror_vertex_data():
    # Grab the active mesh object
    obj = bpy.context.active_object
    if obj.type != 'MESH':
        print("Whoops, active object isn't a mesh!")
        return
    
    # Quick mode switch to safely access mesh data
    bpy.ops.object.mode_set(mode='OBJECT')
    
    # Initialize bmesh for direct vertex manipulation
    bm = bmesh.new()
    bm.from_mesh(obj.data)
    
    # Get our target vertices: active (the correct one) and selected (the broken ones)
    active_vert = bm.select_history.active
    selected_verts = [v for v in bm.verts if v.select and v != active_vert]
    
    if not active_vert or not selected_verts:
        print("Need one active vertex (orange) and at least one selected vertex (white)!")
        bm.free()
        bpy.ops.object.mode_set(mode='EDIT')
        return
    
    # Mirror the active vertex's position to selected vertices
    active_pos = active_vert.co.copy()
    for vert in selected_verts:
        if MIRROR_AXIS == 'X':
            vert.co = (-active_pos.x, active_pos.y, active_pos.z)
        elif MIRROR_AXIS == 'Y':
            vert.co = (active_pos.x, -active_pos.y, active_pos.z)
        elif MIRROR_AXIS == 'Z':
            vert.co = (active_pos.x, active_pos.y, -active_pos.z)
    
    # Copy and mirror vertex weights
    for vert in selected_verts:
        # Clear old weights on the selected vertex first
        for g in vert.groups:
            vert.groups.remove(g)
        
        # Iterate through the active vertex's weight groups
        for group in active_vert.groups:
            source_group = obj.vertex_groups[group.group]
            weight_value = group.weight
            
            # Handle left/right weight group mirroring if enabled
            if USE_SIDE_SUFFIXES:
                group_name = source_group.name
                # Swap suffixes for mirrored groups
                if SUFFIX_LEFT in group_name:
                    mirrored_group_name = group_name.replace(SUFFIX_LEFT, SUFFIX_RIGHT)
                elif SUFFIX_RIGHT in group_name:
                    mirrored_group_name = group_name.replace(SUFFIX_RIGHT, SUFFIX_LEFT)
                else:
                    # No suffix? Keep the same group (for midline bones)
                    mirrored_group_name = group_name
                
                # Create the mirrored group if it doesn't exist yet
                if mirrored_group_name in obj.vertex_groups:
                    target_group = obj.vertex_groups[mirrored_group_name]
                else:
                    target_group = obj.vertex_groups.new(name=mirrored_group_name)
                
                # Assign the mirrored weight
                target_group.add([vert.index], weight_value, 'REPLACE')
            else:
                # Just copy the weight to the same group (for non-side-specific weights)
                source_group.add([vert.index], weight_value, 'REPLACE')
    
    # Save changes back to the mesh and clean up
    bm.to_mesh(obj.data)
    bm.free()
    
    # Switch back to edit mode
    bpy.ops.object.mode_set(mode='EDIT')
    print(f"Done! Mirrored {len(selected_verts)} vertices over {MIRROR_AXIS} axis, including weights.")

# Run the script
mirror_vertex_data()

How to Use This:

  1. Head to the Scripting workspace in Blender.
  2. Click New to create a blank text file, then paste the code above.
  3. Tweak the top configuration variables if needed:
    • MIRROR_AXIS: Set to the axis your model is symmetric over (almost always 'X' for character models).
    • USE_SIDE_SUFFIXES: Toggle this if your weight groups don't use .L/.R suffixes (like if you use _left/_right instead, update the SUFFIX_LEFT/SUFFIX_RIGHT values too).
  4. Go back to your mesh, switch to Edit Mode.
  5. Select the vertices that are broken (the ones you want to fix).
  6. Click the correct symmetric vertex last to make it the active vertex (it'll turn orange).
  7. Hit the Play button in the text editor to run the script.

What This Does Better Than Blender's Symmetrize:

  • Preserves Your Weights: No more losing hours of weight painting work. It copies and mirrors weights perfectly based on your group naming.
  • No Duplicate Vertices: Modifies existing vertices instead of creating new ones, so your mesh stays clean.
  • Faster Than Manual Work: Fix multiple broken vertices in one go, instead of adjusting each one individually.

内容的提问来源于stack exchange,提问作者Shae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:53:45