Describe Your Question
- I’m building a multi-series web viewer with Cornerstone.js that shows one 3D viewport + three MPR viewports. For each series I create a segmentation from surfaces and add its representations to all 4 viewports.
- Problem: when users switch series while the Surface→Labelmap conversion is running, I need to terminate the polyseg worker to avoid leaking the previous series’ segmentation into the MPRs. If I call
workerManager.terminate("polySeg"), the internal flagpolySegConversionInProgressis never reset tofalse, so no subsequent conversions ever start. - Expected: terminating/aborting the worker (or any failure during conversion) should reset the in-progress flag so later conversions can run; ideally there should be a supported cancel/abort path.
- Which OHIF version you are using? N/A (I’m using Cornerstone directly):
@cornerstonejs/core: 4.2.3@cornerstonejs/dicom-image-loader: 4.2.3@cornerstonejs/polymorphic-segmentation: 4.2.3@cornerstonejs/tools: 4.2.3
What steps can we follow to reproduce the bug?
- Load Series A.
- Create a segmentation from surfaces and add segmentation representations to all viewports (3D + 3×MPR). This triggers Surface→Labelmap conversion for the MPRs.
- Before conversion finishes, switch to Series B and call
workerManager.terminate("polySeg")to avoid rendering A’s segmentation in B. - Try to start B’s conversion by adding its labelmap representation(s).
- Observe that conversion never starts for B (and any later series), because
polySegConversionInProgressremainstrue.
// Adding representations to all viewports
for (const viewportId of ids.viewportIdsArray) {
segmentation.addSegmentationRepresentations(viewportId, [
{
segmentationId,
type: SEGMENTATION_REPRESENTATIONS[viewportId].type,
},
]);
}
// On series switch, to avoid old segmentation leaking into new MPRs:
workerManager.terminate("polySeg"); // after this, no new conversions start
// Relevant code path (from @cornerstonejs/tools …/Labelmap/labelmapDisplay.js)
if (
!labelmapData &&
getPolySeg()?.canComputeRequestedRepresentation(segmentationId, SegmentationRepresentations.Labelmap) &&
!polySegConversionInProgress
) {
polySegConversionInProgress = true;
const polySeg = getPolySeg();
labelmapData = await computeAndAddRepresentation(
segmentationId,
SegmentationRepresentations.Labelmap,
() => polySeg.computeLabelmapData(segmentationId, { viewport }),
() => null,
() => {
defaultSegmentationStateManager.processLabelmapRepresentationAddition(viewport.id, segmentationId);
setTimeout(() => {
triggerSegmentationDataModified(segmentationId);
}, 0);
}
);
if (!labelmapData) {
throw new Error(`No labelmap data found for segmentationId ${segmentationId}.`);
}
polySegConversionInProgress = false; // ← never reached if worker is terminated mid-await
}
Actual: After terminating the worker, polySegConversionInProgress stays true and further conversions never start.
Expected: On worker termination/abort (or any failure in computeLabelmapData), the flag should be reset (e.g., via try/finally or an error/abort handler). Ideally expose a cancel/abort API for in-flight polyseg conversions so viewers can safely handle rapid series switching.