Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,51 @@ describe('SegmentationService', () => {

expect(retrievedSegmentationId).toEqual(segmentationId);
});

it('should create a dedicated color LUT and remember its index so every viewport representation reuses it', async () => {
const displaySet = {
imageIds: ['imageId'],
isDynamicVolume: false,
SeriesNumber: 1,
SeriesDescription: 'Series Description',
} as unknown as AppTypes.DisplaySet;

jest
.spyOn(imageLoader, 'createAndCacheDerivedLabelmapImages')
.mockReturnValue([{ imageId: 'imageId' }] as csTypes.IImage[]);
jest.spyOn(cstSegmentation.state, 'getSegmentations').mockReturnValue([]);
jest.spyOn(service, 'addOrUpdateSegmentation').mockReturnValue(undefined);
jest.mocked(cstSegmentation.state.addColorLUT).mockReturnValue(7);

const segmentationId = await service.createLabelmapForDisplaySet(displaySet);

expect(cstSegmentation.state.addColorLUT).toHaveBeenCalledWith([[0, 0, 0, 0]]);
expect(service['_segmentationIdToColorLUTIndexMap'].get(segmentationId)).toBe(7);
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

it('should keep the existing color LUT when called again with the same segmentation id', async () => {
const displaySet = {
imageIds: ['imageId'],
isDynamicVolume: false,
SeriesNumber: 1,
SeriesDescription: 'Series Description',
} as unknown as AppTypes.DisplaySet;

jest
.spyOn(imageLoader, 'createAndCacheDerivedLabelmapImages')
.mockReturnValue([{ imageId: 'imageId' }] as csTypes.IImage[]);
jest.spyOn(cstSegmentation.state, 'getSegmentations').mockReturnValue([]);
jest.spyOn(service, 'addOrUpdateSegmentation').mockReturnValue(undefined);
jest.mocked(cstSegmentation.state.addColorLUT).mockReturnValueOnce(7).mockReturnValueOnce(8);

const segmentationId = await service.createLabelmapForDisplaySet(displaySet);
await service.createLabelmapForDisplaySet(displaySet, { segmentationId });

// Updating an existing segmentation must not strand the representations
// already rendering it on the previous LUT.
expect(cstSegmentation.state.addColorLUT).toHaveBeenCalledTimes(1);
expect(service['_segmentationIdToColorLUTIndexMap'].get(segmentationId)).toBe(7);
});
});

describe('createSegmentationForSEGDisplaySet', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,19 @@ class SegmentationService extends PubSubService implements ISegmentationServiceI
},
};

// Create a dedicated color LUT up front and remember its index so that every
// representation of this segmentation (one per viewport) reuses the same LUT.
// Otherwise each viewport would get its own default LUT copy and editing a
// segment color on one viewport would not be reflected on the others (the
// segment color appears to revert to the default when interacting elsewhere).
// The caller may pass the id of an existing segmentation, which this method
// updates rather than replaces; keep its LUT so representations already
// rendering it don't diverge from the ones created afterwards.
if (!this._segmentationIdToColorLUTIndexMap.has(segmentationId)) {
const colorLUTIndex = addColorLUT([[0, 0, 0, 0]] as csTypes.ColorLUT);
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
}

this.addOrUpdateSegmentation(segmentationPublicInput);
return segmentationId;
}
Expand Down
Loading