Skip to content

Commit 24de941

Browse files
committed
fix(cine): resolve view axis through cine override for slice updates
jumpToTool and paint's cross-plane sync read view.options.orientation directly, but SliceViewer forces every 2D view to render as Axial when the image is a cine. The mismatch meant Reveal Slice updated only views whose configured orientation happened to be Axial (typically the first slot), and paint sync computed the slice index against the wrong LPS axis on cine. Route both through getEffectiveViewAxis so the store layer agrees with what's on screen.
1 parent f77da91 commit 24de941

3 files changed

Lines changed: 29 additions & 6 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Maybe } from '@/src/types';
2+
import { LPSAxis } from '@/src/types/lps';
3+
import { ViewInfo2D } from '@/src/types/views';
4+
import { isCineImage } from './isCineImage';
5+
6+
// Cine images render every 2D view as Axial regardless of the view's configured
7+
// options.orientation (see SliceViewer.vue's viewingVectors). Code that lives
8+
// outside the SliceViewer must use this helper instead of reading
9+
// view.options.orientation directly, or it will silently disagree with what's
10+
// on screen for cine.
11+
export function getEffectiveViewAxis(
12+
view: ViewInfo2D,
13+
imageID: Maybe<string>
14+
): LPSAxis {
15+
if (isCineImage(imageID)) return 'Axial';
16+
return view.options.orientation;
17+
}

src/store/tools/paint.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import { watchImmediate } from '@vueuse/core';
88
import { vec3 } from 'gl-matrix';
99
import { defineStore } from 'pinia';
1010
import { PaintMode } from '@/src/core/tools/paint';
11-
import { getLPSAxisFromDir } from '@/src/utils/lps';
12-
import { get2DViewingVectors } from '@/src/utils/getViewingVectors';
11+
import { getEffectiveViewAxis } from '@/src/core/cine/getEffectiveViewAxis';
1312
import { worldPointToIndex } from '@/src/utils/imageSpace';
1413
import { Tools } from './types';
1514
import { useSegmentGroupStore } from '../segmentGroups';
@@ -353,8 +352,7 @@ export const usePaintToolStore = defineStore('paint', () => {
353352
if (!view || view.type !== '2D') return;
354353

355354
// Update slice position
356-
const { viewDirection } = get2DViewingVectors(view.options.orientation);
357-
const axis = getLPSAxisFromDir(viewDirection);
355+
const axis = getEffectiveViewAxis(view, imageID);
358356
const index = lpsOrientation[axis];
359357
const slice = Math.round(indexPos[index]);
360358
if (slice !== sliceConfig.slice) {

src/store/tools/useAnnotationTool.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { AnnotationTool, ToolID } from '@/src/types/annotation-tool';
1313
import { useIdStore } from '@/src/store/id';
1414
import { useToolSelectionStore } from '@/src/store/tools/toolSelection';
1515
import type { IToolStore } from '@/src/store/tools/types';
16+
import { getEffectiveViewAxis } from '@/src/core/cine/getEffectiveViewAxis';
17+
import { isCineImage } from '@/src/core/cine/isCineImage';
1618
import useViewSliceStore from '../view-configs/slicing';
1719
import { useLabels, type Labels } from './useLabels';
1820

@@ -145,10 +147,16 @@ export const useAnnotationTool = <
145147
if (!toolImageFrame) return;
146148

147149
const viewStore = useViewStore();
150+
// Cine forces every 2D view's effective axis to Axial, so without this
151+
// every cine view would jump to the same frame; scope it to the active
152+
// view instead.
153+
const cineActiveOnly = isCineImage(imageID);
148154
const relevantViews = viewStore.getAllViews().filter((view) => {
149155
if (view.type !== '2D') return false;
150-
const axis = view.options.orientation;
151-
return axis === toolImageFrame.axis;
156+
if (getEffectiveViewAxis(view, imageID) !== toolImageFrame.axis)
157+
return false;
158+
if (cineActiveOnly && view.id !== viewStore.activeView) return false;
159+
return true;
152160
});
153161

154162
const viewSliceStore = useViewSliceStore();

0 commit comments

Comments
 (0)