// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkActor.h" #include "vtkAppendPolyData.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkCellData.h" #include "vtkConeSource.h" #include "vtkImplicitPlaneRepresentation.h" #include "vtkImplicitPlaneWidget2.h" #include "vtkInteractorStyleTrackballCamera.h" #include "vtkLineSource.h" #include "vtkMinimalStandardRandomSequence.h" #include "vtkNamedColors.h" #include "vtkNew.h" #include "vtkPlane.h" #include "vtkPointSource.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkPolyLineSource.h" #include "vtkProperty.h" #include "vtkRegressionTestImage.h" #include "vtkRegularPolygonSource.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkScalarsToColors.h" #include "vtkUnsignedCharArray.h" #include "vtkWidgetRepresentation.h" #include namespace { vtkNew MakePolyLineSource( vtkIdType numPts, bool closed, double offsetX, double offsetY) { vtkNew polylines; polylines->Resize(numPts); polylines->SetClosed(closed); for (vtkIdType i = 0; i < numPts; ++i) { double zigzag = (i % 2); polylines->SetPoint(i, i + offsetX + zigzag, i + offsetY, 0); } return polylines; } void SetupPlaneWidgetCallback( vtkImplicitPlaneWidget2* widget, vtkPlane* plane, double* widgetBounds) { vtkNew onPlaneInteraction; onPlaneInteraction->SetCallback( [](vtkObject* sender, unsigned long, void* clientData, void*) { vtkImplicitPlaneWidget2* planeWidget = vtkImplicitPlaneWidget2::SafeDownCast(sender); vtkImplicitPlaneRepresentation* rep = vtkImplicitPlaneRepresentation::SafeDownCast(planeWidget->GetRepresentation()); rep->GetPlane(reinterpret_cast(clientData)); }); onPlaneInteraction->SetClientData(plane); widget->AddObserver(vtkCommand::InteractionEvent, onPlaneInteraction); auto* rep = vtkImplicitPlaneRepresentation::SafeDownCast(widget->GetRepresentation()); rep->SetPlaceFactor(1.25); rep->PlaceWidget(widgetBounds); rep->SetPlane(plane); widget->On(); } } // namespace int TestPolyDataMapperClipPlanes(int argc, char* argv[]) { vtkNew renWin; renWin->SetWindowName(__func__); renWin->SetMultiSamples(0); vtkNew renderer; renWin->AddRenderer(renderer); vtkNew append; auto polylinesClosed = ::MakePolyLineSource(5, true, 0, 0); append->AddInputConnection(polylinesClosed->GetOutputPort()); auto polylinesOpen = ::MakePolyLineSource(5, false, 6, 0); append->AddInputConnection(polylinesOpen->GetOutputPort()); vtkNew polygon; polygon->SetGeneratePolygon(true); polygon->SetCenter(15, 3, 0); polygon->SetRadius(3); polygon->SetNumberOfSides(12); append->AddInputConnection(polygon->GetOutputPort()); vtkNew lines; lines->SetPoint1(2, 10, 0); lines->SetPoint2(0, 12, 0); append->AddInputConnection(lines->GetOutputPort()); vtkNew points; points->SetNumberOfPoints(20); vtkNew randomSequence; randomSequence->SetSeed(1); points->SetRandomSequence(randomSequence); points->SetCenter(8, 10, 0); points->SetRadius(2); append->AddInputConnection(points->GetOutputPort()); vtkNew cone; cone->SetCenter(15, 10, 0); cone->SetRadius(2); cone->SetHeight(4); append->AddInputConnection(cone->GetOutputPort()); append->Update(); auto* polydata = append->GetOutput(); vtkNew namedColors; std::array colors; colors[0] = namedColors->GetColor4ub("tomato"); colors[1] = namedColors->GetColor4ub("cyan"); colors[2] = namedColors->GetColor4ub("green"); colors[3] = namedColors->GetColor4ub("yellow"); vtkNew colorArray; colorArray->SetName("color"); const vtkIdType numCells = polydata->GetNumberOfCells(); colorArray->SetNumberOfComponents(4); colorArray->SetNumberOfTuples(numCells); // Round-robin assignment of colors for (int i = 0; i < numCells; ++i) { colorArray->SetTypedTuple(i, colors[i % 4].GetData()); } vtkCellData* cd = polydata->GetCellData(); cd->SetScalars(colorArray); vtkNew mapper; mapper->SetInputDataObject(polydata); mapper->ScalarVisibilityOn(); mapper->SetScalarModeToUseCellData(); mapper->SetColorModeToDirectScalars(); vtkNew actor; actor->GetProperty()->SetPointSize(2); actor->GetProperty()->SetLineWidth(2); actor->SetMapper(mapper); renderer->AddActor(actor); renderer->ResetCamera(); vtkNew iren; iren->SetRenderWindow(renWin); vtkNew style; iren->SetInteractorStyle(style); style->SetDefaultRenderer(renderer); renWin->Render(); vtkNew plane1; mapper->AddClippingPlane(plane1); plane1->SetNormal(-0.024947, 0.908778, 0.416534); plane1->SetOrigin(8.58869, 2.77203, 0.258529); vtkNew plane2; mapper->AddClippingPlane(plane2); plane2->SetNormal(-0.1173493, -0.999757, -0.0135635); plane2->SetOrigin(8.60057, 10.4484, 1.47082); vtkNew plane1Widget; plane1Widget->SetInteractor(iren); SetupPlaneWidgetCallback(plane1Widget, plane1, polydata->GetBounds()); vtkNew plane2Widget; plane2Widget->SetInteractor(iren); SetupPlaneWidgetCallback(plane2Widget, plane2, polydata->GetBounds()); const int retVal = vtkRegressionTestImage(renWin); if (retVal == vtkRegressionTester::DO_INTERACTOR) { iren->Start(); } return !retVal; }