11<script setup lang="ts">
2- import { inject , ref , watch , computed , toRefs } from ' vue' ;
2+ import { inject , watch , computed , toRefs } from ' vue' ;
33import { onVTKEvent } from ' @/src/composables/onVTKEvent' ;
44import { VtkViewContext } from ' @/src/components/vtk/context' ;
55import { useCurrentImage } from ' @/src/composables/useCurrentImage' ;
@@ -8,6 +8,7 @@ import { useSliceRepresentation } from '@/src/core/vtk/useSliceRepresentation';
88import { useImageStore } from ' @/src/store/datasets-images' ;
99import { useLayersStore } from ' @/src/store/datasets-layers' ;
1010import { useSegmentGroupStore } from ' @/src/store/segmentGroups' ;
11+ import { useProbeStore } from ' @/src/store/probe' ;
1112
1213type SliceRepresentationType = ReturnType <typeof useSliceRepresentation >;
1314
@@ -18,7 +19,6 @@ const props = defineProps<{
1819}>();
1920
2021const { baseRep, layerReps, segmentGroupsReps } = toRefs (props );
21-
2222const view = inject (VtkViewContext );
2323if (! view ) throw new Error (' No VtkView' );
2424
@@ -28,140 +28,115 @@ const {
2828 currentImageMetadata,
2929 currentLayers,
3030} = useCurrentImage ();
31-
3231const imageStore = useImageStore ();
3332const layersStore = useLayersStore ();
3433const segmentGroupStore = useSegmentGroupStore ();
35- const sampleSet = computed (() => {
36- const baseImage = currentImageData .value ;
37- if (! baseImage || ! currentImageID .value ) {
38- return [];
39- }
34+ const probeStore = useProbeStore ();
4035
41- const baseImageSlice = {
36+ // Helper functions to build a unified sample set
37+ const getBaseSlice = () => {
38+ if (! currentImageData .value || ! currentImageID .value ) return null ;
39+ return {
4240 type: ' layer' ,
4341 id: currentImageID .value ,
4442 name: currentImageMetadata .value .name ,
4543 rep: baseRep .value ,
46- image: baseImage ,
47- } as const ;
44+ image: currentImageData .value ,
45+ };
46+ };
4847
49- const layers = layerReps .value
50- // filter out just deleted layers
51- .filter ((_ , index ) => currentLayers .value [index ] !== undefined )
52- .map ((layerRep , index ) => {
48+ const getLayers = () =>
49+ layerReps .value
50+ .map ((rep , index ) => {
5351 const layer = currentLayers .value [index ];
52+ if (! layer ) return null ;
5453 return {
5554 type: ' layer' ,
5655 id: layer .id ,
5756 name: imageStore .metadata [layer .selection ].name ,
58- rep: layerRep ,
57+ rep ,
5958 image: layersStore .layerImages [layer .id ],
60- } as const ;
61- });
62-
63- const segmentGroups = segmentGroupStore .orderByParent [currentImageID .value ];
64- const segments = segmentGroupsReps .value
65- .map ((group , index ) => ({ group , index }))
66- // filter out just deleted segment groups or on switching current image
67- .filter (({ index }) => segmentGroups && segmentGroups [index ])
68- .map (({ group , index }) => {
69- const id = segmentGroups ! [index ];
70- const meta = segmentGroupStore .metadataByID [id ];
59+ };
60+ })
61+ .filter (Boolean );
62+
63+ const getSegments = () => {
64+ if (! currentImageID .value ) return [];
65+ const parentGroups = segmentGroupStore .orderByParent [currentImageID .value ];
66+ if (! parentGroups ) return [];
67+ return segmentGroupsReps .value
68+ .map ((rep , index ) => {
69+ const groupId = parentGroups [index ];
70+ if (! groupId ) return null ;
71+ const meta = segmentGroupStore .metadataByID [groupId ];
7172 return {
7273 type: ' segmentGroup' ,
73- id ,
74+ id: groupId ,
7475 name: meta .name ,
75- rep: group ,
76+ rep ,
7677 segments: meta .segments ,
77- image: segmentGroupStore .dataIndex [id ],
78- } as const ;
79- });
78+ image: segmentGroupStore .dataIndex [groupId ],
79+ };
80+ })
81+ .filter (Boolean );
82+ };
8083
81- return [... segments , ... layers , baseImageSlice ];
84+ const sampleSet = computed (() => {
85+ const base = getBaseSlice ();
86+ if (! base ) return [];
87+ return [... getSegments (), ... getLayers (), base ];
8288});
8389
8490const pointPicker = vtkPointPicker .newInstance ();
8591pointPicker .setPickFromList (true );
8692
8793watch (
8894 sampleSet ,
89- (toPick ) => {
90- pointPicker .setPickList (toPick .map ((item ) => item .rep .actor ));
95+ (samples ) => {
96+ pointPicker .setPickList (samples .map ((item : any ) => item .rep .actor ));
9197 },
9298 { immediate: true }
9399);
94100
95101const getImageSamples = (x : number , y : number ) => {
96102 pointPicker .pick ([x , y , 1.0 ], view .renderer );
97- if (pointPicker .getActors ().length === 0 ) {
98- return undefined ;
99- }
103+ if (pointPicker .getActors ().length === 0 ) return undefined ;
104+
100105 const ijk = pointPicker .getPointIJK ();
101- const samples = sampleSet .value .map ((toSample ) => {
102- const size = toSample .image .getDimensions ();
103- const scalarData = toSample .image .getPointData ().getScalars ();
104- const scalars = scalarData .getTuple (
105- size [0 ] * size [1 ] * ijk [2 ] + size [0 ] * ijk [1 ] + ijk [0 ]
106- ) as number [];
107- const idName = {
108- id: toSample .id ,
109- name: toSample .name ,
110- };
111- if (toSample .type === ' segmentGroup' ) {
106+ const samples = sampleSet .value .map ((item : any ) => {
107+ const dims = item .image .getDimensions ();
108+ const scalarData = item .image .getPointData ().getScalars ();
109+ const index = dims [0 ] * dims [1 ] * ijk [2 ] + dims [0 ] * ijk [1 ] + ijk [0 ];
110+ const scalars = scalarData .getTuple (index ) as number [];
111+ const baseInfo = { id: item .id , name: item .name };
112+
113+ if (item .type === ' segmentGroup' ) {
112114 return {
113- ... idName ,
115+ ... baseInfo ,
114116 displayValue: scalars .map (
115- (v ) => toSample .segments .byValue [v ]?.name || ' Background'
117+ (v ) => item .segments .byValue [v ]?.name || ' Background'
116118 ),
117119 };
118120 }
119- return {
120- ... idName ,
121- displayValue: scalars ,
122- };
121+ return { ... baseInfo , displayValue: scalars };
123122 });
124- const pos = pointPicker . getPickPosition ();
123+
125124 return {
126- pos ,
125+ pos: pointPicker . getPickPosition () ,
127126 samples ,
128127 };
129128};
130129
131- const samples = ref <ReturnType <typeof getImageSamples > | undefined >(undefined );
132-
133130onVTKEvent (view .interactor , ' onMouseMove' , (event : any ) => {
134- samples .value = getImageSamples (event .position .x , event .position .y );
131+ const samples = getImageSamples (event .position .x , event .position .y );
132+ probeStore .updateProbeData (samples );
135133});
136134
137135onVTKEvent (view .interactor , ' onPointerLeave' , () => {
138- samples . value = undefined ;
136+ probeStore . clearProbeData () ;
139137});
140138
141139watch ([currentImageID , sampleSet ], () => {
142- samples . value = undefined ;
140+ probeStore . clearProbeData () ;
143141});
144142 </script >
145-
146- <template >
147- <div v-if =" samples !== undefined" class =" probe-value-display" >
148- <div v-for =" sample in samples.samples" :key =" sample.id" >
149- <div >{{ sample.name }}: {{ sample.displayValue.join(', ') }}</div >
150- </div >
151- <div >Position: {{ `${samples.pos.map(Math.round).join(', ')}` }}</div >
152- </div >
153- </template >
154-
155- <style scoped>
156- .probe-value-display {
157- position : absolute ;
158- bottom : 10px ;
159- right : 10px ;
160- background-color : rgba (0 , 0 , 0 , 0.7 );
161- color : white ;
162- padding : 5px 10px ;
163- border-radius : 4px ;
164- font-size : 12px ;
165- pointer-events : none ;
166- }
167- </style >
0 commit comments