@@ -41,6 +41,13 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
41
41
// Set our className
42
42
model . classHierarchy . push ( 'vtkOpenGLImageCPRMapper' ) ;
43
43
44
+ function unregisterGraphicsResources ( renderWindow ) {
45
+ [ model . _scalars , model . _colorTransferFunc , model . _pwFunc ] . forEach (
46
+ ( coreObject ) =>
47
+ renderWindow . unregisterGraphicsResourceUser ( coreObject , publicAPI )
48
+ ) ;
49
+ }
50
+
44
51
publicAPI . buildPass = ( prepass ) => {
45
52
if ( prepass ) {
46
53
model . currentRenderPass = null ;
@@ -49,18 +56,23 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
49
56
) ;
50
57
model . _openGLRenderer =
51
58
publicAPI . getFirstAncestorOfType ( 'vtkOpenGLRenderer' ) ;
59
+ const oldOglRenderWindow = model . _openGLRenderWindow ;
52
60
model . _openGLRenderWindow = model . _openGLRenderer . getLastAncestorOfType (
53
61
'vtkOpenGLRenderWindow'
54
62
) ;
63
+ if (
64
+ oldOglRenderWindow &&
65
+ ! oldOglRenderWindow . isDeleted ( ) &&
66
+ oldOglRenderWindow !== model . _openGLRenderWindow
67
+ ) {
68
+ unregisterGraphicsResources ( oldOglRenderWindow ) ;
69
+ }
55
70
model . context = model . _openGLRenderWindow . getContext ( ) ;
56
71
model . openGLCamera = model . _openGLRenderer . getViewNodeFor (
57
72
model . _openGLRenderer . getRenderable ( ) . getActiveCamera ( )
58
73
) ;
59
74
60
75
model . tris . setOpenGLRenderWindow ( model . _openGLRenderWindow ) ;
61
- model . volumeTexture . setOpenGLRenderWindow ( model . _openGLRenderWindow ) ;
62
- model . colorTexture . setOpenGLRenderWindow ( model . _openGLRenderWindow ) ;
63
- model . pwfTexture . setOpenGLRenderWindow ( model . _openGLRenderWindow ) ;
64
76
}
65
77
} ;
66
78
@@ -147,30 +159,8 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
147
159
if ( publicAPI . getNeedToRebuildBufferObjects ( ren , actor ) ) {
148
160
publicAPI . buildBufferObjects ( ren , actor ) ;
149
161
}
150
- } ;
151
-
152
- publicAPI . getNeedToRebuildBufferObjects = ( ren , actor ) => {
153
- // first do a coarse check
154
- // Note that the actor's mtime includes it's properties mtime
155
- const vmtime = model . VBOBuildTime . getMTime ( ) ;
156
- if (
157
- vmtime < publicAPI . getMTime ( ) ||
158
- vmtime < model . renderable . getMTime ( ) ||
159
- vmtime < actor . getMTime ( ) ||
160
- vmtime < model . currentImageDataInput . getMTime ( ) ||
161
- vmtime < model . currentCenterlineInput . getMTime ( )
162
- ) {
163
- return true ;
164
- }
165
- return false ;
166
- } ;
167
-
168
- publicAPI . buildBufferObjects = ( ren , actor ) => {
169
- const image = model . currentImageDataInput ;
170
- const centerline = model . currentCenterlineInput ;
171
- const actorProperty = actor . getProperty ( ) ;
172
-
173
162
// Set interpolation on the texture based on property setting
163
+ const actorProperty = actor . getProperty ( ) ;
174
164
if ( actorProperty . getInterpolationType ( ) === InterpolationType . NEAREST ) {
175
165
model . volumeTexture . setMinificationFilter ( Filter . NEAREST ) ;
176
166
model . volumeTexture . setMagnificationFilter ( Filter . NEAREST ) ;
@@ -186,61 +176,104 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
186
176
model . pwfTexture . setMinificationFilter ( Filter . LINEAR ) ;
187
177
model . pwfTexture . setMagnificationFilter ( Filter . LINEAR ) ;
188
178
}
179
+ } ;
180
+
181
+ publicAPI . getNeedToRebuildBufferObjects = ( ren , actor ) => {
182
+ // first do a coarse check
183
+ // Note that the actor's mtime includes it's properties mtime
184
+ const vmtime = model . VBOBuildTime . getMTime ( ) ;
185
+ return (
186
+ vmtime < publicAPI . getMTime ( ) ||
187
+ vmtime < model . renderable . getMTime ( ) ||
188
+ vmtime < actor . getMTime ( ) ||
189
+ vmtime < model . currentImageDataInput . getMTime ( ) ||
190
+ vmtime < model . currentCenterlineInput . getMTime ( ) ||
191
+ ! model . volumeTexture ?. getHandle ( )
192
+ ) ;
193
+ } ;
194
+
195
+ publicAPI . buildBufferObjects = ( ren , actor ) => {
196
+ const image = model . currentImageDataInput ;
197
+ const centerline = model . currentCenterlineInput ;
189
198
190
199
// Rebuild the volumeTexture if the data has changed
191
- const imageTime = image . getMTime ( ) ;
192
- if ( model . volumeTextureTime !== imageTime ) {
200
+ const scalars = image ?. getPointData ( ) ?. getScalars ( ) ;
201
+ if ( ! scalars ) {
202
+ return ;
203
+ }
204
+ const cachedScalarsEntry =
205
+ model . _openGLRenderWindow . getGraphicsResourceForObject ( scalars ) ;
206
+ const volumeTextureHash = `${ image . getMTime ( ) } A${ scalars . getMTime ( ) } ` ;
207
+ const reBuildTex =
208
+ ! cachedScalarsEntry ?. oglObject ?. getHandle ( ) ||
209
+ cachedScalarsEntry ?. hash !== volumeTextureHash ;
210
+ if ( reBuildTex ) {
211
+ model . volumeTexture = vtkOpenGLTexture . newInstance ( ) ;
212
+ model . volumeTexture . setOpenGLRenderWindow ( model . _openGLRenderWindow ) ;
193
213
// Build the textures
194
214
const dims = image . getDimensions ( ) ;
195
- const scalars = image . getPointData ( ) . getScalars ( ) ;
196
- if ( ! scalars ) {
197
- return ;
198
- }
199
215
// Use norm16 for scalar texture if the extension is available
200
216
model . volumeTexture . setOglNorm16Ext (
201
217
model . context . getExtension ( 'EXT_texture_norm16' )
202
218
) ;
203
- model . volumeTexture . releaseGraphicsResources ( model . _openGLRenderWindow ) ;
204
219
model . volumeTexture . resetFormatAndType ( ) ;
205
- model . volumeTexture . create3DFilterableFromRaw (
220
+ model . volumeTexture . create3DFilterableFromDataArray (
206
221
dims [ 0 ] ,
207
222
dims [ 1 ] ,
208
223
dims [ 2 ] ,
209
- scalars . getNumberOfComponents ( ) ,
210
- scalars . getDataType ( ) ,
211
- scalars . getData ( ) ,
224
+ scalars ,
212
225
model . renderable . getPreferSizeOverAccuracy ( )
213
226
) ;
214
- model . volumeTextureTime = imageTime ;
227
+ model . _openGLRenderWindow . setGraphicsResourceForObject (
228
+ scalars ,
229
+ model . volumeTexture ,
230
+ volumeTextureHash
231
+ ) ;
232
+ if ( scalars !== model . _scalars ) {
233
+ model . _openGLRenderWindow . registerGraphicsResourceUser (
234
+ scalars ,
235
+ publicAPI
236
+ ) ;
237
+ model . _openGLRenderWindow . unregisterGraphicsResourceUser (
238
+ model . _scalars ,
239
+ publicAPI
240
+ ) ;
241
+ }
242
+ model . _scalars = scalars ;
243
+ } else {
244
+ model . volumeTexture = cachedScalarsEntry . oglObject ;
215
245
}
216
246
217
247
// Rebuild the color texture if needed
218
- const scalars = image . getPointData ( ) && image . getPointData ( ) . getScalars ( ) ;
219
- if ( ! scalars ) {
220
- return ;
221
- }
222
248
const numComp = scalars . getNumberOfComponents ( ) ;
223
249
const ppty = actor . getProperty ( ) ;
224
250
const iComps = ppty . getIndependentComponents ( ) ;
225
251
const numIComps = iComps ? numComp : 1 ;
226
252
const textureHeight = iComps ? 2 * numIComps : 1 ;
227
253
228
- const cfunToString = computeFnToString (
254
+ const colorTransferFunc = ppty . getRGBTransferFunction ( ) ;
255
+ const colorTextureHash = computeFnToString (
229
256
ppty ,
230
257
ppty . getRGBTransferFunction ,
231
258
numIComps
232
259
) ;
233
260
234
- if ( model . colorTextureString !== cfunToString ) {
261
+ const cachedColorEntry =
262
+ model . _openGLRenderWindow . getGraphicsResourceForObject ( colorTransferFunc ) ;
263
+ const reBuildColorTexture =
264
+ ! cachedColorEntry ?. oglObject ?. getHandle ( ) ||
265
+ cachedColorEntry ?. hash !== colorTextureHash ;
266
+ if ( reBuildColorTexture ) {
235
267
const cWidth = 1024 ;
236
268
const cSize = cWidth * textureHeight * 3 ;
237
269
const cTable = new Uint8ClampedArray ( cSize ) ;
238
- let cfun = ppty . getRGBTransferFunction ( ) ;
239
- if ( cfun ) {
270
+ model . colorTexture = vtkOpenGLTexture . newInstance ( ) ;
271
+ model . colorTexture . setOpenGLRenderWindow ( model . _openGLRenderWindow ) ;
272
+ if ( colorTransferFunc ) {
240
273
const tmpTable = new Float32Array ( cWidth * 3 ) ;
241
274
242
275
for ( let c = 0 ; c < numIComps ; c ++ ) {
243
- cfun = ppty . getRGBTransferFunction ( c ) ;
276
+ const cfun = ppty . getRGBTransferFunction ( c ) ;
244
277
const cRange = cfun . getRange ( ) ;
245
278
cfun . getTable ( cRange [ 0 ] , cRange [ 1 ] , cWidth , tmpTable , 1 ) ;
246
279
if ( iComps ) {
@@ -254,7 +287,6 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
254
287
}
255
288
}
256
289
}
257
- model . colorTexture . releaseGraphicsResources ( model . _openGLRenderWindow ) ;
258
290
model . colorTexture . resetFormatAndType ( ) ;
259
291
model . colorTexture . create2DFromRaw (
260
292
cWidth ,
@@ -269,6 +301,7 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
269
301
cTable [ i + 1 ] = ( 255.0 * i ) / ( ( cWidth - 1 ) * 3 ) ;
270
302
cTable [ i + 2 ] = ( 255.0 * i ) / ( ( cWidth - 1 ) * 3 ) ;
271
303
}
304
+ model . colorTexture . resetFormatAndType ( ) ;
272
305
model . colorTexture . create2DFromRaw (
273
306
cWidth ,
274
307
1 ,
@@ -278,32 +311,54 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
278
311
) ;
279
312
}
280
313
281
- model . colorTextureString = cfunToString ;
314
+ if ( colorTransferFunc ) {
315
+ model . _openGLRenderWindow . setGraphicsResourceForObject (
316
+ colorTransferFunc ,
317
+ model . colorTexture ,
318
+ colorTextureHash
319
+ ) ;
320
+ if ( colorTransferFunc !== model . _colorTransferFunc ) {
321
+ model . _openGLRenderWindow . registerGraphicsResourceUser (
322
+ colorTransferFunc ,
323
+ publicAPI
324
+ ) ;
325
+ model . _openGLRenderWindow . unregisterGraphicsResourceUser (
326
+ model . _colorTransferFunc ,
327
+ publicAPI
328
+ ) ;
329
+ }
330
+ model . _colorTransferFunc = colorTransferFunc ;
331
+ }
332
+ } else {
333
+ model . colorTexture = cachedColorEntry . oglObject ;
282
334
}
283
335
284
336
// Build piecewise function buffer. This buffer is used either
285
337
// for component weighting or opacity, depending on whether we're
286
338
// rendering components independently or not.
287
- const pwfunToString = computeFnToString (
339
+ const pwFunc = ppty . getPiecewiseFunction ( ) ;
340
+ const pwfTextureHash = computeFnToString (
288
341
ppty ,
289
342
ppty . getPiecewiseFunction ,
290
343
numIComps
291
344
) ;
292
-
293
- if ( model . pwfTextureString !== pwfunToString ) {
345
+ const cachedPwfEntry =
346
+ model . _openGLRenderWindow . getGraphicsResourceForObject ( pwFunc ) ;
347
+ const reBuildPwf =
348
+ ! cachedPwfEntry ?. oglObject ?. getHandle ( ) ||
349
+ cachedPwfEntry ?. hash !== pwfTextureHash ;
350
+ if ( reBuildPwf ) {
294
351
const pwfWidth = 1024 ;
295
352
const pwfSize = pwfWidth * textureHeight ;
296
353
const pwfTable = new Uint8ClampedArray ( pwfSize ) ;
297
- let pwfun = ppty . getPiecewiseFunction ( ) ;
298
- // support case where pwfun is added/removed
299
- model . pwfTexture . releaseGraphicsResources ( model . _openGLRenderWindow ) ;
300
- model . pwfTexture . resetFormatAndType ( ) ;
301
- if ( pwfun ) {
354
+ model . pwfTexture = vtkOpenGLTexture . newInstance ( ) ;
355
+ model . pwfTexture . setOpenGLRenderWindow ( model . _openGLRenderWindow ) ;
356
+ if ( pwFunc ) {
302
357
const pwfFloatTable = new Float32Array ( pwfSize ) ;
303
358
const tmpTable = new Float32Array ( pwfWidth ) ;
304
359
305
360
for ( let c = 0 ; c < numIComps ; ++ c ) {
306
- pwfun = ppty . getPiecewiseFunction ( c ) ;
361
+ const pwfun = ppty . getPiecewiseFunction ( c ) ;
307
362
if ( pwfun === null ) {
308
363
// Piecewise constant max if no function supplied for this component
309
364
pwfFloatTable . fill ( 1.0 ) ;
@@ -323,6 +378,7 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
323
378
}
324
379
}
325
380
}
381
+ model . pwfTexture . resetFormatAndType ( ) ;
326
382
model . pwfTexture . create2DFromRaw (
327
383
pwfWidth ,
328
384
textureHeight ,
@@ -333,6 +389,7 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
333
389
} else {
334
390
// default is opaque
335
391
pwfTable . fill ( 255.0 ) ;
392
+ model . pwfTexture . resetFormatAndType ( ) ;
336
393
model . pwfTexture . create2DFromRaw (
337
394
pwfWidth ,
338
395
1 ,
@@ -341,7 +398,26 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
341
398
pwfTable
342
399
) ;
343
400
}
344
- model . pwfTextureString = pwfunToString ;
401
+ if ( pwFunc ) {
402
+ model . _openGLRenderWindow . setGraphicsResourceForObject (
403
+ pwFunc ,
404
+ model . pwfTexture ,
405
+ pwfTextureHash
406
+ ) ;
407
+ if ( pwFunc !== model . _pwFunc ) {
408
+ model . _openGLRenderWindow . registerGraphicsResourceUser (
409
+ pwFunc ,
410
+ publicAPI
411
+ ) ;
412
+ model . _openGLRenderWindow . unregisterGraphicsResourceUser (
413
+ model . _pwFunc ,
414
+ publicAPI
415
+ ) ;
416
+ }
417
+ model . _pwFunc = pwFunc ;
418
+ }
419
+ } else {
420
+ model . pwfTexture = cachedPwfEntry . oglObject ;
345
421
}
346
422
347
423
// Rebuild the image vertices if needed
@@ -1308,6 +1384,12 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
1308
1384
publicAPI . setCameraShaderParameters ( cellBO , ren , actor ) ;
1309
1385
publicAPI . setPropertyShaderParameters ( cellBO , ren , actor ) ;
1310
1386
} ;
1387
+
1388
+ publicAPI . delete = macro . chain ( ( ) => {
1389
+ if ( model . _openGLRenderWindow ) {
1390
+ unregisterGraphicsResources ( model . _openGLRenderWindow ) ;
1391
+ }
1392
+ } , publicAPI . delete ) ;
1311
1393
}
1312
1394
1313
1395
// ----------------------------------------------------------------------------
@@ -1317,18 +1399,18 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
1317
1399
const DEFAULT_VALUES = {
1318
1400
currentRenderPass : null ,
1319
1401
volumeTexture : null ,
1320
- volumeTextureTime : 0 ,
1321
1402
colorTexture : null ,
1322
- colorTextureString : null ,
1323
1403
pwfTexture : null ,
1324
- pwfTextureString : null ,
1325
1404
tris : null ,
1326
1405
lastHaveSeenDepthRequest : false ,
1327
1406
haveSeenDepthRequest : false ,
1328
1407
lastTextureComponents : 0 ,
1329
1408
lastIndependentComponents : 0 ,
1330
1409
imagemat : null ,
1331
1410
imagematinv : null ,
1411
+ // _scalars: null,
1412
+ // _colorTransferFunc: null,
1413
+ // _pwFunc: null,
1332
1414
} ;
1333
1415
1334
1416
// ----------------------------------------------------------------------------
@@ -1348,9 +1430,9 @@ export function extend(publicAPI, model, initialValues = {}) {
1348
1430
macro . algo ( publicAPI , model , 2 , 0 ) ;
1349
1431
1350
1432
model . tris = vtkHelper . newInstance ( ) ;
1351
- model . volumeTexture = vtkOpenGLTexture . newInstance ( ) ;
1352
- model . colorTexture = vtkOpenGLTexture . newInstance ( ) ;
1353
- model . pwfTexture = vtkOpenGLTexture . newInstance ( ) ;
1433
+ model . volumeTexture = null ;
1434
+ model . colorTexture = null ;
1435
+ model . pwfTexture = null ;
1354
1436
1355
1437
model . imagemat = mat4 . identity ( new Float64Array ( 16 ) ) ;
1356
1438
model . imagematinv = mat4 . identity ( new Float64Array ( 16 ) ) ;
0 commit comments