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(align
=True)
157 col
.prop(animall_properties
, "key_point_location")
158 col
.prop(animall_properties
, "key_shape_key")
160 elif obj
.type == 'MESH':
161 col
= layout
.column(heading
="Points", align
=True)
162 col
.prop(animall_properties
, "key_point_location")
163 col
.prop(animall_properties
, "key_vertex_bevel", text
="Bevel")
164 col
.prop(animall_properties
, "key_vertex_group")
166 col
= layout
.column(heading
="Edges", align
=True)
167 col
.prop(animall_properties
, "key_edge_bevel", text
="Bevel")
168 col
.prop(animall_properties
, "key_edge_crease", text
="Crease")
170 col
= layout
.column(heading
="Faces", align
=True)
171 col
.prop(animall_properties
, "key_material_index")
173 col
= layout
.column(heading
="Others", align
=True)
174 col
.prop(animall_properties
, "key_attribute")
175 col
.prop(animall_properties
, "key_uvs")
176 col
.prop(animall_properties
, "key_shape_key")
178 # Vertex group update operator
179 if (obj
.data
.animation_data
is not None
180 and obj
.data
.animation_data
.action
is not None):
181 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
182 if fcurve
.data_path
.startswith("vertex_colors"):
183 col
= layout
.column(align
=True)
184 col
.label(text
="Object includes old-style vertex colors. Consider updating them.", icon
="ERROR")
185 col
.operator("anim.update_vertex_color_animation_animall", icon
="FILE_REFRESH")
188 elif obj
.type in {'CURVE', 'SURFACE'}:
189 col
= layout
.column(align
=True)
190 col
.prop(animall_properties
, "key_point_location")
191 col
.prop(animall_properties
, "key_radius")
192 col
.prop(animall_properties
, "key_tilt")
193 col
.prop(animall_properties
, "key_material_index")
194 col
.prop(animall_properties
, "key_shape_key")
196 if animall_properties
.key_shape_key
:
197 shape_key
= obj
.active_shape_key
198 shape_key_index
= obj
.active_shape_key_index
200 if shape_key_index
> 0:
201 col
= layout
.column(align
=True)
202 row
= col
.row(align
=True)
203 row
.prop(shape_key
, "value", text
=shape_key
.name
, icon
="SHAPEKEY_DATA")
204 row
.prop(obj
, "show_only_shape_key", text
="")
205 if shape_key
.value
< 1:
206 col
.label(text
='Maybe set "%s" to 1.0?' % shape_key
.name
, icon
="INFO")
207 elif shape_key
is not None:
208 col
= layout
.column(align
=True)
209 col
.label(text
="Cannot key on Basis Shape", icon
="ERROR")
211 col
= layout
.column(align
=True)
212 col
.label(text
="No active Shape Key", icon
="ERROR")
214 if animall_properties
.key_point_location
:
215 col
.label(text
='"Location" and "Shape Key" are redundant?', icon
="INFO")
217 layout
.use_property_split
= False
220 row
.prop(animall_properties
, "key_selected")
222 row
= layout
.row(align
=True)
223 row
.operator("anim.insert_keyframe_animall", icon
="KEY_HLT")
224 row
.operator("anim.delete_keyframe_animall", icon
="KEY_DEHLT")
226 row
.operator("anim.clear_animation_animall", icon
="CANCEL")
229 class ANIM_OT_insert_keyframe_animall(Operator
):
230 bl_label
= "Insert Key"
231 bl_idname
= "anim.insert_keyframe_animall"
232 bl_description
= "Insert a Keyframe"
233 bl_options
= {'REGISTER', 'UNDO'}
235 def execute(op
, context
):
236 animall_properties
= context
.scene
.animall_properties
238 if context
.mode
== 'OBJECT':
239 objects
= context
.selected_objects
241 objects
= context
.objects_in_mode_unique_data
[:]
243 mode
= context
.object.mode
245 # Separate loop for lattices, curves and surfaces, since keyframe insertion
246 # has to happen in Edit Mode, otherwise points move back upon mode switch...
247 # (except for curve shape keys)
248 for obj
in [o
for o
in objects
if o
.type in {'CURVE', 'SURFACE', 'LATTICE'}]:
251 if obj
.type == 'LATTICE':
252 if animall_properties
.key_shape_key
:
253 if obj
.active_shape_key_index
> 0:
254 sk_name
= obj
.active_shape_key
.name
255 for p_i
, point
in enumerate(obj
.active_shape_key
.data
):
256 if not animall_properties
.key_selected
or data
.points
[p_i
].select
:
257 insert_key(point
, 'co', group
="%s Point %s" % (sk_name
, p_i
))
259 if animall_properties
.key_point_location
:
260 for p_i
, point
in enumerate(data
.points
):
261 if not animall_properties
.key_selected
or point
.select
:
262 insert_key(point
, 'co_deform', group
="Point %s" % p_i
)
265 if animall_properties
.key_material_index
:
266 for s_i
, spline
in enumerate(data
.splines
):
267 if (not animall_properties
.key_selected
268 or any(point
.select
for point
in spline
.points
)
269 or any(point
.select_control_point
for point
in spline
.bezier_points
)):
270 insert_key(spline
, 'material_index', group
="Spline %s" % s_i
)
272 for s_i
, spline
in enumerate(data
.splines
):
273 if spline
.type == 'BEZIER':
274 for v_i
, CV
in enumerate(spline
.bezier_points
):
275 if (not animall_properties
.key_selected
276 or CV
.select_control_point
277 or CV
.select_left_handle
278 or CV
.select_right_handle
):
279 if animall_properties
.key_point_location
:
280 insert_key(CV
, 'co', group
="Spline %s CV %s" % (s_i
, v_i
))
281 insert_key(CV
, 'handle_left', group
="Spline %s CV %s" % (s_i
, v_i
))
282 insert_key(CV
, 'handle_right', group
="Spline %s CV %s" % (s_i
, v_i
))
284 if animall_properties
.key_radius
:
285 insert_key(CV
, 'radius', group
="Spline %s CV %s" % (s_i
, v_i
))
287 if animall_properties
.key_tilt
:
288 insert_key(CV
, 'tilt', group
="Spline %s CV %s" % (s_i
, v_i
))
290 elif spline
.type in ('POLY', 'NURBS'):
291 for v_i
, CV
in enumerate(spline
.points
):
292 if not animall_properties
.key_selected
or CV
.select
:
293 if animall_properties
.key_point_location
:
294 insert_key(CV
, 'co', group
="Spline %s CV %s" % (s_i
, v_i
))
296 if animall_properties
.key_radius
:
297 insert_key(CV
, 'radius', group
="Spline %s CV %s" % (s_i
, v_i
))
299 if animall_properties
.key_tilt
:
300 insert_key(CV
, 'tilt', group
="Spline %s CV %s" % (s_i
, v_i
))
302 bpy
.ops
.object.mode_set(mode
='OBJECT')
304 for obj
in [o
for o
in objects
if o
.type in {'MESH', 'CURVE', 'SURFACE'}]:
306 if obj
.type == 'MESH':
307 if animall_properties
.key_point_location
:
308 for v_i
, vert
in enumerate(data
.vertices
):
309 if not animall_properties
.key_selected
or vert
.select
:
310 insert_key(vert
, 'co', group
="Vertex %s" % v_i
)
312 if animall_properties
.key_vertex_bevel
:
313 for v_i
, vert
in enumerate(data
.vertices
):
314 if not animall_properties
.key_selected
or vert
.select
:
315 insert_key(vert
, 'bevel_weight', group
="Vertex %s" % v_i
)
316 # if animall_properties.key_vertex_crease:
317 # for v_i, vert in enumerate(data.vertices):
318 # if not animall_properties.key_selected or vert.select:
319 # insert_key(vert, 'crease', group="Vertex %s" % v_i)
321 if animall_properties
.key_vertex_group
:
322 for v_i
, vert
in enumerate(data
.vertices
):
323 if not animall_properties
.key_selected
or vert
.select
:
324 for group
in vert
.groups
:
325 insert_key(group
, 'weight', group
="Vertex %s" % v_i
)
327 if animall_properties
.key_edge_bevel
:
328 for e_i
, edge
in enumerate(data
.edges
):
329 if not animall_properties
.key_selected
or edge
.select
:
330 insert_key(edge
, 'bevel_weight', group
="Edge %s" % e_i
)
332 if animall_properties
.key_edge_crease
:
333 for e_i
, edge
in enumerate(data
.edges
):
334 if not animall_properties
.key_selected
or edge
.select
:
335 insert_key(edge
, 'crease', group
="Edge %s" % e_i
)
337 if animall_properties
.key_material_index
:
338 for p_i
, polygon
in enumerate(data
.polygons
):
339 if not animall_properties
.key_selected
or polygon
.select
:
340 insert_key(polygon
, 'material_index', group
="Face %s" % p_i
)
342 if animall_properties
.key_attribute
:
343 if data
.attributes
.active
is not None:
344 attribute
= data
.attributes
.active
345 if attribute
.data_type
!= 'STRING':
346 # Cannot animate string attributes?
347 if attribute
.data_type
in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
348 attribute_key
= "value"
349 elif attribute
.data_type
in {'FLOAT_COLOR', 'BYTE_COLOR'}:
350 attribute_key
= "color"
351 elif attribute
.data_type
in {'FLOAT_VECTOR', 'FLOAT2'}:
352 attribute_key
= "vector"
354 if attribute
.domain
== 'POINT':
356 elif attribute
.domain
== 'EDGE':
358 elif attribute
.domain
== 'FACE':
360 elif attribute
.domain
== 'CORNER':
363 for e_i
, _attribute_data
in enumerate(attribute
.data
):
364 if (not animall_properties
.key_selected
365 or attribute
.domain
== 'POINT' and data
.vertices
[e_i
].select
366 or attribute
.domain
== 'EDGE' and data
.edges
[e_i
].select
367 or attribute
.domain
== 'FACE' and data
.polygons
[e_i
].select
368 or attribute
.domain
== 'CORNER' and is_selected_vert_loop(data
, e_i
)):
369 insert_key(data
, f
'attributes["{attribute.name}"].data[{e_i}].{attribute_key}',
372 if animall_properties
.key_uvs
:
373 if data
.uv_layers
.active
is not None:
374 for uv_i
, uv
in enumerate(data
.uv_layers
.active
.data
):
375 if not animall_properties
.key_selected
or uv
.select
:
376 insert_key(uv
, 'uv', group
="UV layer %s" % uv_i
)
378 if animall_properties
.key_shape_key
:
379 if obj
.active_shape_key_index
> 0:
380 sk_name
= obj
.active_shape_key
.name
381 for v_i
, vert
in enumerate(obj
.active_shape_key
.data
):
382 if not animall_properties
.key_selected
or data
.vertices
[v_i
].select
:
383 insert_key(vert
, 'co', group
="%s Vertex %s" % (sk_name
, v_i
))
385 elif obj
.type in {'CURVE', 'SURFACE'}:
386 # Shape key keys have to be inserted in object mode for curves...
387 if animall_properties
.key_shape_key
:
388 sk_name
= obj
.active_shape_key
.name
389 global_spline_index
= 0 # numbering for shape keys, which have flattened indices
390 for s_i
, spline
in enumerate(data
.splines
):
391 if spline
.type == 'BEZIER':
392 for v_i
, CV
in enumerate(spline
.bezier_points
):
393 if (not animall_properties
.key_selected
394 or CV
.select_control_point
395 or CV
.select_left_handle
396 or CV
.select_right_handle
):
397 if obj
.active_shape_key_index
> 0:
398 CV
= obj
.active_shape_key
.data
[global_spline_index
]
399 insert_key(CV
, 'co', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
400 insert_key(CV
, 'handle_left', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
401 insert_key(CV
, 'handle_right', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
402 insert_key(CV
, 'radius', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
403 insert_key(CV
, 'tilt', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
404 global_spline_index
+= 1
406 elif spline
.type in ('POLY', 'NURBS'):
407 for v_i
, CV
in enumerate(spline
.points
):
408 if not animall_properties
.key_selected
or CV
.select
:
409 if obj
.active_shape_key_index
> 0:
410 CV
= obj
.active_shape_key
.data
[global_spline_index
]
411 insert_key(CV
, 'co', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
412 insert_key(CV
, 'radius', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
413 insert_key(CV
, 'tilt', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
414 global_spline_index
+= 1
416 bpy
.ops
.object.mode_set(mode
=mode
)
417 refresh_ui_keyframes()
422 class ANIM_OT_delete_keyframe_animall(Operator
):
423 bl_label
= "Delete Key"
424 bl_idname
= "anim.delete_keyframe_animall"
425 bl_description
= "Delete a Keyframe"
426 bl_options
= {'REGISTER', 'UNDO'}
429 def execute(op
, context
):
430 animall_properties
= context
.scene
.animall_properties
432 if context
.mode
== 'OBJECT':
433 objects
= context
.selected_objects
435 objects
= context
.objects_in_mode_unique_data
[:]
437 mode
= context
.object.mode
441 if obj
.type == 'MESH':
442 if animall_properties
.key_point_location
:
443 for vert
in data
.vertices
:
444 if not animall_properties
.key_selected
or vert
.select
:
445 delete_key(vert
, 'co')
447 if animall_properties
.key_vertex_bevel
:
448 for vert
in data
.vertices
:
449 if not animall_properties
.key_selected
or vert
.select
:
450 delete_key(vert
, 'bevel_weight')
452 if animall_properties
.key_vertex_group
:
453 for vert
in data
.vertices
:
454 if not animall_properties
.key_selected
or vert
.select
:
455 for group
in vert
.groups
:
456 delete_key(group
, 'weight')
458 # if animall_properties.key_vertex_crease:
459 # for vert in data.vertices:
460 # if not animall_properties.key_selected or vert.select:
461 # delete_key(vert, 'crease')
463 if animall_properties
.key_edge_bevel
:
464 for edge
in data
.edges
:
465 if not animall_properties
.key_selected
or edge
.select
:
466 delete_key(edge
, 'bevel_weight')
468 if animall_properties
.key_edge_crease
:
469 for edge
in data
.edges
:
470 if not animall_properties
.key_selected
or vert
.select
:
471 delete_key(edge
, 'crease')
473 if animall_properties
.key_shape_key
:
474 if obj
.active_shape_key
:
475 for v_i
, vert
in enumerate(obj
.active_shape_key
.data
):
476 if not animall_properties
.key_selected
or data
.vertices
[v_i
].select
:
477 delete_key(vert
, 'co')
479 if animall_properties
.key_uvs
:
480 if data
.uv_layers
.active
is not None:
481 for uv
in data
.uv_layers
.active
.data
:
482 if not animall_properties
.key_selected
or uv
.select
:
485 if animall_properties
.key_attribute
:
486 if data
.attributes
.active
is not None:
487 attribute
= data
.attributes
.active
488 if attribute
.data_type
!= 'STRING':
489 # Cannot animate string attributes?
490 if attribute
.data_type
in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
491 attribute_key
= "value"
492 elif attribute
.data_type
in {'FLOAT_COLOR', 'BYTE_COLOR'}:
493 attribute_key
= "color"
494 elif attribute
.data_type
in {'FLOAT_VECTOR', 'FLOAT2'}:
495 attribute_key
= "vector"
497 for e_i
, _attribute_data
in enumerate(attribute
.data
):
498 if (not animall_properties
.key_selected
499 or attribute
.domain
== 'POINT' and data
.vertices
[e_i
].select
500 or attribute
.domain
== 'EDGE' and data
.edges
[e_i
].select
501 or attribute
.domain
== 'FACE' and data
.polygons
[e_i
].select
502 or attribute
.domain
== 'CORNER' and is_selected_vert_loop(data
, e_i
)):
503 delete_key(data
, f
'attributes["{attribute.name}"].data[{e_i}].{attribute_key}')
505 elif obj
.type == 'LATTICE':
506 if animall_properties
.key_shape_key
:
507 if obj
.active_shape_key
:
508 for point
in obj
.active_shape_key
.data
:
509 delete_key(point
, 'co')
511 if animall_properties
.key_point_location
:
512 for point
in data
.points
:
513 if not animall_properties
.key_selected
or point
.select
:
514 delete_key(point
, 'co_deform')
516 elif obj
.type in {'CURVE', 'SURFACE'}:
517 # Run this outside the splines loop (only once)
518 if animall_properties
.key_shape_key
:
519 if obj
.active_shape_key_index
> 0:
520 for CV
in obj
.active_shape_key
.data
:
522 delete_key(CV
, 'handle_left')
523 delete_key(CV
, 'handle_right')
525 for spline
in data
.splines
:
526 if spline
.type == 'BEZIER':
527 for CV
in spline
.bezier_points
:
528 if (not animall_properties
.key_selected
529 or CV
.select_control_point
530 or CV
.select_left_handle
531 or CV
.select_right_handle
):
532 if animall_properties
.key_point_location
:
534 delete_key(CV
, 'handle_left')
535 delete_key(CV
, 'handle_right')
536 if animall_properties
.key_radius
:
537 delete_key(CV
, 'radius')
538 if animall_properties
.key_tilt
:
539 delete_key(CV
, 'tilt')
541 elif spline
.type in ('POLY', 'NURBS'):
542 for CV
in spline
.points
:
543 if not animall_properties
.key_selected
or CV
.select
:
544 if animall_properties
.key_point_location
:
546 if animall_properties
.key_radius
:
547 delete_key(CV
, 'radius')
548 if animall_properties
.key_tilt
:
549 delete_key(CV
, 'tilt')
551 refresh_ui_keyframes()
556 class ANIM_OT_clear_animation_animall(Operator
):
557 bl_label
= "Clear Animation"
558 bl_idname
= "anim.clear_animation_animall"
559 bl_description
= ("Delete all keyframes for this object\n"
560 "If in a specific case it doesn't work\n"
561 "try to delete the keys manually")
562 bl_options
= {'REGISTER', 'UNDO'}
564 def invoke(self
, context
, event
):
565 wm
= context
.window_manager
566 return wm
.invoke_confirm(self
, event
)
568 def execute(self
, context
):
569 if context
.mode
== 'OBJECT':
570 objects
= context
.selected_objects
572 objects
= context
.objects_in_mode_unique_data
577 data
.animation_data_clear()
579 self
.report({'WARNING'}, "Clear Animation could not be performed")
582 refresh_ui_keyframes()
587 class ANIM_OT_update_vertex_color_animation_animall(Operator
):
588 bl_label
= "Update Vertex Color Animation"
589 bl_idname
= "anim.update_vertex_color_animation_animall"
590 bl_description
= "Update old vertex color channel formats from pre-3.3 versions"
591 bl_options
= {'REGISTER', 'UNDO'}
594 def poll(self
, context
):
595 if (context
.active_object
is None
596 or context
.active_object
.type != 'MESH'
597 or context
.active_object
.data
.animation_data
is None
598 or context
.active_object
.data
.animation_data
.action
is None):
600 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
601 if fcurve
.data_path
.startswith("vertex_colors"):
604 def execute(self
, context
):
605 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
606 if fcurve
.data_path
.startswith("vertex_colors"):
607 fcurve
.data_path
= fcurve
.data_path
.replace("vertex_colors", "attributes")
610 # Add-ons Preferences Update Panel
612 # Define Panel classes for updating
618 def update_panel(self
, context
):
619 message
= "AnimAll: Updating Panel locations has failed"
622 if "bl_rna" in panel
.__dict
__:
623 bpy
.utils
.unregister_class(panel
)
626 panel
.bl_category
= context
.preferences
.addons
[__name__
].preferences
.category
627 bpy
.utils
.register_class(panel
)
629 except Exception as e
:
630 print("\n[{}]\n{}\n\nError:\n{}".format(__name__
, message
, e
))
634 class AnimallAddonPreferences(AddonPreferences
):
635 # this must match the addon name, use '__package__'
636 # when defining this in a submodule of a python package.
639 category
: StringProperty(
641 description
="Choose a name for the category of the panel",
646 def draw(self
, context
):
651 col
.label(text
="Tab Category:")
652 col
.prop(self
, "category", text
="")
656 bpy
.utils
.register_class(AnimallProperties
)
657 bpy
.types
.Scene
.animall_properties
= bpy
.props
.PointerProperty(type=AnimallProperties
)
658 bpy
.utils
.register_class(VIEW3D_PT_animall
)
659 bpy
.utils
.register_class(ANIM_OT_insert_keyframe_animall
)
660 bpy
.utils
.register_class(ANIM_OT_delete_keyframe_animall
)
661 bpy
.utils
.register_class(ANIM_OT_clear_animation_animall
)
662 bpy
.utils
.register_class(ANIM_OT_update_vertex_color_animation_animall
)
663 bpy
.utils
.register_class(AnimallAddonPreferences
)
664 update_panel(None, bpy
.context
)
668 del bpy
.types
.Scene
.animall_properties
669 bpy
.utils
.unregister_class(AnimallProperties
)
670 bpy
.utils
.unregister_class(VIEW3D_PT_animall
)
671 bpy
.utils
.unregister_class(ANIM_OT_insert_keyframe_animall
)
672 bpy
.utils
.unregister_class(ANIM_OT_delete_keyframe_animall
)
673 bpy
.utils
.unregister_class(ANIM_OT_clear_animation_animall
)
674 bpy
.utils
.unregister_class(ANIM_OT_update_vertex_color_animation_animall
)
675 bpy
.utils
.unregister_class(AnimallAddonPreferences
)
677 if __name__
== "__main__":