Hi all,
I discovered VTK recently and I am trying to get used to it for now. Currently I am trying to plot some 2D curves that represents the evolution of the sin and cos functions through time at a given rate. To update both curves I had to write a custom rendering loop in which data are updated, the window is rendered and events are processed. All of this works as expected, however, since I am no longer using vtkRenderWIndowInteractor::Start(), the application no longer terminates when I click on the window close button or when I press Alt+f4. I don’t know how to catch these events to close the application without relying on vtkRenderWIndowInteractor::Start().
Here is the source code (based on the vtkChartXY example)
#include <chrono>
#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkFloatArray.h>
#include <vtkPen.h>
#include <vtkPlot.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTable.h>
int
main()
{
// 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> arrC = vtkSmartPointer<vtkFloatArray>::New();
arrC->SetName("Cosine");
table->AddColumn(arrC);
vtkSmartPointer<vtkFloatArray> arrS = vtkSmartPointer<vtkFloatArray>::New();
arrS->SetName("Sine");
table->AddColumn(arrS);
// Set up the view.
vtkSmartPointer<vtkContextView> view = vtkSmartPointer<vtkContextView>::New();
view->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
// 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->SetInputData(table, 0, 1);
line->SetColor(0, 255, 0, 255);
line->SetWidth(1.0);
line = chart->AddPlot(vtkChart::LINE);
line->SetInputData(table, 0, 2);
line->SetColor(255, 0, 0, 255);
line->SetWidth(5.0);
// Save a time origin.
auto t0 = std::chrono::steady_clock::now();
// Start the rendering/event loop.
while (true)
{
// Compute the elapsed time since the start of the loop.
auto t1 = std::chrono::steady_clock::now();
auto dt
= std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count()
/ 1e9f;
// Update data in the table according to the elapsed time.
int num_points = 100;
float time_step = 0.1;
float rad_per_s = 3.14;
table->SetNumberOfRows(num_points);
for (int i = 0; i < num_points; ++i)
{
float t = dt + (i * time_step);
table->SetValue(i, 0, t);
table->SetValue(i, 1, cos(t * rad_per_s));
table->SetValue(i, 2, sin(t * rad_per_s));
}
table->Modified();
// Update the X axis.
auto axis = chart->GetAxis(vtkAxis::BOTTOM);
float t_min = dt;
float t_max = dt + (num_points * time_step);
axis->SetRange(t_min, t_max);
axis->Modified();
// Render and process events.
view->GetRenderWindow()->Render();
view->GetInteractor()->ProcessEvents();
}
return EXIT_SUCCESS;
}