Skip to content

Commit

Permalink
feat(ImageResliceMapper): support updated extents
Browse files Browse the repository at this point in the history
  • Loading branch information
floryst committed Jun 11, 2024
1 parent 5c8f191 commit 22fc452
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 37 deletions.
22 changes: 20 additions & 2 deletions Sources/Rendering/Core/ImageResliceMapper/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import vtkAbstractImageMapper, {
IAbstractImageMapperInitialValues,
} from '../AbstractImageMapper';
import vtkImageData from '../../../Common/DataModel/ImageData';
import vtkPlane from '../../../Common/DataModel/Plane';
import vtkPolyData from '../../../Common/DataModel/PolyData';
import { Bounds, Nullable, Vector3 } from '../../../types';
import { Bounds, Extent } from '../../../types';
import { SlabTypes } from './Constants';

interface ICoincidentTopology {
Expand Down Expand Up @@ -234,6 +233,25 @@ export interface vtkImageResliceMapper extends vtkAbstractImageMapper {
* @param {vtkPolyData} slicePolyData The polydata to slice the volume with. Default: null
*/
setSlicePolyData(slicePolyData: vtkPolyData): boolean;

/**
* Tells the mapper to only update the specified extents.
*
* If there are zero extents, the mapper updates the entire volume texture.
* Otherwise, the mapper will only update the texture by the specified extents
* during the next render call.
*
* This array is cleared after a successful render.
* @param extents
*/
setUpdatedExtents(extents: Extent[]): boolean;

/**
* Retrieves the updated extents.
*
* This array is cleared after every successful render.
*/
getUpdatedExtents(): Extent[];
}

/**
Expand Down
9 changes: 6 additions & 3 deletions Sources/Rendering/Core/ImageResliceMapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,20 @@ function vtkImageResliceMapper(publicAPI, model) {
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
const defaultValues = (initialValues) => ({
slabThickness: 0.0,
slabTrapezoidIntegration: 0,
slabType: SlabTypes.MEAN,
slicePlane: null,
slicePolyData: null,
};
updatedExtents: [],
...initialValues,
});

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
Object.assign(model, defaultValues(initialValues));

// Build VTK API
vtkAbstractImageMapper.extend(publicAPI, model, initialValues);
Expand All @@ -61,6 +63,7 @@ export function extend(publicAPI, model, initialValues = {}) {
'slabType',
'slicePlane',
'slicePolyData',
'updatedExtents',
]);
CoincidentTopologyHelper.implementCoincidentTopologyMethods(publicAPI, model);

Expand Down
42 changes: 22 additions & 20 deletions Sources/Rendering/Core/VolumeMapper/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import vtkPiecewiseFunction from "../../../Common/DataModel/PiecewiseFunction";
import { Bounds, Range, Extent } from "../../../types";
import vtkAbstractMapper3D, { IAbstractMapper3DInitialValues } from "../AbstractMapper3D";
import { BlendMode, FilterMode } from "./Constants";
import vtkPiecewiseFunction from '../../../Common/DataModel/PiecewiseFunction';
import { Bounds, Range, Extent } from '../../../types';
import vtkAbstractMapper3D, {
IAbstractMapper3DInitialValues,
} from '../AbstractMapper3D';
import { BlendMode, FilterMode } from './Constants';

/**
*
Expand Down Expand Up @@ -279,19 +281,19 @@ export interface vtkVolumeMapper extends vtkAbstractMapper3D {
*/
setLAOKernelRadius(LAOKernelRadius: number): void;

/**
* Set kernel size for local ambient occlusion. It specifies the number of rays that are randomly sampled in the hemisphere.
* Value is clipped between 1 and 32.
* @param LAOKernelSize
*/
setLAOKernelSize(LAOKernelSize: number): void;
/**
* Set kernel size for local ambient occlusion. It specifies the number of rays that are randomly sampled in the hemisphere.
* Value is clipped between 1 and 32.
* @param LAOKernelSize
*/
setLAOKernelSize(LAOKernelSize: number): void;

/**
* Set kernel radius for local ambient occlusion. It specifies the number of samples that are considered on each random ray.
* Value must be greater than or equal to 1.
* @param LAOKernelRadius
*/
setLAOKernelRadius(LAOKernelRadius: number): void;
/**
* Set kernel radius for local ambient occlusion. It specifies the number of samples that are considered on each random ray.
* Value must be greater than or equal to 1.
* @param LAOKernelRadius
*/
setLAOKernelRadius(LAOKernelRadius: number): void;

/**
* Tells the mapper to only update the specified extents.
Expand All @@ -312,10 +314,10 @@ export interface vtkVolumeMapper extends vtkAbstractMapper3D {
*/
getUpdatedExtents(): Extent[];

/**
*
*/
update(): void;
/**
*
*/
update(): void;
}

/**
Expand Down
31 changes: 23 additions & 8 deletions Sources/Rendering/OpenGL/ImageResliceMapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,24 +215,39 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {

const tex = model._openGLRenderWindow.getGraphicsResourceForObject(scalars);
const reBuildTex = !tex?.vtkObj || tex?.hash !== toString;
if (reBuildTex) {
const hasUpdatedExtents = !!model.renderable.getUpdatedExtents().length;

// reset the scalars texture if there are no updated extents
if (reBuildTex && !hasUpdatedExtents) {
// Use norm16 for scalar texture if the extension is available
model.scalarTexture.setOglNorm16Ext(
model.context.getExtension('EXT_texture_norm16')
);

model.scalarTexture.releaseGraphicsResources(model._openGLRenderWindow);
model.scalarTexture.resetFormatAndType();
}

if (reBuildTex || hasUpdatedExtents) {
if (!model.openGLTexture) {
model.openGLTexture = vtkOpenGLTexture.newInstance();
model.openGLTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
}

// If hasUpdatedExtents, then the texture is partially updated
const updatedExtents = [...model.renderable.getUpdatedExtents()];
// clear the array to acknowledge the update.
model.renderable.setUpdatedExtents([]);

// Build the image scalar texture
const dims = image.getDimensions();
// Use norm16 for the 3D texture if the extension is available
model.openGLTexture.setOglNorm16Ext(
model.context.getExtension('EXT_texture_norm16')
);
model.openGLTexture.releaseGraphicsResources(model._openGLRenderWindow);
model.openGLTexture.resetFormatAndType();
model.openGLTexture.create3DFilterableFromDataArray(
dims[0],
dims[1],
dims[2],
scalars
scalars,
false,
updatedExtents
);
if (scalars) {
model._openGLRenderWindow.setGraphicsResourceForObject(
Expand Down
32 changes: 28 additions & 4 deletions Sources/Rendering/OpenGL/Texture/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Wrap, Filter } from './Constants';
import vtkOpenGLRenderWindow from '../RenderWindow';
import { Extent, Nullable } from '../../../types';
import { VtkDataTypes } from "../../../Common/Core/DataArray";
import { VtkDataTypes } from '../../../Common/Core/DataArray';
import { vtkViewNode } from '../../../Rendering/SceneGraph/ViewNode';
import { vtkObject } from '../../../interfaces';

Expand Down Expand Up @@ -268,7 +268,15 @@ export interface vtkOpenGLTexture extends vtkViewNode {
* @param updatedExtents Only update the specified extents (default: [])
* @returns {boolean} True if the texture was successfully created, false otherwise.
*/
create3DFromRaw(width: number, height: number, depth: number, numComps: number, dataType: VtkDataTypes, data: any, updatedExtents?: Extent[]): boolean;
create3DFromRaw(
width: number,
height: number,
depth: number,
numComps: number,
dataType: VtkDataTypes,
data: any,
updatedExtents?: Extent[]
): boolean;

/**
* Creates a 3D filterable texture from raw data, with a preference for size over accuracy if necessary.
Expand All @@ -285,7 +293,16 @@ export interface vtkOpenGLTexture extends vtkViewNode {
* @param updatedExtents Only update the specified extents (default: [])
* @returns {boolean} True if the texture was successfully created, false otherwise.
*/
create3DFilterableFromRaw(width: number, height: number, depth: number, numComps: number, dataType: VtkDataTypes, values: any, preferSizeOverAccuracy: boolean, updatedExtents?: Extent[]): boolean;
create3DFilterableFromRaw(
width: number,
height: number,
depth: number,
numComps: number,
dataType: VtkDataTypes,
values: any,
preferSizeOverAccuracy: boolean,
updatedExtents?: Extent[]
): boolean;

/**
* Creates a 3D filterable texture from a data array, with a preference for size over accuracy if necessary.
Expand All @@ -300,7 +317,14 @@ export interface vtkOpenGLTexture extends vtkViewNode {
* @param updatedExtents Only update the specified extents (default: [])
* @returns {boolean} True if the texture was successfully created, false otherwise.
*/
create3DFilterableFromDataArray(width: number, height: number, depth: number, dataArray: any, preferSizeOverAccuracy: boolean, updatedExtents?: Extent[]): boolean;
create3DFilterableFromDataArray(
width: number,
height: number,
depth: number,
dataArray: any,
preferSizeOverAccuracy: boolean,
updatedExtents?: Extent[]
): boolean;

/**
* Sets the OpenGL render window in which the texture will be used.
Expand Down

0 comments on commit 22fc452

Please sign in to comment.