2
$\begingroup$

During execution of a python script, I'm trying to import a .blend file. It's currently not an option to load the file when Blender boots, although ideally we would get the same result either way. I'm using:

bpy.ops.wm.open_mainfile(filepath=path)

However, this destroys bpy.context ({.window, .screen} = None), but only when blender is started without "--background". This is the relevant Blender source code (blender/windowmanager/intern/wm_files.c):

if (!G.background) {
    /* in background mode this makes it hard to load
    * a blend file and do anything since the screen
    * won't be set to a valid value again */
    CTX_wm_window_set(C, NULL); /* exits queues */
}

This causes "invalid context" problems for different operators (e.g., bpy.ops.transform.*) called afterwards.

It would be great to be able to open .blend files without the WM/GUI interference altogether. However, since there doesn't seem to be a WM-less Python call for now, restoring the original context (or at least a context equivalent to the one when Blender starts up) would also work. Bonus points for solutions without WM hacks (e.g. simulating clicks) ;-)

$\endgroup$
3
  • $\begingroup$ Do you run Blender in background mode or not? $\endgroup$
    – CodeManX
    Commented Aug 12, 2014 at 20:04
  • $\begingroup$ In our live environment we do, so there it's no problem, but for developing and testing we run without --background to see what happens. $\endgroup$
    – Turiphro
    Commented Aug 13, 2014 at 8:09
  • $\begingroup$ In fact, the purpose of importing a .blend file here is to import predefined objects + (Cycles) materials & lights. While everything works fine for Blender render with other file formats, .blend seems to be the only one able to export+import Cycles materials. Another way of importing Cycles-compatible scenes (without the bloated .blend file import) is also welcome. $\endgroup$
    – Turiphro
    Commented Aug 13, 2014 at 8:13

1 Answer 1

1
$\begingroup$

Found a WM hack based on this answer that seems to work. Some operators still complain about "PyContext 'blend_data' not found", but this doesn't seem to result in problems so far. Still feels a bit hacky though.

def fix_context():
    """Fix bpy.context if some command (like .blend import) changed/emptied it"""
    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'VIEW_3D':
                for region in area.regions:
                    if region.type == 'WINDOW':
                        override = {'window': window, 'screen': screen, 'area': area, 'region': region}
                        bpy.ops.screen.screen_full_area(override)
                        break

Edit: this works (with --background) but only if there's running an X server for the current user. Feels like there's some gui hacking going around when Blender python scripts are running background... Running on an X-less server gives a segfault.

$\endgroup$
2
  • $\begingroup$ Background mode is actually just hiding the interface, though it is still required to hold necessary data, which is used by operators etc. I'm pretty sure you can just set bpy.context.area.type = 'VIEW_3D' to avoid context overriding, which should slim down your code a lot. $\endgroup$
    – CodeManX
    Commented Aug 27, 2014 at 13:33
  • $\begingroup$ This crashes 2.80 $\endgroup$
    – yarun can
    Commented Mar 13, 2019 at 7:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .