Hello,
I am building a React app and I need to visualize some vtkjs scenes, and I want to add a scalar range widget like the one you can find on the Calculator example (https://kitware.github.io/vtk-js/examples/Calculator.html)
In my case the scene is loaded with vtkHttpSceneLoader, and I tried attaching a mapper with a lookupTable that I could update like in the example with lookupTable.updateMappingRange, but even though the mapping range is updated there is no effect on my scene, as if the scene just ignores the lookup table. I have tried several ways, including changing the lookupTable of all the mappers of my renderer but no success, the visualization doesn’t change. I have also tried to attach a vtkColorTransferFunction to the mapper as lookup table.
I think I am missing something here, maybe a simple concept I didn’t understand.
Here is my code:
class VtkViewer extends Component {
constructor(props) {
super(props);
this.fullScreenRenderer = null;
this.container = React.createRef();
this.updateScalarRange = this.updateScalarRange.bind(this);
}
componentDidMount() {
const { vtk } = window;
this.fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
rootContainer: this.container.current,
containerStyle: {},
});
this.renderer = this.fullScreenRenderer.getRenderer();
this.renderWindow = this.fullScreenRenderer.getRenderWindow();
// One of the tests: create a lookupTable from vtkColorTransferFunction
// I also tried with a regular vtkLookupTable instance
// this.lookupTable = vtkColorTransferFunction.newInstance();
// const preset = vtkColorMaps.getPresetByName('erdc_rainbow_bright');
// const dataRange = [0, 255];
// this.lookupTable.applyColorMap(preset);
// this.lookupTable.setMappingRange(...dataRange);
// this.lookupTable.updateRange();
this.mapper = vtkMapper.newInstance({
interpolateScalarsBeforeMapping: true,
useLookupTableScalarRange: false,
// lookupTable: this.lookupTable,
});
this.actor = vtkActor.newInstance();
// Add scalar range controller
this.addControlPanel();
if (_.isEmpty(vtk)) {
return;
}
// Step 1: only display the first vtk
const dataAccessHelper = DataAccessHelper.get('zip', {
zipContent: vtk[0],
callback: () => {
const sceneImporter = vtkHttpSceneLoader.newInstance({
renderer: this.renderer,
dataAccessHelper,
}, {
actor: this.actor,
mapper: this.mapper,
// lookupTable: this.lookupTable,
});
sceneImporter.setUrl('index.json');
this.onReady(sceneImporter);
},
});
}
onReady(sceneImporter) {
sceneImporter.onReady(() => {
this.renderWindow.render();
});
window.addEventListener('dblclick', () => {
sceneImporter.resetScene();
this.renderWindow.render();
});
}
addControlPanel() {
const { intl } = this.props;
this.fullScreenRenderer.addController(`
<table>
<tr><td>${intl.formatMessage({ id: 'labels.vtk.scalarRange' })}</td></tr>
<tr>
<td data-children-count="1">
<input class="min" type="text" style="width: 100%;" value="0">
</td>
<td data-children-count="1">
<input class="max" type="text" style="width: 100%;" value="1">
</td>
</tr>
</table>
`);
document.querySelector('.min').addEventListener('input', this.updateScalarRange);
document.querySelector('.max').addEventListener('input', this.updateScalarRange);
}
updateScalarRange() {
const min = Number(document.querySelector('.min').value);
const max = Number(document.querySelector('.max').value);
if (!Number.isNaN(min) && !Number.isNaN(max)) {
// this.lookupTable.setMappingRange(min, max);
// this.mapper.updateLookupTable();
this.renderer.getActors().forEach((actor) => {
actor.getMapper().getLookupTable().setMappingRange(min, max);
if (actor.getMapper().getLookupTable().updateRange) { // for vtkColorTransferFunction
actor.getMapper().getLookupTable().updateRange();
}
});
this.renderer.getActors().forEach((actor) => {
console.log(actor.getMapper().getLookupTable().getMappingRange());
});
this.renderWindow.render();
}
}
render() {
return <div className={style.container} ref={this.container} />;
}
}

