@@ -61,6 +61,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
61
61
model . _colorTransferFunc ,
62
62
model . _pwFunc ,
63
63
model . _labelOutlineThicknessArray ,
64
+ model . _labelOutlineOpacity ,
64
65
] . forEach ( ( coreObject ) =>
65
66
renderWindow . unregisterGraphicsResourceUser ( coreObject , publicAPI )
66
67
) ;
@@ -189,10 +190,16 @@ function vtkOpenGLImageMapper(publicAPI, model) {
189
190
'uniform sampler2D texture1;' ,
190
191
'uniform sampler2D colorTexture1;' ,
191
192
'uniform sampler2D pwfTexture1;' ,
192
- 'uniform sampler2D labelOutlineTexture1;' ,
193
193
'uniform float opacity;' ,
194
- 'uniform float outlineOpacity;' ,
195
194
] ;
195
+ if ( actor . getProperty ( ) . getUseLabelOutline ( ) ) {
196
+ tcoordDec = tcoordDec . concat ( [
197
+ // outline thickness
198
+ 'uniform sampler2D labelOutlineTexture1;' ,
199
+ // outline opacity
200
+ 'uniform sampler2D labelOutlineOpacityTexture1;' ,
201
+ ] ) ;
202
+ }
196
203
if ( iComps ) {
197
204
for ( let comp = 1 ; comp < tNumComp ; comp ++ ) {
198
205
tcoordDec = tcoordDec . concat ( [
@@ -263,7 +270,6 @@ function vtkOpenGLImageMapper(publicAPI, model) {
263
270
FSSource ,
264
271
'//VTK::LabelOutline::Dec' ,
265
272
[
266
- 'uniform int outlineThickness;' ,
267
273
'uniform float vpWidth;' ,
268
274
'uniform float vpHeight;' ,
269
275
'uniform float vpOffsetX;' ,
@@ -372,6 +378,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
372
378
int segmentIndex = int(centerValue * 255.0);
373
379
float textureCoordinate = float(segmentIndex - 1) / 1024.0;
374
380
float textureValue = texture2D(labelOutlineTexture1, vec2(textureCoordinate, 0.5)).r;
381
+ float outlineOpacity = texture2D(labelOutlineOpacityTexture1, vec2(textureCoordinate, 0.5)).r;
375
382
int actualThickness = int(textureValue * 255.0);
376
383
377
384
if (segmentIndex == 0){
@@ -547,6 +554,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
547
554
needRebuild ||
548
555
model . lastHaveSeenDepthRequest !== model . haveSeenDepthRequest ||
549
556
cellBO . getProgram ( ) ?. getHandle ( ) === 0 ||
557
+ cellBO . getShaderSourceTime ( ) . getMTime ( ) < model . renderable . getMTime ( ) ||
558
+ cellBO . getShaderSourceTime ( ) . getMTime ( ) < model . currentInput . getMTime ( ) ||
559
+ cellBO . getShaderSourceTime ( ) . getMTime ( ) <
560
+ actor . getProperty ( ) . getMTime ( ) ||
550
561
model . lastTextureComponents !== tNumComp ||
551
562
model . lastIndependentComponents !== iComp
552
563
) {
@@ -721,11 +732,19 @@ function vtkOpenGLImageMapper(publicAPI, model) {
721
732
const texOpacityUnit = model . pwfTexture . getTextureUnit ( ) ;
722
733
cellBO . getProgram ( ) . setUniformi ( 'pwfTexture1' , texOpacityUnit ) ;
723
734
724
- const outlineThicknessUnit =
725
- model . labelOutlineThicknessTexture . getTextureUnit ( ) ;
726
- cellBO
727
- . getProgram ( )
728
- . setUniformi ( 'labelOutlineTexture1' , outlineThicknessUnit ) ;
735
+ if ( actor . getProperty ( ) . getUseLabelOutline ( ) ) {
736
+ const outlineThicknessUnit =
737
+ model . labelOutlineThicknessTexture . getTextureUnit ( ) ;
738
+ cellBO
739
+ . getProgram ( )
740
+ . setUniformi ( 'labelOutlineTexture1' , outlineThicknessUnit ) ;
741
+
742
+ const texOutlineOpacityUnit =
743
+ model . labelOutlineOpacityTexture . getTextureUnit ( ) ;
744
+ cellBO
745
+ . getProgram ( )
746
+ . setUniformi ( 'labelOutlineOpacityTexture1' , texOutlineOpacityUnit ) ;
747
+ }
729
748
730
749
if ( model . renderable . getNumberOfClippingPlanes ( ) ) {
731
750
// add all the clipping planes
@@ -768,14 +787,6 @@ function vtkOpenGLImageMapper(publicAPI, model) {
768
787
cellBO . getProgram ( ) . setUniformi ( 'numClipPlanes' , numClipPlanes ) ;
769
788
cellBO . getProgram ( ) . setUniform4fv ( 'clipPlanes' , planeEquations ) ;
770
789
}
771
-
772
- // outline thickness and opacity
773
- const vtkImageLabelOutline = actor . getProperty ( ) . getUseLabelOutline ( ) ;
774
-
775
- if ( vtkImageLabelOutline === true ) {
776
- const outlineOpacity = actor . getProperty ( ) . getLabelOutlineOpacity ( ) ;
777
- cellBO . getProgram ( ) . setUniformf ( 'outlineOpacity' , outlineOpacity ) ;
778
- }
779
790
} ;
780
791
781
792
publicAPI . setCameraShaderParameters = ( cellBO , ren , actor ) => {
@@ -862,7 +873,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
862
873
// activate the texture
863
874
model . openGLTexture . activate ( ) ;
864
875
model . colorTexture . activate ( ) ;
865
- model . labelOutlineThicknessTexture . activate ( ) ;
876
+ if ( actor . getProperty ( ) . getUseLabelOutline ( ) ) {
877
+ model . labelOutlineThicknessTexture . activate ( ) ;
878
+ model . labelOutlineOpacityTexture . activate ( ) ;
879
+ }
866
880
model . pwfTexture . activate ( ) ;
867
881
868
882
// draw polygons
@@ -875,7 +889,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
875
889
876
890
model . openGLTexture . deactivate ( ) ;
877
891
model . colorTexture . deactivate ( ) ;
878
- model . labelOutlineThicknessTexture . deactivate ( ) ;
892
+ if ( actor . getProperty ( ) . getUseLabelOutline ( ) ) {
893
+ model . labelOutlineThicknessTexture . deactivate ( ) ;
894
+ model . labelOutlineOpacityTexture . deactivate ( ) ;
895
+ }
879
896
model . pwfTexture . deactivate ( ) ;
880
897
} ;
881
898
@@ -917,7 +934,9 @@ function vtkOpenGLImageMapper(publicAPI, model) {
917
934
model . VBOBuildTime . getMTime ( ) < model . currentInput . getMTime ( ) ||
918
935
! model . openGLTexture ?. getHandle ( ) ||
919
936
! model . colorTexture ?. getHandle ( ) ||
920
- ! model . labelOutlineThicknessTexture ?. getHandle ( ) ||
937
+ ( actor . getProperty ( ) . getUseLabelOutline ( ) &&
938
+ ( ! model . labelOutlineThicknessTexture ?. getHandle ( ) ||
939
+ ! model . labelOutlineOpacityTexture ?. getHandle ( ) ) ) ||
921
940
! model . pwfTexture ?. getHandle ( ) ;
922
941
923
942
publicAPI . buildBufferObjects = ( ren , actor ) => {
@@ -1150,8 +1169,11 @@ function vtkOpenGLImageMapper(publicAPI, model) {
1150
1169
model . pwfTexture = pwfTex . oglObject ;
1151
1170
}
1152
1171
1153
- // Build outline thickness buffer
1154
- publicAPI . updatelabelOutlineThicknessTexture ( actor ) ;
1172
+ if ( actor . getProperty ( ) . getUseLabelOutline ( ) ) {
1173
+ // Build outline thickness + opacity buffers
1174
+ publicAPI . updatelabelOutlineThicknessTexture ( actor ) ;
1175
+ publicAPI . updateLabelOutlineOpacityTexture ( actor ) ;
1176
+ }
1155
1177
1156
1178
// Find what IJK axis and what direction to slice along
1157
1179
const { ijkMode } = model . renderable . getClosestIJKAxis ( ) ;
@@ -1393,6 +1415,85 @@ function vtkOpenGLImageMapper(publicAPI, model) {
1393
1415
}
1394
1416
} ;
1395
1417
1418
+ publicAPI . updateLabelOutlineOpacityTexture = ( image ) => {
1419
+ let labelOutlineOpacity = image . getProperty ( ) . getLabelOutlineOpacity ( ) ;
1420
+
1421
+ // when the labelOutlineOpacity is a number, we use _cachedLabelOutlineOpacityObj
1422
+ // as a stable object reference for `[labelOutlineOpacity]`.
1423
+ if ( typeof labelOutlineOpacity === 'number' ) {
1424
+ if ( model . _cachedLabelOutlineOpacityObj ?. [ 0 ] === labelOutlineOpacity ) {
1425
+ labelOutlineOpacity = model . _cachedLabelOutlineOpacityObj ;
1426
+ } else {
1427
+ labelOutlineOpacity = [ labelOutlineOpacity ] ;
1428
+ }
1429
+ model . _cachedLabelOutlineOpacityObj = labelOutlineOpacity ;
1430
+ }
1431
+
1432
+ const lTex =
1433
+ model . _openGLRenderWindow . getGraphicsResourceForObject (
1434
+ labelOutlineOpacity
1435
+ ) ;
1436
+
1437
+ const toString = `${ labelOutlineOpacity . join ( '-' ) } ` ;
1438
+ const reBuildL = ! lTex ?. oglObject ?. getHandle ( ) || lTex ?. hash !== toString ;
1439
+
1440
+ if ( reBuildL ) {
1441
+ let lWidth = model . renderable . getLabelOutlineTextureWidth ( ) ;
1442
+ if ( lWidth <= 0 ) {
1443
+ lWidth = model . context . getParameter ( model . context . MAX_TEXTURE_SIZE ) ;
1444
+ }
1445
+ const lHeight = 1 ;
1446
+ const lSize = lWidth * lHeight ;
1447
+ const lTable = new Float32Array ( lSize ) ;
1448
+
1449
+ for ( let i = 0 ; i < lWidth ; ++ i ) {
1450
+ // Retrieve the opacity value for the current segment index.
1451
+ // If the value is undefined, use the first element's value as a default, otherwise use the value (even if 0)
1452
+ lTable [ i ] = labelOutlineOpacity [ i ] ?? labelOutlineOpacity [ 0 ] ;
1453
+ }
1454
+ model . labelOutlineOpacityTexture = vtkOpenGLTexture . newInstance ( {
1455
+ resizable : false ,
1456
+ } ) ;
1457
+ model . labelOutlineOpacityTexture . setOpenGLRenderWindow (
1458
+ model . _openGLRenderWindow
1459
+ ) ;
1460
+
1461
+ model . labelOutlineOpacityTexture . resetFormatAndType ( ) ;
1462
+ model . labelOutlineOpacityTexture . setMinificationFilter ( Filter . NEAREST ) ;
1463
+ model . labelOutlineOpacityTexture . setMagnificationFilter ( Filter . NEAREST ) ;
1464
+
1465
+ // Create a 2D texture (acting as 1D) from the raw data
1466
+ model . labelOutlineOpacityTexture . create2DFromRaw ( {
1467
+ width : lWidth ,
1468
+ height : lHeight ,
1469
+ numComps : 1 ,
1470
+ dataType : VtkDataTypes . FLOAT ,
1471
+ data : lTable ,
1472
+ } ) ;
1473
+
1474
+ if ( labelOutlineOpacity ) {
1475
+ model . _openGLRenderWindow . setGraphicsResourceForObject (
1476
+ labelOutlineOpacity ,
1477
+ model . labelOutlineOpacityTexture ,
1478
+ toString
1479
+ ) ;
1480
+ if ( labelOutlineOpacity !== model . _labelOutlineOpacity ) {
1481
+ model . _openGLRenderWindow . registerGraphicsResourceUser (
1482
+ labelOutlineOpacity ,
1483
+ publicAPI
1484
+ ) ;
1485
+ model . _openGLRenderWindow . unregisterGraphicsResourceUser (
1486
+ model . _labelOutlineOpacity ,
1487
+ publicAPI
1488
+ ) ;
1489
+ }
1490
+ model . _labelOutlineOpacity = labelOutlineOpacity ;
1491
+ }
1492
+ } else {
1493
+ model . labelOutlineOpacityTexture = lTex . oglObject ;
1494
+ }
1495
+ } ;
1496
+
1396
1497
publicAPI . updatelabelOutlineThicknessTexture = ( image ) => {
1397
1498
const labelOutlineThicknessArray = image
1398
1499
. getProperty ( )
@@ -1509,7 +1610,7 @@ const DEFAULT_VALUES = {
1509
1610
colorTexture : null ,
1510
1611
pwfTexture : null ,
1511
1612
labelOutlineThicknessTexture : null ,
1512
- labelOutlineThicknessTextureString : null ,
1613
+ labelOutlineOpacityTexture : null ,
1513
1614
lastHaveSeenDepthRequest : false ,
1514
1615
haveSeenDepthRequest : false ,
1515
1616
lastTextureComponents : 0 ,
0 commit comments