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} />;
}
}