/*========================================================================= medInria Copyright (c) INRIA 2013 - 2020. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "vtkTensorManager.h" #include #include vtkStandardNewMacro(vtkTensorManager) vtkTensorManager::vtkTensorManager() { this->RenderWindowInteractor = nullptr; this->Input = nullptr; this->Renderer = nullptr; this->TensorVisuManagerAxial = vtkTensorVisuManager::New(); this->TensorVisuManagerSagittal = vtkTensorVisuManager::New(); this->TensorVisuManagerCoronal = vtkTensorVisuManager::New(); this->SetSampleRate(2,2,2); this->DirectionMatrix = nullptr; this->PhysicalToVoxelCoordinatesTransformMatrix = vtkMatrix4x4::New(); this->PhysicalToVoxelCoordinatesTransformMatrix->Identity(); for( int i=0; i<3; i++) { this->CurrentPosition[i] = 0; } } vtkTensorManager::~vtkTensorManager() { this->Initialize(); if( this->RenderWindowInteractor ) { this->RenderWindowInteractor->Delete(); } if( this->Input ) { this->Input->Delete(); } this->TensorVisuManagerAxial->Delete(); this->TensorVisuManagerSagittal->Delete(); this->TensorVisuManagerCoronal->Delete(); if (this->DirectionMatrix) this->DirectionMatrix->Delete(); this->PhysicalToVoxelCoordinatesTransformMatrix->Delete(); } void vtkTensorManager::SetRenderWindowInteractor (vtkRenderWindowInteractor* rwin, vtkRenderer* ren) { if( rwin != this->RenderWindowInteractor ) { if( this->RenderWindowInteractor != nullptr ) { this->Initialize(); this->RenderWindowInteractor->UnRegister (this); } this->RenderWindowInteractor = rwin; if( this->RenderWindowInteractor ) { this->RenderWindowInteractor->Register(this); } } if (ren) { this->Renderer = ren; } else if (this->RenderWindowInteractor) { this->RenderWindowInteractor->GetRenderWindow()->GetRenderers()->InitTraversal(); vtkRenderer* first_renderer = this->RenderWindowInteractor->GetRenderWindow()->GetRenderers()->GetNextItem(); int numLayers = this->RenderWindowInteractor->GetRenderWindow()->GetNumberOfLayers(); this->RenderWindowInteractor->GetRenderWindow()->SetNumberOfLayers ( numLayers + 1 ); this->Renderer = vtkRenderer::New(); this->Renderer->SetLayer ( numLayers ); if (first_renderer) this->Renderer->SetActiveCamera ( first_renderer->GetActiveCamera() ); this->RenderWindowInteractor->GetRenderWindow()->AddRenderer ( this->Renderer ); } } void vtkTensorManager::Initialize() { if( this->RenderWindowInteractor ) { if ( this->Renderer ) { this->Renderer->RemoveActor( this->TensorVisuManagerAxial->GetActor() ); this->Renderer->RemoveActor( this->TensorVisuManagerSagittal->GetActor() ); this->Renderer->RemoveActor( this->TensorVisuManagerCoronal->GetActor() ); } } } void vtkTensorManager::Update() { if( !this->Input || !this->RenderWindowInteractor ) { return; } this->Initialize(); int* dims = this->Input->GetDimensions(); int X = this->CurrentPosition[0]; int Y = this->CurrentPosition[1]; int Z = this->CurrentPosition[2]; // clamping X = X>(dims[0]-1)?(dims[0]-1):X; Y = Y>(dims[1]-1)?(dims[1]-1):Y; Z = Z>(dims[2]-1)?(dims[2]-1):Z; // synchronize with VOI this->TensorVisuManagerSagittal->SetVOI (X, X, 0, dims[1]-1, 0, dims[2]-1); this->TensorVisuManagerCoronal ->SetVOI (0, dims[0]-1, Y, Y, 0, dims[2]-1); this->TensorVisuManagerAxial ->SetVOI (0, dims[0]-1, 0, dims[1]-1, Z, Z); // finally set the data this->TensorVisuManagerSagittal->SetInput (this->Input, this->DirectionMatrix); this->TensorVisuManagerAxial->SetInput (this->Input, this->DirectionMatrix); this->TensorVisuManagerCoronal->SetInput (this->Input, this->DirectionMatrix); if ( this->Renderer ) { this->Renderer->AddActor ( this->TensorVisuManagerAxial->GetActor() ); this->Renderer->AddActor ( this->TensorVisuManagerSagittal->GetActor() ); this->Renderer->AddActor ( this->TensorVisuManagerCoronal->GetActor() ); } } void vtkTensorManager::SetDirectionMatrix(vtkMatrix4x4 *mat) { if (!mat) return; vtkSetObjectBodyMacro(DirectionMatrix, vtkMatrix4x4, mat); vtkMatrix4x4::Invert(this->DirectionMatrix, this->PhysicalToVoxelCoordinatesTransformMatrix); } void vtkTensorManager::SetCurrentPosition (const int& X, const int& Y, const int& Z) { if( !this->Input ) { return; } int* dims = this->Input->GetDimensions(); // clamping int XX = X>(dims[0]-1)?(dims[0]-1):X; int YY = Y>(dims[1]-1)?(dims[1]-1):Y; int ZZ = Z>(dims[2]-1)?(dims[2]-1):Z; // synchronize with VOI this->TensorVisuManagerSagittal->SetVOI (XX, XX, 0, dims[1]-1, 0, dims[2]-1); this->TensorVisuManagerCoronal ->SetVOI (0, dims[0]-1, YY, YY, 0, dims[2]-1); this->TensorVisuManagerAxial ->SetVOI (0, dims[0]-1, 0, dims[1]-1, ZZ, ZZ); this->CurrentPosition[0] = X; this->CurrentPosition[1] = Y; this->CurrentPosition[2] = Z; } void vtkTensorManager::SetCurrentPosition (int pos[3]) { this->SetCurrentPosition (pos[0], pos[1], pos[2]); } void vtkTensorManager::SetCurrentPosition (const double& X, const double& Y, const double& Z) { if( !this->Input ) { return; } double *spacing = this->Input->GetSpacing(); double *origin = this->Input->GetOrigin(); double pos[4]={X, Y, Z, 1.0}; this->PhysicalToVoxelCoordinatesTransformMatrix->MultiplyPoint(pos, pos); int vox_pos[3]; for (int i=0; i<3; i++) vox_pos[i] = vtkMath::Round( (pos[i]-origin[i])/spacing[i] ); this->SetCurrentPosition(vox_pos[0], vox_pos[1], vox_pos[2]); } void vtkTensorManager::SetCurrentPosition (const double pos[3]) { this->SetCurrentPosition (pos[0], pos[1], pos[2]); } void vtkTensorManager::ResetPosition() { if( !this->Input ) { return; } int* dims = this->Input->GetDimensions(); int X = (int)(dims[0]/2); int Y = (int)(dims[1]/2); int Z = (int)(dims[2]/2); this->SetCurrentPosition (X,Y,Z); } void vtkTensorManager::SetGlyphShape (int i) { this->TensorVisuManagerAxial ->SetGlyphShape (i); this->TensorVisuManagerSagittal->SetGlyphShape (i); this->TensorVisuManagerCoronal ->SetGlyphShape (i); } void vtkTensorManager::SetGlyphShapeToLine () { this->TensorVisuManagerAxial ->SetGlyphShapeToLine (); this->TensorVisuManagerSagittal->SetGlyphShapeToLine (); this->TensorVisuManagerCoronal ->SetGlyphShapeToLine (); } void vtkTensorManager::SetGlyphShapeToDisk () { this->TensorVisuManagerAxial ->SetGlyphShapeToDisk (); this->TensorVisuManagerSagittal->SetGlyphShapeToDisk (); this->TensorVisuManagerCoronal ->SetGlyphShapeToDisk (); } void vtkTensorManager::SetGlyphShapeToArrow () { this->TensorVisuManagerAxial ->SetGlyphShapeToArrow (); this->TensorVisuManagerSagittal->SetGlyphShapeToArrow (); this->TensorVisuManagerCoronal ->SetGlyphShapeToArrow (); } void vtkTensorManager::SetGlyphShapeToCube () { this->TensorVisuManagerAxial ->SetGlyphShapeToCube (); this->TensorVisuManagerSagittal->SetGlyphShapeToCube (); this->TensorVisuManagerCoronal ->SetGlyphShapeToCube (); } void vtkTensorManager::SetGlyphShapeToCylinder () { this->TensorVisuManagerAxial ->SetGlyphShapeToCylinder (); this->TensorVisuManagerSagittal->SetGlyphShapeToCylinder (); this->TensorVisuManagerCoronal ->SetGlyphShapeToCylinder (); } void vtkTensorManager::SetGlyphShapeToSphere () { this->TensorVisuManagerAxial ->SetGlyphShapeToSphere (); this->TensorVisuManagerSagittal->SetGlyphShapeToSphere (); this->TensorVisuManagerCoronal ->SetGlyphShapeToSphere (); } void vtkTensorManager::SetGlyphShapeToSuperquadric () { this->TensorVisuManagerAxial ->SetGlyphShapeToSuperquadric (); this->TensorVisuManagerSagittal->SetGlyphShapeToSuperquadric (); this->TensorVisuManagerCoronal ->SetGlyphShapeToSuperquadric (); } void vtkTensorManager::SetGlyphScale (const float& f) { this->TensorVisuManagerAxial ->SetGlyphScale (f); this->TensorVisuManagerSagittal->SetGlyphScale (f); this->TensorVisuManagerCoronal ->SetGlyphScale (f); } void vtkTensorManager::SetMaxGlyphSize (const float& f) { this->TensorVisuManagerAxial ->SetMaxGlyphSize (f); this->TensorVisuManagerSagittal->SetMaxGlyphSize (f); this->TensorVisuManagerCoronal ->SetMaxGlyphSize (f); } void vtkTensorManager::SetSampleRate (const int& n1,const int& n2, const int& n3) { this->TensorVisuManagerAxial ->SetSampleRate (n1, n2, n3); this->TensorVisuManagerSagittal->SetSampleRate (n1, n2, n3); this->TensorVisuManagerCoronal ->SetSampleRate (n1, n2, n3); } void vtkTensorManager::SetGlyphResolution (int res) { this->TensorVisuManagerAxial ->SetGlyphResolution (res); this->TensorVisuManagerSagittal->SetGlyphResolution (res); this->TensorVisuManagerCoronal ->SetGlyphResolution (res); } void vtkTensorManager::SetScalarRange (const float& min, const float& max) { this->TensorVisuManagerAxial ->SetScalarRange (min, max); this->TensorVisuManagerSagittal->SetScalarRange (min, max); this->TensorVisuManagerCoronal ->SetScalarRange (min, max); } void vtkTensorManager::SetColorModeToEigenvector (const int& v) { this->TensorVisuManagerAxial ->SetColorModeToEigenvector (v); this->TensorVisuManagerSagittal->SetColorModeToEigenvector (v); this->TensorVisuManagerCoronal ->SetColorModeToEigenvector (v); } void vtkTensorManager::SetColorModeToEigenvalue (const int& v) { this->TensorVisuManagerAxial ->SetColorModeToEigenvalue (v); this->TensorVisuManagerSagittal->SetColorModeToEigenvalue (v); this->TensorVisuManagerCoronal ->SetColorModeToEigenvalue (v); } void vtkTensorManager::SetColorModeToVolume () { this->TensorVisuManagerAxial ->SetColorModeToVolume (); this->TensorVisuManagerSagittal->SetColorModeToVolume (); this->TensorVisuManagerCoronal ->SetColorModeToVolume (); } void vtkTensorManager::SetColorModeToTrace () { this->TensorVisuManagerAxial ->SetColorModeToTrace (); this->TensorVisuManagerSagittal->SetColorModeToTrace (); this->TensorVisuManagerCoronal ->SetColorModeToTrace (); } void vtkTensorManager::SetColorModeToDistanceToIdentity () { this->TensorVisuManagerAxial ->SetColorModeToDistanceToIdentity (); this->TensorVisuManagerSagittal->SetColorModeToDistanceToIdentity (); this->TensorVisuManagerCoronal ->SetColorModeToDistanceToIdentity (); } void vtkTensorManager::SetColorMode (const int& i) { this->TensorVisuManagerAxial ->SetColorMode (i); this->TensorVisuManagerSagittal->SetColorMode (i); this->TensorVisuManagerCoronal ->SetColorMode (i); } void vtkTensorManager::FlipX (bool a) { this->TensorVisuManagerAxial ->FlipX (a); this->TensorVisuManagerSagittal->FlipX (a); this->TensorVisuManagerCoronal ->FlipX (a); } void vtkTensorManager::FlipY (bool a) { this->TensorVisuManagerAxial ->FlipY (a); this->TensorVisuManagerSagittal->FlipY (a); this->TensorVisuManagerCoronal ->FlipY (a); } void vtkTensorManager::FlipZ (bool a) { this->TensorVisuManagerAxial ->FlipZ (a); this->TensorVisuManagerSagittal->FlipZ (a); this->TensorVisuManagerCoronal ->FlipZ (a); } void vtkTensorManager::SetLookupTable (vtkLookupTable* lut) { this->TensorVisuManagerAxial ->SetLookupTable (lut); this->TensorVisuManagerSagittal->SetLookupTable (lut); this->TensorVisuManagerCoronal ->SetLookupTable (lut); } void vtkTensorManager::SetScalars (vtkDataArray* scalars) { this->TensorVisuManagerAxial ->SetScalars (scalars); this->TensorVisuManagerSagittal->SetScalars (scalars); this->TensorVisuManagerCoronal ->SetScalars (scalars); } void vtkTensorManager::SetAxialSliceVisibility (int i) { this->TensorVisuManagerAxial->GetActor ()->SetVisibility (i); } void vtkTensorManager::SetSagittalSliceVisibility (int i) { this->TensorVisuManagerSagittal->GetActor ()->SetVisibility (i); } void vtkTensorManager::SetCoronalSliceVisibility (int i) { this->TensorVisuManagerCoronal->GetActor ()->SetVisibility (i); }