I'm trying to make a operator/script that reverses the selected

Here is the script with the basic code:

import bpy
from bpy.types import Operator, GreasePencil, Context, GPencilStroke, GPencilStrokePoint, GPencilLayer, GPencilFrame, GPencilFrames, GPencilStrokes, UILayout, Event, Object

def get_gpd(context:Context)->GreasePencil:
#    return context.gpencil_data
    return context.active_object.data

def get_selected_gpencil_frames_in_layer(grease_pencil:GreasePencil, layer:GPencilLayer)->GPencilFrames:
    selected_gpframes = []
    for frame in layer.frames:
        if frame.select:
    return selected_gpframes

def reverse_selected_frames(context):
    # I tried setting off the Autokeying
#    bpy.data.scenes["Scene"].tool_settings.use_keyframe_insert_auto = False
    gpd:GreasePencil = get_gpd(context)
    selected_frames_in_active_layer = get_selected_gpencil_frames_in_layer(gpd, gpd.layers.active)
    _frame_numbers = [frame.frame_number for frame in selected_frames_in_active_layer]
    # Reverse
    print("_frame_numbers:" , _frame_numbers)
    # I tried offseting the frames in case it was some kind of overlaping-frames problem
    for frame in selected_frames_in_active_layer:
        frame.frame_number = frame.frame_number + 9000

    for i,frame in enumerate(selected_frames_in_active_layer):
        _debg_after_frame = frame.frame_number
#        frame.frame_number = _frame_numbers[i-1] # before reversing the _frame_numbers
        frame.frame_number = _frame_numbers[i]
        print(f"Before: {_debg_after_frame}    After: {frame.frame_number}")


The script seems to work correctly, but is like the changes are not "consolidated".

Made a little gif to show it. The changes only have effect when I manually drag the keyframes a bit. And then the animation is reversed as expected.

enter image description here

Is there any thing Im missing?

PS: I know there is a Mirror operator in the Dope Sheet Context Menu -> Mirror even though, the reverse-frames-code is part of another operator and I can't call that Mirror OT since I get wrong context. Also, the reverse effect I want to achieve is different than any in the Mirror options.

Thank you so much for any help/idea, much appreciated.

PS2: I found this question with a similar issue. None of the workarounds work in my case (Blender 3.6 and Blender 4.0).

  • $\begingroup$ hi, just a suggestion but you could implement the same functionality in a totally different way, using scale -1. It would go something like this: a) work out the length of the selected animation , b) move the playhead to the halfway point , c) scale -1 , d) put back the playhead where it used to be. There a bunch of pitfalls you'd have to take into account, like if the length is an even number it might shift all frames by 1, which might accidentally overwrite the next frame along, so by the end it might be more complicated, i'm not sure, but worth a look $\endgroup$
    – pevinkinel
    Dec 13, 2023 at 11:03
  • 1
    $\begingroup$ @pevinkinel thank you so much, I hadn't thought about that option! Sadly, despite technically works, has the same problem (the dopesheet dont updates if its called via script (not until you move a frame via the interface :( )). But much appreciated the idea mate! $\endgroup$
    – Ommadawn
    Dec 16, 2023 at 10:43


You must log in to answer this question.

Browse other questions tagged .