c++visual-studio-2010vtkparaviewvolume-rendering

VTK - Volume Rendering from a Rectilinear Grid


I'm developing a C++ application that uses VTK for some visualization. I need to read a .vtr file (RectilinearGrid) and render it using VTK volume rendering features.
I tried to do that with Paraview and it was VERY easy, I just had to apply a "IsoVolume" Filter and the result is just what I needed:

vtkRectilinearGrid Volume Rendered with Paraview

The problem is... how do I do that in C++? The IsoVolume Filter belongs to an extension of VTK made by the ParaView guys, so it is not in my libraries and I didn't find a way to import these classes without having linking errors.
Is there an easier way? Is there an alternative to the IsoVolume Filter inside VTK that works with rectilinear grid data?


Solution

  • I figured it out by myself:

    #define vtkp vtkSmartPointer
    
    // Read the file.
    vtkp<vtkXMLRectilinearGridReader> vtrReader = vtkp<vtkXMLRectilinearGridReader>::New();
        vtrReader->SetFileName("../models/my_grid_model.vtr");
        vtrReader->Update();
    vtkp<vtkRectilinearGrid> grid = vtrReader->GetOutput();
    vtkp<vtkDataArray> scalars = grid->GetPointData()->GetArray("temperatures");
    
    // Convert the vtkRectilinearGrid to vtkUnstructuredGrid.
    vtkp<vtkUnstructuredGrid> ugrid = vtkp<vtkUnstructuredGrid>::New();
        vtkp<vtkPoints> points = vtkp<vtkPoints>::New();
            grid->GetPoints(points);
        ugrid->SetPoints(points);
        ugrid->GetPointData()->SetScalars(scalars);
    
    for (unsigned int i = 0; i < grid->GetNumberOfCells(); i++){
        vtkCell* cell = grid->GetCell(i);
        ugrid->InsertNextCell(cell->GetCellType(), cell->GetPointIds());
    }
    
    // Make sure we have only tetrahedra. (may be slow for big data. tip: save the result to a file)
    vtkp<vtkDataSetTriangleFilter> trifilter = vtkp<vtkDataSetTriangleFilter>::New();
        trifilter->SetInputData(ugrid);
    
    // The mapper that renders the volume data.
    vtkp<vtkOpenGLProjectedTetrahedraMapper> volumeMapper = vtkp<vtkOpenGLProjectedTetrahedraMapper>::New();
        volumeMapper->SetInputConnection(trifilter->GetOutputPort());
    
    // Create transfer mapping scalar value to opacity.
    vtkp<vtkPiecewiseFunction> opacityTransferFunction = vtkp<vtkPiecewiseFunction>::New();
        opacityTransferFunction->AddPoint(range[0], 0.05);
        opacityTransferFunction->AddPoint(range[1], 0.5);
    
    // Create transfer mapping scalar value to color.
    vtkp<vtkColorTransferFunction> colorTransferFunction = vtkp<vtkColorTransferFunction>::New();
        colorTransferFunction->AddRGBPoint(range[0], 0.0, 0.0, 1.0);
        colorTransferFunction->AddRGBPoint(range[1], 1.0, 0.0, 0.0);
    
    // The property describes how the data will look.
    vtkp<vtkVolumeProperty> volumeProperty = vtkp<vtkVolumeProperty>::New();
        volumeProperty->SetColor(colorTransferFunction);
        volumeProperty->SetScalarOpacity(opacityTransferFunction);
        volumeProperty->SetScalarOpacityUnitDistance(300);
        volumeProperty->ShadeOff();
    
    // Creation of the volume.
    vtkp<vtkVolume> volume = vtkp<vtkVolume>::New();
        volume->SetMapper(volumeMapper);
        volume->SetProperty(volumeProperty);
    
    // Usual visualization.
    vtkp<vtkRenderer> renderer = vtkp<vtkRenderer>::New();
        renderer->AddVolume(volume);
    vtkp<vtkRenderWindow> window = vtkp<vtkRenderWindow>::New();
        window->Render();
    vtkp<vtkInteractorStyleTrackballCamera> style = vtkp<vtkInteractorStyleTrackballCamera>::New();
    vtkp<vtkRenderWindowInteractor> interactor = vtkRenderWindowInteractor::New();
        interactor->SetRenderWindow(window);
        interactor->SetInteractorStyle(style);
        interactor->Initialize();
        interactor->Start();