Как заставить поток кода не закрывать окно визуализации VTK? - PullRequest
2 голосов
/ 01 июля 2011

Я использую Visual Studio 2010, VTK 5.6 и настраиваю свои проекты без использования CMake.

Я имею дело с числовыми вычислениями и хочу создать несколько графиков во время выполнения с использованием VTK. Начиная с примера линейного графика, приведенного на веб-странице VTK, мне удалось создать нужный график. Проблема в том, что код не продолжается без закрытия окна графика.

Из моего файла "main.cpp" я отправляю команду в заголовочный файл, где инициируется процедура VTK.

residualPlotter(x,xdim1d);

"residualPlotter" - это функция, которая генерирует график. Это дано ниже:

int residualPlotter(double* res, int size)
{

  // Create a table with some points in it
  vtkSmartPointer<vtkTable> table = 
    vtkSmartPointer<vtkTable>::New();

  vtkSmartPointer<vtkFloatArray> arrX = 
    vtkSmartPointer<vtkFloatArray>::New();
  arrX->SetName("X Axis");
  table->AddColumn(arrX);

  vtkSmartPointer<vtkFloatArray> arrF = 
    vtkSmartPointer<vtkFloatArray>::New();
  arrF->SetName("Function");
  table->AddColumn(arrF);

  // Fill in the table with some example values
  table->SetNumberOfRows(size);
  for (int i = 0; i < size; ++i)
  {
    table->SetValue(i, 0, i);
    table->SetValue(i, 1, res[i]);
  }

  // Set up the view
  vtkSmartPointer<vtkContextView> view = 
    vtkSmartPointer<vtkContextView>::New();
  view->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
  view->GetRenderWindow()->SetSize(800,600);

  // Add multiple line plots, setting the colors etc
  vtkSmartPointer<vtkChartXY> chart = 
    vtkSmartPointer<vtkChartXY>::New();
  view->GetScene()->AddItem(chart);
  vtkPlot *line = chart->AddPlot(vtkChart::LINE);
  line->SetInput(table, 0, 1);
  line->SetColor(0, 100, 0, 255);
  line->SetWidth(1.75);


  // Set up an interactor and start
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(view->GetRenderWindow());
  renderWindowInteractor->Initialize();
  renderWindowInteractor->Start();


  return EXIT_SUCCESS;

}

Итак, я хочу, чтобы код продолжался без необходимости закрывать окно. Как мне изменить код?

Спасибо всем.

Ответы [ 3 ]

4 голосов
/ 04 июля 2011

Если вы просто хотите визуализировать график, сделать что-то еще, обновить и визуализировать снова, вы можете пропустить код renderWindowInteractor и просто вызвать

view->Render();

Это отобразит график с данными, которые вы предоставили, и элемент управления вернется к вашему коду. Вы можете продолжить делать это и вызывать Render () в представлении всякий раз, когда хотите увидеть обновленный график.

2 голосов
/ 23 марта 2017

Маркус Д. Ханвелл упомянул в комментарии событие таймера. В разделе примера VTK есть код . Для меня я изменил фрагмент;

// Initialize must be called prior to creating timer events.
renderWindowInteractor->Initialize();

// Sign up to receive TimerEvent
vtkSmartPointer<vtkTimerCallback> cb = vtkSmartPointer<vtkTimerCallback>::New();
renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, cb);

int timerId = renderWindowInteractor->CreateRepeatingTimer(100);
std::cout << "timerId: " << timerId << std::endl;


renderWindowInteractor->Start();

и я изменил класс vtkTimerCallback в примере кода (здесь цвет фона продолжает меняться);

class vtkTimerCallback : public vtkCommand
{
public:
    static vtkTimerCallback *New()
    {
        vtkTimerCallback *cb = new vtkTimerCallback;
        cb->TimerCount = 0;
        return cb;
    }

virtual void Execute(vtkObject *vtkNotUsed(caller), unsigned long eventId, void *vtkNotUsed(callData))
{
    if (vtkCommand::TimerEvent == eventId)
    {
        ++this->TimerCount;
    }
    /* this section will be excuted */
    cout << this->TimerCount << " " << "This is from vtkTimerCallback" << endl;
    background_color = (double) rand() / RAND_MAX;
    cout << background_color << endl;
    renderer->SetBackground(background_color, background_color, background_color); 
    renderWindow->AddRenderer(renderer);
    renderWindow->Render();
    /* ----- */
}
private:
    int TimerCount;
};

Я объявил рендер и renderWindow как глобальную переменную, поэтому окно меняет окно в главном разделе.

0 голосов
/ 16 марта 2012

Я добавил сетку в vtkActor следующим образом:

vtkSmartPointer actor_grid = vtkSmartPointer :: New ();

vtkSmartPointer chart = vtkSmartPointer :: New ();

renderer-> AddActor (actor_grid);

Это хорошо работает, поскольку не связано с интерактором.

Спасибо.

...