Blenderでウェイトのない頂点グループをすべて削除する
あらまし
BlenderでRigifyや自動ウェイト付けをすると、メッシュごとに関係のないボーンの頂点グループまで作られてしまう 明らかに関係ない頂点グループは消してしまいたい
しかし頂点グループを一括で消す機能はそもそもない
ポチポチやってたら日が暮れてしまう
ググったらスクリプトでやってる人がいた
keroxp.iconすごーい!
動いたけど、ひとつ問題があった
ミラーモディファイアを適用していないメッシュの場合、バインドされるはずのボーンにちゃんとウェイトはついているのだけど、ミラー後の頂点はまだシーン上にないため、ウェイト最大値が0とみなされてしまっていた
左半分のarmにミラーモディファイアがついていて、頂点グループarm.Lにウェイトがついていたらarm.Rも残すようにスクリプトを改造した
もっとスマートな方法があったような気もするけどまぁいいや
選択されているオブジェクトから、ウェイトのついていない頂点グループをすべて一括で削除するスクリプト
注:実行は自己責任で
code:py
import bpy
def survey(obj):
maxWeight = {}
nameByIndex = {}
indexByName = {}
for vg in obj.vertex_groups:
for v in obj.data.vertices:
for g in v.groups:
gn = g.group
w = obj.vertex_groupsg.group.weight(v.index) if (maxWeight.get(gn) is None or w > maxWeightgn): return maxWeight, nameByIndex, indexByName
# bone_name.(l|L) <-> bone_name.(r|R)
mirroredNameMap = {"L": "R", "R":"L", "l": "r", "r": "l"}
def getMirroredName(name):
prefix = mirroredNameMap.get(name-1) return name0:-1+prefix if prefix is not None else name def __main__():
obj = bpy.context.active_object
maxWeight, nameByIndex, indexByName = survey(obj)
print(indexByName)
ka = []
ka.extend(maxWeight.keys())
ka.sort(key=lambda gn: -gn)
removalFlags = {}
for gn in ka:
if removalFlags.get(gn) is not None:
continue
removalFlagsgn = maxWeightgn <= 0 group_name = nameByIndexgn mirror = getMirroredName(group_name)
mirror_index = indexByName.get(mirror)
if mirror_index is not None:
if removalFlags.get(mirror_index) is None:
removalFlagsgn = maxWeightgn <= 0 else:
removalFlagsgn = maxWeightgn <= 0 for gn in ka:
obj.vertex_groups.remove(obj.vertex_groupsgn) print ("deleted: "+nameByIndexgn) __main__()