diff options
author | Peter Kim <pk15950@gmail.com> | 2022-09-08 07:00:43 +0300 |
---|---|---|
committer | Peter Kim <pk15950@gmail.com> | 2022-09-08 07:00:43 +0300 |
commit | e83f88c951e26b01893acee4f24b40a46062a41c (patch) | |
tree | 09f60bf7d4fc2ae1ef50668823e416fc675b252e /animation_animall.py | |
parent | ec84e3294593e2e26475f18c81e847bf00dc201e (diff) | |
parent | 0cd92169d40ae1c7e103ff269e850eaf1b901646 (diff) |
Merge branch 'master' into xr-devxr-dev
Diffstat (limited to 'animation_animall.py')
-rw-r--r-- | animation_animall.py | 669 |
1 files changed, 0 insertions, 669 deletions
diff --git a/animation_animall.py b/animation_animall.py deleted file mode 100644 index a7d76f53..00000000 --- a/animation_animall.py +++ /dev/null @@ -1,669 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -bl_info = { - "name": "AnimAll", - "author": "Daniel Salazar <zanqdo@gmail.com>", - "version": (0, 9, 1), - "blender": (3, 3, 0), - "location": "3D View > Toolbox > Animation tab > AnimAll", - "description": "Allows animation of mesh, lattice, curve and surface data", - "warning": "", - "doc_url": "{BLENDER_MANUAL_URL}/addons/animation/animall.html", - "category": "Animation", -} - -""" -Thanks to Campbell Barton and Joshua Leung for hes API additions and fixes -Daniel 'ZanQdo' Salazar -""" - -import bpy -from bpy.types import ( - Operator, - Panel, - AddonPreferences, - ) -from bpy.props import ( - BoolProperty, - StringProperty, - ) -from bpy.app.handlers import persistent - - -# Property Definitions -class AnimallProperties(bpy.types.PropertyGroup): - key_selected: BoolProperty( - name="Selected Only", - description="Insert keyframes only on selected elements", - default=True - ) - key_shape: BoolProperty( - name="Shape", - description="Insert keyframes on active Shape Key layer", - default=False - ) - key_uvs: BoolProperty( - name="UVs", - description="Insert keyframes on active UV coordinates", - default=False - ) - key_ebevel: BoolProperty( - name="E-Bevel", - description="Insert keyframes on edge bevel weight", - default=False - ) - key_vbevel: BoolProperty( - name="V-Bevel", - description="Insert keyframes on vertex bevel weight", - default=False - ) - key_crease: BoolProperty( - name="Crease", - description="Insert keyframes on edge creases", - default=False - ) - key_vgroups: BoolProperty( - name="V-groups", - description="Insert keyframes on active Vertex group values", - default=False - ) - key_attribute: BoolProperty( - name="Active Attribute", - description="Insert keyframes on active attribute values", - default=False - ) - key_points: BoolProperty( - name="Points", - description="Insert keyframes on point locations", - default=False - ) - key_handle_type: BoolProperty( - name="Handle Types", - description="Insert keyframes on Bezier point types", - default=False - ) - key_radius: BoolProperty( - name="Radius", - description="Insert keyframes on point radius (Shrink/Fatten)", - default=False - ) - key_tilt: BoolProperty( - name="Tilt", - description="Insert keyframes on point tilt", - default=False - ) - - -# Utility functions - -def refresh_ui_keyframes(): - try: - for area in bpy.context.screen.areas: - if area.type in ('TIMELINE', 'GRAPH_EDITOR', 'DOPESHEET_EDITOR'): - area.tag_redraw() - except: - pass - - -def insert_key(data, key, group=None): - try: - if group is not None: - data.keyframe_insert(key, group=group) - else: - data.keyframe_insert(key) - except: - pass - - -def delete_key(data, key): - try: - data.keyframe_delete(key) - except: - pass - - -def is_selected_vert_loop(data, loop_i): - """Get selection status of vertex corresponding to a loop""" - vertex_index = data.loops[loop_i].vertex_index - return data.vertices[vertex_index].select - - -# GUI (Panel) - -class VIEW3D_PT_animall(Panel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - bl_category = "Animate" - bl_label = 'AnimAll' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(self, context): - return context.active_object and context.active_object.type in {'MESH', 'LATTICE', 'CURVE', 'SURFACE'} - - def draw(self, context): - obj = context.active_object - animall_properties = context.window_manager.animall_properties - - layout = self.layout - col = layout.column(align=True) - row = col.row() - row.prop(animall_properties, "key_selected") - col.separator() - - row = col.row() - - if obj.type == 'LATTICE': - row.prop(animall_properties, "key_points") - row.prop(animall_properties, "key_shape") - - elif obj.type == 'MESH': - row.prop(animall_properties, "key_points") - row.prop(animall_properties, "key_shape") - row = col.row() - row.prop(animall_properties, "key_ebevel") - row.prop(animall_properties, "key_vbevel") - row = col.row() - row.prop(animall_properties, "key_crease") - row.prop(animall_properties, "key_uvs") - row = col.row() - row.prop(animall_properties, "key_attribute") - row.prop(animall_properties, "key_vgroups") - - # Vertex group update operator - if (context.active_object is not None - and context.active_object.type == 'MESH' - and context.active_object.data.animation_data is not None - and context.active_object.data.animation_data.action is not None): - for fcurve in context.active_object.data.animation_data.action.fcurves: - if fcurve.data_path.startswith("vertex_colors"): - layout.separator() - row = layout.row() - row.label(text="Object includes old-style vertex colors. Consider updating them.", icon="ERROR") - row = layout.row() - row.operator("anim.update_vertex_color_animation_animall", icon="FILE_REFRESH") - break - - elif obj.type == 'CURVE': - row.prop(animall_properties, "key_points") - row.prop(animall_properties, "key_shape") - row = col.row() - row.prop(animall_properties, "key_radius") - row.prop(animall_properties, "key_tilt") - row = col.row() - row.prop(animall_properties, "key_handle_type") - - elif obj.type == 'SURFACE': - row.prop(animall_properties, "key_points") - row.prop(animall_properties, "key_shape") - row = col.row() - row.prop(animall_properties, "key_radius") - row.prop(animall_properties, "key_tilt") - - layout.separator() - row = layout.row(align=True) - row.operator("anim.insert_keyframe_animall", icon="KEY_HLT") - row.operator("anim.delete_keyframe_animall", icon="KEY_DEHLT") - row = layout.row() - row.operator("anim.clear_animation_animall", icon="X") - - if animall_properties.key_shape: - shape_key = obj.active_shape_key - shape_key_index = obj.active_shape_key_index - - split = layout.split() - row = split.row() - - if shape_key_index > 0: - row.label(text=shape_key.name, icon="SHAPEKEY_DATA") - row.prop(shape_key, "value", text="") - row.prop(obj, "show_only_shape_key", text="") - if shape_key.value < 1: - row = layout.row() - row.label(text='Maybe set "%s" to 1.0?' % shape_key.name, icon="INFO") - elif shape_key: - row.label(text="Cannot key on Basis Shape", icon="ERROR") - else: - row.label(text="No active Shape Key", icon="ERROR") - - if animall_properties.key_points and animall_properties.key_shape: - row = layout.row() - row.label(text='"Points" and "Shape" are redundant?', icon="INFO") - - -class ANIM_OT_insert_keyframe_animall(Operator): - bl_label = "Insert" - bl_idname = "anim.insert_keyframe_animall" - bl_description = "Insert a Keyframe" - bl_options = {'REGISTER', 'UNDO'} - - def execute(op, context): - animall_properties = context.window_manager.animall_properties - - if context.mode == 'OBJECT': - objects = context.selected_objects - else: - objects = context.objects_in_mode_unique_data[:] - - mode = context.object.mode - - # Separate loop for lattices, curves and surfaces, since keyframe insertion - # has to happen in Edit Mode, otherwise points move back upon mode switch... - # (except for curve shape keys) - for obj in [o for o in objects if o.type in {'CURVE', 'SURFACE', 'LATTICE'}]: - data = obj.data - - if obj.type == 'LATTICE': - if animall_properties.key_shape: - if obj.active_shape_key_index > 0: - sk_name = obj.active_shape_key.name - for p_i, point in enumerate(obj.active_shape_key.data): - if not animall_properties.key_selected or data.points[p_i].select: - insert_key(point, 'co', group="%s Point %s" % (sk_name, p_i)) - - if animall_properties.key_points: - for p_i, point in enumerate(data.points): - if not animall_properties.key_selected or point.select: - insert_key(point, 'co_deform', group="Point %s" % p_i) - - else: - for s_i, spline in enumerate(data.splines): - if spline.type == 'BEZIER': - for v_i, CV in enumerate(spline.bezier_points): - if (not animall_properties.key_selected - or CV.select_control_point - or CV.select_left_handle - or CV.select_right_handle): - if animall_properties.key_points: - insert_key(CV, 'co', group="Spline %s CV %s" % (s_i, v_i)) - insert_key(CV, 'handle_left', group="Spline %s CV %s" % (s_i, v_i)) - insert_key(CV, 'handle_right', group="Spline %s CV %s" % (s_i, v_i)) - - if animall_properties.key_radius: - insert_key(CV, 'radius', group="Spline %s CV %s" % (s_i, v_i)) - - if animall_properties.key_handle_type: - insert_key(CV, 'handle_left_type', group="spline %s CV %s" % (s_i, v_i)) - insert_key(CV, 'handle_right_type', group="spline %s CV %s" % (s_i, v_i)) - - if animall_properties.key_tilt: - insert_key(CV, 'tilt', group="Spline %s CV %s" % (s_i, v_i)) - - elif spline.type in ('POLY', 'NURBS'): - for v_i, CV in enumerate(spline.points): - if not animall_properties.key_selected or CV.select: - if animall_properties.key_points: - insert_key(CV, 'co', group="Spline %s CV %s" % (s_i, v_i)) - - if animall_properties.key_radius: - insert_key(CV, 'radius', group="Spline %s CV %s" % (s_i, v_i)) - - if animall_properties.key_tilt: - insert_key(CV, 'tilt', group="Spline %s CV %s" % (s_i, v_i)) - - bpy.ops.object.mode_set(mode='OBJECT') - - for obj in [o for o in objects if o.type in {'MESH', 'CURVE', 'SURFACE'}]: - data = obj.data - if obj.type == 'MESH': - if animall_properties.key_points: - for v_i, vert in enumerate(data.vertices): - if not animall_properties.key_selected or vert.select: - insert_key(vert, 'co', group="Vertex %s" % v_i) - - if animall_properties.key_vbevel: - for v_i, vert in enumerate(data.vertices): - if not animall_properties.key_selected or vert.select: - insert_key(vert, 'bevel_weight', group="Vertex %s" % v_i) - - if animall_properties.key_vgroups: - for v_i, vert in enumerate(data.vertices): - if not animall_properties.key_selected or vert.select: - for group in vert.groups: - insert_key(group, 'weight', group="Vertex %s" % v_i) - - if animall_properties.key_ebevel: - for e_i, edge in enumerate(data.edges): - if not animall_properties.key_selected or edge.select: - insert_key(edge, 'bevel_weight', group="Edge %s" % e_i) - - if animall_properties.key_crease: - for e_i, edge in enumerate(data.edges): - if not animall_properties.key_selected or edge.select: - insert_key(edge, 'crease', group="Edge %s" % e_i) - - if animall_properties.key_shape: - if obj.active_shape_key_index > 0: - sk_name = obj.active_shape_key.name - for v_i, vert in enumerate(obj.active_shape_key.data): - if not animall_properties.key_selected or data.vertices[v_i].select: - insert_key(vert, 'co', group="%s Vertex %s" % (sk_name, v_i)) - - if animall_properties.key_uvs: - if data.uv_layers.active is not None: - for uv_i, uv in enumerate(data.uv_layers.active.data): - if not animall_properties.key_selected or uv.select: - insert_key(uv, 'uv', group="UV layer %s" % uv_i) - - if animall_properties.key_attribute: - if data.attributes.active is not None: - attribute = data.attributes.active - if attribute.data_type != 'STRING': - # Cannot animate string attributes? - if attribute.data_type in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}: - attribute_key = "value" - elif attribute.data_type in {'FLOAT_COLOR', 'BYTE_COLOR'}: - attribute_key = "color" - elif attribute.data_type in {'FLOAT_VECTOR', 'FLOAT2'}: - attribute_key = "vector" - - if attribute.domain == 'POINT': - group = "Vertex %s" - elif attribute.domain == 'EDGE': - group = "Edge %s" - elif attribute.domain == 'FACE': - group = "Face %s" - elif attribute.domain == 'CORNER': - group = "Loop %s" - - for e_i, _attribute_data in enumerate(attribute.data): - if (not animall_properties.key_selected - or attribute.domain == 'POINT' and data.vertices[e_i].select - or attribute.domain == 'EDGE' and data.edges[e_i].select - or attribute.domain == 'FACE' and data.polygons[e_i].select - or attribute.domain == 'CORNER' and is_selected_vert_loop(data, e_i)): - insert_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}', - group=group % e_i) - - elif obj.type in {'CURVE', 'SURFACE'}: - # Shape key keys have to be inserted in object mode for curves... - if animall_properties.key_shape: - sk_name = obj.active_shape_key.name - global_spline_index = 0 # numbering for shape keys, which have flattened indices - for s_i, spline in enumerate(data.splines): - if spline.type == 'BEZIER': - for v_i, CV in enumerate(spline.bezier_points): - if (not animall_properties.key_selected - or CV.select_control_point - or CV.select_left_handle - or CV.select_right_handle): - if obj.active_shape_key_index > 0: - CV = obj.active_shape_key.data[global_spline_index] - insert_key(CV, 'co', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - insert_key(CV, 'handle_left', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - insert_key(CV, 'handle_right', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - insert_key(CV, 'radius', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - insert_key(CV, 'tilt', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - global_spline_index += 1 - - elif spline.type in ('POLY', 'NURBS'): - for v_i, CV in enumerate(spline.points): - if not animall_properties.key_selected or CV.select: - if obj.active_shape_key_index > 0: - CV = obj.active_shape_key.data[global_spline_index] - insert_key(CV, 'co', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - insert_key(CV, 'radius', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - insert_key(CV, 'tilt', group="%s Spline %s CV %s" % (sk_name, s_i, v_i)) - global_spline_index += 1 - - bpy.ops.object.mode_set(mode=mode) - refresh_ui_keyframes() - - return {'FINISHED'} - - -class ANIM_OT_delete_keyframe_animall(Operator): - bl_label = "Delete" - bl_idname = "anim.delete_keyframe_animall" - bl_description = "Delete a Keyframe" - bl_options = {'REGISTER', 'UNDO'} - - - def execute(op, context): - animall_properties = context.window_manager.animall_properties - - if context.mode == 'OBJECT': - objects = context.selected_objects - else: - objects = context.objects_in_mode_unique_data[:] - - mode = context.object.mode - - for obj in objects: - data = obj.data - if obj.type == 'MESH': - if animall_properties.key_points: - for vert in data.vertices: - if not animall_properties.key_selected or vert.select: - delete_key(vert, 'co') - - if animall_properties.key_vbevel: - for vert in data.vertices: - if not animall_properties.key_selected or vert.select: - delete_key(vert, 'bevel_weight') - - if animall_properties.key_vgroups: - for vert in data.vertices: - if not animall_properties.key_selected or vert.select: - for group in vert.groups: - delete_key(group, 'weight') - - if animall_properties.key_ebevel: - for edge in data.edges: - if not animall_properties.key_selected or edge.select: - delete_key(edge, 'bevel_weight') - - if animall_properties.key_crease: - for edge in data.edges: - if not animall_properties.key_selected or vert.select: - delete_key(edge, 'crease') - - if animall_properties.key_shape: - if obj.active_shape_key: - for v_i, vert in enumerate(obj.active_shape_key.data): - if not animall_properties.key_selected or data.vertices[v_i].select: - delete_key(vert, 'co') - - if animall_properties.key_uvs: - if data.uv_layers.active is not None: - for uv in data.uv_layers.active.data: - if not animall_properties.key_selected or uv.select: - delete_key(uv, 'uv') - - if animall_properties.key_attribute: - if data.attributes.active is not None: - attribute = data.attributes.active - if attribute.data_type != 'STRING': - # Cannot animate string attributes? - if attribute.data_type in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}: - attribute_key = "value" - elif attribute.data_type in {'FLOAT_COLOR', 'BYTE_COLOR'}: - attribute_key = "color" - elif attribute.data_type in {'FLOAT_VECTOR', 'FLOAT2'}: - attribute_key = "vector" - - for e_i, _attribute_data in enumerate(attribute.data): - if (not animall_properties.key_selected - or attribute.domain == 'POINT' and data.vertices[e_i].select - or attribute.domain == 'EDGE' and data.edges[e_i].select - or attribute.domain == 'FACE' and data.polygons[e_i].select - or attribute.domain == 'CORNER' and is_selected_vert_loop(data, e_i)): - delete_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}') - - elif obj.type == 'LATTICE': - if animall_properties.key_shape: - if obj.active_shape_key: - for point in obj.active_shape_key.data: - delete_key(point, 'co') - - if animall_properties.key_points: - for point in data.points: - if not animall_properties.key_selected or point.select: - delete_key(point, 'co_deform') - - elif obj.type in {'CURVE', 'SURFACE'}: - # run this outside the splines loop (only once) - if animall_properties.key_shape: - if obj.active_shape_key_index > 0: - for CV in obj.active_shape_key.data: - delete_key(CV, 'co') - delete_key(CV, 'handle_left') - delete_key(CV, 'handle_right') - - for spline in data.splines: - if spline.type == 'BEZIER': - for CV in spline.bezier_points: - if (not animall_properties.key_selected - or CV.select_control_point - or CV.select_left_handle - or CV.select_right_handle): - if animall_properties.key_points: - delete_key(CV, 'co') - delete_key(CV, 'handle_left') - delete_key(CV, 'handle_right') - if animall_properties.key_handle_type: - delete_key(CV, 'handle_left_type') - delete_key(CV, 'handle_right_type') - if animall_properties.key_radius: - delete_key(CV, 'radius') - if animall_properties.key_tilt: - delete_key(CV, 'tilt') - - elif spline.type in ('POLY', 'NURBS'): - for CV in spline.points: - if not animall_properties.key_selected or CV.select: - if animall_properties.key_points: - delete_key(CV, 'co') - if animall_properties.key_radius: - delete_key(CV, 'radius') - if animall_properties.key_tilt: - delete_key(CV, 'tilt') - - refresh_ui_keyframes() - - return {'FINISHED'} - - -class ANIM_OT_clear_animation_animall(Operator): - bl_label = "Clear Animation" - bl_idname = "anim.clear_animation_animall" - bl_description = ("Delete all keyframes for this object\n" - "If in a specific case it doesn't work\n" - "try to delete the keys manually") - bl_options = {'REGISTER', 'UNDO'} - - def invoke(self, context, event): - wm = context.window_manager - return wm.invoke_confirm(self, event) - - def execute(self, context): - if context.mode == 'OBJECT': - objects = context.selected_objects - else: - objects = context.objects_in_mode_unique_data - - for obj in objects: - try: - data = obj.data - data.animation_data_clear() - except: - self.report({'WARNING'}, "Clear Animation could not be performed") - return {'CANCELLED'} - - refresh_ui_keyframes() - - return {'FINISHED'} - - -class ANIM_OT_update_vertex_color_animation_animall(Operator): - bl_label = "Update Vertex Color Animation" - bl_idname = "anim.update_vertex_color_animation_animall" - bl_description = "Update old vertex color channel formats from pre-3.3 versions" - bl_options = {'REGISTER', 'UNDO'} - - @classmethod - def poll(self, context): - if (context.active_object is None - or context.active_object.type != 'MESH' - or context.active_object.data.animation_data is None - or context.active_object.data.animation_data.action is None): - return False - for fcurve in context.active_object.data.animation_data.action.fcurves: - if fcurve.data_path.startswith("vertex_colors"): - return True - - def execute(self, context): - for fcurve in context.active_object.data.animation_data.action.fcurves: - if fcurve.data_path.startswith("vertex_colors"): - fcurve.data_path = fcurve.data_path.replace("vertex_colors", "attributes") - return {'FINISHED'} - -# Add-ons Preferences Update Panel - -# Define Panel classes for updating -panels = [ - VIEW3D_PT_animall - ] - - -def update_panel(self, context): - message = "AnimAll: Updating Panel locations has failed" - try: - for panel in panels: - if "bl_rna" in panel.__dict__: - bpy.utils.unregister_class(panel) - - for panel in panels: - panel.bl_category = context.preferences.addons[__name__].preferences.category - bpy.utils.register_class(panel) - - except Exception as e: - print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e)) - pass - - -class AnimallAddonPreferences(AddonPreferences): - # this must match the addon name, use '__package__' - # when defining this in a submodule of a python package. - bl_idname = __name__ - - category: StringProperty( - name="Tab Category", - description="Choose a name for the category of the panel", - default="Animate", - update=update_panel - ) - - def draw(self, context): - layout = self.layout - row = layout.row() - col = row.column() - - col.label(text="Tab Category:") - col.prop(self, "category", text="") - - -def register(): - bpy.utils.register_class(AnimallProperties) - bpy.types.WindowManager.animall_properties = bpy.props.PointerProperty(type=AnimallProperties) - bpy.utils.register_class(VIEW3D_PT_animall) - bpy.utils.register_class(ANIM_OT_insert_keyframe_animall) - bpy.utils.register_class(ANIM_OT_delete_keyframe_animall) - bpy.utils.register_class(ANIM_OT_clear_animation_animall) - bpy.utils.register_class(ANIM_OT_update_vertex_color_animation_animall) - bpy.utils.register_class(AnimallAddonPreferences) - update_panel(None, bpy.context) - - -def unregister(): - del bpy.types.WindowManager.animall_properties - bpy.utils.unregister_class(AnimallProperties) - bpy.utils.unregister_class(VIEW3D_PT_animall) - bpy.utils.unregister_class(ANIM_OT_insert_keyframe_animall) - bpy.utils.unregister_class(ANIM_OT_delete_keyframe_animall) - bpy.utils.unregister_class(ANIM_OT_clear_animation_animall) - bpy.utils.unregister_class(ANIM_OT_update_vertex_color_animation_animall) - bpy.utils.unregister_class(AnimallAddonPreferences) - -if __name__ == "__main__": - register() |