diff --git a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx index ea259146..03cdd47b 100644 --- a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx +++ b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx @@ -452,24 +452,25 @@ void vtkSlicerRoomsEyeViewModuleLogic::BuildRoomsEyeViewTransformHierarchy() } //---------------------------------------------------------------------------- -void vtkSlicerRoomsEyeViewModuleLogic::LoadTreatmentMachine(vtkMRMLRoomsEyeViewNode* parameterNode) +std::vector +vtkSlicerRoomsEyeViewModuleLogic::LoadTreatmentMachine(vtkMRMLRoomsEyeViewNode* parameterNode) { vtkMRMLScene* scene = this->GetMRMLScene(); if (!scene) { vtkErrorMacro("LoadTreatmentMachine: Invalid scene"); - return; + return std::vector(); } vtkMRMLSubjectHierarchyNode* shNode = scene->GetSubjectHierarchyNode(); if (!shNode) { vtkErrorMacro("LoadTreatmentMachine: Failed to access subject hierarchy node"); - return; + return std::vector(); } if (!parameterNode || !parameterNode->GetTreatmentMachineDescriptorFilePath()) { vtkErrorMacro("LoadTreatmentMachine: Invalid parameter node"); - return; + return std::vector(); } // Make sure the transform hierarchy is in place @@ -484,7 +485,7 @@ void vtkSlicerRoomsEyeViewModuleLogic::LoadTreatmentMachine(vtkMRMLRoomsEyeViewN if (!fp) { vtkErrorMacro("LoadTreatmentMachine: Failed to load treatment machine descriptor file '" << descriptorFilePath << "'"); - return; + return std::vector(); } char buffer[4096]; rapidjson::FileReadStream fs(fp, buffer, sizeof(buffer)); @@ -492,7 +493,7 @@ void vtkSlicerRoomsEyeViewModuleLogic::LoadTreatmentMachine(vtkMRMLRoomsEyeViewN { vtkErrorMacro("LoadTreatmentMachine: Failed to load treatment machine descriptor file '" << descriptorFilePath << "'"); fclose(fp); - return; + return std::vector(); } fclose(fp); @@ -521,19 +522,21 @@ void vtkSlicerRoomsEyeViewModuleLogic::LoadTreatmentMachine(vtkMRMLRoomsEyeViewN this->Internal->EnsureTreatmentMachinePartModelNode(parameterNode, FlatPanel, true); // Setup treatment machine model display and transforms - this->SetupTreatmentMachineModels(parameterNode); + return this->SetupTreatmentMachineModels(parameterNode); } //---------------------------------------------------------------------------- -void vtkSlicerRoomsEyeViewModuleLogic::SetupTreatmentMachineModels(vtkMRMLRoomsEyeViewNode* parameterNode) +std::vector +vtkSlicerRoomsEyeViewModuleLogic::SetupTreatmentMachineModels(vtkMRMLRoomsEyeViewNode* parameterNode) { vtkMRMLScene* scene = this->GetMRMLScene(); if (!scene) { vtkErrorMacro("SetupTreatmentMachineModels: Invalid scene"); - return; + return std::vector(); } + std::vector loadedParts; for (int partIdx=0; partIdxGetTreatmentMachinePartTypeAsString((TreatmentMachinePartType)partIdx); @@ -548,6 +551,8 @@ void vtkSlicerRoomsEyeViewModuleLogic::SetupTreatmentMachineModels(vtkMRMLRoomsE continue; } + loadedParts.push_back((TreatmentMachinePartType)partIdx); + // Set color vtkVector3d partColor(this->GetColorForPartType(partType)); partModel->CreateDefaultDisplayNodes(); @@ -634,17 +639,13 @@ void vtkSlicerRoomsEyeViewModuleLogic::SetupTreatmentMachineModels(vtkMRMLRoomsE //TODO: ApplicatorHolder, ElectronApplicator? } - //TODO: Whole patient (segmentation, CT) will need to be transformed when the table top is transformed - //vtkMRMLLinearTransformNode* patientModelTransforms = vtkMRMLLinearTransformNode::SafeDownCast( - // this->GetMRMLScene()->GetFirstNodeByName("TableTopEccentricRotationToPatientSupportTransform")); - //patientModel->SetAndObserveTransformNodeID(patientModelTransforms->GetID()); - //TODO: Instead of this make the tableTop the fixed part in RAS - // Set identity transform for patient (parent transform is taken into account when getting poly data from segmentation) vtkNew identityTransform; identityTransform->Identity(); this->GantryPatientCollisionDetection->SetTransform(1, vtkLinearTransform::SafeDownCast(identityTransform)); this->CollimatorPatientCollisionDetection->SetTransform(1, vtkLinearTransform::SafeDownCast(identityTransform)); + + return loadedParts; } //---------------------------------------------------------------------------- diff --git a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h index ec4df1a4..a3faec76 100644 --- a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h +++ b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h @@ -77,9 +77,11 @@ class VTK_SLICER_ROOMSEYEVIEW_LOGIC_EXPORT vtkSlicerRoomsEyeViewModuleLogic : public: /// Load and setup components of the treatment machine into the scene based on its description. /// \param parameterNode Parameter node contains the treatment machine descriptor file path. - void LoadTreatmentMachine(vtkMRMLRoomsEyeViewNode* parameterNode); - /// Set up the IEC transforms and model properties on the treatment machine models - void SetupTreatmentMachineModels(vtkMRMLRoomsEyeViewNode* parameterNode); + /// \return List of parts that were successfully set up. + std::vector LoadTreatmentMachine(vtkMRMLRoomsEyeViewNode* parameterNode); + /// Set up the IEC transforms and model properties on the treatment machine models. + /// \return List of parts that were successfully set up. + std::vector SetupTreatmentMachineModels(vtkMRMLRoomsEyeViewNode* parameterNode); /// Create or get transforms taking part in the IEC logic and additional devices, and build the transform hierarchy void BuildRoomsEyeViewTransformHierarchy(); diff --git a/RoomsEyeView/Resources/UI/qSlicerRoomsEyeViewModule.ui b/RoomsEyeView/Resources/UI/qSlicerRoomsEyeViewModule.ui index 0492e88e..23c710fe 100644 --- a/RoomsEyeView/Resources/UI/qSlicerRoomsEyeViewModule.ui +++ b/RoomsEyeView/Resources/UI/qSlicerRoomsEyeViewModule.ui @@ -113,7 +113,7 @@ - + Imaging panel: diff --git a/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx b/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx index 688203e8..2adf28ba 100644 --- a/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx +++ b/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx @@ -359,6 +359,15 @@ void qSlicerRoomsEyeViewModuleWidget::setup() connect(d->SegmentSelectorWidget_PatientBody, SIGNAL(currentNodeChanged(vtkMRMLNode*)), this, SLOT(onPatientBodySegmentationNodeChanged(vtkMRMLNode*))); connect(d->SegmentSelectorWidget_PatientBody, SIGNAL(currentSegmentChanged(QString)), this, SLOT(onPatientBodySegmentChanged(QString))); + // Disable treatment machine geometry controls until a machine is loaded + d->GantryRotationSlider->setEnabled(false); + d->CollimatorRotationSlider->setEnabled(false); + d->PatientSupportRotationSlider->setEnabled(false); + d->VerticalTableTopDisplacementSlider->setEnabled(false); + d->LongitudinalTableTopDisplacementSlider->setEnabled(false); + d->LateralTableTopDisplacementSlider->setEnabled(false); + d->ImagingPanelMovementSlider->setEnabled(false); + //TODO: Hide additional device models section until reinstated d->AdditionalTreatmentModelsCollapsibleButton->setVisible(false); @@ -577,7 +586,8 @@ void qSlicerRoomsEyeViewModuleWidget::onLoadTreatmentMachineButtonClicked() // Load and setup models paramNode->SetTreatmentMachineDescriptorFilePath(descriptorFilePath.toUtf8().constData()); - d->logic()->LoadTreatmentMachine(paramNode); + std::vector loadedParts = + d->logic()->LoadTreatmentMachine(paramNode); // Set treatment machine dependent properties //TODO: Use degrees of freedom from JSON if (!treatmentMachineType.compare("VarianTrueBeamSTx")) @@ -597,6 +607,20 @@ void qSlicerRoomsEyeViewModuleWidget::onLoadTreatmentMachineButtonClicked() qMRMLThreeDView* threeDView = layoutManager->threeDWidget(0)->threeDView(); threeDView->resetCamera(); + // Enable treatment machine geometry controls + d->GantryRotationSlider->setEnabled(true); + d->CollimatorRotationSlider->setEnabled(true); + d->PatientSupportRotationSlider->setEnabled(true); + d->VerticalTableTopDisplacementSlider->setEnabled(true); + d->LongitudinalTableTopDisplacementSlider->setEnabled(true); + d->LateralTableTopDisplacementSlider->setEnabled(true); + d->ImagingPanelMovementSlider->setEnabled(true); + + // Hide controls that do not have corresponding parts loaded + bool imagingPanelsLoaded = (std::find(loadedParts.begin(), loadedParts.end(), vtkSlicerRoomsEyeViewModuleLogic::ImagingPanelLeft) != loadedParts.end() || + std::find(loadedParts.begin(), loadedParts.end(), vtkSlicerRoomsEyeViewModuleLogic::ImagingPanelRight) != loadedParts.end()); + d->labelImagingPanel->setVisible(imagingPanelsLoaded); + d->ImagingPanelMovementSlider->setVisible(imagingPanelsLoaded); // Set orientation marker //TODO: Add new option 'Treatment room' to orientation marker choices and merged model with actual colors (surface scalars?)