Skip to main content
Blender 3.2+ updates
Source Link
p2or
  • 16.1k
  • 10
  • 87
  • 146

Blender 3.2+

import bpy

C = bpy.context

for area in C.screen.areas:
    if area.type == 'VIEW_3D':
        # Check for WIREFRAME, SOLID, RENDERED, MATERIAL
        if area.spaces.active.shading.type == 'WIREFRAME':
            with C.temp_override(area=area):
                bpy.ops.render.opengl(write_still=True)
            break

Blender 2.8+

import bpy

C = bpy.context

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        # Check for WIREFRAME, SOLID, RENDERED, MATERIAL
        # area.spaces.active.shading.type
        if area.spaces.active.shading.type == 'WIREFRAME':
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override, write_still=True)
            break

Blender 3.2+

file_path = bpy.path.abspath("//screenshot")

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        if area.spaces.active.shading.type == 'WIREFRAME':
            
            # Store the current output path and set it
            temp = C.scene.render.filepath
            C.scene.render.filepath = file_path

            with C.temp_override(area=area):
                bpy.ops.render.opengl(write_still=True)

            # Restore the output path
            C.scene.render.filepath = temp
            break

print (file_path)

Blender 2.8+

file_path = bpy.path.abspath("//screenshot")

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        if area.spaces.active.shading.type == 'WIREFRAME':
            # Store the current output path and set it
            temp = C.scene.render.filepath
            C.scene.render.filepath = file_path
            
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override, write_still=True)
            
            # Restore the output path
            C.scene.render.filepath = temp
            break
            
print (file_path)

3.2 Update

Context overrides are deprecated in Blender 3.2 and are scheduled to be removed in Blender 3.3 The replacement is temp_override. The manual has examples of how to use the new function.

import bpy

C = bpy.context

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        # Check for WIREFRAME, SOLID, RENDERED, MATERIAL
        # area.spaces.active.shading.type
        if area.spaces.active.shading.type == 'WIREFRAME':
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override)
            break
file_path = bpy.path.abspath("//screenshot")

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        if area.spaces.active.shading.type == 'WIREFRAME':
            # Store the current output path and set it
            temp = C.scene.render.filepath
            C.scene.render.filepath = file_path
            
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override, write_still=True)
            
            # Restore the output path
            C.scene.render.filepath = temp
            break
            
print (file_path)

3.2 Update

Context overrides are deprecated in Blender 3.2 and are scheduled to be removed in Blender 3.3 The replacement is temp_override. The manual has examples of how to use the new function.

Blender 3.2+

import bpy

C = bpy.context

for area in C.screen.areas:
    if area.type == 'VIEW_3D':
        # Check for WIREFRAME, SOLID, RENDERED, MATERIAL
        if area.spaces.active.shading.type == 'WIREFRAME':
            with C.temp_override(area=area):
                bpy.ops.render.opengl(write_still=True)
            break

Blender 2.8+

import bpy

C = bpy.context

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        # Check for WIREFRAME, SOLID, RENDERED, MATERIAL
        # area.spaces.active.shading.type
        if area.spaces.active.shading.type == 'WIREFRAME':
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override, write_still=True)
            break

Blender 3.2+

file_path = bpy.path.abspath("//screenshot")

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        if area.spaces.active.shading.type == 'WIREFRAME':
            
            # Store the current output path and set it
            temp = C.scene.render.filepath
            C.scene.render.filepath = file_path

            with C.temp_override(area=area):
                bpy.ops.render.opengl(write_still=True)

            # Restore the output path
            C.scene.render.filepath = temp
            break

print (file_path)

Blender 2.8+

file_path = bpy.path.abspath("//screenshot")

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        if area.spaces.active.shading.type == 'WIREFRAME':
            # Store the current output path and set it
            temp = C.scene.render.filepath
            C.scene.render.filepath = file_path
            
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override, write_still=True)
            
            # Restore the output path
            C.scene.render.filepath = temp
            break
            
print (file_path)
added 296 characters in body
Source Link
Marty Fouts
  • 33.5k
  • 10
  • 37
  • 80

3.2 Update

Context overrides are deprecated in Blender 3.2 and are scheduled to be removed in Blender 3.3 The replacement is temp_override. The manual has examples of how to use the new function.

3.2 Update

Context overrides are deprecated in Blender 3.2 and are scheduled to be removed in Blender 3.3 The replacement is temp_override. The manual has examples of how to use the new function.

Source Link
brockmann
  • 12.8k
  • 4
  • 51
  • 94

The render.opengl() operator is working fine for all modes. But notice that it takes a screenshot of the first viewport found, quoting the docs: "Take a snapshot of the active viewport". So in case you have multiple 3d viewports open at the same time it takes the first one in the area list of your screen (Screen.Areas).


Obviously the simplest option is to close all 3d viewports except one, set the shading mode, call the operator and pass write_still=True to take the screenshot as well as saving the file into the default Output directory:

>>> bpy.ops.render.opengl(write_still=True)

In case you have multiple viewports open and you'd like to specify the area for the screenshot, you can override the context when calling render.opengl() operator. See the following demo on how to find the first 3d viewport set to 'WIREFRAME' and take a screenshot:

import bpy

C = bpy.context

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        # Check for WIREFRAME, SOLID, RENDERED, MATERIAL
        # area.spaces.active.shading.type
        if area.spaces.active.shading.type == 'WIREFRAME':
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override)
            break

In order to set the filename, just temporary assign your path to the RenderSettings.filepath property. Demo on how to take a screenshot of the first viewport found set to 'WIREFRAME' and save the result to the directory of the current blend file:

file_path = bpy.path.abspath("//screenshot")

for area in C.screen.areas:
    if area.type=='VIEW_3D':
        if area.spaces.active.shading.type == 'WIREFRAME':
            # Store the current output path and set it
            temp = C.scene.render.filepath
            C.scene.render.filepath = file_path
            
            override = C.copy()
            override['area'] = area
            bpy.ops.render.opengl(override, write_still=True)
            
            # Restore the output path
            C.scene.render.filepath = temp
            break
            
print (file_path)