about LineWidget?

How to handle the situation where the mouse and handle positions do not coincide when using LineWidget for distance measurement on MPR images?

the code

scene.widgetRender = vtkRenderer.newInstance();
  scene.widgetRender.setLayer(1);
  scene.renderWindow.setNumberOfLayers(2);
  scene.widgetRender.setInteractive(false);
  scene.renderWindow.addRenderer(scene.widgetRender);

  const update = () => {
    const baseCamera = scene.renderer.getActiveCamera();
    scene.widgetRender.getActiveCamera().set({
      viewUp: baseCamera.getViewUp(),
      position: baseCamera.getPosition(),
      viewAngle: baseCamera.getViewAngle(),
      focalPoint: baseCamera.getFocalPoint()
    });
  };
  update();

  scene.widgetManager = vtkWidgetManager.newInstance(ViewTypes.SLICE);
  scene.widgetManager.disablePicking();
  scene.widgetManager.setRenderer(scene.renderer);
  scene.widgetManager.setRenderer(scene.widgetRender);

  scene.widgets = {};
  scene.handles = {};

  scene.widgets.lineWidget = vtkLineWidget.newInstance();
  scene.handles.lineHandle = scene.widgetManager.addWidget(scene.widgets.lineWidget, ViewTypes.SLICE);
  scene.handles.lineHandle.onInteractionEvent(() => {
    const text = scene.widgets.lineWidget.getDistance().toFixed(2) + 'mm';
    scene.widgets.lineWidget.getWidgetState().getText().setText(text);
  });

  setupSVG(scene.widgetRender, scene.widgets.lineWidget);

Could it be linked to the window.devicePixelRatio value ?

Hello, Julien Finet, thank you for your response to this question.

The window.devicePixelRatio value is 1.25.

I implemented MPR using volume, volumMapper, GenericRenderWindow, and vtkInteractorStyleMPRSlice.
There is a renderer in GenericRenderWindow, but when I was using LineWidget for measurement, I recreated a renderer,
As with my code above, I’m not sure if this is the right thing to do. Currently, both the measurement line and value have been displayed, only the handle and mouse positions are not aligned.

Try with a window.devicePixelRatio of 1 (you can do it by changing your Operating System zoom ratio) and see if you still have the problem.
If the problem disapears with devicePixelRatio, it means it is the problem you are facing.
Check in VTK.js code where window.devicePixelRatio is being used to see what you need to change.

1 Like

I tried setting window.devicePixelRatio to 1, but the problem still persists.
In the above code, modify the code as follows:
scene.widgetRender.setInteractive(true);
The handle successfully overlaps with the mouse, but the length measured by LineWidget is incorrect.
So, is it related to certain location attributes, but I don’t know how to do it.

In MPR, measurements need to be performed on each slice, so that after switching slices, the measurement data will be hidden or displayed. Do I need to use components like PlaneManipulator, and is it helpful for the problem?

PlaneManipulator is used by the widget when “interacting” with the handles. It is not used when scrolling. If you want to the measure to “stick” to the current slice, you need to manually project it on the current slice whenever you are notified that the slice change. You can use the PlaneManipulator to do the projection of the handles if you want.

Thank you for your reply.
You’re right, I’ve found the reason.
Because I was working on LineWidget, I recreated the renderer
Currently, we have changed to using the same renderer, but a new issue has arisen where the drawn lines and handles are obstructed by the image. What should I do?
Behind

Looking forward to your answer! thank you!

Are you sure the widgets are in the same plane as the image slice ?
if so, you might want to consider resolveCoincidentTopology

1 Like

Sorry, I don’t know how to use ‘resolveCoincidentTopology’ Can you provide more hints.

I will add vtkImageData to the volume and add the volume to scene.renderer.
Then
scene. widgetManager. setRenderer (scene. renderer);
… Initialize widgets, such as LineWidget, RectangleWidget, etc

I use the following code to ensure that they are on the same plane, for example:
const camera = scene.renderer.getActiveCamera();
const manipulator = scene.widgets.rectangleWidget.getManipulator();
manipulator.setUserOrigin(…camera.getFocalPoint());
manipulator.setUserNormal(…camera.getDirectionOfProjection());

I don’t know if this is enough

Ideally you should not use the camera information to specify the manipulator but more the widget internal state, e.g. rcw.getWidgetState().getPlanes()[0].origin|normal (or something like that).

Widget representations have a coincidentTopologyParameters parameter. You may want to play with the Line offset + factor

I am trying to find
The getPlans method under scene. widgets. rectangWidget. getWidgetState() does not have this method.
After setting the coincideTologyParameters parameter, there was no change, and I am still searching.
From the measured image after the operation, the line is obscured by the image. This should be the main issue(coincidentTopologyParameters).
Behind

thank you!

getPlanes is in the widget state of the reslice cursor widget.
Another approach is to set 'relative’coincidentTopology polygon parameter on the image mapper, so that it “shift away from the camera” the rendering of the image.

I did not use resciceCursorWidget.
I am using volumMapper and trying to set the ‘relative’ coincideTopology parameter as you suggested.
thank you

Thanks for your help.

After loading the MPR using volume and volumMapper, I referred to the demo and have implemented and displayed lines for circles, ellipses, and rectangles.

But when using its LineWidget component to measure straight lines, the lines still cannot be displayed, and I have no other way. It’s really difficult for me, a beginner, to adjust the thickness and color of the lines to match the circular, elliptical, and rectangular styles.

Are the usage methods of LineWidget and PaintWidget different?
What should I do? I’m very distressed!

What happens if you slightly move towards the camera the line widget handles coordinates ?