1
$\begingroup$

I've found that I can't change the normal rendering, from a camera, to WIREFRAME, SOLID, or anything but RENDERED. (Actually, there isn't a setting to change, it just goes to RENDERED.) In the Python Console,I've done this:

enter image description here

First, I set a variable to the area that is the 3D Viewport for convenience. Then I check the shading and it's WIREFRAME. From there, I render that space, the 3D Viewport. It always renders from the default camera. My first test render rendered in the SOLID mode, but now I can't get it to render the 3D Viewport view (using bpy.ops.render.opengl()) and it always renders in RENDERED mode. Here's a sample - rather crowded and from the top:

enter image description here

I was under the impression that if I rendered the 3D Viewport space, I could get it to render in whatever shading method that was currently set for the Viewport. Is that not the case? Other than using plugins, is there a way to control the shading for rendering the view in the Viewport?

I'm beginning to think it just won't work, but I thought I saw instructions (that worked) that would let me do this and I've been searching, but can't find a way to do it.

So, bottom line, how can I specify the shading mode in the Viewport, render that view, then save the file?

$\endgroup$
0

1 Answer 1

4
$\begingroup$

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:

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

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:

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)
$\endgroup$
2
  • $\begingroup$ I'll have to check, but I think the screenshot is wrong. When testing, I had one camera set as the prime camera (can't remember the proper term now - ctrl-numpad-0) and it was rendering from that camera, not from the screenshot of the current view. Like I said, I'll have to check on it and see if I was doing something else I didn't realize was interfering. $\endgroup$
    – Tango
    Commented Apr 19, 2021 at 18:07
  • $\begingroup$ An interesting note on this. I copied it into a text file in Blender and ran it with no trouble and got the output file, but when I did piece by piece in the console and got to the line to render the image, when I hit <return> nothing happened - it didn't move to the next line or anything. Just found that weird. $\endgroup$
    – Tango
    Commented Apr 19, 2021 at 23:26

You must log in to answer this question.

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