Skip to content
Snippets Groups Projects
animation_animall.py 17.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • # ##### BEGIN GPL LICENSE BLOCK #####
    #
    #  This program is free software; you can redistribute it and/or
    #  modify it under the terms of the GNU General Public License
    #  as published by the Free Software Foundation; either version 2
    #  of the License, or (at your option) any later version.
    #
    #  This program is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this program; if not, write to the Free Software Foundation,
    #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ##### END GPL LICENSE BLOCK #####
    
    bl_info = {
    
        "name": "AnimAll",
        "author": "Daniel Salazar <zanqdo@gmail.com>",
    
        "version": (0, 8, 1),
    
        "location": "Tool bar > Animation tab > AnimAll",
        "description": "Allows animation of mesh, lattice, curve and surface data",
        "warning": "",
    
        "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
    
                    "Scripts/Animation/AnimAll",
        "category": "Animation",
    }
    
    Thanks to Campbell Barton and Joshua Leung for hes API additions and fixes
    Daniel 'ZanQdo' Salazar
    
    from bpy.types import (
            Operator,
            Panel,
            AddonPreferences,
            )
    from bpy.props import (
            BoolProperty,
            StringProperty,
            )
    
    bpy.types.WindowManager.key_shape = BoolProperty(
        name="Shape",
        description="Insert keyframes on active Shape Key layer",
    
        default=False
        )
    
    bpy.types.WindowManager.key_uvs = BoolProperty(
        name="UVs",
        description="Insert keyframes on active UV coordinates",
    
        default=False
        )
    
    bpy.types.WindowManager.key_ebevel = BoolProperty(
        name="E-Bevel",
    
        description="Insert keyframes on edge bevel weight",
    
        default=False
        )
    
    bpy.types.WindowManager.key_vbevel = BoolProperty(
        name="V-Bevel",
        description="Insert keyframes on vertex bevel weight",
    
        default=False
        )
    
    bpy.types.WindowManager.key_crease = BoolProperty(
        name="Crease",
        description="Insert keyframes on edge creases",
    
        default=False
        )
    
    bpy.types.WindowManager.key_vcols = BoolProperty(
    
        description="Insert keyframes on active Vertex Color values",
    
        default=False
        )
    
    bpy.types.WindowManager.key_vgroups = BoolProperty(
    
        description="Insert keyframes on active Vertex Group values",
    
        default=False
        )
    
    Daniel Salazar's avatar
    Daniel Salazar committed
    bpy.types.WindowManager.key_points = BoolProperty(
        name="Points",
        description="Insert keyframes on point locations",
    
        default=False
        )
    
    Daniel Salazar's avatar
    Daniel Salazar committed
    bpy.types.WindowManager.key_radius = BoolProperty(
        name="Radius",
        description="Insert keyframes on point radius (Shrink/Fatten)",
    
        default=False
        )
    
    Daniel Salazar's avatar
    Daniel Salazar committed
    bpy.types.WindowManager.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):
        try:
            data.keyframe_insert(key)
        except:
            pass
    
    
    def delete_key(data, key):
        try:
            data.keyframe_delete(key)
        except:
            pass
    
    
    class VIEW3D_PT_animall(Panel):
    
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'TOOLS'
    
        bl_category = "Animation"
    
            if context.active_object and context.active_object.type in {'MESH', 'LATTICE', 'CURVE', 'SURFACE'}:
    
                return context.active_object.type
    
            layout = self.layout
            col = layout.column(align=True)
            row = col.row()
    
    Daniel Salazar's avatar
    Daniel Salazar committed
            if Obj.type == 'LATTICE':
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "key_points")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "key_shape")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
            elif Obj.type == 'MESH':
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "key_points")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "key_shape")
    
                row.prop(context.window_manager, "key_ebevel")
                row.prop(context.window_manager, "key_vbevel")
    
                row = col.row()
                row.prop(context.window_manager, "key_crease")
                row.prop(context.window_manager, "key_uvs")
    
                row.prop(context.window_manager, "key_vcols")
                row.prop(context.window_manager, "key_vgroups")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
            elif Obj.type == 'CURVE':
                row.prop(context.window_manager, "key_points")
    
                row.prop(context.window_manager, "key_shape")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row = col.row()
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "key_radius")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "key_tilt")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
            elif Obj.type == 'SURFACE':
                row.prop(context.window_manager, "key_points")
                row.prop(context.window_manager, "key_shape")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row = col.row()
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "key_radius")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                row.prop(context.window_manager, "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.operator("anim.clear_animation_animall", icon="X")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
            if context.window_manager.key_shape:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                ShapeKeyIndex = Obj.active_shape_key_index
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if ShapeKeyIndex > 0:
    
                    row.label(ShapeKey.name, icon="SHAPEKEY_DATA")
    
                    row.prop(ShapeKey, "value", text="")
                    row.prop(Obj, "show_only_shape_key", text="")
    
                        row.label('Maybe set "%s" to 1.0?' % ShapeKey.name, icon="INFO")
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                elif ShapeKey:
    
                    row.label("Can not key on Basis Shape", icon="ERROR")
    
                    row.label("No active Shape Key", icon="ERROR")
    
            if context.window_manager.key_points and context.window_manager.key_shape:
                row = layout.row()
    
                row.label('"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"
    
        def invoke(self, context, event):
            self.execute(context)
    
            return {'FINISHED'}
    
        def execute(op, context):
            Obj = context.active_object
    
            if Obj.type == 'MESH':
                Mode = False
                if context.mode == 'EDIT_MESH':
                    Mode = not Mode
                    bpy.ops.object.editmode_toggle()
    
                if context.window_manager.key_shape:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                    if Obj.active_shape_key_index > 0:
                        for Vert in Obj.active_shape_key.data:
    
                            insert_key(Vert, 'co')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if context.window_manager.key_points:
                    for Vert in Data.vertices:
    
                        insert_key(Vert, 'co')
    
                        insert_key(Edge, 'bevel_weight')
    
                if context.window_manager.key_vbevel:
                    for Vert in Data.vertices:
    
                        insert_key(Vert, 'bevel_weight')
    
                if context.window_manager.key_crease:
                    for Edge in Data.edges:
    
                        insert_key(Edge, 'crease')
    
                if context.window_manager.key_vgroups:
                    for Vert in Data.vertices:
                        for Group in Vert.groups:
    
                            insert_key(Group, 'weight')
    
                if context.window_manager.key_uvs:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                    for UV in Data.uv_layers.active.data:
    
                        insert_key(UV, 'uv')
    
    
                if context.window_manager.key_vcols:
                    for VColLayer in Data.vertex_colors:
    
                        if VColLayer.active:  # only insert in active VCol layer
    
                                insert_key(Data, 'color')
    
                if Mode:
                    bpy.ops.object.editmode_toggle()
    
                Mode = False
                if context.mode != 'OBJECT':
                    Mode = not Mode
                    bpy.ops.object.editmode_toggle()
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                Data = Obj.data
    
                if context.window_manager.key_shape:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                    if Obj.active_shape_key_index > 0:
    
                        for Point in Obj.active_shape_key.data:
    
                            insert_key(Point, 'co')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if context.window_manager.key_points:
                    for Point in Data.points:
    
                        insert_key(Point, 'co_deform')
    
            if Obj.type in {'CURVE', 'SURFACE'}:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                Mode = False
                if context.mode != 'OBJECT':
                    Mode = not Mode
                    bpy.ops.object.editmode_toggle()
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                Data = Obj.data
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                # run this outside the splines loop (only once)
                if context.window_manager.key_shape:
                    if Obj.active_shape_key_index > 0:
                        for CV in Obj.active_shape_key.data:
    
                            insert_key(CV, 'co')
                            insert_key(CV, 'handle_left')
                            insert_key(CV, 'handle_right')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                for Spline in Data.splines:
                    if Spline.type == 'BEZIER':
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                        for CV in Spline.bezier_points:
                            if context.window_manager.key_points:
    
                                insert_key(CV, 'co')
                                insert_key(CV, 'handle_left')
                                insert_key(CV, 'handle_right')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_radius:
    
                                insert_key(CV, 'radius')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_tilt:
    
                                insert_key(CV, 'tilt')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                    elif Spline.type == 'NURBS':
                        for CV in Spline.points:
                            if context.window_manager.key_points:
    
                                insert_key(CV, 'co')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_radius:
    
                                insert_key(CV, 'radius')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_tilt:
    
                                insert_key(CV, 'tilt')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if Mode:
                    bpy.ops.object.editmode_toggle()
    
            refresh_ui_keyframes()
    
    class ANIM_OT_delete_keyframe_animall(Operator):
        bl_label = "Delete"
        bl_idname = "anim.delete_keyframe_animall"
        bl_description = "Delete a Keyframe"
    
        def invoke(self, context, event):
            self.execute(context)
    
            return {'FINISHED'}
    
        def execute(op, context):
            Obj = context.active_object
    
            if Obj.type == 'MESH':
                Mode = False
                if context.mode == 'EDIT_MESH':
                    Mode = not Mode
                    bpy.ops.object.editmode_toggle()
    
                if context.window_manager.key_shape:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                        for Vert in Obj.active_shape_key.data:
    
                            delete_key(Vert, 'co')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if context.window_manager.key_points:
                    for Vert in Data.vertices:
    
                        delete_key(Vert, 'co')
    
                        delete_key(Edge, 'bevel_weight')
    
                if context.window_manager.key_vbevel:
                    for Vert in Data.vertices:
    
                        delete_key(Vert, 'bevel_weight')
    
                if context.window_manager.key_crease:
                    for Edge in Data.edges:
    
                        delete_key(Edge, 'crease')
    
                if context.window_manager.key_vgroups:
                    for Vert in Data.vertices:
                        for Group in Vert.groups:
    
                            delete_key(Group, 'weight')
    
                if context.window_manager.key_uvs:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                    for UV in Data.uv_layers.active.data:
    
                        delete_key(UV, 'uv')
    
                if context.window_manager.key_vcols:
                    for VColLayer in Data.vertex_colors:
    
                        if VColLayer.active:  # only delete in active VCol layer
    
                                delete_key(Data, 'color')
    
                if Mode:
                    bpy.ops.object.editmode_toggle()
    
            if Obj.type == 'LATTICE':
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                Mode = False
                if context.mode != 'OBJECT':
                    Mode = not Mode
                    bpy.ops.object.editmode_toggle()
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                Data = Obj.data
    
                if context.window_manager.key_shape:
    
                    if Obj.active_shape_key:
                        for Point in Obj.active_shape_key.data:
    
                            delete_key(Point, 'co')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if context.window_manager.key_points:
                    for Point in Data.points:
    
                        delete_key(Point, 'co_deform')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if Mode:
                    bpy.ops.object.editmode_toggle()
    
            if Obj.type in {'CURVE', 'SURFACE'}:
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                Mode = False
                if context.mode != 'OBJECT':
                    Mode = not Mode
                    bpy.ops.object.editmode_toggle()
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                Data = Obj.data
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                # run this outside the splines loop (only once)
                if context.window_manager.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')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                for Spline in Data.splines:
                    if Spline.type == 'BEZIER':
                        for CV in Spline.bezier_points:
                            if context.window_manager.key_points:
    
                                delete_key(CV, 'co')
                                delete_key(CV, 'handle_left')
                                delete_key(CV, 'handle_right')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_radius:
    
                                delete_key(CV, 'radius')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_tilt:
    
                                delete_key(CV, 'tilt')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                    elif Spline.type == 'NURBS':
                        for CV in Spline.points:
                            if context.window_manager.key_points:
    
                                delete_key(CV, 'co')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_radius:
    
                                delete_key(CV, 'radius')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                            if context.window_manager.key_tilt:
    
                                delete_key(CV, 'tilt')
    
    Daniel Salazar's avatar
    Daniel Salazar committed
                if Mode:
                    bpy.ops.object.editmode_toggle()
    
    
            refresh_ui_keyframes()
    
    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):
            try:
                Data = context.active_object.data
                Data.animation_data_clear()
            except:
                self.report({'WARNING'}, "Clear Animation could not be performed")
                return {'CANCELLED'}
    
            refresh_ui_keyframes()
    
    
    # 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"
    
            for panel in panels:
                if "bl_rna" in panel.__dict__:
                    bpy.utils.unregister_class(panel)
    
            for panel in panels:
                panel.bl_category = context.user_preferences.addons[__name__].preferences.category
                bpy.utils.register_class(panel)
    
        except Exception as e:
            print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e))
    
    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="Animation",
    
                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="")
    
        update_panel(None, bpy.context)