如何在不替换顶点组的情况下将顶点组从一个对象添加到另一个对象?

How to add vertex groups from one object to another without replacing them?

我正在使用 Blender 创建人体模型,我有两个模型,一个装有顶点组列表,同一模型的另一个副本有另一组顶点组。我想知道我是否可以拥有包含这两组顶点组的同一模型的副本。或者我可以将顶点组从一个模型复制到另一个模型而不替换已经存在的顶点组。

Blender 中包含一个插件,可以将顶点权重从活动对象复制到其他选定对象。正如您提到的,插件将覆盖任何具有匹配名称的现有顶点权重。

通过从插件中获取执行顶点权重复制的代码并进行小幅调整,以便在名称已经存在时为目标顶点组使用新名称,我得到以下小脚本。

将其粘贴到 blender 的 text editor and click run script. The vertex groups in the active object 被复制到任何其他选定的对象。

import bpy

active = bpy.context.active_object

for ob in bpy.context.selected_objects:
    me_source = active.data
    me_target = ob.data

    # sanity check: do source and target have the same amount of verts?
    if len(me_source.vertices) != len(me_target.vertices):
        print('ERROR: objects {} and {} have different vertex counts.'.format(active.name,ob.name))
        continue

    vgroups_IndexName = {}
    for i in range(0, len(active.vertex_groups)):
        groups = active.vertex_groups[i]
        vgroups_IndexName[groups.index] = groups.name
    data = {}  # vert_indices, [(vgroup_index, weights)]
    for v in me_source.vertices:
        vg = v.groups
        vi = v.index
        if len(vg) > 0:
            vgroup_collect = []
            for i in range(0, len(vg)):
                vgroup_collect.append((vg[i].group, vg[i].weight))
            data[vi] = vgroup_collect
    # write data to target
    if ob != active:
        # add missing vertex groups
        for vgroup_idx, vgroup_name in vgroups_IndexName.items():
            #check if group already exists...
            already_present = 0
            for i in range(0, len(ob.vertex_groups)):
                if ob.vertex_groups[i].name == vgroup_name:
                    vgroup_name = vgroup_name+'_from_'+active.name
                    vgroups_IndexName[vgroup_idx] = vgroup_name
            # ... if not, then add
            if already_present == 0:
                ob.vertex_groups.new(name=vgroup_name)
        # write weights
        for v in me_target.vertices:
            for vi_source, vgroupIndex_weight in data.items():
                if v.index == vi_source:

                    for i in range(0, len(vgroupIndex_weight)):
                        groupName = vgroups_IndexName[vgroupIndex_weight[i][0]]
                        groups = ob.vertex_groups
                        for vgs in range(0, len(groups)):
                            if groups[vgs].name == groupName:
                                groups[vgs].add((v.index,),
                                   vgroupIndex_weight[i][1], "REPLACE")