見出し画像

[Blender]Fカーブのデフォルト補間設定、ハンドル設定ボタンを追加するスクリプト

Fカーブのデフォルト補間設定、ハンドル設定を変更するのにいちいちプリファレンスを開くのが面倒なのでグラフエディターとドープシートに変更ボタンを追加するスクリプトをchatGPTに書いてもらいました。


import bpy

# Set interpolation type
def set_interpolation(interpolation_type):
    prefs = bpy.context.preferences
    prefs.edit.keyframe_new_interpolation_type = interpolation_type

# Set handle type
def set_handle_type(handle_type):
    prefs = bpy.context.preferences
    prefs.edit.keyframe_new_handle_type = handle_type

# Operator to set interpolation
class SetInterpolationOperator(bpy.types.Operator):
    bl_idname = "graph.set_interpolation"
    bl_label = "Set Interpolation"
    bl_options = {'REGISTER', 'UNDO'}
    
    interpolation: bpy.props.EnumProperty(
        name="Interpolation",
        description="Choose interpolation type",
        items=[
            ('CONSTANT', "Constant", ""),
            ('LINEAR', "Linear", ""),
            ('BEZIER', "Bezier", ""),
            ('SINE', "Sine", ""),
            ('QUAD', "Quadratic", ""),
            ('CUBIC', "Cubic", ""),
            ('QUART', "Quartic", ""),
            ('QUINT', "Quintic", ""),
            ('EXPO', "Exponential", ""),
            ('CIRC', "Circular", ""),
            ('BACK', "Back", ""),
            ('BOUNCE', "Bounce", ""),
            ('ELASTIC', "Elastic", "")
        ]
    )
    
    def execute(self, context):
        set_interpolation(self.interpolation)
        self.report({'INFO'}, f"Set interpolation to {self.interpolation}")
        return {'FINISHED'}

# Operator to set handle type
class SetHandleTypeOperator(bpy.types.Operator):
    bl_idname = "graph.set_handle_type"
    bl_label = "Set Handle Type"
    bl_options = {'REGISTER', 'UNDO'}
    
    handle_type: bpy.props.EnumProperty(
        name="Handle Type",
        description="Choose handle type",
        items=[
            ('FREE', "Free", ""),
            ('ALIGNED', "Aligned", ""),
            ('VECTOR', "Vector", ""),
            ('AUTO', "Auto", ""),
            ('AUTO_CLAMPED', "Auto Clamped", "")
        ]
    )
    
    def execute(self, context):
        set_handle_type(self.handle_type)
        self.report({'INFO'}, f"Set handle type to {self.handle_type}")
        return {'FINISHED'}

# Map interpolation types to icons
interpolation_icons = {
    'CONSTANT': 'IPO_CONSTANT',
    'LINEAR': 'IPO_LINEAR',
    'BEZIER': 'IPO_BEZIER',
    'SINE': 'IPO_SINE',
    'QUAD': 'IPO_QUAD',
    'CUBIC': 'IPO_CUBIC',
    'QUART': 'IPO_QUART',
    'QUINT': 'IPO_QUINT',
    'EXPO': 'IPO_EXPO',
    'CIRC': 'IPO_CIRC',
    'BACK': 'IPO_BACK',
    'BOUNCE': 'IPO_BOUNCE',
    'ELASTIC': 'IPO_ELASTIC'
}

# Map handle types to icons
handle_type_icons = {
    'FREE': 'HANDLE_FREE',
    'ALIGNED': 'HANDLE_ALIGNED',
    'VECTOR': 'HANDLE_VECTOR',
    'AUTO': 'HANDLE_AUTO',
    'AUTO_CLAMPED': 'HANDLE_AUTOCLAMPED'
}

# Menu to choose interpolation type
class InterpolationMenu(bpy.types.Menu):
    bl_idname = "GRAPH_MT_interpolation_menu"
    bl_label = "Interpolation"
    
    def draw(self, context):
        layout = self.layout
        prefs = bpy.context.preferences
        current_interpolation = prefs.edit.keyframe_new_interpolation_type
        for interpolation, icon in interpolation_icons.items():
            layout.operator(
                SetInterpolationOperator.bl_idname, 
                text=interpolation.capitalize(), 
                icon=icon
            ).interpolation = interpolation

# Menu to choose handle type
class HandleTypeMenu(bpy.types.Menu):
    bl_idname = "GRAPH_MT_handle_type_menu"
    bl_label = "Handle Type"
    
    def draw(self, context):
        layout = self.layout
        prefs = bpy.context.preferences
        current_handle_type = prefs.edit.keyframe_new_handle_type
        for handle_type, icon in handle_type_icons.items():
            layout.operator(
                SetHandleTypeOperator.bl_idname, 
                text=handle_type.capitalize().replace('_', ' '), 
                icon=icon
            ).handle_type = handle_type

# Draw current interpolation and handle type in the header
def draw_current_settings(self, context):
    layout = self.layout
    prefs = bpy.context.preferences
    current_interpolation = prefs.edit.keyframe_new_interpolation_type
    current_handle_type = prefs.edit.keyframe_new_handle_type

    row = layout.row(align=True)
    row.scale_x = 1.5
    row.menu(InterpolationMenu.bl_idname, text="", icon=interpolation_icons.get(current_interpolation, 'IPO_BEZIER'))
    row.menu(HandleTypeMenu.bl_idname, text="", icon=handle_type_icons.get(current_handle_type, 'HANDLETYPE_AUTO_CLAMPED'))

def register():
    bpy.utils.register_class(SetInterpolationOperator)
    bpy.utils.register_class(SetHandleTypeOperator)
    bpy.utils.register_class(InterpolationMenu)
    bpy.utils.register_class(HandleTypeMenu)
    bpy.types.GRAPH_HT_header.append(draw_current_settings)
    bpy.types.DOPESHEET_HT_header.append(draw_current_settings)

def unregister():
    bpy.utils.unregister_class(SetInterpolationOperator)
    bpy.utils.unregister_class(SetHandleTypeOperator)
    bpy.utils.unregister_class(InterpolationMenu)
    bpy.utils.unregister_class(HandleTypeMenu)
    bpy.types.GRAPH_HT_header.remove(draw_current_settings)
    bpy.types.DOPESHEET_HT_header.remove(draw_current_settings)

if __name__ == "__main__":
    register()

これをアドオン化して使っています。

この記事が気に入ったらサポートをしてみませんか?