vtkActor getCenter() doesn't work unless getBounds() is called first

Hello,

The getCenter() method of vtkActor (of vtkProp3D really) does not work (returns [0,0,0]) unless getBounds() is called first. I am using STL models as sources.

here is the official STLReader example, with the added code:

import '@kitware/vtk.js/favicon';

// Load the rendering pieces we want to use (for both WebGL and WebGPU)
import '@kitware/vtk.js/Rendering/Profiles/Geometry';

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

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

  // My code
  console.log(actor.getCenter());   // [ 0, 0, 0 ]
  actor.getBounds();
  console.log(actor.getCenter());   // [ x, y, z ]

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

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

const myContainer = document.querySelector('body');
const fileContainer = document.createElement('div');
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);

and here is a small stl file:

This seems like a bad side effect, especially since that isn’t explained somewhere.

or that is normal behavior known to many?

Thank you

I think this is related to pipeline execution. The data has not been flushed all the way to the actor.
If the actor was rendered, I would assume getCenter() would give you the right information.
I’m not saying this is a well known behavior, but in general with VTK, you need to make sure your object is up to date before reading some of its state value. Some method will force things to update such as algo.update(), rw.render() while other will report the current state of the object without any pipeline flush.

My guess is that getBounds() in actor execute the pipeline while getCenter() is just doing a local read.

Thank you for your reply.

Yes your guess is correct indeed, if getCenter() is called after rw,render() has been called, it shows the right values.

Thanks again.