From f8e423b0fd8058521dc8d47a945207cb7bf5203e Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 13 Jul 2026 15:33:39 +0200 Subject: [PATCH 01/22] proper all files oxlint passed --- .../Viewer/ObjectTree/Base/TreeRow.vue | 38 ++++++++- .../Viewer/ObjectTree/Views/GlobalObjects.vue | 82 ++++++++++--------- app/stores/app.js | 18 ++++ app/utils/import_workflow.js | 9 +- 4 files changed, 102 insertions(+), 45 deletions(-) diff --git a/app/components/Viewer/ObjectTree/Base/TreeRow.vue b/app/components/Viewer/ObjectTree/Base/TreeRow.vue index f9d24437c..756029ac8 100644 --- a/app/components/Viewer/ObjectTree/Base/TreeRow.vue +++ b/app/components/Viewer/ObjectTree/Base/TreeRow.vue @@ -7,13 +7,32 @@ const { item, itemProps, selection, isSelected, getIndeterminate } = defineProps getIndeterminate: { type: Function, required: true }, }); -defineEmits(["toggle-open", "toggle-select", "hover-eye-enter", "hover-eye-leave"]); +const emit = defineEmits(["toggle-open", "toggle-select", "hover-eye-enter", "hover-eye-leave"]); const INDENT_STEP = 10; + +function triggerHorizonStackModal(rawItem) { + console.log("Triggering Horizon Stack modal for item:", rawItem); + globalThis.dispatchEvent(new CustomEvent('open-horizon-stack-modal', { detail: rawItem })); +} + +function handleRowClick(event) { + if (item.raw.geode_object_type === 'HorizonStack3D') { + if (!item.isLeaf) { + // It's the category node (folder), let it propagate to CommonTreeView to toggle collapse + return; + } + + // It's the actual Horizon Stack object, prevent selection and open modal + event.stopPropagation(); + event.preventDefault(); + triggerHorizonStackModal(item.raw); + } +} diff --git a/app/stores/app.js b/app/stores/app.js index 5eb7cab3c..04edc0696 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -8,6 +8,21 @@ import { useInfraStore } from "@ogw_front/stores/infra"; // oxlint-disable-next-line max-lines-per-function, max-statements export const useAppStore = defineStore("app", () => { const stores = []; + const globalComponents = ref(new Map()); + + function registerGlobalComponent(extensionId, componentId, component) { + if (!globalComponents.value.has(extensionId)) { + globalComponents.value.set(extensionId, new Map()); + } + globalComponents.value.get(extensionId).set(componentId, component); + console.log(`[AppStore] Registered global component ${componentId} for extension ${extensionId}`); + } + + function unregisterGlobalComponent(extensionId, componentId) { + if (globalComponents.value.has(extensionId)) { + globalComponents.value.get(extensionId).delete(componentId); + } + } function registerStore(store) { const isAlreadyRegistered = stores.some((registeredStore) => registeredStore.$id === store.$id); @@ -285,5 +300,8 @@ export const useAppStore = defineStore("app", () => { createProjectFolder, start_request, stop_request, + globalComponents, + registerGlobalComponent, + unregisterGlobalComponent, }; }); diff --git a/app/utils/import_workflow.js b/app/utils/import_workflow.js index 8631091ba..c929285b6 100644 --- a/app/utils/import_workflow.js +++ b/app/utils/import_workflow.js @@ -62,13 +62,18 @@ async function importItem(item) { treeviewStore.addItem(item.geode_object_type, item.name, item.id, item.viewer_type); const addDataStyleTask = dataStyleStore.addDataStyle(item.id, item.geode_object_type); const addViewerTask = addDataTask.then(() => { - if (item.nb_vertices === 0) { + if (item.nb_vertices === 0 || item.viewable_file === "") { return; } return hybridViewerStore.addItem(item.id); }); const applyStyleTask = Promise.all([registerTask, addDataComponentsTask, addDataStyleTask]).then( - () => dataStyleStore.applyDefaultStyle(item.id), + () => { + if (item.viewable_file !== "") { + return dataStyleStore.applyDefaultStyle(item.id); + } + return undefined; + } ); await Promise.all([ registerTask, From 8b600ed32de581d6619f75e0607f616667c206ce Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:44:19 +0000 Subject: [PATCH 02/22] Apply prepare changes --- .../Viewer/ObjectTree/Base/TreeRow.vue | 18 ++++++++++++------ app/stores/app.js | 4 +++- app/utils/import_workflow.js | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/components/Viewer/ObjectTree/Base/TreeRow.vue b/app/components/Viewer/ObjectTree/Base/TreeRow.vue index 756029ac8..bc55e920f 100644 --- a/app/components/Viewer/ObjectTree/Base/TreeRow.vue +++ b/app/components/Viewer/ObjectTree/Base/TreeRow.vue @@ -13,16 +13,16 @@ const INDENT_STEP = 10; function triggerHorizonStackModal(rawItem) { console.log("Triggering Horizon Stack modal for item:", rawItem); - globalThis.dispatchEvent(new CustomEvent('open-horizon-stack-modal', { detail: rawItem })); + globalThis.dispatchEvent(new CustomEvent("open-horizon-stack-modal", { detail: rawItem })); } function handleRowClick(event) { - if (item.raw.geode_object_type === 'HorizonStack3D') { + if (item.raw.geode_object_type === "HorizonStack3D") { if (!item.isLeaf) { // It's the category node (folder), let it propagate to CommonTreeView to toggle collapse return; } - + // It's the actual Horizon Stack object, prevent selection and open modal event.stopPropagation(); event.preventDefault(); @@ -51,19 +51,25 @@ function handleRowClick(event) { { globalComponents.value.set(extensionId, new Map()); } globalComponents.value.get(extensionId).set(componentId, component); - console.log(`[AppStore] Registered global component ${componentId} for extension ${extensionId}`); + console.log( + `[AppStore] Registered global component ${componentId} for extension ${extensionId}`, + ); } function unregisterGlobalComponent(extensionId, componentId) { diff --git a/app/utils/import_workflow.js b/app/utils/import_workflow.js index c929285b6..a10b44901 100644 --- a/app/utils/import_workflow.js +++ b/app/utils/import_workflow.js @@ -73,7 +73,7 @@ async function importItem(item) { return dataStyleStore.applyDefaultStyle(item.id); } return undefined; - } + }, ); await Promise.all([ registerTask, From 8650307c765f991d84ff86fb195e8741fdb8eff0 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 13 Jul 2026 15:45:33 +0200 Subject: [PATCH 03/22] feat(HorizonStack): Add Horizon Stack to the horizon step From 3824442f34215bde2115d43ed876a5475311ef86 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 13 Jul 2026 16:04:15 +0200 Subject: [PATCH 04/22] try with more timeout value --- app/utils/local/microservices.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/utils/local/microservices.js b/app/utils/local/microservices.js index 6883f1617..56c006fec 100644 --- a/app/utils/local/microservices.js +++ b/app/utils/local/microservices.js @@ -12,7 +12,7 @@ import { microservicesMetadatasPath, projectMicroservices } from "./cleanup.js"; import { executablePath } from "./path.js"; const MILLISECONDS_PER_SECOND = 1000; -const DEFAULT_TIMEOUT_SECONDS = 30; +const DEFAULT_TIMEOUT_SECONDS = 120; async function runScript( execPath, From 2c96cbd35aa896d0dfae5867afcb6b667c645543 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Wed, 15 Jul 2026 11:36:01 +0200 Subject: [PATCH 05/22] rm comments --- app/components/Viewer/ObjectTree/Base/TreeRow.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/components/Viewer/ObjectTree/Base/TreeRow.vue b/app/components/Viewer/ObjectTree/Base/TreeRow.vue index bc55e920f..f3361075b 100644 --- a/app/components/Viewer/ObjectTree/Base/TreeRow.vue +++ b/app/components/Viewer/ObjectTree/Base/TreeRow.vue @@ -19,11 +19,9 @@ function triggerHorizonStackModal(rawItem) { function handleRowClick(event) { if (item.raw.geode_object_type === "HorizonStack3D") { if (!item.isLeaf) { - // It's the category node (folder), let it propagate to CommonTreeView to toggle collapse return; } - // It's the actual Horizon Stack object, prevent selection and open modal event.stopPropagation(); event.preventDefault(); triggerHorizonStackModal(item.raw); @@ -49,7 +47,6 @@ function handleRowClick(event) { />
- - item.raw.geode_object_type === "HorizonStack3D"); +const showEyeButton = computed(() => !isHorizonStack.value && item.raw.title !== "HorizonStack3D"); function handleRowClick(event) { - if (item.raw.geode_object_type === "HorizonStack3D") { + if (isHorizonStack.value) { if (!item.isLeaf) { return; } @@ -47,41 +49,37 @@ function handleRowClick(event) { />
- - +
From 876d2bb8b8dc8e2e3013833bff718d3f585b27a0 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Thu, 16 Jul 2026 17:16:28 +0200 Subject: [PATCH 07/22] fix somethings --- app/composables/hover_highlight.js | 7 +++++++ app/composables/use_overlapping_picker.js | 14 +++++++++++++- app/stores/data_style.js | 11 +++++++++++ internal/stores/hybrid_viewer.js | 10 ++++++++-- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app/composables/hover_highlight.js b/app/composables/hover_highlight.js index 9dfe5c8d4..6c17de5d1 100644 --- a/app/composables/hover_highlight.js +++ b/app/composables/hover_highlight.js @@ -20,6 +20,13 @@ export function useHoverhighlight() { currentId = id; currentType = type; + const { useDataStore } = await import("@ogw_front/stores/data"); + const dataStore = useDataStore(); + const value = await dataStore.item(id); + if (value?.binary_light_viewable === "not_viewable") { + return; + } + let block_ids = []; if (typeof block_ids_provider === "function") { block_ids = await block_ids_provider(); diff --git a/app/composables/use_overlapping_picker.js b/app/composables/use_overlapping_picker.js index cf72075f9..85eecb6f6 100644 --- a/app/composables/use_overlapping_picker.js +++ b/app/composables/use_overlapping_picker.js @@ -65,7 +65,19 @@ export function useOverlappingPicker() { async function get_viewer_id({ x, y, containerWidth, containerHeight, containerRect }) { const activeIds = new Set(dataItems.value.map((item) => item.id)); - const ids = Object.keys(dataStyleStore.styles).filter((styleId) => activeIds.has(styleId)); + const ids = Object.keys(dataStyleStore.styles).filter((styleId) => { + if (!activeIds.has(styleId)) { + return false; + } + if (!dataStyleStore.objectVisibility(styleId)) { + return false; + } + const item = dataItems.value.find((i) => i.id === styleId); + if (item && item.binary_light_viewable === "not_viewable") { + return false; + } + return true; + }); const result = { id: undefined, viewer_id: undefined }; let pickedResponse = undefined; diff --git a/app/stores/data_style.js b/app/stores/data_style.js index 5008f5659..3b8414913 100644 --- a/app/stores/data_style.js +++ b/app/stores/data_style.js @@ -21,6 +21,10 @@ export const useDataStyleStore = defineStore("dataStyle", () => { async function setVisibility(id, visibility) { const item = await dataStore.item(id); + if (item.binary_light_viewable === "not_viewable") { + return dataStyleState.mutateStyle(id, { visibility }); + } + const { viewer_type } = item; if (viewer_type === "mesh") { @@ -34,6 +38,10 @@ export const useDataStyleStore = defineStore("dataStyle", () => { async function applyDefaultStyle(id) { const item = await dataStore.item(id); + if (item.binary_light_viewable === "not_viewable") { + return; + } + const { viewer_type } = item; if (viewer_type === "mesh") { @@ -81,6 +89,9 @@ export const useDataStyleStore = defineStore("dataStyle", () => { const ids = Object.keys(dataStyleState.styles.value); const promises = ids.map(async (id) => { const meta = await dataStore.item(id); + if (meta.binary_light_viewable === "not_viewable") { + return; + } const viewerType = meta.viewer_type; if (viewerType === "mesh") { return meshStyleStore.applyMeshStyle(id); diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 80b5a85e0..9dcab26a1 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -148,8 +148,11 @@ async function performAddItem(id, options) { if (!genericRenderWindow) { return; } - const reader = vtkXMLPolyDataReader(), - value = await dataStore.item(id); + const value = await dataStore.item(id); + if (value.binary_light_viewable === "not_viewable") { + return; + } + const reader = vtkXMLPolyDataReader(); await reader.parseAsArrayBuffer(new TextEncoder().encode(value.binary_light_viewable)); const actor = vtkActor(), mapper = vtkMapper(), @@ -158,6 +161,9 @@ async function performAddItem(id, options) { actor.getProperty().setColor(actorColor); actor.setMapper(mapper); const renderer = genericRenderWindow.getRenderer(); + if (hybridDb[id] && hybridDb[id].actor) { + renderer.removeActor(hybridDb[id].actor); + } const isFirst = renderer.getActors().length === 0; renderer.addActor(actor); if (isFirst) { From 324ff80730ef18811fc6d64aa3179a0dc2370f21 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Fri, 24 Jul 2026 10:19:34 +0200 Subject: [PATCH 08/22] clear logs --- app/components/Viewer/ObjectTree/Base/TreeRow.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/app/components/Viewer/ObjectTree/Base/TreeRow.vue b/app/components/Viewer/ObjectTree/Base/TreeRow.vue index a412b7b2c..8424f7f3c 100644 --- a/app/components/Viewer/ObjectTree/Base/TreeRow.vue +++ b/app/components/Viewer/ObjectTree/Base/TreeRow.vue @@ -12,7 +12,6 @@ const emit = defineEmits(["toggle-open", "toggle-select", "hover-eye-enter", "ho const INDENT_STEP = 10; function triggerHorizonStackModal(rawItem) { - console.log("Triggering Horizon Stack modal for item:", rawItem); globalThis.dispatchEvent(new CustomEvent("open-horizon-stack-modal", { detail: rawItem })); } const isHorizonStack = computed(() => item.raw.geode_object_type === "HorizonStack3D"); From 12f6de21faccc5c05020425b313a8b370d11be0d Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Fri, 24 Jul 2026 10:30:09 +0200 Subject: [PATCH 09/22] clean undefined --- app/utils/import_workflow.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/utils/import_workflow.js b/app/utils/import_workflow.js index a10b44901..b77b0d00c 100644 --- a/app/utils/import_workflow.js +++ b/app/utils/import_workflow.js @@ -62,14 +62,14 @@ async function importItem(item) { treeviewStore.addItem(item.geode_object_type, item.name, item.id, item.viewer_type); const addDataStyleTask = dataStyleStore.addDataStyle(item.id, item.geode_object_type); const addViewerTask = addDataTask.then(() => { - if (item.nb_vertices === 0 || item.viewable_file === "") { + if (item.nb_vertices === 0 || !item.viewable_file) { return; } return hybridViewerStore.addItem(item.id); }); const applyStyleTask = Promise.all([registerTask, addDataComponentsTask, addDataStyleTask]).then( () => { - if (item.viewable_file !== "") { + if (item.viewable_file) { return dataStyleStore.applyDefaultStyle(item.id); } return undefined; From 561281d2b75f237d482807d939fde3f80b80dd87 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Fri, 24 Jul 2026 13:12:37 +0200 Subject: [PATCH 10/22] tigger tests From 9e43b9bd38cdc935efdc843d29efc4dc2cb650fa Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Fri, 24 Jul 2026 14:47:19 +0200 Subject: [PATCH 11/22] trigger tests From 126ba11febdfa332200ff737773fea3071d599d0 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Fri, 24 Jul 2026 17:47:57 +0200 Subject: [PATCH 12/22] fix comments front --- .../Viewer/ObjectTree/Base/TreeRow.vue | 3 ++- app/composables/hover_highlight.js | 10 +++++++--- app/stores/data.js | 1 + app/stores/data_style.js | 18 +++++++++++++++--- internal/stores/hybrid_viewer.js | 2 +- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/components/Viewer/ObjectTree/Base/TreeRow.vue b/app/components/Viewer/ObjectTree/Base/TreeRow.vue index 8424f7f3c..927e8a8ec 100644 --- a/app/components/Viewer/ObjectTree/Base/TreeRow.vue +++ b/app/components/Viewer/ObjectTree/Base/TreeRow.vue @@ -15,7 +15,8 @@ function triggerHorizonStackModal(rawItem) { globalThis.dispatchEvent(new CustomEvent("open-horizon-stack-modal", { detail: rawItem })); } const isHorizonStack = computed(() => item.raw.geode_object_type === "HorizonStack3D"); -const showEyeButton = computed(() => !isHorizonStack.value && item.raw.title !== "HorizonStack3D"); +const isViewable = computed(() => item.raw.is_viewable === true || (item.raw.is_viewable === undefined && item.raw.binary_light_viewable !== "not_viewable")); +const showEyeButton = computed(() => !isHorizonStack.value && item.raw.title !== "HorizonStack3D" && isViewable.value); function handleRowClick(event) { if (isHorizonStack.value) { diff --git a/app/composables/hover_highlight.js b/app/composables/hover_highlight.js index 6c17de5d1..58125995a 100644 --- a/app/composables/hover_highlight.js +++ b/app/composables/hover_highlight.js @@ -1,3 +1,4 @@ +import { useDataStore } from "@ogw_front/stores/data"; import { useViewerStore } from "@ogw_front/stores/viewer"; import vtk_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json"; @@ -5,6 +6,7 @@ const HOVER_DELAY = 200; export function useHoverhighlight() { const viewerStore = useViewerStore(); + const dataStore = useDataStore(); let timer = undefined; let currentId = undefined; let currentType = undefined; @@ -20,10 +22,12 @@ export function useHoverhighlight() { currentId = id; currentType = type; - const { useDataStore } = await import("@ogw_front/stores/data"); - const dataStore = useDataStore(); const value = await dataStore.item(id); - if (value?.binary_light_viewable === "not_viewable") { + if ( + value && + (value.is_viewable === false || + (value.is_viewable === undefined && value.binary_light_viewable === "not_viewable")) + ) { return; } diff --git a/app/stores/data.js b/app/stores/data.js index c62e38971..bbbf83fc3 100644 --- a/app/stores/data.js +++ b/app/stores/data.js @@ -94,6 +94,7 @@ export const useDataStore = defineStore("data", () => { visible: true, created_at: new Date().toISOString(), binary_light_viewable: new_item.binary_light_viewable, + is_viewable: new_item.is_viewable, }; return data_db.put(itemData); } diff --git a/app/stores/data_style.js b/app/stores/data_style.js index 3b8414913..fa54c6de1 100644 --- a/app/stores/data_style.js +++ b/app/stores/data_style.js @@ -21,7 +21,11 @@ export const useDataStyleStore = defineStore("dataStyle", () => { async function setVisibility(id, visibility) { const item = await dataStore.item(id); - if (item.binary_light_viewable === "not_viewable") { + if ( + item && + (item.is_viewable === false || + (item.is_viewable === undefined && item.binary_light_viewable === "not_viewable")) + ) { return dataStyleState.mutateStyle(id, { visibility }); } @@ -38,7 +42,11 @@ export const useDataStyleStore = defineStore("dataStyle", () => { async function applyDefaultStyle(id) { const item = await dataStore.item(id); - if (item.binary_light_viewable === "not_viewable") { + if ( + item && + (item.is_viewable === false || + (item.is_viewable === undefined && item.binary_light_viewable === "not_viewable")) + ) { return; } @@ -89,7 +97,11 @@ export const useDataStyleStore = defineStore("dataStyle", () => { const ids = Object.keys(dataStyleState.styles.value); const promises = ids.map(async (id) => { const meta = await dataStore.item(id); - if (meta.binary_light_viewable === "not_viewable") { + if ( + meta && + (meta.is_viewable === false || + (meta.is_viewable === undefined && meta.binary_light_viewable === "not_viewable")) + ) { return; } const viewerType = meta.viewer_type; diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 9dcab26a1..2cad9e669 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -149,7 +149,7 @@ async function performAddItem(id, options) { return; } const value = await dataStore.item(id); - if (value.binary_light_viewable === "not_viewable") { + if (value && (value.is_viewable === false || (value.is_viewable === undefined && value.binary_light_viewable === "not_viewable"))) { return; } const reader = vtkXMLPolyDataReader(); From f5145b3b8d357578ff8e147206f6009641fb0537 Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Fri, 24 Jul 2026 15:48:54 +0000 Subject: [PATCH 13/22] Apply prepare changes --- app/components/Viewer/ObjectTree/Base/TreeRow.vue | 10 ++++++++-- internal/stores/hybrid_viewer.js | 6 +++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/components/Viewer/ObjectTree/Base/TreeRow.vue b/app/components/Viewer/ObjectTree/Base/TreeRow.vue index 927e8a8ec..752e29be8 100644 --- a/app/components/Viewer/ObjectTree/Base/TreeRow.vue +++ b/app/components/Viewer/ObjectTree/Base/TreeRow.vue @@ -15,8 +15,14 @@ function triggerHorizonStackModal(rawItem) { globalThis.dispatchEvent(new CustomEvent("open-horizon-stack-modal", { detail: rawItem })); } const isHorizonStack = computed(() => item.raw.geode_object_type === "HorizonStack3D"); -const isViewable = computed(() => item.raw.is_viewable === true || (item.raw.is_viewable === undefined && item.raw.binary_light_viewable !== "not_viewable")); -const showEyeButton = computed(() => !isHorizonStack.value && item.raw.title !== "HorizonStack3D" && isViewable.value); +const isViewable = computed( + () => + item.raw.is_viewable === true || + (item.raw.is_viewable === undefined && item.raw.binary_light_viewable !== "not_viewable"), +); +const showEyeButton = computed( + () => !isHorizonStack.value && item.raw.title !== "HorizonStack3D" && isViewable.value, +); function handleRowClick(event) { if (isHorizonStack.value) { diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 2cad9e669..2abe392e7 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -149,7 +149,11 @@ async function performAddItem(id, options) { return; } const value = await dataStore.item(id); - if (value && (value.is_viewable === false || (value.is_viewable === undefined && value.binary_light_viewable === "not_viewable"))) { + if ( + value && + (value.is_viewable === false || + (value.is_viewable === undefined && value.binary_light_viewable === "not_viewable")) + ) { return; } const reader = vtkXMLPolyDataReader(); From 7edea04742813ad3632288612e2e4adcb1bd2fde Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Fri, 24 Jul 2026 17:54:24 +0200 Subject: [PATCH 14/22] clear oxlint --- internal/stores/hybrid_viewer.js | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 2cad9e669..558afb0d0 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -8,12 +8,7 @@ const TOTAL_CHANNELS = 400; function mapRect(rect, latestImage, canvasRect) { const scaleX = latestImage.width / canvasRect.width; const scaleY = latestImage.height / canvasRect.height; - return { - relX: (rect.x - canvasRect.left) * scaleX, - relY: (rect.y - canvasRect.top) * scaleY, - relW: rect.width * scaleX, - relH: rect.height * scaleY, - }; + return { relX: (rect.x - canvasRect.left) * scaleX, relY: (rect.y - canvasRect.top) * scaleY, relW: rect.width * scaleX, relH: rect.height * scaleY }; } function computeAverageBrightness(rect, options) { @@ -64,10 +59,7 @@ function performClickPicking(event, options) { const { container, viewerStore, viewer_schemas, genericRenderWindow, syncRemoteCamera } = options; const rect = container.getBoundingClientRect(); const schema = viewer_schemas.opengeodeweb_viewer.viewer.get_point_position; - const params = { - x: Math.round(event.clientX - rect.left), - y: Math.round(rect.height - (event.clientY - rect.top)), - }; + const params = { x: Math.round(event.clientX - rect.left), y: Math.round(rect.height - (event.clientY - rect.top)) }; viewerStore.request( { schema, @@ -106,12 +98,7 @@ function performHoverHighlight(event, options) { } const rect = container.getBoundingClientRect(); const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight; - const params = { - x: Math.round(event.clientX - rect.left), - y: Math.round(rect.height - (event.clientY - rect.top)), - field_type: hover_highlight_field_type.value, - ids: Object.keys(hybridDb), - }; + const params = { x: Math.round(event.clientX - rect.left), y: Math.round(rect.height - (event.clientY - rect.top)), field_type: hover_highlight_field_type.value, ids: Object.keys(hybridDb) }; viewerStore.request( { schema, @@ -126,12 +113,7 @@ function performHoverHighlight(event, options) { function performClearHoverHighlight(options) { const { viewerStore, viewer_schemas, hover_highlight_field_type, hybridDb } = options; const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight; - const params = { - x: -1, - y: -1, - field_type: hover_highlight_field_type.value, - ids: Object.keys(hybridDb), - }; + const params = { x: -1, y: -1, field_type: hover_highlight_field_type.value, ids: Object.keys(hybridDb) }; viewerStore.request({ schema, params }); } From df2242e1a2e3d44fb27116bec5e9d3997248fa0c Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Fri, 24 Jul 2026 15:55:46 +0000 Subject: [PATCH 15/22] Apply prepare changes --- internal/stores/hybrid_viewer.js | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 8b6780d2d..2abe392e7 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -8,7 +8,12 @@ const TOTAL_CHANNELS = 400; function mapRect(rect, latestImage, canvasRect) { const scaleX = latestImage.width / canvasRect.width; const scaleY = latestImage.height / canvasRect.height; - return { relX: (rect.x - canvasRect.left) * scaleX, relY: (rect.y - canvasRect.top) * scaleY, relW: rect.width * scaleX, relH: rect.height * scaleY }; + return { + relX: (rect.x - canvasRect.left) * scaleX, + relY: (rect.y - canvasRect.top) * scaleY, + relW: rect.width * scaleX, + relH: rect.height * scaleY, + }; } function computeAverageBrightness(rect, options) { @@ -59,7 +64,10 @@ function performClickPicking(event, options) { const { container, viewerStore, viewer_schemas, genericRenderWindow, syncRemoteCamera } = options; const rect = container.getBoundingClientRect(); const schema = viewer_schemas.opengeodeweb_viewer.viewer.get_point_position; - const params = { x: Math.round(event.clientX - rect.left), y: Math.round(rect.height - (event.clientY - rect.top)) }; + const params = { + x: Math.round(event.clientX - rect.left), + y: Math.round(rect.height - (event.clientY - rect.top)), + }; viewerStore.request( { schema, @@ -98,7 +106,12 @@ function performHoverHighlight(event, options) { } const rect = container.getBoundingClientRect(); const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight; - const params = { x: Math.round(event.clientX - rect.left), y: Math.round(rect.height - (event.clientY - rect.top)), field_type: hover_highlight_field_type.value, ids: Object.keys(hybridDb) }; + const params = { + x: Math.round(event.clientX - rect.left), + y: Math.round(rect.height - (event.clientY - rect.top)), + field_type: hover_highlight_field_type.value, + ids: Object.keys(hybridDb), + }; viewerStore.request( { schema, @@ -113,7 +126,12 @@ function performHoverHighlight(event, options) { function performClearHoverHighlight(options) { const { viewerStore, viewer_schemas, hover_highlight_field_type, hybridDb } = options; const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight; - const params = { x: -1, y: -1, field_type: hover_highlight_field_type.value, ids: Object.keys(hybridDb) }; + const params = { + x: -1, + y: -1, + field_type: hover_highlight_field_type.value, + ids: Object.keys(hybridDb), + }; viewerStore.request({ schema, params }); } From 66c7cf3914c05c0a5c0177dc2f2a2ff5da84c925 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 27 Jul 2026 11:52:39 +0200 Subject: [PATCH 16/22] trigger From ed3a7a8ab6ad22d67fdee4787612061d3c657ca9 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 27 Jul 2026 11:57:16 +0200 Subject: [PATCH 17/22] create new finles in order to fix oxlint --- app/stores/hybrid_viewer.js | 10 ++-- internal/stores/hybrid_viewer.js | 62 +-------------------- internal/stores/hybrid_viewer_brightness.js | 62 +++++++++++++++++++++ 3 files changed, 68 insertions(+), 66 deletions(-) create mode 100644 internal/stores/hybrid_viewer_brightness.js diff --git a/app/stores/hybrid_viewer.js b/app/stores/hybrid_viewer.js index eee1fa493..068045d79 100644 --- a/app/stores/hybrid_viewer.js +++ b/app/stores/hybrid_viewer.js @@ -12,7 +12,10 @@ import { performSyncRemoteCamera, } from "@ogw_internal/stores/hybrid_viewer_camera"; import { - computeAverageBrightness, + createClearHoverData, + createHoverHighlight, +} from "@ogw_internal/stores/hybrid_viewer_highlight"; +import { performAddItem, performClear, performClearHoverHighlight, @@ -22,10 +25,7 @@ import { performSetVisibility, performSetZScaling, } from "@ogw_internal/stores/hybrid_viewer"; -import { - createClearHoverData, - createHoverHighlight, -} from "@ogw_internal/stores/hybrid_viewer_highlight"; +import { computeAverageBrightness } from "@ogw_internal/stores/hybrid_viewer_brightness"; import { newInstance as vtkActor } from "@kitware/vtk.js/Rendering/Core/Actor"; import { newInstance as vtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow"; import { newInstance as vtkMapper } from "@kitware/vtk.js/Rendering/Core/Mapper"; diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 2abe392e7..028519618 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -1,65 +1,5 @@ -import { BACKGROUND_GREY_VALUE, RGB_MAX } from "./hybrid_viewer_constants"; import { centerCameraOnPosition } from "./hybrid_viewer_camera"; -const RGBA_CHANNELS = 4; -const SAMPLE_SIZE = 10; -const TOTAL_CHANNELS = 400; - -function mapRect(rect, latestImage, canvasRect) { - const scaleX = latestImage.width / canvasRect.width; - const scaleY = latestImage.height / canvasRect.height; - return { - relX: (rect.x - canvasRect.left) * scaleX, - relY: (rect.y - canvasRect.top) * scaleY, - relW: rect.width * scaleX, - relH: rect.height * scaleY, - }; -} - -function computeAverageBrightness(rect, options) { - const { latestImage, offscreenCtx, offscreenCanvas, genericRenderWindow } = options; - if (!latestImage || !offscreenCtx || !offscreenCanvas || !genericRenderWindow) { - return BACKGROUND_GREY_VALUE / RGB_MAX; - } - const canvas = genericRenderWindow.getApiSpecificRenderWindow().getCanvas(); - if (!canvas) { - return BACKGROUND_GREY_VALUE / RGB_MAX; - } - if (rect.width <= 0 || rect.height <= 0) { - return BACKGROUND_GREY_VALUE / RGB_MAX; - } - const { relX, relY, relW, relH } = mapRect(rect, latestImage, canvas.getBoundingClientRect()); - if (relW <= 0 || relH <= 0) { - return BACKGROUND_GREY_VALUE / RGB_MAX; - } - offscreenCanvas.width = SAMPLE_SIZE; - offscreenCanvas.height = SAMPLE_SIZE; - try { - offscreenCtx.drawImage( - latestImage, - Math.max(0, relX), - Math.max(0, relY), - Math.min(latestImage.width, relW), - Math.min(latestImage.height, relH), - 0, - 0, - SAMPLE_SIZE, - SAMPLE_SIZE, - ); - const { data } = offscreenCtx.getImageData(0, 0, SAMPLE_SIZE, SAMPLE_SIZE); - let minBrightness = 1; - for (let i = 0; i < TOTAL_CHANNELS; i += RGBA_CHANNELS) { - const brightness = (data[i] + data[i + 1] + data[i + 2]) / (3 * RGB_MAX); - if (brightness < minBrightness) { - minBrightness = brightness; - } - } - return minBrightness; - } catch { - return BACKGROUND_GREY_VALUE / RGB_MAX; - } -} - function performClickPicking(event, options) { const { container, viewerStore, viewer_schemas, genericRenderWindow, syncRemoteCamera } = options; const rect = container.getBoundingClientRect(); @@ -317,7 +257,6 @@ function performClear(options) { } export { - computeAverageBrightness, performAddItem, performClearHoverHighlight, performClickPicking, @@ -328,3 +267,4 @@ export { performSetVisibility, performClear, }; + diff --git a/internal/stores/hybrid_viewer_brightness.js b/internal/stores/hybrid_viewer_brightness.js new file mode 100644 index 000000000..b4da1328b --- /dev/null +++ b/internal/stores/hybrid_viewer_brightness.js @@ -0,0 +1,62 @@ +import { BACKGROUND_GREY_VALUE, RGB_MAX } from "./hybrid_viewer_constants"; + +const RGBA_CHANNELS = 4; +const SAMPLE_SIZE = 10; +const TOTAL_CHANNELS = 400; + +function mapRect(rect, latestImage, canvasRect) { + const scaleX = latestImage.width / canvasRect.width; + const scaleY = latestImage.height / canvasRect.height; + return { + relX: (rect.x - canvasRect.left) * scaleX, + relY: (rect.y - canvasRect.top) * scaleY, + relW: rect.width * scaleX, + relH: rect.height * scaleY, + }; +} + +function computeAverageBrightness(rect, options) { + const { latestImage, offscreenCtx, offscreenCanvas, genericRenderWindow } = options; + if (!latestImage || !offscreenCtx || !offscreenCanvas || !genericRenderWindow) { + return BACKGROUND_GREY_VALUE / RGB_MAX; + } + const canvas = genericRenderWindow.getApiSpecificRenderWindow().getCanvas(); + if (!canvas) { + return BACKGROUND_GREY_VALUE / RGB_MAX; + } + if (rect.width <= 0 || rect.height <= 0) { + return BACKGROUND_GREY_VALUE / RGB_MAX; + } + const { relX, relY, relW, relH } = mapRect(rect, latestImage, canvas.getBoundingClientRect()); + if (relW <= 0 || relH <= 0) { + return BACKGROUND_GREY_VALUE / RGB_MAX; + } + offscreenCanvas.width = SAMPLE_SIZE; + offscreenCanvas.height = SAMPLE_SIZE; + try { + offscreenCtx.drawImage( + latestImage, + Math.max(0, relX), + Math.max(0, relY), + Math.min(latestImage.width, relW), + Math.min(latestImage.height, relH), + 0, + 0, + SAMPLE_SIZE, + SAMPLE_SIZE, + ); + const { data } = offscreenCtx.getImageData(0, 0, SAMPLE_SIZE, SAMPLE_SIZE); + let minBrightness = 1; + for (let i = 0; i < TOTAL_CHANNELS; i += RGBA_CHANNELS) { + const brightness = (data[i] + data[i + 1] + data[i + 2]) / (3 * RGB_MAX); + if (brightness < minBrightness) { + minBrightness = brightness; + } + } + return minBrightness; + } catch { + return BACKGROUND_GREY_VALUE / RGB_MAX; + } +} + +export { computeAverageBrightness }; From ad3e3995a00b5653e361e94139344c1c8c52b1b6 Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Mon, 27 Jul 2026 09:58:13 +0000 Subject: [PATCH 18/22] Apply prepare changes --- internal/stores/hybrid_viewer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 028519618..237ea1fdf 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -267,4 +267,3 @@ export { performSetVisibility, performClear, }; - From ff7eb08bff7aa3584ccba18ca3ba703da30d9ec2 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Wed, 29 Jul 2026 17:39:05 +0200 Subject: [PATCH 19/22] fix ox and tests --- .../Viewer/ObjectTree/Base/TreeRow.vue | 10 +++---- app/composables/hover_highlight.js | 6 +--- app/composables/use_overlapping_picker.js | 30 ++++++++++--------- app/stores/data.js | 21 ++++++++++++- app/stores/data_style.js | 20 +++---------- app/utils/import_workflow.js | 4 +-- internal/stores/hybrid_viewer.js | 6 +--- 7 files changed, 49 insertions(+), 48 deletions(-) diff --git a/app/components/Viewer/ObjectTree/Base/TreeRow.vue b/app/components/Viewer/ObjectTree/Base/TreeRow.vue index 752e29be8..f4a2dc70d 100644 --- a/app/components/Viewer/ObjectTree/Base/TreeRow.vue +++ b/app/components/Viewer/ObjectTree/Base/TreeRow.vue @@ -1,4 +1,8 @@