/*========================================================================= Program: Visualization Toolkit Module: TestGPURayCastTransfer2D.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * Test 2D transfer function support in GPUVolumeRayCastMapper. The transfer * function is created manually using known value/gradient histogram information * of the test data (tooth.hdr). A filter to create these histograms will be * added in the future. */ #include "vtkCamera.h" #include "vtkColorTransferFunction.h" #include "vtkFloatArray.h" #include "vtkGPUVolumeRayCastMapper.h" #include "vtkImageData.h" #include "vtkInteractorStyleTrackballCamera.h" #include "vtkNew.h" #include "vtkNrrdReader.h" #include "vtkPiecewiseFunction.h" #include "vtkPointData.h" #include "vtkRegressionTestImage.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkTestUtilities.h" #include "vtkVolume.h" #include "vtkVolumeProperty.h" typedef vtkSmartPointer Transfer2DPtr; Transfer2DPtr Create2DTransfer() { int bins[2] = { 256, 256 }; Transfer2DPtr image = Transfer2DPtr::New(); image->SetDimensions(bins[0], bins[1], 1); image->AllocateScalars(VTK_FLOAT, 4); vtkFloatArray* arr = vtkFloatArray::SafeDownCast(image->GetPointData()->GetScalars()); // Initialize to zero void* dataPtr = arr->GetVoidPointer(0); memset(dataPtr, 0, bins[0] * bins[1] * 4 * sizeof(float)); // Setting RGBA [1.0, 0,0, 0.05] for a square in the histogram (known) // containing some of the interesting edges (e.g. tooth root). for (int j = 0; j < bins[1]; j++) for (int i = 0; i < bins[0]; i++) { if (i > 130 && i < 190 && j < 50) { double const jFactor = 256.0 / 50; vtkIdType const index = bins[0] * j + i; double const red = static_cast(i) / bins[0]; double const green = jFactor * static_cast(j) / bins[1]; double const blue = jFactor * static_cast(j) / bins[1]; double const alpha = 0.25 * jFactor * static_cast(j) / bins[0]; double color[4] = { red, green, blue, alpha }; arr->SetTuple(index, color); } } return image; } //////////////////////////////////////////////////////////////////////////////// int TestGPURayCastTransfer2D(int argc, char* argv[]) { cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl; // Load data char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/tooth.nhdr"); vtkNew reader; reader->SetFileName(fname); reader->Update(); delete[] fname; vtkNew volumeProperty; volumeProperty->ShadeOn(); volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION); vtkDataArray* arr = reader->GetOutput()->GetPointData()->GetScalars(); double range[2]; arr->GetRange(range); // Prepare 1D Transfer Functions vtkNew ctf; ctf->AddRGBPoint(0, 0.0, 0.0, 0.0); ctf->AddRGBPoint(510, 0.4, 0.4, 1.0); ctf->AddRGBPoint(640, 1.0, 1.0, 1.0); ctf->AddRGBPoint(range[1], 0.9, 0.1, 0.1); vtkNew pf; pf->AddPoint(0, 0.00); pf->AddPoint(510, 0.00); pf->AddPoint(640, 0.5); pf->AddPoint(range[1], 0.4); vtkNew gf; gf->AddPoint(0, 0.0); gf->AddPoint(range[1] / 4.0, 1.0); volumeProperty->SetScalarOpacity(pf); volumeProperty->SetGradientOpacity(gf); volumeProperty->SetColor(ctf); // Prepare 2D Transfer Functions Transfer2DPtr tf2d = Create2DTransfer(); volumeProperty->SetTransferFunction2D(tf2d); volumeProperty->SetTransferFunctionMode(vtkVolumeProperty::TF_2D); // Setup rendering context vtkNew renWin; renWin->SetSize(512, 512); renWin->SetMultiSamples(0); vtkNew ren; renWin->AddRenderer(ren); ren->SetBackground(0.0, 0.0, 0.0); vtkNew mapper; mapper->SetInputConnection(reader->GetOutputPort()); mapper->SetUseJittering(1); vtkNew volume; volume->SetMapper(mapper); volume->SetProperty(volumeProperty); ren->AddVolume(volume); ren->ResetCamera(); ren->GetActiveCamera()->Elevation(-90.0); ren->GetActiveCamera()->Zoom(1.4); // Interactor vtkNew iren; iren->SetRenderWindow(renWin); vtkNew style; iren->SetInteractorStyle(style); renWin->Render(); // Simulate modification of 2D transfer function to test for shader issues tf2d->Modified(); renWin->Render(); int retVal = vtkTesting::Test(argc, argv, renWin, 90); if (retVal == vtkRegressionTester::DO_INTERACTOR) { iren->Start(); } return !((retVal == vtkTesting::PASSED) || (retVal == vtkTesting::DO_INTERACTOR)); }