Skip to content

Instantly share code, notes, and snippets.

@dmsurti
Created January 12, 2017 10:01
Show Gist options
  • Save dmsurti/aa3411a82e12aaaee564a17bb493f162 to your computer and use it in GitHub Desktop.
Save dmsurti/aa3411a82e12aaaee564a17bb493f162 to your computer and use it in GitHub Desktop.
import bpy
# Distributes the weighting on the vertices so that at most 'maxInfluence'
# bones affect the vertex.
def distributeWeight(obj, maxInfluence):
print("--- %s ----" % (obj.name))
# Access the mesh data.
mesh = obj.data
# Run though the vertices
for v in mesh.vertices:
# Get a list of the non-zero group weightings for the vertex
nonZero = []
for g in v.groups:
g.weight = round(g.weight, 4)
if g.weight > .0001:
nonZero.append(g)
# Sort them by weight decending
byWeight = sorted(nonZero, key=lambda group: group.weight)
byWeight.reverse()
# As long as there are more than 'maxInfluence' bones, take the lowest
# influence bone and distribute the weight to the other bones.
while len(byWeight) > maxInfluence:
print("Distributing weight for vertex %d" % (v.index))
# Pop the lowest influence off and compute how much should go to the
# other bones.
minInfluence = byWeight.pop()
distributeWeight = minInfluence.weight / len(byWeight)
minInfluence.weight = 0
# Add this amount to the other bones
for influence in byWeight:
influence.weight = influence.weight + distributeWeight
# Round off the remaining values.
for influence in byWeight:
influence.weight = round(influence.weight, 4)
class DistributeWeightOperator(bpy.types.Operator):
'''
Distributes the weights at each vertex so that
at most 4 groups are affecting it.
'''
bl_idname = "object.distribute_weight_operator"
bl_label = "Distribute Weight Operator"
@classmethod
def poll(cls, context):
return len(context.selected_objects) > 0
def execute(self, context):
for obj in context.selected_objects:
maxInfluence = 3
distributeWeight(obj, maxInfluence)
return {'FINISHED'}
def register():
bpy.utils.register_class(DistributeWeightOperator)
def unregister():
bpy.utils.unregister_class(DistributeWeightOperato r)
if __name__ == "__main__":
register()
# test call
# bpy.ops.object.distribute_weight_operator()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment