0

A quick bit of context: I am interested in having a startup script that among other things, sets the frame start and frame end. Ideally this would be in a startup script over a startup file as is it makes it easier to see the variables in codes, and potentially let them be determined by an environment variable in the future

While setting the frame start and frame end is easy, it's trying to have the Dope Sheet and Graph Editor (which by default needs to be switched into from the Dope Sheet) to frame to the new range.

Initially I had tried using the old context override method - bpy.context.copy(). This will loop through all workspaces and frame the Dope Sheet Editor

import bpy
c_override = bpy.context.copy()

for my_screen in bpy.data.screens: for my_area in my_screen.areas:

    if(my_area.type == 'DOPESHEET_EDITOR'):            
        for my_region in my_area.regions:

            if my_region.type == 'WINDOW':                    
                c_override['screen'] = my_screen
                c_override['area'] = my_area
                c_override['region'] = my_region
                bpy.ops.action.view_all(c_override)

However if I want to frame the Dope Sheet Editor, then switch to the Graph Editor, frame all, and the switch back to the Dope Sheet Editor so my Animation Editor is back to how it started, I would get "context is incorrect".

import bpy
c_override = bpy.context.copy()

for my_screen in bpy.data.screens:

for my_area in my_screen.areas:
    if(my_area.type == 'DOPESHEET_EDITOR'):

        for my_region in my_area.regions:
            if my_region.type == 'WINDOW':

                c_override['screen'] = my_screen
                c_override['area'] = my_area
                c_override['region'] = my_region

                bpy.ops.action.view_all(c_override)

                my_area.type = 'GRAPH_EDITOR'
                bpy.ops.graph.view_all(c_override)

                c_area.type = 'DOPESHEET_EDITOR'

I had seen in this post A comprehensive list of operator overrides that the way of creating a context override is different now in Blender 3.2, using C.temp_override() instead of C.copy()

I had got this working with the current workspace

import bpy

for my_area in bpy.context.window.screen.areas:

if my_area.type == 'DOPESHEET_EDITOR':        
    for my_region in my_area.regions:

        if my_region.type == 'WINDOW':                
            with bpy.context.temp_override(
                window = bpy.context.window,
                area = my_area,
                region = my_region,
            ):
                bpy.ops.action.view_all()

if my_area.type == 'GRAPH_EDITOR':        
    for my_region in my_area.regions:

        if my_region.type == 'WINDOW':                
            with bpy.context.temp_override(
                window = bpy.context.window,
                area = my_area,
                region = my_region,
            ):
                bpy.ops.graph.view_all()

However if I want this to run over all workspaces, when it gets to the Animation workspace if errors "TypeError: Area not found in screen"

import bpy

for my_screen in bpy.data.screens: for my_area in my_screen.areas:

    if my_area.type == 'DOPESHEET_EDITOR':
        for my_region in my_area.regions:
            if my_region.type == 'WINDOW':
                with bpy.context.temp_override(
                    window = bpy.context.window,
                    #screen = my_screen,
                    area = my_area,
                    region = my_region,
                ):
                    bpy.ops.action.view_all()

I wondered if anyone had any pointers to try and get this working?

Update 1 ===============================================================

It seems to be specifically changing the screens that causes issues. For example, any one of these loops run fine on their own, but one after the other fails

# frame dopesheet and switch to graph editor
for screen in bpy.data.screens:
    for area in screen.areas:
        if area.type == 'DOPESHEET_EDITOR':
            for region in area.regions:
                if region.type == 'WINDOW':
                    ctx = bpy.context.copy()
                    ctx['screen'] = screen
                    ctx['area'] = area
                    ctx['region'] = region
                    bpy.ops.action.view_all(ctx)
                    area.type = 'GRAPH_EDITOR'

frame graph editor and return to dopesheet

for screen in bpy.data.screens: for area in screen.areas: if area.type == 'GRAPH_EDITOR': for region in area.regions: if region.type == 'WINDOW': ctx = bpy.context.copy() ctx['screen'] = screen ctx['area'] = area ctx['region'] = region bpy.ops.graph.view_all(ctx) area.type = 'DOPESHEET_EDITOR'

  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy\ops.py", line 113, in __call__
    ret = _op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
RuntimeError: Operator bpy.ops.graph.view_all.poll() failed, context is incorrect

However if I just run on the current screen, it works fine

# frame dopesheet and switch to graph editor
for area in bpy.context.screen.areas:
        if area.type == 'DOPESHEET_EDITOR':
            for region in area.regions:
                if region.type == 'WINDOW':
                    ctx = bpy.context.copy()
                    ctx['screen'] = bpy.context.screen
                    ctx['area'] = area
                    ctx['region'] = region
                    bpy.ops.action.view_all(ctx)
                    area.type = 'GRAPH_EDITOR'

frame graph editor and return to dopesheet

for area in bpy.context.screen.areas: if area.type == 'GRAPH_EDITOR': for region in area.regions: if region.type == 'WINDOW': ctx = bpy.context.copy() ctx['screen'] = bpy.context.screen ctx['area'] = area ctx['region'] = region bpy.ops.graph.view_all(ctx) area.type = 'DOPESHEET_EDITOR'

luithne
  • 1
  • 1
  • Can you paste the entire error traceback into your answer please? – Marty Fouts Jul 06 '22 at 17:49
  • The second snippet (using the old context copy method) gave me this error
    Error: Python: Traceback (most recent call last):
      File "\Text", line 19, in <module>
      File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy\ops.py", line 113, in __call__
        ret = _op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
    RuntimeError: Operator bpy.ops.graph.view_all.poll() failed, context is incorrect
    
    – luithne Jul 08 '22 at 09:34
  • 1
    the fourth snippet using the newer content temp override gave my this error
    Traceback (most recent call last):
      File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy_types.py", line 864, in draw_ls
        def draw_ls(self, context):
    KeyboardInterrupt
    Error: Python: Traceback (most recent call last):
      File "\Text", line 9, in <module>
    TypeError: Area not found in screen
    
    – luithne Jul 08 '22 at 09:35
  • The issue it displays is TypeError, because the problem with the new temp_override is that it overrides window and area, but not screen. bpy.context.screen won't get overridden meaning temp_override will search for the area in the current screen and not Animation or other. – kemplerart Jul 14 '22 at 15:20

1 Answers1

1

Although context.copy() is depracated, it is still working.
Rewrote your code, gives no errors on execute

import bpy

for screen in bpy.data.screens: for area in screen.areas: if area.ui_type == 'DOPESHEET': override = bpy.context.copy() override['area'] = area override['screen'] = screen bpy.ops.action.view_all(override)

kemplerart
  • 610
  • 1
  • 10
  • I just tried this snippet, but found it only works if a region is added to the context override

    However although this works fine, if I am looping through all screens and I change the editor type such as "area.type = 'GRAPH_EDITOR'" during the loop and then run another loop again it fails (see updated post for better explanation)

    – luithne Jul 21 '22 at 11:02