From 40640d9d167620611495d1c184df3a5f43f82d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Bruy=C3=A8re?= Date: Wed, 2 Oct 2024 15:21:55 +0200 Subject: [PATCH] refactor: Enable multi properties on all vtkProp3D --- Sources/Rendering/Core/Actor/index.d.ts | 19 +++-------- Sources/Rendering/Core/Actor/index.js | 21 +++--------- Sources/Rendering/Core/ImageSlice/index.d.ts | 12 +++++++ Sources/Rendering/Core/ImageSlice/index.js | 36 +++++--------------- Sources/Rendering/Core/Prop3D/index.d.ts | 31 +++++++++++++++++ Sources/Rendering/Core/Prop3D/index.js | 28 +++++++++++++++ Sources/Rendering/Core/Volume/index.js | 29 +--------------- 7 files changed, 89 insertions(+), 87 deletions(-) diff --git a/Sources/Rendering/Core/Actor/index.d.ts b/Sources/Rendering/Core/Actor/index.d.ts index 54a4e68cf74..3035ce513e9 100755 --- a/Sources/Rendering/Core/Actor/index.d.ts +++ b/Sources/Rendering/Core/Actor/index.d.ts @@ -57,16 +57,6 @@ export interface vtkActor extends vtkProp3D { */ getMapper(): Nullable; - /** - * Get the property object that controls this actors surface - * properties. This should be an instance of a vtkProperty object. Every - * actor must have a property associated with it. If one isn’t specified, - * then one will be generated automatically. Multiple actors can share one - * property object. - * @return {vtkProperty} The property object - */ - getProperty(): vtkProperty; - /** * Check whether if the actor supports selection * @return {Boolean} true if the actor support selection. @@ -105,11 +95,12 @@ export interface vtkActor extends vtkProp3D { */ setMapper(mapper: vtkMapper): boolean; - /** - * Set the property object that controls this actors surface properties. - * @param {vtkProperty} property The vtkProperty instance. - */ + // Inherited from vtkProp3D, but takes a vtkProperty instead of a generic vtkObject + getProperty(mapperInputPort?: number): vtkProperty; + getProperties(): vtkProperty[]; + setProperty(mapperInputPort: number, property: vtkProperty): boolean; setProperty(property: vtkProperty): boolean; + setProperties(properties: vtkProperty[]): boolean; } /** diff --git a/Sources/Rendering/Core/Actor/index.js b/Sources/Rendering/Core/Actor/index.js index 4fe57492029..acb2a01613d 100644 --- a/Sources/Rendering/Core/Actor/index.js +++ b/Sources/Rendering/Core/Actor/index.js @@ -23,12 +23,12 @@ function vtkActor(publicAPI, model) { return false; } // make sure we have a property - if (!model.property) { + if (!model.properties[0]) { // force creation of a property publicAPI.getProperty(); } - let isOpaque = model.property.getOpacity() >= 1.0; + let isOpaque = model.properties[0].getOpacity() >= 1.0; // are we using an opaque texture, if any? isOpaque = isOpaque && (!model.texture || !model.texture.isTranslucent()); @@ -44,9 +44,9 @@ function vtkActor(publicAPI, model) { return false; } // make sure we have a property - if (model.property === null) { + if (!model.properties[0]) { // force creation of a property - publicAPI.setProperty(publicAPI.makeProperty()); + publicAPI.getProperty(); } // is this actor opaque ? @@ -55,19 +55,8 @@ function vtkActor(publicAPI, model) { publicAPI.makeProperty = vtkProperty.newInstance; - publicAPI.getProperty = () => { - if (model.property === null) { - model.property = publicAPI.makeProperty(); - } - return model.property; - }; - publicAPI.getMTime = () => { let mt = superClass.getMTime(); - if (model.property !== null) { - const time = model.property.getMTime(); - mt = time > mt ? time : mt; - } if (model.backfaceProperty !== null) { const time = model.backfaceProperty.getMTime(); @@ -108,7 +97,6 @@ function vtkActor(publicAPI, model) { const DEFAULT_VALUES = { mapper: null, - property: null, backfaceProperty: null, forceOpaque: false, @@ -128,7 +116,6 @@ export function extend(publicAPI, model, initialValues = {}) { macro.obj(model.boundsMTime); // Build VTK API - macro.set(publicAPI, model, ['property']); macro.setGet(publicAPI, model, [ 'backfaceProperty', 'forceOpaque', diff --git a/Sources/Rendering/Core/ImageSlice/index.d.ts b/Sources/Rendering/Core/ImageSlice/index.d.ts index b25417fd536..70f1eec0cea 100755 --- a/Sources/Rendering/Core/ImageSlice/index.d.ts +++ b/Sources/Rendering/Core/ImageSlice/index.d.ts @@ -40,6 +40,11 @@ export interface vtkImageSlice extends vtkProp3D { */ getProperty(): vtkImageProperty; + /** + * + */ + getProperties(): vtkImageProperty[]; + /** * */ @@ -124,6 +129,13 @@ export interface vtkImageSlice extends vtkProp3D { */ setProperty(property: vtkImageProperty): boolean; + /** + * Set the actor properties array + * Each element of the array corresponds to a mapper input port + * @param {vtkImageProperty[]} properties + */ + setProperties(properties: vtkImageProperty[]): boolean; + /** * * @param {boolean} forceOpaque If true, render during opaque pass even if opacity value is below 1.0. diff --git a/Sources/Rendering/Core/ImageSlice/index.js b/Sources/Rendering/Core/ImageSlice/index.js index 5c61d2ccc74..17589f2350c 100644 --- a/Sources/Rendering/Core/ImageSlice/index.js +++ b/Sources/Rendering/Core/ImageSlice/index.js @@ -23,12 +23,12 @@ function vtkImageSlice(publicAPI, model) { return false; } // make sure we have a property - if (!model.property) { + if (!model.properties[0]) { // force creation of a property publicAPI.getProperty(); } - let isOpaque = model.property.getOpacity() >= 1.0; + let isOpaque = model.properties[0].getOpacity() >= 1.0; // are we using an opaque scalar array, if any? isOpaque = isOpaque && (!model.mapper || model.mapper.getIsOpaque()); @@ -45,13 +45,6 @@ function vtkImageSlice(publicAPI, model) { publicAPI.makeProperty = vtkImageProperty.newInstance; - publicAPI.getProperty = () => { - if (model.property === null) { - model.property = publicAPI.makeProperty(); - } - return model.property; - }; - publicAPI.getBoundsForSlice = (slice, thickness) => { // Check for the special case when the mapper's bounds are unknown const bds = model.mapper.getBoundsForSlice(slice, thickness); @@ -86,16 +79,6 @@ function vtkImageSlice(publicAPI, model) { // Get the maximum Z bound publicAPI.getMaxZBound = () => publicAPI.getBounds()[5]; - publicAPI.getMTime = () => { - let mt = model.mtime; - if (model.property !== null) { - const time = model.property.getMTime(); - mt = time > mt ? time : mt; - } - - return mt; - }; - publicAPI.getRedrawMTime = () => { let mt = model.mtime; if (model.mapper !== null) { @@ -108,14 +91,13 @@ function vtkImageSlice(publicAPI, model) { mt = time > mt ? time : mt; } } - if (model.property !== null) { - let time = model.property.getMTime(); - mt = time > mt ? time : mt; - if (model.property.getRGBTransferFunction() !== null) { - time = model.property.getRGBTransferFunction().getMTime(); - mt = time > mt ? time : mt; + model.properties.forEach((property) => { + mt = Math.max(mt, property.getMTime()); + const rgbFunc = property.getRGBTransferFunction(); + if (rgbFunc !== null) { + mt = Math.max(mt, rgbFunc.getMTime()); } - } + }); return mt; }; @@ -129,7 +111,6 @@ function vtkImageSlice(publicAPI, model) { const DEFAULT_VALUES = { mapper: null, - property: null, forceOpaque: false, forceTranslucent: false, }; @@ -147,7 +128,6 @@ export function extend(publicAPI, model, initialValues = {}) { macro.obj(model.boundsMTime); // Build VTK API - macro.set(publicAPI, model, ['property']); macro.setGet(publicAPI, model, ['mapper', 'forceOpaque', 'forceTranslucent']); // Object methods diff --git a/Sources/Rendering/Core/Prop3D/index.d.ts b/Sources/Rendering/Core/Prop3D/index.d.ts index 12fa4849f00..488378db565 100755 --- a/Sources/Rendering/Core/Prop3D/index.d.ts +++ b/Sources/Rendering/Core/Prop3D/index.d.ts @@ -1,6 +1,7 @@ import { mat4, quat } from 'gl-matrix'; import { Bounds, Vector3, Range } from '../../../types'; import vtkProp, { IPropInitialValues } from '../Prop'; +import { vtkObject } from '../../../interfaces'; export interface IProp3DInitialValues extends IPropInitialValues { origin?: number[]; @@ -137,6 +138,21 @@ export interface vtkProp3D extends vtkProp { */ getUserMatrix(): mat4; + /** + * Get the actor property for the specified mapper input port, which defaults to 0 + * It controls this actors rendering properties. If one isn’t specified, + * then one will be generated automatically. Multiple actors can share one + * property object. + * @param {number} mapperInputPort Defaults to 0 + */ + getProperty(mapperInputPort?: number): vtkObject; + + /** + * Get the actor properties array + * Each element of the array corresponds to a mapper input port + */ + getProperties(): vtkObject[]; + /** * Rotate the Prop3D in degrees about the X axis using the right hand * rule. The axis is the Prop3D’s X axis, which can change as other @@ -262,6 +278,21 @@ export interface vtkProp3D extends vtkProp { * Generate the matrix based on internal model. */ computeMatrix(): void; + + /** + * Set the actor property for the specified mapper input port, which defaults to 0 + * @param {vtkObject} property + * @param {number} mapperInputPort Is 0 when not given + */ + setProperty(mapperInputPort: number, property: vtkObject): boolean; + setProperty(property: vtkObject): boolean; + + /** + * Set the actor properties array + * Each element of the array corresponds to a mapper input port + * @param {vtkObject[]} properties + */ + setProperties(properties: vtkObject[]): boolean; } /** diff --git a/Sources/Rendering/Core/Prop3D/index.js b/Sources/Rendering/Core/Prop3D/index.js index 2b5e62f3a55..6abb5b65909 100644 --- a/Sources/Rendering/Core/Prop3D/index.js +++ b/Sources/Rendering/Core/Prop3D/index.js @@ -230,6 +230,32 @@ function vtkProp3D(publicAPI, model) { } publicAPI.onModified(updateIdentityFlag); + + publicAPI.getProperty = (mapperInputPort = 0) => { + if (model.properties[mapperInputPort] == null) { + model.properties[mapperInputPort] = publicAPI.makeProperty?.(); + } + return model.properties[mapperInputPort]; + }; + + publicAPI.setProperty = (property, mapperInputPort = 0) => { + if (model.properties[mapperInputPort] === property) { + return false; + } + model.properties[mapperInputPort] = property; + return true; + }; + + publicAPI.getMTime = () => { + let mt = model.mtime; + model.properties.forEach((property) => { + if (property !== null) { + const time = property.getMTime(); + mt = time > mt ? time : mt; + } + }); + return mt; + }; } // ---------------------------------------------------------------------------- @@ -243,6 +269,7 @@ const DEFAULT_VALUES = { rotation: null, scale: [1, 1, 1], bounds: [...vtkBoundingBox.INIT_BOUNDS], + properties: [], userMatrix: null, userMatrixMTime: null, @@ -267,6 +294,7 @@ export function extend(publicAPI, model, initialValues = {}) { macro.get(publicAPI, model, ['isIdentity']); macro.getArray(publicAPI, model, ['orientation']); macro.setGetArray(publicAPI, model, ['origin', 'position', 'scale'], 3); + macro.setGet(publicAPI, model, ['properties']); // Object internal instance model.matrix = mat4.identity(new Float64Array(16)); diff --git a/Sources/Rendering/Core/Volume/index.js b/Sources/Rendering/Core/Volume/index.js index a442d4e0cd3..0e24337b518 100644 --- a/Sources/Rendering/Core/Volume/index.js +++ b/Sources/Rendering/Core/Volume/index.js @@ -14,32 +14,6 @@ function vtkVolume(publicAPI, model) { publicAPI.makeProperty = vtkVolumeProperty.newInstance; - publicAPI.getProperty = (mapperInputPort = 0) => { - if (model.properties[mapperInputPort] == null) { - model.properties[mapperInputPort] = publicAPI.makeProperty(); - } - return model.properties[mapperInputPort]; - }; - - publicAPI.setProperty = (property, mapperInputPort = 0) => { - if (model.properties[mapperInputPort] === property) { - return false; - } - model.properties[mapperInputPort] = property; - return true; - }; - - publicAPI.getMTime = () => { - let mt = model.mtime; - model.properties.forEach((property) => { - if (property !== null) { - const time = property.getMTime(); - mt = time > mt ? time : mt; - } - }); - return mt; - }; - publicAPI.getRedrawMTime = () => { let mt = model.mtime; if (model.mapper !== null) { @@ -62,7 +36,6 @@ function vtkVolume(publicAPI, model) { const DEFAULT_VALUES = { mapper: null, - properties: [], }; // ---------------------------------------------------------------------------- @@ -78,7 +51,7 @@ export function extend(publicAPI, model, initialValues = {}) { macro.obj(model.boundsMTime); // Build VTK API - macro.setGet(publicAPI, model, ['mapper', 'properties']); + macro.setGet(publicAPI, model, ['mapper']); // Object methods vtkVolume(publicAPI, model);