Make event Transform matrix not modified

Hi all

I would like to track a specific transform matrix and change the Qt label to ‘on’ when it changing and to ‘off’ when it doesn’t.

I’ve implemented the code below, but is there a more efficient way?

I’m particularly concerned about the while loop causing performance issues in the program.


        ReferenceToTrackerNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLinearTransformNode", "ReferenceToTracker")
        TranCenterToRefernceNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLinearTransformNode", "TranCenterToReferenc")
        StylusTipToReferenceNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLinearTransformNode", "StylusTipToReference")


        self.lastMatrix = [np.zeros((4, 4)), np.zeros((4, 4)), np.zeros((4, 4))] 
        transformMatrix = vtk.vtkMatrix4x4()
        def checkTransformNode(node, lastMatrix):
            name = node.GetName()
            matrix_arr_origin = np.zeros((4, 4))

            for i in range(0, 4):
                for j in range(0, 4):
                    matrix_arr_origin[i, j] = (transformMatrix.GetElement(i, j))
            if np.array_equal(lastMatrix, matrix_arr_origin):
                if name== "ReferenceToTracker":
                    self.ui.referenceLabel.setText("Reference Off")
                    self.ui.referenceLabel.setStyleSheet("color: #FA8072; width: 15px; ")
                elif name== "TranCenterToReferenc":
                    self.ui.transducerLabel.setText("Transducer Off")
                    self.ui.transducerLabel.setStyleSheet("color: #FA8072; width: 15px; ")
                elif name== "StylusTipToReference":
                    self.ui.stylusLabel.setText("Stylus Off")                    
                    self.ui.stylusLabel.setStyleSheet("color: #FA8072; width: 15px; ")
                if name== "ReferenceToTracker":
                    self.ui.referenceLabel.setText("Reference On")
                    self.ui.referenceLabel.setStyleSheet("color: #4D69E8; width: 15px; ")
                elif name== "TranCenterToReferenc":
                    self.ui.transducerLabel.setText("Transducer On")
                    self.ui.transducerLabel.setStyleSheet("color: #4D69E8; width: 15px; ")
                elif name== "StylusTipToReference":
                    self.ui.stylusLabel.setText("Stylus On")
                    self.ui.stylusLabel.setStyleSheet("color: #4D69E8; width: 15px; ")
            # save current matrix
            if name== "ReferenceToTracker":
                self.lastMatrix[0] = matrix_arr_origin
            elif name== "TranCenterToReferenc":
                self.lastMatrix[1] = matrix_arr_origin
            elif name== "StylusTipToReference":
                self.lastMatrix[2] = matrix_arr_origin

        timer = QTimer()
        timer.timeout.connect(lambda: checkTransformNode(ReferenceToTrackerNode, self.lastMatrix[0]))
        timer.timeout.connect(lambda: checkTransformNode(TranCenterToRefernceNode, self.lastMatrix[1]))
        timer.timeout.connect(lambda: checkTransformNode(StylusTipToReferenceNode, self.lastMatrix[2]))
        # start event loop 
        while True:

You can use the “Watchdog” module in SlicerIGT extension to monitor a transform node and display a message when it is not being continuously updated anymore (and optionally play a sound signal, too). This can be used for example for warning the user when an optical tracker marker is occluded. You can also add an observer to the vtkMRMLWatchdogNode to get a notification in your module when status of a transform changes.

The documentation for vtkMRMLWatchdogNode is limited, so could you provide more examples? I attempted to create it like this, but the process seems too fast, and on-off events are occurring repetitively.

ReferenceToTrackerNode.AddObserver(slicer.vtkMRMLWatchdogNode.TransformModifiedEvent, lambda caller, event: checkTransformNode(caller, event, self.lastMatrix[0]))

You need to observe the watchdog node. The nodes are quite well documented, except maybe a few properties that are mostly self-explaining, see:

However, I would recommend to start with just using the GUI. Normally you don’t need to write any code to use this module, as you can configure what transforms are observed, what messages are displayed and where, and save the scene. You can save all other configuration settings (transform hierarchy, display options of all nodes, OpenIGTLink connection information, etc.) in the scene as well. When you want to start navigation then it is enough to load the scene and everything should work.