Welcome to mirror list, hosted at ThFree Co, Russian Federation.

weightpaint_grow_shrink.py « scripts « release - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 5c0f28685f9bf44c3a8d4df4689a1fe3536a1b9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!BPY
"""
Name: 'Grow/Shrink Weight...'
Blender: 245
Group: 'WeightPaint'
Tooltip: 'Grow/Shrink active vertex group.'
"""

__author__ = "Campbell Barton aka ideasman42"
__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
__version__ = "0.1"
__bpydoc__ = """\

Grow Shrink Weight

This Script is to be used only in weight paint mode,
It grows/shrinks the bounds of the weight painted area
"""

# ***** BEGIN GPL LICENSE BLOCK *****
#
# Script copyright (C) Campbell J Barton
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------

from Blender import Scene, Draw, Window
import BPyMesh
def actWeightNormalize(me, PREF_MODE, PREF_MAX_DIST, PREF_STRENGTH, PREF_ITERATIONS):
	Window.WaitCursor(1)
	groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
	act_group= me.activeGroup
	
	# Start with assumed zero weights
	orig_vert_weights= [0.0] * len(vWeightDict) # Will be directly assigned to orig_vert_weights
	
	
	# fill in the zeros with real weights.
	for i, wd in enumerate(vWeightDict):
		try:
			orig_vert_weights[i]= wd[act_group]
		except:
			pass
	
	new_vert_weights= list(orig_vert_weights)
	
	for dummy in xrange(PREF_ITERATIONS):
		# Minimize or maximize the weights. connection based.
		
		if PREF_MODE==0: # Grow
			op= max
		else: # Shrink
			op= min
		
		for ed in me.edges:
			if not PREF_MAX_DIST or ed.length < PREF_MAX_DIST:
			
				i1= ed.v1.index
				i2= ed.v2.index
				new_weight= op(orig_vert_weights[i1], orig_vert_weights[i2])
				
				if PREF_STRENGTH==1.0: # do a full copy
					new_vert_weights[i1]= op(new_weight, new_vert_weights[i1])
					new_vert_weights[i2]= op(new_weight, new_vert_weights[i2])
					
				else: # Do a faded copy
					new_vert_weights[i1]= op(new_weight, new_vert_weights[i1])
					new_vert_weights[i2]= op(new_weight, new_vert_weights[i2])
					
					# Face the copy with the original (orig is updated per iteration)
					new_vert_weights[i1]= (new_vert_weights[i1]*PREF_STRENGTH) + (orig_vert_weights[i1]*(1-PREF_STRENGTH))
					new_vert_weights[i2]= (new_vert_weights[i2]*PREF_STRENGTH) + (orig_vert_weights[i2]*(1-PREF_STRENGTH))
		
		
		for i, wd in enumerate(vWeightDict):
			new_weight= new_vert_weights[i]
			if new_weight != orig_vert_weights[i]:
				wd[act_group]= new_weight
		
		if dummy+1 != PREF_ITERATIONS: # dont copy the list on the last round.
			orig_vert_weights= list(new_vert_weights)
		
		
	# Copy weights back to the mesh.
	BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
	Window.WaitCursor(0)

def main():
	scn= Scene.GetCurrent()
	ob= scn.objects.active
	
	if not ob or ob.type != 'Mesh':
		Draw.PupMenu('Error, no active mesh object, aborting.')
		return
	
	me= ob.getData(mesh=1)
	
	PREF_MAXDIST= Draw.Create(0.0)
	PREF_STRENGTH= Draw.Create(1.0)
	PREF_MODE= Draw.Create(0)
	PREF_ITERATIONS= Draw.Create(1)
	
	pup_block= [\
	('Bleed Dist:', PREF_MAXDIST, 0.0, 1.0, 'Set a distance limit for bleeding.'),\
	('Bleed Strength:', PREF_STRENGTH, 0.01, 1.0, 'Bleed strength between adjacent verts weight. 1:full, 0:None'),\
	('Iterations', PREF_ITERATIONS, 1, 20, 'Number of times to run the blending calculation.'),\
	('Contract (Shrink)', PREF_MODE, 'Shrink instead of growing.'),\
	]
	
	if not Draw.PupBlock('Grow/Shrink...', pup_block):
		return
	
	actWeightNormalize(me, PREF_MODE.val, PREF_MAXDIST.val, PREF_STRENGTH.val, PREF_ITERATIONS.val)


if __name__=='__main__':
	main()