cornerstone3D icon indicating copy to clipboard operation
cornerstone3D copied to clipboard

[Feature Request] Update vtk.js to prevent memory increasing

Open Sergey1888888 opened this issue 1 year ago • 5 comments

What feature or change would you like to see made?

Since 30.10.0 version developers of vtk.js added garbage collection to shared graphics resources. But if I will update it to myself, I will get error in cornerstone vtkStreamingOpenGLVolumeMapper file. Could you update vtk.js? The problem is infinite increasing memory space when I use setStack on the elements to replace images.

Why should we prioritize this feature?

Without this update we have infinite increasing memory space when using setStack on the elements to replace images.

Sergey1888888 avatar Jul 31 '24 12:07 Sergey1888888

My colleague on work constantly faces that problem. He's in anguish and pain. It would be great if this could be fixed as soon as possible!

arlagonix avatar Aug 02 '24 12:08 arlagonix

This is not about the garbage collection you're referring to. They recently added a new shared mapper (which we already have), and that is related to garbage collection.

If you give me reproducible steps i can take a look at the memory leak

sedghi avatar Aug 02 '24 12:08 sedghi

@sedghi

Initial values:

image image

After some clicks on elements:

image image

I have changed your example with basic StackViewport and able to reproduce:

import { Enums, RenderingEngine, Types } from '@cornerstonejs/core';
import {
  createImageIdsAndCacheMetaData,
  initDemo,
  setTitleAndDescription,
} from '../../../../utils/demo/helpers';

// This is for debugging purposes
console.warn(
  'Click on index.ts to open source code for this example --------->'
);

const { ViewportType } = Enums;

// ======== Set up page ======== //
setTitleAndDescription(
  'Basic Stack',
  'Displays a single DICOM image in a Stack viewport.'
);

const content = document.getElementById('content');
const element1 = document.createElement('div');
element1.id = 'cornerstone-element1';
element1.style.width = '500px';
element1.style.height = '500px';
const element2 = document.createElement('div');
element2.id = 'cornerstone-element2';
element2.style.width = '500px';
element2.style.height = '500px';

content.appendChild(element1);
content.appendChild(element2);
// ============================= //

/**
 * Runs the demo
 */
async function run() {
  // Init Cornerstone and related libraries
  await initDemo();

  // Get Cornerstone imageIds and fetch metadata into RAM
  const imageIds = await createImageIdsAndCacheMetaData({
    StudyInstanceUID:
      '1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463',
    SeriesInstanceUID:
      '1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561',
    wadoRsRoot: 'https://d3t6nz73ql33tx.cloudfront.net/dicomweb',
  });

  // Instantiate a rendering engine
  const renderingEngineId = 'myRenderingEngine';
  const renderingEngine = new RenderingEngine(renderingEngineId);

  // Create a stack viewport
  const viewportId1 = 'CT_STACK1';
  const viewportInput1 = {
    viewportId: viewportId1,
    type: ViewportType.STACK,
    element: element1,
    defaultOptions: {
      background: <Types.Point3>[0.2, 0, 0.2],
    },
  };
  const viewportId2 = 'CT_STACK2';
  const viewportInput2 = {
    viewportId: viewportId2,
    type: ViewportType.STACK,
    element: element2,
    defaultOptions: {
      background: <Types.Point3>[0.2, 0, 0.2],
    },
  };

  renderingEngine.enableElement(viewportInput1);
  renderingEngine.enableElement(viewportInput2);

  // Get the stack viewport that was created
  const viewport1 = <Types.IStackViewport>(
    renderingEngine.getViewport(viewportId1)
  );
  const viewport2 = <Types.IStackViewport>(
    renderingEngine.getViewport(viewportId2)
  );

  // Define a stack containing a single image
  const stack1 = [imageIds[0]];
  const stack2 = [imageIds[1]];

  // Set the stack on the viewport
  await viewport1.setStack(stack1);
  await viewport2.setStack(stack2);

  element1.addEventListener('click', async () => {
    const imageId = viewport1.getCurrentImageId();
    if (imageId === imageIds[0]) {
      await viewport1.setStack([imageIds[1]]);
    } else {
      await viewport1.setStack([imageIds[0]]);
    }
  });

  element2.addEventListener('click', async () => {
    const imageId = viewport2.getCurrentImageId();
    if (imageId === imageIds[0]) {
      await viewport2.setStack([imageIds[1]]);
    } else {
      await viewport2.setStack([imageIds[0]]);
    }
  });

  // Render the image
  viewport1.render();
  viewport2.render();
}

run();

Sergey1888888 avatar Aug 02 '24 13:08 Sergey1888888

@sedghi Were you able to reproduce it?

Sergey1888888 avatar Aug 06 '24 13:08 Sergey1888888

Haven't looked at it, but will upgrade vtk in near future since i'm pushing on cornerstone 2.0

sedghi avatar Aug 06 '24 13:08 sedghi

We bumped vtk version, so i'm gonna close this

sedghi avatar Nov 14 '24 21:11 sedghi