@geode/opengeodeweb-front 10.31.0 → 10.31.1-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.
@@ -0,0 +1,38 @@
1
+ import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
2
+ import { useViewerStore } from "@ogw_front/stores/viewer";
3
+ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
4
+
5
+ function useHybridViewerFilters() {
6
+ async function setClippingPlanes(ids, planes) {
7
+ await performSetClippingPlanes(ids, planes);
8
+ }
9
+
10
+ async function setShrink(ids, shrink_factor) {
11
+ await performSetShrink(ids, shrink_factor);
12
+ }
13
+
14
+ return {
15
+ setClippingPlanes,
16
+ setShrink,
17
+ };
18
+ }
19
+
20
+ async function performSetClippingPlanes(ids, planes) {
21
+ const viewerStore = useViewerStore();
22
+ const { remoteRender } = useHybridViewerStore();
23
+ const schema = viewer_schemas.opengeodeweb_viewer.viewer.clipping_planes;
24
+ const params = { ids, planes };
25
+ await viewerStore.request({ schema, params });
26
+ await remoteRender();
27
+ }
28
+
29
+ async function performSetShrink(ids, shrink_factor) {
30
+ const viewerStore = useViewerStore();
31
+ const { remoteRender } = useHybridViewerStore();
32
+ const schema = viewer_schemas.opengeodeweb_viewer.viewer.shrink;
33
+ const params = { ids, shrink_factor };
34
+ await viewerStore.request({ schema, params });
35
+ await remoteRender();
36
+ }
37
+
38
+ export { performSetClippingPlanes, performSetShrink, useHybridViewerFilters };
@@ -0,0 +1,162 @@
1
+ import { HOVER_DEBOUNCE_MS, HOVER_TIMEOUT_MS } from "./constants";
2
+ import { database } from "@ogw_internal/database/database.js";
3
+ import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
4
+ import { useViewerStore } from "@ogw_front/stores/viewer";
5
+ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
6
+
7
+ function useHybridViewerHighlight() {
8
+ const is_hover_highlight = ref(false);
9
+ const hover_highlight_field_type = ref("CELL");
10
+ const hoverData = ref(undefined);
11
+ const hoverPosition = ref({ x: 0, y: 0 });
12
+ const hoverTimeoutRef = ref(undefined);
13
+ const currentHoverId = ref(undefined);
14
+
15
+ const clearHoverData = createClearHoverData(hoverTimeoutRef, hoverData, currentHoverId);
16
+
17
+ const hoverHighlight = createHoverHighlight({ hoverTimeoutRef, currentHoverId, clearHoverData });
18
+
19
+ function clearHoverHighlight() {
20
+ clearHoverData();
21
+ performClearHoverHighlight();
22
+ }
23
+
24
+ return {
25
+ is_hover_highlight,
26
+ hover_highlight_field_type,
27
+ hoverData,
28
+ hoverPosition,
29
+ clearHoverHighlight,
30
+ hoverHighlight,
31
+ };
32
+ }
33
+
34
+ function performHoverHighlight(event, onResponse) {
35
+ const hybridViewerStore = useHybridViewerStore();
36
+ const { genericRenderWindow, hybridDb } = hybridViewerStore;
37
+ const { is_hover_highlight, hover_highlight_field_type } = storeToRefs(hybridViewerStore);
38
+ if (!is_hover_highlight.value) {
39
+ return;
40
+ }
41
+ const container = genericRenderWindow.value?.getContainer();
42
+ if (!container) {
43
+ return;
44
+ }
45
+ const viewerStore = useViewerStore();
46
+ const rect = container.getBoundingClientRect();
47
+ const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight;
48
+ const params = {
49
+ x: Math.round(event.clientX - rect.left),
50
+ y: Math.round(rect.height - (event.clientY - rect.top)),
51
+ field_type: hover_highlight_field_type.value,
52
+ ids: Object.keys(hybridDb),
53
+ };
54
+ viewerStore.request({ schema, params }, { response_function: onResponse });
55
+ }
56
+
57
+ function performClearHoverHighlight() {
58
+ const { hybridDb } = useHybridViewerStore();
59
+ const { hover_highlight_field_type } = storeToRefs(useHybridViewerStore());
60
+ const viewerStore = useViewerStore();
61
+ const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight;
62
+ const params = {
63
+ x: -1,
64
+ y: -1,
65
+ field_type: hover_highlight_field_type.value,
66
+ ids: Object.keys(hybridDb),
67
+ };
68
+ viewerStore.request({ schema, params });
69
+ }
70
+
71
+ function createClearHoverData(hoverTimeoutRef, hoverData, currentHoverId) {
72
+ return function clearHoverData() {
73
+ if (hoverTimeoutRef.value) {
74
+ clearTimeout(hoverTimeoutRef.value);
75
+ hoverTimeoutRef.value = undefined;
76
+ }
77
+ hoverData.value = undefined;
78
+ currentHoverId.value = undefined;
79
+ };
80
+ }
81
+
82
+ function createHoverHighlight({ hoverTimeoutRef, currentHoverId, clearHoverData }) {
83
+ return useDebounceFn((event) => {
84
+ const hybridViewerStore = useHybridViewerStore();
85
+ const { genericRenderWindow } = hybridViewerStore;
86
+ const { is_hover_highlight, hoverData, hoverPosition } = storeToRefs(hybridViewerStore);
87
+ const containerElement = genericRenderWindow.value?.getContainer();
88
+ const relativeMousePosition = containerElement
89
+ ? {
90
+ x: event.clientX - containerElement.getBoundingClientRect().left,
91
+ y: event.clientY - containerElement.getBoundingClientRect().top,
92
+ }
93
+ : { x: event.clientX, y: event.clientY };
94
+
95
+ performHoverHighlight(event, async (response) => {
96
+ const isResponseValid =
97
+ response && response.id && response.picked_id !== undefined && response.picked_id !== -1;
98
+ if (!is_hover_highlight.value || !isResponseValid) {
99
+ clearHoverData();
100
+ return;
101
+ }
102
+
103
+ const hoverKey = `${response.id}_${response.field_type}_${response.picked_id}`;
104
+ if (currentHoverId.value === hoverKey) {
105
+ return;
106
+ }
107
+
108
+ if (hoverTimeoutRef.value) {
109
+ clearTimeout(hoverTimeoutRef.value);
110
+ hoverTimeoutRef.value = undefined;
111
+ }
112
+
113
+ hoverData.value = undefined;
114
+ currentHoverId.value = hoverKey;
115
+
116
+ let componentInfo = undefined;
117
+ let modelName = undefined;
118
+
119
+ const modelRecord = await database.data.get(response.id);
120
+ if (modelRecord) {
121
+ modelName = modelRecord.name;
122
+ }
123
+
124
+ if (response.geode_id) {
125
+ const components = database.model_components.where("[id+geode_id]");
126
+ const query = components.equals([response.id, response.geode_id]);
127
+ const component = await query.first();
128
+ if (component) {
129
+ componentInfo = {
130
+ name: component.name,
131
+ id: component.geode_id,
132
+ type: component.type,
133
+ };
134
+ }
135
+ }
136
+
137
+ const newHoverData = {
138
+ modelId: response.id,
139
+ modelName,
140
+ blockName: response.geode_id,
141
+ pickedId: response.picked_id,
142
+ fieldType: response.field_type,
143
+ component: componentInfo,
144
+ attributes: response.attributes || {},
145
+ };
146
+
147
+ hoverTimeoutRef.value = setTimeout(() => {
148
+ hoverPosition.value = relativeMousePosition;
149
+ hoverData.value = newHoverData;
150
+ hoverTimeoutRef.value = undefined;
151
+ }, HOVER_TIMEOUT_MS);
152
+ });
153
+ }, HOVER_DEBOUNCE_MS);
154
+ }
155
+
156
+ export {
157
+ createClearHoverData,
158
+ createHoverHighlight,
159
+ performClearHoverHighlight,
160
+ performHoverHighlight,
161
+ useHybridViewerHighlight,
162
+ };
@@ -0,0 +1,141 @@
1
+ import { ACTOR_COLOR } from "./constants";
2
+ import { useDataStore } from "@ogw_front/stores/data";
3
+ import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
4
+ import { useViewerStore } from "@ogw_front/stores/viewer";
5
+ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
6
+ import { newInstance as vtkActor } from "@kitware/vtk.js/Rendering/Core/Actor";
7
+ import { newInstance as vtkMapper } from "@kitware/vtk.js/Rendering/Core/Mapper";
8
+ import { newInstance as vtkXMLPolyDataReader } from "@kitware/vtk.js/IO/XML/XMLPolyDataReader";
9
+
10
+ function useHybridViewerScene() {
11
+ const hybridDb = reactive({});
12
+ const zScale = ref(1);
13
+
14
+ async function addItem(id) {
15
+ await performAddItem(id);
16
+ }
17
+
18
+ function removeItem(id) {
19
+ performRemoveItem(id);
20
+ }
21
+
22
+ function setVisibility(id, visibility) {
23
+ performSetVisibility(id, visibility);
24
+ }
25
+
26
+ async function setZScaling(z_scale) {
27
+ await performSetZScaling(z_scale);
28
+ }
29
+
30
+ function clear() {
31
+ performClear();
32
+ }
33
+
34
+ return {
35
+ hybridDb,
36
+ zScale,
37
+ addItem,
38
+ removeItem,
39
+ setVisibility,
40
+ setZScaling,
41
+ clear,
42
+ };
43
+ }
44
+
45
+ async function performAddItem(id) {
46
+ const { genericRenderWindow, hybridDb } = useHybridViewerStore();
47
+ if (!genericRenderWindow.value) {
48
+ return;
49
+ }
50
+ const dataStore = useDataStore();
51
+ const value = await dataStore.item(id);
52
+ if (value && !dataStore.isItemViewable(value)) {
53
+ return;
54
+ }
55
+
56
+ const reader = vtkXMLPolyDataReader();
57
+ await reader.parseAsArrayBuffer(new TextEncoder().encode(value.binary_light_viewable));
58
+ const actor = vtkActor();
59
+ const mapper = vtkMapper();
60
+ const polydata = reader.getOutputData(0);
61
+ mapper.setInputData(polydata);
62
+ const property = actor.getProperty();
63
+ property.setColor(ACTOR_COLOR);
64
+ actor.setMapper(mapper);
65
+ const renderer = genericRenderWindow.value.getRenderer();
66
+ if (hybridDb[id] && hybridDb[id].actor) {
67
+ renderer.removeActor(hybridDb[id].actor);
68
+ }
69
+ const actors = renderer.getActors();
70
+ const isFirst = actors.length === 0;
71
+ renderer.addActor(actor);
72
+ if (isFirst) {
73
+ renderer.resetCamera();
74
+ }
75
+ hybridDb[id] = { actor, polydata, mapper };
76
+ }
77
+
78
+ function performRemoveItem(id) {
79
+ const { genericRenderWindow, hybridDb } = useHybridViewerStore();
80
+ if (!hybridDb[id]) {
81
+ return;
82
+ }
83
+ const renderer = genericRenderWindow.value.getRenderer();
84
+ renderer.removeActor(hybridDb[id].actor);
85
+ const renderWindow = genericRenderWindow.value.getRenderWindow();
86
+ renderWindow.render();
87
+ delete hybridDb[id];
88
+ }
89
+
90
+ function performSetVisibility(id, visibility) {
91
+ const { genericRenderWindow, hybridDb } = useHybridViewerStore();
92
+ if (!hybridDb[id]) {
93
+ return;
94
+ }
95
+ hybridDb[id].actor.setVisibility(visibility);
96
+ const renderWindow = genericRenderWindow.value.getRenderWindow();
97
+ renderWindow.render();
98
+ }
99
+
100
+ async function performSetZScaling(z_scale) {
101
+ const hybridViewerStore = useHybridViewerStore();
102
+ const { genericRenderWindow, remoteRender } = hybridViewerStore;
103
+ const { zScale } = storeToRefs(hybridViewerStore);
104
+ zScale.value = z_scale;
105
+
106
+ const renderer = genericRenderWindow.value.getRenderer();
107
+ for (const actor of renderer.getActors()) {
108
+ const scale = actor.getScale();
109
+ actor.setScale(scale[0], scale[1], z_scale);
110
+ }
111
+ renderer.resetCamera();
112
+ const renderWindow = genericRenderWindow.value.getRenderWindow();
113
+ renderWindow.render();
114
+ const viewerStore = useViewerStore();
115
+ const schema = viewer_schemas.opengeodeweb_viewer.viewer.set_z_scaling;
116
+ const params = { z_scale };
117
+ await viewerStore.request({ schema, params });
118
+ await remoteRender();
119
+ }
120
+
121
+ function performClear() {
122
+ const { genericRenderWindow, hybridDb } = useHybridViewerStore();
123
+ const renderer = genericRenderWindow.value.getRenderer();
124
+ for (const actor of renderer.getActors()) {
125
+ renderer.removeActor(actor);
126
+ }
127
+ const renderWindow = genericRenderWindow.value.getRenderWindow();
128
+ renderWindow.render();
129
+ for (const id of Object.keys(hybridDb)) {
130
+ delete hybridDb[id];
131
+ }
132
+ }
133
+
134
+ export {
135
+ performAddItem,
136
+ performClear,
137
+ performRemoveItem,
138
+ performSetVisibility,
139
+ performSetZScaling,
140
+ useHybridViewerScene,
141
+ };
@@ -0,0 +1,148 @@
1
+ import { Status } from "@ogw_front/utils/status";
2
+ import { WHEEL_TIME_OUT_MS } from "./constants";
3
+ import { centerCameraOnPosition } from "./camera";
4
+ import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
5
+ import { useViewerStore } from "@ogw_front/stores/viewer";
6
+ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
7
+
8
+ function useHybridViewerViewport() {
9
+ const viewStream = ref(undefined);
10
+
11
+ function setContainer(container) {
12
+ performSetContainer(container);
13
+ }
14
+
15
+ async function resize(width, height) {
16
+ await performResize(width, height);
17
+ }
18
+
19
+ return {
20
+ setContainer,
21
+ resize,
22
+ viewStream,
23
+ };
24
+ }
25
+
26
+ function performClickPicking(event, containerElement) {
27
+ const { genericRenderWindow, syncRemoteCamera } = useHybridViewerStore();
28
+ const viewerStore = useViewerStore();
29
+ const rect = containerElement.getBoundingClientRect();
30
+ const schema = viewer_schemas.opengeodeweb_viewer.viewer.get_point_position;
31
+ const params = {
32
+ x: Math.round(event.clientX - rect.left),
33
+ y: Math.round(rect.height - (event.clientY - rect.top)),
34
+ };
35
+ viewerStore.request(
36
+ {
37
+ schema,
38
+ params,
39
+ },
40
+ {
41
+ response_function: ({ x, y, z }) => {
42
+ const pickedPos = [x, y, z];
43
+ if (pickedPos.some((val) => val !== 0)) {
44
+ const renderer = genericRenderWindow.value.getRenderer();
45
+ const camera = renderer.getActiveCamera();
46
+ centerCameraOnPosition(camera, pickedPos);
47
+ const renderWindow = genericRenderWindow.value.getRenderWindow();
48
+ renderWindow.render();
49
+ syncRemoteCamera();
50
+ }
51
+ },
52
+ },
53
+ );
54
+ }
55
+
56
+ function performSetContainer(container) {
57
+ if (!container || !container.value) {
58
+ return;
59
+ }
60
+
61
+ const hybridViewerStore = useHybridViewerStore();
62
+ const { genericRenderWindow, syncRemoteCamera, hoverHighlight } = hybridViewerStore;
63
+ const { is_picking, is_moving } = storeToRefs(hybridViewerStore);
64
+
65
+ genericRenderWindow.value.setContainer(container.value.$el);
66
+ const webGLRenderWindow = genericRenderWindow.value.getApiSpecificRenderWindow();
67
+ webGLRenderWindow.setUseBackgroundImage(true);
68
+ const imageStyle = webGLRenderWindow.getReferenceByName("bgImage").style;
69
+ Object.assign(imageStyle, { transition: "opacity 0.1s ease-in", zIndex: 1 });
70
+
71
+ performResize(container.value.$el.offsetWidth, container.value.$el.offsetHeight);
72
+
73
+ let has_dragged = false;
74
+ useMousePressed({
75
+ target: container,
76
+ onPressed: (event) => {
77
+ if (event.button !== 0 && event.button !== 1) {
78
+ return;
79
+ }
80
+ if (event.button === 0 && is_picking.value) {
81
+ performClickPicking(event, container.value.$el);
82
+ is_picking.value = false;
83
+ return;
84
+ }
85
+ is_moving.value = true;
86
+ has_dragged = false;
87
+ event.stopPropagation();
88
+ },
89
+ onReleased: () => {
90
+ is_moving.value = false;
91
+ if (has_dragged) {
92
+ const renderer = genericRenderWindow.value.getRenderer();
93
+ renderer.resetCameraClippingRange();
94
+ syncRemoteCamera();
95
+ }
96
+ has_dragged = false;
97
+ },
98
+ });
99
+
100
+ useEventListener(container, "mousemove", (event) => {
101
+ if (is_moving.value) {
102
+ has_dragged = true;
103
+ if (imageStyle) {
104
+ imageStyle.opacity = 0;
105
+ }
106
+ }
107
+ hoverHighlight(event);
108
+ });
109
+
110
+ let wheelEventEndTimeout = undefined;
111
+ useEventListener(container, "wheel", () => {
112
+ is_moving.value = true;
113
+ if (imageStyle) {
114
+ imageStyle.opacity = 0;
115
+ }
116
+ clearTimeout(wheelEventEndTimeout);
117
+ wheelEventEndTimeout = setTimeout(() => {
118
+ is_moving.value = false;
119
+ const renderer = genericRenderWindow.value.getRenderer();
120
+ renderer.resetCameraClippingRange();
121
+ syncRemoteCamera();
122
+ }, WHEEL_TIME_OUT_MS);
123
+ });
124
+ }
125
+
126
+ async function performResize(width, height) {
127
+ const hybridViewerStore = useHybridViewerStore();
128
+ const { genericRenderWindow, remoteRender } = hybridViewerStore;
129
+ const { status, viewStream } = storeToRefs(hybridViewerStore);
130
+ const viewerStore = useViewerStore();
131
+ if (viewerStore.status !== Status.CONNECTED || status.value !== Status.CREATED) {
132
+ return;
133
+ }
134
+ const webGLRenderWindow = genericRenderWindow.value.getApiSpecificRenderWindow();
135
+ const canvas = webGLRenderWindow.getCanvas();
136
+ canvas.width = width;
137
+ canvas.height = height;
138
+ await nextTick();
139
+ webGLRenderWindow.setSize(width, height);
140
+ if (viewStream.value) {
141
+ viewStream.value.setSize(width, height);
142
+ }
143
+ const renderWindow = genericRenderWindow.value.getRenderWindow();
144
+ renderWindow.render();
145
+ await remoteRender();
146
+ }
147
+
148
+ export { performClickPicking, performResize, performSetContainer, useHybridViewerViewport };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geode/opengeodeweb-front",
3
- "version": "10.31.0",
3
+ "version": "10.31.1-rc.1",
4
4
  "description": "OpenSource Vue/Nuxt/Pinia/Vuetify framework for web applications",
5
5
  "homepage": "https://github.com/Geode-solutions/OpenGeodeWeb-Front",
6
6
  "bugs": {
@@ -39,8 +39,8 @@
39
39
  "build": ""
40
40
  },
41
41
  "dependencies": {
42
- "@geode/opengeodeweb-back": "latest",
43
- "@geode/opengeodeweb-viewer": "latest",
42
+ "@geode/opengeodeweb-back": "next",
43
+ "@geode/opengeodeweb-viewer": "next",
44
44
  "@google-cloud/run": "3.2.0",
45
45
  "@kitware/vtk.js": "33.3.0",
46
46
  "@mdi/font": "7.4.47",