Disable or Catch VTK warnings in vtkOutputWindow when embedding Mayavi
Asked Answered
C

4

9

I'd like to either disable the VTK warning window or, better yet, catch them to handle with my application's logging system. My application is using an embedded mayavi view, and I don't want error windows popping up that I have no control over. The following code demonstrates the warning window.

import numpy as np
from mayavi import mlab

x1 = np.array([1, 1, 2, 3])
y1 = np.array([1, 1, 4, 2])
z1 = np.array([1, 1, 5, 1])

mlab.plot3d(x1, y1, z1)

mlab.show()

Ok, I've done some research and discovered that vtk.vtkObject.GlobalWarningDisplayOff() will disable the window completely, which is nice. Better yet the followingcode will log the warnings to a file (found it here):

def redirect_vtk_messages ():
    """ Can be used to redirect VTK related error messages to a
    file."""
    import tempfile
    tempfile.template = 'vtk-err'
    f = tempfile.mktemp('.log')
    log = vtkpython.vtkFileOutputWindow()
    log.SetFlush(1)
    log.SetFileName(f)
    log.SetInstance(log)

So while this is nice, I'm still unable to pipe the warnings directly into a logging handler. I'd rather not have to have a vtk_log file next to my regular log files. Also I might want to handle the warnings in my GUI somehow, or give the user options on how to handle them and constantly watching a log file for changes seems like a poor way to do that.

Any suggestions on a robust pythonic way to handle vtk warnings in an application which embeds mayavi/vtk?

Cucullate answered 9/5, 2014 at 20:47 Comment(1)
I have no idea how to do this. But if you come up with a hack to do something nice, I'd use it.Incomprehension
G
7

I guess this partially answer your question, but you could implement an error observer in python as explained here http://public.kitware.com/pipermail/vtkusers/2012-June/074703.html and add it to the vtk class you are interested.

In c++ I find much simpler to redirect the output to stderr (this example is for windows):

vtkSmartPointer<vtkWin32OutputWindow> myOutputWindow = vtkSmartPointer<vtkWin32OutputWindow>::New(); 
myOutputWindow->SetSendToStdErr(true);
vtkOutputWindow::SetInstance(myOutputWindow);

In python I tried

ow = vtk.vtkOutputWindow()
ow.SendToStdErrOn()

it sends the error to console, but I still see the vtk window and it doesn't really seem catching the errors.

Another option could be to recompile vtk with VTK_USE_DISPLAY turned off ( http://osdir.com/ml/python-enthought-devel/2009-11/msg00164.html). I am not going to try this because I am using the vtk distribution already compiled in paraview

Gerah answered 15/9, 2014 at 8:0 Comment(1)
The python error observer in the link appears to be the most natural solution to this problem and also mentions the caveat that if this were implemented on all VTK objects by default they would be come even more cumbersome in terms of memory and processing overhead. Despite this the author even mentions that this technique could lead to a pure python replacement of vtkOutputWindow or at least propagating VTK errors into Python RuntimeErrors. I don't have time to explore this now and am trying to leave Mayavi to switch to python 3, but I'll mark this correct. Thanks!Cucullate
A
11

I don't know whether this will work in the Mayavi environment, but this works for Python wrappings to VTK

# pipe vtk output errors to file
errOut = vtk.vtkFileOutputWindow()
errOut.SetFileName("VTK Error Out.txt")
vtkStdErrOut = vtk.vtkOutputWindow()
vtkStdErrOut.SetInstance(errOut)
Abigailabigale answered 10/2, 2017 at 18:14 Comment(1)
This is the best solution in my opinion, since the accepted answer uses SendToStdErrOn which is only available on windows. To avoid generating a file, one could also use a StringOutput: errOut = vtk.vtkStringOutputWindow()Thessalonian
G
7

I guess this partially answer your question, but you could implement an error observer in python as explained here http://public.kitware.com/pipermail/vtkusers/2012-June/074703.html and add it to the vtk class you are interested.

In c++ I find much simpler to redirect the output to stderr (this example is for windows):

vtkSmartPointer<vtkWin32OutputWindow> myOutputWindow = vtkSmartPointer<vtkWin32OutputWindow>::New(); 
myOutputWindow->SetSendToStdErr(true);
vtkOutputWindow::SetInstance(myOutputWindow);

In python I tried

ow = vtk.vtkOutputWindow()
ow.SendToStdErrOn()

it sends the error to console, but I still see the vtk window and it doesn't really seem catching the errors.

Another option could be to recompile vtk with VTK_USE_DISPLAY turned off ( http://osdir.com/ml/python-enthought-devel/2009-11/msg00164.html). I am not going to try this because I am using the vtk distribution already compiled in paraview

Gerah answered 15/9, 2014 at 8:0 Comment(1)
The python error observer in the link appears to be the most natural solution to this problem and also mentions the caveat that if this were implemented on all VTK objects by default they would be come even more cumbersome in terms of memory and processing overhead. Despite this the author even mentions that this technique could lead to a pure python replacement of vtkOutputWindow or at least propagating VTK errors into Python RuntimeErrors. I don't have time to explore this now and am trying to leave Mayavi to switch to python 3, but I'll mark this correct. Thanks!Cucullate
C
2

You can create a subclass deriving from vtkOutputWindow and implement your message handling in the method void DisplayText(const char* someText). I did this is in a C++ project to redirect all output to cerr and even suppress specific warnings.

Crotch answered 16/2, 2015 at 10:29 Comment(0)
L
1

An approach I found similar to @SciCompLover's answer that suppresses the output window while also printing to the console:

import vtk
vtk_out = vtk.vtkOutputWindow()
vtk_out.SetInstance(vtk_out)

Tested on Mayavi 4.7.1 with VTK 8.2.0 on Windows and MacOS.

Ludwigg answered 11/2, 2020 at 7:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.