Get ROINode Information by clicking

Hello,

I’m trying to get the all information about a drawed ROINode on the slice view:

Capture1

The goal is the following: I want to click on a white square to get all the ROINode informations / properties (coordinates for exemple).

I already search a lot, step by step, by trying to detect a ModifiedEvent on a non-locked node, but the only event i can get is when i move the square, witch is problematic when i want to manipulate a locked Node by clicking on it … i had this with

sliceNode.AddObserver(vtk.vtkCommand.ModifiedEvent, aFunc)

I trying with “AnyEvent” for tests, but the only two event detected is NoEvent and ModifiedEvent

Does anyone has a solution ?

You can observe click events on markups (in recent preview releases). You can use those markups to draw ROIs (box-shaped model nodes). We plan to improve markups module to manage ROIs and then you’ll be able to get notifications about clicks, but you need to wait about 6-12 months (or help us implementing it).

So you suggest i should draw a lines between all my markups in order to have my ROI ? If yes, how ?

( for the click event i found that, i just put it here if someone need:

    slicer.util.mainWindow().moduleSelector().selectModule('Markups')
    slicer.modules.markups.logic().AddFiducial(5,5,5)
    
    fidNode = slicer.util.getNode("vtkMRMLMarkupsFiducialNode1")
    fidNode.AddObserver(slicer.vtkMRMLMarkupsNode.PointClickedEvent ,aFunction)

Thanks for the tips
)

If you want to create a box then you can create a VTK source for that and then create a model node. You can show box boundaries in slice view by enabling slice view intersections (2D visibility). See example in the script repository: https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Manipulating_objects_in_the_slice_viewer

Okay, i found a way with Markups and vtkMRMLModelDisplayNode to get something like this: (the square can move with the point)

image

But when i changed my markup with SetLocked(1) (to avoid movement of the markup) i cannot trigger a PointClickedEvent… (cant even click on the markup)

So i tried to change the color to transparent but i cannot find any method to manipulate the markup color… even try SetDisplayVisibility(0) , same conclusion, cannot select the point, even with a SetSelectable(1) after theses line…
Any solution ?

If you want to prevent moving the point but you still want to click on it then don’t lock the entire markups node but lock each control point.

Okay, but now i got a problem with code logic …
I tried to apply your solution via
markup.GetControlPoints() but the debugger say there are no function with this say, BUT i saw it on the Doxygen…
I try something like

e = slicer.vtkMRMLMarkupsNode()
print(type(e))
print(e.GetControlPoints())

I get

<type 'vtkSlicerMarkupsModuleMRMLPython.vtkMRMLMarkupsNode'>

and
"no attribute found for "GetControlPoint"
I Try to workaround with other functions but none function related with control points work…

I’m working with python and slicer 4.10.2, i tried with the upper version without success

I dont know what is wrong ….

Some widgets (ROI, ruler) are managed by the old Annotation module. Others (points, line, angle, curve, closed curve) by Markups module. The plan is to remove Annotations module when Markups module reaches feature parity, but we don’t have ROIs in Markups module yet.

You can enter help(someNode) to get API documentation or google vtkMRMLAnnotationROINode.

I found the answer …
The code allow us to pick a square in the red yellow green view, and also get it’s information (without markup,

Here the code:

#We create a Model Node. In my case, he has a polydataConnection with a source vtk cube
self.model_node = slicer.mrmlScene.CreateNodeByClass('vtkMRMLModelNode')
slicer.mrmlScene.AddNode(self.model_node)

#Bind between VTK cube and our model node
self.model_node.SetPolyDataConnection(self.cube_source.GetOutputPort())
    
# . Create model display node
self.model_display_node = slicer.mrmlScene.CreateNodeByClass('vtkMRMLModelDisplayNode')
slicer.mrmlScene.AddNode(self.model_display_node)

self.model_node.SetAndObserveDisplayNodeID(self.model_display_node.GetID())
self.model_display_node.SetColor(0.0,1.0, 0.0) # green color
self.model_display_node.SetSliceDisplayModeToIntersection()

 # . Visibility
 self.model_display_node.SetSliceIntersectionVisibility(1)

#Get the RAS bound of our Model Node
self.tabRas = [0.0,0.0,0.0,0.0,0.0,0.0]
self.model_node.GetRASBounds(self.tabRas)

#We get The Red view (and the other if we want) and we put a observer to trigger a function if the observer detect a left click
interactorRed =slicer.app.layoutManager().sliceWidget('Red').sliceView().interactor()
self.crosshairNode=slicer.util.getNode('Crosshair') 
interactorRed.AddObserver(vtk.vtkCommand.LeftButtonPressEvent , self.SelectCube)

#This function compare the RAS Coordinate of cube's bound and our click, to detect if we click inside the cube on a RGY view:
 def SelectCube(self,caller,event):
      ras=[0,0,0]
      self.crosshairNode.GetCursorPositionRAS(ras)
      print(ras)
      if (ras[0]>self.tabRas[0] and ras[0]<self.tabRas[1]) and (ras[1]>self.tabRas[2] and ras[1]<self.tabRas[3]) and (ras[2]>self.tabRas[4] and ras[2]<self.tabRas[5]):
          self.model_display_node.SetColor(0.0,1.0,0.0) #Green Color if selected
      else:
          self.model_display_node.SetColor(1.0,0.0,0.0) #Red Color if deselected

Hope it help somebody :slight_smile:
Thanks for your help & your time lassoan