Skip to content

Commit 5ed2087

Browse files
committed
Drop web interactive segmentation, keep desktop
Web seg/text-query/stereo support is being deferred until we settle on a better wiring. Desktop integration is unchanged. - Remove server/dive_server/viame_segmentation_service.py. - Drop segmentation_predict, segmentation_status, text_query routes from views_rpc.py (and the matching imports / logger). - Drop the seg/text-query/stereo wrappers from web-girder rpc.service.ts; runPipeline keeps frameRange + pipelineParams. - Reset web-girder views/ViewerLoader.vue to main (no seg UI). - Drop the multi-cam toolbar toggle from web-girder views/Settings.vue.
1 parent dc0dd0b commit 5ed2087

5 files changed

Lines changed: 7 additions & 1065 deletions

File tree

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import girderRest from 'platform/web-girder/plugins/girder';
22
import type { GirderModel } from '@girder/components/src';
3-
import {
4-
Pipe, SegmentationPredictRequest, SegmentationPredictResponse, SegmentationStatusResponse,
5-
TextQueryRequest, TextQueryResponse,
6-
} from 'dive-common/apispec';
3+
import { Pipe } from 'dive-common/apispec';
74

85
function postProcess(folderId: string, skipJobs = false, skipTranscoding = false, additive = false, additivePrepend = '', set: string | undefined = undefined) {
96
return girderRest.post<{folder: GirderModel, warnings: string[], job_ids: string[]}>(`dive_rpc/postprocess/${folderId}`, null, {
@@ -66,101 +63,11 @@ function convertLargeImage(folderId: string) {
6663
return girderRest.post(`dive_rpc/convert_large_image/${folderId}`, null, {});
6764
}
6865

69-
/**
70-
* Interactive Segmentation API
71-
*/
72-
73-
async function segmentationPredict(
74-
folderId: string,
75-
frameNumber: number,
76-
request: SegmentationPredictRequest,
77-
): Promise<SegmentationPredictResponse> {
78-
const { data } = await girderRest.post<SegmentationPredictResponse>('dive_rpc/segmentation_predict', {
79-
points: request.points,
80-
pointLabels: request.pointLabels,
81-
maskInput: request.maskInput,
82-
multimaskOutput: request.multimaskOutput,
83-
}, {
84-
params: {
85-
folderId,
86-
frameNumber,
87-
},
88-
});
89-
return data;
90-
}
91-
92-
async function segmentationStatus(): Promise<SegmentationStatusResponse> {
93-
const { data } = await girderRest.get<SegmentationStatusResponse>('dive_rpc/segmentation_status');
94-
return data;
95-
}
96-
97-
/**
98-
* Initialize segmentation service by checking availability.
99-
* Throws an error if segmentation is not available on the server.
100-
*/
101-
async function segmentationInitialize(): Promise<void> {
102-
const status = await segmentationStatus();
103-
if (!status.available) {
104-
throw new Error('Model failed to load. Ensure that the SAM3 model pack is downloaded from the VIAME add-on repository and that you have enough video RAM to run it.');
105-
}
106-
}
107-
108-
/**
109-
* Initialize and verify that text query is available.
110-
* Throws if the segmentation service or text query capability is not available.
111-
*/
112-
async function textQueryInitialize(): Promise<void> {
113-
const status = await segmentationStatus();
114-
if (!status.available) {
115-
throw new Error('Model failed to load. Ensure that the SAM3 model pack is downloaded from the VIAME add-on repository and that you have enough video RAM to run it.');
116-
}
117-
const tqStatus = await textQueryStatus();
118-
if (!tqStatus.grounding_available) {
119-
throw new Error('Text query model failed to load. Ensure that the SAM3 model pack is downloaded from the VIAME add-on repository and that you have enough video RAM to run it.');
120-
}
121-
}
122-
123-
/**
124-
* Text Query API for open-vocabulary detection/segmentation
125-
*/
126-
127-
async function textQuery(
128-
folderId: string,
129-
frameNumber: number,
130-
request: Omit<TextQueryRequest, 'imagePath'>,
131-
): Promise<TextQueryResponse> {
132-
const { data } = await girderRest.post<TextQueryResponse>('dive_rpc/text_query', {
133-
text: request.text,
134-
boxThreshold: request.boxThreshold,
135-
maxDetections: request.maxDetections,
136-
}, {
137-
params: {
138-
folderId,
139-
frameNumber,
140-
},
141-
});
142-
return data;
143-
}
144-
145-
async function textQueryStatus(): Promise<{ available: boolean; grounding_available: boolean }> {
146-
const { data } = await girderRest.get<{ available: boolean; loaded: boolean; text_query_available: boolean }>('dive_rpc/segmentation_status');
147-
return {
148-
available: data.available,
149-
grounding_available: data.text_query_available,
150-
};
151-
}
152-
15366
export {
15467
convertLargeImage,
15568
postProcess,
15669
runPipeline,
15770
runTraining,
15871
deleteTrainedPipeline,
15972
exportTrainedPipeline,
160-
segmentationPredict,
161-
segmentationStatus,
162-
segmentationInitialize,
163-
textQuery,
164-
textQueryStatus,
165-
textQueryInitialize,
16673
};

client/platform/web-girder/views/Settings.vue

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,6 @@ export default defineComponent({
1919
Annotation Settings
2020
</v-card-title>
2121
<v-card-text>
22-
<v-row>
23-
<v-col>
24-
<v-switch
25-
v-model="clientSettings.multiCamSettings.showToolbar"
26-
color="primary"
27-
label="Show multi-camera toolbar"
28-
hint="Show multi-camera editing tools in the top toolbar when a track is selected"
29-
persistent-hint
30-
class="my-0"
31-
/>
32-
</v-col>
33-
</v-row>
3422
<v-row>
3523
<v-col>
3624
<v-switch

client/platform/web-girder/views/ViewerLoader.vue

Lines changed: 6 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts">
22
import {
3-
computed, defineComponent, onBeforeUnmount, onMounted, ref, toRef, watch, Ref, PropType, nextTick,
4-
watchEffect,
3+
computed, defineComponent, onBeforeUnmount, onMounted, ref, toRef, watch, Ref, PropType,
54
} from 'vue';
65
76
import Viewer from 'dive-common/components/Viewer.vue';
@@ -12,10 +11,8 @@ import SidebarContext from 'dive-common/components/SidebarContext.vue';
1211
import context from 'dive-common/store/context';
1312
import { useStore } from 'platform/web-girder/store/types';
1413
import { usePrompt } from 'dive-common/vue-utilities/prompt-service';
15-
import { useApi, SegmentationPredictRequest } from 'dive-common/apispec';
16-
import {
17-
convertLargeImage, segmentationPredict, segmentationInitialize, textQueryInitialize,
18-
} from 'platform/web-girder/api/rpc.service';
14+
import { useApi } from 'dive-common/apispec';
15+
import { convertLargeImage } from 'platform/web-girder/api/rpc.service';
1916
import { useRouter } from 'vue-router/composables';
2017
import JobsTab from './JobsTab.vue';
2118
import Export from './Export.vue';
@@ -109,23 +106,12 @@ export default defineComponent({
109106
const currentJob = computed(() => getters['Jobs/datasetCompleteJobs'](props.id));
110107
111108
const typeList: Ref<string[]> = ref([]);
112-
const textQueryRunning = ref(false);
113-
const timeFilter: Ref<[number, number] | null> = ref(null);
114109
115110
const findType = async () => {
116111
const meta = await loadMetadata(props.id);
117112
typeList.value = [meta.type];
118113
};
119114
findType();
120-
121-
// Watch the viewer's trackFilters.timeFilters and sync to local ref
122-
watchEffect(() => {
123-
if (viewerRef.value?.trackFilters?.timeFilters?.value) {
124-
timeFilter.value = viewerRef.value.trackFilters.timeFilters.value;
125-
} else {
126-
timeFilter.value = null;
127-
}
128-
});
129115
const runningPipelines = computed(() => {
130116
const results: string[] = [];
131117
if (getters['Jobs/datasetRunningState'](props.id)) {
@@ -169,7 +155,6 @@ export default defineComponent({
169155
170156
onMounted(() => {
171157
window.addEventListener('beforeunload', viewerRef.value.warnBrowserExit);
172-
initializeSegmentation();
173158
});
174159
175160
onBeforeUnmount(() => {
@@ -227,78 +212,6 @@ export default defineComponent({
227212
}
228213
}
229214
230-
/**
231-
* Initialize segmentation recipe with platform-specific functions
232-
*/
233-
async function initializeSegmentation() {
234-
await nextTick(); // Wait for Viewer to be mounted
235-
if (!viewerRef.value?.segmentationRecipe) {
236-
console.warn('[Segmentation] segmentationRecipe not found on Viewer');
237-
return;
238-
}
239-
240-
try {
241-
// Initialize the recipe
242-
// Web platform uses folderId + frameNum; the backend resolves the actual image path
243-
viewerRef.value.segmentationRecipe.initialize({
244-
predictFn: (request: SegmentationPredictRequest, frameNum: number) => segmentationPredict(props.id, frameNum, request),
245-
getImagePath: () => '', // Not used for web platform - backend resolves paths
246-
// Initialize the segmentation service when the recipe is activated (user clicks Segment button)
247-
initializeServiceFn: segmentationInitialize,
248-
});
249-
250-
console.log('[Segmentation] Recipe initialized successfully for web');
251-
} catch (error) {
252-
console.error('[Segmentation] Failed to initialize recipe:', error);
253-
}
254-
}
255-
256-
/**
257-
* Handle text query service initialization request
258-
* Called when user opens the text query dialog
259-
*/
260-
async function handleTextQueryInit() {
261-
try {
262-
// Initialize and verify that text query is specifically available
263-
await textQueryInitialize();
264-
viewerRef.value?.onTextQueryServiceReady(true);
265-
} catch (error) {
266-
const errorMessage = error instanceof Error
267-
? error.message
268-
: 'Text query model failed to load. Ensure that the SAM3 model pack is downloaded from the VIAME add-on repository and that you have enough video RAM to run it.';
269-
viewerRef.value?.onTextQueryServiceReady(false, errorMessage);
270-
}
271-
}
272-
273-
/**
274-
* Handle text query on current frame
275-
*/
276-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
277-
async function handleTextQuery(_params: { text: string; boxThreshold: number }) {
278-
textQueryRunning.value = true;
279-
try {
280-
// Text query for single frame would go here
281-
// For now, this is handled by the segmentation service
282-
await prompt({
283-
title: 'Text Query',
284-
text: ['Text query for single frame is not yet implemented on web platform.'],
285-
});
286-
} finally {
287-
textQueryRunning.value = false;
288-
}
289-
}
290-
291-
/**
292-
* Handle text query on all frames - runs as a pipeline job
293-
*/
294-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
295-
async function handleTextQueryAllFrames(_params: { text: string; boxThreshold: number }) {
296-
await prompt({
297-
title: 'Text Query',
298-
text: ['Text query for all frames is not yet implemented on web platform.'],
299-
});
300-
}
301-
302215
return {
303216
buttonOptions,
304217
brandData,
@@ -313,11 +226,6 @@ export default defineComponent({
313226
routeSet,
314227
largeImageWarning,
315228
typeList,
316-
handleTextQueryInit,
317-
handleTextQuery,
318-
handleTextQueryAllFrames,
319-
textQueryRunning,
320-
timeFilter,
321229
};
322230
},
323231
});
@@ -330,13 +238,10 @@ export default defineComponent({
330238
ref="viewerRef"
331239
:revision="revisionNum"
332240
:current-set="set"
333-
:read-only-mode="!!getters['Jobs/datasetRunningState'](id) || textQueryRunning"
241+
:read-only-mode="!!getters['Jobs/datasetRunningState'](id)"
334242
:comparison-sets="comparisonSets"
335243
@large-image-warning="largeImageWarning()"
336244
@update:set="routeSet"
337-
@text-query-init="handleTextQueryInit"
338-
@text-query="handleTextQuery"
339-
@text-query-all-frames="handleTextQueryAllFrames"
340245
>
341246
<template #title>
342247
<ViewerAlert />
@@ -360,7 +265,6 @@ export default defineComponent({
360265
:selected-dataset-ids="[id]"
361266
:running-pipelines="runningPipelines"
362267
:read-only-mode="revisionNum !== undefined"
363-
:time-filter="timeFilter"
364268
/>
365269
<ImportAnnotations
366270
:button-options="buttonOptions"
@@ -381,8 +285,8 @@ export default defineComponent({
381285
:revision="revisionNum"
382286
/>
383287
</template>
384-
<template #right-sidebar="{ sidebarMode }">
385-
<SidebarContext :bottom-mode="sidebarMode === 'bottom'">
288+
<template #right-sidebar>
289+
<SidebarContext>
386290
<template #default="{ name, subCategory }">
387291
<component
388292
:is="name"

0 commit comments

Comments
 (0)