Help to port a VTK Python library to VTK.js

Good morning,

I am trying to create a web application for a Hospital Lab who has asked for some help. The basic requirement is to render an STL file and then create a pressure map from a series of 144 pressure values for which I have the coordinates.

I have been able to create what I need in Python using @ Kenichiro Yoshimi’s code from this thread however, I’m now struggling to port this to VTK.js. For example, the interpolation looks to be using
gaussian_kernel = vtk.vtkGaussianKernel() gaussian_kernel.SetSharpness(2) gaussian_kernel.SetRadius(12)
which I can’t find in the VTK.js API.

I have written the JS to the point where I am rendering my STL file

Would someone be willing to help me port this code across? Unfortunately, I am not allowed to upload the STL file or pressure file. I have uploaded my code so far below

PYTHON - DOES WHAT I NEED:

import vtk
import numpy as np

points_reader = vtk.vtkDelimitedTextReader()
points_reader.SetFileName('points.txt')
points_reader.DetectNumericColumnsOn()
points_reader.SetFieldDelimiterCharacters(',')
points_reader.SetHaveHeaders(True)

table_points = vtk.vtkTableToPolyData()
table_points.SetInputConnection(points_reader.GetOutputPort())
table_points.SetXColumn('x')
table_points.SetYColumn('y')
table_points.SetZColumn('z')
table_points.Update()

points = table_points.GetOutput()
points.GetPointData().SetActiveScalars('val')

range = points.GetPointData().GetScalars().GetRange()

# Read a probe surface
stl_reader = vtk.vtkSTLReader()
stl_reader.SetFileName('InterpolatingOnSTL_final.stl')
stl_reader.Update()

surface = stl_reader.GetOutput()
bounds = np.array(surface.GetBounds())

dims = np.array([101, 101, 101])
box = vtk.vtkImageData()
box.SetDimensions(dims)
box.SetSpacing((bounds[1::2] - bounds[:-1:2])/(dims - 1))
box.SetOrigin(bounds[::2])

# Gaussian kernel
gaussian_kernel = vtk.vtkGaussianKernel()
gaussian_kernel.SetSharpness(2)
gaussian_kernel.SetRadius(12)

interpolator = vtk.vtkPointInterpolator()
interpolator.SetInputData(box)
interpolator.SetSourceData(points)
interpolator.SetKernel(gaussian_kernel)

resample = vtk.vtkResampleWithDataSet()
resample.SetInputData(surface)
resample.SetSourceConnection(interpolator.GetOutputPort())

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(resample.GetOutputPort())
mapper.SetScalarRange(range)

actor = vtk.vtkActor()
actor.SetMapper(mapper)

point_mapper = vtk.vtkPointGaussianMapper()
point_mapper.SetInputData(points)
point_mapper.SetScalarRange(range)
point_mapper.SetScaleFactor(0.6)
point_mapper.EmissiveOff()
point_mapper.SetSplatShaderCode(
    "//VTK::Color::Impl\n"
    "float dist = dot(offsetVCVSOutput.xy,offsetVCVSOutput.xy);\n"
    "if (dist > 1.0) {\n"
    "  discard;\n"
    "} else {\n"
    "  float scale = (1.0 - dist);\n"
    "  ambientColor *= scale;\n"
    "  diffuseColor *= scale;\n"
    "}\n"
)

point_actor = vtk.vtkActor()
point_actor.SetMapper(point_mapper)

renderer = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(renderer)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

renderer.AddActor(actor)
renderer.AddActor(point_actor)

iren.Initialize()

renWin.Render()
iren.Start()

JAVASCRIPT:

import 'vtk.js/Sources/favicon';

import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkSTLReader from 'vtk.js/Sources/IO/Geometry/STLReader';

const stlFile = './newpivot.stl'

reader.setUrl(stlFile, { binary: true }).then(update)
// ----------------------------------------------------------------------------
// Example code
// ----------------------------------------------------------------------------

const reader = vtkSTLReader.newInstance();
const mapper = vtkMapper.newInstance({ scalarVisibility: false });
const actor = vtkActor.newInstance();

actor.setMapper(mapper);
mapper.setInputConnection(reader.getOutputPort());

// ----------------------------------------------------------------------------

function update() {
  const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
  const renderer = fullScreenRenderer.getRenderer();
  const renderWindow = fullScreenRenderer.getRenderWindow();

  const resetCamera = renderer.resetCamera;
  const render = renderWindow.render;

  renderer.addActor(actor);
  resetCamera();
  render();
}

// ----------------------------------------------------------------------------
// Use a file reader to load a local file
// ----------------------------------------------------------------------------

// const fileContainer = document.getElementById('container');
// fileContainer.innerHTML = '<input type="file" class="file"/>';
// myContainer.appendChild(fileContainer);

// const fileInput = fileContainer.querySelector('input');

// function handleFile(event) {
//   event.preventDefault();
//   const dataTransfer = event.dataTransfer;
//   const files = event.target.files || dataTransfer.files;
//   if (files.length === 1) {
//     myContainer.removeChild(fileContainer);
//     const fileReader = new FileReader();
//     fileReader.onload = function onLoad(e) {
//       reader.parseAsArrayBuffer(fileReader.result);
//       update();
//     };
//     fileReader.readAsArrayBuffer(files[0]);
//   }
// }

// fileInput.addEventListener('change', handleFile);

// ----------------------------------------------------------------------------
// Use the reader to download a file
// ----------------------------------------------------------------------------

// reader.setUrl(`./socket.stl`, { binary: true }).then(update);

Thank you,
Adam