How to record vtkCamera transform matrix?

Dear all,
recently I met a problem.
In Volume Rendering module, I created a volume rendering with a vtkMarkupsROI named nodule_roi. The nodule volume is surrounded by nodule_roi.
Firstly, I adjust 3d view controller to A. So in the world coordinate system, the camera is in the axis of negative y (-y).

Secondly, I rotate the nodule volume to any direction. Of course I know, the nodule volume is not rotated anyway in the world, the camera is rotated actually. As the nodule volume and nodule_roi is related, so the nodule volume and nodule_roi seems to be rotated in the same time.
This will cause the front plane of nodule roi is not vertical to the line between the center of nodule volume and camera position.

So, I want to record the transform matrix of camera during the rotation, and apply this transform matrix to the nodule roi, to achieve the front plane of nodule roi is always vertical to the line, between center of nodule volume and current camera position.

This picture is I adjust the nodule roi manually, rotate by three axis, to achieve the result I expected to achieve. But I want to achieved it automatically, by recording the transform matrix of camera, then apply to the nodule roi.

This is the method I think, or may be there are more efficient way to achieve this goal.
Any advice will be appreciated! @lassoan

World you like to automatically rotate the volume rendering clung ROI to keep its axes aligned with the camera’s normal and view-up axes?

Thank you for your reply.
I upload a picture to show my goal.

Actor is as camera, Cube and shpere display volume and nodule, and the plane source represent the front plane of vtkMarkupsROI.

The first picture, the volume rendering is +A, adjust view controller to A.
The second picture, the volume rendering is rotated by user. Now, If I add a button, when I push the button, I hope the vtkMarkupsROI is rotated, and the front plane of ROI is vertical to the line between nodule center and camera pos, not surround the volume as before.

According test, I find a interface of the camera, which is camera.GetViewTransformMatrix().
If I rotate the volume by any direction, and I called the camera.GetViewTransformMatrix(), I can get a rotation matrix of camera. Then, I transpose the camera view transfrom matrix, and apply the vtkMarkupsROI, then the ROI will rotate, to achieve the front plane of ROI is vertical the line between nodule center and camera.

But the center of ROI is not aligned to nodule center. And I called SetCenter() with the nodule center, then the ROI will moved to the destination as the second picture showed.

    # Get camera view transform matrix & Matrix transpose
    threeDView = slicer.app.layoutManager().threeDWidget(0).threeDView()
    renderer = threeDView.renderWindow().GetRenderers().GetFirstRenderer()
    camera = renderer.GetActiveCamera()
    camera_trans_matrix = camera.GetViewTransformMatrix()

    matrix_zero = [0] * 16
    origin_matrix.DeepCopy(matrix_zero, origin_matrix)
    camera_trans_reverse = np.array(matrix_zero).reshape(4, 4).transpose()
    roiNode.ApplyTransformMatrix(slicer.util.vtkMatrixFromArray(camera_trans_reverse))

I would not recommend to mess with the camera matrices but use the camera’s SetFocalPoint (defines center of rotation), and SetPosition+SetViewUp (defines orientation) methods instead. You can also attach an observer to the camera and keep the ROI node parallel with the camera normal and up vector, if you want to keep the target cut in half from various viewing directions.

1 Like

Thank you for reply and supplied two methods.

Frist method, As the volume and ROI use the single camera. If I called interface of camea, such as SetFocalPoint, SetPosition and SetViewUp, the volume position and orientation displayed will be changed at the same time, which is not to be expected. I only want to rotate the ROI, the volume can not be rotated or moved at the same time.

Second method, could you please show me some example codes, I am not familiar with how to add observer with camera, and applied the camera rotate events to the ROI, to achieve my target.

Any advice will be appreciated!