I try to programme with python to detect the changes of a vector in the object in real time.
I have a volume in the scene, and there is a tranform node M on it. a is a vector in the object, when the object was rotating, the vector a was also rotating with b = a*M. so now I want to detect the vector b in real-time when M was changing. How can I write code with python , thank you.
You can add an observer to the transform node. Search the script repository for AddObserver
and you’ll find lots of examples.
I have tried but the detected vector can’t change in real time.
my code is as following:
def monitorAndAdjustTransform(self):
print("onTransformModified called") #test
if not self.transformNode:
return
vtkMatrix = vtk.vtkMatrix4x4()
self.transformNode.GetMatrixTransformToWorld(vtkMatrix)
npMatrix = np.array([[vtkMatrix.GetElement(i, j) for j in range(4)] for i in range(4)])
normal_vector = np.array([-0.19911008, 0.16549629, 0.96590173])
transformed_vector = np.dot(npMatrix[:3, :3], normal_vector)
target_vector1 = np.array([0, 0, 1])
target_vector2 = np.array([0, 0, -1])
# calculate np.dot
dot1 = np.dot(transformed_vector, target_vector1)
dot2 = np.dot(transformed_vector, target_vector2)
print("Transformed vector: ", transformed_vector)
print("Dot product with (0,0,1): ", dot1)
print("Dot product with (0,0,-1): ", dot2)
# set threshold
threshold = 0.97
if abs(dot1) >= threshold or abs(dot2) >= threshold:
print("Normal vector is aligned with Z-axis, limiting Y-axis rotation")
npMatrix[0, 1] = max(0, npMatrix[0, 1])
npMatrix[2, 1] = max(0, npMatrix[2, 1])
for i in range(4):
for j in range(4):
vtkMatrix.SetElement(i, j, npMatrix[i, j])
self.transformNode.SetMatrixTransformToParent(vtkMatrix)
def loadNextFile(self):
#---Load the next NRRD file from the list and remove the previous one.
# Check if there are more files to load
if self.currentFileIndex < len(self.nrrdFiles):
filePath = self.nrrdFiles[self.currentFileIndex]
volumeNode = slicer.util.loadVolume(filePath)
self.currentFileIndex += 1
# Enable volume rendering for the loaded volume
if volumeNode:
self.applyCustomColorMap()
self.initializeVolumeRendering()
#self.enableVolumeRendering(volumeNode)
#-----
#self.onApplyTransformClicked()
volumeName = volumeNode.GetName()
#print("viewname:", volumeName)
self.update3DViewerTextAnnotation(volumeName)
self.transformNode = slicer.vtkMRMLLinearTransformNode()
self.transformNode.SetName('LinearTransform')
slicer.mrmlScene.AddNode(self.transformNode)
# Apply the transform node to the volume node
volumeNode.SetAndObserveTransformNodeID(self.transformNode.GetID())
self.transformNode.CreateDefaultDisplayNodes()
self.transformNode.GetDisplayNode().SetEditorVisibility(True)
# detect
self.initializeTransformMonitoring()
slicer.mrmlScene.Modified()# update scence
slicer.app.processEvents()
The detect function was integrated to loadnrrdfile function, but can’t be effect, could you please help me check.
Looks like you need a line like this:
self.transformNode.AddObserver(self.transformNode.TransformModifiedEvent, self. monitorAndAdjustTransform)
I htried your code line, but it is not correct.
I have changed my code with more function. now the problem is that it can’t automatically show the vector changing when I rotate the object with mouse. can you please help me check the problem?
def loadNextFile(self):
#—Load the next NRRD file from the list and remove the previous one.
self.removeCurrentVolume()
self.removeAllTransformNodesAndInteractionBoxes()
# Check if there are more files to load
if self.currentFileIndex < len(self.nrrdFiles):
filePath = self.nrrdFiles[self.currentFileIndex]
volumeNode = slicer.util.loadVolume(filePath)
self.currentFileIndex += 1
# Enable volume rendering for the loaded volume
if volumeNode:
self.applyCustomColorMap()
self.initializeVolumeRendering()
#-----
#self.onApplyTransformClicked()
volumeName = volumeNode.GetName()
#print("viewname:", volumeName)
self.update3DViewerTextAnnotation(volumeName)
self.transformNode = slicer.vtkMRMLLinearTransformNode()
self.transformNode.SetName('LinearTransform')
slicer.mrmlScene.AddNode(self.transformNode)
# Apply the transform node to the volume node
volumeNode.SetAndObserveTransformNodeID(self.transformNode.GetID())
self.transformNode.CreateDefaultDisplayNodes()
self.transformNode.GetDisplayNode().SetEditorVisibility(True)
# initialization
self.initializeTransformMonitoring()
self.testTriggerEvent()
slicer.mrmlScene.Modified()# update scence
slicer.app.processEvents()
print("Transform node has been created and applied to the volume node.")
##-----
else:
# Reset the index or inform the user all files have been loaded
slicer.util.infoDisplay("No more NRRD files to load.", windowTitle='Info')
def testTriggerEvent(self):
if self.transformNode:
matrix = vtk.vtkMatrix4x4()
matrix.Identity()
matrix.SetElement(0, 0, 0.99)
self.transformNode.SetMatrixTransformToParent(matrix)
self.transformNode.Modified()
def monitorAndAdjustTransform(self):
print("onTransformModified called")
if not self.transformNode:
return
vtkMatrix = vtk.vtkMatrix4x4()
self.transformNode.GetMatrixTransformToWorld(vtkMatrix)
npMatrix = np.array([[vtkMatrix.GetElement(i, j) for j in range(4)] for i in range(4)])
normal_vector = np.array([-0.19911008, 0.16549629, 0.96590173])
transformed_vector = np.dot(npMatrix[:3, :3], normal_vector)
target_vector1 = np.array([0, 0, 1])
target_vector2 = np.array([0, 0, -1])
dot1 = np.dot(transformed_vector, target_vector1)
dot2 = np.dot(transformed_vector, target_vector2)
print("Transformed vector: ", transformed_vector)
print("Dot product with (0,0,1): ", dot1)
print("Dot product with (0,0,-1): ", dot2)
threshold = 0.97
if abs(dot1) >= threshold or abs(dot2) >= threshold:
print("Normal vector is aligned with Z-axis, limiting Y-axis rotation")
npMatrix[0, 1] = max(0, npMatrix[0, 1])
npMatrix[2, 1] = max(0, npMatrix[2, 1])
for i in range(4):
for j in range(4):
vtkMatrix.SetElement(i, j, npMatrix[i, j])
self.transformNode.SetMatrixTransformToParent(vtkMatrix)
def cleanup(self):
if self.transformNode and self.observerTag:
self.transformNode.RemoveObserver(self.observerTag)
self.observerTag = None
def onTransformModified(self, caller, event):
print("Transform modified detected")
self.monitorAndAdjustTransform()
def initializeTransformMonitoring(self):
if self.transformNode:
if self.observerTag:
self.transformNode.RemoveObserver(self.observerTag)
# add observer
self.observerTag = self.transformNode.AddObserver(vtk.vtkCommand.ModifiedEvent, self.onTransformModified)
print("detect")
Hi Pieper,
I have got the answer from scipt repository.
Thank you so much.