10
$\begingroup$

Using the Blender Python Module bpy the rendering process bpy.ops.render.render(write_still=True) is quite verbose:

Fra:2 Mem:14.35M (0.00M, Peak 14.50M) | Preparing Scene data
Fra:2 Mem:19.00M (0.00M, Peak 19.01M) | Preparing Scene data
...
Fra:2 Mem:15.00M (0.00M, Peak 33.27M) Sce: Scene Ve:21001 Fa:41576 La:1
Saved: /path/to/output.png Time: 00:00.60 (Saving: 00:00.06)

I can't make use of the proposed solution to omit the script output, because the Blender renderings are embedded in a larger python project using import bpy API rather than calling a python script file.

I tried to suppress the output using a python standard method presented here, but no success.

Is there any way to reduce the verbosity of Blender renderings when using bpy module?

$\endgroup$
3
  • 1
    $\begingroup$ i didn't try blender as a module but see if this helps stackoverflow.com/a/11632982/2987234 $\endgroup$
    – Chebhou
    Jan 8, 2016 at 14:20
  • $\begingroup$ Great, it works! $\endgroup$
    – frthjf
    Jan 8, 2016 at 14:47
  • $\begingroup$ if you have a working solution please write a reasonable answer, so it is of some use to others. $\endgroup$
    – zeffii
    Jan 8, 2016 at 14:59

2 Answers 2

15
$\begingroup$

The following output redirection proposed here does work:

# redirect output to log file
logfile = 'blender_render.log'
open(logfile, 'a').close()
old = os.dup(sys.stdout.fileno())
sys.stdout.flush()
os.close(sys.stdout.fileno())
fd = os.open(logfile, os.O_WRONLY)

# do the rendering
bpy.ops.render.render(write_still=True)

# disable output redirection
os.close(fd)
os.dup(old)
os.close(old)
$\endgroup$
1
  • 3
    $\begingroup$ cool! even if only relatively few people need to know this answer, at least they don't have to visit a different link now. $\endgroup$
    – zeffii
    Jan 8, 2016 at 15:07
2
$\begingroup$

This worked for me. https://stackoverflow.com/questions/5081657/how-do-i-prevent-a-c-shared-library-to-print-on-stdout-in-python It makes a context manager you can use to block the output of specific lines. It is similar to above answer but cleaner.

import os
import sys
from contextlib import contextmanager

@contextmanager
def stdout_redirected(to=os.devnull):
    '''
    import os

    with stdout_redirected(to=filename):
        print("from Python")
        os.system("echo non-Python applications are also supported")
    '''
    fd = sys.stdout.fileno()

    ##### assert that Python and C stdio write using the same file descriptor
    ####assert libc.fileno(ctypes.c_void_p.in_dll(libc, "stdout")) == fd == 1

    def _redirect_stdout(to):
        sys.stdout.close() # + implicit flush()
        os.dup2(to.fileno(), fd) # fd writes to 'to' file
        sys.stdout = os.fdopen(fd, 'w') # Python writes to fd

    with os.fdopen(os.dup(fd), 'w') as old_stdout:
        with open(to, 'w') as file:
            _redirect_stdout(to=file)
        try:
            yield # allow code to be run with the redirected stdout
        finally:
            _redirect_stdout(to=old_stdout) # restore stdout.
                                            # buffering and flags such as
                                            # CLOEXEC may be different

Then just use as follows:

with stdout_redirected():
     bpy.ops.render.render(write_still=True)
$\endgroup$

You must log in to answer this question.

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