how to use rotateX in volume rendering

The volume actor renders fine to begin with. However, once I rotate it (uncomment the rotateX line) it looks terrible and wrong, why is that?

const actor = imageDataToVol3D(image_data_obj);
renderer.addActor(actor);
//actor.rotateZ(300);
...
genericRenderWindow.resize();
renderWindow.render();

Hello,

Can you please post two images of what you’re getting: a) when you uncomment the line in question; b) when you keep it?

regards,

Paulo

with actor.rotateX(300) it is terribly wrong

without it looks perfectly fine

Is there a direction matrix set on the image data?

it might be a good point, but i am not sure what exactly the matrix you are talking about, or how to set it.

Actually I am not sure how to display/specify the image data with a different orientation so I am trying to rotate it, which does not work the way I want.

Below are some information I can get from chrome console

information for actor

actor.get().origin 
(3) [0, 0, 0]
actor.get().bounds
(6) [1, -1, 1, -1, 1, -1]
actor.get().position
(3) [0, 0, 0]

information for mapper = actor.get().mapper.get()

sampleDistance: 0.9122243804637651
imageSampleDistance: 1, maximumSamplesPerRay: 1000
bounds: (6) [1, -1, 1, -1, 1, -1]

Information below is for the inputData = actor.get().mapper.get().inputData[0].get()

extent: (6) [0, 511, 0, 511, 0, 301]
origin: (3) [-197.6328125, -296.6328125, -60]
spacing: (3) [0.734375, 0.734375, 1.5]
direction: Float64Array(9) [1, 0, 0, 0, 1, 0, 0, 0, 1,
indexToWorld: Float64Array(16) [0.734375, 0, 0, 0, 0, 0.734375, 0, 0, 0, 0, 1.5, 0, -197.6328125, -296.6328125, -60, 1,
worldToIndex: Float64Array(16) [1.3617021276595744, 0, 0, 0, 0, 1.3617021276595744, 0, 0, 0, 0, 0.6666666666666666, 0, 269.1170212765957, 403.9255319148936, 40, 1
actor.get().mapper.getInputData().getBounds()
(6) [-198, 178, -297, 79, -60.75, 392.25]

from the provided data you can see, in inputData, X is from human right to left, Y is from front to back, Z is from feet to head. thus the DICOM coordinate system is LPS. the DICOM (0,0,0) corresponds to VTK world origin (0,0,0), and the DICOM (X,Y,Z) axes are aligned with world (X,Y,Z) when displaying the data, so so far everything can be explained. The strange thing happens when actor.rotateX() or any rotation takes place. Does it have anything to do with camera clipping range stuff? but I called resize() as you can see in the code.

Translation seems fine. Running actor.setPosition(100,0,100) it renders fine.

Remember that rotation is with respect to the origin. Often people apply a rotation expecting it to rotate on its axis but are surprised to have it “orbited” somewhere else. If your object is far from the origin, you can translate it to the origin, rotate and translate back to have the desired effect. Judging from the XYZ values in your images, rotation is doing exactly what is supposed to do: a rotation about the X axis by 300 degrees.

Maybe you’re refering to what it seems to be an artifact in the first figure (marked with the red arrows in the figure below), right?

Paulo, thank you for your comments. You are absolutely right. The volume image indeed appears to have been rotated around world X axis for 300 degree. However, some part of the skeleton is missing and some strange artifact are generated so it is terribly wrong. Not sure why this happens. If I rotate 300 and rotate back ( -300) it is Ok, but any other rotation degree leads to similar issues.

Also, as you can see from the data provided, the image origin (0,0,0) is inside the volume but not at the geometric center of the volume, and the image origin (0,0,0) is also aligned with the world origin (0,0,0) in vtk.js rendering scene.

Ok, right. So, you may need to apply the same rotation to possibly other elements in your scene. A cutting plane, perhaps? Or is that the entire volume data?

The scene has only one volume, and the volume is from a vtkImageData structure. It looks fine under the camera rotation. When I rotate the volume, why should I rotate other objects in the scene? Also, as you can see after the rotation the bone is not complete anymore, and the artifacts are certainly generated from the volume data because of its color(just not sure how and why).

Is there any other DICOM volume image rotation example? If so it certainly helps to debug this issue.

What else do you have in the scene. Can you post the entire scene-building code?

I finally found the issue was caused by using FullScreenRenderWindow or GenericRenderWindow

if I use the following setup

import vtkFullScreenRenderWindow from “@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow”;
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
//container: document.getElementById(“app”),
background: [0.3, 0.3, 0.3]
});
const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();

it works with rotation, but if I use

import vtkGenericRenderWindow from “@kitware/vtk.js/Rendering/Misc/GenericRenderWindow”;
const genericRenderer = vtkGenericRenderWindow.newInstance({ background: [0.3, 0.3, 0.3]});
genericRenderer.setContainer(document.getElementById(“app”));
const renderer = genericRenderer.getRenderer();
const renderWindow = genericRenderer.getRenderWindow();

it can display the image but will have problems when rotating.

could someone tell me

  1. what’s the difference with these two setups. can FullScreenRenderWindow be used properly within a given div container, how is the performance, does it use openGLRenderWindow underneath?
  2. if FullScreenRenderWindow has limitations, could some one provide a solution for using GenericRenderWindow correct when rotating a volume?

Waiting for your help and reply. Thanks!

Hello,

Do you mind if you enclose the code between two ```? That improves readability quite a lot.

thanks

this becomes a mystery now. I’m including the code here. It works on codesandbox online editor, but not local development using vscode.

index.html (365 Bytes)
test_renderwindow.js (2.8 KB)
tar file is here in case the browser does not allow js download.
test.rar (1.2 KB)

Even on codesandbox, genericRenderWIndow does not work. On my local machine, nothing works. Could someone check and provide a working example.

Please help. Thanks!

this is a serious bug. Originally I thought this just won’t work with vtk.js at all, until I tested it on
codesandbox,

you can check it here by switching between full screen and generic render window.

https://jgzzhh.csb.app/

full screen works with codesanbox but on my local computer with vscode, neither works.

Since it works, so it shouldn’t be so difficult to fix it. Please do look into this issue and solve it as this is indeed a serious bug. When a volume cannot be rotated the app functionality is rather restricted. Thanks!

Could someone help to verify or acknowledge this issue.

The code to repeat is really simple, just a few lines of code, easy to read.

you can switch between createGenericRenderWindow and createFullScreenRenderWindow to check.

Unfortunately, on my local machine with vscode neither works, so I could not debug myself by comparing the difference step by step. It may need someone with deeper knowledge of vtk.js.

Thanks.

Please help. Either confirm or reject this issue. Thanks.

I would like to work on some features if this (rotation issue) can be done or fixed. Originally I thought this is too difficult to fix in vtk.js. But now I see it works on codesandbox with fullscreenrenderwindow, i guess it could just some hidden setting needs to be fixed in vtk,js.

@gzt036 Have you tried using a vtkRenderWindow instead of the generic render window?

Thanks. I’ll try. I’m not that deep into vtk.js so I just followed some examples. If you happen to know how to make the code change to use vtkRenderWindow please provide a function createVTKenderWindow. Thanks!

Also need to mention, if you remove rotateZ(3) line, and everything works, it works with FullScreen or Generic renderWindow, and it works on my local machine too.

Also, I could not really debug this issue and nothing works on my local machine right now if rotateZ() is called. So I cannot really compare and narrow down the issue.

Nevertheless, I’ll check and try with vtkRenderWindow on codesandbox.

Could you help to confirm the problem is indeed there?

Also, what is the supposed VTK way to have a rendering setup within a container?

I have a drafted version copying testMultipleRender.js form RenderWindow directory but it does not work at all.

function createVTKRenderWindow(
  containerRef,
  option = { background: [0.3, 0.3, 0.3] }
) {
  const renderWindowContainer = document.createElement("div");
  containerRef.appendChild(renderWindowContainer);
  const renderWindow = vtkRenderWindow.newInstance();
  const renderer = vtkRenderer.newInstance();
  renderer.setViewport(0, 0, 1, 1);
  renderWindow.addRenderer(renderer);
  renderer.setBackground(0.3, 0.3, 0.3);
  const glwindow = renderWindow.newAPISpecificView();
  glwindow.setContainer(renderWindowContainer);
  renderWindow.addView(glwindow);
  glwindow.setSize(400, 400);
  const interactor = null;
  return { renderer, renderWindow, interactor };
}

Could someone with insight of VTK js help to provide a proper version of createVTKRenderWindow, all needed is to have a rendering set up within containerRef.

You were close. You can look at that example for more details.