diff --git a/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue b/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue index aae3c2e6..63fabd10 100644 --- a/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +++ b/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue @@ -137,6 +137,14 @@ function handleHoverLeave({ item }) { + + diff --git a/app/stores/hybrid_viewer.js b/app/stores/hybrid_viewer.js index dbd05268..74e1bfe1 100644 --- a/app/stores/hybrid_viewer.js +++ b/app/stores/hybrid_viewer.js @@ -9,6 +9,7 @@ import { WHEEL_TIME_OUT_MS, applySnapshot, computeAverageBrightness, + focusCameraOnBounds, getCameraOptions, performCameraOrientation, performClickPicking, @@ -159,6 +160,18 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { syncRemoteCamera(); } + function focusCameraOnObject(id) { + if (!hybridDb[id]) { + return; + } + const bounds = hybridDb[id].actor.getBounds(); + focusCameraOnBounds(bounds, { + genericRenderWindow: genericRenderWindow.value, + imageStyle, + syncRemoteCamera, + }); + } + function setCameraOrientation(orientation) { performCameraOrientation(orientation, { genericRenderWindow: genericRenderWindow.value, @@ -229,6 +242,7 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { return; } is_moving.value = false; + genericRenderWindow.value.getRenderer().resetCameraClippingRange(); syncRemoteCamera(); }, }); @@ -240,6 +254,7 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { clearTimeout(wheelEventEndTimeout); wheelEventEndTimeout = setTimeout(() => { is_moving.value = false; + genericRenderWindow.value.getRenderer().resetCameraClippingRange(); syncRemoteCamera(); }, WHEEL_TIME_OUT_MS); }); @@ -309,6 +324,7 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => { remoteRender, resize, resetCamera, + focusCameraOnObject, setCameraOrientation, setContainer, zScale, diff --git a/app/utils/local/scripts.js b/app/utils/local/scripts.js index 84459372..2f9b8808 100644 --- a/app/utils/local/scripts.js +++ b/app/utils/local/scripts.js @@ -8,9 +8,32 @@ import { appMode } from "./app_mode.js"; function commandExistsSync(execName) { const envPath = process.env.PATH || ""; - return envPath.split(path.delimiter).some((dir) => { + const paths = envPath.split(path.delimiter); + + let currentDir = process.cwd(); + while (currentDir !== path.parse(currentDir).root) { + const venvScripts = path.join( + currentDir, + ".venv", + process.platform === "win32" ? "Scripts" : "bin", + ); + if (fs.existsSync(venvScripts)) { + paths.unshift(venvScripts); + break; + } + currentDir = path.dirname(currentDir); + } + + return paths.some((dir) => { const filePath = path.join(dir, execName); - return fs.existsSync(filePath) && fs.statSync(filePath).isFile(); + if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) return true; + if (process.platform === "win32") { + return [".exe", ".cmd", ".bat", ".ps1"].some((ext) => { + const withExt = `${filePath}${ext}`; + return fs.existsSync(withExt) && fs.statSync(withExt).isFile(); + }); + } + return false; }); } diff --git a/internal/stores/hybrid_viewer.js b/internal/stores/hybrid_viewer.js index 04d72b14..952970ba 100644 --- a/internal/stores/hybrid_viewer.js +++ b/internal/stores/hybrid_viewer.js @@ -129,6 +129,20 @@ function centerCameraOnPosition(camera, pickedPosition) { ); } +function focusCameraOnBounds(bounds, options) { + const { genericRenderWindow, imageStyle, syncRemoteCamera } = options; + if (!bounds || bounds.length < 6 || bounds.some((v) => !isFinite(v))) { + return; + } + const renderer = genericRenderWindow.getRenderer(); + renderer.resetCamera(bounds); + if (imageStyle) { + imageStyle.opacity = 0; + } + genericRenderWindow.getRenderWindow().render(); + syncRemoteCamera(); +} + function performClickPicking(event, options) { const { container, viewerStore, viewer_schemas, genericRenderWindow, syncRemoteCamera } = options; const rect = container.getBoundingClientRect(); @@ -270,6 +284,7 @@ export { applySnapshot, centerCameraOnPosition, computeAverageBrightness, + focusCameraOnBounds, getCameraOptions, performCameraOrientation, performClickPicking,