From 72684c5d4871e134d785b397b60dc0dc68c481fb Mon Sep 17 00:00:00 2001 From: Forrest Li Date: Thu, 18 Jan 2018 15:39:08 -0500 Subject: [PATCH] fix(OrientationMarkerWidget): Use bounded square viewport --- .../Widgets/OrientationMarkerWidget/api.md | 23 ++++++ .../OrientationMarkerWidget/example/index.js | 4 + .../Widgets/OrientationMarkerWidget/index.js | 74 ++++++++++++------- 3 files changed, 76 insertions(+), 25 deletions(-) diff --git a/Sources/Interaction/Widgets/OrientationMarkerWidget/api.md b/Sources/Interaction/Widgets/OrientationMarkerWidget/api.md index 84b338f84e5..d8330797e46 100644 --- a/Sources/Interaction/Widgets/OrientationMarkerWidget/api.md +++ b/Sources/Interaction/Widgets/OrientationMarkerWidget/api.md @@ -1,3 +1,15 @@ +### updateMarkerOrientation() + +Manually updates the marker's orientation. + +### computeViewport() + +Returns the computed viewport size. The format is `[left bottom right top]`. + +### updateViewport() + +Updates the orientation widget viewport size. + ### setEnabled(enabling) Sets the widget enabled status, i.e. to show the widget or not. @@ -11,3 +23,14 @@ BOTTOM_LEFT. Sets the viewport size. The sizeFactor should be between 0.0 and 1.0. It says how much of the main render window to color. Defaults to 0.2. + +### setMinPixelSize(pixelSize) + +Sets the minimum side length, in pixels, for the orientation marker widget +viewport. Defaults to 50. + +### setMaxPixelSize(pixelSize) + +Sets the maximum side length, in pixels, for the orientation marker widget +viewport. Defaults to 200. + diff --git a/Sources/Interaction/Widgets/OrientationMarkerWidget/example/index.js b/Sources/Interaction/Widgets/OrientationMarkerWidget/example/index.js index 176783d2786..55ab915ef33 100644 --- a/Sources/Interaction/Widgets/OrientationMarkerWidget/example/index.js +++ b/Sources/Interaction/Widgets/OrientationMarkerWidget/example/index.js @@ -73,6 +73,10 @@ orientationWidget.setViewportCorner( vtkOrientationMarkerWidget.Corners.BOTTOM_RIGHT ); orientationWidget.setViewportSize(0.15); +orientationWidget.setMinPixelSize(100); +orientationWidget.setMaxPixelSize(300); renderer.resetCamera(); renderWindow.render(); + +global.renderWindow = renderWindow; diff --git a/Sources/Interaction/Widgets/OrientationMarkerWidget/index.js b/Sources/Interaction/Widgets/OrientationMarkerWidget/index.js index 17391a435db..0b9199c2921 100644 --- a/Sources/Interaction/Widgets/OrientationMarkerWidget/index.js +++ b/Sources/Interaction/Widgets/OrientationMarkerWidget/index.js @@ -6,14 +6,6 @@ import Constants from 'vtk.js/Sources/Interaction/Widgets/OrientationMarkerWidge // vtkOrientationMarkerWidget // ---------------------------------------------------------------------------- -// depends on Constants.Corners -const VIEWPORTS = { - TOP_LEFT: (size) => [0, 1 - size, size, 1], - TOP_RIGHT: (size) => [1 - size, 1 - size, 1, 1], - BOTTOM_LEFT: (size) => [0, 0, size, size], - BOTTOM_RIGHT: (size) => [1 - size, 0, 1, size], -}; - function vtkOrientationMarkerWidget(publicAPI, model) { // Set our className model.classHierarchy.push('vtkOrientationMarkerWidget'); @@ -23,9 +15,27 @@ function vtkOrientationMarkerWidget(publicAPI, model) { const selfRenderer = vtkRenderer.newInstance(); let interactorUnsubscribe = null; - // private methods + publicAPI.computeViewport = () => { + const [viewXSize, viewYSize] = model.interactor.getView().getSize(); + let pixelSize = model.viewportSize * Math.min(viewXSize, viewYSize); + // clamp pixel size + pixelSize = Math.max( + model.minPixelSize, + Math.min(model.maxPixelSize, pixelSize) + ); + + const xFrac = pixelSize / viewXSize; + const yFrac = pixelSize / viewYSize; + // [left bottom right top] + return [0, 1 - yFrac, xFrac, 1]; + }; + + publicAPI.updateViewport = () => { + selfRenderer.setViewport(...publicAPI.computeViewport()); + model.interactor.render(); + }; - function updateMarkerOrientation() { + publicAPI.updateMarkerOrientation = () => { const currentCamera = model.interactor .findPokedRenderer() .getActiveCamera(); @@ -34,17 +44,10 @@ function vtkOrientationMarkerWidget(publicAPI, model) { return; } - // window.camera = currentCamera; const state = currentCamera.get('position', 'focalPoint', 'viewUp'); selfRenderer.getActiveCamera().set(state); selfRenderer.resetCamera(); - } - - function getViewport() { - return VIEWPORTS[model.viewportCorner](model.viewportSize); - } - - // public methods + }; /** * Enables/Disables the orientation marker. @@ -81,13 +84,16 @@ function vtkOrientationMarkerWidget(publicAPI, model) { selfRenderer.addViewProp(model.actor); model.actor.setVisibility(true); - selfRenderer.setViewport(...getViewport()); - const { unsubscribe } = model.interactor.onAnimation( - updateMarkerOrientation + publicAPI.updateMarkerOrientation ); interactorUnsubscribe = unsubscribe; + window.addEventListener('resize', publicAPI.updateViewport); + + publicAPI.updateViewport(); + publicAPI.updateMarkerOrientation(); + model.enabled = true; } else { if (!model.enabled) { @@ -95,6 +101,8 @@ function vtkOrientationMarkerWidget(publicAPI, model) { } model.enabled = false; + window.removeEventListener('resize', publicAPI.updateViewport); + interactorUnsubscribe(); interactorUnsubscribe = null; @@ -114,9 +122,13 @@ function vtkOrientationMarkerWidget(publicAPI, model) { * Sets the viewport corner. */ publicAPI.setViewportCorner = (corner) => { + if (corner === model.viewportCorner) { + return; + } + model.viewportCorner = corner; if (model.enabled) { - selfRenderer.setViewport(...getViewport()); + publicAPI.updateViewport(); } }; @@ -124,9 +136,14 @@ function vtkOrientationMarkerWidget(publicAPI, model) { * Sets the viewport size. */ publicAPI.setViewportSize = (sizeFactor) => { - model.viewportSize = Math.min(1, Math.max(0, sizeFactor)); + const viewportSize = Math.min(1, Math.max(0, sizeFactor)); + if (viewportSize === model.viewportSize) { + return; + } + + model.viewportSize = viewportSize; if (model.enabled) { - selfRenderer.setViewport(...getViewport()); + publicAPI.updateViewport(); } }; } @@ -140,6 +157,8 @@ export const DEFAULT_VALUES = { // interactor: null, viewportCorner: Constants.Corners.BOTTOM_LEFT, viewportSize: 0.2, + minPixelSize: 50, + maxPixelSize: 200, }; // ---------------------------------------------------------------------------- @@ -154,7 +173,12 @@ export function extend(publicAPI, model, initialValues = {}) { // NOTE: setting these while the widget is enabled will // not update the widget. - macro.setGet(publicAPI, model, ['actor', 'interactor']); + macro.setGet(publicAPI, model, [ + 'actor', + 'interactor', + 'minPixelSize', + 'maxPixelSize', + ]); // Object methods vtkOrientationMarkerWidget(publicAPI, model);