weightpaint_clean, option to clean all vgroups

weightpaint_envelope_assign - can update active vgroup only
weightpaint_normalize - fixups
BKE_plugin_types - made the max length 32 ratehr then 16 so you can fill the text space in pupBlock
This commit is contained in:
Campbell Barton 2006-12-27 09:31:28 +00:00
parent 11e035b0fc
commit 84f60b19c8
6 changed files with 135 additions and 60 deletions

@ -78,6 +78,8 @@ def list2MeshWeight(me, groupNames, vWeightList):
if len(vWeightList) != len(me.verts):
raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights'
act_group = me.activeGroup
# Clear the vert group.
currentGroupNames= me.getVertGroupNames()
for group in currentGroupNames:
@ -100,6 +102,9 @@ def list2MeshWeight(me, groupNames, vWeightList):
except:
pass # vert group is not used anymore.
try: me.activeGroup = act_group
except: pass
me.update()
@ -134,6 +139,8 @@ def dict2MeshWeight(me, groupNames, vWeightDict):
if len(vWeightDict) != len(me.verts):
raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights'
act_group = me.activeGroup
# Clear the vert group.
currentGroupNames= me.getVertGroupNames()
for group in currentGroupNames:
@ -159,6 +166,9 @@ def dict2MeshWeight(me, groupNames, vWeightDict):
except:
pass # vert group is not used anymore.
try: me.activeGroup = act_group
except: pass
me.update()
def dictWeightMerge(dict_weights):
@ -290,6 +300,23 @@ def mesh2linkedFaces(me):
return [fg for fg in face_groups if fg]
def getEdgeLoopsFromFaces(faces):
'''
Takes me.faces or a list of faces and returns the edge loops
These edge loops are the edges that sit between quads, so they dont touch
1 quad, not not connected will make 2 edge loops, both only containing 2 edges.
'''
edges = {}
for f in faces:
for i, edkey in enumerate(f.edge_keys):
try: edges[edkey].append((f, i))
except: edges[edkey] = [(f, i)]
def getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None):
'''
ob - the object that you want to get the mesh from

@ -41,20 +41,35 @@ It removes very low weighted verts from the current group with a weight option.
from Blender import Scene, Draw
import BPyMesh
SMALL_NUM= 0.000001
def actWeightNormalize(me, PREF_THRESH, PREF_KEEP_SINGLE):
def weightClean(me, PREF_THRESH, PREF_KEEP_SINGLE, PREF_OTHER_GROUPS):
groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
act_group= me.activeGroup
for wd in vWeightDict:
if not PREF_KEEP_SINGLE or len(wd) > 1:
try:
w= wd[act_group]
if w <= PREF_THRESH:
# small weight, remove.
del wd[act_group]
except:
pass
if PREF_OTHER_GROUPS:
for wd in vWeightDict:
l = len(wd)
if not PREF_KEEP_SINGLE or l > 1:
for group in wd.keys():
w= wd[group]
if w <= PREF_THRESH:
# small weight, remove.
del wd[group]
l-=1
if PREF_KEEP_SINGLE and l == 1:
break
else:
for wd in vWeightDict:
if not PREF_KEEP_SINGLE or len(wd) > 1:
try:
w= wd[act_group]
if w <= PREF_THRESH:
# small weight, remove.
del wd[act_group]
except:
pass
# Copy weights back to the mesh.
BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
@ -62,29 +77,28 @@ def actWeightNormalize(me, PREF_THRESH, PREF_KEEP_SINGLE):
def main():
scn= Scene.GetCurrent()
ob= scn.getActiveObject()
ob= scn.objects.active
if not ob or ob.getType() != 'Mesh':
if not ob or ob.type != 'Mesh':
Draw.PupMenu('Error, no active mesh object, aborting.')
return
me= ob.getData(mesh=1)
PREF_PEAKWEIGHT= Draw.Create(0.005)
PREF_PEAKWEIGHT= Draw.Create(0.001)
PREF_KEEP_SINGLE= Draw.Create(1)
PREF_OTHER_GROUPS= Draw.Create(0)
pup_block= [\
('Peak Weight:', PREF_PEAKWEIGHT, 0.01, 1.0, 'Upper weight for normalizing.'),\
('Keep Single User', PREF_KEEP_SINGLE, 'Dont remove verts that are in this group only.'),\
('Peak Weight:', PREF_PEAKWEIGHT, 0.005, 1.0, 'Remove verts from groups below this weight.'),\
('All Other Groups', PREF_OTHER_GROUPS, 'Clean all groups, not just the current one.'),\
('Keep Single User', PREF_KEEP_SINGLE, 'Keep verts in at least 1 group.'),\
]
if not Draw.PupBlock('Clean Selected Meshes...', pup_block):
return
PREF_PEAKWEIGHT= PREF_PEAKWEIGHT.val
PREF_KEEP_SINGLE= PREF_KEEP_SINGLE.val
actWeightNormalize(me, PREF_PEAKWEIGHT, PREF_KEEP_SINGLE)
weightClean(me, PREF_PEAKWEIGHT.val, PREF_KEEP_SINGLE.val, PREF_OTHER_GROUPS.val)
if __name__=='__main__':
main()

@ -135,36 +135,70 @@ def point_in_data(point, mesh_data_tuple):
return len( filter(isect, mesh_data) ) % 2
import BPyMesh
def env_from_group(ob_act, grp, PREF_OVERWRITE=True):
# get intersection data
# group_isect_data = [intersection_data(ob) for ob in group.objects]
group_isect_data = []
for ob in grp.objects:
if ob != ob_act: # in case we're in the group.
gid = intersection_data(ob)
if gid[1]: # has some triangles?
group_isect_data.append( gid )
# sort by name
group_isect_data.sort()
group_names = [gid[0] for gid in group_isect_data]
def env_from_group(ob_act, grp, PREF_UPDATE_ACT=True):
me = ob_act.getData(mesh=1)
len_group_names= len(group_names)
vweight_list= [[0.0]*len_group_names for i in xrange(len(me.verts))]
if PREF_UPDATE_ACT:
act_group = me.activeGroup
if act_group == 'None':
Draw.PupMenu('Error%t|No active vertex group.')
return
try:
ob = Object.Get(act_group)
except:
Draw.PupMenu('Error%t|No object named "'+ act_group +'".')
return
group_isect = intersection_data(ob)
else:
# get intersection data
# group_isect_data = [intersection_data(ob) for ob in group.objects]
group_isect_data = []
for ob in grp.objects:
if ob != ob_act: # in case we're in the group.
gid = intersection_data(ob)
if gid[1]: # has some triangles?
group_isect_data.append( gid )
# we only need 1 for the active group
if PREF_UPDATE_ACT:
break
# sort by name
group_isect_data.sort()
if PREF_UPDATE_ACT:
group_names, vweight_list = BPyMesh.meshWeight2List(me)
group_index = group_names.index(act_group)
else:
group_names = [gid[0] for gid in group_isect_data]
vweight_list= [[0.0]* len(group_names) for i in xrange(len(me.verts))]
ob_act_mat = ob_act.matrixWorld
for vi, v in enumerate(me.verts):
# Get all the groups for this vert
co = v.co * ob_act_mat
for group_index, group_isect in enumerate(group_isect_data):
if point_in_data(co, group_isect):
vweight_list[vi][group_index] = 1.0
if PREF_UPDATE_ACT:
# only update existing
if point_in_data(co, group_isect): w = 1.0
else: w = 0.0
vweight_list[vi][group_index] = w
else:
# generate new vgroup weights.
for group_index, group_isect in enumerate(group_isect_data):
if point_in_data(co, group_isect):
vweight_list[vi][group_index] = 1.0
BPyMesh.list2MeshWeight(me, group_names, vweight_list)
import BPyMessages
def main():
@ -175,28 +209,30 @@ def main():
return
PREF_ENV_GROUPNAME= Draw.Create('')
PREF_OVERWRITE= Draw.Create(False)
PREF_UPDATE_ACT= Draw.Create(True)
pup_block= [\
'Group Name',\
('Update Active', PREF_UPDATE_ACT, 'Only apply envalope weights to the active group.'),\
'or initialize from group',\
('GR:', PREF_ENV_GROUPNAME, 0, 21, 'The name of an existing groups to '),\
#('Overwrite', PREF_OVERWRITE, 'Overwrite existing vertex groups.'),\
]
if not Draw.PupBlock('Envalope From Group...', pup_block):
return
try:
grp = Group.Get(PREF_ENV_GROUPNAME.val)
except:
Draw.PupMenu('Error%t|Group "' + PREF_ENV_GROUPNAME.val + '" does not exist.')
return
PREF_UPDATE_ACT= PREF_UPDATE_ACT.val
PREF_ENV_GROUPNAME= PREF_ENV_GROUPNAME.val
PREF_OVERWRITE= PREF_OVERWRITE.val
if not PREF_UPDATE_ACT:
try:
grp = Group.Get(PREF_ENV_GROUPNAME.val)
except:
Draw.PupMenu('Error%t|Group "' + PREF_ENV_GROUPNAME.val + '" does not exist.')
return
else:
grp = None
Window.WaitCursor(1)
t = sys.time()
env_from_group(ob_act, grp, PREF_OVERWRITE)
env_from_group(ob_act, grp, PREF_UPDATE_ACT)
print 'assigned envelopes in:', sys.time() - t
Window.WaitCursor(0)

@ -25,9 +25,9 @@ import Blender
def main():
scn= Blender.Scene.GetCurrent()
ob= scn.getActiveObject()
ob= scn.objects.active
if not ob or ob.getType() != 'Mesh':
if not ob or ob.type != 'Mesh':
Blender.Draw.PupMenu('Error, no active mesh object, aborting.')
return
# MODE 0 == VCOL

@ -66,6 +66,7 @@ def actWeightNormalize(me, PREF_PEAKWEIGHT, PREF_KEEP_PROPORTION):
if abs(max_weight-PREF_PEAKWEIGHT) < SMALL_NUM:
Draw.PupMenu('Vert Weights are alredy normalized.')
return
max_weight= max_weight/PREF_PEAKWEIGHT
@ -90,13 +91,13 @@ def actWeightNormalize(me, PREF_PEAKWEIGHT, PREF_KEEP_PROPORTION):
# Copy weights back to the mesh.
BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
def main():
scn= Scene.GetCurrent()
ob= scn.getActiveObject()
ob= scn.objects.active
if not ob or ob.getType() != 'Mesh':
if not ob or ob.type != 'Mesh':
Draw.PupMenu('Error, no active mesh object, aborting.')
return
@ -113,10 +114,7 @@ def main():
if not Draw.PupBlock('Clean Selected Meshes...', pup_block):
return
PREF_PEAKWEIGHT= PREF_PEAKWEIGHT.val
PREF_KEEP_PROPORTION= PREF_KEEP_PROPORTION.val
actWeightNormalize(me, PREF_PEAKWEIGHT, PREF_KEEP_PROPORTION)
actWeightNormalize(me, PREF_PEAKWEIGHT.val, PREF_KEEP_PROPORTION.val)
if __name__=='__main__':
main()

@ -46,7 +46,7 @@ typedef void (*SeqDoit)(void*, float, float, int, int,
typedef struct VarStruct {
int type;
char name[16];
char name[32];
float def, min, max;
char tip[80];
} VarStruct;