Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 128x 352x 352x | import {
CONSTANTS,
utilities as csUtils,
type Types,
} from '@cornerstonejs/core';
import { getViewportPresentation } from './viewportPresentation';
const { RENDERING_DEFAULTS } = CONSTANTS;
/**
* Returns the viewport's slab thickness, defaulting to the minimum slab thickness
* for native (Generic) viewports which have no slab API.
*/
export function getSlabThicknessOrDefault(viewport: Types.IViewport): number {
Iif (csUtils.isGenericViewport(viewport)) {
return RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;
}
return (viewport as Types.IVolumeViewport).getSlabThickness();
}
/**
* Navigates a native (Generic) viewport to a focal point via its view reference.
* Native PLANAR_NEXT has no setCamera; navigating by view reference snaps to the
* nearest slice along the view-plane normal.
*/
export function jumpToFocalPoint(
viewport: Types.IViewport,
cameraFocalPoint: Types.Point3
): void {
if (csUtils.isGenericViewport(viewport)) {
viewport.setViewReference({ cameraFocalPoint } as Types.ViewReference);
}
}
/**
* Navigates a native (Generic) planar viewport so its displayed slice passes
* through (or as close as possible to) the given world point, handling both
* content modes:
*
* - volume-backed slices navigate by `cameraFocalPoint` (exact plane through
* the point, pan untouched);
* - image stacks ignore `cameraFocalPoint` in their view-reference handling,
* so the closest image index to the point is resolved from the per-image
* plane metadata and navigated by `sliceIndex`.
*
* Returns true when a navigation was issued.
*/
export function navigatePlanarViewportToPoint(
viewport: Types.IViewport,
worldPoint: Types.Point3
): boolean {
if (!csUtils.isGenericViewport(viewport)) {
return false;
}
const isStackContent = viewport.getCurrentMode?.() === 'stack';
if (isStackContent) {
const stackViewport = viewport as unknown as Types.IStackViewport;
if (
typeof stackViewport.getImageIds !== 'function' ||
typeof stackViewport.getCurrentImageIdIndex !== 'function'
) {
return false;
}
let imageIndex: number | null = null;
try {
imageIndex = csUtils.getClosestStackImageIndexForPoint(
worldPoint,
stackViewport
);
} catch {
return false;
}
if (imageIndex === null || imageIndex < 0) {
return false;
}
viewport.setViewReference({
sliceIndex: imageIndex,
} as Types.ViewReference);
return true;
}
viewport.setViewReference({
cameraFocalPoint: [worldPoint[0], worldPoint[1], worldPoint[2]],
} as Types.ViewReference);
return true;
}
export interface NativeSourceProperties {
/** VOI/LUT properties read via getDisplaySetPresentation. */
properties: Record<string, unknown>;
rotation?: number;
flipHorizontal?: boolean;
flipVertical?: boolean;
currentImageId?: string;
}
/**
* Reads the VOI/LUT properties, rotation/flip presentation and current image id
* from a native (Generic) source viewport, which exposes none of the legacy
* getProperties/getViewPresentation/getCamera APIs.
*/
export function getNativeSourceProperties(
viewport: Types.IViewport
): NativeSourceProperties {
if (!csUtils.viewportSupportsDisplaySetPresentation(viewport)) {
return { properties: {} };
}
const sourceDataId = viewport.getSourceDataId();
const properties = {
...((sourceDataId
? (viewport.getDisplaySetPresentation(sourceDataId) as Record<
string,
unknown
>)
: {}) ?? {}),
} as Record<string, unknown>;
// Generic viewports expose the VOI LUT function as `voiLUTFunction`, but the
// legacy viewport `setProperties` (used by the Magnify loupes) reads the
// uppercase `VOILUTFunction`. Bridge the casing so a sigmoid source does not
// silently render the loupe with a linear LUT.
const voiLUTFunction = properties.VOILUTFunction ?? properties.voiLUTFunction;
if (voiLUTFunction !== undefined) {
properties.VOILUTFunction = voiLUTFunction;
}
const presentation = (getViewportPresentation(viewport) ?? {}) as {
rotation?: number;
flipHorizontal?: boolean;
flipVertical?: boolean;
};
return {
properties,
rotation: presentation.rotation,
flipHorizontal: presentation.flipHorizontal,
flipVertical: presentation.flipVertical,
currentImageId: viewport.getCurrentImageId(),
};
}
|