@ohif/app 3.10.1 → 3.10.2

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.
Files changed (44) hide show
  1. package/dist/{1919.bundle.6f7de53921f3710a1d54.js → 1919.bundle.6cb4a1f5ea770e504398.js} +2 -2
  2. package/dist/{1927.bundle.83810560c4d3a90eb7cf.js → 1927.bundle.5c25b9084f704a3582d2.js} +1 -1
  3. package/dist/{3396.bundle.858cfdfc5ab560840958.js → 2482.bundle.0947bc67ad4429d5fda3.js} +289 -1353
  4. package/dist/{2701.bundle.f1f15df81406d04851c4.js → 2701.bundle.87301d8d94693b5d5fcc.js} +2 -2
  5. package/dist/{2860.bundle.5d93c30e2df60e382bda.js → 2860.bundle.130f5c83c90c83017101.js} +1368 -28
  6. package/dist/{2914.bundle.a0a5ddfebfc9d429063d.js → 2914.bundle.adefec5b51b4955af1f9.js} +2 -0
  7. package/dist/{2932.bundle.038f79dbbfdd9d1f387b.js → 2932.bundle.2757ab993a28dab49d56.js} +2 -2
  8. package/dist/{3075.bundle.0624f6bf3f676f30d1b5.js → 3075.bundle.5d83563c3791a0d884df.js} +16 -3
  9. package/dist/{3353.bundle.184ebb9668df2cbebd26.js → 3353.bundle.1b2d3da25de70f5f1042.js} +33 -4
  10. package/dist/{3984.bundle.592161af4b618c9dd56f.js → 3984.bundle.1248e382e82ee04eff72.js} +12 -7
  11. package/dist/{4113.bundle.7ec6da0eb1ab98e1b791.js → 4113.bundle.1a3202dd6a1b2e6b9d5d.js} +5 -5
  12. package/dist/{4526.bundle.fbdd617a934353019be3.js → 4526.bundle.54c0b8f753ed5c39f6c5.js} +2 -2
  13. package/dist/{6029.bundle.43e04238ac01880fa66c.js → 6029.bundle.a4206e2a2e75c7b1ad7b.js} +238 -40
  14. package/dist/{6066.bundle.345453ace06e86bc481c.js → 6066.bundle.89df990e4f257e8ac73b.js} +1466 -39
  15. package/dist/{6201.bundle.e0d8d1c967a9daed4662.js → 6201.bundle.b584d7554570344d9170.js} +4 -4
  16. package/dist/{7197.bundle.a9c6429f2859a8feeded.js → 7197.bundle.2032eea26c084877d172.js} +3 -3
  17. package/dist/{810.bundle.86ba4f6f1311ccc28d41.js → 810.bundle.8b29de53f9632f0f1bf9.js} +4 -4
  18. package/dist/{8185.bundle.b2252d9ff14ce760df9c.js → 8185.bundle.c7e0ab58fa8f7070de26.js} +22 -16
  19. package/dist/{8558.bundle.5b67110ba3e66f5525ae.js → 8558.bundle.24bb90c2d5a0857577c5.js} +1 -1
  20. package/dist/{7241.bundle.7097a0cd314605d766f5.js → 8572.bundle.bd98ac784dae1e224a52.js} +135 -47
  21. package/dist/{3166.bundle.40162f1d9f9f5fc16b16.js → 908.bundle.7f901ab4610793bb5ee3.js} +29 -5
  22. package/dist/{934.bundle.c446dfb396152899756f.js → 934.bundle.441c775536d8be5029af.js} +2 -2
  23. package/dist/{963.bundle.88152346007c0f5049a3.js → 963.bundle.4b88a54196fdd1976d6c.js} +2 -2
  24. package/dist/{9890.bundle.37d7ed265c0454337a57.js → 9890.bundle.b4c265e3609512785ae8.js} +2 -2
  25. package/dist/{9977.bundle.071821200c1921021d29.js → 9977.bundle.4f44190c1a5d6a69bc00.js} +3 -1
  26. package/dist/{app.bundle.d09601053966ecdcfe4b.js → app.bundle.223c009cd6f636320f76.js} +2148 -1758
  27. package/dist/app.bundle.css +2 -2
  28. package/dist/{compute.bundle.f0c30502c027d04e94f2.js → compute.bundle.83a75c96620eedca973e.js} +3 -3
  29. package/dist/index.html +1 -1
  30. package/dist/{polySeg.bundle.7445d00e1e9ef623d0f1.js → polySeg.bundle.30f6f13491f48e597605.js} +3 -3
  31. package/dist/sw.js +1 -1
  32. package/package.json +19 -19
  33. /package/dist/{1459.bundle.4b6682c8673e199edf64.js → 1459.bundle.ea2023918c1ef217d23a.js} +0 -0
  34. /package/dist/{1807.bundle.e8c6890ca68e62f46990.js → 1807.bundle.a04f3486b00cdcc6a305.js} +0 -0
  35. /package/dist/{213.bundle.d8495e69f1d1405d0356.js → 213.bundle.e861b773d4779d7d724a.js} +0 -0
  36. /package/dist/{2424.bundle.ef98022039ea6e87cfd9.js → 2424.bundle.425cb2260521f2a23f70.js} +0 -0
  37. /package/dist/{3658.bundle.04fdfe11b9d38cd5f3c6.js → 3658.bundle.a6a9c2e1b32d92e3b621.js} +0 -0
  38. /package/dist/{6027.bundle.155cbff7fa97c7ede627.js → 6027.bundle.8e1b6021f0d570eb85f5.js} +0 -0
  39. /package/dist/{7639.bundle.a659acbf2ab7f3f2e8f4.js → 7639.bundle.b622eafdc74d9bfc1280.js} +0 -0
  40. /package/dist/{8228.bundle.74c8ca5e66a44db80464.js → 8228.bundle.f520ecf3c0a8998e770a.js} +0 -0
  41. /package/dist/{85.bundle.e65ed829e1a136e33576.js → 85.bundle.a27a1466f85e01adf8e8.js} +0 -0
  42. /package/dist/{8815.bundle.c8a97b220635e9b15109.js → 8815.bundle.096958a5ae7253911a2e.js} +0 -0
  43. /package/dist/{9026.bundle.eb2ae9e2311a6a620751.js → 9026.bundle.019d8b4b70096b94302e.js} +0 -0
  44. /package/dist/{9862.bundle.87d8249a9cf1d8cf579d.js → 9862.bundle.b0ea941458506379f666.js} +0 -0
@@ -1838,7 +1838,7 @@ function actorIsA(actorEntry, actorType) {
1838
1838
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1839
1839
  /* harmony export */ A: () => (/* binding */ applyPreset)
1840
1840
  /* harmony export */ });
1841
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33739);
1841
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(642);
1842
1842
  /* harmony import */ var _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(99341);
1843
1843
 
1844
1844
 
@@ -2181,11 +2181,18 @@ __webpack_require__.r(__webpack_exports__);
2181
2181
  /* harmony export */ findMatchingColormap: () => (/* binding */ findMatchingColormap),
2182
2182
  /* harmony export */ getColormap: () => (/* binding */ getColormap),
2183
2183
  /* harmony export */ getColormapNames: () => (/* binding */ getColormapNames),
2184
- /* harmony export */ registerColormap: () => (/* binding */ registerColormap)
2184
+ /* harmony export */ registerColormap: () => (/* binding */ registerColormap),
2185
+ /* harmony export */ setColorMapTransferFunctionForVolumeActor: () => (/* binding */ setColorMapTransferFunctionForVolumeActor),
2186
+ /* harmony export */ updateOpacity: () => (/* binding */ updateOpacity),
2187
+ /* harmony export */ updateThreshold: () => (/* binding */ updateThreshold)
2185
2188
  /* harmony export */ });
2186
2189
  /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction_ColorMaps__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(660);
2187
- /* harmony import */ var _isEqual__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74638);
2188
- /* harmony import */ var _actorCheck__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(98039);
2190
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(642);
2191
+ /* harmony import */ var _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(99341);
2192
+ /* harmony import */ var _isEqual__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74638);
2193
+ /* harmony import */ var _actorCheck__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(98039);
2194
+
2195
+
2189
2196
 
2190
2197
 
2191
2198
 
@@ -2210,7 +2217,7 @@ function findMatchingColormap(rgbPoints, actor) {
2210
2217
  return false;
2211
2218
  }
2212
2219
  for (let i = 0; i < presetRGBPoints.length; i += 4) {
2213
- if (!(0,_isEqual__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Ay)(presetRGBPoints.slice(i + 1, i + 4), rgbPoints.slice(i + 1, i + 4))) {
2220
+ if (!(0,_isEqual__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Ay)(presetRGBPoints.slice(i + 1, i + 4), rgbPoints.slice(i + 1, i + 4))) {
2214
2221
  return false;
2215
2222
  }
2216
2223
  }
@@ -2220,7 +2227,7 @@ function findMatchingColormap(rgbPoints, actor) {
2220
2227
  return null;
2221
2228
  }
2222
2229
  const opacity = [];
2223
- if ((0,_actorCheck__WEBPACK_IMPORTED_MODULE_2__/* .actorIsA */ .N)(actor, 'vtkVolume')) {
2230
+ if ((0,_actorCheck__WEBPACK_IMPORTED_MODULE_4__/* .actorIsA */ .N)(actor, 'vtkVolume')) {
2224
2231
  const opacityPoints = actor
2225
2232
  .getProperty()
2226
2233
  .getScalarOpacity(0)
@@ -2242,6 +2249,80 @@ function findMatchingColormap(rgbPoints, actor) {
2242
2249
  opacity,
2243
2250
  };
2244
2251
  }
2252
+ function setColorMapTransferFunctionForVolumeActor(volumeInfo) {
2253
+ const { volumeActor, preset, opacity = 0.9, threshold = null, colorRange = [0, 5], } = volumeInfo;
2254
+ const mapper = volumeActor.getMapper();
2255
+ mapper.setSampleDistance(1.0);
2256
+ const cfun = _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_1__/* ["default"].newInstance */ .Ay.newInstance();
2257
+ const presetToUse = preset || _kitware_vtk_js_Rendering_Core_ColorTransferFunction_ColorMaps__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.getPresetByName('hsv');
2258
+ cfun.applyColorMap(presetToUse);
2259
+ cfun.setMappingRange(colorRange[0], colorRange[1]);
2260
+ volumeActor.getProperty().setRGBTransferFunction(0, cfun);
2261
+ updateOpacityWithThreshold(volumeActor, opacity, threshold);
2262
+ }
2263
+ function updateOpacity(volumeActor, newOpacity) {
2264
+ const currentThreshold = getThresholdValue(volumeActor);
2265
+ updateOpacityWithThreshold(volumeActor, newOpacity, currentThreshold);
2266
+ }
2267
+ function updateThreshold(volumeActor, newThreshold) {
2268
+ const currentOpacity = getMaxOpacity(volumeActor);
2269
+ updateOpacityWithThreshold(volumeActor, currentOpacity, newThreshold);
2270
+ }
2271
+ function updateOpacityWithThreshold(volumeActor, opacity, threshold) {
2272
+ const transferFunction = volumeActor.getProperty().getRGBTransferFunction(0);
2273
+ const range = transferFunction.getRange();
2274
+ const ofun = _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_2__/* ["default"].newInstance */ .Ay.newInstance();
2275
+ if (threshold !== null) {
2276
+ const delta = Math.abs(range[1] - range[0]) * 0.001;
2277
+ const thresholdValue = Math.max(range[0], Math.min(range[1], threshold));
2278
+ ofun.addPoint(range[0], 0);
2279
+ ofun.addPoint(thresholdValue - delta, 0);
2280
+ ofun.addPoint(thresholdValue, opacity);
2281
+ ofun.addPoint(range[1], opacity);
2282
+ }
2283
+ else {
2284
+ ofun.addPoint(range[0], opacity);
2285
+ ofun.addPoint(range[1], opacity);
2286
+ }
2287
+ volumeActor.getProperty().setScalarOpacity(0, ofun);
2288
+ }
2289
+ function getThresholdValue(volumeActor) {
2290
+ const opacityFunction = volumeActor.getProperty().getScalarOpacity(0);
2291
+ if (!opacityFunction) {
2292
+ return null;
2293
+ }
2294
+ const dataArray = opacityFunction.getDataPointer();
2295
+ if (!dataArray || dataArray.length <= 4) {
2296
+ return null;
2297
+ }
2298
+ for (let i = 0; i < dataArray.length - 2; i += 2) {
2299
+ const x1 = dataArray[i];
2300
+ const y1 = dataArray[i + 1];
2301
+ const x2 = dataArray[i + 2];
2302
+ const y2 = dataArray[i + 3];
2303
+ if (y1 === 0 && y2 > 0) {
2304
+ return x2;
2305
+ }
2306
+ }
2307
+ return null;
2308
+ }
2309
+ function getMaxOpacity(volumeActor) {
2310
+ const opacityFunction = volumeActor.getProperty().getScalarOpacity(0);
2311
+ if (!opacityFunction) {
2312
+ return 1.0;
2313
+ }
2314
+ const dataArray = opacityFunction.getDataPointer();
2315
+ if (!dataArray || dataArray.length === 0) {
2316
+ return 1.0;
2317
+ }
2318
+ let maxOpacity = 0;
2319
+ for (let i = 1; i < dataArray.length; i += 2) {
2320
+ if (dataArray[i] > maxOpacity) {
2321
+ maxOpacity = dataArray[i];
2322
+ }
2323
+ }
2324
+ return maxOpacity;
2325
+ }
2245
2326
 
2246
2327
 
2247
2328
 
@@ -2254,7 +2335,7 @@ function findMatchingColormap(rgbPoints, actor) {
2254
2335
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2255
2336
  /* harmony export */ A: () => (/* binding */ createLinearRGBTransferFunction)
2256
2337
  /* harmony export */ });
2257
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33739);
2338
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(642);
2258
2339
 
2259
2340
  function createLinearRGBTransferFunction(voiRange) {
2260
2341
  const cfun = _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__/* ["default"].newInstance */ .Ay.newInstance();
@@ -2279,7 +2360,7 @@ function createLinearRGBTransferFunction(voiRange) {
2279
2360
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2280
2361
  /* harmony export */ A: () => (/* binding */ createSigmoidRGBTransferFunction)
2281
2362
  /* harmony export */ });
2282
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33739);
2363
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(642);
2283
2364
  /* harmony import */ var _kitware_vtk_js_Common_Core_DataArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42008);
2284
2365
  /* harmony import */ var _windowLevel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(68136);
2285
2366
  /* harmony import */ var _logit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(58977);
@@ -2386,12 +2467,15 @@ function fnv1aHash(str) {
2386
2467
  /* harmony export */ });
2387
2468
  /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3823);
2388
2469
  /* harmony import */ var _metaData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74876);
2389
- /* harmony import */ var _getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(85008);
2390
- /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(19325);
2470
+ /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7608);
2471
+ /* harmony import */ var _getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(85008);
2472
+ /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(19325);
2391
2473
 
2392
2474
 
2393
2475
 
2394
2476
 
2477
+
2478
+ const log = _logger__WEBPACK_IMPORTED_MODULE_2__.coreLog.getLogger('utilities', 'getClosestImageId');
2395
2479
  function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
2396
2480
  const { direction, spacing, imageIds } = imageVolume;
2397
2481
  const { ignoreSpacing = false } = options || {};
@@ -2400,13 +2484,12 @@ function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
2400
2484
  }
2401
2485
  const kVector = direction.slice(6, 9);
2402
2486
  const dotProduct = gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.dot */ .eR.dot(kVector, viewPlaneNormal);
2403
- if (Math.abs(dotProduct) < 1 - _constants__WEBPACK_IMPORTED_MODULE_3__.EPSILON) {
2404
- console.debug('View plane normal is not parallel to the image scan axis. Unable to find closest imageId.');
2487
+ if (Math.abs(dotProduct) < 1 - _constants__WEBPACK_IMPORTED_MODULE_4__.EPSILON) {
2405
2488
  return;
2406
2489
  }
2407
2490
  let halfSpacingInNormalDirection;
2408
2491
  if (!ignoreSpacing) {
2409
- const spacingInNormalDirection = (0,_getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)({ direction, spacing }, viewPlaneNormal);
2492
+ const spacingInNormalDirection = (0,_getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)({ direction, spacing }, viewPlaneNormal);
2410
2493
  halfSpacingInNormalDirection = spacingInNormalDirection / 2;
2411
2494
  }
2412
2495
  let closestImageId;
@@ -2415,7 +2498,7 @@ function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
2415
2498
  const imageId = imageIds[i];
2416
2499
  const imagePlaneModule = _metaData__WEBPACK_IMPORTED_MODULE_1__.get('imagePlaneModule', imageId);
2417
2500
  if (!imagePlaneModule?.imagePositionPatient) {
2418
- console.warn(`Missing imagePositionPatient for imageId: ${imageId}`);
2501
+ log.warn(`Missing imagePositionPatient for imageId: ${imageId}`);
2419
2502
  continue;
2420
2503
  }
2421
2504
  const { imagePositionPatient } = imagePlaneModule;
@@ -2436,7 +2519,7 @@ function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
2436
2519
  }
2437
2520
  }
2438
2521
  if (closestImageId === undefined) {
2439
- console.debug('No imageId found within the specified criteria (half spacing or absolute closest).');
2522
+ log.warn('No imageId found within the specified criteria (half spacing or absolute closest).');
2440
2523
  }
2441
2524
  return closestImageId;
2442
2525
  }
@@ -2575,13 +2658,19 @@ function getScalingParameters(imageId) {
2575
2658
  rescaleIntercept: modalityLutModule.rescaleIntercept ?? 0,
2576
2659
  modality,
2577
2660
  };
2578
- const suvFactor = _metaData__WEBPACK_IMPORTED_MODULE_0__.get('scalingModule', imageId) || {};
2661
+ const scalingModules = _metaData__WEBPACK_IMPORTED_MODULE_0__.get('scalingModule', imageId) || {};
2579
2662
  return {
2580
2663
  ...scalingParameters,
2581
2664
  ...(modality === 'PT' && {
2582
- suvbw: suvFactor.suvbw,
2583
- suvbsa: suvFactor.suvbsa,
2584
- suvlbm: suvFactor.suvlbm,
2665
+ suvbw: scalingModules.suvbw,
2666
+ suvbsa: scalingModules.suvbsa,
2667
+ suvlbm: scalingModules.suvlbm,
2668
+ }),
2669
+ ...(modality === 'RTDOSE' && {
2670
+ doseGridScaling: scalingModules.DoseGridScaling,
2671
+ doseSummation: scalingModules.DoseSummation,
2672
+ doseType: scalingModules.DoseType,
2673
+ doseUnit: scalingModules.DoseUnit,
2585
2674
  }),
2586
2675
  };
2587
2676
  }
@@ -10441,6 +10530,7 @@ PlanarRotateTool.toolName = 'PlanarRotate';
10441
10530
 
10442
10531
 
10443
10532
 
10533
+
10444
10534
  class ZoomTool extends base/* BaseTool */.oS {
10445
10535
  constructor(toolProps = {}, defaultToolProps = {
10446
10536
  supportedInteractionTypes: ['Mouse', 'Touch'],
@@ -10553,6 +10643,9 @@ class ZoomTool extends base/* BaseTool */.oS {
10553
10643
  }
10554
10644
  this.mouseDragCallback = this._dragCallback.bind(this);
10555
10645
  }
10646
+ mouseWheelCallback(evt) {
10647
+ this._zoom(evt);
10648
+ }
10556
10649
  _pinchCallback(evt) {
10557
10650
  const pointsList = evt.detail
10558
10651
  .currentPointsList;
@@ -10592,6 +10685,36 @@ class ZoomTool extends base/* BaseTool */.oS {
10592
10685
  }
10593
10686
  viewport.render();
10594
10687
  }
10688
+ _zoom(evt) {
10689
+ const { element, points } = evt.detail;
10690
+ const enabledElement = (0,esm.getEnabledElement)(element);
10691
+ const { viewport } = enabledElement;
10692
+ const camera = viewport.getCamera();
10693
+ const wheelData = evt.detail.wheel;
10694
+ const direction = wheelData.direction;
10695
+ const eventDetails = {
10696
+ detail: {
10697
+ element,
10698
+ eventName: enums.Events.MOUSE_WHEEL,
10699
+ renderingEngineId: enabledElement.renderingEngineId,
10700
+ viewportId: viewport.id,
10701
+ camera: {},
10702
+ deltaPoints: {
10703
+ page: points.page,
10704
+ client: points.client,
10705
+ world: points.world,
10706
+ canvas: [0, -direction * 5],
10707
+ },
10708
+ startPoints: points,
10709
+ lastPoints: points,
10710
+ currentPoints: points,
10711
+ },
10712
+ };
10713
+ if (viewport.type === esm.Enums.ViewportType.STACK) {
10714
+ this.preMouseDownCallback(eventDetails);
10715
+ }
10716
+ this._dragCallback(eventDetails);
10717
+ }
10595
10718
  _panCallback(evt) {
10596
10719
  const { element, deltaPoints } = evt.detail;
10597
10720
  const enabledElement = (0,esm.getEnabledElement)(element);
@@ -15614,6 +15737,7 @@ class LengthTool extends base/* AnnotationTool */.EC {
15614
15737
  return;
15615
15738
  }
15616
15739
  const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, viewport, } = this.hydrateBase(LengthTool, enabledElement, points, options);
15740
+ const { toolInstance, ...serializableOptions } = options || {};
15617
15741
  const annotation = {
15618
15742
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
15619
15743
  data: {
@@ -15631,7 +15755,7 @@ class LengthTool extends base/* AnnotationTool */.EC {
15631
15755
  viewPlaneNormal,
15632
15756
  FrameOfReferenceUID,
15633
15757
  referencedImageId,
15634
- ...options,
15758
+ ...serializableOptions,
15635
15759
  },
15636
15760
  };
15637
15761
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -16177,6 +16301,7 @@ var isViewportPreScaled = __webpack_require__(18990);
16177
16301
 
16178
16302
 
16179
16303
 
16304
+
16180
16305
  const { transformWorldToIndex: ProbeTool_transformWorldToIndex } = esm.utilities;
16181
16306
  class ProbeTool extends base/* AnnotationTool */.EC {
16182
16307
  static { this.toolName = 'Probe'; }
@@ -16187,6 +16312,10 @@ class ProbeTool extends base/* AnnotationTool */.EC {
16187
16312
  preventHandleOutsideImage: false,
16188
16313
  getTextLines: ProbeTool_defaultGetTextLines,
16189
16314
  handleRadius: '6',
16315
+ textCanvasOffset: {
16316
+ x: 6,
16317
+ y: -6,
16318
+ },
16190
16319
  },
16191
16320
  }; }
16192
16321
  constructor(toolProps = {}, defaultToolProps) {
@@ -16355,6 +16484,9 @@ class ProbeTool extends base/* AnnotationTool */.EC {
16355
16484
  console.warn('Rendering Engine has been destroyed');
16356
16485
  return renderStatus;
16357
16486
  }
16487
+ if (!(0,annotationVisibility.isAnnotationVisible)(annotationUID)) {
16488
+ continue;
16489
+ }
16358
16490
  const handleGroupUID = '0';
16359
16491
  (0,drawingSvg.drawHandles)(svgDrawingHelper, annotationUID, handleGroupUID, [canvasCoordinates], { color, lineWidth, handleRadius: this.configuration.handleRadius });
16360
16492
  renderStatus = true;
@@ -16365,8 +16497,8 @@ class ProbeTool extends base/* AnnotationTool */.EC {
16365
16497
  const textLines = this.configuration.getTextLines(data, targetId);
16366
16498
  if (textLines) {
16367
16499
  const textCanvasCoordinates = [
16368
- canvasCoordinates[0] + 6,
16369
- canvasCoordinates[1] - 6,
16500
+ canvasCoordinates[0] + this.configuration.textCanvasOffset.x,
16501
+ canvasCoordinates[1] + this.configuration.textCanvasOffset.y,
16370
16502
  ];
16371
16503
  const textUID = '0';
16372
16504
  (0,drawingSvg.drawTextBox)(svgDrawingHelper, annotationUID, textUID, textLines, [textCanvasCoordinates[0], textCanvasCoordinates[1]], options);
@@ -16390,6 +16522,7 @@ class ProbeTool extends base/* AnnotationTool */.EC {
16390
16522
  return;
16391
16523
  }
16392
16524
  const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, viewUp, instance, viewport, } = this.hydrateBase(ProbeTool, enabledElement, points, options);
16525
+ const { toolInstance, ...serializableOptions } = options || {};
16393
16526
  const annotation = {
16394
16527
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
16395
16528
  data: {
@@ -16407,7 +16540,7 @@ class ProbeTool extends base/* AnnotationTool */.EC {
16407
16540
  viewPlaneNormal,
16408
16541
  FrameOfReferenceUID,
16409
16542
  referencedImageId,
16410
- ...options,
16543
+ ...serializableOptions,
16411
16544
  },
16412
16545
  };
16413
16546
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -17313,6 +17446,7 @@ class EllipticalROITool extends base/* AnnotationTool */.EC {
17313
17446
  return;
17314
17447
  }
17315
17448
  const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, viewport, } = this.hydrateBase(EllipticalROITool, enabledElement, points, options);
17449
+ const { toolInstance, ...serializableOptions } = options || {};
17316
17450
  const annotation = {
17317
17451
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
17318
17452
  data: {
@@ -17333,7 +17467,7 @@ class EllipticalROITool extends base/* AnnotationTool */.EC {
17333
17467
  viewPlaneNormal,
17334
17468
  FrameOfReferenceUID,
17335
17469
  referencedImageId,
17336
- ...options,
17470
+ ...serializableOptions,
17337
17471
  },
17338
17472
  };
17339
17473
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -17969,6 +18103,7 @@ class CircleROITool extends base/* AnnotationTool */.EC {
17969
18103
  return;
17970
18104
  }
17971
18105
  const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, viewport, } = this.hydrateBase(CircleROITool, enabledElement, points, options);
18106
+ const { toolInstance, ...serializableOptions } = options || {};
17972
18107
  const annotation = {
17973
18108
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
17974
18109
  data: {
@@ -17999,7 +18134,7 @@ class CircleROITool extends base/* AnnotationTool */.EC {
17999
18134
  viewPlaneNormal,
18000
18135
  FrameOfReferenceUID,
18001
18136
  referencedImageId,
18002
- ...options,
18137
+ ...serializableOptions,
18003
18138
  },
18004
18139
  };
18005
18140
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -19135,6 +19270,7 @@ class SplineROITool extends ContourSegmentationBaseTool/* default */.A {
19135
19270
  const splineConfig = instance._getSplineConfig(splineType);
19136
19271
  const SplineClass = splineConfig.Class;
19137
19272
  const splineInstance = new SplineClass();
19273
+ const { toolInstance, ...serializableOptions } = options || {};
19138
19274
  const annotation = {
19139
19275
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
19140
19276
  data: {
@@ -19161,7 +19297,7 @@ class SplineROITool extends ContourSegmentationBaseTool/* default */.A {
19161
19297
  viewPlaneNormal,
19162
19298
  FrameOfReferenceUID,
19163
19299
  referencedImageId,
19164
- ...options,
19300
+ ...serializableOptions,
19165
19301
  },
19166
19302
  };
19167
19303
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -20363,6 +20499,7 @@ class ArrowAnnotateTool extends base/* AnnotationTool */.EC {
20363
20499
  return;
20364
20500
  }
20365
20501
  const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, viewport, } = this.hydrateBase(ArrowAnnotateTool, enabledElement, points, options);
20502
+ const { toolInstance, ...serializableOptions } = options || {};
20366
20503
  const annotation = {
20367
20504
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
20368
20505
  data: {
@@ -20381,7 +20518,7 @@ class ArrowAnnotateTool extends base/* AnnotationTool */.EC {
20381
20518
  viewPlaneNormal,
20382
20519
  FrameOfReferenceUID,
20383
20520
  referencedImageId,
20384
- ...options,
20521
+ ...serializableOptions,
20385
20522
  },
20386
20523
  };
20387
20524
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -20456,6 +20593,8 @@ class AngleTool extends base/* AnnotationTool */.EC {
20456
20593
  supportedInteractionTypes: ['Mouse', 'Touch'],
20457
20594
  configuration: {
20458
20595
  shadow: true,
20596
+ showAngleArc: false,
20597
+ arcOffset: 5,
20459
20598
  preventHandleOutsideImage: false,
20460
20599
  getTextLines: AngleTool_defaultGetTextLines,
20461
20600
  },
@@ -20604,6 +20743,7 @@ class AngleTool extends base/* AnnotationTool */.EC {
20604
20743
  (0,annotationState.removeAnnotation)(annotation.annotationUID);
20605
20744
  }
20606
20745
  (0,triggerAnnotationRenderForViewportIds/* default */.A)(viewportIdsToRender);
20746
+ this.doneEditMemo();
20607
20747
  if (newAnnotation) {
20608
20748
  (0,helpers_state.triggerAnnotationCompleted)(annotation);
20609
20749
  }
@@ -20614,8 +20754,9 @@ class AngleTool extends base/* AnnotationTool */.EC {
20614
20754
  this.isDrawing = true;
20615
20755
  const eventDetail = evt.detail;
20616
20756
  const { element } = eventDetail;
20617
- const { annotation, viewportIdsToRender, handleIndex, movingTextBox } = this.editData;
20757
+ const { annotation, viewportIdsToRender, handleIndex, movingTextBox, newAnnotation, } = this.editData;
20618
20758
  const { data } = annotation;
20759
+ this.createMemo(element, annotation, { newAnnotation });
20619
20760
  if (movingTextBox) {
20620
20761
  const { deltaPoints } = eventDetail;
20621
20762
  const worldPosDelta = deltaPoints.world;
@@ -20732,7 +20873,7 @@ class AngleTool extends base/* AnnotationTool */.EC {
20732
20873
  const { annotationUID, data } = annotation;
20733
20874
  const { points, activeHandleIndex } = data.handles;
20734
20875
  styleSpecifier.annotationUID = annotationUID;
20735
- const { color, lineWidth, lineDash } = this.getAnnotationStyle({
20876
+ const { color, lineWidth, lineDash, angleArcLineDash } = this.getAnnotationStyle({
20736
20877
  annotation,
20737
20878
  styleSpecifier,
20738
20879
  });
@@ -20784,6 +20925,36 @@ class AngleTool extends base/* AnnotationTool */.EC {
20784
20925
  width: lineWidth,
20785
20926
  lineDash,
20786
20927
  });
20928
+ if (this.configuration.showAngleArc) {
20929
+ const center = canvasCoordinates[1];
20930
+ const offset = this.configuration.arcOffset;
20931
+ const radius = Math.min(math_line.distanceToPoint([center[0], center[1]], [canvasCoordinates[0][0], canvasCoordinates[0][1]], [canvasCoordinates[2][0], canvasCoordinates[2][1]]), math_line.distanceToPoint([center[0], center[1]], [canvasCoordinates[2][0], canvasCoordinates[2][1]], [canvasCoordinates[0][0], canvasCoordinates[0][1]])) / offset;
20932
+ const anglePoints = [];
20933
+ let startAngle = Math.atan2(canvasCoordinates[0][1] - center[1], canvasCoordinates[0][0] - center[0]);
20934
+ let endAngle = Math.atan2(canvasCoordinates[2][1] - center[1], canvasCoordinates[2][0] - center[0]);
20935
+ if (endAngle < startAngle) {
20936
+ endAngle += 2 * Math.PI;
20937
+ }
20938
+ const angleDifference = endAngle - startAngle;
20939
+ if (angleDifference > Math.PI) {
20940
+ const temp = startAngle;
20941
+ startAngle = endAngle;
20942
+ endAngle = temp + 2 * Math.PI;
20943
+ }
20944
+ const segments = 32;
20945
+ for (let i = 0; i <= segments; i++) {
20946
+ const angle = startAngle + (i / segments) * (endAngle - startAngle);
20947
+ anglePoints.push([
20948
+ center[0] + radius * Math.cos(angle),
20949
+ center[1] + radius * Math.sin(angle),
20950
+ ]);
20951
+ }
20952
+ (0,drawingSvg.drawPath)(svgDrawingHelper, annotationUID, '3', anglePoints, {
20953
+ color: color,
20954
+ width: lineWidth,
20955
+ lineDash: angleArcLineDash,
20956
+ });
20957
+ }
20787
20958
  if (!data.cachedStats[targetId]?.angle) {
20788
20959
  continue;
20789
20960
  }
@@ -20828,6 +20999,7 @@ class AngleTool extends base/* AnnotationTool */.EC {
20828
20999
  return;
20829
21000
  }
20830
21001
  const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, viewport, } = this.hydrateBase(AngleTool, enabledElement, points, options);
21002
+ const { toolInstance, ...serializableOptions } = options || {};
20831
21003
  const annotation = {
20832
21004
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
20833
21005
  data: {
@@ -20845,7 +21017,7 @@ class AngleTool extends base/* AnnotationTool */.EC {
20845
21017
  viewPlaneNormal,
20846
21018
  FrameOfReferenceUID,
20847
21019
  referencedImageId,
20848
- ...options,
21020
+ ...serializableOptions,
20849
21021
  },
20850
21022
  };
20851
21023
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -24985,6 +25157,7 @@ class SegmentBidirectionalTool extends BidirectionalTool/* default */.A {
24985
25157
  const [major0, major1] = majorAxis;
24986
25158
  const [minor0, minor1] = minorAxis;
24987
25159
  const points = [major0, major1, minor0, minor1];
25160
+ const { toolInstance, ...serializableOptions } = options || {};
24988
25161
  const annotation = {
24989
25162
  annotationUID: options?.annotationUID || esm.utilities.uuidv4(),
24990
25163
  data: {
@@ -25016,7 +25189,7 @@ class SegmentBidirectionalTool extends BidirectionalTool/* default */.A {
25016
25189
  viewPlaneNormal,
25017
25190
  FrameOfReferenceUID,
25018
25191
  referencedImageId,
25019
- ...options,
25192
+ ...serializableOptions,
25020
25193
  },
25021
25194
  };
25022
25195
  (0,annotationState.addAnnotation)(annotation, viewport.element);
@@ -28007,7 +28180,7 @@ const segmentationRenderingEngine = new SegmentationRenderingEngine();
28007
28180
  /* unused harmony export default */
28008
28181
  /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(15327);
28009
28182
  /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(99737);
28010
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(33739);
28183
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(642);
28011
28184
  /* harmony import */ var _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99341);
28012
28185
  /* harmony import */ var _triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(49906);
28013
28186
  /* harmony import */ var _SegmentationStyle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(92686);
@@ -28962,13 +29135,16 @@ function normalizeSegments(segmentsConfig, type, data) {
28962
29135
  const normalizedSegments = {};
28963
29136
  if (segmentsConfig) {
28964
29137
  Object.entries(segmentsConfig).forEach(([segmentIndex, segment]) => {
28965
- normalizedSegments[segmentIndex] = {
29138
+ const { label, locked, cachedStats, active, ...rest } = segment;
29139
+ const normalizedSegment = {
28966
29140
  segmentIndex: Number(segmentIndex),
28967
- label: segment.label ?? `Segment ${segmentIndex}`,
28968
- locked: segment.locked ?? false,
28969
- cachedStats: segment.cachedStats ?? {},
28970
- active: segment.active ?? false,
29141
+ label: label ?? `Segment ${segmentIndex}`,
29142
+ locked: locked ?? false,
29143
+ cachedStats: cachedStats ?? {},
29144
+ active: active ?? false,
29145
+ ...rest,
28971
29146
  };
29147
+ normalizedSegments[segmentIndex] = normalizedSegment;
28972
29148
  });
28973
29149
  }
28974
29150
  else if (type === enums.SegmentationRepresentations.Surface) {
@@ -30902,6 +31078,7 @@ class BidirectionalTool extends _base__WEBPACK_IMPORTED_MODULE_3__/* .Annotation
30902
31078
  const [major0, major1] = majorAxis;
30903
31079
  const [minor0, minor1] = minorAxis;
30904
31080
  const points = [major0, major1, minor0, minor1];
31081
+ const { toolInstance, ...serializableOptions } = options || {};
30905
31082
  const annotation = {
30906
31083
  annotationUID: options?.annotationUID || _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.utilities.uuidv4(),
30907
31084
  data: {
@@ -30931,7 +31108,7 @@ class BidirectionalTool extends _base__WEBPACK_IMPORTED_MODULE_3__/* .Annotation
30931
31108
  viewPlaneNormal,
30932
31109
  FrameOfReferenceUID,
30933
31110
  referencedImageId,
30934
- ...options,
31111
+ ...serializableOptions,
30935
31112
  },
30936
31113
  };
30937
31114
  (0,_stateManagement_annotation_annotationState__WEBPACK_IMPORTED_MODULE_5__.addAnnotation)(annotation, viewport.element);
@@ -31244,6 +31421,7 @@ class PlanarFreehandROITool extends _base_ContourSegmentationBaseTool__WEBPACK_I
31244
31421
  toolGroupId: this.toolGroupId,
31245
31422
  toolName: this.getToolName(),
31246
31423
  viewportId: enabledElement.viewport.id,
31424
+ annotationUID: annotation.annotationUID,
31247
31425
  };
31248
31426
  const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
31249
31427
  if (!options.visibility) {
@@ -32133,6 +32311,7 @@ class RectangleROITool extends _base__WEBPACK_IMPORTED_MODULE_0__/* .AnnotationT
32133
32311
  return;
32134
32312
  }
32135
32313
  const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, viewport, } = this.hydrateBase(RectangleROITool, enabledElement, points, options);
32314
+ const { toolInstance, ...serializableOptions } = options || {};
32136
32315
  const annotation = {
32137
32316
  annotationUID: options?.annotationUID || _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.utilities.uuidv4(),
32138
32317
  data: {
@@ -32153,7 +32332,7 @@ class RectangleROITool extends _base__WEBPACK_IMPORTED_MODULE_0__/* .AnnotationT
32153
32332
  viewPlaneNormal,
32154
32333
  FrameOfReferenceUID,
32155
32334
  referencedImageId,
32156
- ...options,
32335
+ ...serializableOptions,
32157
32336
  },
32158
32337
  };
32159
32338
  (0,_stateManagement__WEBPACK_IMPORTED_MODULE_4__/* .addAnnotation */ .lC)(annotation, viewport.element);
@@ -32518,6 +32697,9 @@ class BrushTool extends _LabelmapBaseTool__WEBPACK_IMPORTED_MODULE_10__/* ["defa
32518
32697
  }
32519
32698
  this.doneEditMemo();
32520
32699
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
32700
+ if (!enabledElement) {
32701
+ return;
32702
+ }
32521
32703
  this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), _enums__WEBPACK_IMPORTED_MODULE_2__.StrategyCallbacks.RejectPreview);
32522
32704
  this._previewData.preview = null;
32523
32705
  this._previewData.isDrag = false;
@@ -36713,6 +36895,1251 @@ var vtkImageData$1 = {
36713
36895
 
36714
36896
 
36715
36897
 
36898
+ /***/ }),
36899
+
36900
+ /***/ 642:
36901
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
36902
+
36903
+ "use strict";
36904
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
36905
+ /* harmony export */ Ay: () => (/* binding */ vtkColorTransferFunction$1)
36906
+ /* harmony export */ });
36907
+ /* unused harmony exports extend, newInstance */
36908
+ /* harmony import */ var _macros2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28906);
36909
+ /* harmony import */ var _Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16632);
36910
+ /* harmony import */ var _Common_Core_ScalarsToColors_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(80993);
36911
+ /* harmony import */ var _ColorTransferFunction_Constants_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25128);
36912
+
36913
+
36914
+
36915
+
36916
+
36917
+ const {
36918
+ ColorSpace,
36919
+ Scale
36920
+ } = _ColorTransferFunction_Constants_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Ay;
36921
+ const {
36922
+ ScalarMappingTarget
36923
+ } = _Common_Core_ScalarsToColors_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Ay;
36924
+ const {
36925
+ vtkDebugMacro,
36926
+ vtkErrorMacro,
36927
+ vtkWarningMacro
36928
+ } = _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m;
36929
+
36930
+ // ----------------------------------------------------------------------------
36931
+ // Global methods
36932
+ // ----------------------------------------------------------------------------
36933
+ /* eslint-disable no-continue */
36934
+
36935
+ // Convert to and from a special polar version of CIELAB (useful for creating
36936
+ // continuous diverging color maps).
36937
+ function vtkColorTransferFunctionLabToMsh(lab, msh) {
36938
+ const L = lab[0];
36939
+ const a = lab[1];
36940
+ const b = lab[2];
36941
+ const M = Math.sqrt(L * L + a * a + b * b);
36942
+ const s = M > 0.001 ? Math.acos(L / M) : 0.0;
36943
+ const h = s > 0.001 ? Math.atan2(b, a) : 0.0;
36944
+ msh[0] = M;
36945
+ msh[1] = s;
36946
+ msh[2] = h;
36947
+ }
36948
+ function vtkColorTransferFunctionMshToLab(msh, lab) {
36949
+ const M = msh[0];
36950
+ const s = msh[1];
36951
+ const h = msh[2];
36952
+ lab[0] = M * Math.cos(s);
36953
+ lab[1] = M * Math.sin(s) * Math.cos(h);
36954
+ lab[2] = M * Math.sin(s) * Math.sin(h);
36955
+ }
36956
+
36957
+ // For the case when interpolating from a saturated color to an unsaturated
36958
+ // color, find a hue for the unsaturated color that makes sense.
36959
+ function vtkColorTransferFunctionAdjustHue(msh, unsatM) {
36960
+ if (msh[0] >= unsatM - 0.1) {
36961
+ // The best we can do is hold hue constant.
36962
+ return msh[2];
36963
+ }
36964
+
36965
+ // This equation is designed to make the perceptual change of the
36966
+ // interpolation to be close to constant.
36967
+ const hueSpin = msh[1] * Math.sqrt(unsatM * unsatM - msh[0] * msh[0]) / (msh[0] * Math.sin(msh[1]));
36968
+ // Spin hue away from 0 except in purple hues.
36969
+ if (msh[2] > -0.3 * Math.PI) {
36970
+ return msh[2] + hueSpin;
36971
+ }
36972
+ return msh[2] - hueSpin;
36973
+ }
36974
+ function vtkColorTransferFunctionAngleDiff(a1, a2) {
36975
+ let adiff = a1 - a2;
36976
+ if (adiff < 0.0) {
36977
+ adiff = -adiff;
36978
+ }
36979
+ while (adiff >= 2.0 * Math.PI) {
36980
+ adiff -= 2.0 * Math.PI;
36981
+ }
36982
+ if (adiff > Math.PI) {
36983
+ adiff = 2.0 * Math.PI - adiff;
36984
+ }
36985
+ return adiff;
36986
+ }
36987
+
36988
+ // Interpolate a diverging color map.
36989
+ function vtkColorTransferFunctionInterpolateDiverging(s, rgb1, rgb2, result) {
36990
+ const lab1 = [];
36991
+ const lab2 = [];
36992
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb1, lab1);
36993
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb2, lab2);
36994
+ const msh1 = [];
36995
+ const msh2 = [];
36996
+ vtkColorTransferFunctionLabToMsh(lab1, msh1);
36997
+ vtkColorTransferFunctionLabToMsh(lab2, msh2);
36998
+
36999
+ // If the endpoints are distinct saturated colors, then place white in between
37000
+ // them.
37001
+ let localS = s;
37002
+ if (msh1[1] > 0.05 && msh2[1] > 0.05 && vtkColorTransferFunctionAngleDiff(msh1[2], msh2[2]) > 0.33 * Math.PI) {
37003
+ // Insert the white midpoint by setting one end to white and adjusting the
37004
+ // scalar value.
37005
+ let Mmid = Math.max(msh1[0], msh2[0]);
37006
+ Mmid = Math.max(88.0, Mmid);
37007
+ if (s < 0.5) {
37008
+ msh2[0] = Mmid;
37009
+ msh2[1] = 0.0;
37010
+ msh2[2] = 0.0;
37011
+ localS *= 2.0;
37012
+ } else {
37013
+ msh1[0] = Mmid;
37014
+ msh1[1] = 0.0;
37015
+ msh1[2] = 0.0;
37016
+ localS = 2.0 * localS - 1.0;
37017
+ }
37018
+ }
37019
+
37020
+ // If one color has no saturation, then its hue value is invalid. In this
37021
+ // case, we want to set it to something logical so that the interpolation of
37022
+ // hue makes sense.
37023
+ if (msh1[1] < 0.05 && msh2[1] > 0.05) {
37024
+ msh1[2] = vtkColorTransferFunctionAdjustHue(msh2, msh1[0]);
37025
+ } else if (msh2[1] < 0.05 && msh1[1] > 0.05) {
37026
+ msh2[2] = vtkColorTransferFunctionAdjustHue(msh1, msh2[0]);
37027
+ }
37028
+ const mshTmp = [];
37029
+ mshTmp[0] = (1 - localS) * msh1[0] + localS * msh2[0];
37030
+ mshTmp[1] = (1 - localS) * msh1[1] + localS * msh2[1];
37031
+ mshTmp[2] = (1 - localS) * msh1[2] + localS * msh2[2];
37032
+
37033
+ // Now convert back to RGB
37034
+ const labTmp = [];
37035
+ vtkColorTransferFunctionMshToLab(mshTmp, labTmp);
37036
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.O)(labTmp, result);
37037
+ }
37038
+
37039
+ // ----------------------------------------------------------------------------
37040
+ // vtkColorTransferFunction methods
37041
+ // ----------------------------------------------------------------------------
37042
+
37043
+ function vtkColorTransferFunction(publicAPI, model) {
37044
+ // Set our className
37045
+ model.classHierarchy.push('vtkColorTransferFunction');
37046
+
37047
+ // Return the number of points which specify this function
37048
+ publicAPI.getSize = () => model.nodes.length;
37049
+
37050
+ //----------------------------------------------------------------------------
37051
+ // Add a point defined in RGB
37052
+ publicAPI.addRGBPoint = (x, r, g, b) => publicAPI.addRGBPointLong(x, r, g, b, 0.5, 0.0);
37053
+
37054
+ //----------------------------------------------------------------------------
37055
+ // Add a point defined in RGB
37056
+ publicAPI.addRGBPointLong = function (x, r, g, b) {
37057
+ let midpoint = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0.5;
37058
+ let sharpness = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0.0;
37059
+ // Error check
37060
+ if (midpoint < 0.0 || midpoint > 1.0) {
37061
+ vtkErrorMacro('Midpoint outside range [0.0, 1.0]');
37062
+ return -1;
37063
+ }
37064
+ if (sharpness < 0.0 || sharpness > 1.0) {
37065
+ vtkErrorMacro('Sharpness outside range [0.0, 1.0]');
37066
+ return -1;
37067
+ }
37068
+
37069
+ // remove any node already at this X location
37070
+ if (!model.allowDuplicateScalars) {
37071
+ publicAPI.removePoint(x);
37072
+ }
37073
+
37074
+ // Create the new node
37075
+ const node = {
37076
+ x,
37077
+ r,
37078
+ g,
37079
+ b,
37080
+ midpoint,
37081
+ sharpness
37082
+ };
37083
+
37084
+ // Add it, then sort to get everything in order
37085
+ model.nodes.push(node);
37086
+ publicAPI.sortAndUpdateRange();
37087
+
37088
+ // We need to find the index of the node we just added in order
37089
+ // to return this value
37090
+ let i = 0;
37091
+ for (; i < model.nodes.length; i++) {
37092
+ if (model.nodes[i].x === x) {
37093
+ break;
37094
+ }
37095
+ }
37096
+
37097
+ // If we didn't find it, something went horribly wrong so
37098
+ // return -1
37099
+ if (i < model.nodes.length) {
37100
+ return i;
37101
+ }
37102
+ return -1;
37103
+ };
37104
+
37105
+ //----------------------------------------------------------------------------
37106
+ // Add a point defined in HSV
37107
+ publicAPI.addHSVPoint = (x, h, s, v) => publicAPI.addHSVPointLong(x, h, s, v, 0.5, 0.0);
37108
+
37109
+ //----------------------------------------------------------------------------
37110
+ // Add a point defined in HSV
37111
+ publicAPI.addHSVPointLong = function (x, h, s, v) {
37112
+ let midpoint = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0.5;
37113
+ let sharpness = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0.0;
37114
+ const rgb = [];
37115
+ const hsv = [h, s, v];
37116
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsv, rgb);
37117
+ return publicAPI.addRGBPoint(x, rgb[0], rgb[1], rgb[2], midpoint, sharpness);
37118
+ };
37119
+
37120
+ //----------------------------------------------------------------------------
37121
+ // Set nodes directly
37122
+ publicAPI.setNodes = nodes => {
37123
+ if (model.nodes !== nodes) {
37124
+ const before = JSON.stringify(model.nodes);
37125
+ model.nodes = nodes;
37126
+ const after = JSON.stringify(model.nodes);
37127
+ if (publicAPI.sortAndUpdateRange() || before !== after) {
37128
+ publicAPI.modified();
37129
+ return true;
37130
+ }
37131
+ }
37132
+ return false;
37133
+ };
37134
+
37135
+ //----------------------------------------------------------------------------
37136
+ // Sort the vector in increasing order, then fill in
37137
+ // the Range
37138
+ publicAPI.sortAndUpdateRange = () => {
37139
+ const before = JSON.stringify(model.nodes);
37140
+ model.nodes.sort((a, b) => a.x - b.x);
37141
+ const after = JSON.stringify(model.nodes);
37142
+ const modifiedInvoked = publicAPI.updateRange();
37143
+ // If range is updated, Modified() has been called, don't call it again.
37144
+ if (!modifiedInvoked && before !== after) {
37145
+ publicAPI.modified();
37146
+ return true;
37147
+ }
37148
+ return modifiedInvoked;
37149
+ };
37150
+
37151
+ //----------------------------------------------------------------------------
37152
+ publicAPI.updateRange = () => {
37153
+ const oldRange = [2];
37154
+ oldRange[0] = model.mappingRange[0];
37155
+ oldRange[1] = model.mappingRange[1];
37156
+ const size = model.nodes.length;
37157
+ if (size) {
37158
+ model.mappingRange[0] = model.nodes[0].x;
37159
+ model.mappingRange[1] = model.nodes[size - 1].x;
37160
+ } else {
37161
+ model.mappingRange[0] = 0;
37162
+ model.mappingRange[1] = 0;
37163
+ }
37164
+
37165
+ // If the range is the same, then no need to call Modified()
37166
+ if (oldRange[0] === model.mappingRange[0] && oldRange[1] === model.mappingRange[1]) {
37167
+ return false;
37168
+ }
37169
+ publicAPI.modified();
37170
+ return true;
37171
+ };
37172
+
37173
+ //----------------------------------------------------------------------------
37174
+ // Remove a point
37175
+ publicAPI.removePoint = x => {
37176
+ // First find the node since we need to know its
37177
+ // index as our return value
37178
+ let i = 0;
37179
+ for (; i < model.nodes.length; i++) {
37180
+ if (model.nodes[i].x === x) {
37181
+ break;
37182
+ }
37183
+ }
37184
+ const retVal = i;
37185
+
37186
+ // If the node doesn't exist, we return -1
37187
+ if (i >= model.nodes.length) {
37188
+ return -1;
37189
+ }
37190
+
37191
+ // If the first or last point has been removed, then we update the range
37192
+ // No need to sort here as the order of points hasn't changed.
37193
+ let modifiedInvoked = false;
37194
+ model.nodes.splice(i, 1);
37195
+ if (i === 0 || i === model.nodes.length) {
37196
+ modifiedInvoked = publicAPI.updateRange();
37197
+ }
37198
+ if (!modifiedInvoked) {
37199
+ publicAPI.modified();
37200
+ }
37201
+ return retVal;
37202
+ };
37203
+
37204
+ //----------------------------------------------------------------------------
37205
+ publicAPI.movePoint = (oldX, newX) => {
37206
+ if (oldX === newX) {
37207
+ // Nothing to do.
37208
+ return;
37209
+ }
37210
+ publicAPI.removePoint(newX);
37211
+ for (let i = 0; i < model.nodes.length; i++) {
37212
+ if (model.nodes[i].x === oldX) {
37213
+ model.nodes[i].x = newX;
37214
+ publicAPI.sortAndUpdateRange();
37215
+ break;
37216
+ }
37217
+ }
37218
+ };
37219
+
37220
+ //----------------------------------------------------------------------------
37221
+ // Remove all points
37222
+ publicAPI.removeAllPoints = () => {
37223
+ model.nodes = [];
37224
+ publicAPI.sortAndUpdateRange();
37225
+ };
37226
+
37227
+ //----------------------------------------------------------------------------
37228
+ // Add a line defined in RGB
37229
+ publicAPI.addRGBSegment = (x1, r1, g1, b1, x2, r2, g2, b2) => {
37230
+ // First, find all points in this range and remove them
37231
+ publicAPI.sortAndUpdateRange();
37232
+ for (let i = 0; i < model.nodes.length;) {
37233
+ if (model.nodes[i].x >= x1 && model.nodes[i].x <= x2) {
37234
+ model.nodes.splice(i, 1);
37235
+ } else {
37236
+ i++;
37237
+ }
37238
+ }
37239
+
37240
+ // Now add the points
37241
+ publicAPI.addRGBPointLong(x1, r1, g1, b1, 0.5, 0.0);
37242
+ publicAPI.addRGBPointLong(x2, r2, g2, b2, 0.5, 0.0);
37243
+ publicAPI.modified();
37244
+ };
37245
+
37246
+ //----------------------------------------------------------------------------
37247
+ // Add a line defined in HSV
37248
+ publicAPI.addHSVSegment = (x1, h1, s1, v1, x2, h2, s2, v2) => {
37249
+ const hsv1 = [h1, s1, v1];
37250
+ const hsv2 = [h2, s2, v2];
37251
+ const rgb1 = [];
37252
+ const rgb2 = [];
37253
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsv1, rgb1);
37254
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsv2, rgb2);
37255
+ publicAPI.addRGBSegment(x1, rgb1[0], rgb1[1], rgb1[2], x2, rgb2[0], rgb2[1], rgb2[2]);
37256
+ };
37257
+
37258
+ //----------------------------------------------------------------------------
37259
+ // Returns the RGBA color evaluated at the specified location
37260
+ publicAPI.mapValue = x => {
37261
+ const rgb = [];
37262
+ publicAPI.getColor(x, rgb);
37263
+ return [Math.floor(255.0 * rgb[0] + 0.5), Math.floor(255.0 * rgb[1] + 0.5), Math.floor(255.0 * rgb[2] + 0.5), 255];
37264
+ };
37265
+
37266
+ //----------------------------------------------------------------------------
37267
+ // Returns the RGB color evaluated at the specified location
37268
+ publicAPI.getColor = (x, rgb) => {
37269
+ if (model.indexedLookup) {
37270
+ const numNodes = publicAPI.getSize();
37271
+ // todo
37272
+ const idx = publicAPI.getAnnotatedValueIndexInternal(x);
37273
+ if (idx < 0 || numNodes === 0) {
37274
+ const nanColor = publicAPI.getNanColorByReference();
37275
+ rgb[0] = nanColor[0];
37276
+ rgb[1] = nanColor[1];
37277
+ rgb[2] = nanColor[2];
37278
+ } else {
37279
+ const nodeVal = [];
37280
+ publicAPI.getNodeValue(idx % numNodes, nodeVal);
37281
+ // nodeVal[0] is the x value. nodeVal[1...3] is rgb.
37282
+ rgb[0] = nodeVal[1];
37283
+ rgb[1] = nodeVal[2];
37284
+ rgb[2] = nodeVal[3];
37285
+ }
37286
+ return;
37287
+ }
37288
+ publicAPI.getTable(x, x, 1, rgb);
37289
+ };
37290
+
37291
+ //----------------------------------------------------------------------------
37292
+ // Returns the red color evaluated at the specified location
37293
+ publicAPI.getRedValue = x => {
37294
+ const rgb = [];
37295
+ publicAPI.getColor(x, rgb);
37296
+ return rgb[0];
37297
+ };
37298
+
37299
+ //----------------------------------------------------------------------------
37300
+ // Returns the green color evaluated at the specified location
37301
+ publicAPI.getGreenValue = x => {
37302
+ const rgb = [];
37303
+ publicAPI.getColor(x, rgb);
37304
+ return rgb[1];
37305
+ };
37306
+
37307
+ //----------------------------------------------------------------------------
37308
+ // Returns the blue color evaluated at the specified location
37309
+ publicAPI.getBlueValue = x => {
37310
+ const rgb = [];
37311
+ publicAPI.getColor(x, rgb);
37312
+ return rgb[2];
37313
+ };
37314
+
37315
+ //----------------------------------------------------------------------------
37316
+ // Returns a table of RGB colors at regular intervals along the function
37317
+ publicAPI.getTable = (xStart_, xEnd_, size, table) => {
37318
+ // To handle BigInt limitation
37319
+ const xStart = Number(xStart_);
37320
+ const xEnd = Number(xEnd_);
37321
+
37322
+ // Special case: If either the start or end is a NaN, then all any
37323
+ // interpolation done on them is also a NaN. Therefore, fill the table with
37324
+ // the NaN color.
37325
+ if ((0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.i)(xStart) || (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.i)(xEnd)) {
37326
+ for (let i = 0; i < size; i++) {
37327
+ table[i * 3 + 0] = model.nanColor[0];
37328
+ table[i * 3 + 1] = model.nanColor[1];
37329
+ table[i * 3 + 2] = model.nanColor[2];
37330
+ }
37331
+ return;
37332
+ }
37333
+ let idx = 0;
37334
+ const numNodes = model.nodes.length;
37335
+
37336
+ // Need to keep track of the last value so that
37337
+ // we can fill in table locations past this with
37338
+ // this value if Clamping is On.
37339
+ let lastR = 0.0;
37340
+ let lastG = 0.0;
37341
+ let lastB = 0.0;
37342
+ if (numNodes !== 0) {
37343
+ lastR = model.nodes[numNodes - 1].r;
37344
+ lastG = model.nodes[numNodes - 1].g;
37345
+ lastB = model.nodes[numNodes - 1].b;
37346
+ }
37347
+ let x = 0.0;
37348
+ let x1 = 0.0;
37349
+ let x2 = 0.0;
37350
+ const rgb1 = [0.0, 0.0, 0.0];
37351
+ const rgb2 = [0.0, 0.0, 0.0];
37352
+ let midpoint = 0.0;
37353
+ let sharpness = 0.0;
37354
+ const tmpVec = [];
37355
+
37356
+ // If the scale is logarithmic, make sure the range is valid.
37357
+ let usingLogScale = model.scale === Scale.LOG10;
37358
+ if (usingLogScale) {
37359
+ // Note: This requires range[0] <= range[1].
37360
+ usingLogScale = model.mappingRange[0] > 0.0;
37361
+ }
37362
+ let logStart = 0.0;
37363
+ let logEnd = 0.0;
37364
+ let logX = 0.0;
37365
+ if (usingLogScale) {
37366
+ logStart = Math.log10(xStart);
37367
+ logEnd = Math.log10(xEnd);
37368
+ }
37369
+
37370
+ // For each table entry
37371
+ for (let i = 0; i < size; i++) {
37372
+ // Find our location in the table
37373
+ const tidx = 3 * i;
37374
+
37375
+ // Find our X location. If we are taking only 1 sample, make
37376
+ // it halfway between start and end (usually start and end will
37377
+ // be the same in this case)
37378
+ if (size > 1) {
37379
+ if (usingLogScale) {
37380
+ logX = logStart + i / (size - 1.0) * (logEnd - logStart);
37381
+ x = 10.0 ** logX;
37382
+ } else {
37383
+ x = xStart + i / (size - 1.0) * (xEnd - xStart);
37384
+ }
37385
+ } else if (usingLogScale) {
37386
+ logX = 0.5 * (logStart + logEnd);
37387
+ x = 10.0 ** logX;
37388
+ } else {
37389
+ x = 0.5 * (xStart + xEnd);
37390
+ }
37391
+
37392
+ // Linearly map x from mappingRange to [0, numberOfValues-1],
37393
+ // discretize (round down to the closest integer),
37394
+ // then map back to mappingRange
37395
+ if (model.discretize) {
37396
+ const range = model.mappingRange;
37397
+ if (x >= range[0] && x <= range[1]) {
37398
+ const numberOfValues = model.numberOfValues;
37399
+ const deltaRange = range[1] - range[0];
37400
+ if (numberOfValues <= 1) {
37401
+ x = range[0] + deltaRange / 2.0;
37402
+ } else {
37403
+ // normalize x
37404
+ const xn = (x - range[0]) / deltaRange;
37405
+ // discretize
37406
+ const discretizeIndex = (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.K)(numberOfValues * xn);
37407
+ // get discretized x
37408
+ x = range[0] + discretizeIndex / (numberOfValues - 1) * deltaRange;
37409
+ }
37410
+ }
37411
+ }
37412
+
37413
+ // Do we need to move to the next node?
37414
+ while (idx < numNodes && x > model.nodes[idx].x) {
37415
+ idx++;
37416
+ // If we are at a valid point index, fill in
37417
+ // the value at this node, and the one before (the
37418
+ // two that surround our current sample location)
37419
+ // idx cannot be 0 since we just incremented it.
37420
+ if (idx < numNodes) {
37421
+ x1 = model.nodes[idx - 1].x;
37422
+ x2 = model.nodes[idx].x;
37423
+ if (usingLogScale) {
37424
+ x1 = Math.log10(x1);
37425
+ x2 = Math.log10(x2);
37426
+ }
37427
+ rgb1[0] = model.nodes[idx - 1].r;
37428
+ rgb2[0] = model.nodes[idx].r;
37429
+ rgb1[1] = model.nodes[idx - 1].g;
37430
+ rgb2[1] = model.nodes[idx].g;
37431
+ rgb1[2] = model.nodes[idx - 1].b;
37432
+ rgb2[2] = model.nodes[idx].b;
37433
+
37434
+ // We only need the previous midpoint and sharpness
37435
+ // since these control this region
37436
+ midpoint = model.nodes[idx - 1].midpoint;
37437
+ sharpness = model.nodes[idx - 1].sharpness;
37438
+
37439
+ // Move midpoint away from extreme ends of range to avoid
37440
+ // degenerate math
37441
+ if (midpoint < 0.00001) {
37442
+ midpoint = 0.00001;
37443
+ }
37444
+ if (midpoint > 0.99999) {
37445
+ midpoint = 0.99999;
37446
+ }
37447
+ }
37448
+ }
37449
+
37450
+ // Are we at or past the end? If so, just use the last value
37451
+ if (x > model.mappingRange[1]) {
37452
+ table[tidx] = 0.0;
37453
+ table[tidx + 1] = 0.0;
37454
+ table[tidx + 2] = 0.0;
37455
+ if (model.clamping) {
37456
+ if (publicAPI.getUseAboveRangeColor()) {
37457
+ table[tidx] = model.aboveRangeColor[0];
37458
+ table[tidx + 1] = model.aboveRangeColor[1];
37459
+ table[tidx + 2] = model.aboveRangeColor[2];
37460
+ } else {
37461
+ table[tidx] = lastR;
37462
+ table[tidx + 1] = lastG;
37463
+ table[tidx + 2] = lastB;
37464
+ }
37465
+ }
37466
+ } else if (x < model.mappingRange[0] || (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.L)(x) && x < 0) {
37467
+ // we are before the first node? If so, duplicate this node's values.
37468
+ // We have to deal with -inf here
37469
+ table[tidx] = 0.0;
37470
+ table[tidx + 1] = 0.0;
37471
+ table[tidx + 2] = 0.0;
37472
+ if (model.clamping) {
37473
+ if (publicAPI.getUseBelowRangeColor()) {
37474
+ table[tidx] = model.belowRangeColor[0];
37475
+ table[tidx + 1] = model.belowRangeColor[1];
37476
+ table[tidx + 2] = model.belowRangeColor[2];
37477
+ } else if (numNodes > 0) {
37478
+ table[tidx] = model.nodes[0].r;
37479
+ table[tidx + 1] = model.nodes[0].g;
37480
+ table[tidx + 2] = model.nodes[0].b;
37481
+ }
37482
+ }
37483
+ } else if (idx === 0 && (Math.abs(x - xStart) < 1e-6 || model.discretize)) {
37484
+ if (numNodes > 0) {
37485
+ table[tidx] = model.nodes[0].r;
37486
+ table[tidx + 1] = model.nodes[0].g;
37487
+ table[tidx + 2] = model.nodes[0].b;
37488
+ } else {
37489
+ table[tidx] = 0.0;
37490
+ table[tidx + 1] = 0.0;
37491
+ table[tidx + 2] = 0.0;
37492
+ }
37493
+ } else {
37494
+ // OK, we are between two nodes - interpolate
37495
+ // Our first attempt at a normalized location [0,1] -
37496
+ // we will be modifying this based on midpoint and
37497
+ // sharpness to get the curve shape we want and to have
37498
+ // it pass through (y1+y2)/2 at the midpoint.
37499
+ let s = 0.0;
37500
+ if (usingLogScale) {
37501
+ s = (logX - x1) / (x2 - x1);
37502
+ } else {
37503
+ s = (x - x1) / (x2 - x1);
37504
+ }
37505
+
37506
+ // Readjust based on the midpoint - linear adjustment
37507
+ if (s < midpoint) {
37508
+ s = 0.5 * s / midpoint;
37509
+ } else {
37510
+ s = 0.5 + 0.5 * (s - midpoint) / (1.0 - midpoint);
37511
+ }
37512
+
37513
+ // override for sharpness > 0.99
37514
+ // In this case we just want piecewise constant
37515
+ if (sharpness > 0.99) {
37516
+ // Use the first value since we are below the midpoint
37517
+ if (s < 0.5) {
37518
+ table[tidx] = rgb1[0];
37519
+ table[tidx + 1] = rgb1[1];
37520
+ table[tidx + 2] = rgb1[2];
37521
+ continue;
37522
+ } else {
37523
+ // Use the second value at or above the midpoint
37524
+ table[tidx] = rgb2[0];
37525
+ table[tidx + 1] = rgb2[1];
37526
+ table[tidx + 2] = rgb2[2];
37527
+ continue;
37528
+ }
37529
+ }
37530
+
37531
+ // Override for sharpness < 0.01
37532
+ // In this case we want piecewise linear
37533
+ if (sharpness < 0.01) {
37534
+ // Simple linear interpolation
37535
+ if (model.colorSpace === ColorSpace.RGB) {
37536
+ table[tidx] = (1 - s) * rgb1[0] + s * rgb2[0];
37537
+ table[tidx + 1] = (1 - s) * rgb1[1] + s * rgb2[1];
37538
+ table[tidx + 2] = (1 - s) * rgb1[2] + s * rgb2[2];
37539
+ } else if (model.colorSpace === ColorSpace.HSV) {
37540
+ const hsv1 = [];
37541
+ const hsv2 = [];
37542
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb1, hsv1);
37543
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb2, hsv2);
37544
+ if (model.hSVWrap && (hsv1[0] - hsv2[0] > 0.5 || hsv2[0] - hsv1[0] > 0.5)) {
37545
+ if (hsv1[0] > hsv2[0]) {
37546
+ hsv1[0] -= 1.0;
37547
+ } else {
37548
+ hsv2[0] -= 1.0;
37549
+ }
37550
+ }
37551
+ const hsvTmp = [];
37552
+ hsvTmp[0] = (1.0 - s) * hsv1[0] + s * hsv2[0];
37553
+ if (hsvTmp[0] < 0.0) {
37554
+ hsvTmp[0] += 1.0;
37555
+ }
37556
+ hsvTmp[1] = (1.0 - s) * hsv1[1] + s * hsv2[1];
37557
+ hsvTmp[2] = (1.0 - s) * hsv1[2] + s * hsv2[2];
37558
+
37559
+ // Now convert this back to RGB
37560
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsvTmp, tmpVec);
37561
+ table[tidx] = tmpVec[0];
37562
+ table[tidx + 1] = tmpVec[1];
37563
+ table[tidx + 2] = tmpVec[2];
37564
+ } else if (model.colorSpace === ColorSpace.LAB) {
37565
+ const lab1 = [];
37566
+ const lab2 = [];
37567
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb1, lab1);
37568
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb2, lab2);
37569
+ const labTmp = [];
37570
+ labTmp[0] = (1 - s) * lab1[0] + s * lab2[0];
37571
+ labTmp[1] = (1 - s) * lab1[1] + s * lab2[1];
37572
+ labTmp[2] = (1 - s) * lab1[2] + s * lab2[2];
37573
+
37574
+ // Now convert back to RGB
37575
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.O)(labTmp, tmpVec);
37576
+ table[tidx] = tmpVec[0];
37577
+ table[tidx + 1] = tmpVec[1];
37578
+ table[tidx + 2] = tmpVec[2];
37579
+ } else if (model.colorSpace === ColorSpace.DIVERGING) {
37580
+ vtkColorTransferFunctionInterpolateDiverging(s, rgb1, rgb2, tmpVec);
37581
+ table[tidx] = tmpVec[0];
37582
+ table[tidx + 1] = tmpVec[1];
37583
+ table[tidx + 2] = tmpVec[2];
37584
+ } else {
37585
+ vtkErrorMacro('ColorSpace set to invalid value.', model.colorSpace);
37586
+ }
37587
+ continue;
37588
+ }
37589
+
37590
+ // We have a sharpness between [0.01, 0.99] - we will
37591
+ // used a modified hermite curve interpolation where we
37592
+ // derive the slope based on the sharpness, and we compress
37593
+ // the curve non-linearly based on the sharpness
37594
+
37595
+ // First, we will adjust our position based on sharpness in
37596
+ // order to make the curve sharper (closer to piecewise constant)
37597
+ if (s < 0.5) {
37598
+ s = 0.5 * (s * 2.0) ** (1.0 + 10.0 * sharpness);
37599
+ } else if (s > 0.5) {
37600
+ s = 1.0 - 0.5 * ((1.0 - s) * 2) ** (1 + 10.0 * sharpness);
37601
+ }
37602
+
37603
+ // Compute some coefficients we will need for the hermite curve
37604
+ const ss = s * s;
37605
+ const sss = ss * s;
37606
+ const h1 = 2.0 * sss - 3 * ss + 1;
37607
+ const h2 = -2 * sss + 3 * ss;
37608
+ const h3 = sss - 2 * ss + s;
37609
+ const h4 = sss - ss;
37610
+ let slope;
37611
+ let t;
37612
+ if (model.colorSpace === ColorSpace.RGB) {
37613
+ for (let j = 0; j < 3; j++) {
37614
+ // Use one slope for both end points
37615
+ slope = rgb2[j] - rgb1[j];
37616
+ t = (1.0 - sharpness) * slope;
37617
+
37618
+ // Compute the value
37619
+ table[tidx + j] = h1 * rgb1[j] + h2 * rgb2[j] + h3 * t + h4 * t;
37620
+ }
37621
+ } else if (model.colorSpace === ColorSpace.HSV) {
37622
+ const hsv1 = [];
37623
+ const hsv2 = [];
37624
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb1, hsv1);
37625
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb2, hsv2);
37626
+ if (model.hSVWrap && (hsv1[0] - hsv2[0] > 0.5 || hsv2[0] - hsv1[0] > 0.5)) {
37627
+ if (hsv1[0] > hsv2[0]) {
37628
+ hsv1[0] -= 1.0;
37629
+ } else {
37630
+ hsv2[0] -= 1.0;
37631
+ }
37632
+ }
37633
+ const hsvTmp = [];
37634
+ for (let j = 0; j < 3; j++) {
37635
+ // Use one slope for both end points
37636
+ slope = hsv2[j] - hsv1[j];
37637
+ t = (1.0 - sharpness) * slope;
37638
+
37639
+ // Compute the value
37640
+ hsvTmp[j] = h1 * hsv1[j] + h2 * hsv2[j] + h3 * t + h4 * t;
37641
+ if (j === 0 && hsvTmp[j] < 0.0) {
37642
+ hsvTmp[j] += 1.0;
37643
+ }
37644
+ }
37645
+ // Now convert this back to RGB
37646
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsvTmp, tmpVec);
37647
+ table[tidx] = tmpVec[0];
37648
+ table[tidx + 1] = tmpVec[1];
37649
+ table[tidx + 2] = tmpVec[2];
37650
+ } else if (model.colorSpace === ColorSpace.LAB) {
37651
+ const lab1 = [];
37652
+ const lab2 = [];
37653
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb1, lab1);
37654
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb2, lab2);
37655
+ const labTmp = [];
37656
+ for (let j = 0; j < 3; j++) {
37657
+ // Use one slope for both end points
37658
+ slope = lab2[j] - lab1[j];
37659
+ t = (1.0 - sharpness) * slope;
37660
+
37661
+ // Compute the value
37662
+ labTmp[j] = h1 * lab1[j] + h2 * lab2[j] + h3 * t + h4 * t;
37663
+ }
37664
+ // Now convert this back to RGB
37665
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.O)(labTmp, tmpVec);
37666
+ table[tidx] = tmpVec[0];
37667
+ table[tidx + 1] = tmpVec[1];
37668
+ table[tidx + 2] = tmpVec[2];
37669
+ } else if (model.colorSpace === ColorSpace.DIVERGING) {
37670
+ // I have not implemented proper interpolation by a hermite curve for
37671
+ // the diverging color map, but I cannot think of a good use case for
37672
+ // that anyway.
37673
+ vtkColorTransferFunctionInterpolateDiverging(s, rgb1, rgb2, tmpVec);
37674
+ table[tidx] = tmpVec[0];
37675
+ table[tidx + 1] = tmpVec[1];
37676
+ table[tidx + 2] = tmpVec[2];
37677
+ } else {
37678
+ vtkErrorMacro('ColorSpace set to invalid value.');
37679
+ }
37680
+
37681
+ // Final error check to make sure we don't go outside [0,1]
37682
+ for (let j = 0; j < 3; j++) {
37683
+ table[tidx + j] = table[tidx + j] < 0.0 ? 0.0 : table[tidx + j];
37684
+ table[tidx + j] = table[tidx + j] > 1.0 ? 1.0 : table[tidx + j];
37685
+ }
37686
+ }
37687
+ }
37688
+ };
37689
+
37690
+ //----------------------------------------------------------------------------
37691
+ publicAPI.getUint8Table = function (xStart, xEnd, size) {
37692
+ let withAlpha = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
37693
+ if (publicAPI.getMTime() <= model.buildTime && model.tableSize === size && model.tableWithAlpha !== withAlpha) {
37694
+ return model.table;
37695
+ }
37696
+ if (model.nodes.length === 0) {
37697
+ vtkErrorMacro('Attempting to lookup a value with no points in the function');
37698
+ return model.table;
37699
+ }
37700
+ const nbChannels = withAlpha ? 4 : 3;
37701
+ if (model.tableSize !== size || model.tableWithAlpha !== withAlpha) {
37702
+ model.table = new Uint8Array(size * nbChannels);
37703
+ model.tableSize = size;
37704
+ model.tableWithAlpha = withAlpha;
37705
+ }
37706
+ const tmpTable = [];
37707
+ publicAPI.getTable(xStart, xEnd, size, tmpTable);
37708
+ for (let i = 0; i < size; i++) {
37709
+ model.table[i * nbChannels + 0] = Math.floor(tmpTable[i * 3 + 0] * 255.0 + 0.5);
37710
+ model.table[i * nbChannels + 1] = Math.floor(tmpTable[i * 3 + 1] * 255.0 + 0.5);
37711
+ model.table[i * nbChannels + 2] = Math.floor(tmpTable[i * 3 + 2] * 255.0 + 0.5);
37712
+ if (withAlpha) {
37713
+ model.table[i * nbChannels + 3] = 255;
37714
+ }
37715
+ }
37716
+ model.buildTime.modified();
37717
+ return model.table;
37718
+ };
37719
+ publicAPI.buildFunctionFromArray = array => {
37720
+ publicAPI.removeAllPoints();
37721
+ const numComponents = array.getNumberOfComponents();
37722
+ for (let i = 0; i < array.getNumberOfTuples(); i++) {
37723
+ switch (numComponents) {
37724
+ case 3:
37725
+ {
37726
+ model.nodes.push({
37727
+ x: i,
37728
+ r: array.getComponent(i, 0),
37729
+ g: array.getComponent(i, 1),
37730
+ b: array.getComponent(i, 2),
37731
+ midpoint: 0.5,
37732
+ sharpness: 0.0
37733
+ });
37734
+ break;
37735
+ }
37736
+ case 4:
37737
+ {
37738
+ model.nodes.push({
37739
+ x: array.getComponent(i, 0),
37740
+ r: array.getComponent(i, 1),
37741
+ g: array.getComponent(i, 2),
37742
+ b: array.getComponent(i, 3),
37743
+ midpoint: 0.5,
37744
+ sharpness: 0.0
37745
+ });
37746
+ break;
37747
+ }
37748
+ case 5:
37749
+ {
37750
+ model.nodes.push({
37751
+ x: i,
37752
+ r: array.getComponent(i, 0),
37753
+ g: array.getComponent(i, 1),
37754
+ b: array.getComponent(i, 2),
37755
+ midpoint: array.getComponent(i, 4),
37756
+ sharpness: array.getComponent(i, 5)
37757
+ });
37758
+ break;
37759
+ }
37760
+ case 6:
37761
+ {
37762
+ model.nodes.push({
37763
+ x: array.getComponent(i, 0),
37764
+ r: array.getComponent(i, 1),
37765
+ g: array.getComponent(i, 2),
37766
+ b: array.getComponent(i, 3),
37767
+ midpoint: array.getComponent(i, 4),
37768
+ sharpness: array.getComponent(i, 5)
37769
+ });
37770
+ break;
37771
+ }
37772
+ }
37773
+ }
37774
+ publicAPI.sortAndUpdateRange();
37775
+ };
37776
+
37777
+ //----------------------------------------------------------------------------
37778
+ publicAPI.buildFunctionFromTable = (xStart, xEnd, size, table) => {
37779
+ let inc = 0.0;
37780
+ publicAPI.removeAllPoints();
37781
+ if (size > 1) {
37782
+ inc = (xEnd - xStart) / (size - 1.0);
37783
+ }
37784
+ for (let i = 0; i < size; i++) {
37785
+ const node = {
37786
+ x: xStart + inc * i,
37787
+ r: table[i * 3],
37788
+ g: table[i * 3 + 1],
37789
+ b: table[i * 3 + 2],
37790
+ sharpness: 0.0,
37791
+ midpoint: 0.5
37792
+ };
37793
+ model.nodes.push(node);
37794
+ }
37795
+ publicAPI.sortAndUpdateRange();
37796
+ };
37797
+
37798
+ //----------------------------------------------------------------------------
37799
+ // For a specified index value, get the node parameters
37800
+ publicAPI.getNodeValue = (index, val) => {
37801
+ if (index < 0 || index >= model.nodes.length) {
37802
+ vtkErrorMacro('Index out of range!');
37803
+ return -1;
37804
+ }
37805
+ val[0] = model.nodes[index].x;
37806
+ val[1] = model.nodes[index].r;
37807
+ val[2] = model.nodes[index].g;
37808
+ val[3] = model.nodes[index].b;
37809
+ val[4] = model.nodes[index].midpoint;
37810
+ val[5] = model.nodes[index].sharpness;
37811
+ return 1;
37812
+ };
37813
+
37814
+ //----------------------------------------------------------------------------
37815
+ // For a specified index value, get the node parameters
37816
+ publicAPI.setNodeValue = (index, val) => {
37817
+ if (index < 0 || index >= model.nodes.length) {
37818
+ vtkErrorMacro('Index out of range!');
37819
+ return -1;
37820
+ }
37821
+ const oldX = model.nodes[index].x;
37822
+ model.nodes[index].x = val[0];
37823
+ model.nodes[index].r = val[1];
37824
+ model.nodes[index].g = val[2];
37825
+ model.nodes[index].b = val[3];
37826
+ model.nodes[index].midpoint = val[4];
37827
+ model.nodes[index].sharpness = val[5];
37828
+ if (oldX !== val[0]) {
37829
+ // The point has been moved, the order of points or the range might have
37830
+ // been modified.
37831
+ publicAPI.sortAndUpdateRange();
37832
+ // No need to call Modified() here because SortAndUpdateRange() has done it
37833
+ // already.
37834
+ } else {
37835
+ publicAPI.modified();
37836
+ }
37837
+ return 1;
37838
+ };
37839
+
37840
+ //----------------------------------------------------------------------------
37841
+ publicAPI.getNumberOfAvailableColors = () => {
37842
+ if (model.indexedLookup && publicAPI.getSize()) {
37843
+ return publicAPI.getSize();
37844
+ }
37845
+ if (model.tableSize) {
37846
+ // Not sure if this is correct since it is only set if
37847
+ // "const unsigned char *::GetTable(double xStart, double xEnd,int size)"
37848
+ // has been called.
37849
+ return model.tableSize;
37850
+ }
37851
+ const nNodes = model.nodes?.length ?? 0;
37852
+ // The minimum is 4094 colors so that it fills in the 4096 texels texture in `mapScalarsToTexture`
37853
+ return Math.max(4094, nNodes);
37854
+ };
37855
+
37856
+ //----------------------------------------------------------------------------
37857
+ publicAPI.getIndexedColor = (idx, rgba) => {
37858
+ const n = publicAPI.getSize();
37859
+ if (n > 0 && idx >= 0) {
37860
+ const nodeValue = [];
37861
+ publicAPI.getNodeValue(idx % n, nodeValue);
37862
+ for (let j = 0; j < 3; ++j) {
37863
+ rgba[j] = nodeValue[j + 1];
37864
+ }
37865
+ rgba[3] = 1.0; // NodeColor is RGB-only.
37866
+ return;
37867
+ }
37868
+ const nanColor = publicAPI.getNanColorByReference();
37869
+ rgba[0] = nanColor[0];
37870
+ rgba[1] = nanColor[1];
37871
+ rgba[2] = nanColor[2];
37872
+ rgba[3] = 1.0; // NanColor is RGB-only.
37873
+ };
37874
+
37875
+ //----------------------------------------------------------------------------
37876
+ publicAPI.fillFromDataPointer = (nb, ptr) => {
37877
+ if (nb <= 0 || !ptr) {
37878
+ return;
37879
+ }
37880
+ publicAPI.removeAllPoints();
37881
+ for (let i = 0; i < nb; i++) {
37882
+ publicAPI.addRGBPoint(ptr[i * 4], ptr[i * 4 + 1], ptr[i * 4 + 2], ptr[i * 4 + 3]);
37883
+ }
37884
+ };
37885
+
37886
+ //----------------------------------------------------------------------------
37887
+ publicAPI.setMappingRange = (min, max) => {
37888
+ const range = [min, max];
37889
+ const originalRange = publicAPI.getRange();
37890
+ if (originalRange[1] === range[1] && originalRange[0] === range[0]) {
37891
+ return;
37892
+ }
37893
+ if (range[1] === range[0]) {
37894
+ vtkErrorMacro('attempt to set zero width color range');
37895
+ return;
37896
+ }
37897
+ const scale = (range[1] - range[0]) / (originalRange[1] - originalRange[0]);
37898
+ const shift = range[0] - originalRange[0] * scale;
37899
+ for (let i = 0; i < model.nodes.length; ++i) {
37900
+ model.nodes[i].x = model.nodes[i].x * scale + shift;
37901
+ }
37902
+ model.mappingRange[0] = range[0];
37903
+ model.mappingRange[1] = range[1];
37904
+ publicAPI.modified();
37905
+ };
37906
+
37907
+ //----------------------------------------------------------------------------
37908
+ publicAPI.adjustRange = range => {
37909
+ const functionRange = publicAPI.getRange();
37910
+
37911
+ // Make sure we have points at each end of the range
37912
+ const rgb = [];
37913
+ if (functionRange[0] < range[0]) {
37914
+ publicAPI.getColor(range[0], rgb);
37915
+ publicAPI.addRGBPoint(range[0], rgb[0], rgb[1], rgb[2]);
37916
+ } else {
37917
+ publicAPI.getColor(functionRange[0], rgb);
37918
+ publicAPI.addRGBPoint(range[0], rgb[0], rgb[1], rgb[2]);
37919
+ }
37920
+ if (functionRange[1] > range[1]) {
37921
+ publicAPI.getColor(range[1], rgb);
37922
+ publicAPI.addRGBPoint(range[1], rgb[0], rgb[1], rgb[2]);
37923
+ } else {
37924
+ publicAPI.getColor(functionRange[1], rgb);
37925
+ publicAPI.addRGBPoint(range[1], rgb[0], rgb[1], rgb[2]);
37926
+ }
37927
+
37928
+ // Remove all points out-of-range
37929
+ publicAPI.sortAndUpdateRange();
37930
+ for (let i = 0; i < model.nodes.length;) {
37931
+ if (model.nodes[i].x >= range[0] && model.nodes[i].x <= range[1]) {
37932
+ model.nodes.splice(i, 1);
37933
+ } else {
37934
+ ++i;
37935
+ }
37936
+ }
37937
+ return 1;
37938
+ };
37939
+
37940
+ //--------------------------------------------------------------------------
37941
+ publicAPI.estimateMinNumberOfSamples = (x1, x2) => {
37942
+ const d = publicAPI.findMinimumXDistance();
37943
+ return Math.ceil((x2 - x1) / d);
37944
+ };
37945
+
37946
+ //----------------------------------------------------------------------------
37947
+ publicAPI.findMinimumXDistance = () => {
37948
+ if (model.nodes.length < 2) {
37949
+ return -1.0;
37950
+ }
37951
+ let distance = Number.MAX_VALUE;
37952
+ for (let i = 0; i < model.nodes.length - 1; i++) {
37953
+ const currentDist = model.nodes[i + 1].x - model.nodes[i].x;
37954
+ if (currentDist < distance) {
37955
+ distance = currentDist;
37956
+ }
37957
+ }
37958
+ return distance;
37959
+ };
37960
+ publicAPI.mapScalarsThroughTable = (input, output, outFormat, inputOffset) => {
37961
+ if (publicAPI.getSize() === 0) {
37962
+ vtkDebugMacro('Transfer Function Has No Points!');
37963
+ return;
37964
+ }
37965
+ if (model.indexedLookup) {
37966
+ publicAPI.mapDataIndexed(input, output, outFormat, inputOffset);
37967
+ } else {
37968
+ publicAPI.mapData(input, output, outFormat, inputOffset);
37969
+ }
37970
+ };
37971
+
37972
+ //----------------------------------------------------------------------------
37973
+ publicAPI.mapData = (input, output, outFormat, inputOffset) => {
37974
+ if (publicAPI.getSize() === 0) {
37975
+ vtkWarningMacro('Transfer Function Has No Points!');
37976
+ return;
37977
+ }
37978
+ const alpha = Math.floor(publicAPI.getAlpha() * 255.0 + 0.5);
37979
+ const length = input.getNumberOfTuples();
37980
+ const inIncr = input.getNumberOfComponents();
37981
+ const outputV = output.getData();
37982
+ const inputV = input.getData();
37983
+ const rgb = [];
37984
+ if (outFormat === ScalarMappingTarget.RGBA) {
37985
+ for (let i = 0; i < length; i++) {
37986
+ const x = inputV[i * inIncr + inputOffset];
37987
+ publicAPI.getColor(x, rgb);
37988
+ outputV[i * 4] = Math.floor(rgb[0] * 255.0 + 0.5);
37989
+ outputV[i * 4 + 1] = Math.floor(rgb[1] * 255.0 + 0.5);
37990
+ outputV[i * 4 + 2] = Math.floor(rgb[2] * 255.0 + 0.5);
37991
+ outputV[i * 4 + 3] = alpha;
37992
+ }
37993
+ }
37994
+ if (outFormat === ScalarMappingTarget.RGB) {
37995
+ for (let i = 0; i < length; i++) {
37996
+ const x = inputV[i * inIncr + inputOffset];
37997
+ publicAPI.getColor(x, rgb);
37998
+ outputV[i * 3] = Math.floor(rgb[0] * 255.0 + 0.5);
37999
+ outputV[i * 3 + 1] = Math.floor(rgb[1] * 255.0 + 0.5);
38000
+ outputV[i * 3 + 2] = Math.floor(rgb[2] * 255.0 + 0.5);
38001
+ }
38002
+ }
38003
+ if (outFormat === ScalarMappingTarget.LUMINANCE) {
38004
+ for (let i = 0; i < length; i++) {
38005
+ const x = inputV[i * inIncr + inputOffset];
38006
+ publicAPI.getColor(x, rgb);
38007
+ outputV[i] = Math.floor(rgb[0] * 76.5 + rgb[1] * 150.45 + rgb[2] * 28.05 + 0.5);
38008
+ }
38009
+ }
38010
+ if (outFormat === ScalarMappingTarget.LUMINANCE_ALPHA) {
38011
+ for (let i = 0; i < length; i++) {
38012
+ const x = inputV[i * inIncr + inputOffset];
38013
+ publicAPI.getColor(x, rgb);
38014
+ outputV[i * 2] = Math.floor(rgb[0] * 76.5 + rgb[1] * 150.45 + rgb[2] * 28.05 + 0.5);
38015
+ outputV[i * 2 + 1] = alpha;
38016
+ }
38017
+ }
38018
+ };
38019
+
38020
+ //----------------------------------------------------------------------------
38021
+ publicAPI.applyColorMap = colorMap => {
38022
+ const oldColorSpace = JSON.stringify(model.colorSpace);
38023
+ if (colorMap.ColorSpace) {
38024
+ model.colorSpace = ColorSpace[colorMap.ColorSpace.toUpperCase()];
38025
+ if (model.colorSpace === undefined) {
38026
+ vtkErrorMacro(`ColorSpace ${colorMap.ColorSpace} not supported, using RGB instead`);
38027
+ model.colorSpace = ColorSpace.RGB;
38028
+ }
38029
+ }
38030
+ let isModified = oldColorSpace !== JSON.stringify(model.colorSpace);
38031
+ const oldNanColor = isModified || JSON.stringify(model.nanColor);
38032
+ if (colorMap.NanColor) {
38033
+ model.nanColor = [].concat(colorMap.NanColor);
38034
+ while (model.nanColor.length < 4) {
38035
+ model.nanColor.push(1.0);
38036
+ }
38037
+ }
38038
+ isModified = isModified || oldNanColor !== JSON.stringify(model.nanColor);
38039
+ const oldNodes = isModified || JSON.stringify(model.nodes);
38040
+ if (colorMap.RGBPoints) {
38041
+ const size = colorMap.RGBPoints.length;
38042
+ model.nodes = [];
38043
+ const midpoint = 0.5;
38044
+ const sharpness = 0.0;
38045
+ for (let i = 0; i < size; i += 4) {
38046
+ model.nodes.push({
38047
+ x: colorMap.RGBPoints[i],
38048
+ r: colorMap.RGBPoints[i + 1],
38049
+ g: colorMap.RGBPoints[i + 2],
38050
+ b: colorMap.RGBPoints[i + 3],
38051
+ midpoint,
38052
+ sharpness
38053
+ });
38054
+ }
38055
+ }
38056
+ const modifiedInvoked = publicAPI.sortAndUpdateRange();
38057
+ const callModified = !modifiedInvoked && (isModified || oldNodes !== JSON.stringify(model.nodes));
38058
+ if (callModified) publicAPI.modified();
38059
+ return modifiedInvoked || callModified;
38060
+ };
38061
+ }
38062
+
38063
+ // ----------------------------------------------------------------------------
38064
+ // Object factory
38065
+ // ----------------------------------------------------------------------------
38066
+
38067
+ const DEFAULT_VALUES = {
38068
+ clamping: true,
38069
+ colorSpace: ColorSpace.RGB,
38070
+ hSVWrap: true,
38071
+ scale: Scale.LINEAR,
38072
+ nanColor: null,
38073
+ belowRangeColor: null,
38074
+ aboveRangeColor: null,
38075
+ useAboveRangeColor: false,
38076
+ useBelowRangeColor: false,
38077
+ allowDuplicateScalars: false,
38078
+ table: null,
38079
+ tableSize: 0,
38080
+ buildTime: null,
38081
+ nodes: null,
38082
+ discretize: false,
38083
+ numberOfValues: 256
38084
+ };
38085
+
38086
+ // ----------------------------------------------------------------------------
38087
+
38088
+ function extend(publicAPI, model) {
38089
+ let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
38090
+ Object.assign(model, DEFAULT_VALUES, initialValues);
38091
+
38092
+ // Inheritance
38093
+ _Common_Core_ScalarsToColors_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"].extend */ .Ay.extend(publicAPI, model, initialValues);
38094
+
38095
+ // Internal objects initialization
38096
+ model.table = [];
38097
+ model.nodes = [];
38098
+ model.nanColor = [0.5, 0.0, 0.0, 1.0];
38099
+ model.belowRangeColor = [0.0, 0.0, 0.0, 1.0];
38100
+ model.aboveRangeColor = [1.0, 1.0, 1.0, 1.0];
38101
+ model.buildTime = {};
38102
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.obj(model.buildTime);
38103
+
38104
+ // Create get-only macros
38105
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.get(publicAPI, model, ['buildTime', 'mappingRange']);
38106
+
38107
+ // Create get-set macros
38108
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.setGet(publicAPI, model, ['useAboveRangeColor', 'useBelowRangeColor', 'discretize', 'numberOfValues', {
38109
+ type: 'enum',
38110
+ name: 'colorSpace',
38111
+ enum: ColorSpace
38112
+ }, {
38113
+ type: 'enum',
38114
+ name: 'scale',
38115
+ enum: Scale
38116
+ }]);
38117
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.setArray(publicAPI, model, ['nanColor', 'belowRangeColor', 'aboveRangeColor'], 4);
38118
+
38119
+ // Create get macros for array
38120
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.getArray(publicAPI, model, ['nanColor', 'belowRangeColor', 'aboveRangeColor']);
38121
+
38122
+ // For more macro methods, see "Sources/macros.js"
38123
+
38124
+ // Object specific methods
38125
+ vtkColorTransferFunction(publicAPI, model);
38126
+ }
38127
+
38128
+ // ----------------------------------------------------------------------------
38129
+
38130
+ const newInstance = _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.newInstance(extend, 'vtkColorTransferFunction');
38131
+
38132
+ // ----------------------------------------------------------------------------
38133
+
38134
+ var vtkColorTransferFunction$1 = {
38135
+ newInstance,
38136
+ extend,
38137
+ ..._ColorTransferFunction_Constants_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Ay
38138
+ };
38139
+
38140
+
38141
+
38142
+
36716
38143
  /***/ }),
36717
38144
 
36718
38145
  /***/ 9175: