How to add a widget in a view with rotation

I am creating a component that renders 2D images and STL file.
In both cases or at least in the STL files I need to have interaction, for example zoom and rotate.
I have this code:
const render2D = async (vtk2DRefs, imgSrc) => {
const renderWindow = vtkRenderWindow.newInstance()
const renderer = vtkRenderer.newInstance();
renderer.setBackground([242 / 255, 246 / 255, 254 / 255]);

const mapper = vtkImageSliceMapper.newInstance();
const actor = vtkImageSlice.newInstance();

const data = vtkImageData.newInstance();

async function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.onload = () => resolve(img);
img.onerror = (error) => reject(error);
});
}

const img = await loadImage(imgSrc);
const canvas = document.createElement(‘canvas’);
const ctx = canvas.getContext(‘2d’);

canvas.width = img.width;
canvas.height = img.height;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

const imageDataArray = new Uint8Array(imageData.data);
const dataArray = vtkDataArray.newInstance({
numberOfComponents: 4,
values: imageDataArray
});

data.setDimensions(img.width, img.height, 1);
data.setSpacing(1, 1, 1);
data.setOrigin(0, 0, 0);
data.getPointData().setScalars(dataArray);

mapper.setInputData(data);
actor.setMapper(mapper);
actor.rotateX(180);

const openGLRenderWindow = vtkOpenGLRenderWindow.newInstance();
renderWindow.addView(openGLRenderWindow);
openGLRenderWindow.setContainer(vtkContainerRef.current);

const interactor = vtkRenderWindowInteractor.newInstance();
interactor.setView(openGLRenderWindow);
interactor.initialize();
interactor.setContainer(vtkContainerRef.current);

interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance())

openGLRenderWindow.setSize(
vtkContainerRef.current.clientWidth,
vtkContainerRef.current.clientHeight
);

renderer.addViewProp(actor);
renderWindow.addRenderer(renderer);

const widgetManagerForms = vtkWidgetManager.newInstance()
widgetManagerForms.setRenderer(renderer)
widgetManagerForms.disablePicking()

vtk2DRefs.current = {
widgetManagerForms,
renderWindow,
mapper,
actor,
renderer,
openGLRenderWindow,
interactor,
};

renderer.resetCamera();
renderWindow.render();
}

and this is to add a vtkEllipseWidget:

const AddCircle = () => {
const widget = vtkEllipseWidget.newInstance({
modifierBehavior: {
None: {
[BehaviorCategory.PLACEMENT]: ShapeBehavior[BehaviorCategory.PLACEMENT].CLICK_AND_DRAG,
[BehaviorCategory.POINTS]: ShapeBehavior[BehaviorCategory.POINTS].DIAMETER,
[BehaviorCategory.RATIO]: ShapeBehavior[BehaviorCategory.RATIO].RADIUS
}
}
})

const handle = vtk2DRefs.current.widgetManagerForms.addWidget(widget, ViewTypes.YZ_PLANE)
vtk2DRefs.current.widgetManagerForms.grabFocus(widget)

handle.setActiveColor(0, 0)

handle.getRepresentations()[0].getMapper().setScalarVisibility(false)
handle.getRepresentations()[0].getActor().getProperty().setColor(8 / 255, 29 / 255, 73 / 255)
handle.getRepresentations()[1].getMapper().setScalarVisibility(false)
handle.getRepresentations()[1].getActor().getProperty().setColor(8 / 255, 29 / 255, 73 / 255)

handle.getRepresentations()[1].setDrawBorder(true)
handle.getRepresentations()[1].setDrawFace(false)
handle.getRepresentations()[1].setOpacity(1)

handle.onStartInteractionEvent(() => {
  setCurrentHandle(handle)
})

recordAction({ type: 'add', widget: handle });
setNewWidget(true);

}

so, the problem is that when i do:
const handle = vtk2DRefs.current.widgetManagerForms.addWidget(widget, ViewTypes.YZ_PLANE)

the interaction with the 2D and 3D image (zoom and rotate) are crashed

I have to close mi application if i want to rotate the images.

Can you help me?
When i close the image i delete all the contexts:

const DeleteContexts = () => {

if (vtk3DRefs.current) {
  const { renderWindow, reader, mapper, actor, renderer, openGLRenderWindow, interactor, style } = vtk3DRefs.current;
  renderWindow.delete();
  reader.delete();
  mapper.delete();
  actor.delete();
  renderer.delete();
  openGLRenderWindow.setContainer(null);
  openGLRenderWindow.delete();
  interactor.delete();
  style.delete();
  vtk3DRefs.current = null;
}
if (vtk2DRefs.current) {
  const { widgetManagerForms, renderWindow, mapper, actor, renderer, openGLRenderWindow, interactor } = vtk2DRefs.current;
  // widgetManagerLabel.delete();
  widgetManagerForms.delete();
  // widgetManagerArrow.delete();
  renderWindow.delete();
  mapper.delete();
  actor.delete();
  renderer.delete();
  openGLRenderWindow.setContainer(null);
  openGLRenderWindow.delete();
  interactor.delete();
  vtk2DRefs.current = null;
}

}

but it still doest not working

1 Like

Hello,

Please, enclose all code blocks between a heading ```cpp and a trailing ```. Please, also enclose in-phrase code between two `. This improves readability quite a lot.

thank you,

PC