@@ -203,6 +203,7 @@ def __init__(self, parent=None):
203203 self ._parameterNode = None
204204 self ._volumeNode = None
205205 self ._segmentNode = None
206+ self ._scribblesROINode = None
206207 self ._volumeNodes = []
207208 self ._updatingGUIFromParameterNode = False
208209 self ._scribblesEditorWidget = None
@@ -331,6 +332,11 @@ def setup(self):
331332 self .ui .scribblesSelector .addItem (self .icon ("bg_red.png" ), "Background" )
332333 self .ui .scribblesSelector .setCurrentIndex (0 )
333334
335+ # ROI placement for scribbles
336+ self .ui .scribblesPlaceWidget .setButtonsVisible (False )
337+ self .ui .scribblesPlaceWidget .placeButton ().show ()
338+ self .ui .scribblesPlaceWidget .setMRMLScene (slicer .mrmlScene )
339+
334340 # start with scribbles section disabled
335341 self .ui .scribblesCollapsibleButton .setEnabled (False )
336342 self .ui .scribblesCollapsibleButton .collapsed = True
@@ -383,6 +389,7 @@ def onSceneStartClose(self, caller, event):
383389 self .setParameterNode (None )
384390 self .current_sample = None
385391 self .samples .clear ()
392+ self ._scribblesROINode = None
386393
387394 self .resetPointList (
388395 self .ui .dgPositiveControlPointPlacementWidget ,
@@ -1272,6 +1279,9 @@ def initSample(self, sample, autosegment=True):
12721279 segmentEditorWidget .setSegmentationNode (self ._segmentNode )
12731280 segmentEditorWidget .setMasterVolumeNode (self ._volumeNode )
12741281
1282+ self .createScribblesROINode ()
1283+ self .ui .scribblesPlaceWidget .setCurrentNode (self ._scribblesROINode )
1284+
12751285 # check if user allows overlapping segments
12761286 if slicer .util .settingsValue ("MONAILabel/allowOverlappingSegments" , False , converter = slicer .util .toBool ):
12771287 # set segment editor to allow overlaps
@@ -1600,6 +1610,19 @@ def createSegmentNode(self):
16001610 self ._segmentNode .SetReferenceImageGeometryParameterFromVolumeNode (self ._volumeNode )
16011611 self ._segmentNode .SetName (name )
16021612
1613+ def createScribblesROINode (self ):
1614+ if self ._volumeNode is None :
1615+ return
1616+ if self ._scribblesROINode is None :
1617+ scribblesROINode = slicer .mrmlScene .AddNewNodeByClass ("vtkMRMLMarkupsROINode" )
1618+ scribblesROINode .SetName ("Scribbles ROI" )
1619+ scribblesROINode .CreateDefaultDisplayNodes ()
1620+ scribblesROINode .GetDisplayNode ().SetFillOpacity (0.4 )
1621+ scribblesROINode .GetDisplayNode ().SetSelectedColor (1 , 1 , 1 )
1622+ scribblesROINode .GetDisplayNode ().SetColor (1 , 1 , 1 )
1623+ scribblesROINode .GetDisplayNode ().SetActiveColor (1 , 1 , 1 )
1624+ self ._scribblesROINode = scribblesROINode
1625+
16031626 def getLabelColor (self , name ):
16041627 color = GenericAnatomyColors .get (name .lower ())
16051628 return [c / 255.0 for c in color ] if color else None
@@ -1856,13 +1879,11 @@ def onUpdateScribbles(self):
18561879 self .updateServerSettings ()
18571880 self .reportProgress (60 )
18581881
1859- # try to first fetch vtkMRMLAnnotationROINode
1860- roiNode = slicer .mrmlScene .GetFirstNodeByClass ("vtkMRMLAnnotationROINode" )
1861- if roiNode is None : # if vtkMRMLAnnotationROINode not present, then check for vtkMRMLMarkupsROINode node
1862- roiNode = slicer .mrmlScene .GetFirstNodeByClass ("vtkMRMLMarkupsROINode" )
1863-
1864- # if roi node found, then try to get roi
1865- selected_roi = self .getROIPointsXYZ (roiNode )
1882+ # try to get roi if placed
1883+ roiNode = self .ui .scribblesPlaceWidget .currentNode ()
1884+ selected_roi = []
1885+ if roiNode and roiNode .GetControlPointPlacementComplete ():
1886+ selected_roi = self .getROIPointsXYZ (roiNode )
18661887
18671888 # send scribbles + label to server along with selected scribbles method
18681889 params = self .getParamsFromConfig ("infer" , scribblesMethod )
@@ -1905,20 +1926,10 @@ def getROIPointsXYZ(self, roiNode):
19051926 v .GetRASToIJKMatrix (RasToIjkMatrix )
19061927
19071928 roi_points_ras = [0.0 ] * 6
1908- if roiNode .__class__ .__name__ == "vtkMRMLMarkupsROINode" :
1909- # for vtkMRMLMarkupsROINode
1910- print (roiNode .__class__ .__name__ )
1911- center = [0 ] * 3
1912- roiNode .GetCenter (center )
1913- roi_points_ras = [(x - s / 2 , x + s / 2 ) for x , s in zip (center , roiNode .GetSize ())]
1914- roi_points_ras = [item for sublist in roi_points_ras for item in sublist ]
1915- elif roiNode .__class__ .__name__ == "vtkMRMLAnnotationROINode" :
1916- # for vtkMRMLAnnotationROINode (old method)
1917- print (roiNode .__class__ .__name__ )
1918- roiNode .GetBounds (roi_points_ras )
1919- else :
1920- # if none found then best to return empty list
1921- return []
1929+ center = [0 ] * 3
1930+ roiNode .GetCenter (center )
1931+ roi_points_ras = [(x - s / 2 , x + s / 2 ) for x , s in zip (center , roiNode .GetSize ())]
1932+ roi_points_ras = [item for sublist in roi_points_ras for item in sublist ]
19221933
19231934 min_points_ras = [roi_points_ras [0 ], roi_points_ras [2 ], roi_points_ras [4 ], 1.0 ]
19241935 max_points_ras = [roi_points_ras [0 + 1 ], roi_points_ras [2 + 1 ], roi_points_ras [4 + 1 ], 1.0 ]
@@ -1960,11 +1971,17 @@ def onClearScribblesSegmentNodes(self):
19601971 segmentation .SetDisplayVisibility (False )
19611972 segmentation .SetDisplayVisibility (True )
19621973
1974+ def resetScribblesROI (self ):
1975+ if self ._scribblesROINode :
1976+ self ._scribblesROINode .RemoveAllControlPoints ()
1977+
19631978 def onClearScribbles (self ):
19641979 # for clearing scribbles and resetting tools to default
19651980 # remove "scribbles" segments from label
19661981 self .onClearScribblesSegmentNodes ()
19671982
1983+ self .resetScribblesROI ()
1984+
19681985 self .ui .paintScribblesButton .setChecked (True )
19691986 self .ui .eraseScribblesButton .setChecked (False )
19701987
0 commit comments