From ff81fa504b69035be79b8182d0829f400abc8865 Mon Sep 17 00:00:00 2001 From: Andras Lasso Date: Thu, 7 May 2015 14:36:22 -0400 Subject: [PATCH 01/11] Fixed module loading error import string was missing --- PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py | 1 + 1 file changed, 1 insertion(+) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index 2fa0d5f..9e7f5b7 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -3,6 +3,7 @@ from __main__ import vtk, qt, ctk, slicer import time import math +import string class PercutaneousApproachAnalysis: From 995befb58a3eb86a72837eb2d1323f9efcacfa99 Mon Sep 17 00:00:00 2001 From: murakami516 Date: Thu, 7 Jul 2016 13:17:56 +0900 Subject: [PATCH 02/11] deleted parent helpText in line 14 deleted parent helpText in line 14 --- PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index 9e7f5b7..4c7c675 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -12,7 +12,7 @@ def __init__(self, parent): parent.categories = ["IGT"] parent.dependencies = [] parent.contributors = ["Atsushi Yamada (Shiga University of Medical Science),Koichiro Murakami (Shiga University of Medical Science, Japan, SPL), Laurent Chauvin (SPL), Junichi Tokuda (SPL)"] - parent.helpText = string.Template(""" + # parent.helpText = string.Template(""" The Percutaneous Approach Analysis is used to calculate and visualize the accessibility to liver tumor with a percutaneous approach. See the online documentation to know how to use in detail. """).substitute({ 'a':parent.slicerWikiUrl, 'b':slicer.app.majorVersion, 'c':slicer.app.minorVersion }) From 4af13a2b6e817c2b68d5236f7b22d818d45a9319 Mon Sep 17 00:00:00 2001 From: murakami516 Date: Thu, 7 Jul 2016 13:22:23 +0900 Subject: [PATCH 03/11] deleted helpText in line 15 comment out the help text --- .../PercutaneousApproachAnalysis.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index 4c7c675..2aed1a8 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -13,13 +13,13 @@ def __init__(self, parent): parent.dependencies = [] parent.contributors = ["Atsushi Yamada (Shiga University of Medical Science),Koichiro Murakami (Shiga University of Medical Science, Japan, SPL), Laurent Chauvin (SPL), Junichi Tokuda (SPL)"] # parent.helpText = string.Template(""" - The Percutaneous Approach Analysis is used to calculate and visualize the accessibility to liver tumor with a percutaneous approach. - See the online documentation to know how to use in detail. - """).substitute({ 'a':parent.slicerWikiUrl, 'b':slicer.app.majorVersion, 'c':slicer.app.minorVersion }) - parent.acknowledgementText = """ - This work is supported by Bio-Medical Innovation Center and Department of Surgery, Shiga University of Medical Science in Japan. - This work is also supported in part by the NIH (R01CA111288, P01CA067165, P41RR019703, P41EB015898, R01CA124377, R01CA138586, R42CA137886). - """ + # The Percutaneous Approach Analysis is used to calculate and visualize the accessibility to liver tumor with a percutaneous approach. + # See the online documentation to know how to use in detail. + # """).substitute({ 'a':parent.slicerWikiUrl, 'b':slicer.app.majorVersion, 'c':slicer.app.minorVersion }) + parent.acknowledgementText = """ + # This work is supported by Bio-Medical Innovation Center and Department of Surgery, Shiga University of Medical Science in Japan. + # This work is also supported in part by the NIH (R01CA111288, P01CA067165, P41RR019703, P41EB015898, R01CA124377, R01CA138586, R42CA137886). + # """ self.parent = parent # Add this test to the SelfTest module's list for discovery when the module From e5856f9ac10607215f930263ad070a642d5a37c8 Mon Sep 17 00:00:00 2001 From: murakami516 Date: Thu, 7 Jul 2016 13:25:16 +0900 Subject: [PATCH 04/11] recovery --- .../PercutaneousApproachAnalysis.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index 2aed1a8..af80c91 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -17,9 +17,9 @@ def __init__(self, parent): # See the online documentation to know how to use in detail. # """).substitute({ 'a':parent.slicerWikiUrl, 'b':slicer.app.majorVersion, 'c':slicer.app.minorVersion }) parent.acknowledgementText = """ - # This work is supported by Bio-Medical Innovation Center and Department of Surgery, Shiga University of Medical Science in Japan. - # This work is also supported in part by the NIH (R01CA111288, P01CA067165, P41RR019703, P41EB015898, R01CA124377, R01CA138586, R42CA137886). - # """ + This work is supported by Bio-Medical Innovation Center and Department of Surgery, Shiga University of Medical Science in Japan. + This work is also supported in part by the NIH (R01CA111288, P01CA067165, P41RR019703, P41EB015898, R01CA124377, R01CA138586, R42CA137886). + """ self.parent = parent # Add this test to the SelfTest module's list for discovery when the module From 799ee4b6e020720caaa1796c1a611df8f1ab06f2 Mon Sep 17 00:00:00 2001 From: murakami516 Date: Thu, 7 Jul 2016 13:27:09 +0900 Subject: [PATCH 05/11] removed indent in line 18 --- PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index af80c91..4b06761 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -16,7 +16,7 @@ def __init__(self, parent): # The Percutaneous Approach Analysis is used to calculate and visualize the accessibility to liver tumor with a percutaneous approach. # See the online documentation to know how to use in detail. # """).substitute({ 'a':parent.slicerWikiUrl, 'b':slicer.app.majorVersion, 'c':slicer.app.minorVersion }) - parent.acknowledgementText = """ + parent.acknowledgementText = """ This work is supported by Bio-Medical Innovation Center and Department of Surgery, Shiga University of Medical Science in Japan. This work is also supported in part by the NIH (R01CA111288, P01CA067165, P41RR019703, P41EB015898, R01CA124377, R01CA138586, R42CA137886). """ From 19aaa81ed8bc7e51954b81cebad841bb7b09c259 Mon Sep 17 00:00:00 2001 From: murakami516 Date: Thu, 7 Jul 2016 13:39:57 +0900 Subject: [PATCH 06/11] new pic --- .../PercutaneousApproachAnalysis.pyc | Bin 0 -> 42881 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.pyc diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.pyc b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa2beaad9439c31c009128b8a622d6d9aad0d5a7 GIT binary patch literal 42881 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 Date: Tue, 31 May 2016 09:59:30 -0400 Subject: [PATCH 07/11] BUG: Simplify import of Logic/MRML/DisplayableManager python modules Reference wrapped module directly from "slicer" module to adapt to Slicer core change introduced in r25128. --- PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index 4b06761..9e8c370 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -580,7 +580,7 @@ def onCheckAllPaths(self): def onCheckColorMappedSkin(self): skinModel = self.skinModelSelector.currentNode() modelDisplay = skinModel.GetDisplayNode() - scalarSetting = slicer.modulewidget.qMRMLModelDisplayNodeWidget() + scalarSetting = slicer.qMRMLModelDisplayNodeWidget() scalarSetting.setMRMLModelDisplayNode(modelDisplay) displayNode = skinModel.GetModelDisplayNode() displayNode.SetActiveScalarName("Normals") @@ -1136,7 +1136,7 @@ def calcApproachScore(self, point, skinPolyData, obstacleBspTree, skinModelNode= displayNode = skinModelNode.GetModelDisplayNode() displayNode.SetActiveScalarName("Colors") displayNode.SetScalarRange(0.0,20.0) - scalarSetting = slicer.modulewidget.qMRMLModelDisplayNodeWidget() + scalarSetting = slicer.qMRMLModelDisplayNodeWidget() scalarSetting.setMRMLModelDisplayNode(displayNode) scalarSetting.setScalarsVisibility(invisible) From b6d45984f24fe4b074a31405c1a9b8d9365b3764 Mon Sep 17 00:00:00 2001 From: YAMADA ATSUSHI Date: Sun, 17 Jul 2016 18:19:30 +0900 Subject: [PATCH 08/11] edited the authors --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73fe606..e55150a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(PercutaneousApproachAnalysis) #----------------------------------------------------------------------------- set(EXTENSION_HOMEPAGE "http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/PercutaneousApproachAnalysis") set(EXTENSION_CATEGORY "IGT") -set(EXTENSION_CONTRIBUTORS "Koichiro Murakami (Shiga University of Medical Science, Japan, SPL), Laurent Chauvin (SPL), Junichi Tokuda (SPL)") +set(EXTENSION_CONTRIBUTORS "Koichiro Murakami (Shiga University of Medical Science, Japan, SPL), Atsushi Yamada (Shiga University of Medical Science, Japan), Laurent Chauvin (SPL), Junichi Tokuda (SPL)") set(EXTENSION_DESCRIPTION "The Percutaneous Approach Analysis is used to calculate and visualize the accessibility of liver tumor with a percutaneous approach.") set(EXTENSION_ICONURL "http://www.slicer.org/slicerWiki/images/a/ac/PAAlogo-small.png") set(EXTENSION_SCREENSHOTURLS "http://www.slicer.org/slicerWiki/images/4/42/Accessibility_clinical.png") From 59db3ae7be2a33128017056825289558a877b9f0 Mon Sep 17 00:00:00 2001 From: Andras Lasso Date: Wed, 30 Mar 2022 09:53:35 -0400 Subject: [PATCH 09/11] Fix incompatibilies with Slicer-4.13 Some further fixes may be needed in how point scalar display is activated, but at least now there are no more runtime errors reported. --- .../PercutaneousApproachAnalysis.py | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index 9e8c370..f0f1d22 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -509,7 +509,7 @@ def cleanup(self): def pathSliderValueChanged(self,newValue): logic = PercutaneousApproachAnalysisLogic() - self.pathSliderValue = newValue + self.pathSliderValue = int(newValue) self.onePath, self.onePathDistance = logic.makeSinglePath(self.apReceived, self.pathSliderValue) NeedlePathModel().modify(self.onePath, 1, self.VISIBLE, self.red, "pathCandidate", self.singleLine, self.singlePathModel, self.singlePath, self.singlePathPoints) @@ -580,25 +580,20 @@ def onCheckAllPaths(self): def onCheckColorMappedSkin(self): skinModel = self.skinModelSelector.currentNode() modelDisplay = skinModel.GetDisplayNode() - scalarSetting = slicer.qMRMLModelDisplayNodeWidget() - scalarSetting.setMRMLModelDisplayNode(modelDisplay) displayNode = skinModel.GetModelDisplayNode() - displayNode.SetActiveScalarName("Normals") + displayNode.SetActiveScalar('Normals', vtk.vtkAssignAttribute.POINT_DATA) - visible = 1 - invisible = 0 - if self.colorMapCheckBox.checked == True: - scalarSetting.setScalarsVisibility(visible) + displayNode.SetScalarVisibility(True) # Need to reload the skin model after "displayNode.SetActiveScalarName("Normals")" # to display color map correctly - displayNode.SetActiveScalarName("Colors") - scalarSetting.setScalarsVisibility(visible) - + displayNode.SetActiveScalar('Colors', vtk.vtkAssignAttribute.CELL_DATA) + displayNode.SetScalarVisibility(True) + self.coloredSkinModelOpacitySlider.enabled = True else: - scalarSetting.setScalarsVisibility(invisible) + displayNode.SetScalarVisibility(False) self.coloredSkinModelOpacitySlider.enabled = False @@ -772,7 +767,7 @@ def onReloadAndTest(self,moduleName="PercutaneousApproachAnalysis"): evalString = 'globals()["%s"].%sTest()' % (moduleName, moduleName) tester = eval(evalString) tester.runTest() - except Exception, e: + except Exception as e: import traceback traceback.print_exc() qt.QMessageBox.warning(slicer.util.mainWindow(), @@ -1136,9 +1131,7 @@ def calcApproachScore(self, point, skinPolyData, obstacleBspTree, skinModelNode= displayNode = skinModelNode.GetModelDisplayNode() displayNode.SetActiveScalarName("Colors") displayNode.SetScalarRange(0.0,20.0) - scalarSetting = slicer.qMRMLModelDisplayNodeWidget() - scalarSetting.setMRMLModelDisplayNode(displayNode) - scalarSetting.setScalarsVisibility(invisible) + displayNode.SetScalarVisibility(False) return (score, minDistance, minDistancePoint) @@ -1294,19 +1287,16 @@ def modify(self, path, approachablePoints, visibilityParam, color, modelName, li linesIDArray.SetTuple1( 0, linesIDArray.GetNumberOfTuples() - 1 ) lines.SetNumberOfCells(1) - def make(self, path, approachablePoints, visibilityParam, color, modelName, lineType): + def make(self, path, approachablePoints, visibilityParam, color, modelName, polyData): import numpy # Create an array for all approachable points p = numpy.zeros([approachablePoints*2,3]) - p1 = [0.0, 0.0, 0.0] scene = slicer.mrmlScene self.points = vtk.vtkPoints() - polyData = vtk.vtkPolyData() - polyData = lineType polyData.SetPoints(self.points) lines = vtk.vtkCellArray() @@ -1330,12 +1320,7 @@ def make(self, path, approachablePoints, visibilityParam, color, modelName, line lines.SetNumberOfCells(1) # Save all approachable points - p1[0] = linesIDArray.GetTuple1(1) - p1[1] = linesIDArray.GetTuple1(2) - p1[2] = linesIDArray.GetTuple1(3) - - coord = [p1[0], p1[1], p1[2]] - p[pointIndex] = coord + p[pointIndex] = point # Create model node model = slicer.vtkMRMLModelNode() From f3fcdfbef8e7dbd72af9fc69109070e16c1f9bae Mon Sep 17 00:00:00 2001 From: Andras Lasso Date: Thu, 31 Mar 2022 16:59:54 -0400 Subject: [PATCH 10/11] Refactored the entire module Cleaned up and simplified everything. --- .../PercutaneousApproachAnalysis.py | 1035 ++++++----------- 1 file changed, 347 insertions(+), 688 deletions(-) diff --git a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py index f0f1d22..17c739d 100644 --- a/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py +++ b/PercutaneousApproachAnalysis/PercutaneousApproachAnalysis.py @@ -51,6 +51,7 @@ def __init__(self, parent = None): if not parent: self.setup() self.parent.show() + self.logic = PercutaneousApproachAnalysisLogic() def setup(self): # Instantiate and connect widgets ... @@ -122,19 +123,6 @@ def setup(self): self.entryPointsSelector.setMRMLScene( slicer.mrmlScene ) parametersFormLayout.addRow("Output Fiducial List: ", self.entryPointsSelector) - # - # target model (vtkMRMLModelNode) - # - self.targetModelSelector = slicer.qMRMLNodeComboBox() - self.targetModelSelector.nodeTypes = ( ("vtkMRMLModelNode"), "" ) - self.targetModelSelector.addEnabled = False - self.targetModelSelector.removeEnabled = False - self.targetModelSelector.noneEnabled = True - self.targetModelSelector.showHidden = False - self.targetModelSelector.showChildNodeTypes = False - self.targetModelSelector.setMRMLScene( slicer.mrmlScene ) - self.targetModelSelector.setToolTip( "Pick the target model to the algorithm." ) - # # Skin model (vtkMRMLModelNode) # @@ -196,7 +184,6 @@ def setup(self): # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.targetSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) - self.targetModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.obstacleModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.skinModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.entryPointsSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) @@ -301,23 +288,23 @@ def setup(self): # # Maximum Length # - self.maximumLengthSpinBox = qt.QLineEdit() - self.maximumLengthSpinBox.enabled = True - self.maximumLengthSpinBox.maximumWidth = 70 - self.maximumLengthSpinBox.setReadOnly(True) - self.maximumLengthSpinBox.maxLength = 8 + self.maximumLengthEdit = qt.QLineEdit() + self.maximumLengthEdit.enabled = True + self.maximumLengthEdit.maximumWidth = 70 + self.maximumLengthEdit.setReadOnly(True) + self.maximumLengthEdit.maxLength = 8 # # Maximum Length Path # - self.maximumLengthPathSpinBox = qt.QLineEdit() - self.maximumLengthPathSpinBox.enabled = True - self.maximumLengthPathSpinBox.maximumWidth = 70 - self.maximumLengthPathSpinBox.setReadOnly(True) - self.maximumLengthPathSpinBox.maxLength = 8 + self.maximumLengthPathEdit = qt.QLineEdit() + self.maximumLengthPathEdit.enabled = True + self.maximumLengthPathEdit.maximumWidth = 70 + self.maximumLengthPathEdit.setReadOnly(True) + self.maximumLengthPathEdit.maxLength = 8 - outcomesFormLayout.addRow(" Path (No.): ", self.maximumLengthPathSpinBox) - outcomesFormLayout.addRow(" Length (mm): ", self.maximumLengthSpinBox) + outcomesFormLayout.addRow(" Path (No.): ", self.maximumLengthPathEdit) + outcomesFormLayout.addRow(" Length (mm): ", self.maximumLengthEdit) # # Check box for displaying each path @@ -329,23 +316,23 @@ def setup(self): # # Minimum Length # - self.minimumLengthSpinBox = qt.QLineEdit() - self.minimumLengthSpinBox.enabled = True - self.minimumLengthSpinBox.maximumWidth = 70 - self.minimumLengthSpinBox.setReadOnly(True) - self.minimumLengthSpinBox.maxLength = 8 + self.minimumLengthEdit = qt.QLineEdit() + self.minimumLengthEdit.enabled = True + self.minimumLengthEdit.maximumWidth = 70 + self.minimumLengthEdit.setReadOnly(True) + self.minimumLengthEdit.maxLength = 8 # # Minimum Length Path # - self.minimumLengthPathSpinBox = qt.QLineEdit() - self.minimumLengthPathSpinBox.enabled = True - self.minimumLengthPathSpinBox.maximumWidth = 70 - self.minimumLengthPathSpinBox.setReadOnly(True) - self.minimumLengthPathSpinBox.maxLength = 8 + self.minimumLengthPathEdit = qt.QLineEdit() + self.minimumLengthPathEdit.enabled = True + self.minimumLengthPathEdit.maximumWidth = 70 + self.minimumLengthPathEdit.setReadOnly(True) + self.minimumLengthPathEdit.maxLength = 8 - outcomesFormLayout.addRow(" Path (No.): ", self.minimumLengthPathSpinBox) - outcomesFormLayout.addRow(" Length (mm): ", self.minimumLengthSpinBox) + outcomesFormLayout.addRow(" Path (No.): ", self.minimumLengthPathEdit) + outcomesFormLayout.addRow(" Length (mm): ", self.minimumLengthEdit) # # Check box for displaying each path @@ -363,10 +350,11 @@ def setup(self): outcomesFormLayout.addRow(" Path Candidate (No.):", self.pathSlider) # Point slider + self.pointSliderLength = 5000 self.pointSlider = ctk.ctkSliderWidget() self.pointSlider.decimals = 0 - self.pointSlider.maximum = 5000 - self.pointSlider.minimum = -5000 + self.pointSlider.maximum = self.pointSliderLength + self.pointSlider.minimum = -self.pointSliderLength self.pointSlider.enabled = False outcomesFormLayout.addRow(" Point Candidate on the Path:", self.pointSlider) @@ -390,7 +378,7 @@ def setup(self): self.allPathsCheckBox.connect("clicked(bool)", self.onCheckAllPaths) self.colorMapCheckBox.connect("clicked(bool)", self.onCheckColorMappedSkin) self.createPointOnThePathButton.connect('clicked(bool)', self.onCreatePointOnThePathButton) - self.pathSlider.connect('valueChanged(double)', self.pathSliderValueChanged) + self.pathSlider.connect('valueChanged(double)', self.selectedPathIndexChanged) self.pointSlider.connect('valueChanged(double)', self.pointSliderValueChanged) self.allPathsOpacitySlider.connect('valueChanged(double)', self.allPathsOpacitySliderValueChanged) @@ -418,75 +406,25 @@ def setup(self): self.deleteModelsButton.enabled = False cleaningFormLayout.addWidget(self.deleteModelsButton) - # - # Delete Transforms Button - # - self.deleteTransformsButton = qt.QPushButton("Delete the Created Transforms") - self.deleteTransformsButton.toolTip = "Delete Created Transforms" - self.deleteTransformsButton.enabled = False - cleaningFormLayout.addWidget(self.deleteTransformsButton) - self.deleteModelsButton.connect('clicked()', self.onDeleteModelsButton) - self.deleteTransformsButton.connect('clicked()', self.onDeleteTransformsButton) # Add vertical spacer self.layout.addStretch(1) - # Switch to distinguish between a point target and a target model - self.targetSwitch = 0 - - # Create an array for all approachable points - # tempolary solution - self.apReceived = numpy.zeros([10000,3]) - - self.nPointsReceived = 0 - self.nPathReceived = 0 - self.frameSliderValue = 0 - - self.pathSliderValue = 0 - self.pointSliderValue = 0 - - # avoid initializing error for frameSliderValueChanged(self, newValue) function - self.tmpSwitch = 0 - - self.pointMarker = slicer.vtkMRMLModelDisplayNode() - self.pointMarkerTransform = slicer.vtkMRMLLinearTransformNode() - self.virtualMarker = slicer.vtkMRMLModelDisplayNode() - self.virtualMarkerTransform = slicer.vtkMRMLLinearTransformNode() - - self.allPaths = slicer.vtkMRMLModelDisplayNode() - self.candidatePath = slicer.vtkMRMLModelDisplayNode() - - self.pathReceived = numpy.zeros([10000,3]) - - self.markerPosition = numpy.zeros([3]) - self.virtualMarkerPosition = numpy.zeros([3]) - - self.onePathDistance = 0 - self.virtualPathDistance = 0 - - self.distanceDummy = 0; - - # switch - self.ON = 1 - self.OFF = 0 - self.VISIBLE = 1 - self.INVISIBLE = 0 + self.selectedPathIndex = 0 + self.positionAlongSelectedPath = 0 # model variables - self.modelReceived = slicer.vtkMRMLModelNode() - self.singlePathModel = slicer.vtkMRMLModelNode() - self.virtualPathModel = slicer.vtkMRMLModelNode() - self.selectedPathTipModel = slicer.vtkMRMLModelNode() - self.extendedPathTipModel = slicer.vtkMRMLModelNode() - self.longestPathTipModel = slicer.vtkMRMLModelNode() - self.shortestPathTipModel = slicer.vtkMRMLModelNode() - self.plannedEntryPointModel = slicer.vtkMRMLModelNode() - - self.minimumPoint = 0 - self.maximumPoint = 0 - self.minimumDistance = 0 - self.maximumDistance = 0 + self.allPathsModel = None + self.selectedPathModel = None + self.selectedPathTipModel = None + self.extendedPathModel = None + self.extendedPathTipModel = None + self.longestPathModel = None + self.longestPathTipModel = None + self.shortestPathModel = None + self.shortestPathTipModel = None + self.plannedEntryPointModels = [] # line colors self.yellow = [1, 1, 0] @@ -494,67 +432,54 @@ def setup(self): self.green = [0, 1, 0] self.blue = [0, 0, 1] - # line models - self.singlePathPoints = vtk.vtkPoints() - self.allPathsPoints = vtk.vtkPoints() - self.virtualPathPoints = vtk.vtkPoints() - self.allLines = vtk.vtkPolyData() - self.singleLine = vtk.vtkPolyData() - self.extendedLine = vtk.vtkPolyData() - self.longestLine = vtk.vtkPolyData() - self.shortestLine = vtk.vtkPolyData() - def cleanup(self): pass - def pathSliderValueChanged(self,newValue): - logic = PercutaneousApproachAnalysisLogic() - self.pathSliderValue = int(newValue) - - self.onePath, self.onePathDistance = logic.makeSinglePath(self.apReceived, self.pathSliderValue) - NeedlePathModel().modify(self.onePath, 1, self.VISIBLE, self.red, "pathCandidate", self.singleLine, self.singlePathModel, self.singlePath, self.singlePathPoints) + def selectedPathIndexChanged(self,newValue): + + self.selectedPathIndex = int(newValue) + onePath = self.logic.makeSinglePath(self.selectedPathIndex) + self.logic.updatePathModel(self.selectedPathModel, onePath) + self.logic.setSpherePositionAlongPath(self.selectedPathTipModel, self.selectedPathIndex, 0) - self.markerPosition = SphereModel().move(self.apReceived, self.pathSliderValue, 0, self.pointMarkerTransform) - self.virtualMarkerPosition = SphereModel().move(self.apReceived, self.pathSliderValue, self.pointSliderValue, self.virtualMarkerTransform) - - self.virtualPath, self.virtualPathDistance = logic.makeVirtualPath(self.apReceived, self.pathSliderValue, self.virtualMarkerPosition) - NeedlePathModel().modify(self.virtualPath, 1, self.VISIBLE, self.red, "extendedPath", self.extendedLine, self.virtualPathModel, self.virtualPath, self.virtualPathPoints) - - self.lengthOfPathSpinBox.text = round(self.virtualPathDistance + self.onePathDistance,1) + self.pointSliderValueChanged(self.pointSlider.value) def pointSliderValueChanged(self,newValue): - logic = PercutaneousApproachAnalysisLogic() - self.pointSliderValue = newValue + self.positionAlongSelectedPath = newValue / self.pointSliderLength - self.virtualMarkerPosition = SphereModel().move(self.apReceived, self.pathSliderValue, self.pointSliderValue, self.virtualMarkerTransform) - self.virtualPath, self.virtualPathDistance = logic.makeVirtualPath(self.apReceived, self.pathSliderValue, self.virtualMarkerPosition) - NeedlePathModel().modify(self.virtualPath, 1, self.VISIBLE, self.red, "extendedPath", self.extendedLine, self.virtualPathModel, self.virtualPath, self.virtualPathPoints) + self.virtualMarkerPosition = self.logic.setSpherePositionAlongPath(self.extendedPathTipModel, self.selectedPathIndex, self.positionAlongSelectedPath) + virtualPath = self.logic.makeVirtualPath(self.selectedPathIndex, self.virtualMarkerPosition) + self.logic.updatePathModel(self.extendedPathModel, virtualPath) - self.lengthOfPathSpinBox.text = round(self.virtualPathDistance,1) + #import numpy as np + #targetPointPosition = self.logic.paths[self.selectedPathIndex][0] + #skinPointPosition = self.virtualMarkerPosition + #virtualPathLength = np.linalg.norm(skinPointPosition - targetPointPosition) + #self.lengthOfPathSpinBox.text = round(virtualPathLength,1) + self.lengthOfPathSpinBox.text = round(PercutaneousApproachAnalysisLogic.pathLength(virtualPath), 1) def skinModelOpacitySliderValueChanged(self,newValue): - if(self.skinModelSelector.currentNode() != None): - skinModel = self.skinModelSelector.currentNode() - modelDisplay = skinModel.GetDisplayNode() - modelDisplay.SetOpacity(newValue/1000.0) - self.skinModelOpacitySlider.value = newValue - self.coloredSkinModelOpacitySlider.value = newValue + if not self.skinModelSelector.currentNode(): + return + skinModel = self.skinModelSelector.currentNode() + modelDisplay = skinModel.GetDisplayNode() + modelDisplay.SetOpacity(newValue/1000.0) + self.skinModelOpacitySlider.value = newValue + self.coloredSkinModelOpacitySlider.value = newValue def obstacleModelOpacitySliderValueChanged(self,newValue): - if(self.obstacleModelSelector.currentNode() != None): - obstacleModel = self.obstacleModelSelector.currentNode() - modelDisplay = obstacleModel.GetDisplayNode() - modelDisplay.SetOpacity(newValue/1000.0) + if not self.obstacleModelSelector.currentNode(): + return + obstacleModel = self.obstacleModelSelector.currentNode() + modelDisplay = obstacleModel.GetDisplayNode() + modelDisplay.SetOpacity(newValue/1000.0) def allPathsOpacitySliderValueChanged(self,newValue): - self.allPaths.SetOpacity(newValue/1000.0) + self.allPathsMode.GetDisplayNode().SetOpacity(newValue/1000.0) def onSelect(self): if (self.targetSelector.currentNode() != None) and (self.obstacleModelSelector.currentNode() != None) and (self.skinModelSelector.currentNode() != None): self.applyButton.enabled = True - if (self.targetModelSelector.currentNode() != None) and (self.obstacleModelSelector.currentNode() != None) and (self.skinModelSelector.currentNode() != None): - self.applyButton.enabled = True - self.targetSwitch = 1 self.skinModelOpacitySliderValueChanged(self.skinModelOpacitySlider.value) self.obstacleModelOpacitySliderValueChanged(self.obstacleModelOpacitySlider.value) @@ -566,29 +491,28 @@ def onCreatePointOnThePathButton(self): entryPointsNode.SetNthFiducialLabel(n, "SkinEntryPoint") entryPointsNode.SetNthFiducialVisibility(n,1) - self.plannedEntryPointModel, droppedMarker, droppedMarkerTransform = SphereModel().make(self.VISIBLE, self.red, "plannedEntryPoint") - SphereModel().drop(self.virtualMarkerPosition[0], self.virtualMarkerPosition[1], self.virtualMarkerPosition[2], droppedMarkerTransform) + plannedEntryPointModel = self.logic.createSphereModel("plannedEntryPoint", self.red) + PercutaneousApproachAnalysisLogic.setSpherePosition(plannedEntryPointModel, self.virtualMarkerPosition) + self.plannedEntryPointModels.append(plannedEntryPointModel) def onCheckAllPaths(self): - if self.allPathsCheckBox.checked == True: - self.allPaths.SetVisibility(self.ON) - self.allPathsOpacitySlider.enabled = True - else: - self.allPaths.SetVisibility(self.OFF) - self.allPathsOpacitySlider.enabled = False + visible = self.allPathsCheckBox.checked + self.allPathsModel.GetDisplayNode().SetVisibility(visible) + self.allPathsOpacitySlider.enabled = visible def onCheckColorMappedSkin(self): skinModel = self.skinModelSelector.currentNode() modelDisplay = skinModel.GetDisplayNode() displayNode = skinModel.GetModelDisplayNode() - displayNode.SetActiveScalar('Normals', vtk.vtkAssignAttribute.POINT_DATA) + #displayNode.SetActiveScalar('Normals', vtk.vtkAssignAttribute.POINT_DATA) - if self.colorMapCheckBox.checked == True: - displayNode.SetScalarVisibility(True) + if self.colorMapCheckBox.checked: + #displayNode.SetScalarVisibility(True) # Need to reload the skin model after "displayNode.SetActiveScalarName("Normals")" # to display color map correctly - displayNode.SetActiveScalar('Colors', vtk.vtkAssignAttribute.CELL_DATA) + #displayNode.SetActiveScalar('Colors', vtk.vtkAssignAttribute.CELL_DATA) + displayNode.SetActiveScalar("Accessibility", vtk.vtkAssignAttribute.POINT_DATA) displayNode.SetScalarVisibility(True) self.coloredSkinModelOpacitySlider.enabled = True @@ -598,92 +522,67 @@ def onCheckColorMappedSkin(self): def onCheckTheLongestPath(self): - print(self.maximumPoint-1) - if self.maximumLengthPathCheckBox.checked == True: - self.theLongestPath.SetVisibility(self.ON) - self.theLongestPathPointMarker.SetVisibility(self.ON) - else: - self.theLongestPath.SetVisibility(self.OFF) - self.theLongestPathPointMarker.SetVisibility(self.OFF) + visible = self.maximumLengthPathCheckBox.checked + self.longestPathModel.GetDisplayNode().SetVisibility(visible) + self.longestPathTipModel.GetDisplayNode().SetVisibility(visible) def onCheckTheShortestPath(self): - print(self.minimumPoint-1) - if self.minimumLengthPathCheckBox.checked == True: - self.theShortestPath.SetVisibility(self.ON) - self.theShortestPathPointMarker.SetVisibility(self.ON) - else: - self.theShortestPath.SetVisibility(self.OFF) - self.theShortestPathPointMarker.SetVisibility(self.OFF) + visible = self.minimumLengthPathCheckBox.checked + self.shortestPathModel.GetDisplayNode().SetVisibility(visible) + self.shortestPathTipModel.GetDisplayNode().SetVisibility(visible) def onCheckPathCandidate(self): - if self.pathCandidateCheckBox.checked == True: - self.singlePath.SetVisibility(self.ON) - self.pointMarker.SetVisibility(self.ON) - self.virtualPath2.SetVisibility(self.ON) - self.virtualMarker.SetVisibility(self.ON) - self.pointSlider.enabled = True - self.pathSlider.enabled = True - self.createPointOnThePathButton.enabled = True - else: - self.singlePath.SetVisibility(self.OFF) - self.pointMarker.SetVisibility(self.OFF) - self.virtualPath2.SetVisibility(self.OFF) - self.virtualMarker.SetVisibility(self.OFF) - self.pointSlider.enabled = False - self.pathSlider.enabled = False - self.createPointOnThePathButton.enabled = False - + show = self.pathCandidateCheckBox.checked + self.selectedPathModel.GetDisplayNode().SetVisibility(show) + self.selectedPathTipModel.GetDisplayNode().SetVisibility(show) + self.extendedPathModel.GetDisplayNode().SetVisibility(show) + self.extendedPathTipModel.GetDisplayNode().SetVisibility(show) + self.pointSlider.enabled = show + self.pathSlider.enabled = show + self.createPointOnThePathButton.enabled = show + def onApplyButton(self): - logic = PercutaneousApproachAnalysisLogic() print("onApplyButton() is called ") targetPoint = self.targetSelector.currentNode() - targetModel = self.targetModelSelector.currentNode() obstacleModel = self.obstacleModelSelector.currentNode() skinModel = self.skinModelSelector.currentNode() # clean up work space self.onDeleteModelsButton() - self.onDeleteTransformsButton() - # make all paths - self.pathReceived, self.nPathReceived, self.apReceived, self.minimumPoint, self.minimumDistance, self.maximumPoint, self.maximumDistance = logic.makePaths(targetPoint, targetModel, 0, obstacleModel, skinModel) - # display all paths model - self.modelReceived, pReceived, self.allPaths, self.allPathPoints = NeedlePathModel().make(self.pathReceived, self.nPathReceived, self.VISIBLE, self.yellow, "candidatePaths", self.allLines) + # create model to show all paths + self.logic.computePaths(targetPoint, obstacleModel, skinModel) + self.allPathsModel = PercutaneousApproachAnalysisLogic.createPathsModel(self.logic.paths, "candidatePaths", self.yellow) # display sphere model - self.selectedPathTipModel, self.pointMarker, self.pointMarkerTransform = SphereModel().make(self.INVISIBLE, self.red, "selectedPathTip") - self.markerPosition = SphereModel().move(self.apReceived, self.pathSliderValue, self.pointSliderValue, self.pointMarkerTransform) - self.extendedPathTipModel, self.virtualMarker, self.virtualMarkerTransform = SphereModel().make(self.INVISIBLE, self.red, "extendedPathTip") - self.virtualMarkerPosition = SphereModel().move(self.apReceived, self.pathSliderValue, self.pointSliderValue, self.virtualMarkerTransform) + self.selectedPathTipModel = self.logic.createSphereModel("selectedPathTip", self.red, False) + self.logic.setSpherePositionAlongPath(self.selectedPathTipModel, self.selectedPathIndex, self.positionAlongSelectedPath) + self.extendedPathTipModel = self.logic.createSphereModel("extendedPathTip", self.red, False) + self.logic.setSpherePositionAlongPath(self.extendedPathTipModel, self.selectedPathIndex, self.positionAlongSelectedPath) # make and display single path candidate - self.onePath, self.onePathDistance = logic.makeSinglePath(self.apReceived, self.pathSliderValue) - self.singlePathModel, self.singleP, self.singlePath, self.singlePathPoints = NeedlePathModel().make(self.onePath, 2, self.INVISIBLE, self.red, "selectedPath", self.singleLine) - # make and display virtual path candidate - self.virtualPath, self.virtualPathDistance = logic.makeVirtualPath(self.apReceived, self.pathSliderValue, self.virtualMarkerPosition) - self.virtualPathModel, self.virtualP, self.virtualPath2, self.virtualPathPoints = NeedlePathModel().make(self.virtualPath, 2, self.INVISIBLE, self.red, "extendedPath", self.extendedLine) - - self.lengthOfPathSpinBox.text = round(self.virtualPathDistance,1) + selectedPath = self.logic.makeSinglePath(self.selectedPathIndex) + self.selectedPathModel = self.logic.createPathsModel(selectedPath, "selectedPath", self.red, False) + # make and display virtual path candidate + virtualPath = self.logic.makeSinglePath(self.selectedPathIndex) + self.extendedPathModel = self.logic.createPathsModel(virtualPath, "extendedPath", self.red, False) + self.lengthOfPathSpinBox.text = round(PercutaneousApproachAnalysisLogic.pathLength(virtualPath), 1) # make the longest path - self.theLongestPathTmp, self.distanceDummy = logic.makeSinglePath(self.apReceived, self.maximumPoint-1) - # display the longest path - self.theLongestPathModel, self.theLongestPathP, self.theLongestPath, self.points = NeedlePathModel().make(self.theLongestPathTmp, 2, self.INVISIBLE, self.green, "longestPath", self.longestLine) - # make the point marker on the longest path - self.longestPathTipModel, self.theLongestPathPointMarker, self.theLongestPathPointMarkerTransform = SphereModel().make(self.INVISIBLE, self.green, "longestPathTip") - self.theLongestPathPointMarkerPosition = SphereModel().move(self.apReceived, self.maximumPoint-1, 0, self.theLongestPathPointMarkerTransform) + longestPath = self.logic.makeSinglePath(self.logic.longestPathIndex) + self.longestPathModel = self.logic.createPathsModel(longestPath, "longestPath", self.green, False) + self.longestPathTipModel = self.logic.createSphereModel("longestPathTip", self.green, False) + self.logic.setSpherePositionAlongPath(self.longestPathTipModel, self.logic.longestPathIndex, 0) # make the shortest path - self.theShortestPathTmp, self.distanceDummy = logic.makeSinglePath(self.apReceived, self.minimumPoint-1) - # display the shortest path - self.theShortestPathModel, self.theShortestPathP, self.theShortestPath, self.points = NeedlePathModel().make(self.theShortestPathTmp, 2, self.INVISIBLE, self.blue,"shortestPath", self.shortestLine) - # make the point marker on the shortest path - self.shortestPathTipModel, self.theShortestPathPointMarker, self.theShortestPathPointMarkerTransform = SphereModel().make(self.INVISIBLE, self.blue, "shortestPathTip") - self.theShortestPathPointMarkerPosition = SphereModel().move(self.apReceived, self.minimumPoint-1, 0, self.theShortestPathPointMarkerTransform) + shortestPath = self.logic.makeSinglePath(self.logic.shortestPathIndex) + self.shortestPathModel = self.logic.createPathsModel(shortestPath, "shortestPath", self.blue, False) + self.shortestPathTipModel = self.logic.createSphereModel("shortestPathTip", self.blue, False) + self.logic.setSpherePositionAlongPath(self.shortestPathTipModel, self.logic.shortestPathIndex, 0) # update outcomes - self.numbersOfAllpathsSpinBox.text = self.nPathReceived - self.pathSlider.maximum = self.nPathReceived-1 + self.numbersOfAllpathsSpinBox.text = len(self.logic.paths) + self.pathSlider.maximum = len(self.logic.paths) - 1 self.allPathsCheckBox.checked = True self.allPathsCheckBox.enabled = True self.pathCandidateCheckBox.enabled = True @@ -691,24 +590,24 @@ def onApplyButton(self): self.cleaningList.collapsed = False self.allPathsOpacitySlider.enabled = True self.deleteModelsButton.enabled = True - self.deleteTransformsButton.enabled = True - self.allPaths.SetOpacity(6.0/1000.0) + self.allPathsModel.GetDisplayNode().SetOpacity(0.01) self.skinModelOpacitySliderValueChanged(900.0) self.skinModelOpacitySlider.value = 900 # calculate the length of the Path No.1 and display the length - self.pathSliderValueChanged(0) + self.selectedPathIndexChanged(0) - #self.maximumLengthSpinBox.value = self.maximumDistance - self.maximumLengthSpinBox.text = round(self.maximumDistance,1) - self.maximumLengthPathSpinBox.text = self.maximumPoint-1 - self.minimumLengthSpinBox.text = round(self.minimumDistance,1) - self.minimumLengthPathSpinBox.text = self.minimumPoint-1 + self.minimumLengthEdit.text = round(PercutaneousApproachAnalysisLogic.pathLength(self.logic.paths, self.logic.shortestPathIndex),1) + self.minimumLengthPathEdit.text = self.logic.shortestPathIndex + self.maximumLengthEdit.text = round(PercutaneousApproachAnalysisLogic.pathLength(self.logic.paths, self.logic.longestPathIndex),1) + self.maximumLengthPathEdit.text = self.logic.longestPathIndex # make color mapped skin start = time.time() - (score, mind, mindp) = logic.runPointWise(targetPoint, obstacleModel, skinModel) + (score, minimumDistance, minimumDistancePosition) = self.logic.calcApproachScore(targetPoint, obstacleModel, skinModel) + print(f"Accessible Area = {score}") + print(f"Minimum Distance = {minimumDistance}") self.accessibilityScore.text = round(score,1) @@ -774,49 +673,45 @@ def onReloadAndTest(self,moduleName="PercutaneousApproachAnalysis"): "Reload and Test", 'Exception!\n\n' + str(e) + "\n\nSee Python Console for Stack Trace") def onDeleteModelsButton(self): - if self.deleteModelsButton.enabled == True: - # reset all status - self.deleteModelsButton.enabled = False - self.allPathsCheckBox.checked = True - self.allPathsCheckBox.enabled = False - self.colorMapCheckBox.checked = False - - self.onCheckColorMappedSkin() - self.colorMapCheckBox.checked = True - self.colorMapCheckBox.enabled = False - self.pathCandidateCheckBox.checked = False - self.pathCandidateCheckBox.enabled = False - self.pathSlider.enabled = False - self.pointSlider.enabled = False - self.createPointOnThePathButton.enabled = False - self.maximumLengthPathCheckBox.checked = False - self.maximumLengthPathCheckBox.enabled = False - self.minimumLengthPathCheckBox.checked = False - self.minimumLengthPathCheckBox.enabled = False - self.allPathsOpacitySlider.enabled = False - - # delete all models - logic = PercutaneousApproachAnalysisLogic() - logic.removeModel(self.modelReceived) - logic.removeModel(self.singlePathModel) - logic.removeModel(self.virtualPathModel) - logic.removeModel(self.theLongestPathModel) - logic.removeModel(self.theShortestPathModel) - # - logic.removeModel(self.selectedPathTipModel) - logic.removeModel(self.extendedPathTipModel) - logic.removeModel(self.longestPathTipModel) - logic.removeModel(self.shortestPathTipModel) - - def onDeleteTransformsButton(self): - if self.deleteTransformsButton.enabled == True: - self.deleteTransformsButton.enabled = False - # delete all transforms - logic = PercutaneousApproachAnalysisLogic() - logic.removeTransform(self.pointMarkerTransform) - logic.removeTransform(self.virtualMarkerTransform) - logic.removeTransform(self.theLongestPathPointMarkerTransform) - logic.removeTransform(self.theShortestPathPointMarkerTransform) + if not self.deleteModelsButton.enabled: + return + + # reset all status + self.deleteModelsButton.enabled = False + self.allPathsCheckBox.checked = True + self.allPathsCheckBox.enabled = False + self.colorMapCheckBox.checked = False + + self.onCheckColorMappedSkin() + self.colorMapCheckBox.checked = True + self.colorMapCheckBox.enabled = False + self.pathCandidateCheckBox.checked = False + self.pathCandidateCheckBox.enabled = False + self.pathSlider.enabled = False + self.pointSlider.enabled = False + self.createPointOnThePathButton.enabled = False + self.maximumLengthPathCheckBox.checked = False + self.maximumLengthPathCheckBox.enabled = False + self.minimumLengthPathCheckBox.checked = False + self.minimumLengthPathCheckBox.enabled = False + self.allPathsOpacitySlider.enabled = False + + # delete all transforms + self.logic.removeTransform(self.selectedPathTipModel) + self.logic.removeTransform(self.extendedPathTipModel) + self.logic.removeTransform(self.longestPathTipModel) + self.logic.removeTransform(self.shortestPathTipModel) + + # delete all models + self.logic.removeModel(self.allPathsModel) + self.logic.removeModel(self.selectedPathModel) + self.logic.removeModel(self.selectedPathTipModel) + self.logic.removeModel(self.extendedPathModel) + self.logic.removeModel(self.extendedPathTipModel) + self.logic.removeModel(self.shortestPathModel) + self.logic.removeModel(self.longestPathTipModel) + self.logic.removeModel(self.longestPathModel) + self.logic.removeModel(self.shortestPathTipModel) # # PercutaneousApproachAnalysisLogic @@ -830,20 +725,10 @@ class PercutaneousApproachAnalysisLogic: requiring an instance of the Widget """ def __init__(self): - pass - - def hasImageData(self,volumeNode): - """This is a dummy logic method that - returns true if the passed in volume - node has valid image data - """ - if not volumeNode: - print('no volume node') - return False - if volumeNode.GetImageData() == None: - print('no image data') - return False - return True + # List of [targetPoint, skinPoint] pairs + self.paths = [] + self.shortestPathIndex = -1 + self.longestPathIndex = -1 def delayDisplay(self,message,msec=1000): # @@ -860,98 +745,80 @@ def delayDisplay(self,message,msec=1000): def removeModel(self, model): scene = slicer.mrmlScene - scene.RemoveNode(model) - - def removeTransform(self, transform): - scene = slicer.mrmlScene - scene.RemoveNode(transform) + scene.RemoveNode(model) - def makeSinglePath(self, p, pointNumber): - import numpy + def removeTransform(self, transformedNode): + slicer.mrmlScene.RemoveNode(transformedNode.GetParentTransformNode()) - tipPoint = numpy.zeros([2,3]) + @staticmethod + def pathLength(paths, pathIndex=0): + import numpy as np + [targetPoint, skinPoint] = paths[pathIndex] + pathLength = np.linalg.norm(targetPoint - skinPoint) + return pathLength - targetP = [p[pointNumber*2][0], p[pointNumber*2][1], p[pointNumber*2][2]] - skinP = [p[pointNumber*2+1][0], p[pointNumber*2+1][1], p[pointNumber*2+1][2]] + @staticmethod + def updatePathModel(modelNode, paths): + outputPolyData = vtk.vtkPolyData() - tipPoint[0] = targetP - tipPoint[1] = skinP + points = vtk.vtkPoints() + outputPolyData.SetPoints(points) - onePath = [targetP] - onePath.append(skinP) - - distance = numpy.sqrt(numpy.power(p[pointNumber*2]-p[pointNumber*2+1],2).sum()) + lines = vtk.vtkCellArray() + outputPolyData.SetLines(lines) - self.tmpSwitch = 1 + for targetPoint, skinPoint in paths: + pointIndex1 = points.InsertNextPoint(targetPoint) + pointIndex2 = points.InsertNextPoint(skinPoint) + lines.InsertNextCell(2) + lines.InsertCellPoint(pointIndex1) + lines.InsertCellPoint(pointIndex2) - return (onePath, distance) + modelNode.SetAndObservePolyData(outputPolyData) - def makeVirtualPath(self, p, pointNumber, virtualPosition): - import numpy + @staticmethod + def createPathsModel(paths, modelName, color, visibility=True): - tipPoint = numpy.zeros([2,3]) + # Create model node + model = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLModelNode", slicer.mrmlScene.GenerateUniqueName(modelName)) - targetP = [virtualPosition[0], virtualPosition[1], virtualPosition[2]] - skinP = [p[pointNumber*2+1][0], p[pointNumber*2+1][1], p[pointNumber*2+1][2]] + # Create display node + model.CreateDefaultDisplayNodes() + modelDisplay = model.GetDisplayNode() + modelDisplay.SetColor(color[0], color[1], color[2]) + modelDisplay.SetVisibility(visibility) + modelDisplay.SetSliceIntersectionVisibility(True) # Show in slice view - tipPoint[0] = targetP - tipPoint[1] = skinP + PercutaneousApproachAnalysisLogic.updatePathModel(model, paths) - onePath = [targetP] - onePath.append(skinP) + return model - distance = numpy.sqrt(numpy.power(p[pointNumber*2+1]-virtualPosition,2).sum()) + def makeSinglePath(self, pathIndex): + return [self.paths[pathIndex]] - return (onePath, distance) + def makeVirtualPath(self, pathIndex, virtualPosition): + targetP = self.paths[pathIndex][0] + skinP = virtualPosition + return [[targetP, skinP]] - def makePaths(self, targetPointNode, targetModelNode, targetSwitch, obstacleModelNode, skinModelNode): - """ - Run the actual algorithm + def computePaths(self, targetPointNode, obstacleModelNode, skinModelNode): + """ Compute self.paths """ - print ('makePaths() is called') + import numpy as np - import numpy - - # The variable nPoints represents numbers of polygons for skin model - poly = skinModelNode.GetPolyData() - polyDataNormals = vtk.vtkPolyDataNormals() - - if vtk.VTK_MAJOR_VERSION <= 5: - polyDataNormals.SetInput(poly) - else: - polyDataNormals.SetInputData(poly) + targetPoint = np.array(targetPointNode.GetNthControlPointPositionWorld(0)) + skinPolyData = skinModelNode.GetPolyData() + polyDataNormals = vtk.vtkPolyDataNormals() + polyDataNormals.SetInputData(skinPolyData) polyDataNormals.Update() - polyData = polyDataNormals.GetOutput() - nPoints = polyData.GetNumberOfPoints() - nPoints2 = nPoints*2 - - # The variable nPointsT represents numbers of polygons for target model - if targetSwitch == 1: - polyT = targetModelNode.GetPolyData() - polyTDataNormals = vtk.vtkPolyDataNormals() - - if vtk.VTK_MAJOR_VERSION <= 5: - polyTDataNormals.SetInput(polyT) - else: - polyTDataNormals.SetInputData(polyT) + skinPolyData = polyDataNormals.GetOutput() + nSkinPoints = skinPolyData.GetNumberOfPoints() - polyTDataNormals.Update() - polyTData = polyTDataNormals.GetOutput() - nPointsT = polyTData.GetNumberOfPoints() - nPointsT2 = nPointsT*2 - p2 = [0.0, 0.0, 0.0] - else: - nPointsT = 1 - nPointsT2 = nPointsT*2 - tPoint = targetPointNode.GetMarkupPointVector(0, 0) - p2 = [tPoint[0], tPoint[1], tPoint[2]] - - # The variable approachablePoints represents number of approachable polygons on the skin model - approachablePoints = 0 + # Create an array for needle passing points. + # Each element contains a pair of target point and skin point + self.paths = [] - p1=[0.0, 0.0, 0.0] - tolerance = 0.001 t = vtk.mutable(0.0) x = [0.0, 0.0, 0.0] # The coordinate of the intersection @@ -962,90 +829,91 @@ def makePaths(self, targetPointNode, targetModelNode, targetSwitch, obstacleMode bspTree.SetDataSet(obstacleModelNode.GetPolyData()) bspTree.BuildLocator() - maximumDistance = 0.0 - minimumDistance = 1000.0 - distance = 0.0 - maximumPoint = 0 - minimumPoint = 0 - - # Create an array for needle passing points - self.p = numpy.zeros([nPointsT*nPoints2,3]) - - for indexT in range(0, nPointsT): - - p2 = [tPoint[0], tPoint[1], tPoint[2]] - - for index in range(0, nPoints): - polyData.GetPoint(index, p1) - iD = bspTree.IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId) - - if iD == 0: - coord1 = [p2[0],p2[1],p2[2]] - self.p[approachablePoints*2] = coord1 - coord2 = [p1[0],p1[1],p1[2]] - self.p[approachablePoints*2+1] = coord2 - approachablePoints = approachablePoints + 1 - - # - # Create length calculation algorithm - # - coord1Array = numpy.array(coord1) - coord2Array = numpy.array(coord2) - - distance = numpy.sqrt(numpy.power(coord1Array-coord2Array,2).sum()) - if distance >= maximumDistance: - maximumDistance = distance - maximumPoint = approachablePoints - if distance <= minimumDistance: - minimumDistance = distance - minimumPoint = approachablePoints - - # Create the list for needle passing points to draw virtual ray - self.path = [self.p[0]] - for index in range(1, approachablePoints*2): - self.path.append(self.p[index]) - - # Create an array for all approachable points - pReceived = numpy.zeros([approachablePoints,3]) - - return (self.path, approachablePoints, self.p, minimumPoint, minimumDistance, maximumPoint, maximumDistance) - - def runPointWise(self, targetPointNode, obstacleModelNode, skinModelNode): - """ - Run point-wise analysis - """ - print ("runPointWise()") - tPoint = targetPointNode.GetMarkupPointVector(0, 0) - pTarget = [tPoint[0], tPoint[1], tPoint[2]] - poly = skinModelNode.GetPolyData() - polyDataNormals = vtk.vtkPolyDataNormals() + self.shortestPathIndex = -1 + shortestPathLength = 1e6 + self.longestPathIndex = -1 + longestPathLength = 0.0 + + for index in range(nSkinPoints): + skinPoint = np.array(skinPolyData.GetPoint(index)) + intersect = bspTree.IntersectWithLine(skinPoint, targetPoint, tolerance, t, x, pcoords, subId) + if intersect: + # This path intersects the obstacle, the target is not approachable from here + continue + self.paths.append([targetPoint.copy(), skinPoint.copy()]) + pathLength = np.linalg.norm(targetPoint-skinPoint) + if pathLength < shortestPathLength: + shortestPathLength = pathLength + self.shortestPathIndex = len(self.paths) - 1 + if pathLength > longestPathLength: + longestPathLength = pathLength + self.longestPathIndex = len(self.paths) - 1 + + return self.paths + + @staticmethod + def createSphereModel(modelName, color, visibility=True): + sphere = vtk.vtkSphereSource() + sphere.SetRadius(2.5) + sphere.SetPhiResolution(100) + sphere.SetThetaResolution(100) + sphere.Update() - if vtk.VTK_MAJOR_VERSION <= 5: - polyDataNormals.SetInput(poly) - else: - polyDataNormals.SetInputData(poly) + # Create model node + sphereCursor = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLModelNode", slicer.mrmlScene.GenerateUniqueName(modelName)) + sphereCursor.SetAndObservePolyData(sphere.GetOutput()) + + # Create display node + sphereCursor.CreateDefaultDisplayNodes() + cursorModelDisplay = sphereCursor.GetDisplayNode() + cursorModelDisplay.SetColor(color[0], color[1], color[2]) + cursorModelDisplay.SetOpacity(0.3) + cursorModelDisplay.SetVisibility(visibility) + cursorModelDisplay.SetSliceIntersectionVisibility(True) # Show in slice view + # Create transform node + transform = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLinearTransformNode", slicer.mrmlScene.GenerateUniqueName(modelName + "Transform")) + sphereCursor.SetAndObserveTransformNodeID(transform.GetID()) + + return sphereCursor + + def setSpherePositionAlongPath(self, sphereNode, pathIndex, normalizedPosition): + """normalizedPosition is position along the path, value is between 0.0-1.0 + """ + startPos, endPos = self.paths[pathIndex] + position = endPos + (startPos-endPos) * normalizedPosition + PercutaneousApproachAnalysisLogic.setSpherePosition(sphereNode, position) + return position + + @staticmethod + def setSpherePosition(sphereNode, position): + transformToParent = vtk.vtkMatrix4x4() + transformToParent.SetElement(0, 3, position[0]) + transformToParent.SetElement(1, 3, position[1]) + transformToParent.SetElement(2, 3, position[2]) + sphereNode.GetParentTransformNode().SetMatrixTransformToParent(transformToParent) + + def calcApproachScore(self, targetPointNode, obstacleModelNode, skinModelNode): + # skin model point scalar = -1 if inaccessible (occluded or distance >130); + # point scalar = 100..230 if accessible, the larger distance, the better + import numpy as np + pTarget = np.array(targetPointNode.GetNthControlPointPositionWorld(0)) + + skinPolyData = skinModelNode.GetPolyData() + # Triangulate + triangulator = vtk.vtkTriangleFilter() + triangulator.SetInputData(skinPolyData) + # Compute normals + polyDataNormals = vtk.vtkPolyDataNormals() + polyDataNormals.SetInputConnection(triangulator.GetOutputPort()) polyDataNormals.ComputeCellNormalsOn() polyDataNormals.Update() - polyData = polyDataNormals.GetOutput() + skinPolyData = polyDataNormals.GetOutput() bspTree = vtk.vtkModifiedBSPTree() bspTree.SetDataSet(obstacleModelNode.GetPolyData()) bspTree.BuildLocator() - (score, mind, mindp) = self.calcApproachScore(pTarget, polyData, bspTree, skinModelNode) - - print ("Accessible Area = %f" % (score)) - print ("Minmum Distance = %f" % (mind)) - - return (score, mind, mindp) - - def calcApproachScore(self, point, skinPolyData, obstacleBspTree, skinModelNode=None): - - pTarget = point - polyData = skinPolyData - nPoints = polyData.GetNumberOfPoints() - nCells = polyData.GetNumberOfCells() pSurface=[0.0, 0.0, 0.0] minDistancePoint = [0.0, 0.0, 0.0] @@ -1056,293 +924,85 @@ def calcApproachScore(self, point, skinPolyData, obstacleBspTree, skinModelNode= subId = vtk.mutable(0) # Map surface model - if skinModelNode != None: + if skinModelNode: pointValue = vtk.vtkDoubleArray() - pointValue.SetName("Colors") + pointValue.SetName("Accessibility") pointValue.SetNumberOfComponents(1) - pointValue.SetNumberOfTuples(nPoints) - pointValue.Reset() - pointValue.FillComponent(0,0.0); - - bspTree = obstacleBspTree - - cp0=[0.0, 0.0, 0.0] - cp1=[0.0, 0.0, 0.0] - cp2=[0.0, 0.0, 0.0] + pointValue.SetNumberOfTuples(skinPolyData.GetNumberOfPoints()) + pointValue.FillComponent(0,0.0) accessibleArea = 0.0 inaccessibleArea = 0.0 modifiedArea = 0.0 - + minDistance = -1 + ids=vtk.vtkIdList() + cp0=[0.0, 0.0, 0.0] + cp1=[0.0, 0.0, 0.0] + cp2=[0.0, 0.0, 0.0] - minDistance = -1; - + nCells = skinPolyData.GetNumberOfCells() for index in range(nCells): - cell = polyData.GetCell(index) + cell = skinPolyData.GetCell(index) if cell.GetCellType() == vtk.VTK_TRIANGLE: area = cell.ComputeArea() - polyData.GetCellPoints(index, ids) - polyData.GetPoint(ids.GetId(0), cp0) - polyData.GetPoint(ids.GetId(1), cp1) - polyData.GetPoint(ids.GetId(2), cp2) + skinPolyData.GetCellPoints(index, ids) + skinPolyData.GetPoint(ids.GetId(0), cp0) + skinPolyData.GetPoint(ids.GetId(1), cp1) + skinPolyData.GetPoint(ids.GetId(2), cp2) vtk.vtkTriangle.TriangleCenter(cp0, cp1, cp2, pSurface) iD = bspTree.IntersectWithLine(pSurface, pTarget, tolerance, t, x, pcoords, subId) if iD < 1: - if skinModelNode != None: - d = vtk.vtkMath.Distance2BetweenPoints(pSurface, pTarget) - d = math.sqrt(d) - modifiedArea = area * (130 - d) / 130 + # no intersection + if skinModelNode: + d = math.sqrt(vtk.vtkMath.Distance2BetweenPoints(pSurface, pTarget)) if d < minDistance or minDistance < 0: minDistance = d minDistancePoint = [pSurface[0],pSurface[1],pSurface[2]] - - v = 0 - if d < 130: + + maximumAccessibleDistance = 130 + v = -1.0 + if d < maximumAccessibleDistance: + # entry point is not too far from target point v = d + 101 - accessibleArea = accessibleArea + modifiedArea - else: - v = -1.0 - - pointValue.InsertValue(ids.GetId(0), v) - pointValue.InsertValue(ids.GetId(1), v) - pointValue.InsertValue(ids.GetId(2), v) + modifiedArea = area * (maximumAccessibleDistance - d) / maximumAccessibleDistance + accessibleArea += modifiedArea + + pointValue.SetValue(ids.GetId(0), v) + pointValue.SetValue(ids.GetId(1), v) + pointValue.SetValue(ids.GetId(2), v) else: - if skinModelNode != None: + # intersection + if skinModelNode: v = -1.0 - pointValue.InsertValue(ids.GetId(0), v) - pointValue.InsertValue(ids.GetId(1), v) - pointValue.InsertValue(ids.GetId(2), v) - inaccessibleArea = inaccessibleArea + area + pointValue.SetValue(ids.GetId(0), v) + pointValue.SetValue(ids.GetId(1), v) + pointValue.SetValue(ids.GetId(2), v) + inaccessibleArea += area else: print ("ERROR: Non-triangular cell.") score = accessibleArea - if skinModelNode != None: - visible = 1 - invisible = 0 + if skinModelNode: skinModelNode.AddPointScalars(pointValue) - skinModelNode.SetActivePointScalars("Colors", vtk.vtkDataSetAttributes.SCALARS) - skinModelNode.Modified() - displayNode = skinModelNode.GetModelDisplayNode() - displayNode.SetActiveScalarName("Colors") - displayNode.SetScalarRange(0.0,20.0) - displayNode.SetScalarVisibility(False) - - return (score, minDistance, minDistancePoint) - -class SphereModel: - - def __init__(self): - pass - - def make(self, visibilityParam, color, modelName): - scene = slicer.mrmlScene - - sphere = vtk.vtkSphereSource() - sphere.SetRadius(0.5) - sphere.SetPhiResolution(100) - sphere.SetThetaResolution(100) - sphere.Update() - - sphere1 = vtk.vtkSphereSource() - sphere1.SetRadius(2.5) - sphere1.SetPhiResolution(100) - sphere1.SetThetaResolution(100) - sphere1.SetCenter(20,20,20) - sphere1.Update() - - # Create model node - sphereCursor = slicer.vtkMRMLModelNode() - sphereCursor.SetScene(scene) - sphereCursor.SetName(scene.GenerateUniqueName(modelName)) - sphereCursor.SetAndObservePolyData(sphere.GetOutput()) - - # Create display node - cursorModelDisplay = slicer.vtkMRMLModelDisplayNode() - cursorModelDisplay.SetColor(color[0], color[1], color[2]) - cursorModelDisplay.SetOpacity(0.3) - cursorModelDisplay.SetScene(scene) - cursorModelDisplay.SetVisibility(visibilityParam) - cursorModelDisplay.SetSliceIntersectionVisibility(True) # Show in slice view - - scene.AddNode(cursorModelDisplay) - sphereCursor.SetAndObserveDisplayNodeID(cursorModelDisplay.GetID()) - - # Add to scene - if vtk.VTK_MAJOR_VERSION <= 5: - cursorModelDisplay.SetInputPolyData(sphere.GetOutput()) - - scene.AddNode(sphereCursor) - - # Create transform node - transform = slicer.vtkMRMLLinearTransformNode() - transformName = modelName + "Transform" - transform.SetName(scene.GenerateUniqueName(transformName)) - scene.AddNode(transform) - sphereCursor.SetAndObserveTransformNodeID(transform.GetID()) - - return (sphereCursor, cursorModelDisplay, transform) - - def move(self, p, pointNumber, pointSliderValue, transform): - - r = p[pointNumber*2+1][0] - a = p[pointNumber*2+1][1] - s = p[pointNumber*2+1][2] - - targetR = p[pointNumber*2][0] - targetA = p[pointNumber*2][1] - targetS = p[pointNumber*2][2] - - dirVectorR = r - targetR - dirVectorA = a - targetA - dirVectorS = s - targetS - - movedR = r + pointSliderValue*0.001*dirVectorR - movedA = a + pointSliderValue*0.001*dirVectorA - movedS = s + pointSliderValue*0.001*dirVectorS - - coordinate = vtk.vtkMatrix4x4() - transform.GetMatrixTransformToParent(coordinate) - coordinate.SetElement(0, 3, movedR) - coordinate.SetElement(1, 3, movedA) - coordinate.SetElement(2, 3, movedS) - transform.SetMatrixTransformToParent(coordinate) - - movedRAS = [movedR, movedA, movedS] - - return movedRAS - - def drop(self, r, a, s, transform): - - coordinate = vtk.vtkMatrix4x4() - transform.GetMatrixTransformToParent(coordinate) - coordinate.SetElement(0, 3, r) - coordinate.SetElement(1, 3, a) - coordinate.SetElement(2, 3, s) - transform.SetMatrixTransformToParent(coordinate) - -# NeedlePathModel class is based on EndoscopyPathModel class for Endoscopy module -class NeedlePathModel: - """Create a vtkPolyData for a polyline: - - Add one point per path point. - - Add a single polyline - """ - def __init__(self): - pass - - def createPolyData(self, points): - """make an empty single-polyline polydata""" - - polyData = vtk.vtkPolyData() - polyData.SetPoints(points) - - lines = vtk.vtkCellArray() - polyData.SetLines(lines) - idArray = lines.GetData() - idArray.Reset() - idArray.InsertNextTuple1(0) - - polygons = vtk.vtkCellArray() - polyData.SetPolys(polygons) - idArray = polygons.GetData() - idArray.Reset() - idArray.InsertNextTuple1(0) - - return polyData - - def modify(self, path, approachablePoints, visibilityParam, color, modelName, lineType, model, modelDisplay, points): - import numpy - - # Create an array for all approachable points - p = numpy.zeros([approachablePoints*2,3]) - p1 = [0.0, 0.0, 0.0] - - scene = slicer.mrmlScene - - polyData = vtk.vtkPolyData() - polyData = lineType - - lines = vtk.vtkCellArray() - polyData.SetLines(lines) - linesIDArray = lines.GetData() - linesIDArray.Reset() - linesIDArray.InsertNextTuple1(0) - - polygons = vtk.vtkCellArray() - polyData.SetPolys( polygons ) - idArray = polygons.GetData() - idArray.Reset() - idArray.InsertNextTuple1(0) - - if approachablePoints != 0: - - for point in path: - pointIndex = points.InsertNextPoint(*point) - linesIDArray.InsertNextTuple1(pointIndex) - linesIDArray.SetTuple1( 0, linesIDArray.GetNumberOfTuples() - 1 ) - lines.SetNumberOfCells(1) - - def make(self, path, approachablePoints, visibilityParam, color, modelName, polyData): - - import numpy - - # Create an array for all approachable points - p = numpy.zeros([approachablePoints*2,3]) - scene = slicer.mrmlScene - - self.points = vtk.vtkPoints() - polyData.SetPoints(self.points) - - lines = vtk.vtkCellArray() - polyData.SetLines(lines) - linesIDArray = lines.GetData() - linesIDArray.Reset() - linesIDArray.InsertNextTuple1(0) - - polygons = vtk.vtkCellArray() - polyData.SetPolys( polygons ) - idArray = polygons.GetData() - idArray.Reset() - idArray.InsertNextTuple1(0) + skinModelNode.GetDisplayNode().SetActiveScalar("Accessibility", vtk.vtkAssignAttribute.POINT_DATA) + skinModelNode.GetDisplayNode().SetAndObserveColorNodeID("vtkMRMLColorTableNodeFileMagma.txt") + skinModelNode.GetDisplayNode().SetScalarVisibility(True) - if approachablePoints != 0: + # skinModelNode.SetActivePointScalars("Accessibility", vtk.vtkDataSetAttributes.SCALARS) + # skinModelNode.Modified() + # displayNode = skinModelNode.GetModelDisplayNode() + # displayNode.SetActiveScalarName("Accessibility") + # displayNode.SetScalarRange(0.0,20.0) + # displayNode.SetScalarVisibility(False) - for point in path: - pointIndex = self.points.InsertNextPoint(*point) - linesIDArray.InsertNextTuple1(pointIndex) - linesIDArray.SetTuple1( 0, linesIDArray.GetNumberOfTuples() - 1 ) - lines.SetNumberOfCells(1) - - # Save all approachable points - p[pointIndex] = point - - # Create model node - model = slicer.vtkMRMLModelNode() - model.SetScene(scene) - model.SetName(scene.GenerateUniqueName(modelName)) - model.SetAndObservePolyData(polyData) - - # Create display node - modelDisplay = slicer.vtkMRMLModelDisplayNode() - modelDisplay.SetColor(color[0], color[1], color[2]) - modelDisplay.SetScene(scene) - modelDisplay.SetVisibility(visibilityParam) - modelDisplay.SetSliceIntersectionVisibility(True) # Show in slice view - scene.AddNode(modelDisplay) - model.SetAndObserveDisplayNodeID(modelDisplay.GetID()) - - # Add to scene - if vtk.VTK_MAJOR_VERSION <= 5: - modelDisplay.SetInputPolyData(model.GetPolyData()) - scene.AddNode(model) + return (score, minDistance, minDistancePoint) - return (model, p, modelDisplay, self.points) class PercutaneousApproachAnalysisTest(unittest.TestCase): """ @@ -1410,5 +1070,4 @@ def test_PercutaneousApproachAnalysis1(self): volumeNode = slicer.util.getNode(pattern="FA") logic = PercutaneousApproachAnalysisLogic() - self.assertTrue( logic.hasImageData(volumeNode) ) self.delayDisplay('Test passed!') From 919f22dc3580efd4bdb7aa69a4046e999faff610 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Mon, 22 Apr 2024 17:20:14 -0400 Subject: [PATCH 11/11] ENH: Update extension metadata Consolidate extension metadata based on the corresponding s4ext file organized in the ExtensionsIndex repository. --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e55150a..4abe803 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,12 +3,12 @@ cmake_minimum_required(VERSION 2.8.9) project(PercutaneousApproachAnalysis) #----------------------------------------------------------------------------- -set(EXTENSION_HOMEPAGE "http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/PercutaneousApproachAnalysis") +set(EXTENSION_HOMEPAGE "https://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/PercutaneousApproachAnalysis") set(EXTENSION_CATEGORY "IGT") set(EXTENSION_CONTRIBUTORS "Koichiro Murakami (Shiga University of Medical Science, Japan, SPL), Atsushi Yamada (Shiga University of Medical Science, Japan), Laurent Chauvin (SPL), Junichi Tokuda (SPL)") set(EXTENSION_DESCRIPTION "The Percutaneous Approach Analysis is used to calculate and visualize the accessibility of liver tumor with a percutaneous approach.") -set(EXTENSION_ICONURL "http://www.slicer.org/slicerWiki/images/a/ac/PAAlogo-small.png") -set(EXTENSION_SCREENSHOTURLS "http://www.slicer.org/slicerWiki/images/4/42/Accessibility_clinical.png") +set(EXTENSION_ICONURL "https://www.slicer.org/slicerWiki/images/a/ac/PAAlogo-small.png") +set(EXTENSION_SCREENSHOTURLS "https://www.slicer.org/slicerWiki/images/4/42/Accessibility_clinical.png") #----------------------------------------------------------------------------- find_package(Slicer REQUIRED)