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(self
, context
):
139 obj
= context
.active_object
140 animall_properties
= context
.scene
.animall_properties
144 layout
.use_property_split
= True
145 layout
.use_property_decorate
= False
147 split
= layout
.split(factor
=0.4, align
=True)
149 split
.label(text
=' Key:')
151 if obj
.type == 'LATTICE':
152 col
= layout
.column(align
=True)
153 col
.prop(animall_properties
, "key_point_location")
154 col
.prop(animall_properties
, "key_shape_key")
156 elif obj
.type == 'MESH':
157 col
= layout
.column(heading
="Points", align
=True)
158 col
.prop(animall_properties
, "key_point_location")
159 col
.prop(animall_properties
, "key_vertex_bevel", text
="Bevel")
160 col
.prop(animall_properties
, "key_vertex_group", text
="Vertex Groups")
162 col
= layout
.column(heading
="Edges", align
=True)
163 col
.prop(animall_properties
, "key_edge_bevel", text
="Bevel")
164 col
.prop(animall_properties
, "key_edge_crease", text
="Crease")
166 col
= layout
.column(heading
="Faces", align
=True)
167 col
.prop(animall_properties
, "key_material_index")
169 col
= layout
.column(heading
="Others", align
=True)
170 col
.prop(animall_properties
, "key_attribute")
171 col
.prop(animall_properties
, "key_uvs")
172 col
.prop(animall_properties
, "key_shape_key")
174 # Vertex group update operator
175 if (obj
.data
.animation_data
is not None
176 and obj
.data
.animation_data
.action
is not None):
177 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
178 if fcurve
.data_path
.startswith("vertex_colors"):
179 col
= layout
.column(align
=True)
180 col
.label(text
="Object includes old-style vertex colors. Consider updating them.", icon
="ERROR")
181 col
.operator("anim.update_vertex_color_animation_animall", icon
="FILE_REFRESH")
184 elif obj
.type in {'CURVE', 'SURFACE'}:
185 col
= layout
.column(align
=True)
186 col
.prop(animall_properties
, "key_point_location")
187 col
.prop(animall_properties
, "key_radius")
188 col
.prop(animall_properties
, "key_tilt")
189 col
.prop(animall_properties
, "key_material_index")
190 col
.prop(animall_properties
, "key_shape_key")
192 if animall_properties
.key_shape_key
:
193 shape_key
= obj
.active_shape_key
194 shape_key_index
= obj
.active_shape_key_index
196 if shape_key_index
> 0:
197 col
= layout
.column(align
=True)
198 row
= col
.row(align
=True)
199 row
.prop(shape_key
, "value", text
=shape_key
.name
, icon
="SHAPEKEY_DATA")
200 row
.prop(obj
, "show_only_shape_key", text
="")
201 if shape_key
.value
< 1:
202 col
.label(text
='Maybe set "%s" to 1.0?' % shape_key
.name
, icon
="INFO")
203 elif shape_key
is not None:
204 col
= layout
.column(align
=True)
205 col
.label(text
="Cannot key on Basis Shape", icon
="ERROR")
207 col
= layout
.column(align
=True)
208 col
.label(text
="No active Shape Key", icon
="ERROR")
210 if animall_properties
.key_point_location
:
211 col
.label(text
='"Location" and "Shape Key" are redundant?', icon
="INFO")
213 col
= layout
.column(align
=True)
214 col
.prop(animall_properties
, "key_selected")
216 row
= layout
.row(align
=True)
217 row
.operator("anim.insert_keyframe_animall", icon
="KEY_HLT")
218 row
.operator("anim.delete_keyframe_animall", icon
="KEY_DEHLT")
220 row
.operator("anim.clear_animation_animall", icon
="CANCEL")
223 class ANIM_OT_insert_keyframe_animall(Operator
):
224 bl_label
= "Insert Key"
225 bl_idname
= "anim.insert_keyframe_animall"
226 bl_description
= "Insert a Keyframe"
227 bl_options
= {'REGISTER', 'UNDO'}
229 def execute(op
, context
):
230 animall_properties
= context
.scene
.animall_properties
232 if context
.mode
== 'OBJECT':
233 objects
= context
.selected_objects
235 objects
= context
.objects_in_mode_unique_data
[:]
237 mode
= context
.object.mode
239 # Separate loop for lattices, curves and surfaces, since keyframe insertion
240 # has to happen in Edit Mode, otherwise points move back upon mode switch...
241 # (except for curve shape keys)
242 for obj
in [o
for o
in objects
if o
.type in {'CURVE', 'SURFACE', 'LATTICE'}]:
245 if obj
.type == 'LATTICE':
246 if animall_properties
.key_shape_key
:
247 if obj
.active_shape_key_index
> 0:
248 sk_name
= obj
.active_shape_key
.name
249 for p_i
, point
in enumerate(obj
.active_shape_key
.data
):
250 if not animall_properties
.key_selected
or data
.points
[p_i
].select
:
251 insert_key(point
, 'co', group
="%s Point %s" % (sk_name
, p_i
))
253 if animall_properties
.key_point_location
:
254 for p_i
, point
in enumerate(data
.points
):
255 if not animall_properties
.key_selected
or point
.select
:
256 insert_key(point
, 'co_deform', group
="Point %s" % p_i
)
259 if animall_properties
.key_material_index
:
260 for s_i
, spline
in enumerate(data
.splines
):
261 if (not animall_properties
.key_selected
262 or any(point
.select
for point
in spline
.points
)
263 or any(point
.select_control_point
for point
in spline
.bezier_points
)):
264 insert_key(spline
, 'material_index', group
="Spline %s" % s_i
)
266 for s_i
, spline
in enumerate(data
.splines
):
267 if spline
.type == 'BEZIER':
268 for v_i
, CV
in enumerate(spline
.bezier_points
):
269 if (not animall_properties
.key_selected
270 or CV
.select_control_point
271 or CV
.select_left_handle
272 or CV
.select_right_handle
):
273 if animall_properties
.key_point_location
:
274 insert_key(CV
, 'co', group
="Spline %s CV %s" % (s_i
, v_i
))
275 insert_key(CV
, 'handle_left', group
="Spline %s CV %s" % (s_i
, v_i
))
276 insert_key(CV
, 'handle_right', group
="Spline %s CV %s" % (s_i
, v_i
))
278 if animall_properties
.key_radius
:
279 insert_key(CV
, 'radius', group
="Spline %s CV %s" % (s_i
, v_i
))
281 if animall_properties
.key_tilt
:
282 insert_key(CV
, 'tilt', group
="Spline %s CV %s" % (s_i
, v_i
))
284 elif spline
.type in ('POLY', 'NURBS'):
285 for v_i
, CV
in enumerate(spline
.points
):
286 if not animall_properties
.key_selected
or CV
.select
:
287 if animall_properties
.key_point_location
:
288 insert_key(CV
, 'co', group
="Spline %s CV %s" % (s_i
, v_i
))
290 if animall_properties
.key_radius
:
291 insert_key(CV
, 'radius', group
="Spline %s CV %s" % (s_i
, v_i
))
293 if animall_properties
.key_tilt
:
294 insert_key(CV
, 'tilt', group
="Spline %s CV %s" % (s_i
, v_i
))
296 bpy
.ops
.object.mode_set(mode
='OBJECT')
298 for obj
in [o
for o
in objects
if o
.type in {'MESH', 'CURVE', 'SURFACE'}]:
300 if obj
.type == 'MESH':
301 if animall_properties
.key_point_location
:
302 for v_i
, vert
in enumerate(data
.vertices
):
303 if not animall_properties
.key_selected
or vert
.select
:
304 insert_key(vert
, 'co', group
="Vertex %s" % v_i
)
306 if animall_properties
.key_vertex_bevel
:
307 for v_i
, vert
in enumerate(data
.vertices
):
308 if not animall_properties
.key_selected
or vert
.select
:
309 insert_key(vert
, 'bevel_weight', group
="Vertex %s" % v_i
)
310 # if animall_properties.key_vertex_crease:
311 # for v_i, vert in enumerate(data.vertices):
312 # if not animall_properties.key_selected or vert.select:
313 # insert_key(vert, 'crease', group="Vertex %s" % v_i)
315 if animall_properties
.key_vertex_group
:
316 for v_i
, vert
in enumerate(data
.vertices
):
317 if not animall_properties
.key_selected
or vert
.select
:
318 for group
in vert
.groups
:
319 insert_key(group
, 'weight', group
="Vertex %s" % v_i
)
321 if animall_properties
.key_edge_bevel
:
322 for e_i
, edge
in enumerate(data
.edges
):
323 if not animall_properties
.key_selected
or edge
.select
:
324 insert_key(edge
, 'bevel_weight', group
="Edge %s" % e_i
)
326 if animall_properties
.key_edge_crease
:
327 for e_i
, edge
in enumerate(data
.edges
):
328 if not animall_properties
.key_selected
or edge
.select
:
329 insert_key(edge
, 'crease', group
="Edge %s" % e_i
)
331 if animall_properties
.key_material_index
:
332 for p_i
, polygon
in enumerate(data
.polygons
):
333 if not animall_properties
.key_selected
or polygon
.select
:
334 insert_key(polygon
, 'material_index', group
="Face %s" % p_i
)
336 if animall_properties
.key_attribute
:
337 if data
.attributes
.active
is not None:
338 attribute
= data
.attributes
.active
339 if attribute
.data_type
!= 'STRING':
340 # Cannot animate string attributes?
341 if attribute
.data_type
in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
342 attribute_key
= "value"
343 elif attribute
.data_type
in {'FLOAT_COLOR', 'BYTE_COLOR'}:
344 attribute_key
= "color"
345 elif attribute
.data_type
in {'FLOAT_VECTOR', 'FLOAT2'}:
346 attribute_key
= "vector"
348 if attribute
.domain
== 'POINT':
350 elif attribute
.domain
== 'EDGE':
352 elif attribute
.domain
== 'FACE':
354 elif attribute
.domain
== 'CORNER':
357 for e_i
, _attribute_data
in enumerate(attribute
.data
):
358 if (not animall_properties
.key_selected
359 or attribute
.domain
== 'POINT' and data
.vertices
[e_i
].select
360 or attribute
.domain
== 'EDGE' and data
.edges
[e_i
].select
361 or attribute
.domain
== 'FACE' and data
.polygons
[e_i
].select
362 or attribute
.domain
== 'CORNER' and is_selected_vert_loop(data
, e_i
)):
363 insert_key(data
, f
'attributes["{attribute.name}"].data[{e_i}].{attribute_key}',
366 if animall_properties
.key_uvs
:
367 if data
.uv_layers
.active
is not None:
368 for uv_i
, uv
in enumerate(data
.uv_layers
.active
.data
):
369 if not animall_properties
.key_selected
or uv
.select
:
370 insert_key(uv
, 'uv', group
="UV layer %s" % uv_i
)
372 if animall_properties
.key_shape_key
:
373 if obj
.active_shape_key_index
> 0:
374 sk_name
= obj
.active_shape_key
.name
375 for v_i
, vert
in enumerate(obj
.active_shape_key
.data
):
376 if not animall_properties
.key_selected
or data
.vertices
[v_i
].select
:
377 insert_key(vert
, 'co', group
="%s Vertex %s" % (sk_name
, v_i
))
379 elif obj
.type in {'CURVE', 'SURFACE'}:
380 # Shape key keys have to be inserted in object mode for curves...
381 if animall_properties
.key_shape_key
:
382 sk_name
= obj
.active_shape_key
.name
383 global_spline_index
= 0 # numbering for shape keys, which have flattened indices
384 for s_i
, spline
in enumerate(data
.splines
):
385 if spline
.type == 'BEZIER':
386 for v_i
, CV
in enumerate(spline
.bezier_points
):
387 if (not animall_properties
.key_selected
388 or CV
.select_control_point
389 or CV
.select_left_handle
390 or CV
.select_right_handle
):
391 if obj
.active_shape_key_index
> 0:
392 CV
= obj
.active_shape_key
.data
[global_spline_index
]
393 insert_key(CV
, 'co', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
394 insert_key(CV
, 'handle_left', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
395 insert_key(CV
, 'handle_right', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
396 insert_key(CV
, 'radius', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
397 insert_key(CV
, 'tilt', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
398 global_spline_index
+= 1
400 elif spline
.type in ('POLY', 'NURBS'):
401 for v_i
, CV
in enumerate(spline
.points
):
402 if not animall_properties
.key_selected
or CV
.select
:
403 if obj
.active_shape_key_index
> 0:
404 CV
= obj
.active_shape_key
.data
[global_spline_index
]
405 insert_key(CV
, 'co', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
406 insert_key(CV
, 'radius', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
407 insert_key(CV
, 'tilt', group
="%s Spline %s CV %s" % (sk_name
, s_i
, v_i
))
408 global_spline_index
+= 1
410 bpy
.ops
.object.mode_set(mode
=mode
)
411 refresh_ui_keyframes()
416 class ANIM_OT_delete_keyframe_animall(Operator
):
417 bl_label
= "Delete Key"
418 bl_idname
= "anim.delete_keyframe_animall"
419 bl_description
= "Delete a Keyframe"
420 bl_options
= {'REGISTER', 'UNDO'}
423 def execute(op
, context
):
424 animall_properties
= context
.scene
.animall_properties
426 if context
.mode
== 'OBJECT':
427 objects
= context
.selected_objects
429 objects
= context
.objects_in_mode_unique_data
[:]
431 mode
= context
.object.mode
435 if obj
.type == 'MESH':
436 if animall_properties
.key_point_location
:
437 for vert
in data
.vertices
:
438 if not animall_properties
.key_selected
or vert
.select
:
439 delete_key(vert
, 'co')
441 if animall_properties
.key_vertex_bevel
:
442 for vert
in data
.vertices
:
443 if not animall_properties
.key_selected
or vert
.select
:
444 delete_key(vert
, 'bevel_weight')
446 if animall_properties
.key_vertex_group
:
447 for vert
in data
.vertices
:
448 if not animall_properties
.key_selected
or vert
.select
:
449 for group
in vert
.groups
:
450 delete_key(group
, 'weight')
452 # if animall_properties.key_vcrease:
453 # for vert in data.vertices:
454 # if not animall_properties.key_selected or vert.select:
455 # delete_key(vert, 'crease')
457 if animall_properties
.key_edge_bevel
:
458 for edge
in data
.edges
:
459 if not animall_properties
.key_selected
or edge
.select
:
460 delete_key(edge
, 'bevel_weight')
462 if animall_properties
.key_edge_crease
:
463 for edge
in data
.edges
:
464 if not animall_properties
.key_selected
or vert
.select
:
465 delete_key(edge
, 'crease')
467 if animall_properties
.key_shape_key
:
468 if obj
.active_shape_key
:
469 for v_i
, vert
in enumerate(obj
.active_shape_key
.data
):
470 if not animall_properties
.key_selected
or data
.vertices
[v_i
].select
:
471 delete_key(vert
, 'co')
473 if animall_properties
.key_uvs
:
474 if data
.uv_layers
.active
is not None:
475 for uv
in data
.uv_layers
.active
.data
:
476 if not animall_properties
.key_selected
or uv
.select
:
479 if animall_properties
.key_attribute
:
480 if data
.attributes
.active
is not None:
481 attribute
= data
.attributes
.active
482 if attribute
.data_type
!= 'STRING':
483 # Cannot animate string attributes?
484 if attribute
.data_type
in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}:
485 attribute_key
= "value"
486 elif attribute
.data_type
in {'FLOAT_COLOR', 'BYTE_COLOR'}:
487 attribute_key
= "color"
488 elif attribute
.data_type
in {'FLOAT_VECTOR', 'FLOAT2'}:
489 attribute_key
= "vector"
491 for e_i
, _attribute_data
in enumerate(attribute
.data
):
492 if (not animall_properties
.key_selected
493 or attribute
.domain
== 'POINT' and data
.vertices
[e_i
].select
494 or attribute
.domain
== 'EDGE' and data
.edges
[e_i
].select
495 or attribute
.domain
== 'FACE' and data
.polygons
[e_i
].select
496 or attribute
.domain
== 'CORNER' and is_selected_vert_loop(data
, e_i
)):
497 delete_key(data
, f
'attributes["{attribute.name}"].data[{e_i}].{attribute_key}')
499 elif obj
.type == 'LATTICE':
500 if animall_properties
.key_shape_key
:
501 if obj
.active_shape_key
:
502 for point
in obj
.active_shape_key
.data
:
503 delete_key(point
, 'co')
505 if animall_properties
.key_point_location
:
506 for point
in data
.points
:
507 if not animall_properties
.key_selected
or point
.select
:
508 delete_key(point
, 'co_deform')
510 elif obj
.type in {'CURVE', 'SURFACE'}:
511 # run this outside the splines loop (only once)
512 if animall_properties
.key_shape_key
:
513 if obj
.active_shape_key_index
> 0:
514 for CV
in obj
.active_shape_key
.data
:
516 delete_key(CV
, 'handle_left')
517 delete_key(CV
, 'handle_right')
519 for spline
in data
.splines
:
520 if spline
.type == 'BEZIER':
521 for CV
in spline
.bezier_points
:
522 if (not animall_properties
.key_selected
523 or CV
.select_control_point
524 or CV
.select_left_handle
525 or CV
.select_right_handle
):
526 if animall_properties
.key_point_location
:
528 delete_key(CV
, 'handle_left')
529 delete_key(CV
, 'handle_right')
530 if animall_properties
.key_radius
:
531 delete_key(CV
, 'radius')
532 if animall_properties
.key_tilt
:
533 delete_key(CV
, 'tilt')
535 elif spline
.type in ('POLY', 'NURBS'):
536 for CV
in spline
.points
:
537 if not animall_properties
.key_selected
or CV
.select
:
538 if animall_properties
.key_point_location
:
540 if animall_properties
.key_radius
:
541 delete_key(CV
, 'radius')
542 if animall_properties
.key_tilt
:
543 delete_key(CV
, 'tilt')
545 refresh_ui_keyframes()
550 class ANIM_OT_clear_animation_animall(Operator
):
551 bl_label
= "Clear Animation"
552 bl_idname
= "anim.clear_animation_animall"
553 bl_description
= ("Delete all keyframes for this object\n"
554 "If in a specific case it doesn't work\n"
555 "try to delete the keys manually")
556 bl_options
= {'REGISTER', 'UNDO'}
558 def invoke(self
, context
, event
):
559 wm
= context
.window_manager
560 return wm
.invoke_confirm(self
, event
)
562 def execute(self
, context
):
563 if context
.mode
== 'OBJECT':
564 objects
= context
.selected_objects
566 objects
= context
.objects_in_mode_unique_data
571 data
.animation_data_clear()
573 self
.report({'WARNING'}, "Clear Animation could not be performed")
576 refresh_ui_keyframes()
581 class ANIM_OT_update_vertex_color_animation_animall(Operator
):
582 bl_label
= "Update Vertex Color Animation"
583 bl_idname
= "anim.update_vertex_color_animation_animall"
584 bl_description
= "Update old vertex color channel formats from pre-3.3 versions"
585 bl_options
= {'REGISTER', 'UNDO'}
588 def poll(self
, context
):
589 if (context
.active_object
is None
590 or context
.active_object
.type != 'MESH'
591 or context
.active_object
.data
.animation_data
is None
592 or context
.active_object
.data
.animation_data
.action
is None):
594 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
595 if fcurve
.data_path
.startswith("vertex_colors"):
598 def execute(self
, context
):
599 for fcurve
in context
.active_object
.data
.animation_data
.action
.fcurves
:
600 if fcurve
.data_path
.startswith("vertex_colors"):
601 fcurve
.data_path
= fcurve
.data_path
.replace("vertex_colors", "attributes")
604 # Add-ons Preferences Update Panel
606 # Define Panel classes for updating
612 def update_panel(self
, context
):
613 message
= "AnimAll: Updating Panel locations has failed"
616 if "bl_rna" in panel
.__dict
__:
617 bpy
.utils
.unregister_class(panel
)
620 panel
.bl_category
= context
.preferences
.addons
[__name__
].preferences
.category
621 bpy
.utils
.register_class(panel
)
623 except Exception as e
:
624 print("\n[{}]\n{}\n\nError:\n{}".format(__name__
, message
, e
))
628 class AnimallAddonPreferences(AddonPreferences
):
629 # this must match the addon name, use '__package__'
630 # when defining this in a submodule of a python package.
633 category
: StringProperty(
635 description
="Choose a name for the category of the panel",
640 def draw(self
, context
):
645 col
.label(text
="Tab Category:")
646 col
.prop(self
, "category", text
="")
650 bpy
.utils
.register_class(AnimallProperties
)
651 bpy
.types
.Scene
.animall_properties
= bpy
.props
.PointerProperty(type=AnimallProperties
)
652 bpy
.utils
.register_class(VIEW3D_PT_animall
)
653 bpy
.utils
.register_class(ANIM_OT_insert_keyframe_animall
)
654 bpy
.utils
.register_class(ANIM_OT_delete_keyframe_animall
)
655 bpy
.utils
.register_class(ANIM_OT_clear_animation_animall
)
656 bpy
.utils
.register_class(ANIM_OT_update_vertex_color_animation_animall
)
657 bpy
.utils
.register_class(AnimallAddonPreferences
)
658 update_panel(None, bpy
.context
)
662 del bpy
.types
.Scene
.animall_properties
663 bpy
.utils
.unregister_class(AnimallProperties
)
664 bpy
.utils
.unregister_class(VIEW3D_PT_animall
)
665 bpy
.utils
.unregister_class(ANIM_OT_insert_keyframe_animall
)
666 bpy
.utils
.unregister_class(ANIM_OT_delete_keyframe_animall
)
667 bpy
.utils
.unregister_class(ANIM_OT_clear_animation_animall
)
668 bpy
.utils
.unregister_class(ANIM_OT_update_vertex_color_animation_animall
)
669 bpy
.utils
.unregister_class(AnimallAddonPreferences
)
671 if __name__
== "__main__":