Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Do not display volume rendering if volume is under non-linear transform #7065

Merged
merged 1 commit into from
Jul 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class vtkMRMLVolumeRenderingDisplayableManager::vtkInternal
vtkWeakPointer<vtkMRMLVolumeRenderingDisplayNode> DisplayNode;
vtkSmartPointer<vtkVolume> VolumeActor;
vtkSmartPointer<vtkMatrix4x4> IJKToWorldMatrix;
bool IJKToWorldLinear{ true };
vtkSmartPointer<vtkImageLuminance> ComputeAlphaChannel;
vtkSmartPointer<vtkImageAppendComponents> MergeAlphaChannelToRGB;
};
Expand Down Expand Up @@ -166,7 +167,7 @@ class vtkMRMLVolumeRenderingDisplayableManager::vtkInternal
// Return with true if pipelines may have changed.
// If node==nullptr then all pipelines are updated.
bool UpdatePipelineTransforms(vtkMRMLVolumeNode *node);
bool GetVolumeTransformToWorld(vtkMRMLVolumeNode* node, vtkMatrix4x4* ijkToWorldMatrix);
bool GetVolumeTransformToWorld(vtkMRMLVolumeNode* node, vtkMatrix4x4* ijkToWorldMatrix, bool& ijkToWorldLinear);

// ROIs
void UpdatePipelineROIs(vtkMRMLVolumeRenderingDisplayNode* displayNode, const Pipeline* pipeline);
Expand Down Expand Up @@ -696,7 +697,7 @@ bool vtkMRMLVolumeRenderingDisplayableManager::vtkInternal::UpdatePipelineTransf
this->UpdateDisplayNodePipeline(pipeline->DisplayNode, pipeline);

// Calculate and apply transform matrix
this->GetVolumeTransformToWorld(currentVolumeNode, pipeline->IJKToWorldMatrix);
this->GetVolumeTransformToWorld(currentVolumeNode, pipeline->IJKToWorldMatrix, pipeline->IJKToWorldLinear);
if (pipeline->DisplayNode->IsA("vtkMRMLCPURayCastVolumeRenderingDisplayNode"))
{
const PipelineCPU* pipelineCpu = dynamic_cast<const PipelineCPU*>(pipeline);
Expand All @@ -721,11 +722,12 @@ bool vtkMRMLVolumeRenderingDisplayableManager::vtkInternal::UpdatePipelineTransf

//---------------------------------------------------------------------------
bool vtkMRMLVolumeRenderingDisplayableManager::vtkInternal::GetVolumeTransformToWorld(
vtkMRMLVolumeNode* volumeNode, vtkMatrix4x4* outputIjkToWorldMatrix)
vtkMRMLVolumeNode* volumeNode, vtkMatrix4x4* outputIjkToWorldMatrix, bool& ijkToWorldLinear)
{
if (volumeNode == nullptr)
{
vtkErrorWithObjectMacro(this->External, "GetVolumeTransformToWorld: Invalid volume node");
ijkToWorldLinear = false;
return false;
}

Expand All @@ -734,6 +736,7 @@ bool vtkMRMLVolumeRenderingDisplayableManager::vtkInternal::GetVolumeTransformTo
if (transformNode == nullptr)
{
volumeNode->GetIJKToRASMatrix(outputIjkToWorldMatrix);
ijkToWorldLinear = true;
return true;
}

Expand All @@ -746,14 +749,17 @@ bool vtkMRMLVolumeRenderingDisplayableManager::vtkInternal::GetVolumeTransformTo
int success = transformNode->GetMatrixTransformToWorld(nodeToWorldMatrix);
if (!success)
{
vtkWarningWithObjectMacro(this->External, "GetVolumeTransformToWorld: Non-linear parent transform found for volume node " << volumeNode->GetName());
vtkWarningWithObjectMacro(this->External, "GetVolumeTransformToWorld: Non-linear parent transform found for volume node ("
<< volumeNode->GetName() << "). Volume rendering will not be displayed. See https://github.com/Slicer/Slicer/issues/6648 for details.");
outputIjkToWorldMatrix->Identity();
ijkToWorldLinear = false;
return false;
}

// Transform world to RAS
vtkMatrix4x4::Multiply4x4(nodeToWorldMatrix, ijkToRasMatrix, outputIjkToWorldMatrix);
outputIjkToWorldMatrix->Modified(); // Needed because Multiply4x4 does not invoke Modified
ijkToWorldLinear = true;

ijkToRasMatrix->Delete();
nodeToWorldMatrix->Delete();
Expand Down Expand Up @@ -804,6 +810,13 @@ void vtkMRMLVolumeRenderingDisplayableManager::vtkInternal::UpdateDisplayNodePip

bool displayNodeVisible = this->IsVisible(displayNode);

if (!pipeline->IJKToWorldLinear)
{
// Currently, volumes that are under a non-linear transform cannot be displayed.
// See details at https://github.com/Slicer/Slicer/issues/6648
displayNodeVisible = false;
}

vtkAlgorithmOutput* imageConnection = volumeNode->GetImageDataConnection();
vtkImageData* imageData = volumeNode->GetImageData();
int numberOfChannels = (imageData == nullptr ? 1 : imageData->GetNumberOfScalarComponents());
Expand Down
Loading