17

I want to be able to cycle through the frames I set markers on (I have cameras bound to each marker so these are usually the first frame in a shot). Is there a hot-key for this?

  • 1
    well, there was in 2.4x (Pgup and Pgdown) however, this doesn't work in 2.68. – gandalf3 Oct 12 '13 at 02:34
  • I am not sure if you mean key frames or not but that would be arrow key up and down. –  Oct 12 '13 at 16:36
  • One option is to write your own operator in python which would get the frame of the next marker, and set the current frame to that frame. (you could then write another one to do the same for the previous marker) Then you could assign shortcuts to them. – gandalf3 Oct 12 '13 at 18:56

4 Answers4

16

While @gandalf3's solution worked, I found it a little awkward to set up (user preferences that rely on scripts that need to be in your project, if I understood correctly), and I found that there's now a built-in shortcut adding feature on the menu:

  • In the timeline viewport menu, click Marker
  • Right-click on "Jump to Previous Marker"
  • Click on "Add Shortcut"
  • Hover over the pop-up "A" box, so that it turns into "Press a Key"
  • Hit your target combination, eg "Alt-Left"
  • (repeat for "Jump to Next")

I might be missing something the scripts in @gandalf3's answer provide, please let me know if so!

Tao
  • 261
  • 2
  • 5
8

AFAIK, there is currently no shortcut in 2.68 to do this. (there was in 2.4x) However, you can create your own operator to do this using blenders python API:

I am not very experienced in python, but I came up with two scripts for jumping to the next and previous markers: (pardon my bad python)

Jump_to_next.py:

import bpy
#jump to next marker

class MoveOperator(bpy.types.Operator):
bl_idname = "marker.jump_to_next"
bl_label = "Jump to next marker"

def execute(self, context):  
    frm=0
    frm_close=0
    frm_first = bpy.context.scene.frame_end
    def switchcam():
        if markname:
            if camname != markname:
                for area in bpy.context.screen.areas:
                    if area.type == 'VIEW_3D':
                        for space in area.spaces:
                            if space.type == 'VIEW_3D':
                                if space.region_3d.view_perspective == 'CAMERA':
                                    override = {'window': bpy.context.window, 'screen': bpy.context.screen, 'area': area, 'scene': bpy.context.scene, 'region': bpy.context.region, 'space': space}
                                    bpy.ops.view3d.viewnumpad(override, type='CAMERA')
                                    bpy.ops.view3d.viewnumpad(override, type='CAMERA')
                                else:
                                    print ("not in camera view")
                            else:
                                print ("space is not a 3D view")
                    else:
                        print ("area is not a VIEW_3D")
            else:
                print ("camera bound to next marker is already active")
        else:
            print ("marker is not bound to a camera")

    # get some vars:
    now = bpy.context.scene.frame_current
    cam = bpy.context.scene.camera
    if cam:
        camname = cam.name
    frm_close = bpy.context.scene.frame_end

    # Loop through markers and test how close to the current frame they are:
    for TimelineMarker in bpy.context.scene.timeline_markers:
        frm = TimelineMarker.frame
        if frm > now:
            if frm < frm_close:
                frm_close = frm
                markname = TimelineMarker.camera
                if markname:
                    markname = TimelineMarker.camera.name
        if frm < frm_first:
            frm_first = frm
    #Test if there is a marker that met requirements:
    if frm_close != bpy.context.scene.frame_end:
        #set scene frame to the frame of closest marker:
        bpy.context.scene.frame_set(frm_close)
        switchcam()
    else:
        if frm_first != bpy.context.scene.frame_end:
            self.report({'INFO'}, 'No more markers to jump to in this direction, skipping to first')
            bpy.context.scene.frame_set(frm_first)
        else:
            self.report({'WARNING'}, 'No markers found')
    return {'FINISHED'}

bpy.utils.register_class(MoveOperator)

Jump_to_prev.py:

import bpy
#jump to previous marker

class MoveOperator(bpy.types.Operator):
bl_idname = "marker.jump_to_prev"
bl_label = "Jump to previous marker"

def execute(self, context):  
    frm=0
    frm_close=0
    frm_first=0
    def switchcam():
        if markname:
            if camname != markname:
                for area in bpy.context.screen.areas:
                    if area.type == 'VIEW_3D':
                        for space in area.spaces:
                            if space.type == 'VIEW_3D':
                                if space.region_3d.view_perspective == 'CAMERA':
                                    override = {'window': bpy.context.window, 'screen': bpy.context.screen, 'area': area, 'scene': bpy.context.scene, 'region': bpy.context.region, 'space': space}
                                    bpy.ops.view3d.viewnumpad(override, type='CAMERA')
                                    bpy.ops.view3d.viewnumpad(override, type='CAMERA')
                                else:
                                    print ("not in camera view")
                            else:
                                print ("space is not a 3D view")
                    else:
                        print ("area is not a VIEW_3D")
            else:
                print ("camera bound to next marker is already active")
        else:
            print ("marker is not bound to a camera")

    # get some vars:
    now = bpy.context.scene.frame_current
    cam = bpy.context.scene.camera
    if cam:
        camname = cam.name

    # Loop through markers and test how close to the current frame they are:
    for TimelineMarker in bpy.context.scene.timeline_markers:
        frm = TimelineMarker.frame
        if frm < now:
            if frm > frm_close:
                frm_close = frm
                markname = TimelineMarker.camera
                if markname:
                    markname = TimelineMarker.camera.name
        if frm > frm_first:
            frm_first = frm
    #Test if there is a marker that met requirements:
    if frm_close != 0:
        #set scene frame to the frame of closest marker:
        bpy.context.scene.frame_set(frm_close)
        switchcam()
    else:
        if frm_first != 0:
            self.report({'INFO'}, 'No more markers to jump to in this direction, skipping to last')
            bpy.context.scene.frame_set(frm_first)
        else:
            self.report({'WARNING'}, 'No markers found')
    return {'FINISHED'}

bpy.utils.register_class(MoveOperator)

You can make these into shortcuts by

  1. Paste into the text editor and check the Register option in the header:

    enter image description here

  2. In User Preferences (CtrlAltU)> Input, scroll down to the context you want to use the shortcut in (e.g. Timeline), expand it and click Add new.

  3. Type in the operator name (marker.jump_to_next or marker.jump_to_prev) and set the shortcut to whatever you want (e.g. Page Up):

    enter image description here

  4. Save the default .blend. (CtrlU) This is necessary to save the python script so the operator marker.jump_to_next exists. Be careful when saving the default .blend, this will save information such as geometry, screen layout, User preferences, etc.

Note that you will have to do steps 1-3 twice, once for each operator. (jump_to_next and jump_to_prev)

gandalf3
  • 157,169
  • 58
  • 601
  • 1,133
  • Awesome. This works great. Only thing I did differently was I set the hot-key up under the Screen (Global) section so it works everywhere.

    Now just need to get this into Blender trunk!

    – Consideringthepickle Oct 13 '13 at 02:45
  • One more request actually. Normally when you switch markers and you're in camera view, it also switches to the active camera for that marker, but this script doesn't seem to be doing that. – Consideringthepickle Oct 13 '13 at 03:09
  • @Consideringthepickle Does it switch now? – gandalf3 Oct 14 '13 at 03:09
  • It works but it sends an error message in any screen other than 3dview: line 30, in execute line 188, in call ret = op_call(self.idname_py(), None, kw) RuntimeError: Operator bpy.ops.view3d.viewnumpad.poll() failed, context is incorrect

    location: :-1

    To clarify: It does jump markers in other views from 3d view, but gives an error and doesn't switch cameras.

    – Consideringthepickle Oct 14 '13 at 18:39
  • @Consideringthepickle Fixed :) There is still a bug where the wrong camera is drawn as the active camera when not in camera view, but I can't seem to figure out how to update it.. – gandalf3 Oct 14 '13 at 21:48
  • Not fixed. New error: line 41, in execute line 12, in switchcam line 188, in call ret = op_call(self.idname_py(), None, kw) RuntimeError: Operator bpy.ops.view3d.viewnumpad.poll() failed, context is incorrect

    -Also that camera draw bug happens normally anyway so it's probably a deeper issue.

    – Consideringthepickle Oct 15 '13 at 00:41
  • A 'nice to have' amendment: When it gets to the last marker it would be nice if it looped back around to the first and vice versa. – Consideringthepickle Oct 15 '13 at 00:43
  • 2
    I created a little addon for someone on IRC a while ago doing exactly this. It is also bad code: https://www.dropbox.com/s/jvzlcnobfw6hebc/marker_jumping.py Hotkeys: ',' and '.' for Previous and Next marker. – Greg Zaal Oct 15 '13 at 13:07
  • 1
    @Consideringthepickle I fixed that bug again, (hopefully for real) and made it loop back to the first/last marker. I also reported the camera draw bug on the tracker. There are still some issues when using multiple 3D views, I'll see if I can work some of those out.. – gandalf3 Oct 15 '13 at 20:50
  • @gandalf3 Yes it works. Will the looping be broken by the new lock timeline button that was just added in SVN? Looping should probably only happen within active frame range anyway. Not to get picky. And we don't need to see the camera switching animation for this necessarily. Not sure if that's a particular operator you used or something that can be turned off by the user in settings. – Consideringthepickle Oct 16 '13 at 04:05
  • @GregZaal Yours also works but is missing the looping and those hot-keys conflict with pivot-point switching in 3d view on the default keymap. – Consideringthepickle Oct 16 '13 at 04:06
  • @Consideringthepickle it's a particular operator I used, (AFAIK it can't be turned off in user prefs) because setting it directly with space.region_3d.view_perspective did not seem to be taking into account the changed active camera (possibly related to the drawing bug?) What it does now is basically the same as pressing numpad 0 twice. – gandalf3 Oct 16 '13 at 04:43
  • @Consideringthepickle It doesn't loop, no, but it doesn't conflict with the 3D view hotkeys at all for me. I realize I didn't specify that the hotkeys should only work in the timeline/graph editor/dopesheet, but they don't seem to be conflicting for me. – Greg Zaal Oct 16 '13 at 07:47
  • Related: http://blender.stackexchange.com/a/45144/2843 – Samoth Feb 17 '16 at 20:32
4

Jumping between markers has now been included in trunk as of r60881 with CtrlShift+/ (left/right arrows)

hjaarnio
  • 2,414
  • 18
  • 19
Greg Zaal
  • 10,856
  • 3
  • 47
  • 86
0

In 3.2 and possibly earlier, there's:

  • Marker > Jump to Next/Previous Marker*

I realize you can make your own shortcut for it, however it would be cool if there was already a shortcut assigned to it by default as it's a pretty rudimentary feature.

Duarte Farrajota Ramos
  • 59,425
  • 39
  • 130
  • 187