@geode/opengeodeweb-front 10.38.0-rc.4 → 10.38.0
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,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import FactorFilterPanel from "@ogw_front/components/FactorFilterPanel.vue";
|
|
3
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
4
|
+
|
|
5
|
+
const DEFAULT_EXPLODE_VALUE = 0.2;
|
|
6
|
+
const MIN_EXPLODE_VALUE = 0;
|
|
7
|
+
const MAX_EXPLODE_VALUE = 1;
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
escapeFunction?: () => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { escapeFunction = undefined } = defineProps<Props>();
|
|
14
|
+
|
|
15
|
+
const show = defineModel<boolean>("show", { default: false });
|
|
16
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<FactorFilterPanel
|
|
21
|
+
v-model:show="show"
|
|
22
|
+
title="Exploded View"
|
|
23
|
+
label="Explode Factor"
|
|
24
|
+
test-id-prefix="explode"
|
|
25
|
+
:set-factor="hybridViewerStore.setExplode"
|
|
26
|
+
:factor-range="{
|
|
27
|
+
min: MIN_EXPLODE_VALUE,
|
|
28
|
+
max: MAX_EXPLODE_VALUE,
|
|
29
|
+
defaultValue: DEFAULT_EXPLODE_VALUE,
|
|
30
|
+
neutralValue: MIN_EXPLODE_VALUE,
|
|
31
|
+
}"
|
|
32
|
+
:escapeFunction="escapeFunction"
|
|
33
|
+
/>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import ToolPanel from "@ogw_front/components/ToolPanel.vue";
|
|
3
|
+
import { useDataStore } from "@ogw_front/stores/data";
|
|
4
|
+
import { useDebounceFn } from "@vueuse/core";
|
|
5
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
6
|
+
|
|
7
|
+
const DEBOUNCE_DELAY = 100;
|
|
8
|
+
|
|
9
|
+
interface FactorRange {
|
|
10
|
+
min: number;
|
|
11
|
+
max: number;
|
|
12
|
+
defaultValue: number;
|
|
13
|
+
neutralValue: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
title: string;
|
|
18
|
+
label: string;
|
|
19
|
+
testIdPrefix: string;
|
|
20
|
+
setFactor: (ids: string[], factor: number) => Promise<void>;
|
|
21
|
+
factorRange: FactorRange;
|
|
22
|
+
formatValue?: (value: number) => string;
|
|
23
|
+
escapeFunction?: () => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
title,
|
|
28
|
+
label,
|
|
29
|
+
testIdPrefix,
|
|
30
|
+
setFactor,
|
|
31
|
+
factorRange,
|
|
32
|
+
formatValue = (value: number): string => value.toFixed(2),
|
|
33
|
+
escapeFunction = undefined,
|
|
34
|
+
} = defineProps<Props>();
|
|
35
|
+
|
|
36
|
+
const capitalizedPrefix = computed<string>(
|
|
37
|
+
() => `${testIdPrefix.charAt(0).toUpperCase()}${testIdPrefix.slice(1)}`,
|
|
38
|
+
);
|
|
39
|
+
const show = defineModel<boolean>("show", { default: false });
|
|
40
|
+
const dataStore = useDataStore();
|
|
41
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
42
|
+
const targetAllVisible = ref<boolean>(true);
|
|
43
|
+
const selectedDatasetIds = ref<string[]>([]);
|
|
44
|
+
const factor = ref<number>(factorRange.defaultValue);
|
|
45
|
+
|
|
46
|
+
const allItems = dataStore.refAllItems();
|
|
47
|
+
const availableDatasets = computed<{ title: string; value: string }[]>(() =>
|
|
48
|
+
allItems.value.map((item) => ({
|
|
49
|
+
title: item.name || item.id,
|
|
50
|
+
value: item.id,
|
|
51
|
+
})),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
let appliedFactor: number | undefined = undefined;
|
|
55
|
+
|
|
56
|
+
async function applyFactor(): Promise<void> {
|
|
57
|
+
appliedFactor = factor.value;
|
|
58
|
+
const allIds = allItems.value.map((item) => item.id);
|
|
59
|
+
if (allIds.length === 0) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const targetIds = targetAllVisible.value ? allIds : selectedDatasetIds.value;
|
|
63
|
+
const untargetedIds = allIds.filter((id) => !targetIds.includes(id));
|
|
64
|
+
|
|
65
|
+
if (targetIds.length > 0) {
|
|
66
|
+
await setFactor(targetIds, Number(factor.value));
|
|
67
|
+
}
|
|
68
|
+
if (untargetedIds.length > 0) {
|
|
69
|
+
await setFactor(untargetedIds, factorRange.neutralValue);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const debouncedApply = useDebounceFn(() => applyFactor(), DEBOUNCE_DELAY);
|
|
74
|
+
|
|
75
|
+
async function resetFactor(): Promise<void> {
|
|
76
|
+
factor.value = factorRange.defaultValue;
|
|
77
|
+
await applyFactor();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function removeFactor(): Promise<void> {
|
|
81
|
+
factor.value = factorRange.neutralValue;
|
|
82
|
+
await applyFactor();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
watch(factor, (value) => {
|
|
86
|
+
if (value !== appliedFactor) {
|
|
87
|
+
debouncedApply();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
watch(show, (visible) => {
|
|
92
|
+
if (visible) {
|
|
93
|
+
applyFactor();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
watch(
|
|
98
|
+
[targetAllVisible, selectedDatasetIds],
|
|
99
|
+
() => {
|
|
100
|
+
if (show.value) {
|
|
101
|
+
applyFactor();
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{ deep: true },
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
watch(allItems, () => {
|
|
108
|
+
if (show.value) {
|
|
109
|
+
applyFactor();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
watch(
|
|
114
|
+
() => Object.values(hybridViewerStore.hybridDb).filter((entry) => entry && entry.actor).length,
|
|
115
|
+
(actorCount) => {
|
|
116
|
+
if (show.value && actorCount > 0) {
|
|
117
|
+
applyFactor();
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
</script>
|
|
122
|
+
|
|
123
|
+
<template>
|
|
124
|
+
<ToolPanel
|
|
125
|
+
v-model="show"
|
|
126
|
+
:title="title"
|
|
127
|
+
:width="340"
|
|
128
|
+
:click-outside="false"
|
|
129
|
+
:escapeFunction="escapeFunction"
|
|
130
|
+
>
|
|
131
|
+
<v-card-text class="pa-3 max-panel-height overflow-y-auto overflow-x-hidden">
|
|
132
|
+
<v-switch
|
|
133
|
+
v-model="targetAllVisible"
|
|
134
|
+
:data-testid="`${testIdPrefix}TargetAllVisibleSwitch`"
|
|
135
|
+
label="Apply to all visible datasets"
|
|
136
|
+
color="primary"
|
|
137
|
+
density="compact"
|
|
138
|
+
hide-details
|
|
139
|
+
class="mb-2 text-caption"
|
|
140
|
+
/>
|
|
141
|
+
|
|
142
|
+
<v-select
|
|
143
|
+
v-if="!targetAllVisible"
|
|
144
|
+
v-model="selectedDatasetIds"
|
|
145
|
+
:data-testid="`${testIdPrefix}SelectedDatasetsSelect`"
|
|
146
|
+
:items="availableDatasets"
|
|
147
|
+
label="Select datasets"
|
|
148
|
+
multiple
|
|
149
|
+
chips
|
|
150
|
+
closable-chips
|
|
151
|
+
variant="outlined"
|
|
152
|
+
density="compact"
|
|
153
|
+
hide-details
|
|
154
|
+
class="mb-3 text-caption"
|
|
155
|
+
/>
|
|
156
|
+
|
|
157
|
+
<v-divider class="my-3" />
|
|
158
|
+
|
|
159
|
+
<div class="d-flex align-center justify-space-between mb-1">
|
|
160
|
+
<span class="text-caption font-weight-bold">{{ label }}</span>
|
|
161
|
+
<span class="text-caption text-primary font-weight-bold">
|
|
162
|
+
{{ formatValue(factor) }}
|
|
163
|
+
</span>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<v-slider
|
|
167
|
+
v-model="factor"
|
|
168
|
+
:data-testid="`${testIdPrefix}FactorSlider`"
|
|
169
|
+
:min="factorRange.min"
|
|
170
|
+
:max="factorRange.max"
|
|
171
|
+
step="0.01"
|
|
172
|
+
color="primary"
|
|
173
|
+
track-color="grey-lighten-2"
|
|
174
|
+
density="compact"
|
|
175
|
+
hide-details
|
|
176
|
+
class="my-2 px-1"
|
|
177
|
+
/>
|
|
178
|
+
</v-card-text>
|
|
179
|
+
|
|
180
|
+
<template #actions>
|
|
181
|
+
<v-card-actions class="justify-space-between px-3 pb-3 pt-0">
|
|
182
|
+
<v-btn
|
|
183
|
+
:data-testid="`remove${capitalizedPrefix}Button`"
|
|
184
|
+
variant="text"
|
|
185
|
+
size="small"
|
|
186
|
+
color="error"
|
|
187
|
+
class="text-caption text-none"
|
|
188
|
+
@click="removeFactor"
|
|
189
|
+
>
|
|
190
|
+
Remove {{ capitalizedPrefix }}
|
|
191
|
+
</v-btn>
|
|
192
|
+
<v-btn
|
|
193
|
+
:data-testid="`reset${capitalizedPrefix}Button`"
|
|
194
|
+
variant="tonal"
|
|
195
|
+
size="small"
|
|
196
|
+
color="secondary"
|
|
197
|
+
class="text-caption text-none"
|
|
198
|
+
@click="resetFactor"
|
|
199
|
+
>
|
|
200
|
+
Reset
|
|
201
|
+
</v-btn>
|
|
202
|
+
</v-card-actions>
|
|
203
|
+
</template>
|
|
204
|
+
</ToolPanel>
|
|
205
|
+
</template>
|
|
206
|
+
|
|
207
|
+
<style scoped>
|
|
208
|
+
.max-panel-height {
|
|
209
|
+
max-height: 520px;
|
|
210
|
+
}
|
|
211
|
+
</style>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
3
|
-
import { useDataStore } from "@ogw_front/stores/data";
|
|
4
|
-
import { useDebounceFn } from "@vueuse/core";
|
|
2
|
+
import FactorFilterPanel from "@ogw_front/components/FactorFilterPanel.vue";
|
|
5
3
|
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
6
4
|
|
|
7
5
|
const DEFAULT_SHRINK_VALUE = 0.8;
|
|
6
|
+
const MIN_SHRINK_VALUE = 0;
|
|
8
7
|
const MAX_SHRINK_VALUE = 1;
|
|
9
|
-
const
|
|
8
|
+
const PERCENT = 100;
|
|
10
9
|
|
|
11
10
|
interface Props {
|
|
12
11
|
escapeFunction?: () => void;
|
|
@@ -15,173 +14,27 @@ interface Props {
|
|
|
15
14
|
const { escapeFunction = undefined } = defineProps<Props>();
|
|
16
15
|
|
|
17
16
|
const show = defineModel<boolean>("show", { default: false });
|
|
18
|
-
const dataStore = useDataStore();
|
|
19
17
|
const hybridViewerStore = useHybridViewerStore();
|
|
20
|
-
const targetAllVisible = ref<boolean>(true);
|
|
21
|
-
const selectedDatasetIds = ref<string[]>([]);
|
|
22
|
-
const shrinkFactor = ref<number>(DEFAULT_SHRINK_VALUE);
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
allItems.value.map((item) => ({
|
|
27
|
-
title: item.name || item.id,
|
|
28
|
-
value: item.id,
|
|
29
|
-
})),
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
async function applyShrink(): Promise<void> {
|
|
33
|
-
const allIds = allItems.value.map((item) => item.id);
|
|
34
|
-
if (allIds.length === 0) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const targetIds = targetAllVisible.value ? allIds : selectedDatasetIds.value;
|
|
38
|
-
const untargetedIds = allIds.filter((id) => !targetIds.includes(id));
|
|
39
|
-
|
|
40
|
-
if (targetIds.length > 0) {
|
|
41
|
-
await hybridViewerStore.setShrink(targetIds, Number(shrinkFactor.value));
|
|
42
|
-
}
|
|
43
|
-
if (untargetedIds.length > 0) {
|
|
44
|
-
await hybridViewerStore.setShrink(untargetedIds, MAX_SHRINK_VALUE);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const debouncedApply = useDebounceFn(() => applyShrink(), DEBOUNCE_DELAY);
|
|
49
|
-
|
|
50
|
-
async function resetShrink(): Promise<void> {
|
|
51
|
-
shrinkFactor.value = DEFAULT_SHRINK_VALUE;
|
|
52
|
-
await applyShrink();
|
|
19
|
+
function formatShrinkFactor(value: number): string {
|
|
20
|
+
return `${(value * PERCENT).toFixed(0)}% (${value.toFixed(2)})`;
|
|
53
21
|
}
|
|
54
|
-
|
|
55
|
-
async function removeShrink(): Promise<void> {
|
|
56
|
-
shrinkFactor.value = MAX_SHRINK_VALUE;
|
|
57
|
-
const allIds = allItems.value.map((item) => item.id);
|
|
58
|
-
if (allIds.length > 0) {
|
|
59
|
-
await hybridViewerStore.setShrink(allIds, MAX_SHRINK_VALUE);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
watch(shrinkFactor, () => {
|
|
64
|
-
debouncedApply();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
watch(show, (visible) => {
|
|
68
|
-
if (visible) {
|
|
69
|
-
applyShrink();
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
watch(
|
|
74
|
-
[targetAllVisible, selectedDatasetIds],
|
|
75
|
-
() => {
|
|
76
|
-
if (show.value) {
|
|
77
|
-
applyShrink();
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
{ deep: true },
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
watch(allItems, () => {
|
|
84
|
-
if (show.value) {
|
|
85
|
-
applyShrink();
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
watch(
|
|
90
|
-
() => Object.values(hybridViewerStore.hybridDb).filter((entry) => entry && entry.actor).length,
|
|
91
|
-
(actorCount) => {
|
|
92
|
-
if (show.value && actorCount > 0) {
|
|
93
|
-
applyShrink();
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
);
|
|
97
22
|
</script>
|
|
98
23
|
|
|
99
24
|
<template>
|
|
100
|
-
<
|
|
101
|
-
v-model="show"
|
|
25
|
+
<FactorFilterPanel
|
|
26
|
+
v-model:show="show"
|
|
102
27
|
title="Shrink Filter"
|
|
103
|
-
|
|
104
|
-
|
|
28
|
+
label="Shrink Factor"
|
|
29
|
+
test-id-prefix="shrink"
|
|
30
|
+
:set-factor="hybridViewerStore.setShrink"
|
|
31
|
+
:factor-range="{
|
|
32
|
+
min: MIN_SHRINK_VALUE,
|
|
33
|
+
max: MAX_SHRINK_VALUE,
|
|
34
|
+
defaultValue: DEFAULT_SHRINK_VALUE,
|
|
35
|
+
neutralValue: MAX_SHRINK_VALUE,
|
|
36
|
+
}"
|
|
37
|
+
:format-value="formatShrinkFactor"
|
|
105
38
|
:escapeFunction="escapeFunction"
|
|
106
|
-
|
|
107
|
-
<v-card-text class="pa-3 max-panel-height overflow-y-auto overflow-x-hidden">
|
|
108
|
-
<v-switch
|
|
109
|
-
v-model="targetAllVisible"
|
|
110
|
-
data-testid="shrinkTargetAllVisibleSwitch"
|
|
111
|
-
label="Apply to all visible datasets"
|
|
112
|
-
color="primary"
|
|
113
|
-
density="compact"
|
|
114
|
-
hide-details
|
|
115
|
-
class="mb-2 text-caption"
|
|
116
|
-
/>
|
|
117
|
-
|
|
118
|
-
<v-select
|
|
119
|
-
v-if="!targetAllVisible"
|
|
120
|
-
v-model="selectedDatasetIds"
|
|
121
|
-
data-testid="shrinkSelectedDatasetsSelect"
|
|
122
|
-
:items="availableDatasets"
|
|
123
|
-
label="Select datasets"
|
|
124
|
-
multiple
|
|
125
|
-
chips
|
|
126
|
-
closable-chips
|
|
127
|
-
variant="outlined"
|
|
128
|
-
density="compact"
|
|
129
|
-
hide-details
|
|
130
|
-
class="mb-3 text-caption"
|
|
131
|
-
/>
|
|
132
|
-
|
|
133
|
-
<v-divider class="my-3" />
|
|
134
|
-
|
|
135
|
-
<div class="d-flex align-center justify-space-between mb-1">
|
|
136
|
-
<span class="text-caption font-weight-bold">Shrink Factor</span>
|
|
137
|
-
<span class="text-caption text-primary font-weight-bold">
|
|
138
|
-
{{ (shrinkFactor * 100).toFixed(0) }}% ({{ shrinkFactor.toFixed(2) }})
|
|
139
|
-
</span>
|
|
140
|
-
</div>
|
|
141
|
-
|
|
142
|
-
<v-slider
|
|
143
|
-
v-model="shrinkFactor"
|
|
144
|
-
data-testid="shrinkFactorSlider"
|
|
145
|
-
min="0.0"
|
|
146
|
-
max="1.0"
|
|
147
|
-
step="0.01"
|
|
148
|
-
color="primary"
|
|
149
|
-
track-color="grey-lighten-2"
|
|
150
|
-
density="compact"
|
|
151
|
-
hide-details
|
|
152
|
-
class="my-2 px-1"
|
|
153
|
-
/>
|
|
154
|
-
</v-card-text>
|
|
155
|
-
|
|
156
|
-
<template #actions>
|
|
157
|
-
<v-card-actions class="justify-space-between px-3 pb-3 pt-0">
|
|
158
|
-
<v-btn
|
|
159
|
-
data-testid="removeShrinkButton"
|
|
160
|
-
variant="text"
|
|
161
|
-
size="small"
|
|
162
|
-
color="error"
|
|
163
|
-
class="text-caption text-none"
|
|
164
|
-
@click="removeShrink"
|
|
165
|
-
>
|
|
166
|
-
Remove Shrink
|
|
167
|
-
</v-btn>
|
|
168
|
-
<v-btn
|
|
169
|
-
data-testid="resetShrinkButton"
|
|
170
|
-
variant="tonal"
|
|
171
|
-
size="small"
|
|
172
|
-
color="secondary"
|
|
173
|
-
class="text-caption text-none"
|
|
174
|
-
@click="resetShrink"
|
|
175
|
-
>
|
|
176
|
-
Reset
|
|
177
|
-
</v-btn>
|
|
178
|
-
</v-card-actions>
|
|
179
|
-
</template>
|
|
180
|
-
</ToolPanel>
|
|
39
|
+
/>
|
|
181
40
|
</template>
|
|
182
|
-
|
|
183
|
-
<style scoped>
|
|
184
|
-
.max-panel-height {
|
|
185
|
-
max-height: 520px;
|
|
186
|
-
}
|
|
187
|
-
</style>
|
|
@@ -7,6 +7,7 @@ import CameraBookmarkIcon from "@ogw_front/assets/viewer_svgs/camera-bookmark.sv
|
|
|
7
7
|
import CameraManager from "@ogw_front/components/CameraManager.vue";
|
|
8
8
|
import CameraOrientation from "@ogw_front/components/CameraOrientation.vue";
|
|
9
9
|
import ClippingPlanes from "@ogw_front/components/ClippingPlanes.vue";
|
|
10
|
+
import ExplodeFilter from "@ogw_front/components/ExplodeFilter.vue";
|
|
10
11
|
import Ruler from "@ogw_front/components/Ruler.vue";
|
|
11
12
|
import Screenshot from "@ogw_front/components/Screenshot.vue";
|
|
12
13
|
import ShrinkFilter from "@ogw_front/components/ShrinkFilter.vue";
|
|
@@ -26,6 +27,7 @@ const showCameraOrientation = ref<boolean>(false);
|
|
|
26
27
|
const showZScaling = ref<boolean>(false);
|
|
27
28
|
const showClippingPlanes = ref<boolean>(false);
|
|
28
29
|
const showShrinkFilter = ref<boolean>(false);
|
|
30
|
+
const showExplodeFilter = ref<boolean>(false);
|
|
29
31
|
const showThresholdFilter = ref<boolean>(false);
|
|
30
32
|
const showRuler = ref<boolean>(false);
|
|
31
33
|
const gridScale = ref<boolean>(false);
|
|
@@ -77,6 +79,7 @@ function closeAllToolsExcept(toolRef: Ref<boolean>): void {
|
|
|
77
79
|
showZScaling,
|
|
78
80
|
showClippingPlanes,
|
|
79
81
|
showShrinkFilter,
|
|
82
|
+
showExplodeFilter,
|
|
80
83
|
showThresholdFilter,
|
|
81
84
|
showRuler,
|
|
82
85
|
is_picking,
|
|
@@ -236,6 +239,15 @@ const camera_options = computed<CameraOptionAction[]>(() => [
|
|
|
236
239
|
toggleTool(showShrinkFilter);
|
|
237
240
|
},
|
|
238
241
|
},
|
|
242
|
+
{
|
|
243
|
+
testId: "explodeFilterButton",
|
|
244
|
+
tooltip: "Exploded View",
|
|
245
|
+
icon: "mdi-arrow-expand-all",
|
|
246
|
+
color: showExplodeFilter.value ? "primary" : undefined,
|
|
247
|
+
action: (): void => {
|
|
248
|
+
toggleTool(showExplodeFilter);
|
|
249
|
+
},
|
|
250
|
+
},
|
|
239
251
|
{
|
|
240
252
|
testId: "thresholdFilterButton",
|
|
241
253
|
tooltip: "Threshold Filter",
|
|
@@ -334,6 +346,10 @@ const camera_options = computed<CameraOptionAction[]>(() => [
|
|
|
334
346
|
v-model:show="showShrinkFilter"
|
|
335
347
|
:escapeFunction="() => (showShrinkFilter = false)"
|
|
336
348
|
/>
|
|
349
|
+
<ExplodeFilter
|
|
350
|
+
v-model:show="showExplodeFilter"
|
|
351
|
+
:escapeFunction="() => (showExplodeFilter = false)"
|
|
352
|
+
/>
|
|
337
353
|
<ThresholdFilter
|
|
338
354
|
v-model:show="showThresholdFilter"
|
|
339
355
|
:escapeFunction="() => (showThresholdFilter = false)"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { JsonRpcSchema, ParamsOf, ResponseOf } from "@ogw_shared/utils/types.js";
|
|
1
2
|
import viewer_schemas, {
|
|
2
3
|
type ViewerClippingPlanesParams,
|
|
3
4
|
} from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
@@ -5,55 +6,51 @@ import type { SliceAxis } from "@ogw_front/utils/slice";
|
|
|
5
6
|
import { useHybridViewerCore } from "./core";
|
|
6
7
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
7
8
|
|
|
9
|
+
async function requestAndRender<Schema extends JsonRpcSchema>(
|
|
10
|
+
schema: Schema,
|
|
11
|
+
params: ParamsOf<Schema>,
|
|
12
|
+
): Promise<ResponseOf<Schema>> {
|
|
13
|
+
const viewerStore = useViewerStore();
|
|
14
|
+
const { remoteRender } = useHybridViewerCore();
|
|
15
|
+
const response = await viewerStore.request({
|
|
16
|
+
schema,
|
|
17
|
+
params,
|
|
18
|
+
});
|
|
19
|
+
await remoteRender();
|
|
20
|
+
return response;
|
|
21
|
+
}
|
|
22
|
+
|
|
8
23
|
async function setClippingPlanes(
|
|
9
24
|
ids: string[],
|
|
10
25
|
planes: ViewerClippingPlanesParams["planes"],
|
|
11
26
|
): Promise<void> {
|
|
12
|
-
|
|
13
|
-
const { remoteRender } = useHybridViewerCore();
|
|
14
|
-
const schema = viewer_schemas.opengeodeweb_viewer.viewer.clipping_planes;
|
|
15
|
-
const params = {
|
|
27
|
+
await requestAndRender(viewer_schemas.opengeodeweb_viewer.viewer.clipping_planes, {
|
|
16
28
|
ids,
|
|
17
29
|
planes,
|
|
18
|
-
};
|
|
19
|
-
await viewerStore.request({
|
|
20
|
-
schema,
|
|
21
|
-
params,
|
|
22
30
|
});
|
|
23
|
-
await remoteRender();
|
|
24
31
|
}
|
|
25
32
|
async function setShrink(ids: string[], shrink_factor: number): Promise<void> {
|
|
26
|
-
|
|
27
|
-
const { remoteRender } = useHybridViewerCore();
|
|
28
|
-
const schema = viewer_schemas.opengeodeweb_viewer.viewer.shrink;
|
|
29
|
-
const params = {
|
|
33
|
+
await requestAndRender(viewer_schemas.opengeodeweb_viewer.viewer.shrink, {
|
|
30
34
|
ids,
|
|
31
35
|
shrink_factor,
|
|
32
|
-
};
|
|
33
|
-
await viewerStore.request({
|
|
34
|
-
schema,
|
|
35
|
-
params,
|
|
36
36
|
});
|
|
37
|
-
|
|
37
|
+
}
|
|
38
|
+
async function setExplode(ids: string[], explode_factor: number): Promise<void> {
|
|
39
|
+
await requestAndRender(viewer_schemas.opengeodeweb_viewer.viewer.explode, {
|
|
40
|
+
ids,
|
|
41
|
+
explode_factor,
|
|
42
|
+
});
|
|
38
43
|
}
|
|
39
44
|
async function setSlice(
|
|
40
45
|
ids: string[],
|
|
41
46
|
slices: { axis: SliceAxis; index: number }[],
|
|
42
47
|
): Promise<[number, number, number]> {
|
|
43
|
-
const viewerStore = useViewerStore();
|
|
44
|
-
const { remoteRender } = useHybridViewerCore();
|
|
45
|
-
const schema = viewer_schemas.opengeodeweb_viewer.viewer.slice;
|
|
46
|
-
const params = {
|
|
47
|
-
ids,
|
|
48
|
-
slices,
|
|
49
|
-
};
|
|
50
48
|
const {
|
|
51
49
|
max_indices: [max_i = 0, max_j = 0, max_k = 0],
|
|
52
|
-
} = await
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
} = await requestAndRender(viewer_schemas.opengeodeweb_viewer.viewer.slice, {
|
|
51
|
+
ids,
|
|
52
|
+
slices,
|
|
55
53
|
});
|
|
56
|
-
await remoteRender();
|
|
57
54
|
return [max_i, max_j, max_k];
|
|
58
55
|
}
|
|
59
56
|
interface ThresholdAttribute {
|
|
@@ -64,22 +61,15 @@ interface ThresholdAttribute {
|
|
|
64
61
|
maximum: number;
|
|
65
62
|
}
|
|
66
63
|
async function setThreshold(ids: string[], attribute?: ThresholdAttribute): Promise<void> {
|
|
67
|
-
|
|
68
|
-
const { remoteRender } = useHybridViewerCore();
|
|
69
|
-
const schema = viewer_schemas.opengeodeweb_viewer.viewer.threshold;
|
|
70
|
-
const params = {
|
|
64
|
+
await requestAndRender(viewer_schemas.opengeodeweb_viewer.viewer.threshold, {
|
|
71
65
|
ids,
|
|
72
66
|
attribute,
|
|
73
|
-
};
|
|
74
|
-
await viewerStore.request({
|
|
75
|
-
schema,
|
|
76
|
-
params,
|
|
77
67
|
});
|
|
78
|
-
await remoteRender();
|
|
79
68
|
}
|
|
80
69
|
function useHybridViewerFilters(): {
|
|
81
70
|
setClippingPlanes: (ids: string[], planes: ViewerClippingPlanesParams["planes"]) => Promise<void>;
|
|
82
71
|
setShrink: (ids: string[], shrink_factor: number) => Promise<void>;
|
|
72
|
+
setExplode: (ids: string[], explode_factor: number) => Promise<void>;
|
|
83
73
|
setSlice: (
|
|
84
74
|
ids: string[],
|
|
85
75
|
slices: { axis: SliceAxis; index: number }[],
|
|
@@ -89,6 +79,7 @@ function useHybridViewerFilters(): {
|
|
|
89
79
|
return {
|
|
90
80
|
setClippingPlanes,
|
|
91
81
|
setShrink,
|
|
82
|
+
setExplode,
|
|
92
83
|
setSlice,
|
|
93
84
|
setThreshold,
|
|
94
85
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geode/opengeodeweb-front",
|
|
3
|
-
"version": "10.38.0
|
|
3
|
+
"version": "10.38.0",
|
|
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": {
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"prepublishOnly": "npm run build"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@geode/cloud-api": "
|
|
68
|
-
"@geode/opengeodeweb-back": "
|
|
69
|
-
"@geode/opengeodeweb-viewer": "
|
|
67
|
+
"@geode/cloud-api": "latest",
|
|
68
|
+
"@geode/opengeodeweb-back": "latest",
|
|
69
|
+
"@geode/opengeodeweb-viewer": "latest",
|
|
70
70
|
"@kitware/vtk.js": "33.3.0",
|
|
71
71
|
"@mdi/font": "7.4.47",
|
|
72
72
|
"@pinia/nuxt": "1.0.1",
|