Отключить или перехватить предупреждения VTK в vtkOutputWindow при встраивании Mayavi

Я хотел бы либо отключить окно предупреждения VTK, либо, что еще лучше, поймать их для обработки с помощью системы ведения журнала моего приложения. В моем приложении используется встроенное представление Mayavi, и я не хочу, чтобы появлялись окна с ошибками, которые я не могу контролировать. Следующий код демонстрирует окно предупреждения.

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()

Хорошо, я провел небольшое исследование и обнаружил, что vtk.vtkObject.GlobalWarningDisplayOff() полностью отключает окно, и это приятно. Еще лучше следующий код будет записывать предупреждения в файл (нашел его здесь):

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)

Так что, хотя это хорошо, я все еще не могу передать предупреждения непосредственно в обработчик ведения журнала. Я бы предпочел не иметь файл vtk_log рядом с моими обычными файлами журнала. Кроме того, я мог бы каким-то образом обрабатывать предупреждения в своем графическом интерфейсе или предоставлять пользователю варианты того, как их обрабатывать, и постоянное наблюдение за файлом журнала на предмет изменений кажется плохим способом сделать это.

Любые предложения по надежному pythonic способу обработки предупреждений vtk в приложении, которое встраивает mayavi/vtk?


person flutefreak7    schedule 09.05.2014    source источник
comment
Я понятия не имею, как это сделать. Но если вы придумаете лайфхак, чтобы сделать что-то хорошее, я бы им воспользовался.   -  person aestrivex    schedule 12.05.2014


Ответы (4)


Я предполагаю, что это частично отвечает на ваш вопрос, но вы можете реализовать наблюдатель ошибок в python, как описано здесь http://public.kitware.com/pipermail/vtkusers/2012-June/074703.html и добавьте его в интересующий вас класс vtk.

В С++ мне гораздо проще перенаправить вывод в stderr (этот пример для окон):

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

В питоне пробовал

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

он отправляет ошибку на консоль, но я все еще вижу окно vtk, и, похоже, он не улавливает ошибки.

Другим вариантом может быть перекомпиляция vtk с отключенным VTK_USE_DISPLAY ( http://osdir.com/ml/python-enthought-devel/2009-11/msg00164.html). Я не собираюсь пробовать это, потому что я использую дистрибутив vtk, уже скомпилированный в paraview.

person lib    schedule 15.09.2014
comment
Наблюдатель ошибок python в ссылке кажется наиболее естественным решением этой проблемы, а также упоминает предостережение о том, что если бы это было реализовано для всех объектов VTK по умолчанию, они стали бы еще более громоздкими с точки зрения памяти и накладных расходов на обработку. Несмотря на это, автор даже упоминает, что этот метод может привести к чистой замене vtkOutputWindow на Python или, по крайней мере, распространению ошибок VTK в Python RuntimeErrors. У меня нет времени исследовать это сейчас, и я пытаюсь покинуть Mayavi, чтобы переключиться на Python 3, но я отмечу это правильно. Спасибо! - person flutefreak7; 15.09.2014

Я не знаю, будет ли это работать в среде Mayavi, но это работает для оберток Python в VTK.

# pipe vtk output errors to file
errOut = vtk.vtkFileOutputWindow()
errOut.SetFileName("VTK Error Out.txt")
vtkStdErrOut = vtk.vtkOutputWindow()
vtkStdErrOut.SetInstance(errOut)
person SciCompLover    schedule 10.02.2017
comment
На мой взгляд, это лучшее решение, поскольку в принятом ответе используется SendToStdErrOn, который доступен только в Windows. Чтобы не создавать файл, можно также использовать StringOutput: errOut = vtk.vtkStringOutputWindow() - person greeeeeeen; 15.05.2019

Вы можете создать подкласс, производный от vtkOutputWindow, и реализовать обработку сообщений в методе void DisplayText(const char* someText). Я сделал это в проекте C++, чтобы перенаправить весь вывод на cerr и даже подавить определенные предупреждения. .

person Lars Bilke    schedule 16.02.2015

Подход, который я нашел похожим на ответ @SciCompLover, который подавляет окно вывода, а также печатает на консоль:

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

Протестировано на Mayavi 4.7.1 с VTK 8.2.0 в Windows и MacOS.

person yodavid    schedule 11.02.2020