RenderWindow

Introduction

vtkRenderWindow is an abstract object to specify the behavior of a rendering window.

A rendering window is a window in a graphical user interface where renderers draw their images.
Methods are provided to synchronize the rendering process, set window size, and control double buffering.
The window also allows rendering in stereo. The interlaced render stereo type is for output to a VRex stereo projector.
All of the odd horizontal lines are from the left eye, and the even lines are from the right eye.
The user has to make the render window aligned with the VRex projector, or the eye will be swapped.

Methods

addRenderWindow

Add a child render window

Argument Type Required Description
renderWindow vtkRenderWindow Yes The vtkRenderWindow instance.

addRenderer

Add renderer

Argument Type Required Description
renderer vtkRenderer Yes The vtkRenderer instance.

addView

Add renderer

Argument Type Required Description
view Yes

captureImages

Argument Type Required Description
format String Yes
opts any Yes

extend

Method use to decorate a given object (publicAPI+model) with vtkRenderWindow characteristics.

Argument Type Required Description
publicAPI Yes object on which methods will be bounds (public)
model Yes object on which data structure will be bounds (protected)
initialValues IRenderWindowInitialValues No (default: {})

getChildRenderWindows

getChildRenderWindowsByReference

getDefaultViewAPI

Switch the rendering backend between WebGL and WebGPU.
By default, the WebGL backend is used. To switch, to WebGPU call
renderWindow.setDefaultViewAPI('WebGPU') before calling render.

getInteractor

getNeverRendered

getNumberOfLayers

getRenderers

getRenderersByReference

getStatistics

getViews

hasRenderer

Argument Type Required Description
ren vtkRenderer Yes

hasView

Argument Type Required Description
view Yes

invisiblePropCount

listViewAPIs

newAPISpecificView

newAPISpecificView

Argument Type Required Description
name String Yes
{} Yes [initialValues]

newInstance

Method use to create a new instance of vtkRenderWindow

onCompletion

Argument Type Required Description
callback Yes

propCount

registerViewConstructor

removeRenderWindow

Remove a child render window added using addRenderWindow(renderWindow)

Argument Type Required Description
renderWindow vtkRenderWindow Yes The vtkRenderWindow instance.

removeRenderer

Remove renderer

Argument Type Required Description
renderer vtkRenderer Yes The vtkRenderer instance.

removeView

Remove renderer

Argument Type Required Description
view Yes

render

setDefaultViewAPI

Switch the rendering backend between WebGL and WebGPU.
By default, the WebGL backend is used. To switch, to WebGPU call
renderWindow.setDefaultViewAPI('WebGPU') before calling render.
Must be called before newAPISpecificView() is called.

Argument Type Required Description
defaultViewAPI Yes (default: ‘WebGL’)

setInteractor

Argument Type Required Description
interactor Yes

setNumberOfLayers

Argument Type Required Description
numberOfLayers Yes

setViews

Argument Type Required Description
views Yes

str

Source

index.d.ts
import { vtkObject, vtkSubscription } from '../../../interfaces';
import vtkRenderer from '../Renderer';
import vtkRenderWindowInteractor from '../RenderWindowInteractor';
// import vtkOpenGLRenderWindow from "../../../OpenGL/RenderWindow";

export interface IRenderWindowInitialValues {
renderers?: vtkRenderer[];
views?: vtkRenderWindow[];
interactor?: any;
neverRendered?: boolean;
numberOfLayers?: number;
childRenderWindows?: vtkRenderWindow[];
}

interface IStatistics {
/**
*
*/
propCount: number;

/**
*
*/
invisiblePropCount: number;

/**
*
*/
str: string;
}

export const enum DEFAULT_VIEW_API {
'WebGL',
'WebGPU',
}

export interface vtkRenderWindow extends vtkObject {
/**
* Add renderer
* @param {vtkRenderer} renderer The vtkRenderer instance.
*/
addRenderer(renderer: vtkRenderer): void;

/**
* Add a child render window
* @param {vtkRenderWindow} renderWindow The vtkRenderWindow instance.
*/
addRenderWindow(renderWindow: vtkRenderWindow): void;

/**
* Add renderer
* @param view
*/
addView(view: any): void;

/**
*
* @param {String} format
* @param {*} opts
*/
captureImages(format?: string, opts?: any): Promise<string>[];

/**
* Switch the rendering backend between WebGL and WebGPU.
* By default, the WebGL backend is used. To switch, to WebGPU call
* `renderWindow.setDefaultViewAPI('WebGPU')` before calling `render`.
*/
getDefaultViewAPI(): string;

/**
*
*/
getInteractor(): vtkRenderWindowInteractor;

/**
*
*/
getNumberOfLayers(): number;

/**
*
*/
getNeverRendered(): boolean;

/**
*
*/
getRenderers(): vtkRenderer[];

/**
*
*/
getRenderersByReference(): vtkRenderer[];

/**
*
*/
getChildRenderWindows(): vtkRenderWindow[];

/**
*
*/
getChildRenderWindowsByReference(): vtkRenderWindow[];

/**
*
*/
getStatistics(): IStatistics;

/**
*
*/
getViews(): any[];

// getViews(): vtkOpenGLRenderWindow[];

/**
*
* @param {vtkRenderer} ren
* @return {Boolean} true if the windows has a renderer
*/
hasRenderer(ren: vtkRenderer): boolean;

/**
*
* @param view
*/
hasView(view: any): boolean;

//hasView(view: vtkOpenGLRenderWindow): boolean;

/**
*
* @param callback
*/
onCompletion(callback: (instance: vtkObject) => any): vtkSubscription;

/**
*
* @param {String} name
* @param {} [initialValues]
*/
newAPISpecificView(name: string, initialValues?: object): any;

/**
* Remove renderer
* @param {vtkRenderer} renderer The vtkRenderer instance.
*/
removeRenderer(renderer: vtkRenderer): void;

/**
* Remove a child render window added using addRenderWindow(renderWindow)
* @param {vtkRenderWindow} renderWindow The vtkRenderWindow instance.
*/
removeRenderWindow(renderWindow: vtkRenderWindow): boolean;

/**
* Remove renderer
* @param view
*/
removeView(view: any): void;

/**
*
*/
render(): void;

/**
* Switch the rendering backend between WebGL and WebGPU.
* By default, the WebGL backend is used. To switch, to WebGPU call
* `renderWindow.setDefaultViewAPI('WebGPU')` before calling `render`.
* Must be called before `newAPISpecificView()` is called.
* @param defaultViewAPI (default: 'WebGL')
*/
setDefaultViewAPI(defaultViewAPI: DEFAULT_VIEW_API): boolean;

/**
*
* @param interactor
*/
setInteractor(interactor: vtkRenderWindowInteractor): boolean;

/**
*
* @param numberOfLayers
*/
setNumberOfLayers(numberOfLayers: number): boolean;

/**
*
* @param views
*/
setViews(views: any[]): boolean;

// setViews(views: vtkOpenGLRenderWindow[]): boolean;
}

/**
* Method use to decorate a given object (publicAPI+model) with vtkRenderWindow characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {IRenderWindowInitialValues} [initialValues] (default: {})
*/
export function extend(
publicAPI: object,
model: object,
initialValues?: IRenderWindowInitialValues
): void;

/**
* Method use to create a new instance of vtkRenderWindow
*/
export function newInstance(
initialValues?: IRenderWindowInitialValues
): vtkRenderWindow;

/**
*
*/
export function registerViewConstructor(name: string, constructor: any): void;

/**
*
*/
export function listViewAPIs(): string[];

/**
*
*/
export function newAPISpecificView(name: string, initialValues: object): any;

/**
* vtkRenderWindow is an abstract object to specify the behavior of a rendering window.
*
* A rendering window is a window in a graphical user interface where renderers draw their images.
* Methods are provided to synchronize the rendering process, set window size, and control double buffering.
* The window also allows rendering in stereo. The interlaced render stereo type is for output to a VRex stereo projector.
* All of the odd horizontal lines are from the left eye, and the even lines are from the right eye.
* The user has to make the render window aligned with the VRex projector, or the eye will be swapped.
*/
export declare const vtkRenderWindow: {
newInstance: typeof newInstance;
extend: typeof extend;
registerViewConstructor: typeof registerViewConstructor;
listViewAPIs: typeof listViewAPIs;
newAPISpecificView: typeof newAPISpecificView;
};
export default vtkRenderWindow;
index.js
import macro from 'vtk.js/Sources/macros';

const DEFAULT_VIEW_API = 'WebGL';
const VIEW_CONSTRUCTORS = Object.create(null);

// ----------------------------------------------------------------------------
// static methods
// ----------------------------------------------------------------------------

export function registerViewConstructor(name, constructor) {
VIEW_CONSTRUCTORS[name] = constructor;
}

export function listViewAPIs() {
return Object.keys(VIEW_CONSTRUCTORS);
}

export function newAPISpecificView(name, initialValues = {}) {
return VIEW_CONSTRUCTORS[name] && VIEW_CONSTRUCTORS[name](initialValues);
}

// ----------------------------------------------------------------------------
// vtkRenderWindow methods
// ----------------------------------------------------------------------------

function vtkRenderWindow(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkRenderWindow');

// Add renderer
publicAPI.addRenderer = (renderer) => {
if (publicAPI.hasRenderer(renderer)) {
return;
}
renderer.setRenderWindow(publicAPI);
model.renderers.push(renderer);

// for (this->Renderers->InitTraversal(rsit);
// (aren = this->Renderers->GetNextRenderer(rsit)); )
// {
// aren->SetAllocatedRenderTime
// (1.0/(this->DesiredUpdateRate*this->Renderers->GetNumberOfItems()));
// }

publicAPI.modified();
};

// Remove renderer
publicAPI.removeRenderer = (renderer) => {
model.renderers = model.renderers.filter((r) => r !== renderer);
publicAPI.modified();
};

publicAPI.hasRenderer = (ren) => model.renderers.indexOf(ren) !== -1;

// get an API specific view of this data
publicAPI.newAPISpecificView = (name, initialValues = {}) =>
newAPISpecificView(name || model.defaultViewAPI, initialValues);

// Add renderer
publicAPI.addView = (view) => {
if (publicAPI.hasView(view)) {
return;
}
view.setRenderable(publicAPI);
model._views.push(view);
publicAPI.modified();
};

// Remove renderer
publicAPI.removeView = (view) => {
model._views = model._views.filter((r) => r !== view);
publicAPI.modified();
};

publicAPI.hasView = (view) => model._views.indexOf(view) !== -1;

// handle any pre render initializations
publicAPI.preRender = () => {
model.renderers.forEach((ren) => {
// make sure we have a camera
if (!ren.isActiveCameraCreated()) {
ren.resetCamera();
}
});
};

publicAPI.render = () => {
publicAPI.preRender();
if (model.interactor) {
model.interactor.render();
} else {
model._views.forEach((view) => view.traverseAllPasses());
}
};

publicAPI.getStatistics = () => {
const results = { propCount: 0, invisiblePropCount: 0, gpuMemoryMB: 0 };
model._views.forEach((v) => {
if (v.getGraphicsMemoryInfo)
results.gpuMemoryMB += v.getGraphicsMemoryInfo() / 1e6;
});
model.renderers.forEach((ren) => {
const props = ren.getViewProps();
const gren = model._views[0].getViewNodeFor(ren);
props.forEach((prop) => {
if (prop.getVisibility()) {
results.propCount += 1;
const mpr = prop.getMapper && prop.getMapper();
if (mpr && mpr.getPrimitiveCount) {
const gmpr = gren.getViewNodeFor(mpr);
if (gmpr) {
if (gmpr.getAllocatedGPUMemoryInBytes) {
results.gpuMemoryMB +=
gmpr.getAllocatedGPUMemoryInBytes() / 1e6;
}
const pcount = mpr.getPrimitiveCount();
Object.keys(pcount).forEach((keyName) => {
if (!results[keyName]) {
results[keyName] = 0;
}
results[keyName] += pcount[keyName];
});
}
}
} else {
results.invisiblePropCount += 1;
}
});
});
results.str = Object.keys(results)
.map((keyName) => `${keyName}: ${results[keyName]}`)
.join('\n');

return results;
};

publicAPI.captureImages = (format = 'image/png', opts = {}) => {
macro.setImmediate(publicAPI.render);
return model._views
.map((view) =>
view.captureNextImage ? view.captureNextImage(format, opts) : undefined
)
.filter((i) => !!i);
};

publicAPI.addRenderWindow = (child) => {
if (model.childRenderWindows.includes(child)) {
return false;
}
model.childRenderWindows.push(child);
publicAPI.modified();
return true;
};

publicAPI.removeRenderWindow = (child) => {
const childIndex = model.childRenderWindows.findIndex((x) => x === child);
if (childIndex < 0) {
return false;
}
model.childRenderWindows.splice(childIndex, 1);
publicAPI.modified();
return true;
};
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
defaultViewAPI: DEFAULT_VIEW_API,
renderers: [],
views: [],
interactor: null,
neverRendered: true,
numberOfLayers: 1,
childRenderWindows: [],
};

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

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

// Build VTK API
macro.obj(publicAPI, model);

macro.setGet(publicAPI, model, [
'interactor',
'numberOfLayers',
'_views',
'defaultViewAPI',
]);
macro.get(publicAPI, model, ['neverRendered']);
macro.getArray(publicAPI, model, ['renderers', 'childRenderWindows']);
macro.moveToProtected(publicAPI, model, ['views']);
macro.event(publicAPI, model, 'completion');

// Object methods
vtkRenderWindow(publicAPI, model);
}

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

export const newInstance = macro.newInstance(extend, 'vtkRenderWindow');

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

export default {
newInstance,
extend,
registerViewConstructor,
listViewAPIs,
newAPISpecificView,
};