Slicer 5.6
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
Loading...
Searching...
No Matches
AbstractScriptedSegmentEditorEffect.py
Go to the documentation of this file.
1import qt
2
3import slicer
4
5
7 """Abstract scripted segment editor effects for effects implemented in python.
8
9 An example of generic effect is ``ThresholdEffect``.
10
11 To use the effect, follow these steps:
12
13 1. Instantiation and registration
14
15 Instantiate segment editor effect adaptor class from
16 module (e.g. from setup function), and set python source::
17
18 import qSlicerSegmentationsEditorEffectsPythonQt as effects
19 scriptedEffect = effects.qSlicerSegmentEditorScriptedEffect(None)
20 scriptedEffect.setPythonSource(MyEffect.filePath)
21 scriptedEffect.self().register()
22
23 If effect name is added to ``slicer.modules.segmenteditorscriptedeffectnames``
24 list then the above instantiation and registration steps are not necessary,
25 as the `SegmentEditor` module do all these.
26
27 2. Call host C++ implementation using::
28
29 self.scriptedEffect.functionName()
30
31 2.a. Most frequently used methods are:
32
33 - Parameter get/set: ``parameter``, ``integerParameter``, ``doubleParameter``, ``setParameter``
34 - Add options widget: ``addOptionsWidget``
35 - Coordinate transforms: ``rasToXy``, ``xyzToRas``, ``xyToRas``, ``xyzToIjk``, ``xyToIjk``
36 - Convenience getters: ``renderWindow``, ``renderer``, ``viewNode``
37
38 2.b. Always call API functions (the ones that are defined in the adaptor \
39 class ``qSlicerSegmentEditorScriptedEffect``) using the adaptor accessor ``self.scriptedEffect``.
40
41 For example::
42
43 self.scriptedEffect.updateGUIFromMRML()
44
45 3. To prevent deactivation of an effect by clicking place fiducial toolbar button, \
46 override ``interactionNodeModified(self, interactionNode)``
47 """
48
49 def __init__(self, scriptedEffect):
50 self.scriptedEffect = scriptedEffect
51
52 def register(self):
53 effectFactorySingleton = slicer.qSlicerSegmentEditorEffectFactory.instance()
54 effectFactorySingleton.registerEffect(self.scriptedEffect)
55
56 #
57 # Utility functions for convenient coordinate transformations
58 #
59 def rasToXy(self, ras, viewWidget):
60 rasVector = qt.QVector3D(ras[0], ras[1], ras[2])
61 xyPoint = self.scriptedEffect.rasToXy(rasVector, viewWidget)
62 return [xyPoint.x(), xyPoint.y()]
63
64 def xyzToRas(self, xyz, viewWidget):
65 xyzVector = qt.QVector3D(xyz[0], xyz[1], xyz[2])
66 rasVector = self.scriptedEffect.xyzToRas(xyzVector, viewWidget)
67 return [rasVector.x(), rasVector.y(), rasVector.z()]
68
69 def xyToRas(self, xy, viewWidget):
70 xyPoint = qt.QPoint(xy[0], xy[1])
71 rasVector = self.scriptedEffect.xyToRas(xyPoint, viewWidget)
72 return [rasVector.x(), rasVector.y(), rasVector.z()]
73
74 def xyzToIjk(self, xyz, viewWidget, image, parentTransformNode=None):
75 xyzVector = qt.QVector3D(xyz[0], xyz[1], xyz[2])
76 ijkVector = self.scriptedEffect.xyzToIjk(xyzVector, viewWidget, image, parentTransformNode)
77 return [int(ijkVector.x()), int(ijkVector.y()), int(ijkVector.z())]
78
79 def xyToIjk(self, xy, viewWidget, image, parentTransformNode=None):
80 xyPoint = qt.QPoint(xy[0], xy[1])
81 ijkVector = self.scriptedEffect.xyToIjk(xyPoint, viewWidget, image, parentTransformNode)
82 return [int(ijkVector.x()), int(ijkVector.y()), int(ijkVector.z())]
83
84 def setWidgetMinMaxStepFromImageSpacing(self, spinbox, imageData):
85 # Set spinbox minimum, maximum, and step size from vtkImageData spacing:
86 # Set widget minimum spacing and step size to be 1/10th or less than minimum spacing
87 # Set widget minimum spacing to be 100x or more than minimum spacing
88 if not imageData:
89 return
90 import math
91 spinbox.unitAwareProperties &= ~(slicer.qMRMLSpinBox.MinimumValue | slicer.qMRMLSpinBox.MaximumValue | slicer.qMRMLSpinBox.Precision)
92 stepSize = 10 ** (math.floor(math.log10(min(imageData.GetSpacing()) / 10.0)))
93 spinbox.minimum = stepSize
94 spinbox.maximum = 10 ** (math.ceil(math.log10(max(imageData.GetSpacing()) * 100.0)))
95 spinbox.singleStep = stepSize
96 # number of decimals is set to be able to show the step size (e.g., stepSize = 0.01 => decimals = 2)
97 spinbox.decimals = max(int(-math.floor(math.log10(stepSize))), 0)