3D volume data from react using vtkImageData

Hello VTK support. I am new to vtk.js.
I am trying to render a plain 3d volume data in react app - following examples, but it’s not working. Here is my code:


import { useRef, useEffect } from 'react';
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
import vtkColorMaps from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps";

import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
import vtkVolume           from '@kitware/vtk.js/Rendering/Core/Volume';
import vtkVolumeMapper    from '@kitware/vtk.js/Rendering/Core/VolumeMapper';
import vtkDataArray       from '@kitware/vtk.js/Common/Core/DataArray';
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';

const MAX=100;

function App() {
  const vtkContainerRef = useRef(null);
  const context = useRef(null); 

  useEffect(() => {
    if (!context.current) {
      const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
        background: [.1,.2,1],
        rootContainer: vtkContainerRef.current
      });      

      const actor = vtkVolume.newInstance();
      const mapper = vtkVolumeMapper.newInstance();      
      
      actor.setMapper(mapper);
      const lookupTable = vtkColorTransferFunction.newInstance();
      const piecewiseFun = vtkPiecewiseFunction.newInstance();
      lookupTable.applyColorMap(vtkColorMaps.getPresetByName('Cool to Warm'));

      console.log(lookupTable);
      
      lookupTable.setMappingRange(0, 256);
      lookupTable.updateRange();      
      for (let i = 0; i <= 8; i++) {
        piecewiseFun.addPoint(i * 32, i / 8);
      }

      
      actor.getProperty().setRGBTransferFunction(0, lookupTable);
      actor.getProperty().setScalarOpacity(0, piecewiseFun); 


      const float32 = new Float32Array(MAX*MAX*MAX);
      let idx =0;
      
      for(let i=0; i<MAX; i++){
        for(let j=0; j<MAX; j++){
          for(let k=0; k<MAX; k++){
            float32[idx++] = i *10 %256;
          }       
        }
      }

      const imageData = vtkImageData.newInstance({
        origin: [0, 0, 0],
        spacing: [1,1,1],
        direction: [1,0,0, 0,1,0, 0,0,1]
      })
      
      
      const dataArray = vtkDataArray.newInstance({
        name: 'Data',
        values:float32
      });

      imageData.getPointData().setScalars(dataArray);
      imageData.setDimensions([MAX,MAX,MAX]);
      console.log(imageData.getPointData().getScalars().getRange())
      mapper.setInputData(imageData);
      const renderer = fullScreenRenderer.getRenderer();
      const renderWindow = fullScreenRenderer.getRenderWindow();
      renderer.addVolume(actor);

      const range = imageData.getPointData().getScalars().getRange();
      lookupTable.setMappingRange(...range);
      lookupTable.updateRange();

      renderer.resetCamera();
      renderWindow.render();      
      context.current = {
        fullScreenRenderer,
        renderWindow,
        renderer,
        actor,
        mapper,
        imageData
      };
    }


    return () => {
       if (context.current) {
         const { fullScreenRenderer, actor, mapper,imageData } = context.current;
         actor.delete();
         mapper.delete();
         fullScreenRenderer.delete();
         imageData.delete();
         context.current = null;
       }
     };
  }, [vtkContainerRef]);


  
  return (
    <div>
      <div ref={vtkContainerRef} />
      <table
        style={{
          position: 'absolute',
          top: '25px',
          left: '25px',
          background: 'gray',
          padding: '12px',
        }}
      >
        <tbody>
          <tr>
            <td>
            </td>
          </tr>
          <tr>
            <td>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  );
}

export default App;

What am I doing wrong? All it’s showing is a blank screen.

This is for Geometry rendering:

import ‘@kitware/vtk.js/Rendering/Profiles/Geometry’

You need Volume for volume rendering

import ‘@kitware/vtk.js/Rendering/Profiles/Volume’;

You can see that line in the Volume Viewer example

Also using vtkFullScreenRenderWindow is probably not great if you don’t aim it to be full-screen.

You may want to look at react-vtk-js maybe it will give you some ideas on how to use vtk.js and react.

Thanks