forked from bartvdbraak/blender
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:
parent
11e035b0fc
commit
84f60b19c8
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user