s195t
December 8, 2023, 3:03am
1
Hi everyone,
I am trying to do a volume rendering of a relatively big cfd case (about 60 mln cells).
Before coding everything in c++, I made some test runs with Paraview and because of the size of the mesh, the only way to have a usable volume rendering was to Resample to Image
and then display the volume.
Within vtk I am struggling to do the same, I can load my results in a vtkRectilinearGrid
, vtkStructuredGrid
or vtkUnstructuredGrid
but afterwards I am struggling to use vtkResampleToImage
and visualize it.
vtkNew<vtkResampleToImage> resample;
resample->SetSamplingDimensions(nx, ny, nz);
resample->AddInputDataObject(rectilinearGrid);
resample->Update();
I get here, but after that I am having a bit of difficulties to render the output of resample
.
I couldn’t find anything similar in the c++ examples, does anybody know what would be the proper way to do it?
Hello,
vtkResampleToImage
outputs a vtkImageData
, so you need something like this:
#include <vtkSmartVolumeMapper.h>
#include <vtkVolumeProperty.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
// Create mapper (visualization parameters)
vtkSmartPointer<vtkSmartVolumeMapper> volumeMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
volumeMapper->SetBlendModeToComposite(); // composite first
volumeMapper->SetInputData( resample->GetOutput() );
//volumeMapper->SetRequestedRenderModeToRayCast();
volumeMapper->Update();
//create a color transfer function
//create a color interpolator object
vtkSmartPointer<vtkColorTransferFunction> ctf = vtkSmartPointer<vtkColorTransferFunction>::New();
ctf->SetColorSpaceToRGB();
double delta = max - min;
ctf->AddRGBPoint(min , 0.000, 0.000, 1.000);
ctf->AddRGBPoint(min + delta * 0.25, 0.000, 1.000, 1.000);
ctf->AddRGBPoint(min + delta * 0.50, 0.000, 1.000, 0.000);
ctf->AddRGBPoint(min + delta * 0.75, 1.000, 1.000, 0.000);
ctf->AddRGBPoint(max , 1.000, 0.000, 0.000);
//create transfer mapping scalar value to opacity so unvalued cells are invisible
//if the user set a no-data value.
vtkSmartPointer<vtkPiecewiseFunction> otf = vtkSmartPointer<vtkPiecewiseFunction>::New();
otf->AddPoint( no_data_value, 0.0 );
otf->AddPoint( min, 1.0 );
otf->AddPoint( max, 1.0 );
//this object instructs VTK on how to render the volume.
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->ShadeOff();
volumeProperty->SetColor(ctf);
volumeProperty->SetScalarOpacity(otf);
//volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
volumeProperty->SetInterpolationType(VTK_NEAREST_INTERPOLATION);
// Finally, pass everything to the vtkVolume (some kind of actor) and pass it to the renderer.
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper( volumeMapper );
volume->SetProperty( volumeProperty );
renderer->AddActor( volume );
Of course this is not the only way to render a volume, but I hope this helps to start up.
best,
PC
1 Like