// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-FileCopyrightText: Copyright (c) Sandia Corporation // SPDX-License-Identifier: BSD-3-Clause // This test draws a stick with non-finite values. The topology of the stick is // as follows. // // +---+ INF Red // | | // +---+ 1.0 Red // | | // +---+ 0.5 Green // | | // +---+ NAN Magenta // | | // +---+ 0.5 Green // | | // +---+ 0.0 Blue // | | // +---+ -INF Blue // // These values are mapped to the spectrum colors from blue (low) to red (high). // -INF should be blue, INF should be red. Since these are near extrema, // whatever interpolation used should be constant. NAN should be drawn as // magenta. The interpolation to NAN is ill defined in a texture map. I would // expect a sharp transition to the NAN color, but that might depend on graphics // hardware. #include "vtkActor.h" #include "vtkCellArray.h" #include "vtkColorTransferFunction.h" #include "vtkDiscretizableColorTransferFunction.h" #include "vtkDoubleArray.h" #include "vtkLogLookupTable.h" #include "vtkLookupTable.h" #include "vtkMath.h" #include "vtkPointData.h" #include "vtkPoints.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkRegressionTestImage.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkSmartPointer.h" #define VTK_CREATE(type, var) vtkSmartPointer var = vtkSmartPointer::New() // Create the data described above. static vtkSmartPointer CreateData() { constexpr int cellsHigh = 6; constexpr int pointsHigh = cellsHigh + 1; const double pointValues[pointsHigh] = { vtkMath::NegInf(), 0.0, 0.5, vtkMath::Nan(), 0.5, 1.0, vtkMath::Inf() }; VTK_CREATE(vtkPolyData, polyData); VTK_CREATE(vtkPoints, points); for (int y = 0; y < pointsHigh; y++) { for (int x = 0; x < 2; x++) { points->InsertNextPoint(static_cast(x), static_cast(y), 0.0); } } polyData->SetPoints(points); VTK_CREATE(vtkCellArray, cells); for (int c = 0; c < cellsHigh; c++) { cells->InsertNextCell(4); cells->InsertCellPoint(2 * c); cells->InsertCellPoint(2 * c + 1); cells->InsertCellPoint(2 * c + 3); cells->InsertCellPoint(2 * c + 2); } polyData->SetPolys(cells); VTK_CREATE(vtkDoubleArray, scalars); for (int height = 0; height < pointsHigh; height++) { scalars->InsertNextTuple1(pointValues[height]); scalars->InsertNextTuple1(pointValues[height]); } polyData->GetPointData()->SetScalars(scalars); return polyData; } static vtkSmartPointer CreateLookupTable() { VTK_CREATE(vtkLookupTable, lut); lut->SetRampToLinear(); lut->SetScaleToLinear(); lut->SetTableRange(0.0, 1.0); lut->SetHueRange(0.6, 0.0); lut->SetNanColor(1.0, 0.0, 1.0, 1.0); return lut; } static vtkSmartPointer CreateLogLookupTable() { VTK_CREATE(vtkLogLookupTable, lut); lut->SetRampToLinear(); lut->SetScaleToLinear(); lut->SetTableRange(0.0, 1.0); lut->SetHueRange(0.6, 0.0); lut->SetNanColor(1.0, 0.0, 1.0, 1.0); return lut; } static vtkSmartPointer CreateColorTransferFunction() { VTK_CREATE(vtkColorTransferFunction, ctf); ctf->SetColorSpaceToHSV(); ctf->HSVWrapOff(); ctf->AddHSVSegment(0.0, 0.6, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0); ctf->SetNanColor(1.0, 0.0, 1.0); return ctf; } static vtkSmartPointer CreateDiscretizableColorTransferFunction() { VTK_CREATE(vtkDiscretizableColorTransferFunction, ctf); ctf->DiscretizeOn(); ctf->SetColorSpaceToHSV(); ctf->HSVWrapOff(); ctf->AddHSVSegment(0.0, 0.6, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0); ctf->SetNanColor(1.0, 0.0, 1.0); ctf->Build(); return ctf; } static vtkSmartPointer CreateRenderer( vtkPolyData* input, vtkScalarsToColors* lut, int interpolate) { VTK_CREATE(vtkPolyDataMapper, mapper); mapper->SetInputData(input); mapper->SetLookupTable(lut); mapper->SetInterpolateScalarsBeforeMapping(interpolate); VTK_CREATE(vtkActor, actor); actor->SetMapper(mapper); VTK_CREATE(vtkRenderer, renderer); renderer->AddActor(actor); renderer->ResetCamera(); return renderer; } constexpr int NUM_RENDERERS = 8; static void AddRenderer(vtkRenderer* renderer, vtkRenderWindow* renwin) { static int rencount = 0; renderer->SetViewport(static_cast(rencount) / NUM_RENDERERS, 0.0, static_cast(rencount + 1) / NUM_RENDERERS, 1.0); renwin->AddRenderer(renderer); rencount++; } int RenderNonFinite(int argc, char* argv[]) { vtkSmartPointer input = CreateData(); VTK_CREATE(vtkRenderWindow, renwin); renwin->SetSize(300, 200); vtkSmartPointer renderer; renderer = CreateRenderer(input, CreateLookupTable(), 0); AddRenderer(renderer, renwin); renderer = CreateRenderer(input, CreateLookupTable(), 1); AddRenderer(renderer, renwin); renderer = CreateRenderer(input, CreateLogLookupTable(), 0); AddRenderer(renderer, renwin); renderer = CreateRenderer(input, CreateLogLookupTable(), 1); AddRenderer(renderer, renwin); renderer = CreateRenderer(input, CreateColorTransferFunction(), 0); AddRenderer(renderer, renwin); renderer = CreateRenderer(input, CreateColorTransferFunction(), 1); AddRenderer(renderer, renwin); renderer = CreateRenderer(input, CreateDiscretizableColorTransferFunction(), 0); AddRenderer(renderer, renwin); renderer = CreateRenderer(input, CreateDiscretizableColorTransferFunction(), 1); AddRenderer(renderer, renwin); renwin->Render(); int retVal = vtkRegressionTestImage(renwin); if (retVal == vtkRegressionTester::DO_INTERACTOR) { VTK_CREATE(vtkRenderWindowInteractor, iren); iren->SetRenderWindow(renwin); iren->Initialize(); iren->Start(); retVal = vtkRegressionTester::PASSED; } return (retVal == vtkRegressionTester::PASSED) ? 0 : 1; }