Quick follow up to this, error pretty clear in the end.
Needed to update the useEffect to fire on a scalarVar state change and then improve the cleanup and rerender.
Further steps not included would be to save camera state so that a scalar change will not reset the camera as well - depends on use case I guess.
So, new “ShowPolydata.js”:
import { useRef, useEffect, useState } from 'react';
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
import vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';
import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
import vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
import vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';
import vtkInteractorStyleTrackballCamera from '@kitware/vtk.js/Interaction/Style/InteractorStyleTrackballCamera';
const ShowPolydata = ({ data }) => {
const vtkContainerRef = useRef(null);
const context = useRef(null);
const scalars = [{ name: 'scalarsA', arrayName: 'scalarsA' },
{ name: 'scalarsB', arrayName: 'scalarsB' },]
const [scalarVar, setScalarVar] = useState(scalars[1].arrayName)
useEffect(() => {
if ((!context.current) && (data)) {
//
const openglRenderWindow = vtkOpenGLRenderWindow.newInstance();
const renderWindow = vtkRenderWindow.newInstance();
const renderer = vtkRenderer.newInstance({ background: [0, 0, 0], });
renderWindow.addRenderer(renderer);
// Update data scalar variable
data.getPointData().setActiveScalars(scalarVar);
// mapper - add to actor
const mapper = vtkMapper.newInstance();
const actor = vtkActor.newInstance();
const lookupTable = vtkColorTransferFunction.newInstance();
lookupTable.applyColorMap(vtkColorMaps.getPresetByName('jet'));
lookupTable.updateRange();
mapper.setInputData(data);
mapper.setScalarModeToDefault();
mapper.setScalarRange(0, 1);
mapper.setLookupTable(lookupTable);
actor.setMapper(mapper);
actor.getProperty().setAmbient(1.0);
actor.getProperty().setDiffuse(0.9);
renderer.addActor(actor);
renderWindow.addView(openglRenderWindow);
openglRenderWindow.setSize(600, 500);
openglRenderWindow.setContainer(vtkContainerRef.current)
// Setup interactor and style
const interactor = vtkRenderWindowInteractor.newInstance();
interactor.setView(openglRenderWindow);
interactor.initialize();
interactor.bindEvents(vtkContainerRef.current);
interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance());
// all done - reset camera and render
renderer.resetCamera();
renderWindow.render();
context.current = {
openglRenderWindow,
renderWindow,
renderer,
data,
actor,
mapper,
};
}
return () => {
if (context.current) {
const { openglRenderWindow, actor, mapper, renderWindow, renderer } = context.current;
actor && actor.delete();
mapper && mapper.delete();
openglRenderWindow && openglRenderWindow.delete();
renderWindow && renderWindow.delete();
renderer && renderer.delete();
context.current = null;
if (vtkContainerRef.current) {
vtkContainerRef.current.innerHTML = "";
}
}
};
}, [vtkContainerRef, data, scalarVar]);
function resetCamera() {
if (context.current) {
context.current.renderer.resetCamera();
context.current.renderWindow.render();
}
};
const swapArray = (event) => {
if (scalarVar !== event.target.value) {
setScalarVar(event.target.value);
}
}
return (
<div>
<div ref={vtkContainerRef} ></div>
<div id="buttonRow" className="viewA-buttons">
<button onClick={resetCamera}>
Reset Camera
</button>
<tbody>
<tr>
<td><input type="radio"
value={scalars[0].arrayName}
checked={scalarVar === scalars[0].arrayName}
onChange={swapArray} />{scalars[0].name}</td>
<td><input type="radio"
value={scalars[1].arrayName}
checked={scalarVar === scalars[1].arrayName}
onChange={swapArray} />{scalars[1].name}</td>
</tr>
</tbody>
</div>
</div>
);
}
export default ShowPolydata;