Created
January 12, 2017 10:01
-
-
Save dmsurti/aa3411a82e12aaaee564a17bb493f162 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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