如何在不关闭VTK渲染窗口的情况下使代码流动?

时间:2011-07-01 19:19:30

标签: c++ visual-c++ visualization vtk

我正在使用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 个答案:

答案 0 :(得分:4)

如果你只想渲染绘图,做其他事情,再次更新和渲染你可以跳过renderWindowInteractor代码,然后简单地调用

view->Render();

这将使用您提供的数据渲染绘图,控件将返回到您的代码。您可以继续这样做,只要您想查看更新的图表,就可以在视图上调用Render()。

答案 1 :(得分:2)

Marcus D. Hanwell在评论中提到了计时器事件。 VTK example section处有一个代码。对我来说,我修改了片段;

// 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声明为全局变量,因此窗口会更改主要部分中的窗口。

答案 2 :(得分:-1)

我将网格添加到vtkActor中,如下所示:

  

vtkSmartPointer actor_grid = vtkSmartPointer :: New();

     

vtkSmartPointer chart = vtkSmartPointer :: New();

     

renderer-&GT; AddActor(actor_grid);

这很有效,因为它与交互者无关。

感谢。