Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(coloring): support config defaults #445

Merged
merged 1 commit into from
Oct 6, 2023
Merged
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
7 changes: 7 additions & 0 deletions src/components/SampleDataBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
importDataSources,
} from '@/src/io/import/importDataSources';
import { remoteFileToDataSource } from '@/src/io/import/dataSource';
import useVolumeColoringStore from '@/src/store/view-configs/volume-coloring';
import { SAMPLE_DATA } from '../config';
import { useMessageStore } from '../store/messages';
import { SampleDataset } from '../types';
Expand Down Expand Up @@ -105,6 +106,12 @@ export default defineComponent({
selection.type === 'image' ? selection.dataID : selection.volumeKey;
loaded.idToURL[id] = sample.url;
loaded.urlToID[sample.url] = id;
useVolumeColoringStore().setDefaults(id, {
transferFunction: {
preset: sample.defaults?.colorPreset,
},
});
}
datasetStore.setPrimarySelection(selection);
} catch (error) {
Expand Down
3 changes: 3 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ export const SAMPLE_DATA: SampleDataset[] = [
'3D ultrasound of a baby. Downloaded from tomovision.com.(8 MB)',
url: 'https://data.kitware.com/api/v1/item/635679c311dab8142820a4f4/download',
image: USFetusThumbnail,
defaults: {
colorPreset: 'US-Fetal',
},
},
];

Expand Down
72 changes: 56 additions & 16 deletions src/store/view-configs/volume-coloring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
getDoubleKeyRecord,
patchDoubleKeyRecord,
} from '@/src/utils/doubleKeyRecord';
import { Maybe } from '@/src/types';
import { DeepPartial, Maybe } from '@/src/types';
import { identity } from '@/src/utils';
import { createViewConfigSerializer } from './common';
import { DEFAULT_PRESET } from '../../vtk/ColorMaps';
Expand All @@ -39,6 +39,26 @@ function getPresetFromImageModality(imageID: string) {
return DEFAULT_PRESET;
}

/**
* Gets partial color and opacity function configs from a preset.
* @param preset
* @returns
*/
function getColorAndOpacityFuncsFromPreset(preset: string) {
const ctFunc: Partial<ColorTransferFunction> = {
preset,
};

const ctRange = getColorFunctionRangeFromPreset(preset);
if (ctRange) {
ctFunc.mappingRange = ctRange;
}

const opFunc = getOpacityFunctionFromPreset(preset);

return { colorFunc: ctFunc, opacityFunc: opFunc };
}

export const defaultVolumeColorConfig = (): VolumeColorConfig => ({
colorBy: {
arrayName: '',
Expand Down Expand Up @@ -69,7 +89,12 @@ export const defaultVolumeColorConfig = (): VolumeColorConfig => ({
});

export const useVolumeColoringStore = defineStore('volumeColoring', () => {
const configs = reactive<DoubleKeyRecord<VolumeColorConfig>>({});
const configs = reactive<DoubleKeyRecord<VolumeColorConfig>>(
Object.create(null)
);
const defaultConfigs = reactive<
Record<string, DeepPartial<VolumeColorConfig>>
>(Object.create(null));

const getConfig = (viewID: Maybe<string>, dataID: Maybe<string>) =>
getDoubleKeyRecord(configs, viewID, dataID);
Expand Down Expand Up @@ -114,33 +139,47 @@ export const useVolumeColoringStore = defineStore('volumeColoring', () => {
const setColorPreset = (viewID: string, imageID: string, preset: string) => {
const imageStore = useImageStore();
const image = imageStore.dataIndex[imageID];
if (!image) return;
const imageDataRange = image.getPointData().getScalars().getRange();
if (!image) throw new Error('Invalid imageID');
floryst marked this conversation as resolved.
Show resolved Hide resolved

const ctRange = getColorFunctionRangeFromPreset(preset);
const ctFunc: Partial<ColorTransferFunction> = {
preset,
mappingRange: ctRange || imageDataRange,
};
updateColorTransferFunction(viewID, imageID, ctFunc);
const imageDataRange = image.getPointData().getScalars().getRange();
const { colorFunc, opacityFunc } =
getColorAndOpacityFuncsFromPreset(preset);
colorFunc.mappingRange ||= imageDataRange;
opacityFunc.mappingRange = imageDataRange;

const opFunc = getOpacityFunctionFromPreset(preset);
opFunc.mappingRange = imageDataRange;
updateOpacityFunction(viewID, imageID, opFunc);
updateColorTransferFunction(viewID, imageID, colorFunc);
updateOpacityFunction(viewID, imageID, opacityFunc);
};

const resetToDefaultColoring = (
viewID: string,
dataID: string,
image: vtkImageData
) => {
const defaults = defaultConfigs[dataID];
const scalars = image.getPointData().getScalars();

updateColorBy(viewID, dataID, {
arrayName: scalars.getName(),
location: 'pointData',
arrayName: defaults?.colorBy?.arrayName ?? scalars.getName(),
location: defaults?.colorBy?.location ?? 'pointData',
});
setColorPreset(viewID, dataID, getPresetFromImageModality(dataID));
setColorPreset(
viewID,
dataID,
defaults?.transferFunction?.preset ?? getPresetFromImageModality(dataID)
);
};

/**
* Sets the view config defaults for a dataset.
* @param dataID
* @param defaults
*/
const setDefaults = (
dataID: string,
defaults: DeepPartial<VolumeColorConfig>
) => {
defaultConfigs[dataID] = defaults;
};

const removeView = (viewID: string) => {
Expand Down Expand Up @@ -174,6 +213,7 @@ export const useVolumeColoringStore = defineStore('volumeColoring', () => {
updateOpacityFunction,
updateCVRParameters,
resetToDefaultColoring,
setDefaults,
setColorPreset,
removeView,
removeData,
Expand Down
9 changes: 9 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export type SampleDataset = {
description: string;
url: string;
image: string;
defaults?: {
colorPreset?: string;
};
};

export type RequiredWithPartial<T, K extends keyof T> = Required<Omit<T, K>> &
Expand Down Expand Up @@ -48,3 +51,9 @@ export type TypedArrayConstructorName =
| 'Int32Array'
| 'Float32Array'
| 'Float64Array';

export type DeepPartial<T> = T extends object
? {
[P in keyof T]?: DeepPartial<T[P]>;
}
: T;
Loading