diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index d3d8e8478e5..b182da2d088 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,3 +1,8 @@ +## From 34.x to 35 + +- **vtkMapper**: mappers should overwrite `computeBounds()` instead of `getBounds` that now calls `computeBounds()` before returning a copy of the mapper bounds. + + ## From 33.x to 34 - **vtkMapper**: many properties have moved to `vtkVolumeProperty`. The full list of changed methods is: `getAnisotropy`, `getComputeNormalFromOpacity`, `getFilterMode`, `getFilterModeAsString`, `getGlobalIlluminationReach`, `getIpScalarRange`, `getIpScalarRangeByReference`, `getLAOKernelRadius`, `getLAOKernelSize`, `getLocalAmbientOcclusion`, `getPreferSizeOverAccuracy`, `getVolumetricScatteringBlending`, `setAnisotropy`, `setAverageIPScalarRange`, `setComputeNormalFromOpacity`, `setFilterMode`, `setFilterModeToNormalized`, `setFilterModeToOff`, `setFilterModeToRaw`, `setGlobalIlluminationReach`, `setIpScalarRange`, `setIpScalarRangeFrom`, `setLAOKernelRadius`, `setLAOKernelSize`, `setLocalAmbientOcclusion`, `setPreferSizeOverAccuracy`, `setVolumetricScatteringBlending`. diff --git a/Sources/Common/DataModel/BoundingBox/index.d.ts b/Sources/Common/DataModel/BoundingBox/index.d.ts index e2dc78f5863..1e85a09ae13 100644 --- a/Sources/Common/DataModel/BoundingBox/index.d.ts +++ b/Sources/Common/DataModel/BoundingBox/index.d.ts @@ -1,5 +1,5 @@ import { mat4 } from 'gl-matrix'; -import { Bounds, Vector2, Vector3 } from '../../../types'; +import { Bounds, TypedArray, Vector2, Vector3 } from '../../../types'; import vtkPoints from '../../Core/Points'; import { Nullable } from '../../../types'; @@ -394,11 +394,16 @@ declare class BoundingBox { /** * Adds points to a bounding box. * @param {Bounds} bounds - * @param {number} x + * @param {number|Number[]|TypedArray} xOrPoint * @param {number} y * @param {number} z */ - addPoint(bounds: Bounds, x: number, y: number, z: number): Bounds; + addPoint( + bounds: Bounds, + xOrPoint: number | number[] | TypedArray, + y?: number, + z?: number + ): Bounds; /** * Adds points to a bounding box. diff --git a/Sources/Common/DataModel/BoundingBox/index.js b/Sources/Common/DataModel/BoundingBox/index.js index 485da08e5ae..7fab7adfc3d 100644 --- a/Sources/Common/DataModel/BoundingBox/index.js +++ b/Sources/Common/DataModel/BoundingBox/index.js @@ -49,14 +49,23 @@ export function reset(bounds) { return setBounds(bounds, INIT_BOUNDS); } -export function addPoint(bounds, x, y, z) { +export function addPoint(bounds, xOrPoint, y, z) { const [xMin, xMax, yMin, yMax, zMin, zMax] = bounds; - bounds[0] = xMin < x ? xMin : x; - bounds[1] = xMax > x ? xMax : x; - bounds[2] = yMin < y ? yMin : y; - bounds[3] = yMax > y ? yMax : y; - bounds[4] = zMin < z ? zMin : z; - bounds[5] = zMax > z ? zMax : z; + if (arguments.length === 4) { + bounds[0] = xMin < xOrPoint ? xMin : xOrPoint; + bounds[1] = xMax > xOrPoint ? xMax : xOrPoint; + bounds[2] = yMin < y ? yMin : y; + bounds[3] = yMax > y ? yMax : y; + bounds[4] = zMin < z ? zMin : z; + bounds[5] = zMax > z ? zMax : z; + } else { + bounds[0] = xMin < xOrPoint[0] ? xMin : xOrPoint[0]; + bounds[1] = xMax > xOrPoint[0] ? xMax : xOrPoint[0]; + bounds[2] = yMin < xOrPoint[1] ? yMin : xOrPoint[1]; + bounds[3] = yMax > xOrPoint[1] ? yMax : xOrPoint[1]; + bounds[4] = zMin < xOrPoint[2] ? zMin : xOrPoint[2]; + bounds[5] = zMax > xOrPoint[2] ? zMax : xOrPoint[2]; + } return bounds; } diff --git a/Sources/Common/DataModel/Box/index.js b/Sources/Common/DataModel/Box/index.js index e92747348d3..4664eb65fc2 100644 --- a/Sources/Common/DataModel/Box/index.js +++ b/Sources/Common/DataModel/Box/index.js @@ -120,7 +120,7 @@ function vtkBox(publicAPI, model) { vtkBoundingBox.setBounds(model.bbox, boundsArray); }; - publicAPI.getBounds = () => model.bbox; + publicAPI.getBounds = () => [...model.bbox]; publicAPI.evaluateFunction = (x, y, z) => { const point = Array.isArray(x) ? x : [x, y, z]; diff --git a/Sources/Proxy/Core/ViewProxy/index.js b/Sources/Proxy/Core/ViewProxy/index.js index 948ed58a05a..eee4d584774 100644 --- a/Sources/Proxy/Core/ViewProxy/index.js +++ b/Sources/Proxy/Core/ViewProxy/index.js @@ -353,10 +353,11 @@ function vtkViewProxy(publicAPI, model) { // -------------------------------------------------------------------------- - publicAPI.setBackground = macro.chain( - model.renderer.setBackground, - updateAnnotationColor - ); + publicAPI.setBackground = (...args) => { + const res = model.renderer.setBackground(...args); + updateAnnotationColor(); + return res; + }; // -------------------------------------------------------------------------- diff --git a/Sources/Rendering/Core/AbstractMapper3D/index.d.ts b/Sources/Rendering/Core/AbstractMapper3D/index.d.ts index 1d37f8c7c20..21a5c1ffb36 100755 --- a/Sources/Rendering/Core/AbstractMapper3D/index.d.ts +++ b/Sources/Rendering/Core/AbstractMapper3D/index.d.ts @@ -15,11 +15,30 @@ export interface IAbstractMapper3DInitialValues export interface vtkAbstractMapper3D extends vtkAbstractMapper { /** * Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax]. - * @default 0 - * @return {Bounds} The bounds for the mapper. + * Bounds are (re)computed if needed. + * @return {Bounds} A copy of the bounds for the mapper. + * @see getBoundsByReference + * @see computeBounds */ getBounds(): Bounds; + /** + * Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax]. + * Bounds are (re)computed if needed. + * @return {Bounds} The bounds array of the mapper. + * @see getBounds + * @see computeBounds + */ + getBoundsByReference(): Bounds; + + /** + * Compute the bounds for this mapper. + * Must be implemented by sub-classes. Called by getBounds methods. + * @see getBoundsByReference + * @see getBounds + */ + computeBounds(): void; + /** * Get the center of this mapper’s data. * @return {Vector3} The center of the mapper's data. diff --git a/Sources/Rendering/Core/AbstractMapper3D/index.js b/Sources/Rendering/Core/AbstractMapper3D/index.js index 4f96e84fa94..b6fd27472f5 100644 --- a/Sources/Rendering/Core/AbstractMapper3D/index.js +++ b/Sources/Rendering/Core/AbstractMapper3D/index.js @@ -1,20 +1,30 @@ import macro from 'vtk.js/Sources/macros'; import vtkAbstractMapper from 'vtk.js/Sources/Rendering/Core/AbstractMapper'; import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox'; -import { createUninitializedBounds } from 'vtk.js/Sources/Common/Core/Math'; // ---------------------------------------------------------------------------- // vtkAbstractMapper methods // ---------------------------------------------------------------------------- function vtkAbstractMapper3D(publicAPI, model) { + publicAPI.computeBounds = () => { + macro.vtkErrorMacro(`vtkAbstractMapper3D.computeBounds - NOT IMPLEMENTED`); + }; + + const superGetBounds = publicAPI.getBounds; publicAPI.getBounds = () => { - macro.vtkErrorMacro(`vtkAbstractMapper3D.getBounds - NOT IMPLEMENTED`); - return createUninitializedBounds(); + publicAPI.computeBounds(); + return superGetBounds(); + }; + + const superGetBoundsByReference = publicAPI.getBoundsByReference; + publicAPI.getBoundsByReference = () => { + publicAPI.computeBounds(); + return superGetBoundsByReference(); }; publicAPI.getCenter = () => { - const bounds = publicAPI.getBounds(); + const bounds = publicAPI.getBoundsByReference(); model.center = vtkBoundingBox.isValid(bounds) ? vtkBoundingBox.getCenter(bounds) : null; @@ -22,7 +32,7 @@ function vtkAbstractMapper3D(publicAPI, model) { }; publicAPI.getLength = () => { - const bounds = publicAPI.getBounds(); + const bounds = publicAPI.getBoundsByReference(); return vtkBoundingBox.getDiagonalLength(bounds); }; } @@ -46,6 +56,7 @@ export function extend(publicAPI, model, initialValues = {}) { vtkAbstractMapper.extend(publicAPI, model, initialValues); macro.setGet(publicAPI, model, ['viewSpecificProperties']); + macro.getArray(publicAPI, model, ['bounds'], 6); vtkAbstractMapper3D(publicAPI, model); } diff --git a/Sources/Rendering/Core/CubeAxesActor/index.js b/Sources/Rendering/Core/CubeAxesActor/index.js index 11f0c526d69..da5bfb11425 100644 --- a/Sources/Rendering/Core/CubeAxesActor/index.js +++ b/Sources/Rendering/Core/CubeAxesActor/index.js @@ -788,7 +788,7 @@ function vtkCubeAxesActor(publicAPI, model) { // as it relies on the pixel size of the window. Every time the camera // changes the bounds change. This method simplifies by just expanding // the grid bounds by a user specified factor. - publicAPI.getBounds = () => { + publicAPI.computeBounds = () => { publicAPI.update(); vtkBoundingBox.setBounds(model.bounds, model.gridActor.getBounds()); vtkBoundingBox.scaleAboutCenter( @@ -797,15 +797,15 @@ function vtkCubeAxesActor(publicAPI, model) { model.boundsScaleFactor, model.boundsScaleFactor ); - return model.bounds; }; // Make sure the grid share the actor property - const _setProp = macro.chain( - publicAPI.setProperty, - model.gridActor.setProperty - ); - publicAPI.setProperty = (p) => _setProp(p)[0]; + const superSetProp = publicAPI.setProperty; + publicAPI.setProperty = (p) => { + const res = superSetProp(p); + model.gridActor.setProperty(p); + return res; + }; } // ---------------------------------------------------------------------------- diff --git a/Sources/Rendering/Core/Glyph3DMapper/index.js b/Sources/Rendering/Core/Glyph3DMapper/index.js index a3d9ac232f6..443d08fe381 100644 --- a/Sources/Rendering/Core/Glyph3DMapper/index.js +++ b/Sources/Rendering/Core/Glyph3DMapper/index.js @@ -66,22 +66,16 @@ function vtkGlyph3DMapper(publicAPI, model) { return idata.getPointData().getArray(model.scaleArray); }; - publicAPI.getBounds = () => { - const idata = publicAPI.getInputData(0); - const gdata = publicAPI.getInputData(1); - if (!idata || !gdata) { - return vtkMath.createUninitializedBounds(); - } - - // first we build the arrays used for the glyphing - publicAPI.buildArrays(); - return model.bounds; - }; + publicAPI.computeBounds = () => publicAPI.buildArrays(); publicAPI.buildArrays = () => { // if the mtgime requires it, rebuild const idata = publicAPI.getInputData(0); const gdata = publicAPI.getInputData(1); + if (!idata || !gdata) { + vtkBoundingBox.reset(model.bounds); + return; + } if ( model.buildTime.getMTime() < gdata.getMTime() || model.buildTime.getMTime() < idata.getMTime() || @@ -114,12 +108,7 @@ function vtkGlyph3DMapper(publicAPI, model) { // overall bounds while building the arrays const corners = []; vtkBoundingBox.getCorners(gbounds, corners); - model.bounds[0] = vtkBoundingBox.INIT_BOUNDS[0]; - model.bounds[1] = vtkBoundingBox.INIT_BOUNDS[1]; - model.bounds[2] = vtkBoundingBox.INIT_BOUNDS[2]; - model.bounds[3] = vtkBoundingBox.INIT_BOUNDS[3]; - model.bounds[4] = vtkBoundingBox.INIT_BOUNDS[4]; - model.bounds[5] = vtkBoundingBox.INIT_BOUNDS[5]; + vtkBoundingBox.reset(model.bounds); const tcorner = new Float64Array(3); @@ -225,24 +214,7 @@ function vtkGlyph3DMapper(publicAPI, model) { // update bounds for (let p = 0; p < 8; ++p) { vec3.transformMat4(tcorner, corners[p], z); - if (tcorner[0] < model.bounds[0]) { - model.bounds[0] = tcorner[0]; - } - if (tcorner[1] < model.bounds[2]) { - model.bounds[2] = tcorner[1]; - } - if (tcorner[2] < model.bounds[4]) { - model.bounds[4] = tcorner[2]; - } - if (tcorner[0] > model.bounds[1]) { - model.bounds[1] = tcorner[0]; - } - if (tcorner[1] > model.bounds[3]) { - model.bounds[3] = tcorner[1]; - } - if (tcorner[2] > model.bounds[5]) { - model.bounds[5] = tcorner[2]; - } + vtkBoundingBox.addPoint(model.bounds, tcorner); } const n = new Float32Array(nbuff, i * 36, 9); @@ -333,9 +305,6 @@ export function extend(publicAPI, model, initialValues = {}) { model.buildTime = {}; macro.obj(model.buildTime, { mtime: 0 }); - model.boundsTime = {}; - macro.obj(model.boundsTime, { mtime: 0 }); - macro.setGet(publicAPI, model, [ 'orient', 'orientationMode', diff --git a/Sources/Rendering/Core/HardwareSelector/test/testHardwareSelectorGlyph.js b/Sources/Rendering/Core/HardwareSelector/test/testHardwareSelectorGlyph.js index 3949b49bf63..5adbab10a6c 100644 --- a/Sources/Rendering/Core/HardwareSelector/test/testHardwareSelectorGlyph.js +++ b/Sources/Rendering/Core/HardwareSelector/test/testHardwareSelectorGlyph.js @@ -108,14 +108,16 @@ test('Test HardwareSelectorGlyph', (tapeContext) => { sel.setFieldAssociation(FieldAssociations.FIELD_ASSOCIATION_POINTS); return sel.selectAsync(renderer, 200, 200, 250, 300).then((res) => { - const allGood = res.length === 7 && res[0].getProperties().prop === actor; - - tapeContext.ok(res.length === 7, 'Seven glyphs selected'); + tapeContext.equal(res.length, 7, 'Seven glyphs selected'); tapeContext.ok( res[0].getProperties().compositeID === 71, 'glyph 71 was the first selected' ); - tapeContext.ok(allGood, 'Correct prop was selected'); + tapeContext.equal( + res[0].getProperties().prop, + actor, + 'Correct prop was selected' + ); gc.releaseResources(); }); diff --git a/Sources/Rendering/Core/ImageArrayMapper/index.js b/Sources/Rendering/Core/ImageArrayMapper/index.js index 0178ccc196a..761c707ddac 100644 --- a/Sources/Rendering/Core/ImageArrayMapper/index.js +++ b/Sources/Rendering/Core/ImageArrayMapper/index.js @@ -1,5 +1,6 @@ import macro from 'vtk.js/Sources/macros'; import vtkAbstractImageMapper from 'vtk.js/Sources/Rendering/Core/AbstractImageMapper'; +import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox'; import vtkImageMapper from 'vtk.js/Sources/Rendering/Core/ImageMapper'; import * as vtkMath from 'vtk.js/Sources/Common/Core/Math'; import * as pickingHelper from 'vtk.js/Sources/Rendering/Core/AbstractImageMapper/helper'; @@ -80,13 +81,16 @@ function vtkImageArrayMapper(publicAPI, model) { return null; }; - publicAPI.getBounds = () => { + // reimplemented from AbstractMapper3D + publicAPI.computeBounds = () => { const image = publicAPI.getCurrentImage(); if (!image) { - return vtkMath.createUninitializedBounds(); + vtkBoundingBox.reset(model.bounds); + return; } if (!model.useCustomExtents) { - return image.getBounds(); + vtkBoundingBox.setBounds(model.bounds, image.getBounds()); + return; } const ex = model.customDisplayExtent.slice(); @@ -95,7 +99,7 @@ function vtkImageArrayMapper(publicAPI, model) { const nSlice = publicAPI.getSubSlice(); ex[4] = nSlice; ex[5] = nSlice; - return image.extentToBounds(ex); + vtkBoundingBox.setBounds(model.bounds, image.extentToBounds(ex)); }; publicAPI.getBoundsForSlice = ( diff --git a/Sources/Rendering/Core/ImageCPRMapper/index.js b/Sources/Rendering/Core/ImageCPRMapper/index.js index 2db3873a27c..88d43f27233 100644 --- a/Sources/Rendering/Core/ImageCPRMapper/index.js +++ b/Sources/Rendering/Core/ImageCPRMapper/index.js @@ -1,4 +1,5 @@ import { mat4, quat, vec3 } from 'gl-matrix'; +import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox'; import CoincidentTopologyHelper from 'vtk.js/Sources/Rendering/Core/Mapper/CoincidentTopologyHelper'; import vtkAbstractImageMapper from 'vtk.js/Sources/Rendering/Core/AbstractImageMapper'; import macro from 'vtk.js/Sources/macros'; @@ -21,12 +22,19 @@ function vtkImageCPRMapper(publicAPI, model) { const superClass = { ...publicAPI }; /** - * Public methods + * Reimplemented from AbstractMapper3D */ - publicAPI.getBounds = () => { + publicAPI.computeBounds = () => { const imageWidth = publicAPI.getWidth(); const imageHeight = publicAPI.getHeight(); - return [0, imageWidth, 0, imageHeight, 0, 0]; + vtkBoundingBox.setBounds(model.bounds, [ + 0, + imageWidth, + 0, + imageHeight, + 0, + 0, + ]); }; publicAPI.getOrientationDataArray = () => { diff --git a/Sources/Rendering/Core/ImageMapper/index.js b/Sources/Rendering/Core/ImageMapper/index.js index 7aa27fdc80c..bfdbc2b68cc 100644 --- a/Sources/Rendering/Core/ImageMapper/index.js +++ b/Sources/Rendering/Core/ImageMapper/index.js @@ -1,6 +1,7 @@ import Constants from 'vtk.js/Sources/Rendering/Core/ImageMapper/Constants'; import macro from 'vtk.js/Sources/macros'; import vtkAbstractImageMapper from 'vtk.js/Sources/Rendering/Core/AbstractImageMapper'; +import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox'; import * as pickingHelper from 'vtk.js/Sources/Rendering/Core/AbstractImageMapper/helper'; import * as vtkMath from 'vtk.js/Sources/Common/Core/Math'; import CoincidentTopologyHelper from 'vtk.js/Sources/Rendering/Core/Mapper/CoincidentTopologyHelper'; @@ -204,13 +205,15 @@ function vtkImageMapper(publicAPI, model) { return model.closestIJKAxis; }; - publicAPI.getBounds = () => { + publicAPI.computeBounds = () => { const image = publicAPI.getCurrentImage(); if (!image) { - return vtkMath.createUninitializedBounds(); + vtkBoundingBox.reset(model.bounds); + return; } if (!model.useCustomExtents) { - return image.getBounds(); + vtkBoundingBox.setBounds(model.bounds, image.getBounds()); + return; } const ex = model.customDisplayExtent.slice(); @@ -237,7 +240,7 @@ function vtkImageMapper(publicAPI, model) { break; } - return image.extentToBounds(ex); + vtkBoundingBox.setBounds(model.bounds, image.extentToBounds(ex)); }; publicAPI.getBoundsForSlice = (slice = model.slice, halfThickness = 0) => { diff --git a/Sources/Rendering/Core/ImageSlice/index.js b/Sources/Rendering/Core/ImageSlice/index.js index 17589f2350c..c47771742af 100644 --- a/Sources/Rendering/Core/ImageSlice/index.js +++ b/Sources/Rendering/Core/ImageSlice/index.js @@ -62,22 +62,22 @@ function vtkImageSlice(publicAPI, model) { //---------------------------------------------------------------------------- // Get the minimum X bound - publicAPI.getMinXBound = () => publicAPI.getBounds()[0]; + publicAPI.getMinXBound = () => publicAPI.getBoundsByReference()[0]; // Get the maximum X bound - publicAPI.getMaxXBound = () => publicAPI.getBounds()[1]; + publicAPI.getMaxXBound = () => publicAPI.getBoundsByReference()[1]; // Get the minimum Y bound - publicAPI.getMinYBound = () => publicAPI.getBounds()[2]; + publicAPI.getMinYBound = () => publicAPI.getBoundsByReference()[2]; // Get the maximum Y bound - publicAPI.getMaxYBound = () => publicAPI.getBounds()[3]; + publicAPI.getMaxYBound = () => publicAPI.getBoundsByReference()[3]; // Get the minimum Z bound - publicAPI.getMinZBound = () => publicAPI.getBounds()[4]; + publicAPI.getMinZBound = () => publicAPI.getBoundsByReference()[4]; // Get the maximum Z bound - publicAPI.getMaxZBound = () => publicAPI.getBounds()[5]; + publicAPI.getMaxZBound = () => publicAPI.getBoundsByReference()[5]; publicAPI.getRedrawMTime = () => { let mt = model.mtime; diff --git a/Sources/Rendering/Core/Mapper/index.js b/Sources/Rendering/Core/Mapper/index.js index 1dad231c541..6fe0f1eb615 100644 --- a/Sources/Rendering/Core/Mapper/index.js +++ b/Sources/Rendering/Core/Mapper/index.js @@ -1,5 +1,6 @@ import macro from 'vtk.js/Sources/macros'; import vtkAbstractMapper3D from 'vtk.js/Sources/Rendering/Core/AbstractMapper3D'; +import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox'; import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray'; import vtkImageData from 'vtk.js/Sources/Common/DataModel/ImageData'; import vtkLookupTable from 'vtk.js/Sources/Common/Core/LookupTable'; @@ -297,17 +298,16 @@ function vtkMapper(publicAPI, model) { // Set our className model.classHierarchy.push('vtkMapper'); - publicAPI.getBounds = () => { + publicAPI.computeBounds = () => { const input = publicAPI.getInputData(); if (!input) { - model.bounds = vtkMath.createUninitializedBounds(); + vtkBoundingBox.reset(model.bounds); } else { if (!model.static) { publicAPI.update(); } - model.bounds = input.getBounds(); + vtkBoundingBox.setBounds(model.bounds, input.getBounds()); } - return model.bounds; }; publicAPI.setForceCompileOnly = (v) => { diff --git a/Sources/Rendering/Core/Prop3D/index.js b/Sources/Rendering/Core/Prop3D/index.js index a35aeb8a9f9..b16a8f9abb1 100644 --- a/Sources/Rendering/Core/Prop3D/index.js +++ b/Sources/Rendering/Core/Prop3D/index.js @@ -161,24 +161,24 @@ function vtkProp3D(publicAPI, model) { } }; - publicAPI.getBoundsByReference = () => { - if (model.mapper === null) { - return model.bounds; + publicAPI.computeBounds = () => { + if (model.bounds == null) { + model.bounds = []; } - // Check for the special case when the mapper's bounds are unknown - const bds = model.mapper.getBounds(); - if (!bds || bds.length !== 6) { - return bds; + if (model.mapper === null) { + vtkBoundingBox.reset(model.bounds); + return; } - // Check for the special case when the actor is empty. - if (bds[0] > bds[1]) { + // Check for the special case when the mapper's bounds are invalid + const bds = model.mapper.getBounds(); + if (!bds || bds.length !== 6 || !vtkBoundingBox.isValid(bds)) { // No need to copy bds, a new array is created when calling getBounds() model.mapperBounds = bds; - model.bounds = [...vtkBoundingBox.INIT_BOUNDS]; + vtkBoundingBox.reset(model.bounds); model.boundsMTime.modified(); - return bds; + return; } // Check if we have cached values for these bounds - we cache the @@ -203,25 +203,29 @@ function vtkProp3D(publicAPI, model) { model.boundsMTime.modified(); } - - return model.bounds; }; + const superGetBounds = publicAPI.getBounds; publicAPI.getBounds = () => { - const bounds = publicAPI.getBoundsByReference(); - // Handle case when bounds are not iterable (for example null or undefined) - try { - return [...bounds]; - } catch { - return bounds; - } + publicAPI.computeBounds(); + return superGetBounds(); }; - publicAPI.getCenter = () => vtkBoundingBox.getCenter(model.bounds); - publicAPI.getLength = () => vtkBoundingBox.getLength(model.bounds); - publicAPI.getXRange = () => vtkBoundingBox.getXRange(model.bounds); - publicAPI.getYRange = () => vtkBoundingBox.getYRange(model.bounds); - publicAPI.getZRange = () => vtkBoundingBox.getZRange(model.bounds); + const superGetBoundsByReference = publicAPI.getBoundsByReference; + publicAPI.getBoundsByReference = () => { + publicAPI.computeBounds(); + return superGetBoundsByReference(); + }; + publicAPI.getCenter = () => + vtkBoundingBox.getCenter(publicAPI.getBoundsByReference()); + publicAPI.getLength = () => + vtkBoundingBox.getLength(publicAPI.getBoundsByReference()); + publicAPI.getXRange = () => + vtkBoundingBox.getXRange(publicAPI.getBoundsByReference()); + publicAPI.getYRange = () => + vtkBoundingBox.getYRange(publicAPI.getBoundsByReference()); + publicAPI.getZRange = () => + vtkBoundingBox.getZRange(publicAPI.getBoundsByReference()); publicAPI.getUserMatrix = () => model.userMatrix; @@ -271,12 +275,12 @@ function vtkProp3D(publicAPI, model) { // ---------------------------------------------------------------------------- const DEFAULT_VALUES = { + // bounds: null, origin: [0, 0, 0], position: [0, 0, 0], orientation: [0, 0, 0], rotation: null, scale: [1, 1, 1], - bounds: [...vtkBoundingBox.INIT_BOUNDS], properties: [], userMatrix: null, @@ -303,6 +307,7 @@ export function extend(publicAPI, model, initialValues = {}) { macro.getArray(publicAPI, model, ['orientation']); macro.setGetArray(publicAPI, model, ['origin', 'position', 'scale'], 3); macro.setGet(publicAPI, model, ['properties']); + macro.getArray(publicAPI, model, ['bounds'], 6); // Object internal instance model.matrix = mat4.identity(new Float64Array(16)); diff --git a/Sources/Widgets/Representations/ArrowHandleRepresentation/index.js b/Sources/Widgets/Representations/ArrowHandleRepresentation/index.js index d843935f8d3..9291fb50b8c 100644 --- a/Sources/Widgets/Representations/ArrowHandleRepresentation/index.js +++ b/Sources/Widgets/Representations/ArrowHandleRepresentation/index.js @@ -115,11 +115,13 @@ function vtkArrowHandleRepresentation(publicAPI, model) { // -------------------------------------------------------------------------- - publicAPI.setGlyphResolution = macro.chain( - publicAPI.setGlyphResolution, - (r) => model._pipeline.glyph.setPhiResolution(r), - (r) => model._pipeline.glyph.setThetaResolution(r) - ); + const superSetGlyphResolution = publicAPI.setGlyphResolution; + publicAPI.setGlyphResolution = (r) => { + const res = superSetGlyphResolution(r); + model._pipeline.glyph.setPhiResolution(r); + model._pipeline.glyph.setThetaResolution(r); + return res; + }; // -------------------------------------------------------------------------- diff --git a/Sources/Widgets/Representations/CircleContextRepresentation/index.js b/Sources/Widgets/Representations/CircleContextRepresentation/index.js index 388e747db84..829b107b5b1 100644 --- a/Sources/Widgets/Representations/CircleContextRepresentation/index.js +++ b/Sources/Widgets/Representations/CircleContextRepresentation/index.js @@ -11,6 +11,7 @@ import { Resolve } from 'vtk.js/Sources/Rendering/Core/Mapper/CoincidentTopology function vtkCircleContextRepresentation(publicAPI, model) { // Set our className model.classHierarchy.push('vtkCircleContextRepresentation'); + const superClass = { ...publicAPI }; // -------------------------------------------------------------------------- // Generic rendering pipeline @@ -25,22 +26,27 @@ function vtkCircleContextRepresentation(publicAPI, model) { // -------------------------------------------------------------------------- - publicAPI.setGlyphResolution = macro.chain( - publicAPI.setGlyphResolution, - model._pipeline.glyph.setResolution - ); + publicAPI.setGlyphResolution = (r) => { + const res = superClass.setGlyphResolution(r); + model._pipeline.glyph.setResolution(r); + return res; + }; // -------------------------------------------------------------------------- - publicAPI.setDrawBorder = macro.chain(publicAPI.setDrawBorder, (draw) => - model._pipeline.glyph.setLines(draw) - ); + publicAPI.setDrawBorder = (draw) => { + const res = superClass.setDrawBorder(draw); + model._pipeline.glyph.setLines(draw); + return res; + }; // -------------------------------------------------------------------------- - publicAPI.setDrawFace = macro.chain(publicAPI.setDrawFace, (draw) => - model._pipeline.glyph.setFace(draw) - ); + publicAPI.setDrawFace = (draw) => { + const res = superClass.setDrawFace(draw); + model._pipeline.glyph.setFace(draw); + return res; + }; // -------------------------------------------------------------------------- diff --git a/Sources/Widgets/Representations/SplineContextRepresentation/index.js b/Sources/Widgets/Representations/SplineContextRepresentation/index.js index 5a0309e153e..bd4548260c6 100644 --- a/Sources/Widgets/Representations/SplineContextRepresentation/index.js +++ b/Sources/Widgets/Representations/SplineContextRepresentation/index.js @@ -142,15 +142,19 @@ function vtkSplineContextRepresentation(publicAPI, model) { publicAPI.getSelectedState = (prop, compositeID) => model.state; - function updateAreaVisibility() { - model._pipelines.area.actor.setVisibility(model.fill); - } - - publicAPI.setFill = macro.chain(publicAPI.setFill, updateAreaVisibility); + const superSetFill = publicAPI.setFill; + publicAPI.setFill = (fill) => { + const res = superSetFill(fill); + model._pipelines.area.actor.setVisibility(fill); + return res; + }; - publicAPI.setOutputBorder = macro.chain(publicAPI.setOutputBorder, (v) => - model._pipelines.border.actor.setVisibility(v) - ); + const superSetOutputBorder = publicAPI.setOutputBorder; + publicAPI.setOutputBorder = (v) => { + const res = superSetOutputBorder(v); + model._pipelines.border.actor.setVisibility(v); + return res; + }; } // ---------------------------------------------------------------------------- diff --git a/Sources/Widgets/Widgets3D/ResliceCursorWidget/index.js b/Sources/Widgets/Widgets3D/ResliceCursorWidget/index.js index cc779af9beb..a500c043c88 100644 --- a/Sources/Widgets/Widgets3D/ResliceCursorWidget/index.js +++ b/Sources/Widgets/Widgets3D/ResliceCursorWidget/index.js @@ -638,17 +638,17 @@ function vtkResliceCursorWidget(publicAPI, model) { }, {} ); - publicAPI.setScaleInPixels = macro.chain( - publicAPI.setScaleInPixels, - (scale) => { - publicAPI.getViewWidgets().forEach((w) => w.setScaleInPixels(scale)); - updateState( - model.widgetState, - model.scaleInPixels, - model.rotationHandlePosition - ); - } - ); + const superSetScaleInPixels = publicAPI.setScaleInPixels; + publicAPI.setScaleInPixels = (scale) => { + const res = superSetScaleInPixels(scale); + publicAPI.getViewWidgets().forEach((w) => w.setScaleInPixels(scale)); + updateState( + model.widgetState, + model.scaleInPixels, + model.rotationHandlePosition + ); + return res; + }; publicAPI.getPlaneExtremities = (viewType) => { const dirProj = publicAPI.getWidgetState().getPlanes()[viewType].normal;