not getting what I require. What is the problem in the code. doesnt load models one by one when ever the new event occurs (new event is the adding of a fiducial for a each model)
def onMarkupsAdded(self, caller, event):
index=0
print(index)
index+=1
modelFileExt = "ply"
print(index)
modelDir = "/media/useradmin/Disk2/Slicer-5.3.0-2023-01-21-linux-amd64/Case1"
modelFiles = list(f for f in os.listdir(modelDir) if f.endswith("."+modelFileExt))
print(modelFiles)
placeModePersistence = 0
slicer.modules.markups.logic().StartPlaceMode(placeModePersistence)
modelNode = slicer.util.loadModel(modelDir + "/" + modelFiles[index])
def process(self, inputDir, inputVolume, outputVolume):
"""
Run the processing algorithm.
Can be used without GUI widget.
:param inputVolume: volume to be thresholded
:param outputVolume: thresholding result
:param imageThreshold: values above/below this threshold will be set to 0
:param invert: if True then values above the threshold will be set to 0, otherwise values below are set to 0
:param showResult: show output volume in slice viewers
"""
global index
print(inputDir)
if not inputVolume or not outputVolume:
raise ValueError("Input or output volume is invalid")
import time
startTime = time.time()
logging.info('Processing started')
logging.info('Search for .ply files')
modelDir = inputDir
modelFileExt = "ply"
import math
import os
modelFiles = list(f for f in os.listdir(modelDir) if f.endswith("."+modelFileExt))
print(modelFiles)
#load models and show in 3D view
#for modelIndex, modelFile in enumerate(modelFiles):
index = 0
#name = os.path.basename(modelFiles)
modelNode = slicer.util.loadModel(modelDir + "/" + modelFiles[index])
placeModePersistence = 1
slicer.modules.markups.logic().StartPlaceMode(placeModePersistence)
markup_node = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode")
markup_node.AddObserver(slicer.vtkMRMLMarkupsNode.PointAddedEvent, self.onMarkupsAdded)
My first thought was that you would load the next model immediately when you placed the point, but actually you only want to switch to the next model when you confirmed that the markup was placed at the correct position (you rotate the view around and adjust the point position as needed). So, instead of observing the point added event, I would recommend to switch to the next model using a keyboard shortcut.
In the function that is executed by thr keyboard shortcut, you can check the number of points in the markup point list and from that you would know how many models are annotated already and load the next one.
in the keyboard shortcut, is there a possibility to pass arguments to the called function.
shortcut = qt.QShortcut(slicer.util.mainWindow())
shortcut.setKey(qt.QKeySequence(“s”))
shortcut.connect( “activated()”, self.switchNextModel, like here can we pass arguments)
I am not understanding how the user will add the markup control points after locating the position on the model. I want to set the number of control points as well for a given model not just one control point for all models. For example in future user can adjust the number of control points to be added for a given model.
after adding the specified number of control points I will use keyboard shortcut to move to next model.
I am stuck with the adding of control points by the user. what is the best way to add the control points.
Should there be a button to select for adding control points or a keyboard shortcut to add control points.
and would be switching between node placement mode for control points.
The initialize_points function is below:
N_POINT = 3
def initialize_points(self):
slicer.modules.markups.logic().SetActiveListID(self.markup_node)
self.markup_node.SetControlPointLabelFormat(‘P%d’)
for i in range(1, self.N_POINT + 1):
self.markup_node.AddControlPoint([0, 0, 0])
self.markup_node.UnsetAllControlPoints()
self.markup_node.SetMaximumNumberOfControlPoints(self.N_POINT)
The addNewNode function is below: I want this function to do the following 1) convert mouse cursor to control point placement mode and then add no more than N_POINT.
for i in range(n_point):
self.markup_node.UnsetNthControlPointPosition(i)
self.markup_node.SetControlPointPlacementStartIndex(i)
self.markup_node.SetNthControlPointLabel(index, "p"+i)
slicer.modules.markups.logic().StartPlaceMode(0)
This is too much code and to fragmented to copy-paste. If you send a link to your module source code on Github then I can have a look and give you some feedback.
Hi Andras,
I have added the code on github and added you in collaboration.
can you see the code?
Please let me know.
The switchnextmodel is not working with the shortcut key.
how can I get access to the df variable created. it is a list of models and I am keeping track using this list for the next model to . be uploaded.
How to lock the control points when the user move the model to locate the point
Hi Andras,
I have added the code on github and added you in collaboration.
can you see the code?
Please let me know.
The switchnextmodel is not working with the shortcut key.
how can I get access to the df variable created. it is a list of models and I am keeping track using this list for the next model to . be uploaded.
How to lock the control points when the user move the model to locate the point
Hi Andras,
I am putting the fiducials at each vertex for all the cells (triangles) in a surface model. I am using the following code. I need this for the next step where user needs to select a point in a surface model.
Problem: its very very time consuming to create a markup file for all the models (4000).
How can I improve the following code? or is there any way to highlight the vertices for all the cells in a model instead of looping through each cell and than creating a point at each vertex.
def process(self, dataDirectoryPath, showResult=True):
“”"
Run the processing algorithm.
Can be used without GUI widget.
:param dataDirectoryPath: path to the data directory containing .ply files
"""
if not dataDirectoryPath:
raise ValueError("no Data folder selected")
import time
startTime = time.time()
logging.info('Processing started')
logging.info('Search for .ply files')
modelDir = dataDirectoryPath
modelFileExt = "ply"
modelFiles = list(f for f in os.listdir(modelDir) if f.endswith("."+modelFileExt))
print(modelFiles)
import pandas as pd
#dataframe to store all the ply files name along with index
df = pd.DataFrame(modelFiles, columns =['FileNames'])
filepath = dataDirectoryPath+'/models_ids.csv'
df.to_csv(filepath, index=True)
idFile = 0
for idFile in range(idFile,len(df)):
print(df.iloc[idFile].FileNames)
markupsNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode")
markupsNode.CreateDefaultDisplayNodes()
modelFileName = df.iloc[idFile].FileNames
modelNode = slicer.util.loadModel(dataDirectoryPath+ "/" + modelFileName)
size = len(modelFileName)
modelFileName = modelFileName[:size - 4]
print(modelFileName)
markupsNode.SetName(modelFileName)
print(df.index.get_loc(idFile))
meshModel = modelNode.GetMesh()
points = meshModel.GetPoints()
nPoints = points.GetNumberOfPoints()
for i in range(nPoints):
p = points.GetPoint(i)
markupsNode.AddControlPoint(p[0],p[1],p[2])
markupsNode.SetNthControlPointLocked(i, True)
d = markupsNode.GetDisplayNode()
d.PointLabelsVisibilityOff()
#saving the markup point and cleaning the scene
slicer.util.saveNode(markupsNode, os.path.join(dataDirectoryPath, modelFileName+".mrk.json"))
slicer.mrmlScene.Clear(0)
stopTime = time.time()
logging.info(f'Processing completed in {stopTime-startTime:.2f} seconds')
In the next step after creating all these points, there is another program where the user select the point and the respective point coordinates are saved in a file.
can i still retrieve the point coordinates with the glyph?
Any example scripts?