I am starting from this example and I want to extend it to put multiple lines in a single polydata. My attempt is below. It results in an empty render window, whereas I expect some lines to be visible. What am I doing wrong and how to fix it?
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkNamedColors.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyLine.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
int
main(int, char *[])
{
constexpr unsigned numberOfPoints = 12;
constexpr unsigned numberOfContours = 7;
auto cells = vtkSmartPointer<vtkCellArray>::New();
auto points = vtkSmartPointer<vtkPoints>::New();
points->Allocate(numberOfPoints * numberOfContours);
vtkIdType cpNumber = 0;
for (unsigned k = 0; k < numberOfContours; k++)
{
double point[3];
auto polyLine = vtkSmartPointer<vtkPolyLine>::New();
polyLine->GetPointIds()->SetNumberOfIds(numberOfPoints);
for (vtkIdType i = 0; i < numberOfPoints; i++)
{
point[0] = i;
point[1] = numberOfPoints - i;
point[2] = k;
points->SetPoint(cpNumber, point);
polyLine->GetPointIds()->SetId(i, cpNumber);
++cpNumber;
}
cells->InsertNextCell(polyLine);
}
// Create a polydata to store everything in
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
// Add the points to the dataset
polyData->SetPoints(points);
// Add the lines to the dataset
polyData->SetLines(cells);
// Setup actor and mapper
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(colors->GetColor3d("Tomato").GetData());
// Setup render window, renderer, and interactor
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetWindowName("PolyLine");
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(actor);
renderer->SetBackground(colors->GetColor3d("DarkOliveGreen").GetData());
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
This is how I did in a project in my current job :
struct Something....
{
....
vtkSmartPointer<vtkPoints> Points;
vtkSmartPointer<vtkCellArray> Lines; // stores the lines between points
vtkSmartPointer<vtkPolyData> PolyData;
....
};
PolyData->SetPoints(Points.GetPointer());
PolyData->SetLines(Lines.GetPointer());
// Reset the vtkPoints and vtkCellArray objects and the sum of the lengths
// of the lines between the points associated with the interval.
interval.Points->Reset();
interval.Lines->Reset();
// Insert multi line points into interval.Points
for(vtkIdType i = 0; i < interval.Points->GetNumberOfPoints() - 1; i++)
{
vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();
line->GetPointIds()->SetId(0, i);
line->GetPointIds()->SetId(1, i + 1);
interval.Lines->InsertNextCell(line);
}
Ignore it (remove it, I copied parts from a project so it’s not a clean example, interval is a struct something instance).
In short, you will need a vtkPoints and a vtkCellArray, set them to a vtkPolyData like in the example above.
Add your points to the vtkPoints object in the right order, than create simple lines that will define a (having 2 extremities hence the 0 and 1 values that you can see in SetId and which IDs are vtkPoints’s points IDs).
Let me know, if you want an example of how to color the lines with an array (float for example) and a lookup table.
I never used vtkPolyLine, so I will continue with what I know :
Store ALL your points in a vtkPoints object (M * N points I guess) and call
YourPolyData->SetPoints(YourVTKPointsObject);
We assume that calling YourVTKPointsObject->GetNumberOfPoints(); will return M*N
Create a vtkCellArray object “YourVTKLines” in which you will create your N Lines and call this :
YourPolyData->SetLines(YourVTKLines);
Then iterate on YourVTKPointsObject’s points to create the N Lines points and set their points (define them) - I didn’t really understand what are you trying to do, but hope that helps anyway !