@kitware/vtk.js 30.3.3 → 30.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Rendering/Core/RenderWindow.d.ts +17 -0
- package/Rendering/Core/RenderWindow.js +11 -2
- package/Rendering/OpenGL/ForwardPass.js +3 -3
- package/Rendering/OpenGL/ImageMapper.js +2 -2
- package/Rendering/OpenGL/RenderWindow.d.ts +38 -9
- package/Rendering/OpenGL/RenderWindow.js +103 -24
- package/Rendering/OpenGL/Renderer.js +2 -2
- package/Rendering/OpenGL/VolumeMapper.js +4 -6
- package/Rendering/SceneGraph/ViewNode.d.ts +10 -2
- package/Rendering/SceneGraph/ViewNode.js +33 -25
- package/Rendering/SceneGraph/ViewNodeFactory.d.ts +0 -8
- package/Rendering/SceneGraph/ViewNodeFactory.js +0 -3
- package/Rendering/WebGPU/RenderWindow.js +4 -4
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ export interface IRenderWindowInitialValues {
|
|
|
9
9
|
interactor?: any,
|
|
10
10
|
neverRendered?: boolean,
|
|
11
11
|
numberOfLayers?: number
|
|
12
|
+
childRenderWindows?: vtkRenderWindow[],
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
interface IStatistics {
|
|
@@ -42,6 +43,12 @@ export interface vtkRenderWindow extends vtkObject {
|
|
|
42
43
|
*/
|
|
43
44
|
addRenderer(renderer: vtkRenderer): void;
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Add a child render window
|
|
48
|
+
* @param {vtkRenderWindow} renderWindow The vtkRenderWindow instance.
|
|
49
|
+
*/
|
|
50
|
+
addRenderWindow(renderWindow: vtkRenderWindow): void;
|
|
51
|
+
|
|
45
52
|
/**
|
|
46
53
|
* Add renderer
|
|
47
54
|
* @param view
|
|
@@ -87,6 +94,16 @@ export interface vtkRenderWindow extends vtkObject {
|
|
|
87
94
|
*/
|
|
88
95
|
getRenderersByReference(): vtkRenderer[];
|
|
89
96
|
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
*/
|
|
100
|
+
getChildRenderWindows(): vtkRenderWindow[];
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
*
|
|
104
|
+
*/
|
|
105
|
+
getChildRenderWindowsByReference(): vtkRenderWindow[];
|
|
106
|
+
|
|
90
107
|
/**
|
|
91
108
|
*
|
|
92
109
|
*/
|
|
@@ -136,6 +136,14 @@ function vtkRenderWindow(publicAPI, model) {
|
|
|
136
136
|
macro.setImmediate(publicAPI.render);
|
|
137
137
|
return model._views.map(view => view.captureNextImage ? view.captureNextImage(format, opts) : undefined).filter(i => !!i);
|
|
138
138
|
};
|
|
139
|
+
publicAPI.addRenderWindow = child => {
|
|
140
|
+
if (model.childRenderWindows.includes(child)) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
model.childRenderWindows.push(child);
|
|
144
|
+
publicAPI.modified();
|
|
145
|
+
return true;
|
|
146
|
+
};
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
// ----------------------------------------------------------------------------
|
|
@@ -148,7 +156,8 @@ const DEFAULT_VALUES = {
|
|
|
148
156
|
views: [],
|
|
149
157
|
interactor: null,
|
|
150
158
|
neverRendered: true,
|
|
151
|
-
numberOfLayers: 1
|
|
159
|
+
numberOfLayers: 1,
|
|
160
|
+
childRenderWindows: []
|
|
152
161
|
};
|
|
153
162
|
|
|
154
163
|
// ----------------------------------------------------------------------------
|
|
@@ -161,7 +170,7 @@ function extend(publicAPI, model) {
|
|
|
161
170
|
macro.obj(publicAPI, model);
|
|
162
171
|
macro.setGet(publicAPI, model, ['interactor', 'numberOfLayers', '_views', 'defaultViewAPI']);
|
|
163
172
|
macro.get(publicAPI, model, ['neverRendered']);
|
|
164
|
-
macro.getArray(publicAPI, model, ['renderers']);
|
|
173
|
+
macro.getArray(publicAPI, model, ['renderers', 'childRenderWindows']);
|
|
165
174
|
macro.moveToProtected(publicAPI, model, ['views']);
|
|
166
175
|
macro.event(publicAPI, model, 'completion');
|
|
167
176
|
|
|
@@ -28,11 +28,11 @@ function vtkForwardPass(publicAPI, model) {
|
|
|
28
28
|
const numlayers = viewNode.getRenderable().getNumberOfLayers();
|
|
29
29
|
|
|
30
30
|
// iterate over renderers
|
|
31
|
-
const renderers = viewNode.
|
|
31
|
+
const renderers = viewNode.getRenderable().getRenderersByReference();
|
|
32
32
|
for (let i = 0; i < numlayers; i++) {
|
|
33
33
|
for (let index = 0; index < renderers.length; index++) {
|
|
34
|
-
const
|
|
35
|
-
const
|
|
34
|
+
const ren = renderers[index];
|
|
35
|
+
const renNode = viewNode.getViewNodeFor(ren);
|
|
36
36
|
if (ren.getDraw() && ren.getLayer() === i) {
|
|
37
37
|
// check for both opaque and volume actors
|
|
38
38
|
model.opaqueActorCount = 0;
|
|
@@ -923,8 +923,8 @@ function vtkOpenGLImageMapper(publicAPI, model) {
|
|
|
923
923
|
// Assuming labelOutlineThicknessArray contains the thickness for each segment
|
|
924
924
|
for (let i = 0; i < lWidth; ++i) {
|
|
925
925
|
// Retrieve the thickness value for the current segment index.
|
|
926
|
-
// If the value is undefined,
|
|
927
|
-
const thickness = labelOutlineThicknessArray[i]
|
|
926
|
+
// If the value is undefined, use the first element's value as a default, otherwise use the value (even if 0)
|
|
927
|
+
const thickness = typeof labelOutlineThicknessArray[i] !== 'undefined' ? labelOutlineThicknessArray[i] : labelOutlineThicknessArray[0];
|
|
928
928
|
lTable[i] = thickness;
|
|
929
929
|
}
|
|
930
930
|
model.labelOutlineThicknessTexture.releaseGraphicsResources(model._openGLRenderWindow);
|
|
@@ -18,6 +18,7 @@ export interface IOpenGLRenderWindowInitialValues {
|
|
|
18
18
|
shaderCache?: null;
|
|
19
19
|
initialized?: boolean;
|
|
20
20
|
context?: WebGLRenderingContext | WebGL2RenderingContext;
|
|
21
|
+
context2D?: CanvasRenderingContext2D;
|
|
21
22
|
canvas?: HTMLCanvasElement;
|
|
22
23
|
cursorVisibility?: boolean;
|
|
23
24
|
cursor?: string;
|
|
@@ -40,13 +41,6 @@ export interface ICaptureOptions {
|
|
|
40
41
|
scale?: number
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
export interface I3DContextOptions {
|
|
44
|
-
preserveDrawingBuffer?: boolean;
|
|
45
|
-
depth?: boolean;
|
|
46
|
-
alpha?: boolean;
|
|
47
|
-
powerPreference?: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
44
|
type vtkOpenGLRenderWindowBase = vtkObject & Omit<vtkAlgorithm,
|
|
51
45
|
| 'getInputData'
|
|
52
46
|
| 'setInputData'
|
|
@@ -228,9 +222,44 @@ export interface vtkOpenGLRenderWindow extends vtkOpenGLRenderWindowBase {
|
|
|
228
222
|
|
|
229
223
|
/**
|
|
230
224
|
*
|
|
231
|
-
* @param {
|
|
225
|
+
* @param {WebGLContextAttributes} options
|
|
226
|
+
*/
|
|
227
|
+
get3DContext(options: WebGLContextAttributes): Nullable<WebGLRenderingContext>;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
*
|
|
231
|
+
* @param {CanvasRenderingContext2DSettings} options
|
|
232
|
+
*/
|
|
233
|
+
get2DContext(options: CanvasRenderingContext2DSettings): Nullable<CanvasRenderingContext2D>;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Copy the content of the root parent, if there is one, to the canvas
|
|
237
|
+
*/
|
|
238
|
+
copyParentContent(): void;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Resize this render window using the size of its children
|
|
242
|
+
* The new size of the renderwindow is the size of the bounding box
|
|
243
|
+
* containing all the child render windows
|
|
244
|
+
*/
|
|
245
|
+
resizeFromChildRenderWindows(): void;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Returns the last ancestor of type vtkOpenGLRenderWindow if there is one
|
|
249
|
+
* If there is no parent vtkOpenGLRenderWindow, returns undefined
|
|
250
|
+
*/
|
|
251
|
+
getRootOpenGLRenderWindow(): vtkOpenGLRenderWindow | undefined;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* The context 2D is created during initialization instead of the WebGL context
|
|
255
|
+
* when there is a parent render window
|
|
256
|
+
*/
|
|
257
|
+
getContext2D(): CanvasRenderingContext2D | undefined;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
*
|
|
232
261
|
*/
|
|
233
|
-
|
|
262
|
+
setContext2D(context2D: CanvasRenderingContext2D | undefined): boolean;
|
|
234
263
|
|
|
235
264
|
/**
|
|
236
265
|
*
|
|
@@ -5,7 +5,7 @@ import vtkForwardPass from './ForwardPass.js';
|
|
|
5
5
|
import vtkHardwareSelector from './HardwareSelector.js';
|
|
6
6
|
import vtkShaderCache from './ShaderCache.js';
|
|
7
7
|
import vtkTextureUnitManager from './TextureUnitManager.js';
|
|
8
|
-
import vtkViewNodeFactory from './ViewNodeFactory.js';
|
|
8
|
+
import vtkViewNodeFactory, { registerOverride } from './ViewNodeFactory.js';
|
|
9
9
|
import vtkRenderPass from '../SceneGraph/RenderPass.js';
|
|
10
10
|
import vtkRenderWindowViewNode from '../SceneGraph/RenderWindowViewNode.js';
|
|
11
11
|
import { createContextProxyHandler } from './RenderWindow/ContextProxy.js';
|
|
@@ -21,6 +21,7 @@ const SCREENSHOT_PLACEHOLDER = {
|
|
|
21
21
|
width: '100%',
|
|
22
22
|
height: '100%'
|
|
23
23
|
};
|
|
24
|
+
const parentMethodsToProxy = ['activateTexture', 'deactivateTexture', 'disableCullFace', 'enableCullFace', 'get3DContext', 'getActiveFramebuffer', 'getContext', 'getDefaultTextureByteSize', 'getDefaultTextureInternalFormat', 'getDefaultToWebgl2', 'getGLInformations', 'getGraphicsMemoryInfo', 'getGraphicsResourceForObject', 'getHardwareMaximumLineWidth', 'getPixelData', 'getShaderCache', 'getTextureUnitForTexture', 'getTextureUnitManager', 'getWebgl2', 'makeCurrent', 'releaseGraphicsResources', 'releaseGraphicsResourcesForObject', 'restoreContext', 'setActiveFramebuffer', 'setContext', 'setDefaultToWebgl2', 'setGraphicsResourceForObject'];
|
|
24
25
|
function checkRenderTargetSupport(gl, format, type) {
|
|
25
26
|
// create temporary frame buffer and texture
|
|
26
27
|
const framebuffer = gl.createFramebuffer();
|
|
@@ -70,7 +71,15 @@ function _preventDefault(e) {
|
|
|
70
71
|
function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
71
72
|
// Set our className
|
|
72
73
|
model.classHierarchy.push('vtkOpenGLRenderWindow');
|
|
73
|
-
|
|
74
|
+
|
|
75
|
+
// Only create a cachingContextHandler if needed
|
|
76
|
+
let cachingContextHandler;
|
|
77
|
+
function getCachingContextHandler() {
|
|
78
|
+
if (!cachingContextHandler) {
|
|
79
|
+
cachingContextHandler = createContextProxyHandler();
|
|
80
|
+
}
|
|
81
|
+
return cachingContextHandler;
|
|
82
|
+
}
|
|
74
83
|
publicAPI.getViewNodeFactory = () => model.myFactory;
|
|
75
84
|
|
|
76
85
|
// prevent default context lost handler
|
|
@@ -117,24 +126,40 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
117
126
|
}
|
|
118
127
|
publicAPI.prepareNodes();
|
|
119
128
|
publicAPI.addMissingNodes(model.renderable.getRenderersByReference());
|
|
129
|
+
publicAPI.addMissingNodes(model.renderable.getChildRenderWindowsByReference());
|
|
120
130
|
publicAPI.removeUnusedNodes();
|
|
121
131
|
publicAPI.initialize();
|
|
122
132
|
model.children.forEach(child => {
|
|
123
|
-
|
|
133
|
+
// Children can be openGl renderer or openGl render windows
|
|
134
|
+
// Only openGl renderers have a method setOpenGLRenderWindow
|
|
135
|
+
child.setOpenGLRenderWindow?.(publicAPI);
|
|
124
136
|
});
|
|
125
137
|
}
|
|
126
138
|
};
|
|
127
139
|
publicAPI.initialize = () => {
|
|
128
140
|
if (!model.initialized) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
model.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
// Set root parent if there is one
|
|
142
|
+
// Some methods of the root parent are proxied (see parentMethodsToProxy)
|
|
143
|
+
model.rootOpenGLRenderWindow = publicAPI.getLastAncestorOfType('vtkOpenGLRenderWindow');
|
|
144
|
+
if (model.rootOpenGLRenderWindow) {
|
|
145
|
+
// Initialize a 2D context that will copy the content of the root parent
|
|
146
|
+
model.context2D = publicAPI.get2DContext();
|
|
147
|
+
} else {
|
|
148
|
+
// Initialize a 3D context that may be used by child render windows
|
|
149
|
+
model.context = publicAPI.get3DContext();
|
|
150
|
+
publicAPI.resizeFromChildRenderWindows();
|
|
151
|
+
if (model.context) {
|
|
152
|
+
createGLContext();
|
|
153
|
+
}
|
|
154
|
+
model.textureUnitManager = vtkTextureUnitManager.newInstance();
|
|
155
|
+
model.textureUnitManager.setContext(model.context);
|
|
156
|
+
model.shaderCache.setContext(model.context);
|
|
157
|
+
// initialize blending for transparency
|
|
158
|
+
const gl = model.context;
|
|
159
|
+
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
160
|
+
gl.depthFunc(gl.LEQUAL);
|
|
161
|
+
gl.enable(gl.BLEND);
|
|
162
|
+
}
|
|
138
163
|
model.initialized = true;
|
|
139
164
|
}
|
|
140
165
|
};
|
|
@@ -213,7 +238,11 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
213
238
|
vtkDebugMacro('using webgl1');
|
|
214
239
|
result = model.canvas.getContext('webgl', options) || model.canvas.getContext('experimental-webgl', options);
|
|
215
240
|
}
|
|
216
|
-
return new Proxy(result,
|
|
241
|
+
return new Proxy(result, getCachingContextHandler());
|
|
242
|
+
};
|
|
243
|
+
publicAPI.get2DContext = function () {
|
|
244
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
245
|
+
return model.canvas.getContext('2d', options);
|
|
217
246
|
};
|
|
218
247
|
publicAPI.restoreContext = () => {
|
|
219
248
|
const rp = vtkRenderPass.newInstance();
|
|
@@ -545,6 +574,37 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
545
574
|
if (model.notifyStartCaptureImage) {
|
|
546
575
|
getCanvasDataURL();
|
|
547
576
|
}
|
|
577
|
+
publicAPI.copyParentContent();
|
|
578
|
+
const childrenRW = model.renderable.getChildRenderWindowsByReference();
|
|
579
|
+
for (let i = 0; i < childrenRW.length; ++i) {
|
|
580
|
+
publicAPI.getViewNodeFor(childrenRW[i])?.traverseAllPasses();
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
publicAPI.copyParentContent = () => {
|
|
584
|
+
const rootParent = model.rootOpenGLRenderWindow;
|
|
585
|
+
if (!rootParent || !model.context2D) {
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
const parentCanvas = rootParent.getCanvas();
|
|
589
|
+
const selfCanvas = model.canvas;
|
|
590
|
+
model.context2D.drawImage(parentCanvas, 0, parentCanvas.height - selfCanvas.height,
|
|
591
|
+
// source y axis is inverted
|
|
592
|
+
selfCanvas.width, selfCanvas.height, 0, 0, selfCanvas.width, selfCanvas.height);
|
|
593
|
+
};
|
|
594
|
+
publicAPI.resizeFromChildRenderWindows = () => {
|
|
595
|
+
// Adapt the size of the parent render window to the child render windows
|
|
596
|
+
const childrenRW = model.renderable.getChildRenderWindowsByReference();
|
|
597
|
+
if (childrenRW.length > 0) {
|
|
598
|
+
const maxSize = [0, 0];
|
|
599
|
+
for (let i = 0; i < childrenRW.length; ++i) {
|
|
600
|
+
const childSize = publicAPI.getViewNodeFor(childrenRW[i])?.getSize();
|
|
601
|
+
if (childSize) {
|
|
602
|
+
maxSize[0] = childSize[0] > maxSize[0] ? childSize[0] : maxSize[0];
|
|
603
|
+
maxSize[1] = childSize[1] > maxSize[1] ? childSize[1] : maxSize[1];
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
publicAPI.setSize(...maxSize);
|
|
607
|
+
}
|
|
548
608
|
};
|
|
549
609
|
publicAPI.disableCullFace = () => {
|
|
550
610
|
if (model.cullFaceEnabled) {
|
|
@@ -593,7 +653,11 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
593
653
|
model.canvas.removeEventListener('webglcontextlost', _preventDefault);
|
|
594
654
|
model.canvas.removeEventListener('webglcontextrestored', publicAPI.restoreContext);
|
|
595
655
|
}
|
|
596
|
-
publicAPI.delete = macro.chain(
|
|
656
|
+
publicAPI.delete = macro.chain(() => {
|
|
657
|
+
if (model.context) {
|
|
658
|
+
deleteGLContext();
|
|
659
|
+
}
|
|
660
|
+
}, clearEvents, publicAPI.delete, publicAPI.setViewStream);
|
|
597
661
|
|
|
598
662
|
// Do not trigger modified for performance reasons
|
|
599
663
|
publicAPI.setActiveFramebuffer = newActiveFramebuffer => {
|
|
@@ -662,6 +726,20 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
662
726
|
glRen?.releaseGraphicsResources();
|
|
663
727
|
});
|
|
664
728
|
};
|
|
729
|
+
|
|
730
|
+
// Proxy some methods if needed
|
|
731
|
+
const publicAPIBeforeProxy = {
|
|
732
|
+
...publicAPI
|
|
733
|
+
};
|
|
734
|
+
parentMethodsToProxy.forEach(methodName => {
|
|
735
|
+
publicAPI[methodName] = function () {
|
|
736
|
+
if (model.rootOpenGLRenderWindow) {
|
|
737
|
+
// Proxy only methods when the render window has a parent
|
|
738
|
+
return model.rootOpenGLRenderWindow[methodName](...arguments);
|
|
739
|
+
}
|
|
740
|
+
return publicAPIBeforeProxy[methodName](...arguments);
|
|
741
|
+
};
|
|
742
|
+
});
|
|
665
743
|
}
|
|
666
744
|
|
|
667
745
|
// ----------------------------------------------------------------------------
|
|
@@ -673,6 +751,7 @@ const DEFAULT_VALUES = {
|
|
|
673
751
|
shaderCache: null,
|
|
674
752
|
initialized: false,
|
|
675
753
|
context: null,
|
|
754
|
+
context2D: null,
|
|
676
755
|
canvas: null,
|
|
677
756
|
cursorVisibility: true,
|
|
678
757
|
cursor: 'pointer',
|
|
@@ -700,9 +779,10 @@ function extend(publicAPI, model) {
|
|
|
700
779
|
vtkRenderWindowViewNode.extend(publicAPI, model, initialValues);
|
|
701
780
|
|
|
702
781
|
// Create internal instances
|
|
703
|
-
model.canvas
|
|
704
|
-
|
|
705
|
-
|
|
782
|
+
if (!model.canvas) {
|
|
783
|
+
model.canvas = document.createElement('canvas');
|
|
784
|
+
model.canvas.style.width = '100%';
|
|
785
|
+
}
|
|
706
786
|
if (!model.selector) {
|
|
707
787
|
model.selector = vtkHardwareSelector.newInstance();
|
|
708
788
|
model.selector.setOpenGLRenderWindow(publicAPI);
|
|
@@ -721,21 +801,17 @@ function extend(publicAPI, model) {
|
|
|
721
801
|
model._graphicsResourceHash = new Map();
|
|
722
802
|
model._glInformation = null;
|
|
723
803
|
model.myFactory = vtkViewNodeFactory.newInstance();
|
|
724
|
-
/* eslint-disable no-use-before-define */
|
|
725
|
-
model.myFactory.registerOverride('vtkRenderWindow', newInstance);
|
|
726
|
-
/* eslint-enable no-use-before-define */
|
|
727
|
-
|
|
728
804
|
model.shaderCache = vtkShaderCache.newInstance();
|
|
729
805
|
model.shaderCache.setOpenGLRenderWindow(publicAPI);
|
|
730
806
|
|
|
731
807
|
// setup default forward pass rendering
|
|
732
808
|
model.renderPasses[0] = vtkForwardPass.newInstance();
|
|
733
|
-
macro.event(publicAPI, model, 'imageReady');
|
|
734
809
|
|
|
735
810
|
// Build VTK API
|
|
736
|
-
macro.get(publicAPI, model, ['shaderCache', 'textureUnitManager', 'webgl2', 'useBackgroundImage', 'activeFramebuffer']);
|
|
737
|
-
macro.setGet(publicAPI, model, ['initialized', 'context', 'canvas', 'renderPasses', 'notifyStartCaptureImage', 'defaultToWebgl2', 'cursor', 'useOffScreen']);
|
|
811
|
+
macro.get(publicAPI, model, ['shaderCache', 'textureUnitManager', 'webgl2', 'useBackgroundImage', 'activeFramebuffer', 'rootOpenGLRenderWindow']);
|
|
812
|
+
macro.setGet(publicAPI, model, ['initialized', 'context', 'context2D', 'canvas', 'renderPasses', 'notifyStartCaptureImage', 'defaultToWebgl2', 'cursor', 'useOffScreen']);
|
|
738
813
|
macro.setGetArray(publicAPI, model, ['size'], 2);
|
|
814
|
+
macro.event(publicAPI, model, 'imageReady');
|
|
739
815
|
macro.event(publicAPI, model, 'windowResizeEvent');
|
|
740
816
|
|
|
741
817
|
// Object methods
|
|
@@ -761,4 +837,7 @@ var vtkRenderWindow = {
|
|
|
761
837
|
popMonitorGLContextCount
|
|
762
838
|
};
|
|
763
839
|
|
|
840
|
+
// Register ourself to OpenGL backend if imported
|
|
841
|
+
registerOverride('vtkRenderWindow', newInstance);
|
|
842
|
+
|
|
764
843
|
export { vtkRenderWindow as default, extend, newInstance, popMonitorGLContextCount, pushMonitorGLContextCount };
|
|
@@ -124,13 +124,13 @@ function vtkOpenGLRenderer(publicAPI, model) {
|
|
|
124
124
|
if (!model.renderable.getTransparent()) {
|
|
125
125
|
const background = model.renderable.getBackgroundByReference();
|
|
126
126
|
// renderable ensures that background has 4 entries.
|
|
127
|
-
|
|
127
|
+
gl.clearColor(background[0], background[1], background[2], background[3]);
|
|
128
128
|
clearMask |= gl.COLOR_BUFFER_BIT;
|
|
129
129
|
}
|
|
130
130
|
if (!model.renderable.getPreserveDepthBuffer()) {
|
|
131
131
|
gl.clearDepth(1.0);
|
|
132
132
|
clearMask |= gl.DEPTH_BUFFER_BIT;
|
|
133
|
-
|
|
133
|
+
gl.depthMask(true);
|
|
134
134
|
}
|
|
135
135
|
gl.colorMask(true, true, true, true);
|
|
136
136
|
const ts = publicAPI.getTiledSizeAndOrigin();
|
|
@@ -1119,7 +1119,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
1119
1119
|
const tex = model._openGLRenderWindow.getGraphicsResourceForObject(scalars);
|
|
1120
1120
|
// rebuild the scalarTexture if the data has changed
|
|
1121
1121
|
toString = `${image.getMTime()}A${scalars.getMTime()}`;
|
|
1122
|
-
const reBuildTex = !tex?.vtkObj || tex?.hash !== toString
|
|
1122
|
+
const reBuildTex = !tex?.vtkObj || tex?.hash !== toString;
|
|
1123
1123
|
if (reBuildTex) {
|
|
1124
1124
|
// Build the textures
|
|
1125
1125
|
const dims = image.getDimensions();
|
|
@@ -1128,13 +1128,11 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
1128
1128
|
model.scalarTexture.releaseGraphicsResources(model._openGLRenderWindow);
|
|
1129
1129
|
model.scalarTexture.resetFormatAndType();
|
|
1130
1130
|
model.scalarTexture.create3DFilterableFromDataArray(dims[0], dims[1], dims[2], scalars, model.renderable.getPreferSizeOverAccuracy());
|
|
1131
|
-
model.scalarTextureString = toString;
|
|
1132
1131
|
if (scalars) {
|
|
1133
|
-
model._openGLRenderWindow.setGraphicsResourceForObject(scalars, model.scalarTexture,
|
|
1132
|
+
model._openGLRenderWindow.setGraphicsResourceForObject(scalars, model.scalarTexture, toString);
|
|
1134
1133
|
}
|
|
1135
1134
|
} else {
|
|
1136
1135
|
model.scalarTexture = tex.vtkObj;
|
|
1137
|
-
model.scalarTextureString = tex.hash;
|
|
1138
1136
|
}
|
|
1139
1137
|
if (!model.tris.getCABO().getElementCount()) {
|
|
1140
1138
|
// build the CABO
|
|
@@ -1214,8 +1212,8 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
1214
1212
|
// Assuming labelOutlineThicknessArray contains the thickness for each segment
|
|
1215
1213
|
for (let i = 0; i < lWidth; ++i) {
|
|
1216
1214
|
// Retrieve the thickness value for the current segment index.
|
|
1217
|
-
// If the value is undefined,
|
|
1218
|
-
const thickness = labelOutlineThicknessArray[i]
|
|
1215
|
+
// If the value is undefined, use the first element's value as a default, otherwise use the value (even if 0)
|
|
1216
|
+
const thickness = typeof labelOutlineThicknessArray[i] !== 'undefined' ? labelOutlineThicknessArray[i] : labelOutlineThicknessArray[0];
|
|
1219
1217
|
lTable[i] = thickness;
|
|
1220
1218
|
}
|
|
1221
1219
|
model.labelOutlineThicknessTexture.releaseGraphicsResources(model._openGLRenderWindow);
|
|
@@ -20,10 +20,12 @@ export interface IViewNodeInitialValues {
|
|
|
20
20
|
export interface vtkViewNode extends vtkObject {
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Add a child view node to this node, created from the renderable given as argument
|
|
24
|
+
* If the node creation fails or the argument is falsy, returns undefined
|
|
25
|
+
* Otherwise, returns the newly created node or the existing node
|
|
24
26
|
* @param dobj
|
|
25
27
|
*/
|
|
26
|
-
addMissingNode(dobj: any):
|
|
28
|
+
addMissingNode(dobj: any): vtkViewNode | undefined;
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
*
|
|
@@ -66,6 +68,12 @@ export interface vtkViewNode extends vtkObject {
|
|
|
66
68
|
*/
|
|
67
69
|
getFirstAncestorOfType(type: any): void;
|
|
68
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Find the last parent/grandparent of the desired type
|
|
73
|
+
* @param type
|
|
74
|
+
*/
|
|
75
|
+
getLastAncestorOfType(type: any): void;
|
|
76
|
+
|
|
69
77
|
/**
|
|
70
78
|
*
|
|
71
79
|
*/
|
|
@@ -63,27 +63,44 @@ function vtkViewNode(publicAPI, model) {
|
|
|
63
63
|
}
|
|
64
64
|
return model._parent.getFirstAncestorOfType(type);
|
|
65
65
|
};
|
|
66
|
+
publicAPI.getLastAncestorOfType = type => {
|
|
67
|
+
if (!model._parent) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const lastAncestor = model._parent.getLastAncestorOfType(type);
|
|
71
|
+
if (lastAncestor) {
|
|
72
|
+
return lastAncestor;
|
|
73
|
+
}
|
|
74
|
+
if (model._parent.isA(type)) {
|
|
75
|
+
return model._parent;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
};
|
|
66
79
|
|
|
67
80
|
// add a missing node/child for the passed in renderables. This should
|
|
68
81
|
// be called only in between prepareNodes and removeUnusedNodes
|
|
69
82
|
publicAPI.addMissingNode = dobj => {
|
|
70
83
|
if (!dobj) {
|
|
71
|
-
return;
|
|
84
|
+
return undefined;
|
|
72
85
|
}
|
|
73
|
-
|
|
86
|
+
|
|
74
87
|
// if found just mark as visited
|
|
88
|
+
const result = model._renderableChildMap.get(dobj);
|
|
75
89
|
if (result !== undefined) {
|
|
76
90
|
result.setVisited(true);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// otherwise create a node
|
|
95
|
+
const newNode = publicAPI.createViewNode(dobj);
|
|
96
|
+
if (newNode) {
|
|
97
|
+
newNode.setParent(publicAPI);
|
|
98
|
+
newNode.setVisited(true);
|
|
99
|
+
model._renderableChildMap.set(dobj, newNode);
|
|
100
|
+
model.children.push(newNode);
|
|
101
|
+
return newNode;
|
|
86
102
|
}
|
|
103
|
+
return undefined;
|
|
87
104
|
};
|
|
88
105
|
|
|
89
106
|
// add missing nodes/children for the passed in renderables. This should
|
|
@@ -94,20 +111,7 @@ function vtkViewNode(publicAPI, model) {
|
|
|
94
111
|
}
|
|
95
112
|
for (let index = 0; index < dataObjs.length; ++index) {
|
|
96
113
|
const dobj = dataObjs[index];
|
|
97
|
-
|
|
98
|
-
// if found just mark as visited
|
|
99
|
-
if (result !== undefined) {
|
|
100
|
-
result.setVisited(true);
|
|
101
|
-
} else {
|
|
102
|
-
// otherwise create a node
|
|
103
|
-
const newNode = publicAPI.createViewNode(dobj);
|
|
104
|
-
if (newNode) {
|
|
105
|
-
newNode.setParent(publicAPI);
|
|
106
|
-
newNode.setVisited(true);
|
|
107
|
-
model._renderableChildMap.set(dobj, newNode);
|
|
108
|
-
model.children.push(newNode);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
114
|
+
publicAPI.addMissingNode(dobj);
|
|
111
115
|
}
|
|
112
116
|
};
|
|
113
117
|
|
|
@@ -125,6 +129,10 @@ function vtkViewNode(publicAPI, model) {
|
|
|
125
129
|
if (cindex === -1) {
|
|
126
130
|
child.setParent(publicAPI);
|
|
127
131
|
model.children.push(child);
|
|
132
|
+
const childRenderable = child.getRenderable();
|
|
133
|
+
if (childRenderable) {
|
|
134
|
+
model._renderableChildMap.set(childRenderable, child);
|
|
135
|
+
}
|
|
128
136
|
}
|
|
129
137
|
child.setVisited(true);
|
|
130
138
|
}
|
|
@@ -12,14 +12,6 @@ export interface vtkViewNodeFactory extends vtkObject {
|
|
|
12
12
|
* @param dataObject
|
|
13
13
|
*/
|
|
14
14
|
createNode(dataObject: any): void;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Give a function pointer to a class that will manufacture a vtkViewNode
|
|
18
|
-
* when given a class name string.
|
|
19
|
-
* @param className
|
|
20
|
-
* @param func
|
|
21
|
-
*/
|
|
22
|
-
registerOverride(className: any, func: any): void;
|
|
23
15
|
}
|
|
24
16
|
|
|
25
17
|
/**
|
|
@@ -34,9 +34,6 @@ function vtkViewNodeFactory(publicAPI, model) {
|
|
|
34
34
|
vn.setMyFactory(publicAPI);
|
|
35
35
|
return vn;
|
|
36
36
|
};
|
|
37
|
-
publicAPI.registerOverride = (className, func) => {
|
|
38
|
-
model.overrides[className] = func;
|
|
39
|
-
};
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
// ----------------------------------------------------------------------------
|
|
@@ -4,7 +4,7 @@ import vtkForwardPass from './ForwardPass.js';
|
|
|
4
4
|
import vtkWebGPUBuffer from './Buffer.js';
|
|
5
5
|
import vtkWebGPUDevice from './Device.js';
|
|
6
6
|
import vtkWebGPUHardwareSelector from './HardwareSelector.js';
|
|
7
|
-
import vtkWebGPUViewNodeFactory from './ViewNodeFactory.js';
|
|
7
|
+
import vtkWebGPUViewNodeFactory, { registerOverride } from './ViewNodeFactory.js';
|
|
8
8
|
import vtkRenderPass from '../SceneGraph/RenderPass.js';
|
|
9
9
|
import vtkRenderWindowViewNode from '../SceneGraph/RenderWindowViewNode.js';
|
|
10
10
|
import HalfFloat from '../../Common/Core/HalfFloat.js';
|
|
@@ -549,9 +549,6 @@ function extend(publicAPI, model) {
|
|
|
549
549
|
// Inheritance
|
|
550
550
|
vtkRenderWindowViewNode.extend(publicAPI, model, initialValues);
|
|
551
551
|
model.myFactory = vtkWebGPUViewNodeFactory.newInstance();
|
|
552
|
-
/* eslint-disable no-use-before-define */
|
|
553
|
-
model.myFactory.registerOverride('vtkRenderWindow', newInstance);
|
|
554
|
-
/* eslint-enable no-use-before-define */
|
|
555
552
|
|
|
556
553
|
// setup default forward pass rendering
|
|
557
554
|
model.renderPasses[0] = vtkForwardPass.newInstance();
|
|
@@ -589,4 +586,7 @@ var vtkRenderWindow = {
|
|
|
589
586
|
extend
|
|
590
587
|
};
|
|
591
588
|
|
|
589
|
+
// Register ourself to WebGPU backend if imported
|
|
590
|
+
registerOverride('vtkRenderWindow', newInstance);
|
|
591
|
+
|
|
592
592
|
export { vtkRenderWindow as default, extend, newInstance };
|