Page MenuHome

mesh_weightloss.py

mesh_weightloss.py

# ************************ BEGIN GPL LICENSE BLOCK ************************
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ************************* END GPL LICENSE BLOCK *************************
# <pep8 compliant>
# Weight Loss
#
# Adds a button to tool panel that when pressed in object mode sets the count
# of non-zero weight bone influences in the mesh to a requested maximum
bl_info = {
"name": "Weight Loss",
"author": "Stuntman,(acknowledgement to GorkaMendieta for idea)",
"version": (1, 0),
"blender": (2, 6, 3),
"location": "View3D > Tool Shelf > Weight Loss",
"description": "Prunes the count of non-zero weight bone influences",
"warning": "",
"wiki_url": "http://wiki.blender.org/index.php/User:Stuntman/Extensions:2.6/Py/Scripts/Mesh/weightloss",
"tracker_url": "",
"category": "Mesh"}
import bpy
import sys
def get_influence_count(v):
'''Get the number of non-zero bone influences on the vert'''
count = 0
for group in v.groups:
if group.weight > 0.0:
count = count + 1
return count
def get_group_with_min(v):
'''Get the group with the lowest non-zero weight for the vert'''
vgroup = -1
min = sys.maxsize
for group in v.groups:
if (group.weight > 0.0) and (group.weight < min):
min = group.weight
vgroup = group.group
return vgroup
class WeightLossPanel(bpy.types.Panel):
'''Panel displaying slider and button for addon'''
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_context = 'objectmode'
bl_label = 'Weight Loss'
@classmethod
def poll(self, context):
if context.active_object:
return context.active_object.type == 'MESH'
def draw(self, context):
layout = self.layout
row = layout.row()
row.prop(context.scene, 'max')
row = layout.row()
row.operator('weightloss.prune', text='Prune Weights')
class WeightLossOperator(bpy.types.Operator):
'''Prunes the count of non-zero weight bone influences'''
bl_idname = 'weightloss.prune'
bl_label = 'Prune Weights'
bl_description = 'Set excess bone influence weights to zero'
bl_options = {'UNDO'}
def invoke(self, context, event):
mesh = context.object
max = context.scene.max
removed = 0
# Loop through all verts, get the count of groups that vert has
# a non-zero weight influence and remove the lowest weights until
# the maximum number of none-zero weights has been reached
for v in mesh.data.vertices:
infcount = get_influence_count(v)
if infcount > max:
for i in range(infcount - max):
min_group = get_group_with_min(v)
mesh.vertex_groups[min_group].add([v.index], 0.0,
'REPLACE')
removed = removed + 1
self.report({'INFO'},
'Number of influences reset to zero weight : %d' % removed)
return {'FINISHED'}
def register():
bpy.types.Scene.max = bpy.props.IntProperty(name='Maximum Count',
default=4, min=1, max=8,
description='Max count of non-zero influences to retain per vertex')
bpy.utils.register_module(__name__)
pass
def unregister():
del bpy.types.Scene.max
bpy.utils.unregister_module(__name__)
pass
if __name__ == "__main__":
register()

File Metadata

Mime Type
text/x-c++
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
ef/94/f1fc1df6c501f1a3745d87bce1d9

Event Timeline