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