2

我正在使用 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;

}

所以,我希望代码继续运行而无需关闭窗口。我应该如何修改代码?

谢谢你们。

4

3 回答 3

4

如果您只想渲染绘图,做其他事情,更新并再次渲染,您可以跳过 renderWindowInteractor 代码,只需调用

view->Render();

这将使用您提供的数据渲染绘图,并且控制权将返回到您的代码。您可以继续执行此操作,并在您想查看更新的图表时在视图上调用 Render()。

于 2011-07-04T02:25:52.507 回答
2

Marcus D. Hanwell 在评论中提到了一个计时器事件。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;
};

我将渲染器和渲染窗口声明为全局变量,因此窗口更改了主要部分中的窗口。

于 2017-03-23T20:42:35.303 回答
-1

我将网格添加到 vtkActor 如下:

vtkSmartPointer actor_grid = vtkSmartPointer::New();

vtkSmartPointer 图表 = vtkSmartPointer::New();

渲染器->AddActor(actor_grid);

这很好用,因为它不与交互器关联。

谢谢。

于 2012-03-16T03:53:18.460 回答