I’m stuck trying to slice a vtkCutter through my vtkPolyData object. Normally this is not a problem but for some reason, I’m getting no results from the cutter on datasets where I need to use vtkVertexGlyphFilter on the polydata object. If I do not use a vtkVertexGlyphFilter the polydata object is not displayed in the view.
Here is the shortened code I used for testing. What am I doing wrong?
int main(int argc, char *argv[])
{
string fileName = "c:\\TheFile.ply";
vtkSmartPointer <vtkPLYReader> pvtkPlyReader = vtkSmartPointer <vtkPLYReader>::New();
pvtkPlyReader->SetFileName(fileName.c_str());
vtkSmartPointer < vtkPolyData> polyDataN = pvtkPlyReader->GetOutput();
pvtkPlyReader->Update();
double means[3] = { 0 };
polyDataN->GetCenter(means);
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
camera->SetPosition(0, 0, 4.0 * means[2]);
camera->SetFocalPoint(means[0], means[1], means[2]);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> modelInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
// Create a renderer, render window, and interactor
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkActor> modelActor = vtkSmartPointer<vtkActor>::New();
std::string renderWindowName;
// Create a new polyData structure
vtkSmartPointer<vtkPolyData> pointsPolydata = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPolyData> polyDataNN = vtkSmartPointer<vtkPolyData>::New();
// Set up arrays for the points, vertices and the colours
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
colors->SetNumberOfComponents(3);
colors->SetName("Colors");
//bool useColors = false;
vtkSmartPointer<vtkUnsignedCharArray> pointColours = vtkSmartPointer<vtkUnsignedCharArray>::New();
pointColours = vtkUnsignedCharArray::SafeDownCast(polyDataN->GetPointData()->GetArray(0));
unsigned long nColours = pointColours->GetDataSize();
vtkIdType nPoints = polyDataN->GetNumberOfPoints();
for (int i = 0; i < nPoints; i++)
{
double p[3];
polyDataN->GetPoint(i, p);
unsigned char c[3] = { 0,0,0 };
// Declare a variable to store the index of the point that gets added.
// This behaves just like an unsigned int.
vtkIdType pid[1];
int ncc = i * 3;
c[0] = pointColours->GetValue(ncc);
c[1] = pointColours->GetValue(ncc + 1);
c[2] = pointColours->GetValue(ncc + 2);
colors->InsertNextTypedTuple(c);
pid[0] = points->InsertNextPoint(p[0], p[1], p[2]);
// Create a vertex cell on the point that was just added.
vertices->InsertNextCell(1, pid);
}
pointsPolydata->SetPoints(points);
pointsPolydata->SetVerts(vertices);
pointsPolydata->GetCellData()->SetScalars(colors);
vtkSmartPointer<vtkVertexGlyphFilter> vertexFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
vertexFilter->SetInputData(pointsPolydata);
vertexFilter->Update();
polyDataNN->ShallowCopy(vertexFilter->GetOutput());
polyDataNN->GetPointData()->SetScalars(colors);
mapper->SetInputData(polyDataNN);
modelActor->SetMapper(mapper);
modelActor->GetProperty()->SetPointSize(1);
// Display the result
// The axes are positioned with a user transform
vtkSmartPointer<vtkTransform> axesTransform = vtkSmartPointer<vtkTransform>::New();
axesTransform->Translate(0.0, 0.0, 0.0);
axesTransform->Update();
vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
axes->SetUserTransform(axesTransform);
vtkSmartPointer<vtkOrientationMarkerWidget> widget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
widget->SetOrientationMarker(axes);
renderer->SetBackground(.1, .2, .3);
renderer->SetActiveCamera(camera);
// Add the renderer to the window
renderWindow->AddRenderer(renderer);
modelInteractor->SetRenderWindow(renderWindow);
widget->SetInteractor(modelInteractor);
widget->SetViewport(0.0, 0.0, 0.4, 0.4);
widget->SetEnabled(1);
widget->InteractiveOn();
double center[3] = { 0 };
mapper->GetCenter(center);
double zLevel = center[2];
// Create a plane to cut the model, here it cuts in the XY plane (normal=(0,0,1))
vtkSmartPointer < vtkPlane > cuttingPlane = vtkSmartPointer < vtkPlane >::New();
cuttingPlane->SetOrigin(0, 0, zLevel);
cuttingPlane->SetNormal(0, 0, 1);
// Create cutter
vtkSmartPointer < vtkCutter > planeCutter = vtkSmartPointer < vtkCutter >::New();
planeCutter->SetCutFunction(cuttingPlane);
planeCutter->SetInputData(mapper->GetInput());
planeCutter->Update();
vtkIdType numberOfLines = planeCutter->GetOutput()->GetNumberOfLines(); //<-- this is always 0
vtkSmartPointer < vtkPolyDataMapper > planeCutterMapper = vtkSmartPointer < vtkPolyDataMapper >::New();
planeCutterMapper->SetInputConnection(planeCutter->GetOutputPort());
//planeCutterMapper->SetResolveCoincidentTopologyToPolygonOffset();
planeCutterMapper->Update();
vtkSmartPointer<vtkActor> cutterActor = vtkSmartPointer<vtkActor>::New();
cutterActor->GetProperty()->SetPointSize(2);
vtkNew<vtkNamedColors> color;
cutterActor->GetProperty()->SetColor(color->GetColor3d("Red").GetData());
cutterActor->GetProperty()->SetLineWidth(2);
cutterActor->SetMapper(planeCutterMapper);
renderer->AddActor(cutterActor);
cutterActor->GetProperty()->SetInterpolationToFlat();
renderer->AddActor(modelActor);
modelActor->GetProperty()->SetInterpolationToFlat();
modelInteractor->Initialize();
renderWindow->SetWindowName(renderWindowName.c_str());
// Set trackball mode of interaction
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
modelInteractor->SetInteractorStyle(style);
renderer->ResetCamera();
renderWindow->Render();
modelInteractor->Start();
return EXIT_SUCCESS;
}
Thanks!