1
# mangle_tools.py (c) 2011 Phil Cote (cotejrp1)
3
# ***** BEGIN GPL LICENSE BLOCK *****
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software Foundation,
18
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
# ***** END GPL LICENCE BLOCK *****
22
"name": "Mangle Tools",
23
"author": "Phil Cote",
26
"location": "View3D > Tools",
27
"description": "Set of tools to mangle curves, meshes, and shape keys",
28
"warning": "", # used for warning icon and text in addons panel
29
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
31
"tracker_url": "https://projects.blender.org/tracker/index.php?"\
32
"func=detail&aid=29071",
41
def move_coordinate(context, co, is_curve=False):
42
xyz_const = context.scene.constraint_vector
43
random.seed(time.time())
46
# For curves, we base the multiplier on the circumference formula.
47
# This helps make curve changes more noticable.
50
random_mag = context.scene.random_magnitude
52
co.x += .01 * random.randrange( -random_mag, random_mag ) * multiplier
54
co.y += .01 * random.randrange( -random_mag, random_mag ) * multiplier
56
co.z += .01 * random.randrange( -random_mag, random_mag ) * multiplier
59
class MeshManglerOperator(bpy.types.Operator):
60
'''push vertices on the selected object around in random directions to
61
create a crumpled look'''
62
bl_idname = "ba.mesh_mangler"
63
bl_label = "Mangle Mesh"
64
bl_options = { "REGISTER", "UNDO" }
67
def poll(cls, context):
68
ob = context.active_object
69
return ob != None and ob.type == 'MESH'
71
def execute(self, context):
72
mesh = context.active_object.data
75
verts, faces = bm.verts, bm.faces
76
randomMag = context.scene.random_magnitude
77
random.seed( time.time() )
79
if mesh.shape_keys != None:
80
self.report( {"INFO"}, "Cannot mangle mesh: Shape keys present" )
84
xVal = .01 * random.randrange( -randomMag, randomMag )
85
yVal = .01 * random.randrange( -randomMag, randomMag)
86
zVal = .01 * random.randrange( -randomMag, randomMag )
87
vert.co.x = vert.co.x + xVal
88
vert.co.y = vert.co.y + yVal
89
vert.co.z = vert.co.z + zVal
96
class AnimanglerOperator(bpy.types.Operator):
97
'''makes a shape key and pushes the verts around on it to set up for random pulsating animation'''
98
bl_idname = "ba.ani_mangler"
99
bl_label = "Mangle Shape Key"
103
def poll(cls, context):
104
ob = context.active_object
105
return ob != None and ob.type in [ 'MESH', 'CURVE' ]
107
def execute(self, context):
109
mangleName = scn.mangle_name
111
shapeKey = ob.shape_key_add( name=mangleName )
112
verts = shapeKey.data
115
move_coordinate(context, vert.co, is_curve=ob.type=='CURVE')
120
class CurveManglerOp(bpy.types.Operator):
121
'''Mangles a curve to the degree the user specifies'''
122
bl_idname = "ba.curve_mangler"
123
bl_label = "Mangle Curve"
124
bl_options = { 'REGISTER', 'UNDO' }
127
def poll(cls, context):
128
ob = context.active_object
129
return ob != None and ob.type == "CURVE"
132
def execute(self, context):
134
ob = context.active_object
135
if ob.data.shape_keys != None:
136
self.report({"INFO"}, "Cannot mangle curve. Shape keys present")
138
splines = context.object.data.splines
140
for spline in splines:
141
if spline.type == 'BEZIER':
142
points = spline.bezier_points
143
elif spline.type in ('POLY', 'NURBS'):
144
points = spline.points
147
move_coordinate(context, point.co, is_curve=True)
152
class MangleToolsPanel(bpy.types.Panel):
153
bl_label = "Mangle Tools"
154
bl_space_type = "VIEW_3D"
155
bl_region_type="TOOLS"
156
bl_context = "objectmode"
157
bl_options = {'DEFAULT_CLOSED'}
159
def draw(self, context):
162
col = layout.column()
163
col.prop(scn, "constraint_vector")
164
col.prop(scn, "random_magnitude")
166
col.operator("ba.curve_mangler")
167
col.operator("ba.mesh_mangler")
169
col.prop(scn, "mangle_name")
170
col.operator("ba.ani_mangler")
173
IntProperty = bpy.props.IntProperty
174
StringProperty = bpy.props.StringProperty
175
BoolVectorProperty = bpy.props.BoolVectorProperty
178
bpy.utils.register_class(AnimanglerOperator)
179
bpy.utils.register_class(MeshManglerOperator)
180
bpy.utils.register_class(CurveManglerOp)
181
bpy.utils.register_class(MangleToolsPanel)
182
scnType = bpy.types.Scene
185
scnType.constraint_vector = BoolVectorProperty(name="Mangle Constraint",
186
default=(True,True,True),
188
description="Constrains Mangle Direction")
190
scnType.random_magnitude = IntProperty( name = "Mangle Severity",
191
default = 10, min = 1, max = 30,
192
description = "Severity of mangling")
194
scnType.mangle_name = StringProperty(name="Shape Key Name",
196
description="Name given for mangled shape keys")
198
bpy.utils.unregister_class(AnimanglerOperator)
199
bpy.utils.unregister_class(MeshManglerOperator)
200
bpy.utils.unregister_class(MangleToolsPanel)
201
bpy.utils.unregister_class(CurveManglerOp)
204
if __name__ == "__main__":