bobcat
bobcat

Reputation: 41

vtk 6.x, Qt: 3D (line, surface, scatter) plotting

I am working on a Qt (4.7.4) project and need to plot data in 2D and 3D coordinate systems. I've been looking into vtk 6.1 because it seems very powerful overall and I will also need to visualize image data at a later point. I basically got 2D plots working but am stuck plotting data in 3D.

Here's what I tried: I'm using the following piece of code that I took from one of vtk's tests ( Charts / Core / Testing / Cxx / TestSurfacePlot.cxx ). The only thing I added is the QVTKWidget that I use in my GUI and its interactor:

QVTKWidget vtkWidget;
vtkNew<vtkChartXYZ> chart;
vtkNew<vtkPlotSurface> plot;
vtkNew<vtkContextView> view;
view->GetRenderWindow()->SetSize(400, 300);
vtkWidget.SetRenderWindow(view->GetRenderWindow());

view->GetScene()->AddItem(chart.GetPointer());

chart->SetGeometry(vtkRectf(75.0, 20.0, 250, 260));

// Create a surface
vtkNew<vtkTable> table;
float numPoints = 70;
float inc = 9.424778 / (numPoints - 1);
for (float i = 0; i < numPoints; ++i)
{
    vtkNew<vtkFloatArray> arr;
    table->AddColumn(arr.GetPointer());
}
table->SetNumberOfRows(numPoints);
for (float i = 0; i < numPoints; ++i)
{
    float x = i * inc;
    for (float j = 0; j < numPoints; ++j)
    {
        float y  = j * inc;
        table->SetValue(i, j, sin(sqrt(x*x + y*y)));
    }
}

// Set up the surface plot we wish to visualize and add it to the chart.
plot->SetXRange(0, 9.424778);
plot->SetYRange(0, 9.424778);
plot->SetInputData(table.GetPointer());
chart->AddPlot(plot.GetPointer());

view->GetRenderWindow()->SetMultiSamples(0);
view->SetInteractor(vtkWidget.GetInteractor());
view->GetInteractor()->Initialize();
view->GetRenderWindow()->Render();

Now, this produces a plot but I can neither interact with it not does it look 3D. I would like to do some basic stuff like zoom, pan, or rotate about a pivot. A few questions that come to my mind about this are:

Upvotes: 1

Views: 2787

Answers (2)

Steve
Steve

Reputation: 1510

You might want read the detailed description in vtkRenderViewBase

QVTKWidget *widget = new QVTKWidget;
vtkContextView *view = vtkContextView::New();
view->SetInteractor(widget->GetInteractor());
widget->SetRenderWindow(view->GetRenderWindow());

Upvotes: 0

bobcat
bobcat

Reputation: 41

The following piece of code worked for me. No need to explicitly assign an interactor because that's already been taken care of by QVTKWidget.

QVTKWidget vtkWidget;
vtkSmartPointer<vtkContextView> view  = vtkSmartPointer<vtkContextView>::New();
vtkSmartPointer<vtkChartXYZ>    chart = vtkSmartPointer<vtkChartXYZ>::New();

// Create a surface
vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
float numPoints = 70;
float inc = 9.424778 / (numPoints - 1);
for (float i = 0; i < numPoints; ++i)
{
   vtkSmartPointer<vtkFloatArray> arr = vtkSmartPointer<vtkFloatArray>::New();
   table->AddColumn(arr.GetPointer());
}
table->SetNumberOfRows(numPoints);
for (float i = 0; i < numPoints; ++i)
{
    float x = i * inc;
    for (float j = 0; j < numPoints; ++j)
    {
        float y  = j * inc;
        table->SetValue(i, j, sin(sqrt(x*x + y*y)));
    }
}

view->SetRenderWindow(vtkWidget.GetRenderWindow());
chart->SetGeometry(vtkRectf(200.0, 200.0, 300, 300));
view->GetScene()->AddItem(chart.GetPointer());

vtkSmartPointer<vtkPlotSurface> plot = vtkSmartPointer<vtkPlotSurface>::New();

// Set up the surface plot we wish to visualize and add it to the chart.
plot->SetXRange(0, 10.0);
plot->SetYRange(0, 10.0);
plot->SetInputData(table.GetPointer());
chart->AddPlot(plot.GetPointer());

view->GetRenderWindow()->SetMultiSamples(0);
view->GetRenderWindow()->Render();

Upvotes: 1

Related Questions