Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rrazgriz/414fd7e666a927e05dde5f8959107389 to your computer and use it in GitHub Desktop.
Save rrazgriz/414fd7e666a927e05dde5f8959107389 to your computer and use it in GitHub Desktop.
Blender: Visualize vertex weight distribution
# by Razgriz
# Use sum of weights (raised to a defined power) to visualize how many weights affect vertices
# Darker -> less groups affecting vert
# Lighter -> many groups affecting vert
#
# May be useful for determining where to reduce topological density with minimal deformation impact
#
# If any verts are unweighted, they'll be set to magenta ((1,0,1) / #FFOOFF) and selected in edit mode
#
# To Use:
# Open Scripting Workspace (tab at top)
# Create a new script
# Paste script content in text editor
# Select Object in object mode
# Run script
#
# Note: Will create or overwrite the vertex color layer named 'WeightDistribution'
# Will switch mode to Vertex Paint to visualize
weight_power = 6
import bpy
object = bpy.context.active_object.data
verts = object.vertices
color_map_collection = object.vertex_colors
unweighted_verts = []
# Create layer if it doesn't exist already
layer_name = 'WeightDistribution'
has_layer = False
for collection in color_map_collection:
if collection.name == layer_name:
has_layer = True
if not has_layer:
color_map_collection.new(name=layer_name)
color_map = color_map_collection[layer_name]
# Loop across polygons and verts
i = 0
for poly in object.polygons:
for idx in poly.loop_indices:
loop = object.loops[idx]
v = loop.vertex_index
val = 0
groups = verts[v].groups
if len(groups) > 0:
for g in groups:
val += pow(g.weight, weight_power)
val = max(min(1 - val, 1), 0)
final_color = (val, val, val, 1.0)
else:
final_color = (1, 0, 1, 1) # if no groups, set to magenta
unweighted_verts.append(verts[v].index)
t = 0
color_map.data[i].color = final_color
i += 1
if len(unweighted_verts) > 0:
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.mesh.select_mode(type="VERT")
bpy.ops.mesh.select_all(action = 'DESELECT')
bpy.ops.object.mode_set(mode = 'OBJECT')
for vid in unweighted_verts:
object.vertices[vid].select = True
bpy.ops.object.mode_set(mode = 'EDIT')
for area in bpy.context.screen.areas: # zoom to selected
if area.type == 'VIEW_3D':
ctx = bpy.context.copy()
ctx['area'] = area
ctx['region'] = area.regions[-1]
bpy.ops.view3d.view_selected(ctx) # points view
else:
object.vertex_colors.active = object.vertex_colors[layer_name]
bpy.ops.object.mode_set(mode='VERTEX_PAINT')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment