# Mouse Interaction with ModelNode: Hover and Click Functions

**URL:** <https://discourse.slicer.org/t/mouse-interaction-with-modelnode-hover-and-click-functions/37664>\
**Category:** Development\
**Created:** [August 2, 2024, 8:48am UTC](https://discourse.slicer.org/t/mouse-interaction-with-modelnode-hover-and-click-functions/37664 "2024-08-02T08:48:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![park](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/park/32/5717_2.png) [@park](https://discourse.slicer.org/u/park)\
**Post date:** [August 2, 2024, 8:48am UTC](https://discourse.slicer.org/t/mouse-interaction-with-modelnode-hover-and-click-functions/37664/1 "2024-08-02T08:48:35Z")

</div>

Hello,

I want to create a feature that interacts with a `modelNode` through the mouse. Specifically, when the mouse hovers over a model, I want its color to change, and when clicked, I want the camera to center on that model.

I have come across several similar questions, but I couldn’t find a solution, and some of the example links were invalid.

I thought knowing the mouse (cursor) position would be the starting point, so I found the following code that allows me to get the mouse coordinates:

> crosshairNode=slicer.util.getNode(“Crosshair”)
> 
> def onMouseMoved(ViewName):  
> ras=[0,0,0]  
> crosshairNode.GetCursorPositionRAS(ras)  
> print(ras)
> 
> for viewName in [“View1”]:  
> threeDView = slicer.app.layoutManager().threeDWidget(viewName).threeDView()  
> tag = threeDView.interactor().AddObserver(vtk.vtkCommand.MouseMoveEvent , lambda caller, event, viewName=viewName: onMouseMoved(viewName))

However, I am having difficulty determining if the mouse is over a specific model with these coordinates (do I need to write code to compare the coordinates with all points of the model? This seems to take too long).

I believe that the features I mentioned are already implemented in the `markups` module. Therefore, I would appreciate it if you could provide a code snippet or some tips.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 3, 2024, 10:36pm UTC](https://discourse.slicer.org/t/mouse-interaction-with-modelnode-hover-and-click-functions/37664/2 "2024-08-03T22:36:46Z")

</div>

Check out focus implementation @Sunderlandkyl. It seems to be what you would like to achieve. You can find more information [here](https://projectweek.na-mic.org/PW41_2024_MIT/Projects/NodeFocus/).

---

<div class="post-metadata">

**Author:** ![park](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/park/32/5717_2.png) [@park](https://discourse.slicer.org/u/park)\
**Post date:** [August 6, 2024, 8:18am UTC](https://discourse.slicer.org/t/mouse-interaction-with-modelnode-hover-and-click-functions/37664/3 "2024-08-06T08:18:45Z")

</div>

I solved this using `vtk.vtkCellPicker()`.  
This is the code snippet of my implementation.

```auto
def setThreeDViewInteraction(self):
    self.picker = vtk.vtkCellPicker()
    self.picker.SetTolerance(0.005)    

    modelDisplayableManager = slicer.app.layoutManager().threeDWidget('View1').threeDView().displayableManagerByClassName("vtkMRMLModelDisplayableManager")
    self.actorModels = []
    for modelNode in self.modelNodes:
        self.actorModels.append(modelDisplayableManager.GetActorByID(modelNode.GetDisplayNode().GetID()))

    self.interactor3D = slicer.app.layoutManager().threeDWidget('View1').threeDView().interactor()
    self.threeDViewMouseHoverTag = self.interactor3D.AddObserver(vtk.vtkCommand.MouseMoveEvent, self.threeDViewMouseHover)
    self.threeDViewMouseClickTag = self.interactor3D.AddObserver(vtk.vtkCommand.LeftButtonDoubleClickEvent, self.threeDViewMouseClick)
    
def threeDViewMouseHover(self, caller, event):
    x, y = caller.GetEventPosition()
    self.picker.Pick(x, y, 0, caller.GetRenderWindow().GetRenderers().GetFirstRenderer())
    actorMouse = self.picker.GetActor()

    if actorMouse in self.actorModels:
        for modelNode in self.modelNodes:
            modelNode.GetDisplayNode().SetAmbient(0.95)
    else:
        for modelNode in self.modelNodes:
            modelNode.GetDisplayNode().SetAmbient(0.5)

```
