Skip to content

Commit 5820f97

Browse files
sedghifinetjul
authored andcommitted
feat: refactor code to enable direct usage of create3DFromRaw
1 parent 4463a59 commit 5820f97

File tree

2 files changed

+101
-89
lines changed

2 files changed

+101
-89
lines changed

Sources/Rendering/OpenGL/Texture/index.js

Lines changed: 100 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,69 @@ function vtkOpenGLTexture(publicAPI, model) {
13631363

13641364
publicAPI.create2DFromRaw(width, height, numComps, dataType, data);
13651365
};
1366+
1367+
publicAPI.updateVolumeScaleForOpenGL = (dataType, numComps) => {
1368+
let isScalingApplied = false;
1369+
1370+
// Initialize volume info if it doesn't exist
1371+
if (!model.volumeInfo?.scale || !model.volumeInfo?.offset) {
1372+
model.volumeInfo = {
1373+
scale: new Array(numComps),
1374+
offset: new Array(numComps),
1375+
};
1376+
}
1377+
1378+
// Default scaling and offset
1379+
for (let c = 0; c < numComps; ++c) {
1380+
model.volumeInfo.scale[c] = 1.0;
1381+
model.volumeInfo.offset[c] = 0.0;
1382+
}
1383+
1384+
// Handle SHORT data type with EXT_texture_norm16 extension
1385+
if (
1386+
model.oglNorm16Ext &&
1387+
!model.useHalfFloat &&
1388+
dataType === VtkDataTypes.SHORT
1389+
) {
1390+
for (let c = 0; c < numComps; ++c) {
1391+
model.volumeInfo.scale[c] = 32767.0; // Scale to [-1, 1] range
1392+
}
1393+
isScalingApplied = true;
1394+
}
1395+
1396+
// Handle UNSIGNED_SHORT data type with EXT_texture_norm16 extension
1397+
if (
1398+
model.oglNorm16Ext &&
1399+
!model.useHalfFloat &&
1400+
dataType === VtkDataTypes.UNSIGNED_SHORT
1401+
) {
1402+
for (let c = 0; c < numComps; ++c) {
1403+
model.volumeInfo.scale[c] = 65535.0; // Scale to [0, 1] range
1404+
}
1405+
isScalingApplied = true;
1406+
}
1407+
1408+
// Handle UNSIGNED_CHAR data type
1409+
if (dataType === VtkDataTypes.UNSIGNED_CHAR) {
1410+
for (let c = 0; c < numComps; ++c) {
1411+
model.volumeInfo.scale[c] = 255.0; // Scale to [0, 1] range
1412+
}
1413+
isScalingApplied = true;
1414+
}
1415+
1416+
// No scaling needed for FLOAT or HalfFloat (SHORT/UNSIGNED_SHORT)
1417+
if (
1418+
dataType === VtkDataTypes.FLOAT ||
1419+
(model.useHalfFloat &&
1420+
(dataType === VtkDataTypes.SHORT ||
1421+
dataType === VtkDataTypes.UNSIGNED_SHORT))
1422+
) {
1423+
isScalingApplied = true;
1424+
}
1425+
1426+
return isScalingApplied;
1427+
};
1428+
13661429
//----------------------------------------------------------------------------
13671430
publicAPI.create3DFromRaw = (
13681431
width,
@@ -1372,12 +1435,37 @@ function vtkOpenGLTexture(publicAPI, model) {
13721435
dataType,
13731436
data
13741437
) => {
1438+
let dataTypeToUse = dataType;
1439+
let dataToUse = data;
1440+
1441+
if (!publicAPI.updateVolumeScaleForOpenGL(dataTypeToUse, numComps)) {
1442+
const numPixelsIn = width * height * depth;
1443+
const scaleOffsetsCopy = structuredClone(model.volumeInfo);
1444+
// otherwise convert to float
1445+
const newArray = new Float32Array(numPixelsIn * numComps);
1446+
// use computed scale and offset
1447+
model.volumeInfo.offset = scaleOffsetsCopy.offset;
1448+
model.volumeInfo.scale = scaleOffsetsCopy.scale;
1449+
let count = 0;
1450+
const scaleInverse = scaleOffsetsCopy.scale.map((s) => 1 / s);
1451+
for (let i = 0; i < numPixelsIn; i++) {
1452+
for (let nc = 0; nc < numComps; nc++) {
1453+
newArray[count] =
1454+
(dataToUse[count] - scaleOffsetsCopy.offset[nc]) * scaleInverse[nc];
1455+
count++;
1456+
}
1457+
}
1458+
1459+
dataTypeToUse = VtkDataTypes.FLOAT;
1460+
dataToUse = newArray;
1461+
}
1462+
13751463
// Permit OpenGLDataType to be half float, if applicable, for 3D
1376-
publicAPI.getOpenGLDataType(dataType);
1464+
publicAPI.getOpenGLDataType(dataTypeToUse);
13771465

13781466
// Now determine the texture parameters using the arguments.
1379-
publicAPI.getInternalFormat(dataType, numComps);
1380-
publicAPI.getFormat(dataType, numComps);
1467+
publicAPI.getInternalFormat(dataTypeToUse, numComps);
1468+
publicAPI.getFormat(dataTypeToUse, numComps);
13811469

13821470
if (!model.internalFormat || !model.format || !model.openGLDataType) {
13831471
vtkErrorMacro('Failed to determine texture parameters.');
@@ -1394,9 +1482,9 @@ function vtkOpenGLTexture(publicAPI, model) {
13941482
publicAPI.createTexture();
13951483
publicAPI.bind();
13961484
// Create an array of texture with one texture
1397-
const dataArray = [data];
1485+
const dataArray = [dataToUse];
13981486
const is3DArray = true;
1399-
const pixData = updateArrayDataType(dataType, dataArray, is3DArray);
1487+
const pixData = updateArrayDataType(dataTypeToUse, dataArray, is3DArray);
14001488
const scaledData = scaleTextureToHighestPowerOfTwo(pixData);
14011489

14021490
// Source texture data from the PBO.
@@ -1405,7 +1493,7 @@ function vtkOpenGLTexture(publicAPI, model) {
14051493

14061494
// openGLDataType
14071495

1408-
if (useTexStorage(dataType)) {
1496+
if (useTexStorage(dataTypeToUse)) {
14091497
model.context.texStorage3D(
14101498
model.target,
14111499
1,
@@ -1454,7 +1542,7 @@ function vtkOpenGLTexture(publicAPI, model) {
14541542
model.depth *
14551543
model.components *
14561544
model._openGLRenderWindow.getDefaultTextureByteSize(
1457-
dataType,
1545+
dataTypeToUse,
14581546
model.oglNorm16Ext,
14591547
model.useHalfFloat
14601548
);
@@ -1501,8 +1589,6 @@ function vtkOpenGLTexture(publicAPI, model) {
15011589
preferSizeOverAccuracy
15021590
);
15031591

1504-
const numPixelsIn = width * height * depth;
1505-
15061592
const offset = [];
15071593
const scale = [];
15081594
for (let c = 0; c < numComps; ++c) {
@@ -1528,96 +1614,22 @@ function vtkOpenGLTexture(publicAPI, model) {
15281614
// Create a copy of scale and offset to avoid aliasing issues
15291615
// Original is read only, copy is read/write
15301616
// Use the copy as volumeInfo.scale and volumeInfo.offset
1531-
const scaleOffsetsCopy = structuredClone(scaleOffsets);
15321617

15331618
// WebGL2 path, we have 3d textures etc
15341619
if (model._openGLRenderWindow.getWebgl2()) {
1535-
if (
1536-
model.oglNorm16Ext &&
1537-
!model.useHalfFloat &&
1538-
dataType === VtkDataTypes.SHORT
1539-
) {
1540-
for (let c = 0; c < numComps; ++c) {
1541-
model.volumeInfo.scale[c] = 32767.0;
1542-
}
1543-
return publicAPI.create3DFromRaw(
1544-
width,
1545-
height,
1546-
depth,
1547-
numComps,
1548-
dataType,
1549-
data
1550-
);
1551-
}
1552-
if (
1553-
model.oglNorm16Ext &&
1554-
!model.useHalfFloat &&
1555-
dataType === VtkDataTypes.UNSIGNED_SHORT
1556-
) {
1557-
for (let c = 0; c < numComps; ++c) {
1558-
model.volumeInfo.scale[c] = 65535.0;
1559-
}
1560-
return publicAPI.create3DFromRaw(
1561-
width,
1562-
height,
1563-
depth,
1564-
numComps,
1565-
dataType,
1566-
data
1567-
);
1568-
}
1569-
if (
1570-
dataType === VtkDataTypes.FLOAT ||
1571-
(model.useHalfFloat &&
1572-
(dataType === VtkDataTypes.SHORT ||
1573-
dataType === VtkDataTypes.UNSIGNED_SHORT))
1574-
) {
1575-
return publicAPI.create3DFromRaw(
1576-
width,
1577-
height,
1578-
depth,
1579-
numComps,
1580-
dataType,
1581-
data
1582-
);
1583-
}
1584-
if (dataType === VtkDataTypes.UNSIGNED_CHAR) {
1585-
for (let c = 0; c < numComps; ++c) {
1586-
model.volumeInfo.scale[c] = 255.0;
1587-
}
1588-
return publicAPI.create3DFromRaw(
1589-
width,
1590-
height,
1591-
depth,
1592-
numComps,
1593-
dataType,
1594-
data
1595-
);
1596-
}
1597-
// otherwise convert to float
1598-
const newArray = new Float32Array(numPixelsIn * numComps);
1599-
// use computed scale and offset
1600-
model.volumeInfo.offset = scaleOffsetsCopy.offset;
1601-
model.volumeInfo.scale = scaleOffsetsCopy.scale;
1602-
let count = 0;
1603-
const scaleInverse = scaleOffsetsCopy.scale.map((s) => 1 / s);
1604-
for (let i = 0; i < numPixelsIn; i++) {
1605-
for (let nc = 0; nc < numComps; nc++) {
1606-
newArray[count] =
1607-
(data[count] - scaleOffsetsCopy.offset[nc]) * scaleInverse[nc];
1608-
count++;
1609-
}
1610-
}
16111620
return publicAPI.create3DFromRaw(
16121621
width,
16131622
height,
16141623
depth,
16151624
numComps,
1616-
VtkDataTypes.FLOAT,
1617-
newArray
1625+
dataType,
1626+
data
16181627
);
16191628
}
16201629

1630+
const numPixelsIn = width * height * depth;
1631+
const scaleOffsetsCopy = structuredClone(scaleOffsets);
1632+
16211633
// not webgl2, deal with webgl1, no 3d textures
16221634
// and maybe no float textures
16231635

Sources/Rendering/OpenGL/VolumeMapper/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
708708

709709
// In some situations, we might not have computed the scale and offset
710710
// for the data range, or it might not be needed.
711-
if (volInfo.dataComputedScale?.length) {
711+
if (volInfo?.dataComputedScale?.length) {
712712
const minVals = [];
713713
const maxVals = [];
714714
for (let i = 0; i < 4; i++) {

0 commit comments

Comments
 (0)