From a5f25218ba9fcf8e6b14d22c7c664daf02a87a43 Mon Sep 17 00:00:00 2001 From: Csaba Pinter Date: Tue, 17 Oct 2023 15:42:57 +0100 Subject: [PATCH] ENH: Add option to user to force calculate collisions when flagged as lengthy Re #218 --- .../vtkSlicerRoomsEyeViewModuleLogic.cxx | 20 +++++++------- .../Logic/vtkSlicerRoomsEyeViewModuleLogic.h | 5 +++- .../qSlicerRoomsEyeViewModuleWidget.cxx | 26 ++++++++++++++++--- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx index 74760ded..371fb5ed 100644 --- a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx +++ b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.cxx @@ -534,7 +534,7 @@ vtkSlicerRoomsEyeViewModuleLogic::LoadTreatmentMachine(vtkMRMLRoomsEyeViewNode* //---------------------------------------------------------------------------- std::vector -vtkSlicerRoomsEyeViewModuleLogic::SetupTreatmentMachineModels(vtkMRMLRoomsEyeViewNode* parameterNode) +vtkSlicerRoomsEyeViewModuleLogic::SetupTreatmentMachineModels(vtkMRMLRoomsEyeViewNode* parameterNode, bool forceEnableCollisionDetection/*=false*/) { vtkMRMLScene* scene = this->GetMRMLScene(); if (!scene) @@ -649,24 +649,24 @@ vtkSlicerRoomsEyeViewModuleLogic::SetupTreatmentMachineModels(vtkMRMLRoomsEyeVie } // Disable collision detection if product of number of triangles of the two models is above threshold - if (loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[TableTop] > MAX_TRIANGLE_NUMBER_PRODUCT_FOR_COLLISIONS) + if (loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[TableTop] > MAX_TRIANGLE_NUMBER_PRODUCT_FOR_COLLISIONS && !forceEnableCollisionDetection) { - vtkWarningMacro("Collision detection between gantry and table top is disabled due to too many combined triangles (product = " - << loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[TableTop] << ")"); + vtkWarningMacro("Too many combined triangles (product = " << loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[TableTop] + << ") detected between gantry and table top. Collision detection may take a very long time."); this->GantryTableTopCollisionDetection->SetInputData(0, nullptr); this->GantryTableTopCollisionDetection->SetInputData(1, nullptr); } - if (loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[PatientSupport] > MAX_TRIANGLE_NUMBER_PRODUCT_FOR_COLLISIONS) + if (loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[PatientSupport] > MAX_TRIANGLE_NUMBER_PRODUCT_FOR_COLLISIONS && !forceEnableCollisionDetection) { - vtkWarningMacro("Collision detection between gantry and patient support is disabled due to too many combined triangles (product = " - << loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[PatientSupport] << ")"); + vtkWarningMacro("Too many combined triangles (product = " << loadedPartsNumTriangles[Gantry] * loadedPartsNumTriangles[PatientSupport] + << ") detected between gantry and patient support. Collision detection may take a very long time."); this->GantryPatientSupportCollisionDetection->SetInputData(0, nullptr); this->GantryPatientSupportCollisionDetection->SetInputData(1, nullptr); } - if (loadedPartsNumTriangles[Collimator] * loadedPartsNumTriangles[TableTop] > MAX_TRIANGLE_NUMBER_PRODUCT_FOR_COLLISIONS) + if (loadedPartsNumTriangles[Collimator] * loadedPartsNumTriangles[TableTop] > MAX_TRIANGLE_NUMBER_PRODUCT_FOR_COLLISIONS && !forceEnableCollisionDetection) { - vtkWarningMacro("Collision detection between collimator and table top is disabled due to too many combined triangles (product = " - << loadedPartsNumTriangles[Collimator] * loadedPartsNumTriangles[TableTop] << ")"); + vtkWarningMacro("Too many combined triangles (product = " << loadedPartsNumTriangles[Collimator] * loadedPartsNumTriangles[TableTop] + << ") detected between collimator and table top. Collision detection may take a very long time."); this->CollimatorTableTopCollisionDetection->SetInputData(0, nullptr); this->CollimatorTableTopCollisionDetection->SetInputData(1, nullptr); } diff --git a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h index 2c1f1c8a..30bdf346 100644 --- a/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h +++ b/RoomsEyeView/Logic/vtkSlicerRoomsEyeViewModuleLogic.h @@ -81,8 +81,11 @@ class VTK_SLICER_ROOMSEYEVIEW_LOGIC_EXPORT vtkSlicerRoomsEyeViewModuleLogic : /// \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. + /// \param forceEnableCollisionDetection Enable collision detection between parts even if calculation is potentially + /// lengthy absed on the number of triangles of the parts. /// \return List of parts that were successfully set up. - std::vector SetupTreatmentMachineModels(vtkMRMLRoomsEyeViewNode* parameterNode); + std::vector SetupTreatmentMachineModels( + vtkMRMLRoomsEyeViewNode* parameterNode, bool forceEnableCollisionDetection=false); /// Create or get transforms taking part in the IEC logic and additional devices, and build the transform hierarchy void BuildRoomsEyeViewTransformHierarchy(); diff --git a/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx b/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx index 4e41c1a9..60f0d38e 100644 --- a/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx +++ b/RoomsEyeView/qSlicerRoomsEyeViewModuleWidget.cxx @@ -592,7 +592,7 @@ void qSlicerRoomsEyeViewModuleWidget::onLoadTreatmentMachineButtonClicked() // Warn the user if collision detection is disabled for certain part pairs QString disabledCollisionDetectionMessage( - "Collision detection has been disabled for the following part pairs due to high triangle numbers:\n\n"); + tr("Collision detection for the following part pairs may take very long due to high triangle numbers:\n\n")); bool collisionDetectionDisabled = false; if (d->logic()->GetGantryTableTopCollisionDetection()->GetInputData(0) == nullptr) { @@ -609,9 +609,22 @@ void qSlicerRoomsEyeViewModuleWidget::onLoadTreatmentMachineButtonClicked() disabledCollisionDetectionMessage.append("Collimator-TableTop\n"); collisionDetectionDisabled = true; } + disabledCollisionDetectionMessage.append(tr("\nWhat would you like to do?")); if (collisionDetectionDisabled) { - QMessageBox::warning(this, tr("Collision detection disabled"), disabledCollisionDetectionMessage); + ctkMessageBox* existingMachineMsgBox = new ctkMessageBox(this); + existingMachineMsgBox->setWindowTitle(tr("Collision detection might take too long")); + existingMachineMsgBox->setText(disabledCollisionDetectionMessage); + existingMachineMsgBox->addButton(tr("Disable on these part pairs"), QMessageBox::AcceptRole); + existingMachineMsgBox->addButton(tr("Calculate anyway"), QMessageBox::RejectRole); + existingMachineMsgBox->setIcon(QMessageBox::Warning); + existingMachineMsgBox->exec(); + int resultCode = existingMachineMsgBox->buttonRole(existingMachineMsgBox->clickedButton()); + if (resultCode == QMessageBox::RejectRole) + { + // Set up treatment machine models again but make sure collision detection is not disabled between any parts + d->logic()->SetupTreatmentMachineModels(paramNode, true); + } } // Set treatment machine dependent properties //TODO: Use degrees of freedom from JSON @@ -1058,7 +1071,14 @@ void qSlicerRoomsEyeViewModuleWidget::checkForCollisions() } else { - d->CollisionDetectionStatusLabel->setText(QString::fromStdString("No collisions detected")); + QString noCollisionsMessage(tr("No collisions detected")); + if (d->logic()->GetGantryTableTopCollisionDetection()->GetInputData(0) == nullptr + || d->logic()->GetGantryPatientSupportCollisionDetection()->GetInputData(0) == nullptr + || d->logic()->GetCollimatorTableTopCollisionDetection()->GetInputData(0) == nullptr) + { + noCollisionsMessage.append(tr(" (excluding certain parts)")); + } + d->CollisionDetectionStatusLabel->setText(noCollisionsMessage); d->CollisionDetectionStatusLabel->setStyleSheet("color: green"); } }