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(interpolation): Contour segmentation interpolation for freehand and SplineROI #1003

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b1d3d74
Added contour roi interpolation tool
Belbin-GK Dec 20, 2023
dc07950
Generated documentation and minor updates
Belbin-GK Dec 21, 2023
f5aba92
Test file updated and minor documentation updation
Belbin-GK Jan 8, 2024
db78975
Added interpolated annotations remove event type
Belbin-GK Jan 8, 2024
e52dde7
Merge remote-tracking branch 'origin/main' into feat/contour-segmenta…
wayfarer3130 Jan 10, 2024
1455753
fix: Inter-slice interpolation working with master
wayfarer3130 Jan 11, 2024
c86c850
Reduction of required code to be closer to original
wayfarer3130 Jan 11, 2024
045f073
feat: Contour segmentation interpolation - basically working
wayfarer3130 Jan 12, 2024
0c9bc1b
Compile fixes
wayfarer3130 Jan 12, 2024
09b1df8
Merge remote-tracking branch 'origin/main' into feat/contour-segmenta…
wayfarer3130 Jan 12, 2024
141691d
fix: build issues
wayfarer3130 Jan 12, 2024
b1185e7
fix: Integration tests
wayfarer3130 Jan 16, 2024
247f3de
fix: Autogenerated outline dash/fill styles
wayfarer3130 Jan 16, 2024
e63fde2
fix: Allow contour interpolation to be done on any contour segmentation
wayfarer3130 Jan 16, 2024
50ad6bc
Remove ContourROITool in favour of configuration
wayfarer3130 Jan 16, 2024
6f56013
feat: Add livewire interpolation example
wayfarer3130 Jan 16, 2024
2553081
Merge remote-tracking branch 'origin/main' into feat/contour-segmenta…
wayfarer3130 Jan 16, 2024
355a754
feat: Add spline interpolation
wayfarer3130 Jan 16, 2024
16a8e9d
fix: Generate handles for spline interpolation
wayfarer3130 Jan 17, 2024
7285fd6
fix: Make livewire fire the right annotation completed event
wayfarer3130 Jan 17, 2024
adb24ef
fix: Numerous fixes for annotation update notification
wayfarer3130 Jan 17, 2024
f649e15
Merge remote-tracking branch 'origin/main' into feat/contour-segmenta…
wayfarer3130 Jan 18, 2024
79555c3
Change to use getTargetId
wayfarer3130 Jan 18, 2024
4e9dea6
Fix some docs and minor issues
wayfarer3130 Jan 19, 2024
776d414
PR review changes
wayfarer3130 Jan 19, 2024
47a9dc3
Use the points array for conversion to/from xyz
wayfarer3130 Jan 19, 2024
b6cf87e
Accept all the autogenerated contours
wayfarer3130 Jan 19, 2024
055e95d
Merge remote-tracking branch 'origin/main' into feat/contour-segmenta…
wayfarer3130 Jan 22, 2024
7b82a75
PR comments
wayfarer3130 Jan 23, 2024
21fa4b4
PR fixes
wayfarer3130 Jan 23, 2024
27772d7
Change to use maps instead of arrays for indexed data
wayfarer3130 Jan 23, 2024
de36dab
fix: Bug in spline change notification causing interpolation error
wayfarer3130 Jan 23, 2024
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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
at: ~/repo
- run: mkdir ~/junit
- run:
command: yarn run test:ci
command: yarn run test:unit:ci
environment:
JUNIT_REPORT_PATH: ./junit/
JUNIT_REPORT_NAME: test-results.xml
Expand Down
8 changes: 8 additions & 0 deletions common/reviews/api/core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,13 @@ type Point3 = [number, number, number];
// @public (undocumented)
type Point4 = [number, number, number, number];

// @public (undocumented)
type PointsXYZ = {
x: number[];
y: number[];
z: number[];
};

// @public (undocumented)
const presets: ViewportPreset[];

Expand Down Expand Up @@ -3086,6 +3093,7 @@ declare namespace Types {
AABB2,
Point2,
Point3,
PointsXYZ,
Point4,
Mat3,
Plane,
Expand Down
137 changes: 130 additions & 7 deletions common/reviews/api/tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import { Corners } from '@kitware/vtk.js/Interaction/Widgets/OrientationMarkerWidget/Constants';
import type { GetGPUTier } from 'detect-gpu';
import { IColorMapPreset } from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';
import { IStackViewport as IStackViewport_2 } from 'packages/core/dist/types/types';
import { IVolumeViewport as IVolumeViewport_2 } from 'packages/core/dist/types/types';
import { mat3 } from 'gl-matrix';
import { mat4 } from 'gl-matrix';
import type { TierResult } from 'detect-gpu';
Expand All @@ -27,6 +29,9 @@ declare namespace aabb {
}
}

// @public (undocumented)
function acceptAutogeneratedInterpolations(annotationGroupSelector: AnnotationGroupSelector, selector: AcceptInterpolationSelector): void;

declare namespace activeSegmentation {
export {
getActiveSegmentationRepresentation,
Expand Down Expand Up @@ -218,6 +223,7 @@ type Annotation = {
isLocked?: boolean;
isVisible?: boolean;
invalidated?: boolean;
autoGenerated?: boolean;
metadata: {
cameraPosition?: Types_2.Point3;
cameraFocalPoint?: Types_2.Point3;
Expand Down Expand Up @@ -275,6 +281,7 @@ type AnnotationAddedEventType = Types_2.CustomEventType<AnnotationAddedEventDeta
// @public (undocumented)
type AnnotationCompletedEventDetail = {
annotation: Annotation;
changeType?: ChangeTypes.Completed;
};

// @public (undocumented)
Expand Down Expand Up @@ -344,6 +351,28 @@ type AnnotationGroupSelector = HTMLDivElement | string;
// @public (undocumented)
type AnnotationHandle = Types_2.Point3;

// @public (undocumented)
type AnnotationInterpolationCompletedEventDetail = {
annotation: InterpolationROIAnnotation;
element: HTMLDivElement;
viewportId: string;
renderingEngineId: string;
};

// @public (undocumented)
type AnnotationInterpolationCompletedEventType = Types_2.CustomEventType<AnnotationInterpolationCompletedEventDetail>;

// @public (undocumented)
type AnnotationInterpolationRemovedEventDetail = {
annotations: Array<InterpolationROIAnnotation>;
element: HTMLDivElement;
viewportId: string;
renderingEngineId: string;
};

// @public (undocumented)
type AnnotationInterpolationRemovedEventType = Types_2.CustomEventType<AnnotationInterpolationRemovedEventDetail>;

// @public (undocumented)
type AnnotationLockChangeEventDetail = {
added: Array<Annotation>;
Expand All @@ -359,6 +388,7 @@ type AnnotationModifiedEventDetail = {
viewportId: string;
renderingEngineId: string;
annotation: Annotation;
changeType?: ChangeTypes;
};

// @public (undocumented)
Expand Down Expand Up @@ -417,6 +447,8 @@ type AnnotationStyle_2 = {

// @public (undocumented)
enum AnnotationStyleStates {
// (undocumented)
AutoGenerated = "AutoGenerated",
// (undocumented)
Default = "",
// (undocumented)
Expand Down Expand Up @@ -833,6 +865,20 @@ type CardinalSplineProps = SplineProps & {
fixedScale?: boolean;
};

// @public (undocumented)
enum ChangeTypes {
// (undocumented)
Completed = "Completed",
// (undocumented)
HandlesUpdated = "HandlesUpdated",
// (undocumented)
InitialSetup = "InitialSetup",
// (undocumented)
Interaction = "Interaction",
// (undocumented)
StatsUpdated = "StatsUpdated"
}

// @public (undocumented)
function checkAndDefineIsLockedProperty(annotation: Annotation): void;

Expand Down Expand Up @@ -1313,7 +1359,9 @@ declare namespace contours {
_default_3 as mergePoints,
_default_4 as detectContourHoles,
generateContourSetsFromLabelmap,
AnnotationToPointData
AnnotationToPointData,
interpolation,
acceptAutogeneratedInterpolations
}
}

Expand All @@ -1322,6 +1370,7 @@ type ContourSegmentationAnnotation = ContourAnnotation & ContourSegmentationAnno

// @public (undocumented)
type ContourSegmentationAnnotationData = {
autoGenerated?: boolean;
data: {
segmentation: {
segmentationId: string;
Expand Down Expand Up @@ -1579,7 +1628,7 @@ const _default_4: {

// @public (undocumented)
const _default_5: {
interpolateAnnotation: typeof interpolateAnnotation;
smoothAnnotation: typeof smoothAnnotation;
};

// @public (undocumented)
Expand Down Expand Up @@ -1856,7 +1905,8 @@ declare namespace Enums {
Events,
SegmentationRepresentations,
Swipe,
StrategyCallbacks
StrategyCallbacks,
ChangeTypes
}
}
export { Enums }
Expand All @@ -1874,6 +1924,8 @@ enum Events {
// (undocumented)
ANNOTATION_COMPLETED = "CORNERSTONE_TOOLS_ANNOTATION_COMPLETED",
// (undocumented)
ANNOTATION_INTERPOLATION_PROCESS_COMPLETED = "CORNERSTONE_TOOLS_ANNOTATION_INTERPOLATION_PROCESS_COMPLETED",
// (undocumented)
ANNOTATION_LOCK_CHANGE = "CORNERSTONE_TOOLS_ANNOTATION_LOCK_CHANGE",
// (undocumented)
ANNOTATION_MODIFIED = "CORNERSTONE_TOOLS_ANNOTATION_MODIFIED",
Expand All @@ -1886,6 +1938,8 @@ enum Events {
// (undocumented)
ANNOTATION_VISIBILITY_CHANGE = "CORNERSTONE_TOOLS_ANNOTATION_VISIBILITY_CHANGE",
// (undocumented)
INTERPOLATED_ANNOTATIONS_REMOVED = "CORNERSTONE_TOOLS_INTERPOLATED_ANNOTATIONS_REMOVED",
// (undocumented)
KEY_DOWN = "CORNERSTONE_TOOLS_KEY_DOWN",
// (undocumented)
KEY_UP = "CORNERSTONE_TOOLS_KEY_UP",
Expand Down Expand Up @@ -1973,6 +2027,10 @@ declare namespace EventTypes_2 {
AnnotationVisibilityChangeEventDetail,
AnnotationLockChangeEventType,
AnnotationVisibilityChangeEventType,
AnnotationInterpolationCompletedEventDetail,
AnnotationInterpolationCompletedEventType,
AnnotationInterpolationRemovedEventDetail,
AnnotationInterpolationRemovedEventType,
SegmentationDataModifiedEventType,
SegmentationRepresentationModifiedEventDetail,
SegmentationRepresentationModifiedEventType,
Expand Down Expand Up @@ -2252,7 +2310,7 @@ function getNumberOfAnnotations(toolName: string, annotationGroupSelector: Annot
function getOrientationStringLPS(vector: Types_2.Point3): string;

// @public (undocumented)
function getPoint(points: any, idx: any): any[];
function getPoint(points: any, idx: any): Types_2.Point3;

// @public (undocumented)
function getPointInLineOfSightWithCriteria(viewport: Types_2.IVolumeViewport, worldPos: Types_2.Point3, targetVolumeId: string, criteriaFunction: (intensity: number, point: Types_2.Point3) => Types_2.Point3, stepSize?: number): Types_2.Point3;
Expand Down Expand Up @@ -2342,6 +2400,9 @@ function getToolGroupsWithToolName(toolName: string): IToolGroup[] | [];
// @public (undocumented)
function getToolState(element: HTMLDivElement): CINETypes.ToolData | undefined;

// @public (undocumented)
function getViewportForAnnotation(annotation: Annotation): IVolumeViewport_2 | IStackViewport_2;

// @public (undocumented)
function getViewportIdsWithToolToRender(element: HTMLDivElement, toolName: string, requireParallelNormals?: boolean): string[];

Expand Down Expand Up @@ -2389,6 +2450,12 @@ type IDistance = {
world: number;
};

// @public (undocumented)
type ImageInterpolationData = {
sliceIndex: number;
annotations?: Annotation[];
};

// @public (undocumented)
class ImageMouseCursor extends MouseCursor {
constructor(url: string, x?: number, y?: number, name?: string | undefined, fallback?: MouseCursor | undefined);
Expand Down Expand Up @@ -2416,8 +2483,51 @@ type InteractionStartType = Types_2.CustomEventType<InteractionStartEventDetail>
// @public (undocumented)
type InteractionTypes = 'Mouse' | 'Touch';

declare namespace interpolation {
export {
InterpolationManager
}
}

// @public (undocumented)
function interpolateAnnotation(enabledElement: Types_2.IEnabledElement, annotation: PlanarFreehandROIAnnotation, knotsRatioPercentage: number): boolean;
class InterpolationManager {
// (undocumented)
static acceptAutoGenerated(annotationGroupSelector: AnnotationGroupSelector, selector?: AcceptInterpolationSelector): void;
// (undocumented)
static addTool(toolName: string): void;
// (undocumented)
static handleAnnotationCompleted: (evt: AnnotationCompletedEventType) => void;
// (undocumented)
static handleAnnotationDelete: (evt: AnnotationRemovedEventType) => void;
// (undocumented)
static handleAnnotationUpdate: (evt: AnnotationModifiedEventType) => void;
// (undocumented)
static toolNames: any[];
}

// @public (undocumented)
type InterpolationROIAnnotation = ContourAnnotation & {
metadata: {
cameraPosition?: Types_2.Point3;
cameraFocalPoint?: Types_2.Point3;
viewPlaneNormal?: Types_2.Point3;
viewUp?: Types_2.Point3;
annotationUID?: string;
FrameOfReferenceUID: string;
referencedImageId?: string;
toolName: string;
referencedSliceIndex?: number;
};
interpolationUID?: string;
};

// @public (undocumented)
type InterpolationViewportData = {
annotation: InterpolationROIAnnotation;
interpolationUID: string;
viewport: Types_2.IViewport;
sliceData: Types_2.ImageSliceData;
};

// @public (undocumented)
function intersectLine(line1Start: Types_2.Point2, line1End: Types_2.Point2, line2Start: Types_2.Point2, line2End: Types_2.Point2): number[];
Expand Down Expand Up @@ -3380,6 +3490,8 @@ type PlanarFreehandROIAnnotation = ContourAnnotation & {
export class PlanarFreehandROITool extends ContourSegmentationBaseTool {
constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
// (undocumented)
protected activateDraw: (evt: EventTypes_2.InteractionEventType, annotation: PlanarFreehandROIAnnotation, viewportIdsToRender: string[]) => void;
// (undocumented)
addNewAnnotation: (evt: EventTypes_2.InteractionEventType) => PlanarFreehandROIAnnotation;
// (undocumented)
_calculateStatsIfActive(annotation: PlanarFreehandROIAnnotation, targetId: string, viewport: any, renderingEngine: any, enabledElement: any): void;
Expand Down Expand Up @@ -3430,7 +3542,7 @@ export class PlanarFreehandROITool extends ContourSegmentationBaseTool {
declare namespace planarFreehandROITool {
export {
_default_5 as default,
interpolateAnnotation
smoothAnnotation
}
}

Expand Down Expand Up @@ -4443,6 +4555,9 @@ function setToolGroupSpecificConfig_2(toolGroupId: string, segmentationRepresent
// @public (undocumented)
function showAllAnnotations(): void;

// @public (undocumented)
function smoothAnnotation(enabledElement: Types_2.IEnabledElement, annotation: PlanarFreehandROIAnnotation, knotsRatioPercentage: number): boolean;

// @public (undocumented)
export class SphereScissorsTool extends BaseTool {
constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
Expand Down Expand Up @@ -4560,6 +4675,8 @@ export class SplineROITool extends ContourSegmentationBaseTool {
// (undocumented)
protected createAnnotation(evt: EventTypes_2.InteractionEventType): Annotation;
// (undocumented)
protected createInterpolatedSplineControl(annotation: any): void;
// (undocumented)
deleteControlPointCallback: (evt: EventTypes_2.InteractionEventType, annotation: SplineROIAnnotation) => void;
// (undocumented)
editData: {
Expand All @@ -4574,6 +4691,8 @@ export class SplineROITool extends ContourSegmentationBaseTool {
// (undocumented)
_endCallback: (evt: EventTypes_2.InteractionEventType) => void;
// (undocumented)
fireChangeOnUpdate: ChangeTypes;
// (undocumented)
handleSelectedCallback: (evt: EventTypes_2.InteractionEventType, annotation: SplineROIAnnotation, handle: ToolHandle) => void;
// (undocumented)
protected isContourSegmentationTool(): boolean;
Expand Down Expand Up @@ -4604,7 +4723,7 @@ export class SplineROITool extends ContourSegmentationBaseTool {
// (undocumented)
touchDragCallback: any;
// (undocumented)
triggerAnnotationModified: (annotation: SplineROIAnnotation, enabledElement: Types_2.IEnabledElement) => void;
triggerAnnotationModified: (annotation: SplineROIAnnotation, enabledElement: Types_2.IEnabledElement, changeType?: ChangeTypes) => void;
}

// @public (undocumented)
Expand Down Expand Up @@ -5024,6 +5143,7 @@ declare namespace ToolSpecificAnnotationTypes {
RectangleROIStartEndThresholdAnnotation,
PlanarFreehandROIAnnotation,
PlanarFreehandContourSegmentationAnnotation,
InterpolationROIAnnotation,
ArrowAnnotation,
AngleAnnotation,
UltrasoundDirectionalAnnotation,
Expand Down Expand Up @@ -5174,6 +5294,8 @@ declare namespace Types {
BidirectionalData,
CanvasCoordinates,
IAnnotationManager,
InterpolationViewportData,
ImageInterpolationData,
GroupSpecificAnnotations,
AnnotationState,
AnnotationStyle,
Expand Down Expand Up @@ -5362,6 +5484,7 @@ declare namespace utilities {
pointInShapeCallback,
getSphereBoundsInfo,
getAnnotationNearPoint,
getViewportForAnnotation,
getAnnotationNearPointOnEnabledElement,
jumpToSlice,
pointInSurroundingSphereCallback,
Expand Down
1 change: 1 addition & 0 deletions jest.config.base.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default {
collectCoverageFrom: [
'<rootDir>/src/**/*.{js,jsx}',
// Not
'!<rootDir>/src/RenderingEngine/vtkClasses/**',
'!<rootDir>/src/**/*.test.js',
'!**/node_modules/**',
'!**/__tests__/**',
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"start": "yarn run dev",
"test:firefox": "karma start ./karma.conf.js --browsers Firefox",
"test:dev": "karma start",
"test:ci": "yarn test:unit && karma start --single-run",
"test:ci": "karma start --single-run",
"test:unit:ci": "yarn test:unit && yarn test:ci",
"test": "karma start",
"test:unit": "jest --collectCoverage",
"test:debug": "karma start ./karma.conf.js --browsers Chrome --no-single-run",
Expand Down
1 change: 1 addition & 0 deletions packages/adapters/src/adapters/Cornerstone/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ArrowAnnotate from "./ArrowAnnotate";
import CobbAngle from "./CobbAngle";
import Angle from "./Angle";
import RectangleRoi from "./RectangleRoi";

// Segmentation
import Segmentation from "./Segmentation";

Expand Down
Loading