Skip to content

Instantly share code, notes, and snippets.

@OptoCloud
Created May 1, 2022 07:45
Show Gist options
  • Save OptoCloud/55f1c61f4deea619bf5b39cb21781f6a to your computer and use it in GitHub Desktop.
Save OptoCloud/55f1c61f4deea619bf5b39cb21781f6a to your computer and use it in GitHub Desktop.
Blender remove empty Vertex Groups and Shape Keys
## Remove empty vertex groups and shape keys
## Credits:
## https://blender.stackexchange.com/questions/237599/is-there-a-way-to-automatically-delete-shape-keys-that-are-identical-to-the-basi
## https://blender.stackexchange.com/questions/16517/how-to-quickly-remove-all-zero-weight-vertex-groups
import bpy
import numpy as np
# Tolerance to small differences, change it if you want
tolerance = 0.001
assert bpy.context.mode == 'OBJECT', "Must be in object mode!"
def survey(obj):
maxWeight = {}
for i in obj.vertex_groups:
maxWeight[i.index] = 0
for v in obj.data.vertices:
for g in v.groups:
gn = g.group
w = obj.vertex_groups[g.group].weight(v.index)
if (maxWeight.get(gn) is None or w>maxWeight[gn]):
maxWeight[gn] = w
return maxWeight
for obj in bpy.context.selected_objects:
if obj.type != 'MESH': continue
if not obj.data.shape_keys: continue
if not obj.data.shape_keys.use_relative: continue
kbs = obj.data.shape_keys.key_blocks
nverts = len(obj.data.vertices)
to_delete = []
# Cache locs for rel keys since many keys have the same rel key
cache = {}
locs = np.empty(3*nverts, dtype=np.float32)
for kb in kbs:
if kb == kb.relative_key or 'vrc.v_' in kb.name:
continue
kb.data.foreach_get("co", locs)
if kb.relative_key.name not in cache:
rel_locs = np.empty(3*nverts, dtype=np.float32)
kb.relative_key.data.foreach_get("co", rel_locs)
cache[kb.relative_key.name] = rel_locs
rel_locs = cache[kb.relative_key.name]
locs -= rel_locs
if (np.abs(locs) < tolerance).all():
to_delete.append(kb.name)
for kb_name in to_delete:
obj.shape_key_remove(obj.data.shape_keys.key_blocks[kb_name])
maxWeight = survey(obj)
# fix bug pointed out by user2859
ka = []
ka.extend(maxWeight.keys())
ka.sort(key=lambda gn: -gn)
print (ka)
for gn in ka:
if maxWeight[gn]<=0:
print ("delete %d"%gn)
obj.vertex_groups.remove(obj.vertex_groups[gn]) # actually remove the group
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment