Skip to content

Commit 9ee80c6

Browse files
committed
feat(ColorTransferFunction): Add sigmoid mapping
1 parent aed71ec commit 9ee80c6

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

Examples/Applications/ImageViewer/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ function createUI(renderWindow, interactorStyle, imageSlice) {
117117

118118
function applyPreset() {
119119
const preset = vtkColorMaps.getPresetByName(presetSelector.value);
120+
lookupTable.setSigmoidGrowthRate(-4.0);
120121
lookupTable.applyColorMap(preset);
121122
lookupTable.setMappingRange(...scalars.getRange());
122123
lookupTable.updateRange();
@@ -194,12 +195,35 @@ function createUI(renderWindow, interactorStyle, imageSlice) {
194195
}
195196
interpolationSelector.addEventListener('input', updateInterpolation);
196197

198+
const mappingModeLabel = document.createElement('label');
199+
mappingModeLabel.for = 'mappingMode';
200+
mappingModeLabel.innerText = 'Mapping Sigmoid:';
201+
const mappingModeSelector = document.createElement('input');
202+
mappingModeSelector.setAttribute('class', selectorClass);
203+
mappingModeSelector.setAttribute('id', 'mappingMode');
204+
mappingModeSelector.type = 'checkbox';
205+
mappingModeSelector.checked = false;
206+
const mappingMode = document.createElement('div');
207+
mappingMode.appendChild(mappingModeLabel);
208+
mappingMode.appendChild(mappingModeSelector);
209+
210+
function updateMappingMode() {
211+
if (mappingModeSelector.checked) {
212+
lookupTable.setScalarMappingModeToSigmoid();
213+
} else {
214+
lookupTable.setScalarMappingModeToLinear();
215+
}
216+
renderWindow.getInteractor().render();
217+
}
218+
mappingModeSelector.addEventListener('input', updateMappingMode);
219+
197220
const controlContainer = document.createElement('div');
198221
controlContainer.setAttribute('class', style.control);
199222
controlContainer.appendChild(info);
200223
controlContainer.appendChild(presetSelector);
201224
controlContainer.appendChild(windowLevel);
202225
controlContainer.appendChild(interpolation);
226+
controlContainer.appendChild(mappingMode);
203227
rootControllerContainer.appendChild(controlContainer);
204228
}
205229
// ----------------------------------------------------------------------------

Sources/Rendering/Core/ColorTransferFunction/Constants.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@ export declare enum Scale {
1010
LOG10 = 1,
1111
}
1212

13+
export declare enum ScalarMappingMode {
14+
LINEAR = 0,
15+
SIGMOID = 1,
16+
}
17+
1318
declare const _default: {
1419
ColorSpace: typeof ColorSpace;
1520
Scale: typeof Scale;
21+
ScalarMappingMode: typeof ScalarMappingMode;
1622
};
1723
export default _default;

Sources/Rendering/Core/ColorTransferFunction/Constants.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ export const Scale = {
1010
LOG10: 1,
1111
};
1212

13+
export const ScalarMappingMode = {
14+
LINEAR: 0,
15+
SIGMOID: 1,
16+
};
17+
1318
export default {
1419
ColorSpace,
1520
Scale,
21+
ScalarMappingMode,
1622
};

Sources/Rendering/Core/ColorTransferFunction/index.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
33
import vtkScalarsToColors from 'vtk.js/Sources/Common/Core/ScalarsToColors';
44
import Constants from 'vtk.js/Sources/Rendering/Core/ColorTransferFunction/Constants';
55

6-
const { ColorSpace, Scale } = Constants;
6+
const { ColorSpace, Scale, ScalarMappingMode } = Constants;
77
const { ScalarMappingTarget } = vtkScalarsToColors;
88
const { vtkDebugMacro, vtkErrorMacro, vtkWarningMacro } = macro;
99

@@ -493,6 +493,8 @@ function vtkColorTransferFunction(publicAPI, model) {
493493
];
494494
}
495495

496+
const useSigmoid =
497+
publicAPI.getScalarMappingMode() == ScalarMappingMode.SIGMOID;
496498
// For each table entry
497499
for (let i = 0; i < size; i++) {
498500
// Find our location in the table
@@ -501,11 +503,23 @@ function vtkColorTransferFunction(publicAPI, model) {
501503
// Find our X location. If we are taking only 1 sample, make
502504
// it halfway between start and end (usually start and end will
503505
// be the same in this case)
506+
let c = 0,
507+
w = 0;
504508
if (size > 1) {
509+
c = (xEnd + xStart) / 2.0;
510+
w = xEnd - xStart;
505511
x = xStart + (i / (size - 1.0)) * (xEnd - xStart);
506512
} else {
513+
c = (scaledMappingRange[0] + scaledMappingRange[1]) / 2.0;
514+
w = scaledMappingRange[1] - scaledMappingRange[0];
507515
x = 0.5 * (xStart + xEnd);
508516
}
517+
if (useSigmoid) {
518+
// Apply the sigmoid function to x,
519+
const y = 1 / (1 + Math.exp((model.sigmoidGrowthRate * (x - c)) / w));
520+
// and re-interpret it as a linear parameter.
521+
x = y * w + (c - w / 2);
522+
}
509523

510524
// Linearly map x from mappingRange to [0, numberOfValues-1],
511525
// discretize (round down to the closest integer),
@@ -1273,6 +1287,12 @@ function vtkColorTransferFunction(publicAPI, model) {
12731287

12741288
return modifiedInvoked || callModified;
12751289
};
1290+
1291+
publicAPI.setScalarMappingModeToLinear = () =>
1292+
publicAPI.setScalarMappingMode(ScalarMappingMode.LINEAR);
1293+
1294+
publicAPI.setScalarMappingModeToSigmoid = () =>
1295+
publicAPI.setScalarMappingMode(ScalarMappingMode.SIGMOID);
12761296
}
12771297

12781298
// ----------------------------------------------------------------------------
@@ -1284,6 +1304,7 @@ const DEFAULT_VALUES = {
12841304
colorSpace: ColorSpace.RGB,
12851305
hSVWrap: true,
12861306
scale: Scale.LINEAR,
1307+
scalarMappingMode: ScalarMappingMode.LINEAR,
12871308

12881309
nanColor: null,
12891310
belowRangeColor: null,
@@ -1301,6 +1322,7 @@ const DEFAULT_VALUES = {
13011322

13021323
discretize: false,
13031324
numberOfValues: 256,
1325+
sigmoidGrowthRate: -4,
13041326
};
13051327

13061328
// ----------------------------------------------------------------------------
@@ -1331,8 +1353,10 @@ export function extend(publicAPI, model, initialValues = {}) {
13311353
'useBelowRangeColor',
13321354
'discretize',
13331355
'numberOfValues',
1356+
'sigmoidGrowthRate',
13341357
{ type: 'enum', name: 'colorSpace', enum: ColorSpace },
13351358
{ type: 'enum', name: 'scale', enum: Scale },
1359+
{ type: 'enum', name: 'scalarMappingMode', enum: ScalarMappingMode },
13361360
]);
13371361

13381362
macro.setArray(

0 commit comments

Comments
 (0)