-
-
Save AOphagen/f09d302320db67168dd9fe7316bd35e5 to your computer and use it in GitHub Desktop.
MultiVolumeRenderWindow - prototypical test of multi volume handling with VTK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created by: A. Ophagen | |
// Created on: 2018-10-25 | |
#define RENDERPIPELINEOUTPUT 0 | |
#include "MultiVolumeRenderWindow.h" | |
#include <vtkNew.h> | |
#include <vtkImageData.h> | |
#include <vtkTrivialProducer.h> | |
#include <vtkColorTransferFunction.h> | |
#include <vtkPiecewiseFunction.h> | |
#include <vtkVolume.h> | |
#include <vtkVolumeProperty.h> | |
#include <vtkRenderWindow.h> | |
#include <vtkRenderer.h> | |
#include <vtkRenderWindowInteractor.h> | |
#include <vtkInteractorStyleTrackballCamera.h> | |
#include <vtkCamera.h> | |
#include <vtkMultiVolume.h> | |
#include <vtkOpenGLGPUVolumeRayCastMapper.h> | |
int main(int , char *[]) | |
{ | |
// Multi volume instance | |
// --------------------- | |
vtkNew<vtkMultiVolume> overlappingVol; | |
vtkNew<vtkOpenGLGPUVolumeRayCastMapper> mapper; | |
mapper->SetUseJittering(0); | |
overlappingVol->SetMapper(mapper); | |
// Create data | |
std::vector< vtkSmartPointer< vtkTrivialProducer > > producers{}; | |
std::vector< vtkSmartPointer< vtkColorTransferFunction > > ctfs{}; | |
std::vector< vtkSmartPointer< vtkPiecewiseFunction > > sofs{}; | |
std::vector< vtkSmartPointer< vtkPiecewiseFunction > > gofs{}; | |
std::vector< vtkSmartPointer< vtkVolume > > volumes{}; | |
// Volume 0 (value 0 - -127, size 128 x 128 x 128) | |
// --------------------------- | |
int index = static_cast< int >( producers.size() ); | |
producers.emplace_back( vtkSmartPointer< vtkTrivialProducer >::New() ); | |
producers.back()->SetOutput( createVtkImage( true, 128, 128, 128 ) ); | |
producers.back()->Update(); | |
ctfs.emplace_back( vtkSmartPointer<vtkColorTransferFunction>::New() ); | |
ctfs.back()->AddRGBPoint( -127, 0.0, 0.0, 0.0 ); | |
ctfs.back()->AddRGBPoint( -63, 1.0, 0.5, 0.3 ); | |
ctfs.back()->AddRGBPoint( 0, 1.0, 1.0, 0.9 ); | |
ctfs.back()->SetColorSpaceToHSV(); | |
sofs.emplace_back( vtkSmartPointer<vtkPiecewiseFunction>::New() ); | |
sofs.back()->AddPoint( -127, 0.0 ); | |
sofs.back()->AddPoint( 0, 1.0 ); | |
// gofs.emplace_back( vtkSmartPointer<vtkPiecewiseFunction>::New() ); | |
// gofs.back()->AddPoint( 0, 1.0 ); | |
// gofs.back()->AddPoint( 100, 1.0 ); | |
volumes.emplace_back( vtkSmartPointer<vtkVolume>::New() ); | |
volumes.back()->GetProperty()->SetColor(ctfs.back()); | |
volumes.back()->GetProperty()->SetScalarOpacity(sofs.back()); | |
// volumes.back()->GetProperty()->SetGradientOpacity(gofs.back()); | |
volumes.back()->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION); | |
// use data for volume 0 | |
mapper->SetInputConnection( index, producers.back()->GetOutputPort()); | |
overlappingVol->SetVolume( volumes.back(), index ); | |
// Volume 1 (value 0 - 63, size 64 x 64 x 64) | |
// --------------------------- | |
index = static_cast< int >( producers.size() ); | |
producers.emplace_back( vtkSmartPointer< vtkTrivialProducer >::New() ); | |
producers.back()->SetOutput( createVtkImage( false, 64, 64, 64 ) ); | |
producers.back()->Update(); | |
ctfs.emplace_back( vtkSmartPointer<vtkColorTransferFunction>::New() ); | |
ctfs.back()->AddRGBPoint( 0, 0.0, 0.0, 0.0 ); | |
ctfs.back()->AddRGBPoint( 15, 0.5, 1.0, 0.3 ); | |
ctfs.back()->AddRGBPoint( 47, 0.5, 1.0, 0.3 ); | |
ctfs.back()->AddRGBPoint( 63, 1.0, 1.0, 0.9 ); | |
ctfs.back()->SetColorSpaceToHSV(); | |
sofs.emplace_back( vtkSmartPointer<vtkPiecewiseFunction>::New() ); | |
sofs.back()->AddPoint( 0, 0.0 ); | |
sofs.back()->AddPoint( 63, 1.0 ); | |
// gofs.emplace_back( vtkSmartPointer<vtkPiecewiseFunction>::New() ); | |
// gofs.back()->AddPoint( 0, 1.0 ); | |
// gofs.back()->AddPoint( 100, 1.0 ); | |
volumes.emplace_back( vtkSmartPointer<vtkVolume>::New() ); | |
volumes.back()->GetProperty()->SetColor(ctfs.back()); | |
volumes.back()->GetProperty()->SetScalarOpacity(sofs.back()); | |
// volumes.back()->GetProperty()->SetGradientOpacity(gofs.back()); | |
volumes.back()->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION); | |
volumes.back()->RotateX( -55. ); | |
volumes.back()->SetPosition( 80., 50., 130. ); | |
// use data for volume 1 | |
mapper->SetInputConnection( index, producers.back()->GetOutputPort()); | |
overlappingVol->SetVolume( volumes.back(), index ); | |
// Volume 2 (value 0 - 127, size 64 x 128 x 64) | |
// ----------------------------- | |
index = static_cast< int >( producers.size() ); | |
producers.emplace_back( vtkSmartPointer< vtkTrivialProducer >::New() ); | |
producers.back()->SetOutput( createVtkImage( false, 64, 128, 64 ) ); | |
producers.back()->Update(); | |
ctfs.emplace_back( vtkSmartPointer<vtkColorTransferFunction>::New() ); | |
ctfs.back()->AddRGBPoint( 0, 1.0, 0.3, 0.2 ); | |
ctfs.back()->AddRGBPoint( 64, 0.3, 0.2, 0.9 ); | |
ctfs.back()->AddRGBPoint( 127, 0.5, 0.6, 1.0 ); | |
sofs.emplace_back( vtkSmartPointer<vtkPiecewiseFunction>::New() ); | |
sofs.back()->AddPoint( 0, 0.3 ); | |
sofs.back()->AddPoint( 127, 0.8 ); | |
// gofs.emplace_back( vtkSmartPointer<vtkPiecewiseFunction>::New() ); | |
// gofs.back()->AddPoint( 0, 1.0 ); | |
// gofs.back()->AddPoint( 100, 1.0 ); | |
volumes.emplace_back( vtkSmartPointer<vtkVolume>::New() ); | |
volumes.back()->GetProperty()->SetColor( ctfs.back() ); | |
volumes.back()->GetProperty()->SetScalarOpacity( sofs.back() ); | |
// volumes.back()->GetProperty()->SetGradientOpacity( gofs.back() ); | |
volumes.back()->GetProperty()->SetInterpolationType( VTK_LINEAR_INTERPOLATION ); | |
volumes.back()->SetPosition( 210., 200., -90. ); | |
volumes.back()->RotateX( 90. ); | |
volumes.back()->RotateY( -95. ); | |
volumes.back()->RotateZ( -5. ); | |
// use data for volume 2 | |
mapper->SetInputConnection( index, producers.back()->GetOutputPort() ); | |
overlappingVol->SetVolume( volumes.back(), index ); | |
// Rendering context | |
vtkNew<vtkRenderWindow> renWin; | |
renWin->SetSize( 512, 512 ); | |
renWin->SetMultiSamples( 0 ); | |
vtkNew<vtkRenderer> ren; | |
renWin->AddRenderer( ren ); | |
ren->SetBackground( 0.0, 0.0, 0.0 ); | |
vtkNew<vtkRenderWindowInteractor> iren; | |
iren->SetRenderWindow( renWin ); | |
#if RENDERPIPELINEOUTPUT | |
std::cout << "RENDERER " << std::endl; | |
std::cout << "======== " << std::endl; | |
ren->PrintSelf( std::cout, vtkIndent() ); | |
std::cout << "MAPPER " << std::endl; | |
std::cout << "====== " << std::endl; | |
mapper->PrintSelf( std::cout, vtkIndent() ); | |
std::cout << "MULTI VOLUME " << std::endl; | |
std::cout << "============ " << std::endl; | |
overlappingVol->PrintSelf( std::cout, vtkIndent() ); | |
for( size_t i = 0; i < volumes.size(); ++i ) | |
{ | |
std::cout << "VOLUME " << i << std::endl; | |
std::cout << "========" << std::endl; | |
volumes.at( i )->PrintSelf( std::cout, vtkIndent() ); | |
vtkImageData* image = vtkImageData::SafeDownCast( producers.at( i )->GetOutputDataObject( 0 ) ); | |
if(image) | |
{ | |
std::cout << "IMAGE DATA " << i << std::endl; | |
std::cout << "============" << std::endl; | |
image->PrintSelf( std::cout, vtkIndent(2) ); | |
} | |
std::cout << "VOLUME PROPERTIES " << i << std::endl; | |
std::cout << "===================" << std::endl; | |
volumes.at( i )->GetProperty()->PrintSelf( std::cout, vtkIndent(2) ); | |
std::cout << "-> COLOR TRANSFER FUNCTION " << i << std::endl; | |
std::cout << " =========================" << std::endl; | |
volumes.at( i )->GetProperty()->GetRGBTransferFunction()->PrintSelf( std::cout, vtkIndent(3) ); | |
std::cout << "-> SCALAR OPACITY " << i << std::endl; | |
std::cout << " ================" << std::endl; | |
volumes.at( i )->GetProperty()->GetScalarOpacity()->PrintSelf( std::cout, vtkIndent(3) ); | |
std::cout << "-> GRADIENT OPACITY " << i << std::endl; | |
std::cout << " ==================" << std::endl; | |
volumes.at( i )->GetProperty()->GetGradientOpacity()->PrintSelf( std::cout, vtkIndent(3) ); | |
} | |
#endif | |
ren->AddVolume(overlappingVol); | |
renWin->Render(); | |
iren->Start(); | |
} | |
vtkSmartPointer<vtkImageData> createVtkImage(bool invert , int x, int y, int z) | |
{ | |
// Create an image data | |
vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New(); | |
// Specify the size of the image data | |
imageData->SetDimensions( x, y, z); | |
imageData->AllocateScalars(VTK_DOUBLE,1); | |
int* dims = imageData->GetDimensions(); | |
// Fill every entry of the image data with "2.0" | |
for (int slice = 0; slice < dims[2]; slice++) | |
{ | |
for (int row = 0; row < dims[1]; row++) | |
{ | |
for (int voxel = 0; voxel < dims[0]; voxel++) | |
{ | |
double value = invert ? -slice : slice; | |
double* pixel = static_cast<double*>( imageData->GetScalarPointer( | |
voxel, row, slice ) ); | |
pixel[0] = value; | |
} | |
} | |
} | |
return imageData; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created by: Angelika Ophagen | |
// Created on: 2018-10-25 | |
#include <vtkSmartPointer.h> | |
class vtkImageData; | |
vtkSmartPointer<vtkImageData> createVtkImage(bool invert, int x = 3, int y = 3, int z = 3 ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment