how to create a mouse event inside the 3d slicer view. Need to pick cells from a mesh object from within the 3d slice view of the slicer.
Need help
how to create a mouse event inside the 3d slicer view. Need to pick cells from a mesh object from within the 3d slice view of the slicer.
Need help
You can get 3D position from views as shown in these examples:
If you want to select several cells, you can use markups fiducials : drop a fiducials on the cells you want to select and then use FindCell to get the cell IDs. If you don’t want the fiducials to stay there then you can remove them immediately after you retrieved their position. In recent Slicer Preview builds, markups points slide on visible surfaces, so you can make position adjustments quite easily.
Hi andras,
I wrote the following to get the cell using fiducial
def onMouseMoved(self, observer,eventid):
ras=[0,0,0]
crosshairNode.GetCursorPositionRAS(ras)
if markupsNode.GetNumberOfFiducials() == 0:
markupsNode.AddFiducial(*ras)
else:
markupsNode.SetNthFiducialPosition(0,*ras)
closestCell = cell.FindCell(ras)
closestPointValue = modelPointValues.GetTuple(closestCell)
print("RAS = " + repr(ras) + " value = " + repr(closestPointValue))
calling this within a scripted module in the run function as
global cell, modelPointValues, crosshairNode, markupsNode
modelNode = slicer.util.getNode(‘Model_1’)
#modelPointValues = modelNode.GetPolyData().GetPointData().GetArray(“Normals”)
modelPointValues = modelNode.GetMesh().GetCells()
markupsNode = slicer.util.getNode(‘F’)
if not markupsNode:
markupsNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode","F")
#pointsLocator = vtk.vtkPointLocator() # could try using vtk.vtkStaticPointLocator() if need to optimize
#pointsLocator.SetDataSet(modelNode.GetPolyData())
#pointsLocator.BuildLocator()
cell = vtk.vtkCellLocator()
cell.SetDataSet(modelNode.GetMesh())
cell.BuildLocator
crosshairNode=slicer.mrmlScene.AddNewNodeByClass("vtkMRMLCrosshairNode")
crosshairNodeObserverTag = crosshairNode.AddObserver(slicer.vtkMRMLCrosshairNode.CursorPositionModifiedEvent, self.onMouseMoved)
The application stoped working. although there was no error. the mouse cursor was paused. Could you tell me whats wrong with the code.
I replaced the crosshair node part with
crosshairNode=slicer.util.getNode(‘Crosshair’)
crosshairNodeObserverTag = crosshairNode.AddObserver(slicer.vtkMRMLCrosshairNode.CursorPositionModifiedEvent, self.onMouseMoved)
but still the program doessnt work. What is wrong in the code. could you please tell me. because the program haults and then the slicer application closes.
Modify crosshair examples of the script repository step by step. If you encounter any problems then post the script, describe what you do, what you expect to happen, and what happens instead.
I need cells to be selected with mouse of the mesh in attached pic. The script gives me the position of mousecursor. I defined the celllocator and using the findcell to locate the cell. Could you please guide in this respect. What I need to look at.
I need to get the pcoords of tetra cell rather then the mousecursorpoint. what should I do.
global cell, modelPointValues, crosshairNode, markupsNode
modelNode = slicer.util.getNode('Model_1')
modelPointValues = modelNode.GetMesh().GetCells().GetData()
cell = vtk.vtkCellLocator()
cell.SetDataSet(modelNode.GetMesh())
cell.BuildLocator
crosshairNode=slicer.util.getNode('Crosshair')
crosshairNodeObserverTag = crosshairNode.AddObserver(slicer.vtkMRMLCrosshairNode.CursorPositionModifiedEvent, self.onMouseMoved)
def onMouseMoved(self, observer, eventid):
ras=[0,0,0]
crosshairNode.GetCursorPositionRAS(ras)
if markupsNode.GetNumberOfFiducials() == 0:
markupsNode.AddFiducial(*ras)
else:
markupsNode.SetNthFiducialPosition(0,*ras)
closestCell = cell.FindCell(ras) /**//Problem starts here
print("inside mouse event")
#closestPointValue = modelPointValues.GetTuple(closestCell)
print("RAS = " + repr(ras) )#+ " value = " + repr(closestPointValue))
The code crashed because you did not build the locator. cell.BuildLocator
just prints the address of the BuildLocator
method. You need to add ()
to call the method: cell.BuildLocator()
.
Another issue is that you mix two approaches: getting point coordinates from markups and crosshair. If you use markups then you don’t need to use crosshair, as you can get 3D positions from the markup points.
See a complete working example here (requires recent Preview Release of Slicer): https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Select_cells_of_a_using_markups_fiducial_points
Hi Andras,
Is there a way to select cells on the surface of mesh using onMouseClicked event.
Please suggest.
Regards,
Saima Safdar
It should be possible, but the example script that I linked above can already add markups and thus select cells on mouse click.
Andras I need to use only the mouse clicks to select the cells of a mesh without using the fiducials.
I understand adding three fiducial points to locate the cell will be not feasible.
I would want to select may cells from the surface of the brain where I can apply force. the craniotomy induced part I need to select and it will be different for each MRI. So I need to select the area by mouse. Any suggestions how can I do it?
Thank you so much for replies.
Looking forward to your answer.
Regards,
Saima Safdar
Can you write a bit more about what exactly you would like to achieve?
What is your input data? 3D volumes? Segmentations? Surface scans?
What would you like to do with the data? What would you like to get as end results?
Data = 3D volumetric brain Mesh
What would you like to do with the data? Need to select the surface cells from the brain portion where craniotomy was induced. I will be using the preoperative mri images.
What would you like to get as end results? after selecting cells I will save those cells in a file and will pass those cells along with the complete brain mesh to external Meshless algorithm to compute the craniotomy induced brain shift.
We have very good tool to mark regions in volumetric images: Segment Editor module. You can get cell IDs that overlap the craniotomy region by following these steps:
Hi Andras,
Can above be done through scripting. Please help
thank you
Regards,
Saima Safdar
Hi ANdras, I used the steps you told me in 3d slicer its producing the following results instead of only highlighting the segmented volume portion.
What am I doing wrong.
I loaded the skull stripped volume.
created a segmentation using scissors and mask volume effect.
used the new volume for input in probe volume model.
Could you please guide me what am I doing wrong I need only the segmented volume region to be selected on the model.
Please help.
Also I need to do all this through scripting.
Regards,
Saima Safdar
Hi andras,
I applied the probe volume with model filter. Got the cell ids using the script below:
for cellIndex in range(ncells):
cellpoints = mesh.GetCellPoints(cellIndex,idList)
scalarArray = mesh.GetPointData().GetArray(0)
#print(scalarArray)
numPoints = idList.GetNumberOfIds()
#print(numPoints)
for pointIndex in range(numPoints):
value = scalarArray.GetValue(idList.GetId(pointIndex))
if(value == 1):
print(cellIndex)
could you please tell me how could I get those cells coloured differently on the model.
Looking forward to your reply.
Thank you
Regards,
Saima Safdar
P.S. Also please tell me how can i use the probe volume with model using script. thankyou
While the VTK code above that gives you point IDs that have a certain scalar value is correct, you may find it easier to get the point data as numpy array and use numpy for processing:
import numpy as np
voxelValues = slicer.util.arrayFromModelPointData(getNode('Output Model'), 'NRRDImage')
pointIDs = np.where(voxelValues == 1)
You can use Models module / Display / Scalars section to color a model by a selected scalar.
“Probe volume with model” module is a CLI module, so you can run it from Python as described here.
n = getNode(“Output Model_1”)
n
(MRMLCorePython.vtkMRMLModelNode)0000023BCBDE8E28
voxelValues = slicer.util.arrayFromModelPointData(n, ‘NRRDImage’)
Traceback (most recent call last):
File “”, line 1, in
File “C:\Users\22374464\AppData\Local\NA-MIC\Slicer 4.11.0-2019-07-06\bin\Python\slicer\util.py”, line 1009, in arrayFromModelPointData
arrayVtk = modelNode.GetPolyData().GetPointData().GetArray(arrayName)
AttributeError: ‘NoneType’ object has no attribute ‘GetPointData’
getting the above error. Why dont understand?
I need to color the selected cells. For example I want to color the cell in the model. I am getting the location of that cell then using that location to set the activescalar. is it right. I dont know how to color. Any help?
nn = slicer.util.getNode(outputVolume.GetID())
d = nn.GetModelDisplayNode()
l = nn.GetMesh().GetCellLocationsArray()
v = l.GetValue(4740)
d.SetActiveScalar(‘R’,v)
d.SetAndObserveColorNodeID(‘FullRainbow’)
d.ScalarVisibilityOn()
d.AutoScalarRangeOn()
Hi Andras,
Is there a way to change the color for different cells in a 3d volumetric mesh by scripting. i know cell ids I need to change the color for those cells. How can I do it. please guide
Thank you
Regards,
Saima Safdar