1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
21 "author": "Daniel Salazar <zanqdo@gmail.com>",
24 "location": "Tool bar > Animation tab > AnimAll",
25 "description": "Allows animation of mesh, lattice, curve and surface data",
27 "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
28 "Scripts/Animation/AnimAll",
29 "category": "Animation",
33 Thanks to Campbell Barton and Joshua Leung for hes API additions and fixes
34 Daniel 'ZanQdo' Salazar
38 from bpy
.types
import (
43 from bpy
.props
import (
49 # Property Definitions
51 bpy
.types
.WindowManager
.key_shape
= BoolProperty(
53 description
="Insert keyframes on active Shape Key layer",
56 bpy
.types
.WindowManager
.key_uvs
= BoolProperty(
58 description
="Insert keyframes on active UV coordinates",
61 bpy
.types
.WindowManager
.key_ebevel
= BoolProperty(
63 description
="Insert keyframes on edge bevel weight",
66 bpy
.types
.WindowManager
.key_vbevel
= BoolProperty(
68 description
="Insert keyframes on vertex bevel weight",
71 bpy
.types
.WindowManager
.key_crease
= BoolProperty(
73 description
="Insert keyframes on edge creases",
76 bpy
.types
.WindowManager
.key_vcols
= BoolProperty(
78 description
="Insert keyframes on active Vertex Color values",
81 bpy
.types
.WindowManager
.key_vgroups
= BoolProperty(
83 description
="Insert keyframes on active Vertex Group values",
86 bpy
.types
.WindowManager
.key_points
= BoolProperty(
88 description
="Insert keyframes on point locations",
91 bpy
.types
.WindowManager
.key_radius
= BoolProperty(
93 description
="Insert keyframes on point radius (Shrink/Fatten)",
96 bpy
.types
.WindowManager
.key_tilt
= BoolProperty(
98 description
="Insert keyframes on point tilt",
105 def refresh_ui_keyframes():
107 for area
in bpy
.context
.screen
.areas
:
108 if area
.type in ('TIMELINE', 'GRAPH_EDITOR', 'DOPESHEET_EDITOR'):
114 def insert_key(data
, key
):
116 data
.keyframe_insert(key
)
121 def delete_key(data
, key
):
123 data
.keyframe_delete(key
)
130 class VIEW3D_PT_animall(Panel
):
131 bl_space_type
= 'VIEW_3D'
132 bl_region_type
= 'TOOLS'
133 bl_category
= "Animation"
137 def poll(self
, context
):
138 if context
.active_object
and context
.active_object
.type in {'MESH', 'LATTICE', 'CURVE', 'SURFACE'}:
139 return context
.active_object
.type
141 def draw(self
, context
):
142 Obj
= context
.active_object
145 col
= layout
.column(align
=True)
148 if Obj
.type == 'LATTICE':
149 row
.prop(context
.window_manager
, "key_points")
150 row
.prop(context
.window_manager
, "key_shape")
152 elif Obj
.type == 'MESH':
153 row
.prop(context
.window_manager
, "key_points")
154 row
.prop(context
.window_manager
, "key_shape")
156 row
.prop(context
.window_manager
, "key_ebevel")
157 row
.prop(context
.window_manager
, "key_vbevel")
159 row
.prop(context
.window_manager
, "key_crease")
160 row
.prop(context
.window_manager
, "key_uvs")
162 row
.prop(context
.window_manager
, "key_vcols")
163 row
.prop(context
.window_manager
, "key_vgroups")
165 elif Obj
.type == 'CURVE':
166 row
.prop(context
.window_manager
, "key_points")
167 row
.prop(context
.window_manager
, "key_shape")
169 row
.prop(context
.window_manager
, "key_radius")
170 row
.prop(context
.window_manager
, "key_tilt")
172 elif Obj
.type == 'SURFACE':
173 row
.prop(context
.window_manager
, "key_points")
174 row
.prop(context
.window_manager
, "key_shape")
176 row
.prop(context
.window_manager
, "key_radius")
177 row
.prop(context
.window_manager
, "key_tilt")
180 row
= layout
.row(align
=True)
181 row
.operator("anim.insert_keyframe_animall", icon
="KEY_HLT")
182 row
.operator("anim.delete_keyframe_animall", icon
="KEY_DEHLT")
184 row
.operator("anim.clear_animation_animall", icon
="X")
186 if context
.window_manager
.key_shape
:
187 ShapeKey
= Obj
.active_shape_key
188 ShapeKeyIndex
= Obj
.active_shape_key_index
190 split
= layout
.split()
193 if ShapeKeyIndex
> 0:
194 row
.label(ShapeKey
.name
, icon
="SHAPEKEY_DATA")
195 row
.prop(ShapeKey
, "value", text
="")
196 row
.prop(Obj
, "show_only_shape_key", text
="")
197 if ShapeKey
.value
< 1:
199 row
.label('Maybe set "%s" to 1.0?' % ShapeKey
.name
, icon
="INFO")
201 row
.label("Can not key on Basis Shape", icon
="ERROR")
203 row
.label("No active Shape Key", icon
="ERROR")
205 if context
.window_manager
.key_points
and context
.window_manager
.key_shape
:
207 row
.label('"Points" and "Shape" are redundant?', icon
="INFO")
210 class ANIM_OT_insert_keyframe_animall(Operator
):
212 bl_idname
= "anim.insert_keyframe_animall"
213 bl_description
= "Insert a Keyframe"
214 bl_options
= {'REGISTER', 'UNDO'}
216 def invoke(self
, context
, event
):
217 self
.execute(context
)
221 def execute(op
, context
):
222 Obj
= context
.active_object
224 if Obj
.type == 'MESH':
226 if context
.mode
== 'EDIT_MESH':
228 bpy
.ops
.object.editmode_toggle()
232 if context
.window_manager
.key_shape
:
233 if Obj
.active_shape_key_index
> 0:
234 for Vert
in Obj
.active_shape_key
.data
:
235 insert_key(Vert
, 'co')
237 if context
.window_manager
.key_points
:
238 for Vert
in Data
.vertices
:
239 insert_key(Vert
, 'co')
241 if context
.window_manager
.key_ebevel
:
242 for Edge
in Data
.edges
:
243 insert_key(Edge
, 'bevel_weight')
245 if context
.window_manager
.key_vbevel
:
246 for Vert
in Data
.vertices
:
247 insert_key(Vert
, 'bevel_weight')
249 if context
.window_manager
.key_crease
:
250 for Edge
in Data
.edges
:
251 insert_key(Edge
, 'crease')
253 if context
.window_manager
.key_vgroups
:
254 for Vert
in Data
.vertices
:
255 for Group
in Vert
.groups
:
256 insert_key(Group
, 'weight')
258 if context
.window_manager
.key_uvs
:
259 for UV
in Data
.uv_layers
.active
.data
:
262 if context
.window_manager
.key_vcols
:
263 for VColLayer
in Data
.vertex_colors
:
264 if VColLayer
.active
: # only insert in active VCol layer
265 for Data
in VColLayer
.data
:
266 insert_key(Data
, 'color')
269 bpy
.ops
.object.editmode_toggle()
271 if Obj
.type == 'LATTICE':
273 if context
.mode
!= 'OBJECT':
275 bpy
.ops
.object.editmode_toggle()
279 if context
.window_manager
.key_shape
:
280 if Obj
.active_shape_key_index
> 0:
281 for Point
in Obj
.active_shape_key
.data
:
282 insert_key(Point
, 'co')
284 if context
.window_manager
.key_points
:
285 for Point
in Data
.points
:
286 insert_key(Point
, 'co_deform')
289 bpy
.ops
.object.editmode_toggle()
291 if Obj
.type in {'CURVE', 'SURFACE'}:
293 if context
.mode
!= 'OBJECT':
295 bpy
.ops
.object.editmode_toggle()
299 # run this outside the splines loop (only once)
300 if context
.window_manager
.key_shape
:
301 if Obj
.active_shape_key_index
> 0:
302 for CV
in Obj
.active_shape_key
.data
:
304 insert_key(CV
, 'handle_left')
305 insert_key(CV
, 'handle_right')
307 for Spline
in Data
.splines
:
308 if Spline
.type == 'BEZIER':
310 for CV
in Spline
.bezier_points
:
311 if context
.window_manager
.key_points
:
313 insert_key(CV
, 'handle_left')
314 insert_key(CV
, 'handle_right')
316 if context
.window_manager
.key_radius
:
317 insert_key(CV
, 'radius')
319 if context
.window_manager
.key_tilt
:
320 insert_key(CV
, 'tilt')
322 elif Spline
.type == 'NURBS':
323 for CV
in Spline
.points
:
324 if context
.window_manager
.key_points
:
327 if context
.window_manager
.key_radius
:
328 insert_key(CV
, 'radius')
330 if context
.window_manager
.key_tilt
:
331 insert_key(CV
, 'tilt')
334 bpy
.ops
.object.editmode_toggle()
336 refresh_ui_keyframes()
341 class ANIM_OT_delete_keyframe_animall(Operator
):
343 bl_idname
= "anim.delete_keyframe_animall"
344 bl_description
= "Delete a Keyframe"
345 bl_options
= {'REGISTER', 'UNDO'}
347 def invoke(self
, context
, event
):
348 self
.execute(context
)
352 def execute(op
, context
):
353 Obj
= context
.active_object
355 if Obj
.type == 'MESH':
357 if context
.mode
== 'EDIT_MESH':
359 bpy
.ops
.object.editmode_toggle()
363 if context
.window_manager
.key_shape
:
364 if Obj
.active_shape_key
:
365 for Vert
in Obj
.active_shape_key
.data
:
366 delete_key(Vert
, 'co')
368 if context
.window_manager
.key_points
:
369 for Vert
in Data
.vertices
:
370 delete_key(Vert
, 'co')
372 if context
.window_manager
.key_ebevel
:
373 for Edge
in Data
.edges
:
374 delete_key(Edge
, 'bevel_weight')
376 if context
.window_manager
.key_vbevel
:
377 for Vert
in Data
.vertices
:
378 delete_key(Vert
, 'bevel_weight')
380 if context
.window_manager
.key_crease
:
381 for Edge
in Data
.edges
:
382 delete_key(Edge
, 'crease')
384 if context
.window_manager
.key_vgroups
:
385 for Vert
in Data
.vertices
:
386 for Group
in Vert
.groups
:
387 delete_key(Group
, 'weight')
389 if context
.window_manager
.key_uvs
:
390 for UV
in Data
.uv_layers
.active
.data
:
393 if context
.window_manager
.key_vcols
:
394 for VColLayer
in Data
.vertex_colors
:
395 if VColLayer
.active
: # only delete in active VCol layer
396 for Data
in VColLayer
.data
:
397 delete_key(Data
, 'color')
400 bpy
.ops
.object.editmode_toggle()
402 if Obj
.type == 'LATTICE':
404 if context
.mode
!= 'OBJECT':
406 bpy
.ops
.object.editmode_toggle()
410 if context
.window_manager
.key_shape
:
411 if Obj
.active_shape_key
:
412 for Point
in Obj
.active_shape_key
.data
:
413 delete_key(Point
, 'co')
415 if context
.window_manager
.key_points
:
416 for Point
in Data
.points
:
417 delete_key(Point
, 'co_deform')
420 bpy
.ops
.object.editmode_toggle()
422 if Obj
.type in {'CURVE', 'SURFACE'}:
424 if context
.mode
!= 'OBJECT':
426 bpy
.ops
.object.editmode_toggle()
430 # run this outside the splines loop (only once)
431 if context
.window_manager
.key_shape
:
432 if Obj
.active_shape_key_index
> 0:
433 for CV
in Obj
.active_shape_key
.data
:
435 delete_key(CV
, 'handle_left')
436 delete_key(CV
, 'handle_right')
438 for Spline
in Data
.splines
:
439 if Spline
.type == 'BEZIER':
440 for CV
in Spline
.bezier_points
:
441 if context
.window_manager
.key_points
:
443 delete_key(CV
, 'handle_left')
444 delete_key(CV
, 'handle_right')
445 if context
.window_manager
.key_radius
:
446 delete_key(CV
, 'radius')
447 if context
.window_manager
.key_tilt
:
448 delete_key(CV
, 'tilt')
450 elif Spline
.type == 'NURBS':
451 for CV
in Spline
.points
:
452 if context
.window_manager
.key_points
:
454 if context
.window_manager
.key_radius
:
455 delete_key(CV
, 'radius')
456 if context
.window_manager
.key_tilt
:
457 delete_key(CV
, 'tilt')
460 bpy
.ops
.object.editmode_toggle()
462 refresh_ui_keyframes()
467 class ANIM_OT_clear_animation_animall(Operator
):
468 bl_label
= "Clear Animation"
469 bl_idname
= "anim.clear_animation_animall"
470 bl_description
= ("Delete all keyframes for this object\n"
471 "If in a specific case it doesn't work\n"
472 "try to delete the keys manually")
473 bl_options
= {'REGISTER', 'UNDO'}
475 def invoke(self
, context
, event
):
476 wm
= context
.window_manager
477 return wm
.invoke_confirm(self
, event
)
479 def execute(self
, context
):
481 Data
= context
.active_object
.data
482 Data
.animation_data_clear()
484 self
.report({'WARNING'}, "Clear Animation could not be performed")
487 refresh_ui_keyframes()
492 # Add-ons Preferences Update Panel
494 # Define Panel classes for updating
500 def update_panel(self
, context
):
501 message
= "AnimAll: Updating Panel locations has failed"
504 if "bl_rna" in panel
.__dict
__:
505 bpy
.utils
.unregister_class(panel
)
508 panel
.bl_category
= context
.user_preferences
.addons
[__name__
].preferences
.category
509 bpy
.utils
.register_class(panel
)
511 except Exception as e
:
512 print("\n[{}]\n{}\n\nError:\n{}".format(__name__
, message
, e
))
516 class AnimallAddonPreferences(AddonPreferences
):
517 # this must match the addon name, use '__package__'
518 # when defining this in a submodule of a python package.
521 category
= StringProperty(
523 description
="Choose a name for the category of the panel",
528 def draw(self
, context
):
533 col
.label(text
="Tab Category:")
534 col
.prop(self
, "category", text
="")
538 bpy
.utils
.register_module(__name__
)
539 update_panel(None, bpy
.context
)
544 bpy
.utils
.unregister_module(__name__
)
548 if __name__
== "__main__":