From 604de038819daf91751ebb4a54f1cbfd7e06e0b9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 30 Apr 2020 07:31:04 -0400 Subject: [PATCH] ENH: Add support for --reference-view, --view-angle and --annotation-file List of Slicer changes: $ git shortlog 08bf6c4218..735a05d8e2 --no-merges Jean-Christophe Fillion-Robin (1): [cell-locator] ENH: Add reference-view/view-angle/annotation-file command line args Fixes #97 --- CHANGES.md | 5 ++ CMakeLists.txt | 2 +- Modules/Scripted/Home/Home.py | 91 ++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 23 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 32bbf62..ea231ba 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ ## Cell Locator 0.1.0 2020-04-30 +Features: + +* Add support for ``--reference-view``, ``--view-angle`` and ``--annotation-file`` + command-line arguments. See [#97](https://github.com/BICCN/cell-locator/issues/97) + Fixes: * Ensure that +x is +P in both slice view and 3D view. See [#101](https://github.com/BICCN/cell-locator/issues/101#issuecomment-615406252) diff --git a/CMakeLists.txt b/CMakeLists.txt index 178888c..9e53841 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ if(NOT DEFINED slicersources_SOURCE_DIR) # Download Slicer sources and set variables slicersources_SOURCE_DIR and slicersources_BINARY_DIR FetchContent_Populate(slicersources GIT_REPOSITORY git://github.com/KitwareMedical/Slicer - GIT_TAG 08bf6c42187801c03c717e12c182138f791554af # cell-locator-v4.11.0-2018-12-19-0dc589ee5 + GIT_TAG 735a05d8e2b806ed29ab64e88b9df42f2f15a2cb # cell-locator-v4.11.0-2018-12-19-0dc589ee5 GIT_PROGRESS 1 ) else() diff --git a/Modules/Scripted/Home/Home.py b/Modules/Scripted/Home/Home.py index eaed326..017a8f1 100644 --- a/Modules/Scripted/Home/Home.py +++ b/Modules/Scripted/Home/Home.py @@ -60,6 +60,13 @@ def __init__(self, parent = None): self.DefaultAnnotationType = 'spline' self.DefaultReferenceView = 'Coronal' + if slicer.app.commandOptions().referenceView: + referenceView = slicer.app.commandOptions().referenceView + if referenceView in ["Axial", "Coronal", "Sagittal"]: + self.DefaultReferenceView = referenceView + else: + logging.error("Invalid value '%s' associated with --reference-view command-line argument. " + "Accepted values are %s" % (referenceView, ", ".join(["Axial", "Coronal", "Sagittal"]))) self.DefaultStepSize = 1 self.DefaultThickness = 50 @@ -92,7 +99,32 @@ def set(self, widget): self._widget_cache[key] = widget def onStartupCompleted(self, *unused): - qt.QTimer.singleShot(0, lambda: self.onSceneEndCloseEvent(slicer.mrmlScene)) + + def postStartupInitialization(): + self.onSceneEndCloseEvent(slicer.mrmlScene) + + if slicer.app.commandOptions().argumentParsed("view-angle"): + viewAngle = slicer.app.commandOptions().viewAngle + + angles = {'Roll': 0, 'Yaw': 0, 'Pitch': 0} + if self.getReferenceView() == "Coronal": + angles['Roll'] = viewAngle - 90 + elif self.getReferenceView() == "Sagittal": + angles['Pitch'] = viewAngle - 90 + elif self.getReferenceView() == "Axial": + angles['Yaw'] = viewAngle - 90 + + for axe in angles: + with SignalBlocker(self.get('%sSliderWidget' % axe)): + self.get('%sSliderWidget' % axe).value = angles[axe] + + self.onViewOrientationChanged() + + annotationFilePath = slicer.app.commandOptions().annotationFilePath + if annotationFilePath: + self.loadAnnotationFile(annotationFilePath) + + qt.QTimer.singleShot(0, lambda: postStartupInitialization()) def isAnnotationSavingRequired(self): shouldSave = (slicer.mrmlScene.GetStorableNodesModifiedSinceReadByClass("vtkMRMLMarkupsSplinesNode") @@ -205,32 +237,47 @@ def onSaveAsAnnotationButtonClicked(self, annotationNode=None, windowTitle=None) def onLoadAnnotationButtonClicked(self): from slicer import app, qSlicerFileDialog + # Save current one + if self.isAnnotationSavingRequired(): + question = "The annotation has been modified. Do you want to save before loading a new one ?" + if slicer.util.confirmYesNoDisplay(question, parent=slicer.util.mainWindow()): + if not self.onSaveAnnotationButtonClicked(): + return + + directory = slicer.app.userSettings().value("LastAnnotationDirectory", qt.QStandardPaths.writableLocation( + qt.QStandardPaths.DocumentsLocation)) + + # Load a new one + properties = { + "defaultFileName": os.path.join(directory, "annotation.json"), + } + loadedNodes = vtk.vtkCollection() + if not app.ioManager().openDialog('MarkupsSplines', qSlicerFileDialog.Read, properties, loadedNodes): + return + + # Get reference to loaded node + assert loadedNodes.GetNumberOfItems() == 1 + newAnnotationNode = loadedNodes.GetItemAsObject(0) + + self.onAnnotationLoaded(newAnnotationNode) + + def loadAnnotationFile(self, filename): + if not os.path.exists(filename): + logging.error( + "Annotation file '%s' associated with --annotation-file command-line argument does not exist" % filename) + return False + success, loadedNode = slicer.util.loadNodeFromFile(filename, 'MarkupsSplines', {}, returnNode=True) + if success: + self.onAnnotationLoaded(loadedNode) + return success + + def onAnnotationLoaded(self, newAnnotationNode): + sliceNode = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeSlice') viewNode = slicer.app.layoutManager().threeDWidget(0).threeDView().mrmlViewNode() cameraNode = slicer.modules.cameras.logic().GetViewActiveCameraNode(viewNode) with NodeModify(cameraNode), NodeModify(sliceNode): - # Save current one - if self.isAnnotationSavingRequired(): - question = "The annotation has been modified. Do you want to save before loading a new one ?" - if slicer.util.confirmYesNoDisplay(question, parent=slicer.util.mainWindow()): - if not self.onSaveAnnotationButtonClicked(): - return - - directory = slicer.app.userSettings().value("LastAnnotationDirectory", qt.QStandardPaths.writableLocation( - qt.QStandardPaths.DocumentsLocation)) - - # Load a new one - properties = { - "defaultFileName": os.path.join(directory, "annotation.json"), - } - loadedNodes = vtk.vtkCollection() - if not app.ioManager().openDialog('MarkupsSplines', qSlicerFileDialog.Read, properties, loadedNodes): - return - - # Get reference to loaded node - assert loadedNodes.GetNumberOfItems() == 1 - newAnnotationNode = loadedNodes.GetItemAsObject(0) newAnnotationNode.SetName("Annotation") directory = os.path.dirname(newAnnotationNode.GetStorageNode().GetFileName())