@geode/opengeodeweb-front 10.31.0 → 10.32.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/components/CameraOrientation.vue +1 -1
- package/app/components/HybridRenderingView.vue +8 -0
- package/app/components/Ruler.vue +144 -0
- package/app/components/ViewToolbar.vue +12 -0
- package/app/components/Viewer/Ui.vue +27 -1
- package/app/stores/hybrid_viewer.js +52 -262
- package/internal/stores/{hybrid_viewer_brightness.js → hybrid_viewer/brightness.js} +29 -5
- package/internal/stores/{hybrid_viewer_camera.js → hybrid_viewer/camera.js} +105 -55
- package/internal/stores/hybrid_viewer/filters.js +38 -0
- package/internal/stores/hybrid_viewer/highlight.js +162 -0
- package/internal/stores/hybrid_viewer/ruler.js +121 -0
- package/internal/stores/hybrid_viewer/scene.js +141 -0
- package/internal/stores/hybrid_viewer/viewport.js +148 -0
- package/package.json +3 -3
- package/internal/stores/hybrid_viewer.js +0 -300
- package/internal/stores/hybrid_viewer_highlight.js +0 -114
- /package/internal/stores/{hybrid_viewer_camera_animation.js → hybrid_viewer/camera_animation.js} +0 -0
- /package/internal/stores/{hybrid_viewer_constants.js → hybrid_viewer/constants.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import ToolPanel from "@ogw_front/components/ToolPanel";
|
|
3
|
-
import { applyCameraOptions } from "@ogw_internal/stores/
|
|
3
|
+
import { applyCameraOptions } from "@ogw_internal/stores/hybrid_viewer/camera";
|
|
4
4
|
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
5
5
|
import { newInstance as vtkAnnotatedCubeActor } from "@kitware/vtk.js/Rendering/Core/AnnotatedCubeActor";
|
|
6
6
|
import { newInstance as vtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow";
|
|
@@ -55,6 +55,14 @@ function debounce(func, wait) {
|
|
|
55
55
|
|
|
56
56
|
async function handleClick(event) {
|
|
57
57
|
const { offsetX, offsetY, clientX, clientY } = event;
|
|
58
|
+
if (hybridViewerStore.is_ruler_active) {
|
|
59
|
+
const rect = container.value.$el.getBoundingClientRect();
|
|
60
|
+
const x = event.clientX - rect.left;
|
|
61
|
+
const y = elementHeight.value - (event.clientY - rect.top);
|
|
62
|
+
await hybridViewerStore.handleRulerClick(x, y);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
58
66
|
if (viewerStore.picking_mode) {
|
|
59
67
|
const rect = container.value.$el.getBoundingClientRect();
|
|
60
68
|
const x = event.clientX - rect.left;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import ToolPanel from "@ogw_front/components/ToolPanel";
|
|
3
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
4
|
+
|
|
5
|
+
const show = defineModel("show", { type: Boolean, default: false });
|
|
6
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
7
|
+
|
|
8
|
+
const localPoint1 = ref([0, 0, 0]);
|
|
9
|
+
const localPoint2 = ref([0, 0, 0]);
|
|
10
|
+
|
|
11
|
+
watch(
|
|
12
|
+
() => hybridViewerStore.ruler_point1,
|
|
13
|
+
(point) => {
|
|
14
|
+
if (point) {
|
|
15
|
+
localPoint1.value = [...point];
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
watch(
|
|
21
|
+
() => hybridViewerStore.ruler_point2,
|
|
22
|
+
(point) => {
|
|
23
|
+
if (point) {
|
|
24
|
+
localPoint2.value = [...point];
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
watch(show, (visible) => {
|
|
30
|
+
if (visible) {
|
|
31
|
+
hybridViewerStore.is_ruler_active = true;
|
|
32
|
+
} else if (hybridViewerStore.is_ruler_active) {
|
|
33
|
+
hybridViewerStore.deactivateRuler();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
watch(
|
|
38
|
+
() => hybridViewerStore.is_ruler_active,
|
|
39
|
+
(active) => {
|
|
40
|
+
if (!active) {
|
|
41
|
+
show.value = false;
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
async function applyManualCoords() {
|
|
47
|
+
hybridViewerStore.ruler_point1 = [...localPoint1.value];
|
|
48
|
+
hybridViewerStore.ruler_point2 = [...localPoint2.value];
|
|
49
|
+
await hybridViewerStore.applyRuler();
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<template>
|
|
54
|
+
<ToolPanel
|
|
55
|
+
v-model="show"
|
|
56
|
+
title="Ruler"
|
|
57
|
+
:width="300"
|
|
58
|
+
close-label="Stop ruler"
|
|
59
|
+
:click-outside="false"
|
|
60
|
+
>
|
|
61
|
+
<v-card-text class="pa-3">
|
|
62
|
+
<v-switch
|
|
63
|
+
v-model="hybridViewerStore.ruler_snap"
|
|
64
|
+
data-testid="rulerSnapToggle"
|
|
65
|
+
label="Snap to vertex"
|
|
66
|
+
color="primary"
|
|
67
|
+
density="compact"
|
|
68
|
+
hide-details
|
|
69
|
+
class="mb-4"
|
|
70
|
+
/>
|
|
71
|
+
|
|
72
|
+
<v-divider class="mb-3" />
|
|
73
|
+
|
|
74
|
+
<div class="text-caption font-weight-bold mb-2 text-medium-emphasis">Point 1</div>
|
|
75
|
+
<v-row dense class="mb-1" data-testid="rulerPointCard">
|
|
76
|
+
<v-col v-for="(axis, index) in ['X', 'Y', 'Z']" :key="axis">
|
|
77
|
+
<v-text-field
|
|
78
|
+
v-model.number="localPoint1[index]"
|
|
79
|
+
data-testid="rulerPointCoordInput"
|
|
80
|
+
:label="axis"
|
|
81
|
+
type="number"
|
|
82
|
+
density="compact"
|
|
83
|
+
variant="outlined"
|
|
84
|
+
hide-details
|
|
85
|
+
/>
|
|
86
|
+
</v-col>
|
|
87
|
+
</v-row>
|
|
88
|
+
|
|
89
|
+
<div class="text-caption font-weight-bold mb-2 mt-3 text-medium-emphasis">Point 2</div>
|
|
90
|
+
<v-row dense class="mb-1" data-testid="rulerPointCard">
|
|
91
|
+
<v-col v-for="(axis, index) in ['X', 'Y', 'Z']" :key="axis">
|
|
92
|
+
<v-text-field
|
|
93
|
+
v-model.number="localPoint2[index]"
|
|
94
|
+
data-testid="rulerPointCoordInput"
|
|
95
|
+
:label="axis"
|
|
96
|
+
type="number"
|
|
97
|
+
density="compact"
|
|
98
|
+
variant="outlined"
|
|
99
|
+
hide-details
|
|
100
|
+
/>
|
|
101
|
+
</v-col>
|
|
102
|
+
</v-row>
|
|
103
|
+
|
|
104
|
+
<v-btn
|
|
105
|
+
data-testid="rulerApplyButton"
|
|
106
|
+
variant="tonal"
|
|
107
|
+
size="small"
|
|
108
|
+
color="primary"
|
|
109
|
+
block
|
|
110
|
+
class="mt-3 text-caption text-none"
|
|
111
|
+
@click="applyManualCoords"
|
|
112
|
+
>
|
|
113
|
+
Apply
|
|
114
|
+
</v-btn>
|
|
115
|
+
|
|
116
|
+
<v-divider class="my-3" />
|
|
117
|
+
|
|
118
|
+
<div v-if="hybridViewerStore.ruler_distance !== undefined" class="text-center">
|
|
119
|
+
<div class="text-caption text-medium-emphasis mb-1">Distance</div>
|
|
120
|
+
<div data-testid="rulerDistance" class="text-h6 font-weight-bold">
|
|
121
|
+
{{ hybridViewerStore.ruler_distance.toFixed(4) }}
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
<div v-else class="text-caption text-medium-emphasis text-center">
|
|
125
|
+
Click in the scene to set both points
|
|
126
|
+
</div>
|
|
127
|
+
</v-card-text>
|
|
128
|
+
|
|
129
|
+
<template #actions>
|
|
130
|
+
<v-card-actions class="justify-center pb-3 pt-0">
|
|
131
|
+
<v-btn
|
|
132
|
+
data-testid="rulerClearButton"
|
|
133
|
+
variant="text"
|
|
134
|
+
size="small"
|
|
135
|
+
color="error"
|
|
136
|
+
class="text-caption text-none"
|
|
137
|
+
@click="hybridViewerStore.clearRuler()"
|
|
138
|
+
>
|
|
139
|
+
Clear
|
|
140
|
+
</v-btn>
|
|
141
|
+
</v-card-actions>
|
|
142
|
+
</template>
|
|
143
|
+
</ToolPanel>
|
|
144
|
+
</template>
|
|
@@ -4,6 +4,7 @@ import CameraBookmarkIcon from "@ogw_front/assets/viewer_svgs/camera-bookmark.sv
|
|
|
4
4
|
import CameraManager from "@ogw_front/components/CameraManager";
|
|
5
5
|
import CameraOrientation from "@ogw_front/components/CameraOrientation";
|
|
6
6
|
import ClippingPlanes from "@ogw_front/components/ClippingPlanes";
|
|
7
|
+
import Ruler from "@ogw_front/components/Ruler";
|
|
7
8
|
import Screenshot from "@ogw_front/components/Screenshot";
|
|
8
9
|
import ShrinkFilter from "@ogw_front/components/ShrinkFilter";
|
|
9
10
|
import ZScaling from "@ogw_front/components/ZScaling";
|
|
@@ -19,6 +20,7 @@ const showCameraOrientation = ref(false);
|
|
|
19
20
|
const showZScaling = ref(false);
|
|
20
21
|
const showClippingPlanes = ref(false);
|
|
21
22
|
const showShrinkFilter = ref(false);
|
|
23
|
+
const showRuler = ref(false);
|
|
22
24
|
const grid_scale = ref(false);
|
|
23
25
|
const zScale = ref(hybridViewerStore.zScale);
|
|
24
26
|
|
|
@@ -173,6 +175,15 @@ const camera_options = computed(() => [
|
|
|
173
175
|
showShrinkFilter.value = !showShrinkFilter.value;
|
|
174
176
|
},
|
|
175
177
|
},
|
|
178
|
+
{
|
|
179
|
+
testId: "rulerButton",
|
|
180
|
+
tooltip: "Ruler",
|
|
181
|
+
icon: "mdi-ruler",
|
|
182
|
+
color: showRuler.value ? "primary" : undefined,
|
|
183
|
+
action: () => {
|
|
184
|
+
showRuler.value = !showRuler.value;
|
|
185
|
+
},
|
|
186
|
+
},
|
|
176
187
|
]);
|
|
177
188
|
</script>
|
|
178
189
|
|
|
@@ -247,6 +258,7 @@ const camera_options = computed(() => [
|
|
|
247
258
|
/>
|
|
248
259
|
<ClippingPlanes v-model:show="showClippingPlanes" />
|
|
249
260
|
<ShrinkFilter v-model:show="showShrinkFilter" />
|
|
261
|
+
<Ruler v-model:show="showRuler" />
|
|
250
262
|
</template>
|
|
251
263
|
|
|
252
264
|
<style module>
|
|
@@ -25,7 +25,9 @@ function stopHoverHighlight() {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
onKeyStroke("Escape", () => {
|
|
28
|
-
if (hybridViewerStore.
|
|
28
|
+
if (hybridViewerStore.is_ruler_active) {
|
|
29
|
+
hybridViewerStore.deactivateRuler();
|
|
30
|
+
} else if (hybridViewerStore.is_hover_highlight) {
|
|
29
31
|
stopHoverHighlight();
|
|
30
32
|
}
|
|
31
33
|
});
|
|
@@ -129,6 +131,30 @@ defineExpose({ get_viewer_id });
|
|
|
129
131
|
</v-chip>
|
|
130
132
|
</div>
|
|
131
133
|
</v-fade-transition>
|
|
134
|
+
|
|
135
|
+
<v-fade-transition>
|
|
136
|
+
<div
|
|
137
|
+
v-if="hybridViewerStore.is_ruler_active"
|
|
138
|
+
class="picking-message-container d-flex justify-center w-100 pa-4"
|
|
139
|
+
>
|
|
140
|
+
<v-chip
|
|
141
|
+
data-testid="rulerActiveChip"
|
|
142
|
+
color="secondary"
|
|
143
|
+
elevation="8"
|
|
144
|
+
size="large"
|
|
145
|
+
variant="flat"
|
|
146
|
+
class="pick-pulse"
|
|
147
|
+
style="pointer-events: auto"
|
|
148
|
+
prepend-icon="mdi-ruler"
|
|
149
|
+
@click="hybridViewerStore.clearRuler()"
|
|
150
|
+
>
|
|
151
|
+
Ruler — click to set point {{ hybridViewerStore.ruler_awaiting_point }}
|
|
152
|
+
· Esc to stop
|
|
153
|
+
<v-divider vertical class="mx-2 my-1" opacity="0.3" />
|
|
154
|
+
<v-icon icon="mdi-close" size="small" />
|
|
155
|
+
</v-chip>
|
|
156
|
+
</div>
|
|
157
|
+
</v-fade-transition>
|
|
132
158
|
</template>
|
|
133
159
|
|
|
134
160
|
<style scoped>
|
|
@@ -1,81 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ACTOR_COLOR,
|
|
3
|
-
BACKGROUND_COLOR,
|
|
4
|
-
WHEEL_TIME_OUT_MS,
|
|
5
|
-
} from "@ogw_internal/stores/hybrid_viewer_constants";
|
|
6
1
|
import {
|
|
7
2
|
applySnapshot,
|
|
8
3
|
getCameraOptions,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "@ogw_internal/stores/
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from "@ogw_internal/stores/
|
|
18
|
-
import {
|
|
19
|
-
performAddItem,
|
|
20
|
-
performClear,
|
|
21
|
-
performClearHoverHighlight,
|
|
22
|
-
performClickPicking,
|
|
23
|
-
performRemoveItem,
|
|
24
|
-
performResize,
|
|
25
|
-
performSetClippingPlanes,
|
|
26
|
-
performSetContainer,
|
|
27
|
-
performSetShrink,
|
|
28
|
-
performSetVisibility,
|
|
29
|
-
performSetZScaling,
|
|
30
|
-
} from "@ogw_internal/stores/hybrid_viewer";
|
|
31
|
-
import { computeAverageBrightness } from "@ogw_internal/stores/hybrid_viewer_brightness";
|
|
32
|
-
import { newInstance as vtkActor } from "@kitware/vtk.js/Rendering/Core/Actor";
|
|
4
|
+
useHybridViewerCamera,
|
|
5
|
+
} from "@ogw_internal/stores/hybrid_viewer/camera";
|
|
6
|
+
import { BACKGROUND_COLOR } from "@ogw_internal/stores/hybrid_viewer/constants";
|
|
7
|
+
import { useHybridViewerBrightness } from "@ogw_internal/stores/hybrid_viewer/brightness";
|
|
8
|
+
import { useHybridViewerFilters } from "@ogw_internal/stores/hybrid_viewer/filters";
|
|
9
|
+
import { useHybridViewerHighlight } from "@ogw_internal/stores/hybrid_viewer/highlight";
|
|
10
|
+
import { useHybridViewerRuler } from "@ogw_internal/stores/hybrid_viewer/ruler";
|
|
11
|
+
import { useHybridViewerScene } from "@ogw_internal/stores/hybrid_viewer/scene";
|
|
12
|
+
import { useHybridViewerViewport } from "@ogw_internal/stores/hybrid_viewer/viewport";
|
|
33
13
|
import { newInstance as vtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow";
|
|
34
|
-
import { newInstance as vtkMapper } from "@kitware/vtk.js/Rendering/Core/Mapper";
|
|
35
|
-
import { newInstance as vtkXMLPolyDataReader } from "@kitware/vtk.js/IO/XML/XMLPolyDataReader";
|
|
36
14
|
|
|
37
15
|
import { Status } from "@ogw_front/utils/status";
|
|
38
|
-
import { useDataStore } from "@ogw_front/stores/data";
|
|
39
16
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
40
17
|
|
|
41
18
|
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
42
19
|
|
|
43
20
|
// oxlint-disable max-lines-per-function, max-statements
|
|
44
21
|
export const useHybridViewerStore = defineStore("hybridViewer", () => {
|
|
45
|
-
const dataStore = useDataStore();
|
|
46
|
-
const hybridDb = reactive({});
|
|
47
22
|
const viewerStore = useViewerStore();
|
|
48
|
-
const camera_options = reactive({});
|
|
49
23
|
const genericRenderWindow = reactive({});
|
|
50
24
|
const status = ref(Status.NOT_CREATED);
|
|
51
25
|
const is_moving = ref(false);
|
|
52
26
|
const is_picking = ref(false);
|
|
53
|
-
const is_hover_highlight = ref(false);
|
|
54
|
-
const hover_highlight_field_type = ref("CELL");
|
|
55
|
-
const hoverData = ref(undefined);
|
|
56
|
-
const hoverPosition = ref({ x: 0, y: 0 });
|
|
57
|
-
const zScale = ref(1);
|
|
58
27
|
let imageStyle = undefined;
|
|
59
|
-
let viewStream = undefined;
|
|
60
|
-
let wheelEventEndTimeout = undefined;
|
|
61
|
-
const gridActor = undefined;
|
|
62
28
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
29
|
+
const brightnessStore = useHybridViewerBrightness();
|
|
30
|
+
const sceneStore = useHybridViewerScene();
|
|
31
|
+
const filtersStore = useHybridViewerFilters();
|
|
32
|
+
const highlightStore = useHybridViewerHighlight();
|
|
33
|
+
const rulerStore = useHybridViewerRuler();
|
|
34
|
+
const cameraStore = useHybridViewerCamera();
|
|
35
|
+
const viewportStore = useHybridViewerViewport();
|
|
36
|
+
|
|
37
|
+
const is_cursor_crosshair = computed(() => is_picking.value || rulerStore.is_ruler_active.value);
|
|
38
|
+
|
|
39
|
+
watch(is_cursor_crosshair, (value) => {
|
|
40
|
+
if (!genericRenderWindow.value) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const webGLRenderWindow = genericRenderWindow.value.getApiSpecificRenderWindow();
|
|
44
|
+
const canvas = webGLRenderWindow.getCanvas();
|
|
45
|
+
if (canvas && canvas.parentElement) {
|
|
46
|
+
canvas.parentElement.style.cursor = value ? "crosshair" : "default";
|
|
69
47
|
}
|
|
70
48
|
});
|
|
71
49
|
|
|
72
|
-
const latestImage = ref(undefined);
|
|
73
|
-
const offscreenCanvas =
|
|
74
|
-
typeof document === "undefined" ? undefined : document.createElement("canvas");
|
|
75
|
-
const offscreenCtx = offscreenCanvas
|
|
76
|
-
? offscreenCanvas.getContext("2d", { willReadFrequently: true })
|
|
77
|
-
: undefined;
|
|
78
|
-
|
|
79
50
|
async function initHybridViewer() {
|
|
80
51
|
if (status.value !== Status.NOT_CREATED) {
|
|
81
52
|
return;
|
|
@@ -89,112 +60,25 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => {
|
|
|
89
60
|
imageStyle = webGLRenderWindow.getReferenceByName("bgImage").style;
|
|
90
61
|
Object.assign(imageStyle, { transition: "opacity 0.1s ease-in", zIndex: 1 });
|
|
91
62
|
await viewerStore.ws_connect();
|
|
92
|
-
|
|
93
|
-
viewStream.
|
|
63
|
+
const imageStream = viewerStore.client.getImageStream();
|
|
64
|
+
viewportStore.viewStream.value = imageStream.createViewStream("-1");
|
|
65
|
+
viewportStore.viewStream.value.onImageReady((event) => {
|
|
94
66
|
if (is_moving.value) {
|
|
95
67
|
return;
|
|
96
68
|
}
|
|
97
|
-
latestImage.value = event.image;
|
|
69
|
+
brightnessStore.latestImage.value = event.image;
|
|
98
70
|
webGLRenderWindow.setBackgroundImage(event.image);
|
|
99
71
|
imageStyle.opacity = 1;
|
|
100
72
|
});
|
|
101
|
-
const
|
|
102
|
-
|
|
73
|
+
const renderer = genericRenderWindow.value.getRenderer();
|
|
74
|
+
const camera = renderer.getActiveCamera();
|
|
75
|
+
Object.assign(cameraStore.camera_options, getCameraOptions(camera));
|
|
103
76
|
camera.onModified(() => {
|
|
104
|
-
Object.assign(camera_options, getCameraOptions(camera));
|
|
77
|
+
Object.assign(cameraStore.camera_options, getCameraOptions(camera));
|
|
105
78
|
});
|
|
106
79
|
status.value = Status.CREATED;
|
|
107
80
|
}
|
|
108
81
|
|
|
109
|
-
async function addItem(id) {
|
|
110
|
-
await performAddItem(id, {
|
|
111
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
112
|
-
dataStore,
|
|
113
|
-
vtkXMLPolyDataReader,
|
|
114
|
-
vtkActor,
|
|
115
|
-
vtkMapper,
|
|
116
|
-
actorColor: ACTOR_COLOR,
|
|
117
|
-
hybridDb,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function removeItem(id) {
|
|
122
|
-
performRemoveItem(id, { genericRenderWindow: genericRenderWindow.value, hybridDb });
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function setVisibility(id, visibility) {
|
|
126
|
-
performSetVisibility(id, visibility, {
|
|
127
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
128
|
-
hybridDb,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async function setZScaling(z_scale) {
|
|
133
|
-
await performSetZScaling(z_scale, {
|
|
134
|
-
zScale,
|
|
135
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
136
|
-
gridActor,
|
|
137
|
-
viewerStore,
|
|
138
|
-
viewer_schemas,
|
|
139
|
-
remoteRender,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async function setClippingPlanes(ids, planes) {
|
|
144
|
-
await performSetClippingPlanes(ids, planes, { viewerStore, viewer_schemas, remoteRender });
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async function setShrink(ids, shrink_factor) {
|
|
148
|
-
await performSetShrink(ids, shrink_factor, { viewerStore, viewer_schemas, remoteRender });
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function resetCamera() {
|
|
152
|
-
genericRenderWindow.value.getRenderer().resetCamera();
|
|
153
|
-
genericRenderWindow.value.getRenderWindow().render();
|
|
154
|
-
syncRemoteCamera();
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
async function focusCameraOnObject(id, block_ids = []) {
|
|
158
|
-
await performFocusCameraOnObject(id, {
|
|
159
|
-
hybridDb,
|
|
160
|
-
viewerStore,
|
|
161
|
-
viewer_schemas,
|
|
162
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
163
|
-
block_ids,
|
|
164
|
-
is_moving,
|
|
165
|
-
imageStyle,
|
|
166
|
-
syncRemoteCamera,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function setCameraOrientation(orientation) {
|
|
171
|
-
performCameraOrientation(orientation, {
|
|
172
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
173
|
-
is_moving,
|
|
174
|
-
imageStyle,
|
|
175
|
-
syncRemoteCamera,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function setCamera(targetCameraOptions) {
|
|
180
|
-
performSetCamera(targetCameraOptions, {
|
|
181
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
182
|
-
is_moving,
|
|
183
|
-
imageStyle,
|
|
184
|
-
syncRemoteCamera,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function syncRemoteCamera() {
|
|
189
|
-
performSyncRemoteCamera({
|
|
190
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
191
|
-
viewerStore,
|
|
192
|
-
viewer_schemas,
|
|
193
|
-
remoteRender,
|
|
194
|
-
camera_options,
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
82
|
let renderPromise = undefined;
|
|
199
83
|
let renderPending = false;
|
|
200
84
|
|
|
@@ -219,124 +103,30 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => {
|
|
|
219
103
|
return renderPromise;
|
|
220
104
|
}
|
|
221
105
|
|
|
222
|
-
const hoverTimeoutRef = ref(undefined);
|
|
223
|
-
const currentHoverId = ref(undefined);
|
|
224
|
-
|
|
225
|
-
const clearHoverData = createClearHoverData(hoverTimeoutRef, hoverData, currentHoverId);
|
|
226
|
-
|
|
227
|
-
const hoverHighlight = createHoverHighlight({
|
|
228
|
-
genericRenderWindow,
|
|
229
|
-
is_hover_highlight,
|
|
230
|
-
viewerStore,
|
|
231
|
-
viewer_schemas,
|
|
232
|
-
hover_highlight_field_type,
|
|
233
|
-
hybridDb,
|
|
234
|
-
hoverData,
|
|
235
|
-
hoverPosition,
|
|
236
|
-
currentHoverId,
|
|
237
|
-
hoverTimeoutRef,
|
|
238
|
-
clearHoverData,
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
function clearHoverHighlight() {
|
|
242
|
-
clearHoverData();
|
|
243
|
-
performClearHoverHighlight({
|
|
244
|
-
viewerStore,
|
|
245
|
-
viewer_schemas,
|
|
246
|
-
hover_highlight_field_type,
|
|
247
|
-
hybridDb,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
function setContainer(container) {
|
|
252
|
-
performSetContainer({
|
|
253
|
-
container,
|
|
254
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
255
|
-
imageStyleSetter: (style) => (imageStyle = style),
|
|
256
|
-
resize,
|
|
257
|
-
useMousePressed,
|
|
258
|
-
useEventListener,
|
|
259
|
-
is_picking,
|
|
260
|
-
is_moving,
|
|
261
|
-
clickPickingCallback: performClickPicking,
|
|
262
|
-
viewerStore,
|
|
263
|
-
viewer_schemas,
|
|
264
|
-
syncRemoteCamera,
|
|
265
|
-
hoverHighlight,
|
|
266
|
-
wheelTimeoutMs: WHEEL_TIME_OUT_MS,
|
|
267
|
-
wheelEventEndTimeout,
|
|
268
|
-
wheelTimeoutSetter: (timeout) => (wheelEventEndTimeout = timeout),
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
async function resize(width, height) {
|
|
273
|
-
await performResize(width, height, {
|
|
274
|
-
viewerStore,
|
|
275
|
-
status,
|
|
276
|
-
Status,
|
|
277
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
278
|
-
viewStream,
|
|
279
|
-
remoteRender,
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function getAverageBrightness(rect) {
|
|
284
|
-
return computeAverageBrightness(rect, {
|
|
285
|
-
latestImage: latestImage.value,
|
|
286
|
-
offscreenCtx,
|
|
287
|
-
offscreenCanvas,
|
|
288
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
106
|
function exportStores() {
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
genericRenderWindow: genericRenderWindow.value,
|
|
300
|
-
setZScaling,
|
|
301
|
-
syncRemoteCamera,
|
|
302
|
-
setCamera,
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
function clear() {
|
|
307
|
-
performClear({ genericRenderWindow: genericRenderWindow.value, hybridDb });
|
|
107
|
+
const renderer = genericRenderWindow.value.getRenderer();
|
|
108
|
+
const camera = renderer.getActiveCamera();
|
|
109
|
+
return {
|
|
110
|
+
zScale: sceneStore.zScale.value,
|
|
111
|
+
camera_options: getCameraOptions(camera) || cameraStore.camera_options,
|
|
112
|
+
};
|
|
308
113
|
}
|
|
309
114
|
|
|
310
115
|
return {
|
|
311
|
-
hybridDb,
|
|
312
116
|
genericRenderWindow,
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
setZScaling,
|
|
317
|
-
setClippingPlanes,
|
|
318
|
-
setShrink,
|
|
319
|
-
syncRemoteCamera,
|
|
320
|
-
setCamera,
|
|
117
|
+
status,
|
|
118
|
+
is_moving,
|
|
119
|
+
is_picking,
|
|
321
120
|
initHybridViewer,
|
|
322
121
|
remoteRender,
|
|
323
|
-
resize,
|
|
324
|
-
resetCamera,
|
|
325
|
-
focusCameraOnObject,
|
|
326
|
-
setCameraOrientation,
|
|
327
|
-
setContainer,
|
|
328
|
-
zScale,
|
|
329
|
-
is_picking,
|
|
330
|
-
is_hover_highlight,
|
|
331
|
-
hover_highlight_field_type,
|
|
332
|
-
clearHoverHighlight,
|
|
333
|
-
hoverData,
|
|
334
|
-
hoverPosition,
|
|
335
|
-
clear,
|
|
336
122
|
exportStores,
|
|
337
|
-
importStores,
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
123
|
+
importStores: applySnapshot,
|
|
124
|
+
...brightnessStore,
|
|
125
|
+
...sceneStore,
|
|
126
|
+
...viewportStore,
|
|
127
|
+
...filtersStore,
|
|
128
|
+
...highlightStore,
|
|
129
|
+
...rulerStore,
|
|
130
|
+
...cameraStore,
|
|
341
131
|
};
|
|
342
132
|
});
|
|
@@ -1,9 +1,32 @@
|
|
|
1
|
-
import { BACKGROUND_GREY_VALUE, RGB_MAX } from "./
|
|
1
|
+
import { BACKGROUND_GREY_VALUE, RGB_MAX } from "./constants";
|
|
2
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
2
3
|
|
|
3
4
|
const RGBA_CHANNELS = 4;
|
|
4
5
|
const SAMPLE_SIZE = 10;
|
|
5
6
|
const TOTAL_CHANNELS = 400;
|
|
6
7
|
|
|
8
|
+
function useHybridViewerBrightness() {
|
|
9
|
+
const latestImage = ref(undefined);
|
|
10
|
+
const offscreenCanvas =
|
|
11
|
+
typeof document === "undefined" ? undefined : document.createElement("canvas");
|
|
12
|
+
const offscreenCtx = offscreenCanvas
|
|
13
|
+
? offscreenCanvas.getContext("2d", { willReadFrequently: true })
|
|
14
|
+
: undefined;
|
|
15
|
+
|
|
16
|
+
function getAverageBrightness(rect) {
|
|
17
|
+
return computeAverageBrightness(rect, {
|
|
18
|
+
latestImage: latestImage.value,
|
|
19
|
+
offscreenCtx,
|
|
20
|
+
offscreenCanvas,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
latestImage,
|
|
26
|
+
getAverageBrightness,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
7
30
|
function mapRect(rect, latestImage, canvasRect) {
|
|
8
31
|
const scaleX = latestImage.width / canvasRect.width;
|
|
9
32
|
const scaleY = latestImage.height / canvasRect.height;
|
|
@@ -16,11 +39,12 @@ function mapRect(rect, latestImage, canvasRect) {
|
|
|
16
39
|
}
|
|
17
40
|
|
|
18
41
|
function computeAverageBrightness(rect, options) {
|
|
19
|
-
const { latestImage, offscreenCtx, offscreenCanvas
|
|
20
|
-
|
|
42
|
+
const { latestImage, offscreenCtx, offscreenCanvas } = options;
|
|
43
|
+
const { genericRenderWindow } = useHybridViewerStore();
|
|
44
|
+
if (!latestImage || !offscreenCtx || !offscreenCanvas || !genericRenderWindow.value) {
|
|
21
45
|
return BACKGROUND_GREY_VALUE / RGB_MAX;
|
|
22
46
|
}
|
|
23
|
-
const canvas = genericRenderWindow.getApiSpecificRenderWindow().getCanvas();
|
|
47
|
+
const canvas = genericRenderWindow.value.getApiSpecificRenderWindow().getCanvas();
|
|
24
48
|
if (!canvas) {
|
|
25
49
|
return BACKGROUND_GREY_VALUE / RGB_MAX;
|
|
26
50
|
}
|
|
@@ -59,4 +83,4 @@ function computeAverageBrightness(rect, options) {
|
|
|
59
83
|
}
|
|
60
84
|
}
|
|
61
85
|
|
|
62
|
-
export { computeAverageBrightness };
|
|
86
|
+
export { computeAverageBrightness, useHybridViewerBrightness };
|