How to make the code flow without closing the VTK render window?
I'm using Visual Studio 2010, VTK 5.6 and configure my projects without using CMake.
I'm dealing with numerical computing and want to generate several plots during the runtime using VTK. Starting with the line plot example given in the VTK web page I managed to generate the plot that I want. The problem is that the code doesn't continue without closing the plot window.
From my "main.cpp" file, I send the command to a header file, where the VTK procedure is initiated.
residualPlotter(x,xdim1d);
"residualPlotter" is the function that generates the plot. It's given below:
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;
}
So, I want the code to continue without the need to close the window. How should I modify the code?
Thank you all.
If you just want to render the plot, do something else, update and render again you can skip the renderWindowInteractor code, and simply call
view->Render();
This will render the plot with the data you supplied, and control will return to your code. You can continue doing this and call Render() on the view whenever you want to see an updated chart.
Marcus D. Hanwell mentioned a timer event at the comment. There is a code at a VTK example section. For me, I modified the snippet;
// 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();
and I changed the vtkTimerCallback class at the sample code (in here, the background color keep being changed);
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;
};
I declared the renderer and renderWindow as global variable, so the window change the window in the main section.
I added the grid to a vtkActor as follow:
vtkSmartPointer actor_grid = vtkSmartPointer::New();
vtkSmartPointer chart = vtkSmartPointer::New();
renderer->AddActor(actor_grid);
This works well since it is not associated with an interactor.
Thanks.
精彩评论