1 # SPDX-License-Identifier: GPL-2.0-or-later
5 "author": "Daniel Salazar (ZanQdo), Damien Picard (pioverfour)",
8 "location": "3D View > Toolbox > Animation tab > AnimAll",
9 "description": "Allows animation of mesh, lattice, curve and surface data",
11 "doc_url": "{BLENDER_MANUAL_URL}/addons/animation/animall.html",
12 "category": "Animation",
16 from bpy
.types
import (
21 from bpy
.props
import (
25 from bpy
.app
.handlers
import persistent
28 # Property Definitions
29 class AnimallProperties(bpy
.types
.PropertyGroup
):
30 key_selected
: BoolProperty(
31 name
="Key Selected Only",
32 description
="Insert keyframes only on selected elements",
36 key_point_location
: BoolProperty(
38 description
="Insert keyframes on point locations",
40 key_shape_key
: BoolProperty(
42 description
="Insert keyframes on active Shape Key layer",
44 key_material_index
: BoolProperty(
45 name
="Material Index",
46 description
="Insert keyframes on face material indices",
50 key_vertex_bevel
: BoolProperty(
52 description
="Insert keyframes on vertex bevel weight",
54 # key_vertex_crease: BoolProperty(
55 # name="Vertex Crease",
56 # description="Insert keyframes on vertex crease weight",
58 key_vertex_group
: BoolProperty(
60 description
="Insert keyframes on active vertex group values",
63 key_edge_bevel
: BoolProperty(
65 description
="Insert keyframes on edge bevel weight",
67 key_edge_crease
: BoolProperty(
69 description
="Insert keyframes on edge creases",
72 key_attribute
: BoolProperty(
74 description
="Insert keyframes on active attribute values",
76 key_uvs
: BoolProperty(
78 description
="Insert keyframes on active UV coordinates",
81 # Curve and surface attributes
82 key_radius
: BoolProperty(
84 description
="Insert keyframes on point radius (Shrink/Fatten)",
86 key_tilt
: BoolProperty(
88 description
="Insert keyframes on point tilt",
94 def refresh_ui_keyframes():
96 for area
in bpy
.context
.screen
.areas
:
97 if area
.type in ('TIMELINE', 'GRAPH_EDITOR', 'DOPESHEET_EDITOR'):
103 def insert_key(data
, key
, group
=None):
105 if group
is not None:
106 data
.keyframe_insert(key
, group
=group
)
108 data
.keyframe_insert(key
)
113 def delete_key(data
, key
):
115 data
.keyframe_delete(key
)
120 def is_selected_vert_loop(data
, loop_i
):
121 """Get selection status of vertex corresponding to a loop"""
122 vertex_index
= data
.loops
[loop_i
].vertex_index
123 return data
.vertices
[vertex_index
].select
128 class VIEW3D_PT_animall(Panel
):
129 bl_space_type
= 'VIEW_3D'
130 bl_region_type
= 'UI'
131 bl_category
= "Animate"
135 def poll(self
, context
):
136 return context
.active_object
and context
.active_object
.type in {'MESH', 'LATTICE', 'CURVE', 'SURFACE'}
138 def draw_header(self
, context
):
142 row
.label (text
= 'AnimAll', icon
= 'ARMATURE_DATA')
144 def draw(self
, context
):
145 obj
= context
.active_object
146 animall_properties
= context
.scene
.animall_properties
150 layout
.label(text
='Key:')
152 layout
.use_property_split
= True
153 layout
.use_property_decorate
= False
155 if obj
.type == 'LATTICE':
156 col
= layout
.column(heading
="Points", align
=True)
157 col
.prop(animall_properties
, "key_point_location")
159 col
= layout
.column(heading
="Others", align
=True)
160 col
.prop(animall_properties
, "key_shape_key")
162 elif obj
.type == 'MESH':
163 col
= layout
.column(heading
="Points", align
=True)
164 col
.prop(animall_properties
, "key_point_location")
165 col
.prop(animall_properties
, "key_vertex_bevel", text
="Bevel")
166 col
.prop(animall_properties
, "key_vertex_group")
168 col
= layout
.column(heading
="Edges", align
=True)
169 col
.prop(animall_properties
, "key_edge_bevel", text
="Bevel")
170 col
.prop(animall_properties
, "key_edge_crease", text
="Crease")
172 col
= layout
.column(heading
="Faces", align
=True)
173 col
.prop(animall_properties
, "key_material_index")
175 col
= layout
.column(heading
="Others", align
=True)
176 col
.prop(animall_properties
, "key_attribute")
177 col
.prop(animall_properties
, "key_uvs")
178 col
.prop(animall_properties
, "key_shape_key")
180 # Vertex group update operator
181 if (obj
.data
.animation_data
is not None
182 and obj
.data
.animation_data
.action
is not None):
183 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
184 if fcurve
.data_path
.startswith("vertex_colors"):
185 col
= layout
.column(align
=True)
186 col
.label(text
="Object includes old-style vertex colors. Consider updating them.", icon
="ERROR")
187 col
.operator("anim.update_vertex_color_animation_animall", icon
="FILE_REFRESH")
190 elif obj
.type in {'CURVE', 'SURFACE'}:
191 col
= layout
.column(align
=True)
192 col
= layout
.column(heading
="Points", align
=True)
193 col
.prop(animall_properties
, "key_point_location")
194 col
.prop(animall_properties
, "key_radius")
195 col
.prop(animall_properties
, "key_tilt")
197 col
= layout
.column(heading
="Splines", align
=True)
198 col
.prop(animall_properties
, "key_material_index")
200 col
= layout
.column(heading
="Others", align
=True)
201 col
.prop(animall_properties
, "key_shape_key")
203 if animall_properties
.key_shape_key
:
204 shape_key
= obj
.active_shape_key
205 shape_key_index
= obj
.active_shape_key_index
207 if shape_key_index
> 0:
208 col
= layout
.column(align
=True)
209 row
= col
.row(align
=True)
210 row
.prop(shape_key
, "value", text
=shape_key
.name
, icon
="SHAPEKEY_DATA")
211 row
.prop(obj
, "show_only_shape_key", text
="")
212 if shape_key
.value
< 1:
213 col
.label(text
='Maybe set "%s" to 1.0?' % shape_key
.name
, icon
="INFO")
214 elif shape_key
is not None:
215 col
= layout
.column(align
=True)
216 col
.label(text
="Cannot key on Basis Shape", icon
="ERROR")
218 col
= layout
.column(align
=True)
219 col
.label(text
="No active Shape Key", icon
="ERROR")
221 if animall_properties
.key_point_location
:
222 col
.label(text
='"Location" and "Shape Key" are redundant?', icon
="INFO")
224 layout
.use_property_split
= False
227 row
.prop(animall_properties
, "key_selected")
229 row
= layout
.row(align
=True)
230 row
.operator("anim.insert_keyframe_animall", icon
="KEY_HLT")
231 row
.operator("anim.delete_keyframe_animall", icon
="KEY_DEHLT")
233 row
.operator("anim.clear_animation_animall", icon
="CANCEL")
236 class ANIM_OT_insert_keyframe_animall(Operator
):
237 bl_label
= "Insert Key"
238 bl_idname
= "anim.insert_keyframe_animall"
239 bl_description
= "Insert a Keyframe"
240 bl_options
= {'REGISTER', 'UNDO'}
242 def execute(op
, context
):
243 animall_properties
= context
.scene
.animall_properties
245 if context
.mode
== 'OBJECT':
246 objects
= context
.selected_objects
248 objects
= context
.objects_in_mode_unique_data
[:]
250 mode
= context
.object.mode
252 # Separate loop for lattices, curves and surfaces, since keyframe insertion
253 # has to happen in Edit Mode, otherwise points move back upon mode switch...
254 # (except for curve shape keys)
255 for obj
in [o
for o
in objects
if o
.type in {'CURVE', 'SURFACE', 'LATTICE'}]:
258 if obj
.type == 'LATTICE':
259 if animall_properties
.key_shape_key
:
260 if obj
.active_shape_key_index
> 0:
261 sk_name
= obj
.active_shape_key
.name
262 for p_i
, point
in enumerate(obj
.active_shape_key
.data
):
263 if not animall_properties
.key_selected
or data
.points
[p_i
].select
:
264 insert_key(point
, 'co', group
="%s Point %s" % (sk_name
, p_i
))
266 if animall_properties
.key_point_location
:
267 for p_i
, point
in enumerate(data
.points
):
268 if not animall_properties
.key_selected
or point
.select
:
269 insert_key(point
, 'co_deform', group
="Point %s" % p_i
)
272 if animall_properties
.key_material_index
:
273 for s_i
, spline
in enumerate(data
.splines
):
274 if (not animall_properties
.key_selected
275 or any(point
.select
for point
in spline
.points
)
276 or any(point
.select_control_point
for point
in spline
.bezier_points
)):
277 insert_key(spline
, 'material_index', group
="Spline %s" % s_i
)
279 for s_i
, spline
in enumerate(data
.splines
):
280 if spline
.type == 'BEZIER':
281 for v_i
, CV
in enumerate(spline
.bezier_points
):
282 if (not animall_properties
.key_selected
283 or CV
.select_control_point
284 or CV
.select_left_handle
285 or CV
.select_right_handle
):
286 if animall_properties
.key_point_location
:
287 insert_key(CV
, 'co', group
="Spline %s CV %s" % (s_i
, v_i
))
288 insert_key(CV
, 'handle_left', group
="Spline %s CV %s" % (s_i
, v_i
))
289 insert_key(CV
, 'handle_right', group
="Spline %s CV %s" % (s_i
, v_i
))
291 if animall_properties
.key_radius
:
292 insert_key(CV
, 'radius', group
="Spline %s CV %s" % (s_i
, v_i
))
294 if animall_properties
.key_tilt
:
295 insert_key(CV
, 'tilt', group
="Spline %s CV %s" % (s_i
, v_i
))
297 elif spline
.type in ('POLY', 'NURBS'):
298 for v_i
, CV
in enumerate(spline
.points
):
299 if not animall_properties
.key_selected
or CV
.select
:
300 if animall_properties
.key_point_location
:
301 insert_key(CV
, 'co', group
="Spline %s CV %s" % (s_i
, v_i
))
303 if animall_properties
.key_radius
:
304 insert_key(CV
, 'radius', group
="Spline %s CV %s" % (s_i
, v_i
))
306 if animall_properties
.key_tilt
:
307 insert_key(CV
, 'tilt', group
="Spline %s CV %s" % (s_i
, v_i
))
309 bpy
.ops
.object.mode_set(mode
='OBJECT')
311 for obj
in [o
for o
in objects
if o
.type in {'MESH', 'CURVE', 'SURFACE'}]:
313 if obj
.type == 'MESH':
314 if animall_properties
.key_point_location
:
315 for v_i
, vert
in enumerate(data
.vertices
):
316 if not animall_properties
.key_selected
or vert
.select
:
317 insert_key(vert
, 'co', group
="Vertex %s" % v_i
)
319 if animall_properties
.key_vertex_bevel
:
320 for v_i
, vert
in enumerate(data
.vertices
):
321 if not animall_properties
.key_selected
or vert
.select
:
322 insert_key(vert
, 'bevel_weight', group
="Vertex %s" % v_i
)
323 # if animall_properties.key_vertex_crease:
324 # for v_i, vert in enumerate(data.vertices):
325 # if not animall_properties.key_selected or vert.select:
326 # insert_key(vert, 'crease', group="Vertex %s" % v_i)
328 if animall_properties
.key_vertex_group
:
329 for v_i
, vert
in enumerate(data
.vertices
):
330 if not animall_properties
.key_selected
or vert
.select
:
331 for group
in vert
.groups
:
332 insert_key(group
, 'weight', group
="Vertex %s" % v_i
)
334 if animall_properties
.key_edge_bevel
:
335 for e_i
, edge
in enumerate(data
.edges
):
336 if not animall_properties
.key_selected
or edge
.select
:
337 insert_key(edge
, 'bevel_weight', group
="Edge %s" % e_i
)
339 if animall_properties
.key_edge_crease
:
340 for e_i
, edge
in enumerate(data
.edges
):
341 if not animall_properties
.key_selected
or edge
.select
:
342 insert_key(edge
, 'crease', group
="Edge %s" % e_i
)
344 if animall_properties
.key_material_index
:
345 for p_i
, polygon
in enumerate(data
.polygons
):
346 if not animall_properties
.key_selected
or polygon
.select
:
347 insert_key(polygon
, 'material_index', group
="Face %s" % p_i
)
349 if animall_properties
.key_attribute
:
350 if data
.attributes
.active
is not None:
351 attribute
= data
.attributes
.active
352 if attribute
.data_type
!= 'STRING':
353 # Cannot animate string attributes?
354 if attribute
.data_type
in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
355 attribute_key
= "value"
356 elif attribute
.data_type
in {'FLOAT_COLOR', 'BYTE_COLOR'}:
357 attribute_key
= "color"
358 elif attribute
.data_type
in {'FLOAT_VECTOR', 'FLOAT2'}:
359 attribute_key
= "vector"
361 if attribute
.domain
== 'POINT':
363 elif attribute
.domain
== 'EDGE':
365 elif attribute
.domain
== 'FACE':
367 elif attribute
.domain
== 'CORNER':
370 for e_i
, _attribute_data
in enumerate(attribute
.data
):
371 if (not animall_properties
.key_selected
372 or attribute
.domain
== 'POINT' and data
.vertices
[e_i
].select
373 or attribute
.domain
== 'EDGE' and data
.edges
[e_i
].select
374 or attribute
.domain
== 'FACE' and data
.polygons
[e_i
].select
375 or attribute
.domain
== 'CORNER' and is_selected_vert_loop(data
, e_i
)):
376 insert_key(data
, f
'attributes["{attribute.name}"].data[{e_i}].{attribute_key}',
379 if animall_properties
.key_uvs
:
380 if data
.uv_layers
.active
is not None:
381 for uv_i
, uv
in enumerate(data
.uv_layers
.active
.data
):
382 if not animall_properties
.key_selected
or uv
.select
:
383 insert_key(uv
, 'uv', group
="UV layer %s" % uv_i
)
385 if animall_properties
.key_shape_key
:
386 if obj
.active_shape_key_index
> 0:
387 sk_name
= obj
.active_shape_key
.name
388 for v_i
, vert
in enumerate(obj
.active_shape_key
.data
):
389 if not animall_properties
.key_selected
or data
.vertices
[v_i
].select
:
390 insert_key(vert
, 'co', group
="%s Vertex %s" % (sk_name
, v_i
))
392 elif obj
.type in {'CURVE', 'SURFACE'}:
393 # Shape key keys have to be inserted in object mode for curves...
394 if animall_properties
.key_shape_key
:
395 sk_name
= obj
.active_shape_key
.name
396 global_spline_index
= 0 # numbering for shape keys, which have flattened indices
397 for s_i
, spline
in enumerate(data
.splines
):
398 if spline
.type == 'BEZIER':
399 for v_i
, CV
in enumerate(spline
.bezier_points
):
400 if (not animall_properties
.key_selected
401 or CV
.select_control_point
402 or CV
.select_left_handle
403 or CV
.select_right_handle
):
404 if obj
.active_shape_key_index
> 0:
405 CV
= obj
.active_shape_key
.data
[global_spline_index
]
406 insert_key(CV
, 'co', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
407 insert_key(CV
, 'handle_left', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
408 insert_key(CV
, 'handle_right', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
409 insert_key(CV
, 'radius', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
410 insert_key(CV
, 'tilt', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
411 global_spline_index
+= 1
413 elif spline
.type in ('POLY', 'NURBS'):
414 for v_i
, CV
in enumerate(spline
.points
):
415 if not animall_properties
.key_selected
or CV
.select
:
416 if obj
.active_shape_key_index
> 0:
417 CV
= obj
.active_shape_key
.data
[global_spline_index
]
418 insert_key(CV
, 'co', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
419 insert_key(CV
, 'radius', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
420 insert_key(CV
, 'tilt', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
421 global_spline_index
+= 1
423 bpy
.ops
.object.mode_set(mode
=mode
)
424 refresh_ui_keyframes()
429 class ANIM_OT_delete_keyframe_animall(Operator
):
430 bl_label
= "Delete Key"
431 bl_idname
= "anim.delete_keyframe_animall"
432 bl_description
= "Delete a Keyframe"
433 bl_options
= {'REGISTER', 'UNDO'}
436 def execute(op
, context
):
437 animall_properties
= context
.scene
.animall_properties
439 if context
.mode
== 'OBJECT':
440 objects
= context
.selected_objects
442 objects
= context
.objects_in_mode_unique_data
[:]
444 mode
= context
.object.mode
448 if obj
.type == 'MESH':
449 if animall_properties
.key_point_location
:
450 for vert
in data
.vertices
:
451 if not animall_properties
.key_selected
or vert
.select
:
452 delete_key(vert
, 'co')
454 if animall_properties
.key_vertex_bevel
:
455 for vert
in data
.vertices
:
456 if not animall_properties
.key_selected
or vert
.select
:
457 delete_key(vert
, 'bevel_weight')
459 if animall_properties
.key_vertex_group
:
460 for vert
in data
.vertices
:
461 if not animall_properties
.key_selected
or vert
.select
:
462 for group
in vert
.groups
:
463 delete_key(group
, 'weight')
465 # if animall_properties.key_vertex_crease:
466 # for vert in data.vertices:
467 # if not animall_properties.key_selected or vert.select:
468 # delete_key(vert, 'crease')
470 if animall_properties
.key_edge_bevel
:
471 for edge
in data
.edges
:
472 if not animall_properties
.key_selected
or edge
.select
:
473 delete_key(edge
, 'bevel_weight')
475 if animall_properties
.key_edge_crease
:
476 for edge
in data
.edges
:
477 if not animall_properties
.key_selected
or vert
.select
:
478 delete_key(edge
, 'crease')
480 if animall_properties
.key_shape_key
:
481 if obj
.active_shape_key
:
482 for v_i
, vert
in enumerate(obj
.active_shape_key
.data
):
483 if not animall_properties
.key_selected
or data
.vertices
[v_i
].select
:
484 delete_key(vert
, 'co')
486 if animall_properties
.key_uvs
:
487 if data
.uv_layers
.active
is not None:
488 for uv
in data
.uv_layers
.active
.data
:
489 if not animall_properties
.key_selected
or uv
.select
:
492 if animall_properties
.key_attribute
:
493 if data
.attributes
.active
is not None:
494 attribute
= data
.attributes
.active
495 if attribute
.data_type
!= 'STRING':
496 # Cannot animate string attributes?
497 if attribute
.data_type
in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
498 attribute_key
= "value"
499 elif attribute
.data_type
in {'FLOAT_COLOR', 'BYTE_COLOR'}:
500 attribute_key
= "color"
501 elif attribute
.data_type
in {'FLOAT_VECTOR', 'FLOAT2'}:
502 attribute_key
= "vector"
504 for e_i
, _attribute_data
in enumerate(attribute
.data
):
505 if (not animall_properties
.key_selected
506 or attribute
.domain
== 'POINT' and data
.vertices
[e_i
].select
507 or attribute
.domain
== 'EDGE' and data
.edges
[e_i
].select
508 or attribute
.domain
== 'FACE' and data
.polygons
[e_i
].select
509 or attribute
.domain
== 'CORNER' and is_selected_vert_loop(data
, e_i
)):
510 delete_key(data
, f
'attributes["{attribute.name}"].data[{e_i}].{attribute_key}')
512 elif obj
.type == 'LATTICE':
513 if animall_properties
.key_shape_key
:
514 if obj
.active_shape_key
:
515 for point
in obj
.active_shape_key
.data
:
516 delete_key(point
, 'co')
518 if animall_properties
.key_point_location
:
519 for point
in data
.points
:
520 if not animall_properties
.key_selected
or point
.select
:
521 delete_key(point
, 'co_deform')
523 elif obj
.type in {'CURVE', 'SURFACE'}:
524 # Run this outside the splines loop (only once)
525 if animall_properties
.key_shape_key
:
526 if obj
.active_shape_key_index
> 0:
527 for CV
in obj
.active_shape_key
.data
:
529 delete_key(CV
, 'handle_left')
530 delete_key(CV
, 'handle_right')
532 for spline
in data
.splines
:
533 if spline
.type == 'BEZIER':
534 for CV
in spline
.bezier_points
:
535 if (not animall_properties
.key_selected
536 or CV
.select_control_point
537 or CV
.select_left_handle
538 or CV
.select_right_handle
):
539 if animall_properties
.key_point_location
:
541 delete_key(CV
, 'handle_left')
542 delete_key(CV
, 'handle_right')
543 if animall_properties
.key_radius
:
544 delete_key(CV
, 'radius')
545 if animall_properties
.key_tilt
:
546 delete_key(CV
, 'tilt')
548 elif spline
.type in ('POLY', 'NURBS'):
549 for CV
in spline
.points
:
550 if not animall_properties
.key_selected
or CV
.select
:
551 if animall_properties
.key_point_location
:
553 if animall_properties
.key_radius
:
554 delete_key(CV
, 'radius')
555 if animall_properties
.key_tilt
:
556 delete_key(CV
, 'tilt')
558 refresh_ui_keyframes()
563 class ANIM_OT_clear_animation_animall(Operator
):
564 bl_label
= "Clear Animation"
565 bl_idname
= "anim.clear_animation_animall"
566 bl_description
= ("Delete all keyframes for this object\n"
567 "If in a specific case it doesn't work\n"
568 "try to delete the keys manually")
569 bl_options
= {'REGISTER', 'UNDO'}
571 def invoke(self
, context
, event
):
572 wm
= context
.window_manager
573 return wm
.invoke_confirm(self
, event
)
575 def execute(self
, context
):
576 if context
.mode
== 'OBJECT':
577 objects
= context
.selected_objects
579 objects
= context
.objects_in_mode_unique_data
584 data
.animation_data_clear()
586 self
.report({'WARNING'}, "Clear Animation could not be performed")
589 refresh_ui_keyframes()
594 class ANIM_OT_update_vertex_color_animation_animall(Operator
):
595 bl_label
= "Update Vertex Color Animation"
596 bl_idname
= "anim.update_vertex_color_animation_animall"
597 bl_description
= "Update old vertex color channel formats from pre-3.3 versions"
598 bl_options
= {'REGISTER', 'UNDO'}
601 def poll(self
, context
):
602 if (context
.active_object
is None
603 or context
.active_object
.type != 'MESH'
604 or context
.active_object
.data
.animation_data
is None
605 or context
.active_object
.data
.animation_data
.action
is None):
607 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
608 if fcurve
.data_path
.startswith("vertex_colors"):
611 def execute(self
, context
):
612 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
613 if fcurve
.data_path
.startswith("vertex_colors"):
614 fcurve
.data_path
= fcurve
.data_path
.replace("vertex_colors", "attributes")
617 # Add-ons Preferences Update Panel
619 # Define Panel classes for updating
625 def update_panel(self
, context
):
626 message
= "AnimAll: Updating Panel locations has failed"
629 if "bl_rna" in panel
.__dict
__:
630 bpy
.utils
.unregister_class(panel
)
633 panel
.bl_category
= context
.preferences
.addons
[__name__
].preferences
.category
634 bpy
.utils
.register_class(panel
)
636 except Exception as e
:
637 print("\n[{}]\n{}\n\nError:\n{}".format(__name__
, message
, e
))
641 class AnimallAddonPreferences(AddonPreferences
):
642 # this must match the addon name, use '__package__'
643 # when defining this in a submodule of a python package.
646 category
: StringProperty(
648 description
="Choose a name for the category of the panel",
653 def draw(self
, context
):
658 col
.label(text
="Tab Category:")
659 col
.prop(self
, "category", text
="")
663 bpy
.utils
.register_class(AnimallProperties
)
664 bpy
.types
.Scene
.animall_properties
= bpy
.props
.PointerProperty(type=AnimallProperties
)
665 bpy
.utils
.register_class(VIEW3D_PT_animall
)
666 bpy
.utils
.register_class(ANIM_OT_insert_keyframe_animall
)
667 bpy
.utils
.register_class(ANIM_OT_delete_keyframe_animall
)
668 bpy
.utils
.register_class(ANIM_OT_clear_animation_animall
)
669 bpy
.utils
.register_class(ANIM_OT_update_vertex_color_animation_animall
)
670 bpy
.utils
.register_class(AnimallAddonPreferences
)
671 update_panel(None, bpy
.context
)
675 del bpy
.types
.Scene
.animall_properties
676 bpy
.utils
.unregister_class(AnimallProperties
)
677 bpy
.utils
.unregister_class(VIEW3D_PT_animall
)
678 bpy
.utils
.unregister_class(ANIM_OT_insert_keyframe_animall
)
679 bpy
.utils
.unregister_class(ANIM_OT_delete_keyframe_animall
)
680 bpy
.utils
.unregister_class(ANIM_OT_clear_animation_animall
)
681 bpy
.utils
.unregister_class(ANIM_OT_update_vertex_color_animation_animall
)
682 bpy
.utils
.unregister_class(AnimallAddonPreferences
)
684 if __name__
== "__main__":