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

ENH: Temporary fix of compilation error after ITK-5.3 update #207

Merged
merged 1 commit into from Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
285 changes: 133 additions & 152 deletions DrrImageComputation/Logic/vtkSlicerDrrImageComputationLogic.cxx

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions DrrImageComputation/Logic/vtkSlicerDrrImageComputationLogic.h
Expand Up @@ -40,7 +40,6 @@ class vtkMRMLScalarVolumeNode;
class vtkMRMLDrrImageComputationNode;
class vtkMRMLRTBeamNode;
class vtkMRMLMarkupsPlaneNode;
class vtkMRMLMarkupsClosedCurveNode;
class vtkMRMLMarkupsFiducialNode;
class vtkMRMLMarkupsLineNode;

Expand All @@ -55,8 +54,8 @@ class VTK_SLICER_DRRIMAGECOMPUTATION_MODULE_LOGIC_EXPORT vtkSlicerDrrImageComput
public vtkSlicerModuleLogic
{
public:
static const char* IMAGER_BOUNDARY_MARKUPS_NODE_NAME; // curve
static const char* IMAGE_WINDOW_MARKUPS_NODE_NAME; // curve
static const char* IMAGER_BOUNDARY_MARKUPS_NODE_NAME; // plane
static const char* IMAGE_WINDOW_MARKUPS_NODE_NAME; // plane
static const char* FIDUCIALS_MARKUPS_NODE_NAME; // fiducial
static const char* NORMAL_VECTOR_MARKUPS_NODE_NAME; // line
static const char* VUP_VECTOR_MARKUPS_NODE_NAME; // line
Expand All @@ -73,7 +72,7 @@ class VTK_SLICER_DRRIMAGECOMPUTATION_MODULE_LOGIC_EXPORT vtkSlicerDrrImageComput
void CreateMarkupsNodes(vtkMRMLDrrImageComputationNode* parameterNode);
/// Update markups nodes using parameter node data
void UpdateMarkupsNodes(vtkMRMLDrrImageComputationNode* parameterNode);
/// Show markups
/// Show/hide markups
void ShowMarkupsNodes(bool toggled = false);

/// Set Planar Image module logic
Expand Down Expand Up @@ -116,9 +115,9 @@ class VTK_SLICER_DRRIMAGECOMPUTATION_MODULE_LOGIC_EXPORT vtkSlicerDrrImageComput
/// Create markups for view up normal vector
vtkMRMLMarkupsLineNode* CreateImagerVUP(vtkMRMLDrrImageComputationNode* node); // vup
/// Create markups for imager boundary
vtkMRMLMarkupsClosedCurveNode* CreateImagerBoundary(vtkMRMLDrrImageComputationNode* node); // Imager == Reciever == Detector
vtkMRMLMarkupsPlaneNode* CreateImagerBoundary(vtkMRMLDrrImageComputationNode* node); // Imager == Reciever == Detector
/// Create markups for image window within imager
vtkMRMLMarkupsClosedCurveNode* CreateImageWindow(vtkMRMLDrrImageComputationNode* node); // subwindow
vtkMRMLMarkupsPlaneNode* CreateImageWindow(vtkMRMLDrrImageComputationNode* node); // subwindow
/// Create fiducial markups: (0,0), Center, etc
vtkMRMLMarkupsFiducialNode* CreateFiducials(vtkMRMLDrrImageComputationNode* node);
/// Setup nodes for calculated DRR image
Expand Down
37 changes: 37 additions & 0 deletions DrrImageComputation/MRML/vtkMRMLDrrImageComputationNode.cxx
Expand Up @@ -32,6 +32,9 @@

#include "vtkMRMLDrrImageComputationNode.h"

// STD include
#include <cstring>

//------------------------------------------------------------------------------
namespace
{
Expand Down Expand Up @@ -82,6 +85,13 @@ vtkMRMLDrrImageComputationNode::vtkMRMLDrrImageComputationNode()

IsocenterImagerDistance = 300.;
HUThresholdBelow = -1000;

// Observe RTBeam node events (like change of transform or geometry)
vtkNew<vtkIntArray> nodeEvents;
nodeEvents->InsertNextValue(vtkCommand::ModifiedEvent);
nodeEvents->InsertNextValue(vtkMRMLRTBeamNode::BeamGeometryModified);
nodeEvents->InsertNextValue(vtkMRMLRTBeamNode::BeamTransformModified);
this->AddNodeReferenceRole(BEAM_REFERENCE_ROLE, nullptr, nodeEvents);
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -252,6 +262,33 @@ void vtkMRMLDrrImageComputationNode::PrintSelf(ostream& os, vtkIndent indent)
vtkMRMLPrintEndMacro();
}

//----------------------------------------------------------------------------
void vtkMRMLDrrImageComputationNode::ProcessMRMLEvents(vtkObject *caller, unsigned long eventID, void *callData)
{
Superclass::ProcessMRMLEvents(caller, eventID, callData);

if (!this->Scene)
{
vtkErrorMacro("ProcessMRMLEvents: Invalid MRML scene");
return;
}
if (this->Scene->IsBatchProcessing())
{
return;
}

// Update the DRR View-Up and normal vectors, if beam geometry or transform was changed
switch (eventID)
{
case vtkMRMLRTBeamNode::BeamGeometryModified:
case vtkMRMLRTBeamNode::BeamTransformModified:
this->Modified();
break;
default:
break;
}
}

//----------------------------------------------------------------------------
vtkMRMLRTBeamNode* vtkMRMLDrrImageComputationNode::GetBeamNode()
{
Expand Down
3 changes: 3 additions & 0 deletions DrrImageComputation/MRML/vtkMRMLDrrImageComputationNode.h
Expand Up @@ -77,6 +77,9 @@ class VTK_SLICER_DRRIMAGECOMPUTATION_MODULE_MRML_EXPORT vtkMRMLDrrImageComputati
void GetRTImagePosition(double position[2]);
void GetIsocenterPositionLPS(double position[3]);

/// Handles events registered in the observer manager
void ProcessMRMLEvents(vtkObject *caller, unsigned long eventID, void *callData) override;

public:
/// Get beam node
vtkMRMLRTBeamNode* GetBeamNode();
Expand Down
58 changes: 3 additions & 55 deletions DrrImageComputation/Testing/Python/DrrImageComputationTest.py
Expand Up @@ -39,8 +39,6 @@ def test_DRRComputationTest_FullTest1(self):
self.assertIsNotNone( slicer.modules.plastimatch_slicer_drr )
self.assertIsNotNone( slicer.modules.drrimagecomputation )

# Main setups
self.TestSection_SetupPathsAndNames()
# Load CT volume
ctVolumeNode = self.TestSection_DownloadCtData()
# Create dummy RTPlan and RTBeam
Expand All @@ -54,63 +52,13 @@ def test_DRRComputationTest_FullTest1(self):

logging.info("Test finished")

#------------------------------------------------------------------------------
def TestSection_SetupPathsAndNames(self):
pass
if not os.access(slicer.app.temporaryPath, os.F_OK):
os.mkdir(slicer.app.temporaryPath)
#
# self.DRR_SelfTestDir = slicer.app.temporaryPath + '/DRR_SelfTestDir'
# if not os.access(self.DRR_SelfTestDir, os.F_OK):
# os.mkdir(self.DRR_SelfTestDir)

self.CT_FileUrl = 'http://slicer.kitware.com/midas3/download/?items=292307,1' # CT-Chest.rnnd
self.CT_FileName = 'CT-Chest.nrrd'
self.CT_FileSize = 42189103

#------------------------------------------------------------------------------
def TestSection_DownloadCtData(self):
# import SampleData
# sampleDataLogic = SampleData.SampleDataLogic()
# ctVolumeNode = sampleDataLogic.downloadCTChest()
# self.assertIsNotNone( ctVolumeNode )
# return ctVolumeNode

try:
import urllib.request, urllib.parse, urllib.error

numOfScalarVolumeNodesBeforeLoad = len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') )

ctVolumeNode = None
downloaded = False
filePath = slicer.app.temporaryPath + '/' + self.CT_FileName
if not os.path.exists(filePath) or os.stat(filePath).st_size != self.CT_FileSize:
if not downloaded:
logging.info('Downloading DRR CT data to folder\n' + slicer.app.temporaryPath + '\n\n It may take a few minutes...')
logging.info('Requesting download from %s...\n' % (self.CT_FileUrl))
newfilePath, httpMsg = urllib.request.urlretrieve(self.CT_FileUrl, filePath)

self.assertTrue( filePath == newfilePath )

if os.stat(filePath).st_size == self.CT_FileSize:
downloaded = True
else:
logging.warning('Wrong filesize: ' + os.stat(filePath).st_size + ' bytes, instead of ' + self.CT_FileSize + ' bytes')
raise Exception("Downloaded CT file has a wrong size!")
else:
downloaded = True
logging.info('DRR CT data has been found in folder ' + slicer.app.temporaryPath)

logging.info("Finished with download test CT data")

if downloaded:
logging.info('Loading %s...' % (os.path.split(filePath)[1]))
ctVolumeNode = slicer.util.loadVolume(filePath)

# Verify that the CT volume has been loaded
self.assertEqual( len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') ), numOfScalarVolumeNodesBeforeLoad + 1 )
import SampleData
sampleDataLogic = SampleData.SampleDataLogic()
ctVolumeNode = sampleDataLogic.downloadCTChest()
self.assertIsNotNone( ctVolumeNode )

return ctVolumeNode

except Exception as e:
Expand Down
Expand Up @@ -289,7 +289,6 @@ void qSlicerDrrImageComputationPlastimatchParametersWidget::onUseExponentialMapp
qCritical() << Q_FUNC_INFO << ": Invalid parameter node";
return;
}

d->ParameterNode->SetExponentialMappingFlag(value);
}

Expand All @@ -303,7 +302,6 @@ void qSlicerDrrImageComputationPlastimatchParametersWidget::onAutoscalePixelsRan
qCritical() << Q_FUNC_INFO << ": Invalid parameter node";
return;
}

d->ParameterNode->SetAutoscaleFlag(value);
}

Expand All @@ -317,8 +315,9 @@ void qSlicerDrrImageComputationPlastimatchParametersWidget::onHUThresholdChanged
qCritical() << Q_FUNC_INFO << ": Invalid parameter node";
return;
}

d->ParameterNode->DisableModifiedEventOn();
d->ParameterNode->SetHUThresholdBelow(static_cast<int>(value));
d->ParameterNode->DisableModifiedEventOff();
}

//-----------------------------------------------------------------------------
Expand All @@ -331,7 +330,6 @@ void qSlicerDrrImageComputationPlastimatchParametersWidget::onInvertIntensityTog
qCritical() << Q_FUNC_INFO << ": Invalid parameter node";
return;
}

d->ParameterNode->SetInvertIntensityFlag(value);
}

Expand Down
20 changes: 11 additions & 9 deletions DrrImageComputation/qSlicerDrrImageComputationModuleWidget.cxx
Expand Up @@ -303,24 +303,26 @@ void qSlicerDrrImageComputationModuleWidget::onRTBeamNodeChanged(vtkMRMLNode* no
// return;
// }

vtkMRMLDrrImageComputationNode* parameterNode = vtkMRMLDrrImageComputationNode::SafeDownCast(d->MRMLNodeComboBox_ParameterSet->currentNode());
if (!parameterNode)
{
qCritical() << Q_FUNC_INFO << ": Invalid parameter node";
return;
}

vtkMRMLRTBeamNode* beamNode = vtkMRMLRTBeamNode::SafeDownCast(node);
if (!beamNode)
{
qCritical() << Q_FUNC_INFO << ": Invalid beam node";
parameterNode->SetAndObserveBeamNode(nullptr); // Disable imager and image markups update, VUP and normal vectors recalculation
return;
}

vtkMRMLRTIonBeamNode* ionBeamNode = vtkMRMLRTIonBeamNode::SafeDownCast(node);
Q_UNUSED(ionBeamNode);

vtkMRMLDrrImageComputationNode* parameterNode = vtkMRMLDrrImageComputationNode::SafeDownCast(d->MRMLNodeComboBox_ParameterSet->currentNode());
if (!parameterNode)
{
qCritical() << Q_FUNC_INFO << ": Invalid parameter node";
return;
}

parameterNode->SetAndObserveBeamNode(beamNode); // Update imager and image markups, DRR arguments in logic
parameterNode->Modified();
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -423,7 +425,7 @@ void qSlicerDrrImageComputationModuleWidget::onEnter()
d->logic()->UpdateNormalAndVupVectors(parameterNode);
}

// Create or update DRR markups nodes
// Create DRR markups nodes
d->logic()->CreateMarkupsNodes(parameterNode);

this->updateWidgetFromMRML();
Expand Down Expand Up @@ -472,7 +474,7 @@ void qSlicerDrrImageComputationModuleWidget::onShowMarkupsToggled(bool toggled)
{
Q_D(qSlicerDrrImageComputationModuleWidget);

// Update imager and image markups, DRR arguments
// Show/hide imager and image markups
d->logic()->ShowMarkupsNodes(toggled);
}

Expand Down
14 changes: 14 additions & 0 deletions PlastimatchPy/Logic/vtkPlmpyDicomSroExport.cxx
Expand Up @@ -27,8 +27,22 @@
#include "vtkOrientedBSplineTransform.h"
#include "vtkOrientedGridTransform.h"

/// This workaround prevents a compilation fail with ITK-5.3
/// Something defines POSIX in preprocessor, and it conflicts
/// with ITK KWSys POSIX enumeration constant
#if (ITK_VERSION_MAJOR == 5) && (ITK_VERSION_MINOR > 2) && defined(POSIX)
#define PLMPOSIX_TMP (POSIX)
#undef POSIX
#endif

// MRML includes
#include <vtkITKTransformConverter.h>

#ifdef PLMPOSIX_TMP
#define POSIX (PLMPOSIX_TMP)
#undef PLMPOSIX_TMP
#endif

#include <vtkMRMLGridTransformNode.h>
#include <vtkMRMLLinearTransformNode.h>
#include <vtkMRMLScalarVolumeNode.h>
Expand Down
15 changes: 15 additions & 0 deletions PlmCommon/PlmCommon.cxx
Expand Up @@ -20,8 +20,23 @@

#include "PlmCommon.h"

/// This workaround prevents a compilation fail with ITK-5.3
/// Something defines POSIX in preprocessor, and it conflicts
/// with ITK KWSys POSIX enumeration constant
#if (ITK_VERSION_MAJOR == 5) && (ITK_VERSION_MINOR > 2) && defined(POSIX)
#define PLMPOSIX_TMP (POSIX)
#undef POSIX
#endif

// MRML includes
#include <vtkMRMLScalarVolumeNode.h>

#ifdef PLMPOSIX_TMP
#define POSIX (PLMPOSIX_TMP)
#undef PLMPOSIX_TMP
#endif

// MRML includes
#include <vtkMRMLModelNode.h>
#include <vtkMRMLScene.h>

Expand Down
4 changes: 2 additions & 2 deletions SuperBuild/External_Plastimatch.cmake
Expand Up @@ -27,13 +27,13 @@ if(NOT DEFINED ${proj}_DIR AND NOT ${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj})

ExternalProject_SetIfNotDefined(
${CMAKE_PROJECT_NAME}_${proj}_GIT_REPOSITORY
"${EP_GIT_PROTOCOL}://github.com/SlicerRt/plastimatch.git"
"${EP_GIT_PROTOCOL}://gitlab.com/MichaelColonel/plastimatch.git"
QUIET
)

ExternalProject_SetIfNotDefined(
${CMAKE_PROJECT_NAME}_${proj}_GIT_TAG
"6307b2193f48724a31c6b735516eeb50abb14b62" # slicerrt-1.9.2-2021.03.03-6307b219
"072f70c30ba3168063be2a8d5edf41fa69bae918" # Temporary fix to prevent compilation error with ITK-5.3
QUIET
)

Expand Down