@ohif/app 3.13.0-beta.35 → 3.13.0-beta.39
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.
- package/dist/{147.bundle.9c245011849e09bd7904.js → 147.bundle.f71d384c49f50e23f795.js} +15 -40
- package/dist/{1608.bundle.417884758328a1fc04a9.js → 1608.bundle.c10d9aef452fe5a86d77.js} +2 -2
- package/dist/{1933.bundle.19f83b2c7881912dcc34.js → 1933.bundle.0aba0ce3d97d32bd3ca5.js} +2 -2
- package/dist/{2701.bundle.2cfa58ae04427d4c897d.js → 2701.bundle.28b3ca0e6ae5a13f78b3.js} +2 -2
- package/dist/{3138.bundle.4e151e0dbd74a8265f42.js → 3138.bundle.a377f868158dec8efdb0.js} +2 -2
- package/dist/{4202.bundle.9dc6af971a47981d2a5e.js → 4202.bundle.f11f02596e30a22d1105.js} +1 -1
- package/dist/{4287.bundle.d2d09ffd5cd8680fad8d.js → 4287.bundle.b7840e7b94cbbc102236.js} +3 -3
- package/dist/{4688.bundle.add6a6c6bb72fcd35ee3.js → 4688.bundle.324f320f177fe7f70db8.js} +130 -120
- package/dist/{4819.bundle.1ff04ae518bab5e59dc6.js → 4819.bundle.5aa5ed42843908dbb820.js} +4 -4
- package/dist/{5015.bundle.a35182426b6b4d2d1fe4.js → 5015.bundle.4f91f03ea8084a82657b.js} +2 -2
- package/dist/{5802.bundle.70d423c8b488cc56cc36.js → 5802.bundle.a3a398ddaac222cf08f7.js} +2 -2
- package/dist/{581.bundle.b70e5d2d0f3958df69f0.js → 581.bundle.f48ce2a0f0dae080154c.js} +7 -6
- package/dist/{6354.bundle.d8a592b03e9a5b7a66c2.js → 6354.bundle.929febcf6d326e582e00.js} +50 -45
- package/dist/{6386.bundle.c0618e49b65769ddf752.js → 6386.bundle.e75a2f70039dfe42f935.js} +11 -3
- package/dist/{7537.bundle.1a18959ceec98634bc48.js → 7537.bundle.b784154ebd4c85946642.js} +758 -679
- package/dist/{8305.bundle.7e577ab4f21ac44d355e.js → 8305.bundle.371dde3415de88db3f43.js} +2 -2
- package/dist/{8583.bundle.47394b6ef65ff3a4190c.js → 8583.bundle.f6c226c9fa6de90f2bcb.js} +2 -2
- package/dist/{6280.bundle.081861b7e685b28616c8.js → 9039.bundle.fd54c15934103ff3fd3b.js} +1470 -1259
- package/dist/{9195.bundle.a38804074672c87ad1ec.js → 9195.bundle.afd5483195e12e5cef8e.js} +8 -8
- package/dist/{9205.bundle.09c52845b43bd8513d50.js → 9205.bundle.7c4a29705386dcefd999.js} +1602 -1347
- package/dist/{933.bundle.ea9db108b8a4e3d51904.js → 9567.bundle.be350438bed4e656f278.js} +2690 -193
- package/dist/{9845.bundle.fe6930acb204e2fd8323.js → 9845.bundle.36b3563ae1dba65b6b9a.js} +2 -2
- package/dist/{9862.bundle.47e7574a486c30ab0dfd.js → 9862.bundle.f59f3a574a92024c8823.js} +1 -1
- package/dist/{app.bundle.3e902f3aba87f5fdaca0.js → app.bundle.6c3daf11c7fbd7e48175.js} +970 -811
- package/dist/app.bundle.css +1 -1
- package/dist/{compute.bundle.6016de6e5f7c25749422.js → compute.bundle.47da6b38c64751bdb9c4.js} +1 -1
- package/dist/{histogram-worker.bundle.5b679ce4142c803c80a4.js → histogram-worker.bundle.a2a50c4674d99c619ca7.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/{interpolation.bundle.072a28b303f2dbafe05c.js → interpolation.bundle.53073c15cca1c5a41ae4.js} +1 -1
- package/dist/{polySeg.bundle.cdcc2c3d11009ccf112c.js → polySeg.bundle.8954fb59f99daeb3f0b0.js} +3 -3
- package/dist/sw.js +1 -1
- package/package.json +21 -21
- /package/dist/{1459.bundle.062605b72ad894597c40.js → 1459.bundle.4aef0d934c3a12aa66bb.js} +0 -0
- /package/dist/{2018.bundle.d8cf3001bae55516d13a.js → 2018.bundle.896e322e7c39599383f7.js} +0 -0
- /package/dist/{2075.bundle.16215ba94d714a1c905f.js → 2075.bundle.0e69a126a39539ff8e9a.js} +0 -0
- /package/dist/{213.bundle.5527b63c734814bca27c.js → 213.bundle.9a4de523c0842d7bd7fd.js} +0 -0
- /package/dist/{2424.bundle.7cf905346cf856a74d18.js → 2424.bundle.6a9ca8e7e84f5528c8d1.js} +0 -0
- /package/dist/{3461.bundle.19921563b1d9ee7c4599.js → 3461.bundle.b6304f280d7dc0ade73a.js} +0 -0
- /package/dist/{4507.bundle.816349fd19d1f7feb8cc.js → 4507.bundle.67c73fab897aa7040fce.js} +0 -0
- /package/dist/{5028.bundle.12210efc962029543cf8.js → 5028.bundle.71b240621417df1a6fab.js} +0 -0
- /package/dist/{5457.bundle.ce2a509fad38c7b5d23e.js → 5457.bundle.109f104b4520e6374fa6.js} +0 -0
- /package/dist/{5485.bundle.18ac74bcc1f62f4ff48a.js → 5485.bundle.a88fd5be3f5aa20dc643.js} +0 -0
- /package/dist/{6027.bundle.11593983ae8a72b4b10d.js → 6027.bundle.555553c951bba02afa54.js} +0 -0
- /package/dist/{7431.bundle.84b3d88ef94b97c84298.js → 7431.bundle.e5a9b628c993b78ff7db.js} +0 -0
- /package/dist/{7639.bundle.47fa2f67acb39082efe9.js → 7639.bundle.0f0b2419e43c7dc3b88a.js} +0 -0
- /package/dist/{8499.bundle.ef8d548ca8261c78ed2b.js → 8499.bundle.c179a028eae7170b397d.js} +0 -0
- /package/dist/{85.bundle.47697c7697f28e3d1865.js → 85.bundle.80b16edc06976de80ae6.js} +0 -0
- /package/dist/{8558.bundle.b7124f251785e778c3c1.js → 8558.bundle.f08683ca26d63fb8c0ef.js} +0 -0
- /package/dist/{9927.bundle.861ce96aab6eed8e6ff3.js → 9927.bundle.6966a86ab930197c8295.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[2075,
|
|
1
|
+
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[2075,9039],{
|
|
2
2
|
|
|
3
3
|
/***/ 5057
|
|
4
4
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -348,6 +348,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
348
348
|
addImageSlicesToViewports: () => (/* reexport */ helpers/* addImageSlicesToViewports */.ge),
|
|
349
349
|
addVolumesToViewports: () => (/* reexport */ helpers/* addVolumesToViewports */.x),
|
|
350
350
|
cache: () => (/* reexport */ cache_cache/* default */.Ay),
|
|
351
|
+
convertColorArrayToRgbString: () => (/* reexport */ convertColorArrayToRgbString/* convertColorArrayToRgbString */.J),
|
|
351
352
|
convertMapperToNotSharedMapper: () => (/* reexport */ createVolumeMapper/* convertMapperToNotSharedMapper */.h),
|
|
352
353
|
eventTarget: () => (/* reexport */ eventTarget/* default */.A),
|
|
353
354
|
getConfiguration: () => (/* reexport */ init/* getConfiguration */.D0),
|
|
@@ -626,6 +627,8 @@ var decimatedVolumeLoader = __webpack_require__(18481);
|
|
|
626
627
|
var utilities = __webpack_require__(85343);
|
|
627
628
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/triggerEvent.js
|
|
628
629
|
var triggerEvent = __webpack_require__(69372);
|
|
630
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/convertColorArrayToRgbString.js
|
|
631
|
+
var convertColorArrayToRgbString = __webpack_require__(57652);
|
|
629
632
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/loaders/cornerstoneStreamingImageVolumeLoader.js
|
|
630
633
|
var cornerstoneStreamingImageVolumeLoader = __webpack_require__(55500);
|
|
631
634
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/loaders/cornerstoneStreamingDynamicImageVolumeLoader.js
|
|
@@ -675,6 +678,7 @@ var helpers = __webpack_require__(40661);
|
|
|
675
678
|
|
|
676
679
|
|
|
677
680
|
|
|
681
|
+
|
|
678
682
|
|
|
679
683
|
|
|
680
684
|
/***/ },
|
|
@@ -3231,6 +3235,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
3231
3235
|
clip: () => (/* reexport */ utilities_clip),
|
|
3232
3236
|
color: () => (/* reexport */ color_namespaceObject),
|
|
3233
3237
|
colormap: () => (/* reexport */ colormap),
|
|
3238
|
+
convertColorArrayToRgbString: () => (/* reexport */ convertColorArrayToRgbString/* convertColorArrayToRgbString */.J),
|
|
3234
3239
|
convertStackToVolumeViewport: () => (/* reexport */ convertStackToVolumeViewport),
|
|
3235
3240
|
convertToGrayscale: () => (/* reexport */ convertToGrayscale),
|
|
3236
3241
|
convertVolumeToStackViewport: () => (/* reexport */ convertVolumeToStackViewport),
|
|
@@ -4660,6 +4665,8 @@ function convertToGrayscale(scalarData, width, height) {
|
|
|
4660
4665
|
}
|
|
4661
4666
|
}
|
|
4662
4667
|
|
|
4668
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/convertColorArrayToRgbString.js
|
|
4669
|
+
var convertColorArrayToRgbString = __webpack_require__(57652);
|
|
4663
4670
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/RenderingEngine/index.js + 3 modules
|
|
4664
4671
|
var RenderingEngine = __webpack_require__(90340);
|
|
4665
4672
|
;// ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/getViewportImageIds.js
|
|
@@ -5573,6 +5580,7 @@ var updatePlaneRestriction = __webpack_require__(41365);
|
|
|
5573
5580
|
|
|
5574
5581
|
|
|
5575
5582
|
|
|
5583
|
+
|
|
5576
5584
|
|
|
5577
5585
|
|
|
5578
5586
|
const getViewportModality = (viewport, volumeId) => _getViewportModality(viewport, volumeId, cache/* default */.Ay.getVolume);
|
|
@@ -6347,7 +6355,7 @@ function toLowHighRange(windowWidth, windowCenter, voiLUTFunction = _enums_VOILU
|
|
|
6347
6355
|
|
|
6348
6356
|
/***/ },
|
|
6349
6357
|
|
|
6350
|
-
/***/
|
|
6358
|
+
/***/ 94836
|
|
6351
6359
|
(__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) {
|
|
6352
6360
|
|
|
6353
6361
|
"use strict";
|
|
@@ -7298,7 +7306,7 @@ var COLOR_LUT = __webpack_require__(93952);
|
|
|
7298
7306
|
|
|
7299
7307
|
|
|
7300
7308
|
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/version.js
|
|
7301
|
-
const version = '4.
|
|
7309
|
+
const version = '4.19.0';
|
|
7302
7310
|
|
|
7303
7311
|
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/synchronizers/callbacks/cameraSyncCallback.js
|
|
7304
7312
|
/* unused harmony import specifier */ var cameraSyncCallback_getRenderingEngine;
|
|
@@ -8251,6 +8259,65 @@ function _createCinePlayContext(viewport, playClipOptions) {
|
|
|
8251
8259
|
|
|
8252
8260
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/boundingBox/index.js
|
|
8253
8261
|
var boundingBox = __webpack_require__(72282);
|
|
8262
|
+
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/DataModel/PolyData.js + 7 modules
|
|
8263
|
+
var PolyData = __webpack_require__(27480);
|
|
8264
|
+
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/Points.js
|
|
8265
|
+
var Points = __webpack_require__(74973);
|
|
8266
|
+
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/CellArray.js
|
|
8267
|
+
var CellArray = __webpack_require__(32461);
|
|
8268
|
+
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/Actor.js
|
|
8269
|
+
var Actor = __webpack_require__(44404);
|
|
8270
|
+
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/Mapper.js + 1 modules
|
|
8271
|
+
var Mapper = __webpack_require__(81418);
|
|
8272
|
+
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/draw3D/addLine3DBetweenPoints.js
|
|
8273
|
+
|
|
8274
|
+
|
|
8275
|
+
|
|
8276
|
+
|
|
8277
|
+
|
|
8278
|
+
function addLine3DBetweenPoints(viewport, point1, point2, color = [0.7, 0.7, 0.7], uid = '', showHandles = true) {
|
|
8279
|
+
if (point1[0] === point2[0] &&
|
|
8280
|
+
point1[1] === point2[1] &&
|
|
8281
|
+
point1[2] === point2[2]) {
|
|
8282
|
+
return { actor: null, source: null };
|
|
8283
|
+
}
|
|
8284
|
+
const points = Points/* default.newInstance */.Ay.newInstance();
|
|
8285
|
+
points.setNumberOfPoints(2);
|
|
8286
|
+
points.setPoint(0, point1[0], point1[1], point1[2]);
|
|
8287
|
+
points.setPoint(1, point2[0], point2[1], point2[2]);
|
|
8288
|
+
const lines = CellArray/* default.newInstance */.Ay.newInstance({ values: [2, 0, 1] });
|
|
8289
|
+
const polyData = PolyData/* default.newInstance */.Ay.newInstance();
|
|
8290
|
+
polyData.setPoints(points);
|
|
8291
|
+
polyData.setLines(lines);
|
|
8292
|
+
const mapper = Mapper/* default.newInstance */.Ay.newInstance();
|
|
8293
|
+
mapper.setInputData(polyData);
|
|
8294
|
+
const actor = Actor/* default.newInstance */.Ay.newInstance();
|
|
8295
|
+
actor.setMapper(mapper);
|
|
8296
|
+
actor.getProperty().setColor(...color);
|
|
8297
|
+
actor.getProperty().setLineWidth(0.5);
|
|
8298
|
+
actor.getProperty().setOpacity(1.0);
|
|
8299
|
+
actor.getProperty().setInterpolationToFlat();
|
|
8300
|
+
actor.getProperty().setAmbient(1.0);
|
|
8301
|
+
actor.getProperty().setDiffuse(0.0);
|
|
8302
|
+
actor.getProperty().setSpecular(0.0);
|
|
8303
|
+
actor.setVisibility(showHandles);
|
|
8304
|
+
viewport.addActor({ actor, uid });
|
|
8305
|
+
return { actor, source: polyData };
|
|
8306
|
+
}
|
|
8307
|
+
|
|
8308
|
+
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/draw3D/calculateAdaptiveSphereRadius.js
|
|
8309
|
+
function calculateAdaptiveSphereRadius(diagonal, config) {
|
|
8310
|
+
const scaleFactor = config.sphereRadiusScale || 0.01;
|
|
8311
|
+
const adaptiveRadius = diagonal * scaleFactor;
|
|
8312
|
+
const minRadius = config.minSphereRadius || 2;
|
|
8313
|
+
const maxRadius = config.maxSphereRadius || 50;
|
|
8314
|
+
return Math.max(minRadius, Math.min(maxRadius, adaptiveRadius));
|
|
8315
|
+
}
|
|
8316
|
+
|
|
8317
|
+
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/draw3D/index.js
|
|
8318
|
+
|
|
8319
|
+
|
|
8320
|
+
|
|
8254
8321
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/planarFreehandROITool/smoothAnnotation.js
|
|
8255
8322
|
var smoothAnnotation = __webpack_require__(61587);
|
|
8256
8323
|
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/planarFreehandROITool/index.js
|
|
@@ -10265,6 +10332,7 @@ function calculateFanGeometry(imageId) {
|
|
|
10265
10332
|
|
|
10266
10333
|
|
|
10267
10334
|
|
|
10335
|
+
|
|
10268
10336
|
|
|
10269
10337
|
|
|
10270
10338
|
const roundNumber = esm.utilities.roundNumber;
|
|
@@ -11266,20 +11334,12 @@ class TrackballRotateTool extends base/* BaseTool */.oS {
|
|
|
11266
11334
|
TrackballRotateTool.toolName = 'TrackballRotate';
|
|
11267
11335
|
/* harmony default export */ const tools_TrackballRotateTool = ((/* unused pure expression or super */ null && (TrackballRotateTool)));
|
|
11268
11336
|
|
|
11269
|
-
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/DataModel/PolyData.js + 11 modules
|
|
11270
|
-
var PolyData = __webpack_require__(12548);
|
|
11271
|
-
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/Points.js
|
|
11272
|
-
var Points = __webpack_require__(74973);
|
|
11273
|
-
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/CellArray.js
|
|
11274
|
-
var CellArray = __webpack_require__(32461);
|
|
11275
|
-
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/Actor.js
|
|
11276
|
-
var Actor = __webpack_require__(44404);
|
|
11277
11337
|
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Filters/Sources/SphereSource.js
|
|
11278
11338
|
var SphereSource = __webpack_require__(73435);
|
|
11279
|
-
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/
|
|
11280
|
-
var
|
|
11281
|
-
// EXTERNAL MODULE: ../../../node_modules/@
|
|
11282
|
-
var
|
|
11339
|
+
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/DataModel/Plane.js
|
|
11340
|
+
var Plane = __webpack_require__(49794);
|
|
11341
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/volumeCropping/index.js + 8 modules
|
|
11342
|
+
var volumeCropping = __webpack_require__(88380);
|
|
11283
11343
|
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/VolumeCroppingTool.js
|
|
11284
11344
|
|
|
11285
11345
|
|
|
@@ -11294,30 +11354,6 @@ var Plane = __webpack_require__(43884);
|
|
|
11294
11354
|
|
|
11295
11355
|
|
|
11296
11356
|
|
|
11297
|
-
const PLANEINDEX = {
|
|
11298
|
-
XMIN: 0,
|
|
11299
|
-
XMAX: 1,
|
|
11300
|
-
YMIN: 2,
|
|
11301
|
-
YMAX: 3,
|
|
11302
|
-
ZMIN: 4,
|
|
11303
|
-
ZMAX: 5,
|
|
11304
|
-
};
|
|
11305
|
-
const SPHEREINDEX = {
|
|
11306
|
-
XMIN: 0,
|
|
11307
|
-
XMAX: 1,
|
|
11308
|
-
YMIN: 2,
|
|
11309
|
-
YMAX: 3,
|
|
11310
|
-
ZMIN: 4,
|
|
11311
|
-
ZMAX: 5,
|
|
11312
|
-
XMIN_YMIN_ZMIN: 6,
|
|
11313
|
-
XMIN_YMIN_ZMAX: 7,
|
|
11314
|
-
XMIN_YMAX_ZMIN: 8,
|
|
11315
|
-
XMIN_YMAX_ZMAX: 9,
|
|
11316
|
-
XMAX_YMIN_ZMIN: 10,
|
|
11317
|
-
XMAX_YMIN_ZMAX: 11,
|
|
11318
|
-
XMAX_YMAX_ZMIN: 12,
|
|
11319
|
-
XMAX_YMAX_ZMAX: 13,
|
|
11320
|
-
};
|
|
11321
11357
|
class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
11322
11358
|
constructor(toolProps = {}, defaultToolProps = {
|
|
11323
11359
|
configuration: {
|
|
@@ -11339,6 +11375,7 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11339
11375
|
grabSpherePixelDistance: 20,
|
|
11340
11376
|
rotateIncrementDegrees: 2,
|
|
11341
11377
|
rotateSampleDistanceFactor: 2,
|
|
11378
|
+
rotateClippingPlanesIncrementDegrees: 5,
|
|
11342
11379
|
},
|
|
11343
11380
|
}) {
|
|
11344
11381
|
super(toolProps, defaultToolProps);
|
|
@@ -11346,16 +11383,15 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11346
11383
|
this._hasResolutionChanged = false;
|
|
11347
11384
|
this.originalClippingPlanes = [];
|
|
11348
11385
|
this.draggingSphereIndex = null;
|
|
11349
|
-
this.
|
|
11386
|
+
this.rotatePlanesOnDrag = false;
|
|
11350
11387
|
this.cornerDragOffset = null;
|
|
11351
11388
|
this.faceDragOffset = null;
|
|
11389
|
+
this.volumeDirectionVectors = null;
|
|
11352
11390
|
this.sphereStates = [];
|
|
11353
11391
|
this.edgeLines = {};
|
|
11354
11392
|
this.onSetToolConfiguration = () => {
|
|
11355
|
-
console.debug('Setting tool settoolconfiguration : volumeCropping');
|
|
11356
11393
|
};
|
|
11357
11394
|
this.onSetToolEnabled = () => {
|
|
11358
|
-
console.debug('Setting tool enabled: volumeCropping');
|
|
11359
11395
|
};
|
|
11360
11396
|
this.onCameraModified = (evt) => {
|
|
11361
11397
|
const { element } = evt.currentTarget
|
|
@@ -11398,9 +11434,16 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11398
11434
|
this.faceDragOffset = null;
|
|
11399
11435
|
}
|
|
11400
11436
|
else {
|
|
11401
|
-
const
|
|
11437
|
+
const directionVector = this._getDirectionVectorForAxis(sphereState.axis);
|
|
11438
|
+
const delta = [
|
|
11439
|
+
sphereState.point[0] - mouseWorld[0],
|
|
11440
|
+
sphereState.point[1] - mouseWorld[1],
|
|
11441
|
+
sphereState.point[2] - mouseWorld[2],
|
|
11442
|
+
];
|
|
11402
11443
|
this.faceDragOffset =
|
|
11403
|
-
|
|
11444
|
+
delta[0] * directionVector[0] +
|
|
11445
|
+
delta[1] * directionVector[1] +
|
|
11446
|
+
delta[2] * directionVector[2];
|
|
11404
11447
|
this.cornerDragOffset = null;
|
|
11405
11448
|
}
|
|
11406
11449
|
return true;
|
|
@@ -11455,118 +11498,143 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11455
11498
|
return false;
|
|
11456
11499
|
}
|
|
11457
11500
|
if (sphereState.isCorner) {
|
|
11458
|
-
const newCorner = this.
|
|
11459
|
-
|
|
11460
|
-
|
|
11461
|
-
|
|
11462
|
-
|
|
11501
|
+
const newCorner = this.cornerDragOffset
|
|
11502
|
+
? gl_matrix_esm/* vec3.add */.eR.add([0, 0, 0], world, this.cornerDragOffset)
|
|
11503
|
+
: world;
|
|
11504
|
+
const oldCorner = sphereState.point;
|
|
11505
|
+
const axisFlags = (0,volumeCropping.parseCornerKey)(sphereState.uid);
|
|
11506
|
+
const { xDir, yDir, zDir } = this._getDirectionVectors();
|
|
11507
|
+
if (!xDir || !yDir || !zDir)
|
|
11508
|
+
return false;
|
|
11509
|
+
const delta = [
|
|
11510
|
+
newCorner[0] - oldCorner[0],
|
|
11511
|
+
newCorner[1] - oldCorner[1],
|
|
11512
|
+
newCorner[2] - oldCorner[2],
|
|
11513
|
+
];
|
|
11514
|
+
const deltaX = delta[0] * xDir[0] + delta[1] * xDir[1] + delta[2] * xDir[2];
|
|
11515
|
+
const deltaY = delta[0] * yDir[0] + delta[1] * yDir[1] + delta[2] * yDir[2];
|
|
11516
|
+
const deltaZ = delta[0] * zDir[0] + delta[1] * zDir[1] + delta[2] * zDir[2];
|
|
11517
|
+
if (axisFlags.isXMin) {
|
|
11518
|
+
const faceXMin = this.sphereStates[volumeCropping.SPHEREINDEX.XMIN];
|
|
11519
|
+
const newPoint = [
|
|
11520
|
+
faceXMin.point[0] + deltaX * xDir[0],
|
|
11521
|
+
faceXMin.point[1] + deltaX * xDir[1],
|
|
11522
|
+
faceXMin.point[2] + deltaX * xDir[2],
|
|
11523
|
+
];
|
|
11524
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.XMIN, newPoint);
|
|
11525
|
+
}
|
|
11526
|
+
else if (axisFlags.isXMax) {
|
|
11527
|
+
const faceXMax = this.sphereStates[volumeCropping.SPHEREINDEX.XMAX];
|
|
11528
|
+
const newPoint = [
|
|
11529
|
+
faceXMax.point[0] + deltaX * xDir[0],
|
|
11530
|
+
faceXMax.point[1] + deltaX * xDir[1],
|
|
11531
|
+
faceXMax.point[2] + deltaX * xDir[2],
|
|
11532
|
+
];
|
|
11533
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.XMAX, newPoint);
|
|
11534
|
+
}
|
|
11535
|
+
if (axisFlags.isYMin) {
|
|
11536
|
+
const faceYMin = this.sphereStates[volumeCropping.SPHEREINDEX.YMIN];
|
|
11537
|
+
const newPoint = [
|
|
11538
|
+
faceYMin.point[0] + deltaY * yDir[0],
|
|
11539
|
+
faceYMin.point[1] + deltaY * yDir[1],
|
|
11540
|
+
faceYMin.point[2] + deltaY * yDir[2],
|
|
11541
|
+
];
|
|
11542
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.YMIN, newPoint);
|
|
11543
|
+
}
|
|
11544
|
+
else if (axisFlags.isYMax) {
|
|
11545
|
+
const faceYMax = this.sphereStates[volumeCropping.SPHEREINDEX.YMAX];
|
|
11546
|
+
const newPoint = [
|
|
11547
|
+
faceYMax.point[0] + deltaY * yDir[0],
|
|
11548
|
+
faceYMax.point[1] + deltaY * yDir[1],
|
|
11549
|
+
faceYMax.point[2] + deltaY * yDir[2],
|
|
11550
|
+
];
|
|
11551
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.YMAX, newPoint);
|
|
11552
|
+
}
|
|
11553
|
+
if (axisFlags.isZMin) {
|
|
11554
|
+
const faceZMin = this.sphereStates[volumeCropping.SPHEREINDEX.ZMIN];
|
|
11555
|
+
const newPoint = [
|
|
11556
|
+
faceZMin.point[0] + deltaZ * zDir[0],
|
|
11557
|
+
faceZMin.point[1] + deltaZ * zDir[1],
|
|
11558
|
+
faceZMin.point[2] + deltaZ * zDir[2],
|
|
11559
|
+
];
|
|
11560
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.ZMIN, newPoint);
|
|
11561
|
+
}
|
|
11562
|
+
else if (axisFlags.isZMax) {
|
|
11563
|
+
const faceZMax = this.sphereStates[volumeCropping.SPHEREINDEX.ZMAX];
|
|
11564
|
+
const newPoint = [
|
|
11565
|
+
faceZMax.point[0] + deltaZ * zDir[0],
|
|
11566
|
+
faceZMax.point[1] + deltaZ * zDir[1],
|
|
11567
|
+
faceZMax.point[2] + deltaZ * zDir[2],
|
|
11568
|
+
];
|
|
11569
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.ZMAX, newPoint);
|
|
11570
|
+
}
|
|
11463
11571
|
this._updateCornerSpheres();
|
|
11572
|
+
this._updateFaceSpheresFromCorners();
|
|
11464
11573
|
}
|
|
11465
11574
|
else {
|
|
11466
|
-
const
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
|
|
11472
|
-
|
|
11473
|
-
|
|
11575
|
+
const directionVector = this._getDirectionVectorForAxis(sphereState.axis);
|
|
11576
|
+
const delta = [
|
|
11577
|
+
world[0] - sphereState.point[0],
|
|
11578
|
+
world[1] - sphereState.point[1],
|
|
11579
|
+
world[2] - sphereState.point[2],
|
|
11580
|
+
];
|
|
11581
|
+
const distanceAlongAxis = delta[0] * directionVector[0] +
|
|
11582
|
+
delta[1] * directionVector[1] +
|
|
11583
|
+
delta[2] * directionVector[2];
|
|
11584
|
+
const adjustedDistance = this.faceDragOffset !== null
|
|
11585
|
+
? distanceAlongAxis + this.faceDragOffset
|
|
11586
|
+
: distanceAlongAxis;
|
|
11587
|
+
const newPoint = [
|
|
11588
|
+
sphereState.point[0] + adjustedDistance * directionVector[0],
|
|
11589
|
+
sphereState.point[1] + adjustedDistance * directionVector[1],
|
|
11590
|
+
sphereState.point[2] + adjustedDistance * directionVector[2],
|
|
11591
|
+
];
|
|
11592
|
+
this._updateSpherePosition(this.draggingSphereIndex, newPoint);
|
|
11474
11593
|
this._updateCornerSpheresFromFaces();
|
|
11475
11594
|
this._updateFaceSpheresFromCorners();
|
|
11476
11595
|
this._updateCornerSpheres();
|
|
11477
11596
|
}
|
|
11478
11597
|
this._updateClippingPlanesFromFaceSpheres(viewport);
|
|
11479
11598
|
viewport.render();
|
|
11480
|
-
this.
|
|
11599
|
+
this._notifyClippingPlanesChanged();
|
|
11481
11600
|
return true;
|
|
11482
11601
|
};
|
|
11483
11602
|
this._onControlToolChange = (evt) => {
|
|
11484
11603
|
const viewport = this._getViewport();
|
|
11485
|
-
if (
|
|
11486
|
-
|
|
11487
|
-
originalClippingPlanes: this.originalClippingPlanes,
|
|
11488
|
-
viewportId: viewport.id,
|
|
11489
|
-
renderingEngineId: viewport.renderingEngineId,
|
|
11490
|
-
seriesInstanceUID: this.seriesInstanceUID,
|
|
11491
|
-
});
|
|
11604
|
+
if (evt.detail.seriesInstanceUID !== this.seriesInstanceUID) {
|
|
11605
|
+
return;
|
|
11492
11606
|
}
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11496
|
-
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
? evt.detail.toolCenterMin
|
|
11500
|
-
: evt.detail.toolCenterMax;
|
|
11501
|
-
const normals = isMin
|
|
11502
|
-
? [
|
|
11503
|
-
[1, 0, 0],
|
|
11504
|
-
[0, 1, 0],
|
|
11505
|
-
[0, 0, 1],
|
|
11506
|
-
]
|
|
11507
|
-
: [
|
|
11508
|
-
[-1, 0, 0],
|
|
11509
|
-
[0, -1, 0],
|
|
11510
|
-
[0, 0, -1],
|
|
11511
|
-
];
|
|
11512
|
-
const planeIndices = isMin
|
|
11513
|
-
? [PLANEINDEX.XMIN, PLANEINDEX.YMIN, PLANEINDEX.ZMIN]
|
|
11514
|
-
: [PLANEINDEX.XMAX, PLANEINDEX.YMAX, PLANEINDEX.ZMAX];
|
|
11515
|
-
const sphereIndices = isMin
|
|
11516
|
-
? [SPHEREINDEX.XMIN, SPHEREINDEX.YMIN, SPHEREINDEX.ZMIN]
|
|
11517
|
-
: [SPHEREINDEX.XMAX, SPHEREINDEX.YMAX, SPHEREINDEX.ZMAX];
|
|
11518
|
-
const axes = ['x', 'y', 'z'];
|
|
11519
|
-
const orientationAxes = [
|
|
11520
|
-
esm.Enums.OrientationAxis.SAGITTAL,
|
|
11521
|
-
esm.Enums.OrientationAxis.CORONAL,
|
|
11522
|
-
esm.Enums.OrientationAxis.AXIAL,
|
|
11523
|
-
];
|
|
11524
|
-
for (let i = 0; i < 3; ++i) {
|
|
11525
|
-
const origin = [0, 0, 0];
|
|
11526
|
-
origin[i] = toolCenter[i];
|
|
11527
|
-
const plane = Plane/* default.newInstance */.Ay.newInstance({
|
|
11528
|
-
origin,
|
|
11529
|
-
normal: normals[i],
|
|
11530
|
-
});
|
|
11531
|
-
this.originalClippingPlanes[planeIndices[i]].origin = plane.getOrigin();
|
|
11532
|
-
this.sphereStates[sphereIndices[i]].point[i] = plane.getOrigin()[i];
|
|
11533
|
-
this.sphereStates[sphereIndices[i]].sphereSource.setCenter(...this.sphereStates[sphereIndices[i]].point);
|
|
11534
|
-
this.sphereStates[sphereIndices[i]].sphereSource.modified();
|
|
11535
|
-
const otherSphere = this.sphereStates.find((s, idx) => s.axis === axes[i] && idx !== sphereIndices[i]);
|
|
11536
|
-
const newCenter = (otherSphere.point[i] + plane.getOrigin()[i]) / 2;
|
|
11537
|
-
this.sphereStates.forEach((state) => {
|
|
11538
|
-
if (!state.isCorner &&
|
|
11539
|
-
state.axis !== axes[i] &&
|
|
11540
|
-
!evt.detail.viewportOrientation.includes(orientationAxes[i])) {
|
|
11541
|
-
state.point[i] = newCenter;
|
|
11542
|
-
state.sphereSource.setCenter(state.point);
|
|
11543
|
-
state.sphereActor.getProperty().setColor(state.color);
|
|
11544
|
-
state.sphereSource.modified();
|
|
11545
|
-
}
|
|
11546
|
-
});
|
|
11547
|
-
const volumeActor = viewport.getDefaultActor()?.actor;
|
|
11548
|
-
if (volumeActor) {
|
|
11549
|
-
const mapper = volumeActor.getMapper();
|
|
11550
|
-
const clippingPlanes = mapper.getClippingPlanes();
|
|
11551
|
-
if (clippingPlanes) {
|
|
11552
|
-
clippingPlanes[planeIndices[i]].setOrigin(plane.getOrigin());
|
|
11553
|
-
}
|
|
11554
|
-
}
|
|
11555
|
-
}
|
|
11607
|
+
if (evt.detail.clippingPlanes &&
|
|
11608
|
+
evt.detail.clippingPlanes.length >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
11609
|
+
this.originalClippingPlanes = (0,volumeCropping.copyClippingPlanes)(evt.detail.clippingPlanes);
|
|
11610
|
+
this._updateFaceSpheresFromClippingPlanes();
|
|
11611
|
+
this._updateCornerSpheresFromFaces();
|
|
11612
|
+
this._updateFaceSpheresFromCorners();
|
|
11556
11613
|
this._updateCornerSpheres();
|
|
11614
|
+
const mapper = this._getVolumeMapper(viewport);
|
|
11615
|
+
if (mapper) {
|
|
11616
|
+
this._applyClippingPlanesToMapper(mapper);
|
|
11617
|
+
}
|
|
11557
11618
|
viewport.render();
|
|
11619
|
+
this._notifyClippingPlanesChanged(viewport);
|
|
11620
|
+
}
|
|
11621
|
+
else {
|
|
11622
|
+
this._notifyClippingPlanesChanged(viewport);
|
|
11558
11623
|
}
|
|
11559
11624
|
};
|
|
11560
11625
|
this._getViewportsInfo = () => {
|
|
11561
|
-
const
|
|
11562
|
-
return
|
|
11626
|
+
const toolGroup = (0,ToolGroupManager.getToolGroup)(this.toolGroupId);
|
|
11627
|
+
return toolGroup?.viewportsInfo || [];
|
|
11563
11628
|
};
|
|
11564
11629
|
this._initialize3DViewports = (viewportsInfo) => {
|
|
11565
|
-
if (!viewportsInfo
|
|
11630
|
+
if (!viewportsInfo?.length || !viewportsInfo[0]) {
|
|
11566
11631
|
console.warn('VolumeCroppingTool: No viewportsInfo available for initialization of volumecroppingtool.');
|
|
11567
11632
|
return;
|
|
11568
11633
|
}
|
|
11569
11634
|
const viewport = this._getViewport();
|
|
11635
|
+
if (!viewport) {
|
|
11636
|
+
return;
|
|
11637
|
+
}
|
|
11570
11638
|
const volumeActors = viewport.getActors();
|
|
11571
11639
|
if (!volumeActors || volumeActors.length === 0) {
|
|
11572
11640
|
console.warn('VolumeCroppingTool: No volume actors found in the viewport.');
|
|
@@ -11578,78 +11646,85 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11578
11646
|
return;
|
|
11579
11647
|
}
|
|
11580
11648
|
this.seriesInstanceUID = imageData.seriesInstanceUID || 'unknown';
|
|
11581
|
-
|
|
11649
|
+
this.volumeDirectionVectors = (0,volumeCropping.extractVolumeDirectionVectors)(imageData);
|
|
11650
|
+
const { xDir, yDir, zDir } = this.volumeDirectionVectors;
|
|
11651
|
+
const dimensions = imageData.getDimensions();
|
|
11582
11652
|
const cropFactor = this.configuration.initialCropFactor || 0.1;
|
|
11583
|
-
const
|
|
11584
|
-
const
|
|
11585
|
-
const
|
|
11586
|
-
const
|
|
11587
|
-
const
|
|
11588
|
-
const
|
|
11589
|
-
const
|
|
11590
|
-
const
|
|
11591
|
-
const
|
|
11592
|
-
const
|
|
11593
|
-
const
|
|
11594
|
-
|
|
11595
|
-
|
|
11653
|
+
const xMin = cropFactor * dimensions[0];
|
|
11654
|
+
const xMax = (1 - cropFactor) * dimensions[0];
|
|
11655
|
+
const yMin = cropFactor * dimensions[1];
|
|
11656
|
+
const yMax = (1 - cropFactor) * dimensions[1];
|
|
11657
|
+
const zMin = cropFactor * dimensions[2];
|
|
11658
|
+
const zMax = (1 - cropFactor) * dimensions[2];
|
|
11659
|
+
const xCenter = (xMin + xMax) / 2;
|
|
11660
|
+
const yCenter = (yMin + yMax) / 2;
|
|
11661
|
+
const zCenter = (zMin + zMax) / 2;
|
|
11662
|
+
const faceXMin = imageData.indexToWorld([xMin, yCenter, zCenter]);
|
|
11663
|
+
const faceXMax = imageData.indexToWorld([xMax, yCenter, zCenter]);
|
|
11664
|
+
const faceYMin = imageData.indexToWorld([xCenter, yMin, zCenter]);
|
|
11665
|
+
const faceYMax = imageData.indexToWorld([xCenter, yMax, zCenter]);
|
|
11666
|
+
const faceZMin = imageData.indexToWorld([xCenter, yCenter, zMin]);
|
|
11667
|
+
const faceZMax = imageData.indexToWorld([xCenter, yCenter, zMax]);
|
|
11668
|
+
const planeXMin = Plane/* default.newInstance */.Ay.newInstance({
|
|
11669
|
+
origin: faceXMin,
|
|
11670
|
+
normal: xDir,
|
|
11596
11671
|
});
|
|
11597
|
-
const
|
|
11598
|
-
origin:
|
|
11599
|
-
normal: [-
|
|
11672
|
+
const planeXMax = Plane/* default.newInstance */.Ay.newInstance({
|
|
11673
|
+
origin: faceXMax,
|
|
11674
|
+
normal: [-xDir[0], -xDir[1], -xDir[2]],
|
|
11600
11675
|
});
|
|
11601
|
-
const
|
|
11602
|
-
origin:
|
|
11603
|
-
normal:
|
|
11676
|
+
const planeYMin = Plane/* default.newInstance */.Ay.newInstance({
|
|
11677
|
+
origin: faceYMin,
|
|
11678
|
+
normal: yDir,
|
|
11604
11679
|
});
|
|
11605
|
-
const
|
|
11606
|
-
origin:
|
|
11607
|
-
normal: [0, -1,
|
|
11680
|
+
const planeYMax = Plane/* default.newInstance */.Ay.newInstance({
|
|
11681
|
+
origin: faceYMax,
|
|
11682
|
+
normal: [-yDir[0], -yDir[1], -yDir[2]],
|
|
11608
11683
|
});
|
|
11609
|
-
const
|
|
11610
|
-
origin:
|
|
11611
|
-
normal:
|
|
11684
|
+
const planeZMin = Plane/* default.newInstance */.Ay.newInstance({
|
|
11685
|
+
origin: faceZMin,
|
|
11686
|
+
normal: zDir,
|
|
11612
11687
|
});
|
|
11613
|
-
const
|
|
11614
|
-
origin:
|
|
11615
|
-
normal: [0,
|
|
11688
|
+
const planeZMax = Plane/* default.newInstance */.Ay.newInstance({
|
|
11689
|
+
origin: faceZMax,
|
|
11690
|
+
normal: [-zDir[0], -zDir[1], -zDir[2]],
|
|
11616
11691
|
});
|
|
11617
|
-
const
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
11625
|
-
planes.push(planeZmax);
|
|
11692
|
+
const planes = [
|
|
11693
|
+
planeXMin,
|
|
11694
|
+
planeXMax,
|
|
11695
|
+
planeYMin,
|
|
11696
|
+
planeYMax,
|
|
11697
|
+
planeZMin,
|
|
11698
|
+
planeZMax,
|
|
11699
|
+
];
|
|
11626
11700
|
const originalPlanes = planes.map((plane) => ({
|
|
11627
11701
|
origin: [...plane.getOrigin()],
|
|
11628
11702
|
normal: [...plane.getNormal()],
|
|
11629
11703
|
}));
|
|
11630
11704
|
this.originalClippingPlanes = originalPlanes;
|
|
11631
|
-
const
|
|
11632
|
-
const
|
|
11633
|
-
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
|
|
11637
|
-
const
|
|
11638
|
-
|
|
11639
|
-
this._addSphere(viewport,
|
|
11640
|
-
this._addSphere(viewport,
|
|
11641
|
-
this._addSphere(viewport,
|
|
11642
|
-
this._addSphere(viewport,
|
|
11643
|
-
this._addSphere(viewport,
|
|
11705
|
+
const diag0 = imageData.indexToWorld([0, 0, 0]);
|
|
11706
|
+
const diag1 = imageData.indexToWorld([
|
|
11707
|
+
dimensions[0],
|
|
11708
|
+
dimensions[1],
|
|
11709
|
+
dimensions[2],
|
|
11710
|
+
]);
|
|
11711
|
+
const diagonal = gl_matrix_esm/* vec3.distance */.eR.distance(diag0, diag1);
|
|
11712
|
+
const adaptiveRadius = calculateAdaptiveSphereRadius(diagonal, this.configuration);
|
|
11713
|
+
this._addSphere(viewport, faceXMin, 'x', 'min', null, adaptiveRadius);
|
|
11714
|
+
this._addSphere(viewport, faceXMax, 'x', 'max', null, adaptiveRadius);
|
|
11715
|
+
this._addSphere(viewport, faceYMin, 'y', 'min', null, adaptiveRadius);
|
|
11716
|
+
this._addSphere(viewport, faceYMax, 'y', 'max', null, adaptiveRadius);
|
|
11717
|
+
this._addSphere(viewport, faceZMin, 'z', 'min', null, adaptiveRadius);
|
|
11718
|
+
this._addSphere(viewport, faceZMax, 'z', 'max', null, adaptiveRadius);
|
|
11644
11719
|
const corners = [
|
|
11645
|
-
[xMin, yMin, zMin],
|
|
11646
|
-
[xMin, yMin, zMax],
|
|
11647
|
-
[xMin, yMax, zMin],
|
|
11648
|
-
[xMin, yMax, zMax],
|
|
11649
|
-
[xMax, yMin, zMin],
|
|
11650
|
-
[xMax, yMin, zMax],
|
|
11651
|
-
[xMax, yMax, zMin],
|
|
11652
|
-
[xMax, yMax, zMax],
|
|
11720
|
+
imageData.indexToWorld([xMin, yMin, zMin]),
|
|
11721
|
+
imageData.indexToWorld([xMin, yMin, zMax]),
|
|
11722
|
+
imageData.indexToWorld([xMin, yMax, zMin]),
|
|
11723
|
+
imageData.indexToWorld([xMin, yMax, zMax]),
|
|
11724
|
+
imageData.indexToWorld([xMax, yMin, zMin]),
|
|
11725
|
+
imageData.indexToWorld([xMax, yMin, zMax]),
|
|
11726
|
+
imageData.indexToWorld([xMax, yMax, zMin]),
|
|
11727
|
+
imageData.indexToWorld([xMax, yMax, zMax]),
|
|
11653
11728
|
];
|
|
11654
11729
|
const cornerKeys = [
|
|
11655
11730
|
'XMIN_YMIN_ZMIN',
|
|
@@ -11678,21 +11753,24 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11678
11753
|
['XMAX_YMIN_ZMIN', 'XMAX_YMIN_ZMAX'],
|
|
11679
11754
|
['XMAX_YMAX_ZMIN', 'XMAX_YMAX_ZMAX'],
|
|
11680
11755
|
];
|
|
11681
|
-
edgeCornerPairs.forEach(([key1, key2]
|
|
11756
|
+
edgeCornerPairs.forEach(([key1, key2]) => {
|
|
11682
11757
|
const state1 = this.sphereStates.find((s) => s.uid === `corner_${key1}`);
|
|
11683
11758
|
const state2 = this.sphereStates.find((s) => s.uid === `corner_${key2}`);
|
|
11684
11759
|
if (state1 && state2) {
|
|
11685
11760
|
const uid = `edge_${key1}_${key2}`;
|
|
11686
|
-
const { actor, source } =
|
|
11761
|
+
const { actor, source } = addLine3DBetweenPoints(viewport, state1.point, state2.point, [0.7, 0.7, 0.7], uid, this.configuration.showHandles);
|
|
11687
11762
|
this.edgeLines[uid] = { actor, source, key1, key2 };
|
|
11688
11763
|
}
|
|
11689
11764
|
});
|
|
11690
|
-
mapper
|
|
11691
|
-
|
|
11692
|
-
|
|
11693
|
-
mapper.addClippingPlane(
|
|
11694
|
-
mapper.addClippingPlane(
|
|
11695
|
-
mapper.addClippingPlane(
|
|
11765
|
+
const mapper = viewport
|
|
11766
|
+
.getDefaultActor()
|
|
11767
|
+
.actor.getMapper();
|
|
11768
|
+
mapper.addClippingPlane(planeXMin);
|
|
11769
|
+
mapper.addClippingPlane(planeXMax);
|
|
11770
|
+
mapper.addClippingPlane(planeYMin);
|
|
11771
|
+
mapper.addClippingPlane(planeYMax);
|
|
11772
|
+
mapper.addClippingPlane(planeZMin);
|
|
11773
|
+
mapper.addClippingPlane(planeZMax);
|
|
11696
11774
|
esm.eventTarget.addEventListener(enums.Events.VOLUMECROPPINGCONTROL_TOOL_CHANGED, (evt) => {
|
|
11697
11775
|
this._onControlToolChange(evt);
|
|
11698
11776
|
});
|
|
@@ -11706,107 +11784,14 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11706
11784
|
return { viewport, world };
|
|
11707
11785
|
};
|
|
11708
11786
|
this._getViewport = () => {
|
|
11709
|
-
const
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
};
|
|
11713
|
-
this._handleCornerSphereMovement = (sphereState, world, viewport) => {
|
|
11714
|
-
const newCorner = this._calculateNewCornerPosition(world);
|
|
11715
|
-
this._updateSpherePosition(sphereState, newCorner);
|
|
11716
|
-
const axisFlags = this._parseCornerKey(sphereState.uid);
|
|
11717
|
-
this._updateRelatedCorners(sphereState, newCorner, axisFlags);
|
|
11718
|
-
this._updateAfterCornerMovement(viewport);
|
|
11719
|
-
};
|
|
11720
|
-
this._handleFaceSphereMovement = (sphereState, world, viewport) => {
|
|
11721
|
-
const axisIdx = { x: 0, y: 1, z: 2 }[sphereState.axis];
|
|
11722
|
-
let newValue = world[axisIdx];
|
|
11723
|
-
if (this.faceDragOffset !== null) {
|
|
11724
|
-
newValue += this.faceDragOffset;
|
|
11725
|
-
}
|
|
11726
|
-
sphereState.point[axisIdx] = newValue;
|
|
11727
|
-
sphereState.sphereSource.setCenter(...sphereState.point);
|
|
11728
|
-
sphereState.sphereSource.modified();
|
|
11729
|
-
this._updateAfterFaceMovement(viewport);
|
|
11730
|
-
};
|
|
11731
|
-
this._calculateNewCornerPosition = (world) => {
|
|
11732
|
-
let newCorner = [world[0], world[1], world[2]];
|
|
11733
|
-
if (this.cornerDragOffset) {
|
|
11734
|
-
newCorner = [
|
|
11735
|
-
world[0] + this.cornerDragOffset[0],
|
|
11736
|
-
world[1] + this.cornerDragOffset[1],
|
|
11737
|
-
world[2] + this.cornerDragOffset[2],
|
|
11738
|
-
];
|
|
11739
|
-
}
|
|
11740
|
-
return newCorner;
|
|
11741
|
-
};
|
|
11742
|
-
this._parseCornerKey = (uid) => {
|
|
11743
|
-
const cornerKey = uid.replace('corner_', '');
|
|
11744
|
-
return {
|
|
11745
|
-
isXMin: cornerKey.includes('XMIN'),
|
|
11746
|
-
isXMax: cornerKey.includes('XMAX'),
|
|
11747
|
-
isYMin: cornerKey.includes('YMIN'),
|
|
11748
|
-
isYMax: cornerKey.includes('YMAX'),
|
|
11749
|
-
isZMin: cornerKey.includes('ZMIN'),
|
|
11750
|
-
isZMax: cornerKey.includes('ZMAX'),
|
|
11751
|
-
};
|
|
11752
|
-
};
|
|
11753
|
-
this._updateSpherePosition = (sphereState, newPosition) => {
|
|
11754
|
-
sphereState.point = newPosition;
|
|
11755
|
-
sphereState.sphereSource.setCenter(...newPosition);
|
|
11756
|
-
sphereState.sphereSource.modified();
|
|
11757
|
-
};
|
|
11758
|
-
this._updateRelatedCorners = (draggedSphere, newCorner, axisFlags) => {
|
|
11759
|
-
this.sphereStates.forEach((state) => {
|
|
11760
|
-
if (!state.isCorner || state === draggedSphere) {
|
|
11761
|
-
return;
|
|
11762
|
-
}
|
|
11763
|
-
const key = state.uid.replace('corner_', '');
|
|
11764
|
-
const shouldUpdate = this._shouldUpdateCorner(key, axisFlags);
|
|
11765
|
-
if (shouldUpdate) {
|
|
11766
|
-
this._updateCornerCoordinates(state, newCorner, key, axisFlags);
|
|
11767
|
-
}
|
|
11768
|
-
});
|
|
11769
|
-
};
|
|
11770
|
-
this._shouldUpdateCorner = (cornerKey, axisFlags) => {
|
|
11771
|
-
return ((axisFlags.isXMin && cornerKey.includes('XMIN')) ||
|
|
11772
|
-
(axisFlags.isXMax && cornerKey.includes('XMAX')) ||
|
|
11773
|
-
(axisFlags.isYMin && cornerKey.includes('YMIN')) ||
|
|
11774
|
-
(axisFlags.isYMax && cornerKey.includes('YMAX')) ||
|
|
11775
|
-
(axisFlags.isZMin && cornerKey.includes('ZMIN')) ||
|
|
11776
|
-
(axisFlags.isZMax && cornerKey.includes('ZMAX')));
|
|
11777
|
-
};
|
|
11778
|
-
this._updateCornerCoordinates = (state, newCorner, cornerKey, axisFlags) => {
|
|
11779
|
-
if ((axisFlags.isXMin && cornerKey.includes('XMIN')) ||
|
|
11780
|
-
(axisFlags.isXMax && cornerKey.includes('XMAX'))) {
|
|
11781
|
-
state.point[0] = newCorner[0];
|
|
11782
|
-
}
|
|
11783
|
-
if ((axisFlags.isYMin && cornerKey.includes('YMIN')) ||
|
|
11784
|
-
(axisFlags.isYMax && cornerKey.includes('YMAX'))) {
|
|
11785
|
-
state.point[1] = newCorner[1];
|
|
11786
|
-
}
|
|
11787
|
-
if ((axisFlags.isZMin && cornerKey.includes('ZMIN')) ||
|
|
11788
|
-
(axisFlags.isZMax && cornerKey.includes('ZMAX'))) {
|
|
11789
|
-
state.point[2] = newCorner[2];
|
|
11787
|
+
const viewportsInfo = this._getViewportsInfo();
|
|
11788
|
+
if (!viewportsInfo || viewportsInfo.length === 0) {
|
|
11789
|
+
return null;
|
|
11790
11790
|
}
|
|
11791
|
-
|
|
11792
|
-
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
this._updateFaceSpheresFromCorners();
|
|
11796
|
-
this._updateCornerSpheres();
|
|
11797
|
-
this._updateClippingPlanesFromFaceSpheres(viewport);
|
|
11798
|
-
};
|
|
11799
|
-
this._updateAfterFaceMovement = (viewport) => {
|
|
11800
|
-
this._updateCornerSpheresFromFaces();
|
|
11801
|
-
this._updateClippingPlanesFromFaceSpheres(viewport);
|
|
11802
|
-
};
|
|
11803
|
-
this._triggerToolChangedEvent = (sphereState) => {
|
|
11804
|
-
(0,esm.triggerEvent)(esm.eventTarget, enums.Events.VOLUMECROPPING_TOOL_CHANGED, {
|
|
11805
|
-
toolCenter: sphereState.point,
|
|
11806
|
-
axis: sphereState.isCorner ? 'corner' : sphereState.axis,
|
|
11807
|
-
draggingSphereIndex: this.draggingSphereIndex,
|
|
11808
|
-
seriesInstanceUID: this.seriesInstanceUID,
|
|
11809
|
-
});
|
|
11791
|
+
const [viewport3D] = viewportsInfo;
|
|
11792
|
+
const renderingEngine = (0,esm.getRenderingEngine)(viewport3D.renderingEngineId);
|
|
11793
|
+
const viewport = renderingEngine?.getViewport(viewport3D.viewportId);
|
|
11794
|
+
return viewport || null;
|
|
11810
11795
|
};
|
|
11811
11796
|
this._onNewVolume = () => {
|
|
11812
11797
|
const viewportsInfo = this._getViewportsInfo();
|
|
@@ -11815,6 +11800,207 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11815
11800
|
this.edgeLines = {};
|
|
11816
11801
|
this._initialize3DViewports(viewportsInfo);
|
|
11817
11802
|
};
|
|
11803
|
+
this._rotateClippingPlanes = (evt) => {
|
|
11804
|
+
const { element, currentPoints, lastPoints } = evt.detail;
|
|
11805
|
+
const currentPointsCanvas = currentPoints.canvas;
|
|
11806
|
+
const lastPointsCanvas = lastPoints.canvas;
|
|
11807
|
+
const rotateIncrementDegrees = this.configuration.rotateClippingPlanesIncrementDegrees ??
|
|
11808
|
+
this.configuration.rotateIncrementDegrees ??
|
|
11809
|
+
5;
|
|
11810
|
+
const enabledElement = (0,esm.getEnabledElement)(element);
|
|
11811
|
+
const { viewport } = enabledElement;
|
|
11812
|
+
const camera = viewport.getCamera();
|
|
11813
|
+
const width = element.clientWidth;
|
|
11814
|
+
const height = element.clientHeight;
|
|
11815
|
+
const normalizedPosition = [
|
|
11816
|
+
currentPointsCanvas[0] / width,
|
|
11817
|
+
currentPointsCanvas[1] / height,
|
|
11818
|
+
];
|
|
11819
|
+
const normalizedPreviousPosition = [
|
|
11820
|
+
lastPointsCanvas[0] / width,
|
|
11821
|
+
lastPointsCanvas[1] / height,
|
|
11822
|
+
];
|
|
11823
|
+
const normalizedCenter = [0.5, 0.5];
|
|
11824
|
+
const radsq = (1.0 + Math.abs(normalizedCenter[0])) ** 2.0;
|
|
11825
|
+
const op = [normalizedPreviousPosition[0], 0, 0];
|
|
11826
|
+
const oe = [normalizedPosition[0], 0, 0];
|
|
11827
|
+
const opsq = op[0] ** 2;
|
|
11828
|
+
const oesq = oe[0] ** 2;
|
|
11829
|
+
const lop = opsq > radsq ? 0 : Math.sqrt(radsq - opsq);
|
|
11830
|
+
const loe = oesq > radsq ? 0 : Math.sqrt(radsq - oesq);
|
|
11831
|
+
const nop = [op[0], 0, lop];
|
|
11832
|
+
Core_Math/* default.normalize */.Ay.normalize(nop);
|
|
11833
|
+
const noe = [oe[0], 0, loe];
|
|
11834
|
+
Core_Math/* default.normalize */.Ay.normalize(noe);
|
|
11835
|
+
const dot = Core_Math/* default.dot */.Ay.dot(nop, noe);
|
|
11836
|
+
if (Math.abs(dot) > 0.0001) {
|
|
11837
|
+
const angleX = 20 *
|
|
11838
|
+
Math.acos(Core_Math/* default.clampValue */.Ay.clampValue(dot, -1.0, 1.0)) *
|
|
11839
|
+
Math.sign(normalizedPosition[0] - normalizedPreviousPosition[0]) *
|
|
11840
|
+
rotateIncrementDegrees;
|
|
11841
|
+
const upVec = camera.viewUp;
|
|
11842
|
+
const atV = camera.viewPlaneNormal;
|
|
11843
|
+
const rightV = [0, 0, 0];
|
|
11844
|
+
const forwardV = [0, 0, 0];
|
|
11845
|
+
Core_Math/* default.cross */.Ay.cross(upVec, atV, rightV);
|
|
11846
|
+
Core_Math/* default.normalize */.Ay.normalize(rightV);
|
|
11847
|
+
Core_Math/* default.cross */.Ay.cross(atV, rightV, forwardV);
|
|
11848
|
+
Core_Math/* default.normalize */.Ay.normalize(forwardV);
|
|
11849
|
+
const angleY = 20 *
|
|
11850
|
+
(normalizedPosition[1] - normalizedPreviousPosition[1]) *
|
|
11851
|
+
rotateIncrementDegrees;
|
|
11852
|
+
let rotationCenter;
|
|
11853
|
+
if (this.sphereStates.length >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
11854
|
+
const faces = [
|
|
11855
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMIN],
|
|
11856
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMAX],
|
|
11857
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.YMIN],
|
|
11858
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.YMAX],
|
|
11859
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.ZMIN],
|
|
11860
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.ZMAX],
|
|
11861
|
+
];
|
|
11862
|
+
rotationCenter = [
|
|
11863
|
+
(faces[0].point[0] +
|
|
11864
|
+
faces[1].point[0] +
|
|
11865
|
+
faces[2].point[0] +
|
|
11866
|
+
faces[3].point[0] +
|
|
11867
|
+
faces[4].point[0] +
|
|
11868
|
+
faces[5].point[0]) /
|
|
11869
|
+
volumeCropping.NUM_CLIPPING_PLANES,
|
|
11870
|
+
(faces[0].point[1] +
|
|
11871
|
+
faces[1].point[1] +
|
|
11872
|
+
faces[2].point[1] +
|
|
11873
|
+
faces[3].point[1] +
|
|
11874
|
+
faces[4].point[1] +
|
|
11875
|
+
faces[5].point[1]) /
|
|
11876
|
+
volumeCropping.NUM_CLIPPING_PLANES,
|
|
11877
|
+
(faces[0].point[2] +
|
|
11878
|
+
faces[1].point[2] +
|
|
11879
|
+
faces[2].point[2] +
|
|
11880
|
+
faces[3].point[2] +
|
|
11881
|
+
faces[4].point[2] +
|
|
11882
|
+
faces[5].point[2]) /
|
|
11883
|
+
volumeCropping.NUM_CLIPPING_PLANES,
|
|
11884
|
+
];
|
|
11885
|
+
}
|
|
11886
|
+
else {
|
|
11887
|
+
rotationCenter = [0, 0, 0];
|
|
11888
|
+
}
|
|
11889
|
+
const transformX = gl_matrix_esm/* mat4.identity */.pB.identity(new Float32Array(16));
|
|
11890
|
+
gl_matrix_esm/* mat4.translate */.pB.translate(transformX, transformX, rotationCenter);
|
|
11891
|
+
gl_matrix_esm/* mat4.rotate */.pB.rotate(transformX, transformX, (angleX * Math.PI) / 180, forwardV);
|
|
11892
|
+
gl_matrix_esm/* mat4.translate */.pB.translate(transformX, transformX, [
|
|
11893
|
+
-rotationCenter[0],
|
|
11894
|
+
-rotationCenter[1],
|
|
11895
|
+
-rotationCenter[2],
|
|
11896
|
+
]);
|
|
11897
|
+
const transformY = gl_matrix_esm/* mat4.identity */.pB.identity(new Float32Array(16));
|
|
11898
|
+
gl_matrix_esm/* mat4.translate */.pB.translate(transformY, transformY, rotationCenter);
|
|
11899
|
+
gl_matrix_esm/* mat4.rotate */.pB.rotate(transformY, transformY, (angleY * Math.PI) / 180, rightV);
|
|
11900
|
+
gl_matrix_esm/* mat4.translate */.pB.translate(transformY, transformY, [
|
|
11901
|
+
-rotationCenter[0],
|
|
11902
|
+
-rotationCenter[1],
|
|
11903
|
+
-rotationCenter[2],
|
|
11904
|
+
]);
|
|
11905
|
+
const transform = gl_matrix_esm/* mat4.create */.pB.create();
|
|
11906
|
+
gl_matrix_esm/* mat4.multiply */.pB.multiply(transform, transformY, transformX);
|
|
11907
|
+
const normalTransformX4 = gl_matrix_esm/* mat4.identity */.pB.identity(new Float32Array(16));
|
|
11908
|
+
gl_matrix_esm/* mat4.rotate */.pB.rotate(normalTransformX4, normalTransformX4, (angleX * Math.PI) / 180, forwardV);
|
|
11909
|
+
const normalTransformX = gl_matrix_esm/* mat3.create */.w0.create();
|
|
11910
|
+
gl_matrix_esm/* mat3.fromMat4 */.w0.fromMat4(normalTransformX, normalTransformX4);
|
|
11911
|
+
const normalTransformY4 = gl_matrix_esm/* mat4.identity */.pB.identity(new Float32Array(16));
|
|
11912
|
+
gl_matrix_esm/* mat4.rotate */.pB.rotate(normalTransformY4, normalTransformY4, (angleY * Math.PI) / 180, rightV);
|
|
11913
|
+
const normalTransformY = gl_matrix_esm/* mat3.create */.w0.create();
|
|
11914
|
+
gl_matrix_esm/* mat3.fromMat4 */.w0.fromMat4(normalTransformY, normalTransformY4);
|
|
11915
|
+
const normalTransform = gl_matrix_esm/* mat3.create */.w0.create();
|
|
11916
|
+
gl_matrix_esm/* mat3.multiply */.w0.multiply(normalTransform, normalTransformY, normalTransformX);
|
|
11917
|
+
for (let i = 0; i < this.originalClippingPlanes.length; ++i) {
|
|
11918
|
+
const plane = this.originalClippingPlanes[i];
|
|
11919
|
+
const originVec = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(plane.origin[0], plane.origin[1], plane.origin[2]);
|
|
11920
|
+
gl_matrix_esm/* vec3.transformMat4 */.eR.transformMat4(originVec, originVec, transform);
|
|
11921
|
+
plane.origin = [originVec[0], originVec[1], originVec[2]];
|
|
11922
|
+
const normalVec = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(plane.normal[0], plane.normal[1], plane.normal[2]);
|
|
11923
|
+
gl_matrix_esm/* vec3.transformMat3 */.eR.transformMat3(normalVec, normalVec, normalTransform);
|
|
11924
|
+
gl_matrix_esm/* vec3.normalize */.eR.normalize(normalVec, normalVec);
|
|
11925
|
+
plane.normal = [normalVec[0], normalVec[1], normalVec[2]];
|
|
11926
|
+
}
|
|
11927
|
+
if (this.sphereStates.length >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
11928
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMIN].point = [
|
|
11929
|
+
...this.originalClippingPlanes[volumeCropping.PLANEINDEX.XMIN].origin,
|
|
11930
|
+
];
|
|
11931
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMAX].point = [
|
|
11932
|
+
...this.originalClippingPlanes[volumeCropping.PLANEINDEX.XMAX].origin,
|
|
11933
|
+
];
|
|
11934
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.YMIN].point = [
|
|
11935
|
+
...this.originalClippingPlanes[volumeCropping.PLANEINDEX.YMIN].origin,
|
|
11936
|
+
];
|
|
11937
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.YMAX].point = [
|
|
11938
|
+
...this.originalClippingPlanes[volumeCropping.PLANEINDEX.YMAX].origin,
|
|
11939
|
+
];
|
|
11940
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.ZMIN].point = [
|
|
11941
|
+
...this.originalClippingPlanes[volumeCropping.PLANEINDEX.ZMIN].origin,
|
|
11942
|
+
];
|
|
11943
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.ZMAX].point = [
|
|
11944
|
+
...this.originalClippingPlanes[volumeCropping.PLANEINDEX.ZMAX].origin,
|
|
11945
|
+
];
|
|
11946
|
+
[
|
|
11947
|
+
volumeCropping.SPHEREINDEX.XMIN,
|
|
11948
|
+
volumeCropping.SPHEREINDEX.XMAX,
|
|
11949
|
+
volumeCropping.SPHEREINDEX.YMIN,
|
|
11950
|
+
volumeCropping.SPHEREINDEX.YMAX,
|
|
11951
|
+
volumeCropping.SPHEREINDEX.ZMIN,
|
|
11952
|
+
volumeCropping.SPHEREINDEX.ZMAX,
|
|
11953
|
+
].forEach((idx) => {
|
|
11954
|
+
const s = this.sphereStates[idx];
|
|
11955
|
+
s.sphereSource.setCenter(...s.point);
|
|
11956
|
+
s.sphereSource.modified();
|
|
11957
|
+
});
|
|
11958
|
+
const cornerIndices = [
|
|
11959
|
+
volumeCropping.SPHEREINDEX.XMIN_YMIN_ZMIN,
|
|
11960
|
+
volumeCropping.SPHEREINDEX.XMIN_YMIN_ZMAX,
|
|
11961
|
+
volumeCropping.SPHEREINDEX.XMIN_YMAX_ZMIN,
|
|
11962
|
+
volumeCropping.SPHEREINDEX.XMIN_YMAX_ZMAX,
|
|
11963
|
+
volumeCropping.SPHEREINDEX.XMAX_YMIN_ZMIN,
|
|
11964
|
+
volumeCropping.SPHEREINDEX.XMAX_YMIN_ZMAX,
|
|
11965
|
+
volumeCropping.SPHEREINDEX.XMAX_YMAX_ZMIN,
|
|
11966
|
+
volumeCropping.SPHEREINDEX.XMAX_YMAX_ZMAX,
|
|
11967
|
+
];
|
|
11968
|
+
cornerIndices.forEach((idx) => {
|
|
11969
|
+
const cornerState = this.sphereStates[idx];
|
|
11970
|
+
if (cornerState) {
|
|
11971
|
+
const cornerVec = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(cornerState.point[0], cornerState.point[1], cornerState.point[2]);
|
|
11972
|
+
gl_matrix_esm/* vec3.transformMat4 */.eR.transformMat4(cornerVec, cornerVec, transform);
|
|
11973
|
+
cornerState.point = [
|
|
11974
|
+
cornerVec[0],
|
|
11975
|
+
cornerVec[1],
|
|
11976
|
+
cornerVec[2],
|
|
11977
|
+
];
|
|
11978
|
+
cornerState.sphereSource.setCenter(...cornerState.point);
|
|
11979
|
+
cornerState.sphereSource.modified();
|
|
11980
|
+
}
|
|
11981
|
+
});
|
|
11982
|
+
Object.values(this.edgeLines).forEach(({ source, key1, key2 }) => {
|
|
11983
|
+
const state1 = this.sphereStates.find((s) => s.uid === `corner_${key1}`);
|
|
11984
|
+
const state2 = this.sphereStates.find((s) => s.uid === `corner_${key2}`);
|
|
11985
|
+
if (state1 && state2) {
|
|
11986
|
+
const points = source.getPoints();
|
|
11987
|
+
points.setPoint(0, state1.point[0], state1.point[1], state1.point[2]);
|
|
11988
|
+
points.setPoint(1, state2.point[0], state2.point[1], state2.point[2]);
|
|
11989
|
+
points.modified();
|
|
11990
|
+
source.modified();
|
|
11991
|
+
}
|
|
11992
|
+
});
|
|
11993
|
+
}
|
|
11994
|
+
this._updateClippingPlanes(viewport);
|
|
11995
|
+
viewport.render();
|
|
11996
|
+
(0,esm.triggerEvent)(esm.eventTarget, enums.Events.VOLUMECROPPING_TOOL_CHANGED, {
|
|
11997
|
+
originalClippingPlanes: this.originalClippingPlanes,
|
|
11998
|
+
viewportId: viewport.id,
|
|
11999
|
+
renderingEngineId: viewport.renderingEngineId,
|
|
12000
|
+
seriesInstanceUID: this.seriesInstanceUID,
|
|
12001
|
+
});
|
|
12002
|
+
}
|
|
12003
|
+
};
|
|
11818
12004
|
this._rotateCamera = (viewport, centerWorld, axis, angle) => {
|
|
11819
12005
|
const vtkCamera = viewport.getVtkActiveCamera();
|
|
11820
12006
|
const viewUp = vtkCamera.getViewUp();
|
|
@@ -11846,59 +12032,55 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11846
12032
|
this.mouseDragCallback = this._dragCallback.bind(this);
|
|
11847
12033
|
}
|
|
11848
12034
|
onSetToolActive() {
|
|
11849
|
-
|
|
11850
|
-
|
|
11851
|
-
|
|
11852
|
-
this.
|
|
11853
|
-
|
|
11854
|
-
|
|
11855
|
-
|
|
11856
|
-
|
|
11857
|
-
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
|
|
11861
|
-
const subscribeToElementResize = () => {
|
|
11862
|
-
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
11863
|
-
if (!this._resizeObservers.has(viewportId)) {
|
|
11864
|
-
const { viewport } = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId) || { viewport: null };
|
|
11865
|
-
if (!viewport) {
|
|
12035
|
+
const viewportsInfo = this._getViewportsInfo();
|
|
12036
|
+
const subscribeToElementResize = () => {
|
|
12037
|
+
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
12038
|
+
if (!this._resizeObservers.has(viewportId)) {
|
|
12039
|
+
const { viewport } = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId) || { viewport: null };
|
|
12040
|
+
if (!viewport) {
|
|
12041
|
+
return;
|
|
12042
|
+
}
|
|
12043
|
+
const { element } = viewport;
|
|
12044
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
12045
|
+
const element = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
12046
|
+
if (!element) {
|
|
11866
12047
|
return;
|
|
11867
12048
|
}
|
|
11868
|
-
const {
|
|
11869
|
-
const
|
|
11870
|
-
|
|
11871
|
-
|
|
11872
|
-
|
|
11873
|
-
|
|
11874
|
-
|
|
11875
|
-
|
|
11876
|
-
viewport.resetCamera();
|
|
11877
|
-
viewport.setViewPresentation(viewPresentation);
|
|
11878
|
-
viewport.render();
|
|
11879
|
-
});
|
|
11880
|
-
resizeObserver.observe(element);
|
|
11881
|
-
this._resizeObservers.set(viewportId, resizeObserver);
|
|
11882
|
-
}
|
|
11883
|
-
});
|
|
11884
|
-
};
|
|
11885
|
-
subscribeToElementResize();
|
|
11886
|
-
this._viewportAddedListener = (evt) => {
|
|
11887
|
-
if (evt.detail.toolGroupId === this.toolGroupId) {
|
|
11888
|
-
subscribeToElementResize();
|
|
12049
|
+
const { viewport } = element;
|
|
12050
|
+
const viewPresentation = viewport.getViewPresentation();
|
|
12051
|
+
viewport.resetCamera();
|
|
12052
|
+
viewport.setViewPresentation(viewPresentation);
|
|
12053
|
+
viewport.render();
|
|
12054
|
+
});
|
|
12055
|
+
resizeObserver.observe(element);
|
|
12056
|
+
this._resizeObservers.set(viewportId, resizeObserver);
|
|
11889
12057
|
}
|
|
11890
|
-
};
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
12058
|
+
});
|
|
12059
|
+
};
|
|
12060
|
+
subscribeToElementResize();
|
|
12061
|
+
this._viewportAddedListener = (evt) => {
|
|
12062
|
+
if (evt.detail.toolGroupId === this.toolGroupId) {
|
|
12063
|
+
subscribeToElementResize();
|
|
12064
|
+
}
|
|
12065
|
+
};
|
|
12066
|
+
esm.eventTarget.addEventListener(enums.Events.TOOLGROUP_VIEWPORT_ADDED, this._viewportAddedListener);
|
|
12067
|
+
this._unsubscribeToViewportNewVolumeSet(viewportsInfo);
|
|
12068
|
+
this._subscribeToViewportNewVolumeSet(viewportsInfo);
|
|
12069
|
+
if (this.sphereStates && this.sphereStates.length === 0) {
|
|
12070
|
+
this.originalClippingPlanes = [];
|
|
11894
12071
|
this._initialize3DViewports(viewportsInfo);
|
|
12072
|
+
}
|
|
12073
|
+
this.configuration.showClippingPlanes = false;
|
|
12074
|
+
this.configuration.showHandles = false;
|
|
12075
|
+
const viewport = this._getViewport();
|
|
12076
|
+
if (viewport &&
|
|
12077
|
+
this.originalClippingPlanes &&
|
|
12078
|
+
this.originalClippingPlanes.length > 0) {
|
|
12079
|
+
this._updateClippingPlanes(viewport);
|
|
11895
12080
|
if (this.sphereStates && this.sphereStates.length > 0) {
|
|
11896
|
-
this.
|
|
11897
|
-
}
|
|
11898
|
-
else {
|
|
11899
|
-
this.originalClippingPlanes = [];
|
|
11900
|
-
this._initialize3DViewports(viewportsInfo);
|
|
12081
|
+
this._updateHandlesVisibility();
|
|
11901
12082
|
}
|
|
12083
|
+
viewport.render();
|
|
11902
12084
|
}
|
|
11903
12085
|
}
|
|
11904
12086
|
onSetToolDisabled() {
|
|
@@ -11916,30 +12098,7 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11916
12098
|
setHandlesVisible(visible) {
|
|
11917
12099
|
this.configuration.showHandles = visible;
|
|
11918
12100
|
if (visible) {
|
|
11919
|
-
this.
|
|
11920
|
-
this.originalClippingPlanes[PLANEINDEX.XMIN].origin[0];
|
|
11921
|
-
this.sphereStates[SPHEREINDEX.XMAX].point[0] =
|
|
11922
|
-
this.originalClippingPlanes[PLANEINDEX.XMAX].origin[0];
|
|
11923
|
-
this.sphereStates[SPHEREINDEX.YMIN].point[1] =
|
|
11924
|
-
this.originalClippingPlanes[PLANEINDEX.YMIN].origin[1];
|
|
11925
|
-
this.sphereStates[SPHEREINDEX.YMAX].point[1] =
|
|
11926
|
-
this.originalClippingPlanes[PLANEINDEX.YMAX].origin[1];
|
|
11927
|
-
this.sphereStates[SPHEREINDEX.ZMIN].point[2] =
|
|
11928
|
-
this.originalClippingPlanes[PLANEINDEX.ZMIN].origin[2];
|
|
11929
|
-
this.sphereStates[SPHEREINDEX.ZMAX].point[2] =
|
|
11930
|
-
this.originalClippingPlanes[PLANEINDEX.ZMAX].origin[2];
|
|
11931
|
-
[
|
|
11932
|
-
SPHEREINDEX.XMIN,
|
|
11933
|
-
SPHEREINDEX.XMAX,
|
|
11934
|
-
SPHEREINDEX.YMIN,
|
|
11935
|
-
SPHEREINDEX.YMAX,
|
|
11936
|
-
SPHEREINDEX.ZMIN,
|
|
11937
|
-
SPHEREINDEX.ZMAX,
|
|
11938
|
-
].forEach((idx) => {
|
|
11939
|
-
const s = this.sphereStates[idx];
|
|
11940
|
-
s.sphereSource.setCenter(...s.point);
|
|
11941
|
-
s.sphereSource.modified();
|
|
11942
|
-
});
|
|
12101
|
+
this._updateFaceSpheresFromClippingPlanes();
|
|
11943
12102
|
this._updateCornerSpheres();
|
|
11944
12103
|
}
|
|
11945
12104
|
this._updateHandlesVisibility();
|
|
@@ -11959,14 +12118,38 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
11959
12118
|
this.configuration.showClippingPlanes = visible;
|
|
11960
12119
|
const viewport = this._getViewport();
|
|
11961
12120
|
this._updateClippingPlanes(viewport);
|
|
12121
|
+
if (this.sphereStates && this.sphereStates.length > 0) {
|
|
12122
|
+
this.configuration.showHandles = visible;
|
|
12123
|
+
this._updateHandlesVisibility();
|
|
12124
|
+
}
|
|
12125
|
+
if (visible &&
|
|
12126
|
+
viewport &&
|
|
12127
|
+
this.originalClippingPlanes?.length >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
12128
|
+
this._notifyClippingPlanesChanged(viewport);
|
|
12129
|
+
}
|
|
11962
12130
|
viewport.render();
|
|
11963
12131
|
}
|
|
12132
|
+
getRotatePlanesOnDrag() {
|
|
12133
|
+
return this.rotatePlanesOnDrag;
|
|
12134
|
+
}
|
|
12135
|
+
setRotatePlanesOnDrag(enable) {
|
|
12136
|
+
this.rotatePlanesOnDrag = enable;
|
|
12137
|
+
const viewport = this._getViewport();
|
|
12138
|
+
if (viewport) {
|
|
12139
|
+
viewport.render();
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
11964
12142
|
_dragCallback(evt) {
|
|
11965
12143
|
const { element, currentPoints, lastPoints } = evt.detail;
|
|
11966
12144
|
if (this.draggingSphereIndex !== null) {
|
|
11967
12145
|
this._onMouseMoveSphere(evt);
|
|
11968
12146
|
}
|
|
11969
12147
|
else {
|
|
12148
|
+
const shiftKey = evt.detail.event?.shiftKey ?? false;
|
|
12149
|
+
if (this.rotatePlanesOnDrag === true || shiftKey) {
|
|
12150
|
+
this._rotateClippingPlanes(evt);
|
|
12151
|
+
return;
|
|
12152
|
+
}
|
|
11970
12153
|
const currentPointsCanvas = currentPoints.canvas;
|
|
11971
12154
|
const lastPointsCanvas = lastPoints.canvas;
|
|
11972
12155
|
const { rotateIncrementDegrees } = this.configuration;
|
|
@@ -12022,13 +12205,6 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
12022
12205
|
}
|
|
12023
12206
|
_updateClippingPlanes(viewport) {
|
|
12024
12207
|
const actorEntry = viewport.getDefaultActor();
|
|
12025
|
-
if (!actorEntry || !actorEntry.actor) {
|
|
12026
|
-
if (!viewport._missingActorWarned) {
|
|
12027
|
-
console.warn('VolumeCroppingTool._updateClippingPlanes: No default actor found in viewport.');
|
|
12028
|
-
viewport._missingActorWarned = true;
|
|
12029
|
-
}
|
|
12030
|
-
return;
|
|
12031
|
-
}
|
|
12032
12208
|
const actor = actorEntry.actor;
|
|
12033
12209
|
const mapper = actor.getMapper();
|
|
12034
12210
|
const matrix = actor.getMatrix();
|
|
@@ -12080,35 +12256,6 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
12080
12256
|
}
|
|
12081
12257
|
});
|
|
12082
12258
|
}
|
|
12083
|
-
_addLine3DBetweenPoints(viewport, point1, point2, color = [0.7, 0.7, 0.7], uid = '') {
|
|
12084
|
-
if (point1[0] === point2[0] &&
|
|
12085
|
-
point1[1] === point2[1] &&
|
|
12086
|
-
point1[2] === point2[2]) {
|
|
12087
|
-
return { actor: null, source: null };
|
|
12088
|
-
}
|
|
12089
|
-
const points = Points/* default.newInstance */.Ay.newInstance();
|
|
12090
|
-
points.setNumberOfPoints(2);
|
|
12091
|
-
points.setPoint(0, point1[0], point1[1], point1[2]);
|
|
12092
|
-
points.setPoint(1, point2[0], point2[1], point2[2]);
|
|
12093
|
-
const lines = CellArray/* default.newInstance */.Ay.newInstance({ values: [2, 0, 1] });
|
|
12094
|
-
const polyData = PolyData/* default.newInstance */.Ay.newInstance();
|
|
12095
|
-
polyData.setPoints(points);
|
|
12096
|
-
polyData.setLines(lines);
|
|
12097
|
-
const mapper = Mapper/* default.newInstance */.Ay.newInstance();
|
|
12098
|
-
mapper.setInputData(polyData);
|
|
12099
|
-
const actor = Actor/* default.newInstance */.Ay.newInstance();
|
|
12100
|
-
actor.setMapper(mapper);
|
|
12101
|
-
actor.getProperty().setColor(...color);
|
|
12102
|
-
actor.getProperty().setLineWidth(0.5);
|
|
12103
|
-
actor.getProperty().setOpacity(1.0);
|
|
12104
|
-
actor.getProperty().setInterpolationToFlat();
|
|
12105
|
-
actor.getProperty().setAmbient(1.0);
|
|
12106
|
-
actor.getProperty().setDiffuse(0.0);
|
|
12107
|
-
actor.getProperty().setSpecular(0.0);
|
|
12108
|
-
actor.setVisibility(this.configuration.showHandles);
|
|
12109
|
-
viewport.addActor({ actor, uid });
|
|
12110
|
-
return { actor, source: polyData };
|
|
12111
|
-
}
|
|
12112
12259
|
_addSphere(viewport, point, axis, position, cornerKey = null, adaptiveRadius) {
|
|
12113
12260
|
const uid = cornerKey ? `corner_${cornerKey}` : `${axis}_${position}`;
|
|
12114
12261
|
const sphereState = this.sphereStates.find((s) => s.uid === uid);
|
|
@@ -12137,9 +12284,10 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
12137
12284
|
color = sphereColors.CORONAL || [0.0, 1.0, 0.0];
|
|
12138
12285
|
}
|
|
12139
12286
|
const idx = this.sphereStates.findIndex((s) => s.uid === uid);
|
|
12287
|
+
const pointCopy = [point[0], point[1], point[2]];
|
|
12140
12288
|
if (idx === -1) {
|
|
12141
12289
|
this.sphereStates.push({
|
|
12142
|
-
point:
|
|
12290
|
+
point: pointCopy,
|
|
12143
12291
|
axis,
|
|
12144
12292
|
uid,
|
|
12145
12293
|
sphereSource,
|
|
@@ -12149,185 +12297,248 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
12149
12297
|
});
|
|
12150
12298
|
}
|
|
12151
12299
|
else {
|
|
12152
|
-
this.sphereStates[idx].point =
|
|
12300
|
+
this.sphereStates[idx].point = pointCopy;
|
|
12153
12301
|
this.sphereStates[idx].sphereSource = sphereSource;
|
|
12154
12302
|
}
|
|
12155
|
-
const existingActors = viewport.getActors();
|
|
12156
|
-
const existing = existingActors.find((a) => a.uid === uid);
|
|
12157
|
-
if (existing) {
|
|
12158
|
-
return;
|
|
12159
|
-
}
|
|
12160
12303
|
sphereActor.getProperty().setColor(color);
|
|
12161
12304
|
sphereActor.setVisibility(this.configuration.showHandles);
|
|
12162
12305
|
viewport.addActor({ actor: sphereActor, uid: uid });
|
|
12163
12306
|
}
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12172
|
-
|
|
12307
|
+
_getDirectionVectorForAxis(axis) {
|
|
12308
|
+
if (this.originalClippingPlanes &&
|
|
12309
|
+
this.originalClippingPlanes.length >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
12310
|
+
switch (axis) {
|
|
12311
|
+
case 'x':
|
|
12312
|
+
return this.originalClippingPlanes[volumeCropping.PLANEINDEX.XMIN]
|
|
12313
|
+
.normal;
|
|
12314
|
+
case 'y':
|
|
12315
|
+
return this.originalClippingPlanes[volumeCropping.PLANEINDEX.YMIN]
|
|
12316
|
+
.normal;
|
|
12317
|
+
case 'z':
|
|
12318
|
+
return this.originalClippingPlanes[volumeCropping.PLANEINDEX.ZMIN]
|
|
12319
|
+
.normal;
|
|
12320
|
+
default:
|
|
12321
|
+
return [1, 0, 0];
|
|
12322
|
+
}
|
|
12323
|
+
}
|
|
12324
|
+
if (!this.volumeDirectionVectors) {
|
|
12325
|
+
if (axis === 'x')
|
|
12326
|
+
return [1, 0, 0];
|
|
12327
|
+
if (axis === 'y')
|
|
12328
|
+
return [0, 1, 0];
|
|
12329
|
+
if (axis === 'z')
|
|
12330
|
+
return [0, 0, 1];
|
|
12331
|
+
return [1, 0, 0];
|
|
12332
|
+
}
|
|
12333
|
+
switch (axis) {
|
|
12334
|
+
case 'x':
|
|
12335
|
+
return this.volumeDirectionVectors.xDir;
|
|
12336
|
+
case 'y':
|
|
12337
|
+
return this.volumeDirectionVectors.yDir;
|
|
12338
|
+
case 'z':
|
|
12339
|
+
return this.volumeDirectionVectors.zDir;
|
|
12340
|
+
default:
|
|
12341
|
+
return [1, 0, 0];
|
|
12342
|
+
}
|
|
12343
|
+
}
|
|
12344
|
+
_getVolumeActor(viewport) {
|
|
12345
|
+
const vp = viewport || this._getViewport();
|
|
12346
|
+
return vp?.getDefaultActor()?.actor;
|
|
12347
|
+
}
|
|
12348
|
+
_getVolumeMapper(viewport) {
|
|
12349
|
+
const actor = this._getVolumeActor(viewport);
|
|
12350
|
+
return actor?.getMapper();
|
|
12351
|
+
}
|
|
12352
|
+
_applyClippingPlanesToMapper(mapper) {
|
|
12353
|
+
mapper.removeAllClippingPlanes();
|
|
12354
|
+
for (let i = 0; i < volumeCropping.NUM_CLIPPING_PLANES; ++i) {
|
|
12355
|
+
const plane = Plane/* default.newInstance */.Ay.newInstance({
|
|
12356
|
+
origin: this.originalClippingPlanes[i].origin,
|
|
12357
|
+
normal: this.originalClippingPlanes[i].normal,
|
|
12358
|
+
});
|
|
12359
|
+
mapper.addClippingPlane(plane);
|
|
12360
|
+
}
|
|
12173
12361
|
}
|
|
12174
12362
|
_updateClippingPlanesFromFaceSpheres(viewport) {
|
|
12175
12363
|
const mapper = viewport.getDefaultActor().actor.getMapper();
|
|
12176
|
-
this.originalClippingPlanes[
|
|
12177
|
-
...this.sphereStates[SPHEREINDEX.XMIN].point,
|
|
12364
|
+
this.originalClippingPlanes[volumeCropping.PLANEINDEX.XMIN].origin = [
|
|
12365
|
+
...this.sphereStates[volumeCropping.SPHEREINDEX.XMIN].point,
|
|
12178
12366
|
];
|
|
12179
|
-
this.originalClippingPlanes[
|
|
12180
|
-
...this.sphereStates[SPHEREINDEX.XMAX].point,
|
|
12367
|
+
this.originalClippingPlanes[volumeCropping.PLANEINDEX.XMAX].origin = [
|
|
12368
|
+
...this.sphereStates[volumeCropping.SPHEREINDEX.XMAX].point,
|
|
12181
12369
|
];
|
|
12182
|
-
this.originalClippingPlanes[
|
|
12183
|
-
...this.sphereStates[SPHEREINDEX.YMIN].point,
|
|
12370
|
+
this.originalClippingPlanes[volumeCropping.PLANEINDEX.YMIN].origin = [
|
|
12371
|
+
...this.sphereStates[volumeCropping.SPHEREINDEX.YMIN].point,
|
|
12184
12372
|
];
|
|
12185
|
-
this.originalClippingPlanes[
|
|
12186
|
-
...this.sphereStates[SPHEREINDEX.YMAX].point,
|
|
12373
|
+
this.originalClippingPlanes[volumeCropping.PLANEINDEX.YMAX].origin = [
|
|
12374
|
+
...this.sphereStates[volumeCropping.SPHEREINDEX.YMAX].point,
|
|
12187
12375
|
];
|
|
12188
|
-
this.originalClippingPlanes[
|
|
12189
|
-
...this.sphereStates[SPHEREINDEX.ZMIN].point,
|
|
12376
|
+
this.originalClippingPlanes[volumeCropping.PLANEINDEX.ZMIN].origin = [
|
|
12377
|
+
...this.sphereStates[volumeCropping.SPHEREINDEX.ZMIN].point,
|
|
12190
12378
|
];
|
|
12191
|
-
this.originalClippingPlanes[
|
|
12192
|
-
...this.sphereStates[SPHEREINDEX.ZMAX].point,
|
|
12379
|
+
this.originalClippingPlanes[volumeCropping.PLANEINDEX.ZMAX].origin = [
|
|
12380
|
+
...this.sphereStates[volumeCropping.SPHEREINDEX.ZMAX].point,
|
|
12193
12381
|
];
|
|
12194
|
-
|
|
12195
|
-
for (let i = 0; i < 6; ++i) {
|
|
12196
|
-
const origin = this.originalClippingPlanes[i].origin;
|
|
12197
|
-
const normal = this.originalClippingPlanes[i].normal;
|
|
12198
|
-
const plane = Plane/* default.newInstance */.Ay.newInstance({
|
|
12199
|
-
origin,
|
|
12200
|
-
normal,
|
|
12201
|
-
});
|
|
12202
|
-
mapper.addClippingPlane(plane);
|
|
12203
|
-
}
|
|
12382
|
+
this._applyClippingPlanesToMapper(mapper);
|
|
12204
12383
|
}
|
|
12205
12384
|
_updateCornerSpheresFromFaces() {
|
|
12206
|
-
const
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
const
|
|
12210
|
-
const
|
|
12211
|
-
const
|
|
12385
|
+
const { xDir, yDir, zDir } = this._getDirectionVectors();
|
|
12386
|
+
if (!xDir || !yDir || !zDir)
|
|
12387
|
+
return;
|
|
12388
|
+
const faceXMin = this.sphereStates[volumeCropping.SPHEREINDEX.XMIN].point;
|
|
12389
|
+
const faceXMax = this.sphereStates[volumeCropping.SPHEREINDEX.XMAX].point;
|
|
12390
|
+
const faceYMin = this.sphereStates[volumeCropping.SPHEREINDEX.YMIN].point;
|
|
12391
|
+
const faceYMax = this.sphereStates[volumeCropping.SPHEREINDEX.YMAX].point;
|
|
12392
|
+
const faceZMin = this.sphereStates[volumeCropping.SPHEREINDEX.ZMIN].point;
|
|
12393
|
+
const faceZMax = this.sphereStates[volumeCropping.SPHEREINDEX.ZMAX].point;
|
|
12212
12394
|
const corners = [
|
|
12213
|
-
{
|
|
12214
|
-
|
|
12215
|
-
|
|
12216
|
-
|
|
12217
|
-
{
|
|
12218
|
-
|
|
12219
|
-
|
|
12220
|
-
|
|
12395
|
+
{
|
|
12396
|
+
key: 'XMIN_YMIN_ZMIN',
|
|
12397
|
+
pos: this._calculateCornerFromFaces(faceXMin, faceYMin, faceZMin, xDir, yDir, zDir),
|
|
12398
|
+
},
|
|
12399
|
+
{
|
|
12400
|
+
key: 'XMIN_YMIN_ZMAX',
|
|
12401
|
+
pos: this._calculateCornerFromFaces(faceXMin, faceYMin, faceZMax, xDir, yDir, zDir),
|
|
12402
|
+
},
|
|
12403
|
+
{
|
|
12404
|
+
key: 'XMIN_YMAX_ZMIN',
|
|
12405
|
+
pos: this._calculateCornerFromFaces(faceXMin, faceYMax, faceZMin, xDir, yDir, zDir),
|
|
12406
|
+
},
|
|
12407
|
+
{
|
|
12408
|
+
key: 'XMIN_YMAX_ZMAX',
|
|
12409
|
+
pos: this._calculateCornerFromFaces(faceXMin, faceYMax, faceZMax, xDir, yDir, zDir),
|
|
12410
|
+
},
|
|
12411
|
+
{
|
|
12412
|
+
key: 'XMAX_YMIN_ZMIN',
|
|
12413
|
+
pos: this._calculateCornerFromFaces(faceXMax, faceYMin, faceZMin, xDir, yDir, zDir),
|
|
12414
|
+
},
|
|
12415
|
+
{
|
|
12416
|
+
key: 'XMAX_YMIN_ZMAX',
|
|
12417
|
+
pos: this._calculateCornerFromFaces(faceXMax, faceYMin, faceZMax, xDir, yDir, zDir),
|
|
12418
|
+
},
|
|
12419
|
+
{
|
|
12420
|
+
key: 'XMAX_YMAX_ZMIN',
|
|
12421
|
+
pos: this._calculateCornerFromFaces(faceXMax, faceYMax, faceZMin, xDir, yDir, zDir),
|
|
12422
|
+
},
|
|
12423
|
+
{
|
|
12424
|
+
key: 'XMAX_YMAX_ZMAX',
|
|
12425
|
+
pos: this._calculateCornerFromFaces(faceXMax, faceYMax, faceZMax, xDir, yDir, zDir),
|
|
12426
|
+
},
|
|
12221
12427
|
];
|
|
12222
12428
|
for (const corner of corners) {
|
|
12223
|
-
const
|
|
12224
|
-
if (
|
|
12225
|
-
|
|
12226
|
-
state.point[1] = corner.pos[1];
|
|
12227
|
-
state.point[2] = corner.pos[2];
|
|
12228
|
-
state.sphereSource.setCenter(...state.point);
|
|
12229
|
-
state.sphereSource.modified();
|
|
12429
|
+
const stateIndex = this.sphereStates.findIndex((s) => s.uid === `corner_${corner.key}`);
|
|
12430
|
+
if (stateIndex !== -1) {
|
|
12431
|
+
this._updateSpherePosition(stateIndex, corner.pos);
|
|
12230
12432
|
}
|
|
12231
12433
|
}
|
|
12232
12434
|
}
|
|
12233
12435
|
_updateFaceSpheresFromCorners() {
|
|
12436
|
+
if (!this.volumeDirectionVectors)
|
|
12437
|
+
return;
|
|
12234
12438
|
const corners = [
|
|
12235
|
-
this.sphereStates[SPHEREINDEX.XMIN_YMIN_ZMIN].point,
|
|
12236
|
-
this.sphereStates[SPHEREINDEX.XMIN_YMIN_ZMAX].point,
|
|
12237
|
-
this.sphereStates[SPHEREINDEX.XMIN_YMAX_ZMIN].point,
|
|
12238
|
-
this.sphereStates[SPHEREINDEX.XMIN_YMAX_ZMAX].point,
|
|
12239
|
-
this.sphereStates[SPHEREINDEX.XMAX_YMIN_ZMIN].point,
|
|
12240
|
-
this.sphereStates[SPHEREINDEX.XMAX_YMIN_ZMAX].point,
|
|
12241
|
-
this.sphereStates[SPHEREINDEX.XMAX_YMAX_ZMIN].point,
|
|
12242
|
-
this.sphereStates[SPHEREINDEX.XMAX_YMAX_ZMAX].point,
|
|
12243
|
-
];
|
|
12244
|
-
const xs = corners.map((p) => p[0]);
|
|
12245
|
-
const ys = corners.map((p) => p[1]);
|
|
12246
|
-
const zs = corners.map((p) => p[2]);
|
|
12247
|
-
const xMin = Math.min(...xs), xMax = Math.max(...xs);
|
|
12248
|
-
const yMin = Math.min(...ys), yMax = Math.max(...ys);
|
|
12249
|
-
const zMin = Math.min(...zs), zMax = Math.max(...zs);
|
|
12250
|
-
this.sphereStates[SPHEREINDEX.XMIN].point = [
|
|
12251
|
-
xMin,
|
|
12252
|
-
(yMin + yMax) / 2,
|
|
12253
|
-
(zMin + zMax) / 2,
|
|
12254
|
-
];
|
|
12255
|
-
this.sphereStates[SPHEREINDEX.XMAX].point = [
|
|
12256
|
-
xMax,
|
|
12257
|
-
(yMin + yMax) / 2,
|
|
12258
|
-
(zMin + zMax) / 2,
|
|
12259
|
-
];
|
|
12260
|
-
this.sphereStates[SPHEREINDEX.YMIN].point = [
|
|
12261
|
-
(xMin + xMax) / 2,
|
|
12262
|
-
yMin,
|
|
12263
|
-
(zMin + zMax) / 2,
|
|
12264
|
-
];
|
|
12265
|
-
this.sphereStates[SPHEREINDEX.YMAX].point = [
|
|
12266
|
-
(xMin + xMax) / 2,
|
|
12267
|
-
yMax,
|
|
12268
|
-
(zMin + zMax) / 2,
|
|
12269
|
-
];
|
|
12270
|
-
this.sphereStates[SPHEREINDEX.ZMIN].point = [
|
|
12271
|
-
(xMin + xMax) / 2,
|
|
12272
|
-
(yMin + yMax) / 2,
|
|
12273
|
-
zMin,
|
|
12274
|
-
];
|
|
12275
|
-
this.sphereStates[SPHEREINDEX.ZMAX].point = [
|
|
12276
|
-
(xMin + xMax) / 2,
|
|
12277
|
-
(yMin + yMax) / 2,
|
|
12278
|
-
zMax,
|
|
12439
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMIN_YMIN_ZMIN].point,
|
|
12440
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMIN_YMIN_ZMAX].point,
|
|
12441
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMIN_YMAX_ZMIN].point,
|
|
12442
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMIN_YMAX_ZMAX].point,
|
|
12443
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMAX_YMIN_ZMIN].point,
|
|
12444
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMAX_YMIN_ZMAX].point,
|
|
12445
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMAX_YMAX_ZMIN].point,
|
|
12446
|
+
this.sphereStates[volumeCropping.SPHEREINDEX.XMAX_YMAX_ZMAX].point,
|
|
12279
12447
|
];
|
|
12280
|
-
[
|
|
12281
|
-
|
|
12282
|
-
|
|
12283
|
-
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
12448
|
+
const faceXMin = this._averagePoints([
|
|
12449
|
+
corners[0],
|
|
12450
|
+
corners[1],
|
|
12451
|
+
corners[2],
|
|
12452
|
+
corners[3],
|
|
12453
|
+
]);
|
|
12454
|
+
const faceXMax = this._averagePoints([
|
|
12455
|
+
corners[4],
|
|
12456
|
+
corners[5],
|
|
12457
|
+
corners[6],
|
|
12458
|
+
corners[7],
|
|
12459
|
+
]);
|
|
12460
|
+
const faceYMin = this._averagePoints([
|
|
12461
|
+
corners[0],
|
|
12462
|
+
corners[1],
|
|
12463
|
+
corners[4],
|
|
12464
|
+
corners[5],
|
|
12465
|
+
]);
|
|
12466
|
+
const faceYMax = this._averagePoints([
|
|
12467
|
+
corners[2],
|
|
12468
|
+
corners[3],
|
|
12469
|
+
corners[6],
|
|
12470
|
+
corners[7],
|
|
12471
|
+
]);
|
|
12472
|
+
const faceZMin = this._averagePoints([
|
|
12473
|
+
corners[0],
|
|
12474
|
+
corners[2],
|
|
12475
|
+
corners[4],
|
|
12476
|
+
corners[6],
|
|
12477
|
+
]);
|
|
12478
|
+
const faceZMax = this._averagePoints([
|
|
12479
|
+
corners[1],
|
|
12480
|
+
corners[3],
|
|
12481
|
+
corners[5],
|
|
12482
|
+
corners[7],
|
|
12483
|
+
]);
|
|
12484
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.XMIN, faceXMin);
|
|
12485
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.XMAX, faceXMax);
|
|
12486
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.YMIN, faceYMin);
|
|
12487
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.YMAX, faceYMax);
|
|
12488
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.ZMIN, faceZMin);
|
|
12489
|
+
this._updateSpherePosition(volumeCropping.SPHEREINDEX.ZMAX, faceZMax);
|
|
12292
12490
|
}
|
|
12293
12491
|
_updateCornerSpheres() {
|
|
12294
|
-
const
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
const
|
|
12298
|
-
const
|
|
12299
|
-
const
|
|
12492
|
+
const { xDir, yDir, zDir } = this._getDirectionVectors();
|
|
12493
|
+
if (!xDir || !yDir || !zDir)
|
|
12494
|
+
return;
|
|
12495
|
+
const faceXMin = this.sphereStates[volumeCropping.SPHEREINDEX.XMIN].point;
|
|
12496
|
+
const faceXMax = this.sphereStates[volumeCropping.SPHEREINDEX.XMAX].point;
|
|
12497
|
+
const faceYMin = this.sphereStates[volumeCropping.SPHEREINDEX.YMIN].point;
|
|
12498
|
+
const faceYMax = this.sphereStates[volumeCropping.SPHEREINDEX.YMAX].point;
|
|
12499
|
+
const faceZMin = this.sphereStates[volumeCropping.SPHEREINDEX.ZMIN].point;
|
|
12500
|
+
const faceZMax = this.sphereStates[volumeCropping.SPHEREINDEX.ZMAX].point;
|
|
12300
12501
|
const corners = [
|
|
12301
|
-
{
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
|
|
12305
|
-
{
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12502
|
+
{
|
|
12503
|
+
key: 'XMIN_YMIN_ZMIN',
|
|
12504
|
+
pos: this._calculateCornerFromProjection(faceXMin, faceYMin, faceZMin, xDir, yDir, zDir),
|
|
12505
|
+
},
|
|
12506
|
+
{
|
|
12507
|
+
key: 'XMIN_YMIN_ZMAX',
|
|
12508
|
+
pos: this._calculateCornerFromProjection(faceXMin, faceYMin, faceZMax, xDir, yDir, zDir),
|
|
12509
|
+
},
|
|
12510
|
+
{
|
|
12511
|
+
key: 'XMIN_YMAX_ZMIN',
|
|
12512
|
+
pos: this._calculateCornerFromProjection(faceXMin, faceYMax, faceZMin, xDir, yDir, zDir),
|
|
12513
|
+
},
|
|
12514
|
+
{
|
|
12515
|
+
key: 'XMIN_YMAX_ZMAX',
|
|
12516
|
+
pos: this._calculateCornerFromProjection(faceXMin, faceYMax, faceZMax, xDir, yDir, zDir),
|
|
12517
|
+
},
|
|
12518
|
+
{
|
|
12519
|
+
key: 'XMAX_YMIN_ZMIN',
|
|
12520
|
+
pos: this._calculateCornerFromProjection(faceXMax, faceYMin, faceZMin, xDir, yDir, zDir),
|
|
12521
|
+
},
|
|
12522
|
+
{
|
|
12523
|
+
key: 'XMAX_YMIN_ZMAX',
|
|
12524
|
+
pos: this._calculateCornerFromProjection(faceXMax, faceYMin, faceZMax, xDir, yDir, zDir),
|
|
12525
|
+
},
|
|
12526
|
+
{
|
|
12527
|
+
key: 'XMAX_YMAX_ZMIN',
|
|
12528
|
+
pos: this._calculateCornerFromProjection(faceXMax, faceYMax, faceZMin, xDir, yDir, zDir),
|
|
12529
|
+
},
|
|
12530
|
+
{
|
|
12531
|
+
key: 'XMAX_YMAX_ZMAX',
|
|
12532
|
+
pos: this._calculateCornerFromProjection(faceXMax, faceYMax, faceZMax, xDir, yDir, zDir),
|
|
12533
|
+
},
|
|
12309
12534
|
];
|
|
12310
12535
|
for (const corner of corners) {
|
|
12311
|
-
const
|
|
12312
|
-
if (
|
|
12313
|
-
|
|
12314
|
-
state.point[1] = corner.pos[1];
|
|
12315
|
-
state.point[2] = corner.pos[2];
|
|
12316
|
-
state.sphereSource.setCenter(...state.point);
|
|
12317
|
-
state.sphereSource.modified();
|
|
12536
|
+
const stateIndex = this.sphereStates.findIndex((s) => s.uid === `corner_${corner.key}`);
|
|
12537
|
+
if (stateIndex !== -1) {
|
|
12538
|
+
this._updateSpherePosition(stateIndex, corner.pos);
|
|
12318
12539
|
}
|
|
12319
12540
|
}
|
|
12320
|
-
|
|
12321
|
-
const state1 = this.sphereStates.find((s) => s.uid === `corner_${key1}`);
|
|
12322
|
-
const state2 = this.sphereStates.find((s) => s.uid === `corner_${key2}`);
|
|
12323
|
-
if (state1 && state2) {
|
|
12324
|
-
const points = source.getPoints();
|
|
12325
|
-
points.setPoint(0, state1.point[0], state1.point[1], state1.point[2]);
|
|
12326
|
-
points.setPoint(1, state2.point[0], state2.point[1], state2.point[2]);
|
|
12327
|
-
points.modified();
|
|
12328
|
-
source.modified();
|
|
12329
|
-
}
|
|
12330
|
-
});
|
|
12541
|
+
this._updateEdgeLines();
|
|
12331
12542
|
}
|
|
12332
12543
|
_unsubscribeToViewportNewVolumeSet(viewportsInfo) {
|
|
12333
12544
|
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
@@ -12343,14 +12554,111 @@ class VolumeCroppingTool extends base/* BaseTool */.oS {
|
|
|
12343
12554
|
element.addEventListener(esm.Enums.Events.VOLUME_VIEWPORT_NEW_VOLUME, this._onNewVolume);
|
|
12344
12555
|
});
|
|
12345
12556
|
}
|
|
12557
|
+
_getDirectionVectors() {
|
|
12558
|
+
const hasPlanes = this.originalClippingPlanes?.length >= volumeCropping.NUM_CLIPPING_PLANES;
|
|
12559
|
+
return {
|
|
12560
|
+
xDir: hasPlanes
|
|
12561
|
+
? this.originalClippingPlanes[volumeCropping.PLANEINDEX.XMIN].normal
|
|
12562
|
+
: this.volumeDirectionVectors?.xDir || [1, 0, 0],
|
|
12563
|
+
yDir: hasPlanes
|
|
12564
|
+
? this.originalClippingPlanes[volumeCropping.PLANEINDEX.YMIN].normal
|
|
12565
|
+
: this.volumeDirectionVectors?.yDir || [0, 1, 0],
|
|
12566
|
+
zDir: hasPlanes
|
|
12567
|
+
? this.originalClippingPlanes[volumeCropping.PLANEINDEX.ZMIN].normal
|
|
12568
|
+
: this.volumeDirectionVectors?.zDir || [0, 0, 1],
|
|
12569
|
+
};
|
|
12570
|
+
}
|
|
12571
|
+
_updateSpherePosition(sphereIndex, newPoint) {
|
|
12572
|
+
const state = this.sphereStates[sphereIndex];
|
|
12573
|
+
if (state) {
|
|
12574
|
+
state.point = newPoint;
|
|
12575
|
+
state.sphereSource.setCenter(...newPoint);
|
|
12576
|
+
state.sphereSource.modified();
|
|
12577
|
+
}
|
|
12578
|
+
}
|
|
12579
|
+
_updateFaceSpheresFromClippingPlanes() {
|
|
12580
|
+
const faceMappings = [
|
|
12581
|
+
{ sphereIdx: volumeCropping.SPHEREINDEX.XMIN, planeIdx: volumeCropping.PLANEINDEX.XMIN },
|
|
12582
|
+
{ sphereIdx: volumeCropping.SPHEREINDEX.XMAX, planeIdx: volumeCropping.PLANEINDEX.XMAX },
|
|
12583
|
+
{ sphereIdx: volumeCropping.SPHEREINDEX.YMIN, planeIdx: volumeCropping.PLANEINDEX.YMIN },
|
|
12584
|
+
{ sphereIdx: volumeCropping.SPHEREINDEX.YMAX, planeIdx: volumeCropping.PLANEINDEX.YMAX },
|
|
12585
|
+
{ sphereIdx: volumeCropping.SPHEREINDEX.ZMIN, planeIdx: volumeCropping.PLANEINDEX.ZMIN },
|
|
12586
|
+
{ sphereIdx: volumeCropping.SPHEREINDEX.ZMAX, planeIdx: volumeCropping.PLANEINDEX.ZMAX },
|
|
12587
|
+
];
|
|
12588
|
+
faceMappings.forEach(({ sphereIdx, planeIdx }) => {
|
|
12589
|
+
const newPoint = [
|
|
12590
|
+
...this.originalClippingPlanes[planeIdx].origin,
|
|
12591
|
+
];
|
|
12592
|
+
this._updateSpherePosition(sphereIdx, newPoint);
|
|
12593
|
+
});
|
|
12594
|
+
}
|
|
12595
|
+
_averagePoints(points) {
|
|
12596
|
+
const sum = points.reduce((acc, p) => [acc[0] + p[0], acc[1] + p[1], acc[2] + p[2]], [0, 0, 0]);
|
|
12597
|
+
return [
|
|
12598
|
+
sum[0] / points.length,
|
|
12599
|
+
sum[1] / points.length,
|
|
12600
|
+
sum[2] / points.length,
|
|
12601
|
+
];
|
|
12602
|
+
}
|
|
12603
|
+
_notifyClippingPlanesChanged(viewport) {
|
|
12604
|
+
const eventData = {
|
|
12605
|
+
originalClippingPlanes: this.originalClippingPlanes,
|
|
12606
|
+
seriesInstanceUID: this.seriesInstanceUID,
|
|
12607
|
+
};
|
|
12608
|
+
if (viewport) {
|
|
12609
|
+
eventData.viewportId = viewport.id;
|
|
12610
|
+
eventData.renderingEngineId = viewport.renderingEngineId;
|
|
12611
|
+
}
|
|
12612
|
+
(0,esm.triggerEvent)(esm.eventTarget, enums.Events.VOLUMECROPPING_TOOL_CHANGED, eventData);
|
|
12613
|
+
}
|
|
12614
|
+
_calculateCornerFromFaces(faceX, faceY, faceZ, xDir, yDir, zDir) {
|
|
12615
|
+
const deltaXY = [
|
|
12616
|
+
faceY[0] - faceX[0],
|
|
12617
|
+
faceY[1] - faceX[1],
|
|
12618
|
+
faceY[2] - faceX[2],
|
|
12619
|
+
];
|
|
12620
|
+
const distY = deltaXY[0] * yDir[0] + deltaXY[1] * yDir[1] + deltaXY[2] * yDir[2];
|
|
12621
|
+
const deltaXZ = [
|
|
12622
|
+
faceZ[0] - faceX[0],
|
|
12623
|
+
faceZ[1] - faceX[1],
|
|
12624
|
+
faceZ[2] - faceX[2],
|
|
12625
|
+
];
|
|
12626
|
+
const distZ = deltaXZ[0] * zDir[0] + deltaXZ[1] * zDir[1] + deltaXZ[2] * zDir[2];
|
|
12627
|
+
return [
|
|
12628
|
+
faceX[0] + distY * yDir[0] + distZ * zDir[0],
|
|
12629
|
+
faceX[1] + distY * yDir[1] + distZ * zDir[1],
|
|
12630
|
+
faceX[2] + distY * yDir[2] + distZ * zDir[2],
|
|
12631
|
+
];
|
|
12632
|
+
}
|
|
12633
|
+
_calculateCornerFromProjection(faceX, faceY, faceZ, xDir, yDir, zDir) {
|
|
12634
|
+
const dX = faceX[0] * xDir[0] + faceX[1] * xDir[1] + faceX[2] * xDir[2];
|
|
12635
|
+
const dY = faceY[0] * yDir[0] + faceY[1] * yDir[1] + faceY[2] * yDir[2];
|
|
12636
|
+
const dZ = faceZ[0] * zDir[0] + faceZ[1] * zDir[1] + faceZ[2] * zDir[2];
|
|
12637
|
+
return [
|
|
12638
|
+
dX * xDir[0] + dY * yDir[0] + dZ * zDir[0],
|
|
12639
|
+
dX * xDir[1] + dY * yDir[1] + dZ * zDir[1],
|
|
12640
|
+
dX * xDir[2] + dY * yDir[2] + dZ * zDir[2],
|
|
12641
|
+
];
|
|
12642
|
+
}
|
|
12643
|
+
_updateEdgeLines() {
|
|
12644
|
+
Object.values(this.edgeLines).forEach(({ source, key1, key2 }) => {
|
|
12645
|
+
const state1 = this.sphereStates.find((s) => s.uid === `corner_${key1}`);
|
|
12646
|
+
const state2 = this.sphereStates.find((s) => s.uid === `corner_${key2}`);
|
|
12647
|
+
if (state1 && state2) {
|
|
12648
|
+
const points = source.getPoints();
|
|
12649
|
+
points.setPoint(0, state1.point[0], state1.point[1], state1.point[2]);
|
|
12650
|
+
points.setPoint(1, state2.point[0], state2.point[1], state2.point[2]);
|
|
12651
|
+
points.modified();
|
|
12652
|
+
source.modified();
|
|
12653
|
+
}
|
|
12654
|
+
});
|
|
12655
|
+
}
|
|
12346
12656
|
}
|
|
12347
12657
|
VolumeCroppingTool.toolName = 'VolumeCropping';
|
|
12348
12658
|
/* harmony default export */ const tools_VolumeCroppingTool = ((/* unused pure expression or super */ null && (VolumeCroppingTool)));
|
|
12349
12659
|
|
|
12350
12660
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/cursors/elementCursor.js
|
|
12351
12661
|
var elementCursor = __webpack_require__(7001);
|
|
12352
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/math/vec2/liangBarksyClip.js
|
|
12353
|
-
var liangBarksyClip = __webpack_require__(35381);
|
|
12354
12662
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/annotationLocking.js
|
|
12355
12663
|
var annotationLocking = __webpack_require__(2076);
|
|
12356
12664
|
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/VolumeCroppingControlTool.js
|
|
@@ -12369,13 +12677,6 @@ var annotationLocking = __webpack_require__(2076);
|
|
|
12369
12677
|
|
|
12370
12678
|
|
|
12371
12679
|
|
|
12372
|
-
const { RENDERING_DEFAULTS } = esm.CONSTANTS;
|
|
12373
|
-
function defaultReferenceLineColor() {
|
|
12374
|
-
return 'rgb(0, 200, 0)';
|
|
12375
|
-
}
|
|
12376
|
-
function defaultReferenceLineControllable() {
|
|
12377
|
-
return true;
|
|
12378
|
-
}
|
|
12379
12680
|
const OPERATION = {
|
|
12380
12681
|
DRAG: 1,
|
|
12381
12682
|
ROTATE: 2,
|
|
@@ -12408,12 +12709,7 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12408
12709
|
},
|
|
12409
12710
|
}) {
|
|
12410
12711
|
super(toolProps, defaultToolProps);
|
|
12411
|
-
this.
|
|
12412
|
-
this.sphereStates = [];
|
|
12413
|
-
this.draggingSphereIndex = null;
|
|
12414
|
-
this.toolCenter = [0, 0, 0];
|
|
12415
|
-
this.toolCenterMin = [0, 0, 0];
|
|
12416
|
-
this.toolCenterMax = [0, 0, 0];
|
|
12712
|
+
this.clippingPlanes = [];
|
|
12417
12713
|
this.initializeViewport = ({ renderingEngineId, viewportId, }) => {
|
|
12418
12714
|
if (!renderingEngineId || !viewportId) {
|
|
12419
12715
|
console.warn('VolumeCroppingControlTool: Missing renderingEngineId or viewportId');
|
|
@@ -12424,15 +12720,21 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12424
12720
|
return;
|
|
12425
12721
|
}
|
|
12426
12722
|
const { viewport } = enabledElement;
|
|
12427
|
-
|
|
12723
|
+
const volumeActors = viewport.getActors();
|
|
12724
|
+
if (volumeActors && volumeActors.length > 0) {
|
|
12725
|
+
const imageData = volumeActors[0].actor.getMapper().getInputData();
|
|
12726
|
+
if (imageData) {
|
|
12727
|
+
this.seriesInstanceUID = imageData.seriesInstanceUID || 'unknown';
|
|
12728
|
+
}
|
|
12729
|
+
}
|
|
12428
12730
|
const { element } = viewport;
|
|
12429
|
-
const { position, focalPoint
|
|
12731
|
+
const { position, focalPoint } = viewport.getCamera();
|
|
12430
12732
|
let annotations = this._getAnnotations(enabledElement);
|
|
12431
12733
|
annotations = this.filterInteractableAnnotationsForElement(element, annotations);
|
|
12432
12734
|
if (annotations?.length) {
|
|
12433
12735
|
(0,annotationState.removeAnnotation)(annotations[0].annotationUID);
|
|
12434
12736
|
}
|
|
12435
|
-
const orientation =
|
|
12737
|
+
const orientation = (0,volumeCropping.getOrientationFromNormal)(viewport.getCamera().viewPlaneNormal);
|
|
12436
12738
|
const annotation = {
|
|
12437
12739
|
highlighted: false,
|
|
12438
12740
|
metadata: {
|
|
@@ -12442,11 +12744,11 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12442
12744
|
},
|
|
12443
12745
|
data: {
|
|
12444
12746
|
handles: {
|
|
12445
|
-
|
|
12446
|
-
|
|
12447
|
-
|
|
12747
|
+
activeOperation: null,
|
|
12748
|
+
clippingPlanes: this.clippingPlanes.length > 0
|
|
12749
|
+
? (0,volumeCropping.copyClippingPlanes)(this.clippingPlanes)
|
|
12750
|
+
: [],
|
|
12448
12751
|
},
|
|
12449
|
-
activeOperation: null,
|
|
12450
12752
|
activeViewportIds: [],
|
|
12451
12753
|
viewportId,
|
|
12452
12754
|
referenceLines: [],
|
|
@@ -12454,10 +12756,6 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12454
12756
|
},
|
|
12455
12757
|
};
|
|
12456
12758
|
(0,annotationState.addAnnotation)(annotation, element);
|
|
12457
|
-
return {
|
|
12458
|
-
normal: viewPlaneNormal,
|
|
12459
|
-
point: viewport.canvasToWorld([100, 100]),
|
|
12460
|
-
};
|
|
12461
12759
|
};
|
|
12462
12760
|
this._getViewportsInfo = () => {
|
|
12463
12761
|
const viewports = (0,ToolGroupManager.getToolGroup)(this.toolGroupId).viewportsInfo;
|
|
@@ -12490,139 +12788,22 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12490
12788
|
}
|
|
12491
12789
|
viewport.render();
|
|
12492
12790
|
}
|
|
12493
|
-
this.
|
|
12791
|
+
this._initializeViewports(viewportsInfo);
|
|
12494
12792
|
};
|
|
12495
|
-
this.
|
|
12496
|
-
|
|
12497
|
-
|
|
12498
|
-
this._computeToolCenter = (viewportsInfo) => {
|
|
12499
|
-
if (!viewportsInfo || !viewportsInfo[0]) {
|
|
12500
|
-
console.warn(' _computeToolCenter : No valid viewportsInfo for computeToolCenter.');
|
|
12793
|
+
this._initializeViewports = (viewportsInfo) => {
|
|
12794
|
+
if (!viewportsInfo?.length || !viewportsInfo[0]) {
|
|
12795
|
+
console.warn('VolumeCroppingControlTool: No valid viewportsInfo for initialization.');
|
|
12501
12796
|
return;
|
|
12502
12797
|
}
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
.map((vp) => {
|
|
12506
|
-
if (vp.renderingEngineId) {
|
|
12507
|
-
const renderingEngine = (0,esm.getRenderingEngine)(vp.renderingEngineId);
|
|
12508
|
-
const viewport = renderingEngine.getViewport(vp.viewportId);
|
|
12509
|
-
if (viewport && viewport.getCamera) {
|
|
12510
|
-
const orientation = this._getOrientationFromNormal(viewport.getCamera().viewPlaneNormal);
|
|
12511
|
-
if (orientation) {
|
|
12512
|
-
return orientation;
|
|
12513
|
-
}
|
|
12514
|
-
}
|
|
12515
|
-
}
|
|
12516
|
-
return null;
|
|
12517
|
-
})
|
|
12518
|
-
.filter(Boolean);
|
|
12519
|
-
const missingOrientation = orientationIds.find((id) => !presentOrientations.includes(id));
|
|
12520
|
-
const presentNormals = [];
|
|
12521
|
-
const presentCenters = [];
|
|
12522
|
-
const presentViewportInfos = viewportsInfo.filter((vp) => {
|
|
12523
|
-
let orientation = null;
|
|
12524
|
-
if (vp.renderingEngineId) {
|
|
12525
|
-
const renderingEngine = (0,esm.getRenderingEngine)(vp.renderingEngineId);
|
|
12526
|
-
const viewport = renderingEngine.getViewport(vp.viewportId);
|
|
12527
|
-
if (viewport && viewport.getCamera) {
|
|
12528
|
-
orientation = this._getOrientationFromNormal(viewport.getCamera().viewPlaneNormal);
|
|
12529
|
-
}
|
|
12530
|
-
}
|
|
12531
|
-
return orientation && orientationIds.includes(orientation);
|
|
12532
|
-
});
|
|
12533
|
-
presentViewportInfos.forEach((vpInfo) => {
|
|
12534
|
-
const { normal, point } = this.initializeViewport(vpInfo);
|
|
12535
|
-
presentNormals.push(normal);
|
|
12536
|
-
presentCenters.push(point);
|
|
12798
|
+
viewportsInfo.forEach((vpInfo) => {
|
|
12799
|
+
this.initializeViewport(vpInfo);
|
|
12537
12800
|
});
|
|
12538
|
-
|
|
12539
|
-
const virtualNormal = [0, 0, 0];
|
|
12540
|
-
gl_matrix_esm/* vec3.cross */.eR.cross(virtualNormal, presentNormals[0], presentNormals[1]);
|
|
12541
|
-
gl_matrix_esm/* vec3.normalize */.eR.normalize(virtualNormal, virtualNormal);
|
|
12542
|
-
const virtualCenter = [
|
|
12543
|
-
(presentCenters[0][0] + presentCenters[1][0]) / 2,
|
|
12544
|
-
(presentCenters[0][1] + presentCenters[1][1]) / 2,
|
|
12545
|
-
(presentCenters[0][2] + presentCenters[1][2]) / 2,
|
|
12546
|
-
];
|
|
12547
|
-
const orientation = null;
|
|
12548
|
-
const virtualAnnotation = {
|
|
12549
|
-
highlighted: false,
|
|
12550
|
-
metadata: {
|
|
12551
|
-
cameraPosition: [...virtualCenter],
|
|
12552
|
-
cameraFocalPoint: [...virtualCenter],
|
|
12553
|
-
toolName: this.getToolName(),
|
|
12554
|
-
},
|
|
12555
|
-
data: {
|
|
12556
|
-
handles: {
|
|
12557
|
-
activeOperation: null,
|
|
12558
|
-
toolCenter: this.toolCenter,
|
|
12559
|
-
toolCenterMin: this.toolCenterMin,
|
|
12560
|
-
toolCenterMax: this.toolCenterMax,
|
|
12561
|
-
},
|
|
12562
|
-
activeViewportIds: [],
|
|
12563
|
-
viewportId: missingOrientation,
|
|
12564
|
-
referenceLines: [],
|
|
12565
|
-
orientation,
|
|
12566
|
-
},
|
|
12567
|
-
isVirtual: true,
|
|
12568
|
-
virtualNormal,
|
|
12569
|
-
};
|
|
12570
|
-
this._virtualAnnotations = [virtualAnnotation];
|
|
12571
|
-
}
|
|
12572
|
-
else if (presentViewportInfos.length === 1) {
|
|
12573
|
-
let presentOrientation = null;
|
|
12574
|
-
const vpInfo = presentViewportInfos[0];
|
|
12575
|
-
if (vpInfo.renderingEngineId) {
|
|
12576
|
-
const renderingEngine = (0,esm.getRenderingEngine)(vpInfo.renderingEngineId);
|
|
12577
|
-
const viewport = renderingEngine.getViewport(vpInfo.viewportId);
|
|
12578
|
-
if (viewport && viewport.getCamera) {
|
|
12579
|
-
presentOrientation = this._getOrientationFromNormal(viewport.getCamera().viewPlaneNormal);
|
|
12580
|
-
}
|
|
12581
|
-
}
|
|
12582
|
-
const presentCenter = presentCenters[0];
|
|
12583
|
-
const canonicalNormals = {
|
|
12584
|
-
AXIAL: [0, 0, 1],
|
|
12585
|
-
CORONAL: [0, 1, 0],
|
|
12586
|
-
SAGITTAL: [1, 0, 0],
|
|
12587
|
-
};
|
|
12588
|
-
const missingIds = orientationIds.filter((id) => id !== presentOrientation);
|
|
12589
|
-
const virtualAnnotations = missingIds.map((orientation) => {
|
|
12590
|
-
const normal = canonicalNormals[orientation];
|
|
12591
|
-
const virtualAnnotation = {
|
|
12592
|
-
highlighted: false,
|
|
12593
|
-
metadata: {
|
|
12594
|
-
cameraPosition: [...presentCenter],
|
|
12595
|
-
cameraFocalPoint: [...presentCenter],
|
|
12596
|
-
toolName: this.getToolName(),
|
|
12597
|
-
},
|
|
12598
|
-
data: {
|
|
12599
|
-
handles: {
|
|
12600
|
-
activeOperation: null,
|
|
12601
|
-
toolCenter: this.toolCenter,
|
|
12602
|
-
toolCenterMin: this.toolCenterMin,
|
|
12603
|
-
toolCenterMax: this.toolCenterMax,
|
|
12604
|
-
},
|
|
12605
|
-
activeViewportIds: [],
|
|
12606
|
-
viewportId: orientation,
|
|
12607
|
-
referenceLines: [],
|
|
12608
|
-
orientation,
|
|
12609
|
-
},
|
|
12610
|
-
isVirtual: true,
|
|
12611
|
-
virtualNormal: normal,
|
|
12612
|
-
};
|
|
12613
|
-
return virtualAnnotation;
|
|
12614
|
-
});
|
|
12615
|
-
this._virtualAnnotations = virtualAnnotations;
|
|
12616
|
-
}
|
|
12617
|
-
if (viewportsInfo && viewportsInfo.length) {
|
|
12618
|
-
(0,triggerAnnotationRenderForViewportIds/* default */.A)(viewportsInfo.map(({ viewportId }) => viewportId));
|
|
12619
|
-
}
|
|
12801
|
+
(0,triggerAnnotationRenderForViewportIds/* default */.A)(viewportsInfo.map(({ viewportId }) => viewportId));
|
|
12620
12802
|
};
|
|
12621
12803
|
this.cancel = () => {
|
|
12622
|
-
console.log('Not implemented yet');
|
|
12623
12804
|
};
|
|
12624
12805
|
this.isPointNearTool = (element, annotation, canvasCoords, proximity) => {
|
|
12625
|
-
if (this._pointNearTool(element, annotation, canvasCoords,
|
|
12806
|
+
if (this._pointNearTool(element, annotation, canvasCoords, volumeCropping.POINT_PROXIMITY_THRESHOLD_PIXELS)) {
|
|
12626
12807
|
return true;
|
|
12627
12808
|
}
|
|
12628
12809
|
return false;
|
|
@@ -12654,13 +12835,8 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12654
12835
|
if (!data.handles) {
|
|
12655
12836
|
continue;
|
|
12656
12837
|
}
|
|
12657
|
-
const previousActiveOperation = data.handles.activeOperation;
|
|
12658
|
-
const previousActiveViewportIds = data.activeViewportIds && data.activeViewportIds.length > 0
|
|
12659
|
-
? [...data.activeViewportIds]
|
|
12660
|
-
: [];
|
|
12661
12838
|
data.activeViewportIds = [];
|
|
12662
|
-
|
|
12663
|
-
near = this._pointNearTool(element, annotation, canvasCoords, 6);
|
|
12839
|
+
const near = this._pointNearTool(element, annotation, canvasCoords, volumeCropping.POINT_PROXIMITY_THRESHOLD_PIXELS);
|
|
12664
12840
|
const nearToolAndNotMarkedActive = near && !highlighted;
|
|
12665
12841
|
const notNearToolAndMarkedActive = !near && highlighted;
|
|
12666
12842
|
if (nearToolAndNotMarkedActive || notNearToolAndMarkedActive) {
|
|
@@ -12677,12 +12853,9 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12677
12853
|
const enabledElement = (0,esm.getEnabledElement)(element);
|
|
12678
12854
|
let orientation = null;
|
|
12679
12855
|
if (enabledElement.viewport && enabledElement.viewport.getCamera) {
|
|
12680
|
-
orientation =
|
|
12856
|
+
orientation = (0,volumeCropping.getOrientationFromNormal)(enabledElement.viewport.getCamera().viewPlaneNormal);
|
|
12681
12857
|
}
|
|
12682
12858
|
const filtered = annotations.filter((annotation) => {
|
|
12683
|
-
if (annotation.isVirtual) {
|
|
12684
|
-
return true;
|
|
12685
|
-
}
|
|
12686
12859
|
if (annotation.data.orientation &&
|
|
12687
12860
|
orientation &&
|
|
12688
12861
|
annotation.data.orientation === orientation) {
|
|
@@ -12699,7 +12872,7 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12699
12872
|
const s2_x = q2[0] - q1[0];
|
|
12700
12873
|
const s2_y = q2[1] - q1[1];
|
|
12701
12874
|
const denom = -s2_x * s1_y + s1_x * s2_y;
|
|
12702
|
-
if (Math.abs(denom) <
|
|
12875
|
+
if (Math.abs(denom) < volumeCropping.LINE_INTERSECTION_TOLERANCE) {
|
|
12703
12876
|
return null;
|
|
12704
12877
|
}
|
|
12705
12878
|
const s = (-s1_y * (p1[0] - q1[0]) + s1_x * (p1[1] - q1[1])) / denom;
|
|
@@ -12716,10 +12889,7 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12716
12889
|
let renderStatus = false;
|
|
12717
12890
|
const { viewport, renderingEngine } = enabledElement;
|
|
12718
12891
|
const { element } = viewport;
|
|
12719
|
-
|
|
12720
|
-
if (this._virtualAnnotations && this._virtualAnnotations.length) {
|
|
12721
|
-
annotations = annotations.concat(this._virtualAnnotations);
|
|
12722
|
-
}
|
|
12892
|
+
const annotations = this._getAnnotations(enabledElement);
|
|
12723
12893
|
const camera = viewport.getCamera();
|
|
12724
12894
|
const filteredToolAnnotations = this.filterInteractableAnnotationsForElement(element, annotations);
|
|
12725
12895
|
const viewportAnnotation = filteredToolAnnotations[0];
|
|
@@ -12730,135 +12900,65 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12730
12900
|
const { clientWidth, clientHeight } = viewport.canvas;
|
|
12731
12901
|
const canvasDiagonalLength = Math.sqrt(clientWidth * clientWidth + clientHeight * clientHeight);
|
|
12732
12902
|
const data = viewportAnnotation.data;
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12739
|
-
const data = annotation.data;
|
|
12740
|
-
const isVirtual = 'isVirtual' in annotation &&
|
|
12741
|
-
annotation.isVirtual === true;
|
|
12742
|
-
data.handles.toolCenter = this.toolCenter;
|
|
12743
|
-
let otherViewport, otherCamera, clientWidth, clientHeight, otherCanvasDiagonalLength, otherCanvasCenter, otherViewportCenterWorld;
|
|
12744
|
-
if (isVirtual) {
|
|
12745
|
-
const realViewports = viewportsInfo.filter((vp) => vp.viewportId !== data.viewportId);
|
|
12746
|
-
if (realViewports.length === 2) {
|
|
12747
|
-
const vp1 = renderingEngine.getViewport(realViewports[0].viewportId);
|
|
12748
|
-
const vp2 = renderingEngine.getViewport(realViewports[1].viewportId);
|
|
12749
|
-
const normal1 = vp1.getCamera().viewPlaneNormal;
|
|
12750
|
-
const normal2 = vp2.getCamera().viewPlaneNormal;
|
|
12751
|
-
const virtualNormal = gl_matrix_esm/* vec3.create */.eR.create();
|
|
12752
|
-
gl_matrix_esm/* vec3.cross */.eR.cross(virtualNormal, normal1, normal2);
|
|
12753
|
-
gl_matrix_esm/* vec3.normalize */.eR.normalize(virtualNormal, virtualNormal);
|
|
12754
|
-
otherCamera = {
|
|
12755
|
-
viewPlaneNormal: virtualNormal,
|
|
12756
|
-
position: data.handles.toolCenter,
|
|
12757
|
-
focalPoint: data.handles.toolCenter,
|
|
12758
|
-
viewUp: [0, 1, 0],
|
|
12759
|
-
};
|
|
12760
|
-
clientWidth = viewport.canvas.clientWidth;
|
|
12761
|
-
clientHeight = viewport.canvas.clientHeight;
|
|
12762
|
-
otherCanvasDiagonalLength = Math.sqrt(clientWidth * clientWidth + clientHeight * clientHeight);
|
|
12763
|
-
otherCanvasCenter = [clientWidth * 0.5, clientHeight * 0.5];
|
|
12764
|
-
otherViewportCenterWorld = data.handles.toolCenter;
|
|
12765
|
-
otherViewport = {
|
|
12766
|
-
id: data.viewportId,
|
|
12767
|
-
canvas: viewport.canvas,
|
|
12768
|
-
canvasToWorld: () => data.handles.toolCenter,
|
|
12769
|
-
};
|
|
12770
|
-
}
|
|
12771
|
-
else {
|
|
12772
|
-
const virtualNormal = annotation
|
|
12773
|
-
.virtualNormal ?? [0, 0, 1];
|
|
12774
|
-
otherCamera = {
|
|
12775
|
-
viewPlaneNormal: virtualNormal,
|
|
12776
|
-
position: data.handles.toolCenter,
|
|
12777
|
-
focalPoint: data.handles.toolCenter,
|
|
12778
|
-
viewUp: [0, 1, 0],
|
|
12779
|
-
};
|
|
12780
|
-
clientWidth = viewport.canvas.clientWidth;
|
|
12781
|
-
clientHeight = viewport.canvas.clientHeight;
|
|
12782
|
-
otherCanvasDiagonalLength = Math.sqrt(clientWidth * clientWidth + clientHeight * clientHeight);
|
|
12783
|
-
otherCanvasCenter = [clientWidth * 0.5, clientHeight * 0.5];
|
|
12784
|
-
otherViewportCenterWorld = data.handles.toolCenter;
|
|
12785
|
-
otherViewport = {
|
|
12786
|
-
id: data.viewportId,
|
|
12787
|
-
canvas: viewport.canvas,
|
|
12788
|
-
canvasToWorld: () => data.handles.toolCenter,
|
|
12789
|
-
};
|
|
12790
|
-
}
|
|
12903
|
+
let clippingPlanes = viewportAnnotation.data.handles.clippingPlanes;
|
|
12904
|
+
if (!clippingPlanes || clippingPlanes.length < volumeCropping.NUM_CLIPPING_PLANES) {
|
|
12905
|
+
if (this.clippingPlanes &&
|
|
12906
|
+
this.clippingPlanes.length >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
12907
|
+
clippingPlanes = this.clippingPlanes;
|
|
12908
|
+
data.handles.clippingPlanes = (0,volumeCropping.copyClippingPlanes)(this.clippingPlanes);
|
|
12791
12909
|
}
|
|
12792
12910
|
else {
|
|
12793
|
-
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12911
|
+
return false;
|
|
12912
|
+
}
|
|
12913
|
+
}
|
|
12914
|
+
const { viewPlaneNormal, focalPoint } = camera;
|
|
12915
|
+
const referenceLines = [];
|
|
12916
|
+
const planeTypes = [
|
|
12917
|
+
'min',
|
|
12918
|
+
'max',
|
|
12919
|
+
'min',
|
|
12920
|
+
'max',
|
|
12921
|
+
'min',
|
|
12922
|
+
'max',
|
|
12923
|
+
];
|
|
12924
|
+
for (let planeIndex = 0; planeIndex < volumeCropping.NUM_CLIPPING_PLANES; planeIndex++) {
|
|
12925
|
+
const clippingPlane = clippingPlanes[planeIndex];
|
|
12926
|
+
const intersection = (0,volumeCropping.computePlanePlaneIntersection)(clippingPlane, viewPlaneNormal, focalPoint);
|
|
12927
|
+
if (!intersection) {
|
|
12928
|
+
continue;
|
|
12929
|
+
}
|
|
12930
|
+
const lineBounds = (0,volumeCropping.findLineBoundsIntersection)(intersection.point, intersection.direction, viewport);
|
|
12931
|
+
if (!lineBounds) {
|
|
12932
|
+
continue;
|
|
12801
12933
|
}
|
|
12802
|
-
const otherViewportControllable = this._getReferenceLineControllable(otherViewport.id);
|
|
12803
|
-
const direction = [0, 0, 0];
|
|
12804
|
-
Core_Math/* default.cross */.Ay.cross(camera.viewPlaneNormal, otherCamera.viewPlaneNormal, direction);
|
|
12805
|
-
Core_Math/* default.normalize */.Ay.normalize(direction);
|
|
12806
|
-
Core_Math/* default.multiplyScalar */.Ay.multiplyScalar(direction, otherCanvasDiagonalLength);
|
|
12807
|
-
const pointWorld0 = [0, 0, 0];
|
|
12808
|
-
Core_Math/* default.add */.Ay.add(otherViewportCenterWorld, direction, pointWorld0);
|
|
12809
|
-
const pointWorld1 = [0, 0, 0];
|
|
12810
|
-
Core_Math/* default.subtract */.Ay.subtract(otherViewportCenterWorld, direction, pointWorld1);
|
|
12811
|
-
const pointCanvas0 = viewport.worldToCanvas(pointWorld0);
|
|
12812
|
-
const otherViewportCenterCanvas = viewport.worldToCanvas([
|
|
12813
|
-
otherViewportCenterWorld[0] ?? 0,
|
|
12814
|
-
otherViewportCenterWorld[1] ?? 0,
|
|
12815
|
-
otherViewportCenterWorld[2] ?? 0,
|
|
12816
|
-
]);
|
|
12817
|
-
const canvasUnitVectorFromCenter = gl_matrix_esm/* vec2.create */.Zc.create();
|
|
12818
|
-
gl_matrix_esm/* vec2.subtract */.Zc.subtract(canvasUnitVectorFromCenter, pointCanvas0, otherViewportCenterCanvas);
|
|
12819
|
-
gl_matrix_esm/* vec2.normalize */.Zc.normalize(canvasUnitVectorFromCenter, canvasUnitVectorFromCenter);
|
|
12820
|
-
const canvasVectorFromCenterLong = gl_matrix_esm/* vec2.create */.Zc.create();
|
|
12821
|
-
gl_matrix_esm/* vec2.scale */.Zc.scale(canvasVectorFromCenterLong, canvasUnitVectorFromCenter, canvasDiagonalLength * 100);
|
|
12822
|
-
const refLinesCenterMin = otherViewportControllable
|
|
12823
|
-
? gl_matrix_esm/* vec2.clone */.Zc.clone(volumeCroppingCenterCanvasMin)
|
|
12824
|
-
: gl_matrix_esm/* vec2.clone */.Zc.clone(otherViewportCenterCanvas);
|
|
12825
|
-
const refLinePointMinOne = gl_matrix_esm/* vec2.create */.Zc.create();
|
|
12826
|
-
const refLinePointMinTwo = gl_matrix_esm/* vec2.create */.Zc.create();
|
|
12827
|
-
gl_matrix_esm/* vec2.add */.Zc.add(refLinePointMinOne, refLinesCenterMin, canvasVectorFromCenterLong);
|
|
12828
|
-
gl_matrix_esm/* vec2.subtract */.Zc.subtract(refLinePointMinTwo, refLinesCenterMin, canvasVectorFromCenterLong);
|
|
12829
|
-
(0,liangBarksyClip/* default */.A)(refLinePointMinOne, refLinePointMinTwo, canvasBox);
|
|
12830
|
-
referenceLines.push([
|
|
12831
|
-
otherViewport,
|
|
12832
|
-
refLinePointMinOne,
|
|
12833
|
-
refLinePointMinTwo,
|
|
12834
|
-
'min',
|
|
12835
|
-
]);
|
|
12836
|
-
const refLinesCenterMax = otherViewportControllable
|
|
12837
|
-
? gl_matrix_esm/* vec2.clone */.Zc.clone(volumeCroppingCenterCanvasMax)
|
|
12838
|
-
: gl_matrix_esm/* vec2.clone */.Zc.clone(otherViewportCenterCanvas);
|
|
12839
|
-
const refLinePointMaxOne = gl_matrix_esm/* vec2.create */.Zc.create();
|
|
12840
|
-
const refLinePointMaxTwo = gl_matrix_esm/* vec2.create */.Zc.create();
|
|
12841
|
-
gl_matrix_esm/* vec2.add */.Zc.add(refLinePointMaxOne, refLinesCenterMax, canvasVectorFromCenterLong);
|
|
12842
|
-
gl_matrix_esm/* vec2.subtract */.Zc.subtract(refLinePointMaxTwo, refLinesCenterMax, canvasVectorFromCenterLong);
|
|
12843
|
-
(0,liangBarksyClip/* default */.A)(refLinePointMaxOne, refLinePointMaxTwo, canvasBox);
|
|
12844
12934
|
referenceLines.push([
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12935
|
+
{
|
|
12936
|
+
id: viewport.id,
|
|
12937
|
+
canvas: viewport.canvas,
|
|
12938
|
+
},
|
|
12939
|
+
lineBounds.start,
|
|
12940
|
+
lineBounds.end,
|
|
12941
|
+
planeTypes[planeIndex],
|
|
12942
|
+
planeIndex,
|
|
12849
12943
|
]);
|
|
12850
|
-
}
|
|
12944
|
+
}
|
|
12851
12945
|
data.referenceLines = referenceLines;
|
|
12852
12946
|
const viewportColor = this._getReferenceLineColor(viewport.id);
|
|
12853
|
-
const
|
|
12947
|
+
const defaultColor = viewportColor !== undefined ? viewportColor : 'rgb(200, 200, 200)';
|
|
12854
12948
|
referenceLines.forEach((line, lineIndex) => {
|
|
12949
|
+
const [otherViewport, startPoint, endPoint, type, planeIndex] = line;
|
|
12950
|
+
if (planeIndex === undefined ||
|
|
12951
|
+
planeIndex < 0 ||
|
|
12952
|
+
planeIndex >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
12953
|
+
return;
|
|
12954
|
+
}
|
|
12855
12955
|
const intersections = [];
|
|
12856
12956
|
for (let j = 0; j < referenceLines.length; ++j) {
|
|
12857
12957
|
if (j === lineIndex) {
|
|
12858
12958
|
continue;
|
|
12859
12959
|
}
|
|
12860
12960
|
const otherLine = referenceLines[j];
|
|
12861
|
-
const intersection = lineIntersection2D(
|
|
12961
|
+
const intersection = lineIntersection2D(startPoint, endPoint, otherLine[1], otherLine[2]);
|
|
12862
12962
|
if (intersection) {
|
|
12863
12963
|
intersections.push({
|
|
12864
12964
|
with: otherLine[3],
|
|
@@ -12866,32 +12966,12 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12866
12966
|
});
|
|
12867
12967
|
}
|
|
12868
12968
|
}
|
|
12869
|
-
const
|
|
12870
|
-
let orientation = null;
|
|
12871
|
-
if (otherViewport && otherViewport.id) {
|
|
12872
|
-
const annotationForViewport = annotations.find((a) => a.data.viewportId === otherViewport.id);
|
|
12873
|
-
if (annotationForViewport && annotationForViewport.data.orientation) {
|
|
12874
|
-
orientation = String(annotationForViewport.data.orientation).toUpperCase();
|
|
12875
|
-
}
|
|
12876
|
-
else {
|
|
12877
|
-
const idUpper = otherViewport.id.toUpperCase();
|
|
12878
|
-
if (idUpper.includes('AXIAL')) {
|
|
12879
|
-
orientation = 'AXIAL';
|
|
12880
|
-
}
|
|
12881
|
-
else if (idUpper.includes('CORONAL')) {
|
|
12882
|
-
orientation = 'CORONAL';
|
|
12883
|
-
}
|
|
12884
|
-
else if (idUpper.includes('SAGITTAL')) {
|
|
12885
|
-
orientation = 'SAGITTAL';
|
|
12886
|
-
}
|
|
12887
|
-
}
|
|
12888
|
-
}
|
|
12969
|
+
const colorKey = (0,volumeCropping.getColorKeyForPlaneIndex)(planeIndex);
|
|
12889
12970
|
const lineColors = this.configuration.lineColors || {};
|
|
12890
|
-
const colorArr =
|
|
12891
|
-
lineColors.
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
: colorArr;
|
|
12971
|
+
const colorArr = colorKey
|
|
12972
|
+
? lineColors[colorKey] || lineColors.UNKNOWN || [1.0, 0.0, 0.0]
|
|
12973
|
+
: [1.0, 0.0, 0.0];
|
|
12974
|
+
const color = (0,esm.convertColorArrayToRgbString)(colorArr);
|
|
12895
12975
|
const viewportControllable = this._getReferenceLineControllable(otherViewport.id);
|
|
12896
12976
|
const selectedViewportId = data.activeViewportIds.find((id) => id === otherViewport.id);
|
|
12897
12977
|
let lineWidth = this.configuration.lineWidth ?? 1.5;
|
|
@@ -12901,28 +12981,29 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12901
12981
|
if (lineActive) {
|
|
12902
12982
|
lineWidth = this.configuration.activeLineWidth ?? 2.5;
|
|
12903
12983
|
}
|
|
12904
|
-
const lineUID =
|
|
12905
|
-
if (
|
|
12906
|
-
|
|
12907
|
-
|
|
12908
|
-
|
|
12909
|
-
|
|
12910
|
-
|
|
12911
|
-
|
|
12912
|
-
|
|
12913
|
-
|
|
12914
|
-
|
|
12915
|
-
|
|
12916
|
-
|
|
12917
|
-
|
|
12918
|
-
|
|
12919
|
-
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
}
|
|
12984
|
+
const lineUID = `plane_${planeIndex}`;
|
|
12985
|
+
if (intersections.length === 2) {
|
|
12986
|
+
(0,drawingSvg.drawLine)(svgDrawingHelper, annotationUID, lineUID, intersections[0].point, intersections[1].point, {
|
|
12987
|
+
color,
|
|
12988
|
+
lineWidth,
|
|
12989
|
+
});
|
|
12990
|
+
}
|
|
12991
|
+
else {
|
|
12992
|
+
(0,drawingSvg.drawLine)(svgDrawingHelper, annotationUID, lineUID, startPoint, endPoint, {
|
|
12993
|
+
color,
|
|
12994
|
+
lineWidth,
|
|
12995
|
+
});
|
|
12996
|
+
}
|
|
12997
|
+
if (this.configuration.extendReferenceLines &&
|
|
12998
|
+
intersections.length === 2) {
|
|
12999
|
+
const sortedIntersections = intersections
|
|
13000
|
+
.map((intersection) => ({
|
|
13001
|
+
...intersection,
|
|
13002
|
+
distance: gl_matrix_esm/* vec2.distance */.Zc.distance(startPoint, intersection.point),
|
|
13003
|
+
}))
|
|
13004
|
+
.sort((a, b) => a.distance - b.distance);
|
|
13005
|
+
(0,drawingSvg.drawLine)(svgDrawingHelper, annotationUID, lineUID + '_dashed_before', startPoint, sortedIntersections[0].point, { color, lineWidth, lineDash: [4, 4] });
|
|
13006
|
+
(0,drawingSvg.drawLine)(svgDrawingHelper, annotationUID, lineUID + '_dashed_after', sortedIntersections[1].point, endPoint, { color, lineWidth, lineDash: [4, 4] });
|
|
12926
13007
|
}
|
|
12927
13008
|
});
|
|
12928
13009
|
renderStatus = true;
|
|
@@ -12936,7 +13017,7 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12936
13017
|
];
|
|
12937
13018
|
const circleRadius = viewportIndicatorsConfig?.circleRadius || canvasDiagonalLength * 0.01;
|
|
12938
13019
|
const circleUID = '0';
|
|
12939
|
-
(0,drawingSvg.drawCircle)(svgDrawingHelper, annotationUID, circleUID, referenceColorCoordinates, circleRadius, { color, fill:
|
|
13020
|
+
(0,drawingSvg.drawCircle)(svgDrawingHelper, annotationUID, circleUID, referenceColorCoordinates, circleRadius, { color: defaultColor, fill: defaultColor });
|
|
12940
13021
|
}
|
|
12941
13022
|
return renderStatus;
|
|
12942
13023
|
};
|
|
@@ -12958,40 +13039,7 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12958
13039
|
if (evt.detail.seriesInstanceUID !== this.seriesInstanceUID) {
|
|
12959
13040
|
return;
|
|
12960
13041
|
}
|
|
12961
|
-
|
|
12962
|
-
const newMin = [...this.toolCenterMin];
|
|
12963
|
-
const newMax = [...this.toolCenterMax];
|
|
12964
|
-
if (draggingSphereIndex >= 0 && draggingSphereIndex <= 5) {
|
|
12965
|
-
const axis = Math.floor(draggingSphereIndex / 2);
|
|
12966
|
-
const isMin = draggingSphereIndex % 2 === 0;
|
|
12967
|
-
(isMin ? newMin : newMax)[axis] = toolCenter[axis];
|
|
12968
|
-
this.setToolCenter(newMin, 'min');
|
|
12969
|
-
this.setToolCenter(newMax, 'max');
|
|
12970
|
-
return;
|
|
12971
|
-
}
|
|
12972
|
-
if (draggingSphereIndex >= 6 && draggingSphereIndex <= 13) {
|
|
12973
|
-
const idx = draggingSphereIndex;
|
|
12974
|
-
if (idx < 10) {
|
|
12975
|
-
newMin[0] = toolCenter[0];
|
|
12976
|
-
}
|
|
12977
|
-
else {
|
|
12978
|
-
newMax[0] = toolCenter[0];
|
|
12979
|
-
}
|
|
12980
|
-
if ([6, 7, 10, 11].includes(idx)) {
|
|
12981
|
-
newMin[1] = toolCenter[1];
|
|
12982
|
-
}
|
|
12983
|
-
else {
|
|
12984
|
-
newMax[1] = toolCenter[1];
|
|
12985
|
-
}
|
|
12986
|
-
if (idx % 2 === 0) {
|
|
12987
|
-
newMin[2] = toolCenter[2];
|
|
12988
|
-
}
|
|
12989
|
-
else {
|
|
12990
|
-
newMax[2] = toolCenter[2];
|
|
12991
|
-
}
|
|
12992
|
-
this.setToolCenter(newMin, 'min');
|
|
12993
|
-
this.setToolCenter(newMax, 'max');
|
|
12994
|
-
}
|
|
13042
|
+
return;
|
|
12995
13043
|
}
|
|
12996
13044
|
};
|
|
12997
13045
|
this._onNewVolume = () => {
|
|
@@ -12999,72 +13047,28 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
12999
13047
|
if (viewportsInfo && viewportsInfo.length > 0) {
|
|
13000
13048
|
const { viewportId, renderingEngineId } = viewportsInfo[0];
|
|
13001
13049
|
const renderingEngine = (0,esm.getRenderingEngine)(renderingEngineId);
|
|
13050
|
+
if (!renderingEngine) {
|
|
13051
|
+
return;
|
|
13052
|
+
}
|
|
13002
13053
|
const viewport = renderingEngine.getViewport(viewportId);
|
|
13054
|
+
if (!viewport) {
|
|
13055
|
+
return;
|
|
13056
|
+
}
|
|
13003
13057
|
const volumeActors = viewport.getActors();
|
|
13004
13058
|
if (volumeActors.length > 0) {
|
|
13005
13059
|
const imageData = volumeActors[0].actor.getMapper().getInputData();
|
|
13006
13060
|
if (imageData) {
|
|
13007
13061
|
this.seriesInstanceUID = imageData.seriesInstanceUID;
|
|
13008
|
-
this._updateToolCentersFromViewport(viewport);
|
|
13009
|
-
const annotations = (0,annotationState.getAnnotations)(this.getToolName(), viewportId) || [];
|
|
13010
|
-
annotations.forEach((annotation) => {
|
|
13011
|
-
if (annotation.data && annotation.data.handles) {
|
|
13012
|
-
annotation.data.handles.toolCenter = [...this.toolCenter];
|
|
13013
|
-
}
|
|
13014
|
-
});
|
|
13015
13062
|
}
|
|
13016
13063
|
}
|
|
13017
13064
|
}
|
|
13018
|
-
this.
|
|
13065
|
+
this._initializeViewports(viewportsInfo);
|
|
13019
13066
|
(0,esm.triggerEvent)(esm.eventTarget, enums.Events.VOLUMECROPPINGCONTROL_TOOL_CHANGED, {
|
|
13020
13067
|
toolGroupId: this.toolGroupId,
|
|
13021
13068
|
viewportsInfo: viewportsInfo,
|
|
13022
13069
|
seriesInstanceUID: this.seriesInstanceUID,
|
|
13023
13070
|
});
|
|
13024
13071
|
};
|
|
13025
|
-
this._getAnnotationsForViewportsWithDifferentCameras = (enabledElement, annotations) => {
|
|
13026
|
-
const { viewportId, renderingEngine, viewport } = enabledElement;
|
|
13027
|
-
const otherViewportAnnotations = annotations.filter((annotation) => annotation.data.viewportId !== viewportId);
|
|
13028
|
-
if (!otherViewportAnnotations || !otherViewportAnnotations.length) {
|
|
13029
|
-
return [];
|
|
13030
|
-
}
|
|
13031
|
-
const camera = viewport.getCamera();
|
|
13032
|
-
const { viewPlaneNormal, position } = camera;
|
|
13033
|
-
const viewportsWithDifferentCameras = otherViewportAnnotations.filter((annotation) => {
|
|
13034
|
-
const { viewportId } = annotation.data;
|
|
13035
|
-
const targetViewport = renderingEngine.getViewport(viewportId);
|
|
13036
|
-
const cameraOfTarget = targetViewport.getCamera();
|
|
13037
|
-
return !(esm.utilities.isEqual(cameraOfTarget.viewPlaneNormal, viewPlaneNormal, 1e-2) && esm.utilities.isEqual(cameraOfTarget.position, position, 1));
|
|
13038
|
-
});
|
|
13039
|
-
return viewportsWithDifferentCameras;
|
|
13040
|
-
};
|
|
13041
|
-
this._filterViewportWithSameOrientation = (enabledElement, referenceAnnotation, annotations) => {
|
|
13042
|
-
const { renderingEngine } = enabledElement;
|
|
13043
|
-
const { data } = referenceAnnotation;
|
|
13044
|
-
const viewport = renderingEngine.getViewport(data.viewportId);
|
|
13045
|
-
const linkedViewportAnnotations = annotations.filter((annotation) => {
|
|
13046
|
-
const { data } = annotation;
|
|
13047
|
-
const otherViewport = renderingEngine.getViewport(data.viewportId);
|
|
13048
|
-
const otherViewportControllable = this._getReferenceLineControllable(otherViewport.id);
|
|
13049
|
-
return otherViewportControllable === true;
|
|
13050
|
-
});
|
|
13051
|
-
if (!linkedViewportAnnotations || !linkedViewportAnnotations.length) {
|
|
13052
|
-
return [];
|
|
13053
|
-
}
|
|
13054
|
-
const camera = viewport.getCamera();
|
|
13055
|
-
const viewPlaneNormal = camera.viewPlaneNormal;
|
|
13056
|
-
Core_Math/* default.normalize */.Ay.normalize(viewPlaneNormal);
|
|
13057
|
-
const otherViewportsAnnotationsWithSameCameraDirection = linkedViewportAnnotations.filter((annotation) => {
|
|
13058
|
-
const { viewportId } = annotation.data;
|
|
13059
|
-
const otherViewport = renderingEngine.getViewport(viewportId);
|
|
13060
|
-
const otherCamera = otherViewport.getCamera();
|
|
13061
|
-
const otherViewPlaneNormal = otherCamera.viewPlaneNormal;
|
|
13062
|
-
Core_Math/* default.normalize */.Ay.normalize(otherViewPlaneNormal);
|
|
13063
|
-
return (esm.utilities.isEqual(viewPlaneNormal, otherViewPlaneNormal, 1e-2) &&
|
|
13064
|
-
esm.utilities.isEqual(camera.viewUp, otherCamera.viewUp, 1e-2));
|
|
13065
|
-
});
|
|
13066
|
-
return otherViewportsAnnotationsWithSameCameraDirection;
|
|
13067
|
-
};
|
|
13068
13072
|
this._activateModify = (element) => {
|
|
13069
13073
|
state/* state */.wk.isInteractingWithTool = !this.configuration.mobile?.enabled;
|
|
13070
13074
|
element.addEventListener(enums.Events.MOUSE_UP, this._endCallback);
|
|
@@ -13116,48 +13120,71 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13116
13120
|
return;
|
|
13117
13121
|
}
|
|
13118
13122
|
const { handles } = viewportAnnotation.data;
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13123
|
+
const clippingPlanes = handles.clippingPlanes;
|
|
13124
|
+
if (handles.activeOperation === OPERATION.DRAG &&
|
|
13125
|
+
clippingPlanes &&
|
|
13126
|
+
clippingPlanes.length >= volumeCropping.NUM_CLIPPING_PLANES) {
|
|
13127
|
+
if (handles.activePlaneIndex !== undefined &&
|
|
13128
|
+
handles.activePlaneIndex >= 0 &&
|
|
13129
|
+
handles.activePlaneIndex < volumeCropping.NUM_CLIPPING_PLANES) {
|
|
13130
|
+
const planeIndex = handles.activePlaneIndex;
|
|
13131
|
+
const plane = clippingPlanes[planeIndex];
|
|
13132
|
+
const normal = plane.normal;
|
|
13133
|
+
const dotProd = Core_Math/* default.dot */.Ay.dot(delta, normal);
|
|
13134
|
+
const moveDistance = dotProd;
|
|
13135
|
+
plane.origin[0] += normal[0] * moveDistance;
|
|
13136
|
+
plane.origin[1] += normal[1] * moveDistance;
|
|
13137
|
+
plane.origin[2] += normal[2] * moveDistance;
|
|
13124
13138
|
}
|
|
13125
|
-
else if (handles.activeType === '
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
|
|
13139
|
+
else if (handles.activeType === 'min') {
|
|
13140
|
+
clippingPlanes[0].origin[0] += delta[0];
|
|
13141
|
+
clippingPlanes[2].origin[1] += delta[1];
|
|
13142
|
+
clippingPlanes[4].origin[2] += delta[2];
|
|
13129
13143
|
}
|
|
13130
|
-
else {
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13144
|
+
else if (handles.activeType === 'max') {
|
|
13145
|
+
clippingPlanes[1].origin[0] += delta[0];
|
|
13146
|
+
clippingPlanes[3].origin[1] += delta[1];
|
|
13147
|
+
clippingPlanes[5].origin[2] += delta[2];
|
|
13134
13148
|
}
|
|
13149
|
+
this.clippingPlanes = (0,volumeCropping.copyClippingPlanes)(clippingPlanes);
|
|
13135
13150
|
const viewportsInfo = this._getViewportsInfo();
|
|
13151
|
+
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
13152
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
13153
|
+
if (enabledElement) {
|
|
13154
|
+
const annotations = this._getAnnotations(enabledElement);
|
|
13155
|
+
annotations.forEach((annotation) => {
|
|
13156
|
+
if (annotation.data?.handles) {
|
|
13157
|
+
annotation.data.handles.clippingPlanes = (0,volumeCropping.copyClippingPlanes)(this.clippingPlanes);
|
|
13158
|
+
}
|
|
13159
|
+
});
|
|
13160
|
+
}
|
|
13161
|
+
});
|
|
13136
13162
|
(0,triggerAnnotationRenderForViewportIds/* default */.A)(viewportsInfo.map(({ viewportId }) => viewportId));
|
|
13137
13163
|
(0,esm.triggerEvent)(esm.eventTarget, enums.Events.VOLUMECROPPINGCONTROL_TOOL_CHANGED, {
|
|
13138
13164
|
toolGroupId: this.toolGroupId,
|
|
13139
|
-
|
|
13140
|
-
toolCenterMin: this.toolCenterMin,
|
|
13141
|
-
toolCenterMax: this.toolCenterMax,
|
|
13165
|
+
clippingPlanes: this.clippingPlanes,
|
|
13142
13166
|
handleType: handles.activeType,
|
|
13143
|
-
viewportOrientation: [],
|
|
13144
13167
|
seriesInstanceUID: this.seriesInstanceUID,
|
|
13145
13168
|
});
|
|
13146
13169
|
}
|
|
13147
13170
|
};
|
|
13148
13171
|
this._getReferenceLineColor =
|
|
13149
13172
|
toolProps.configuration?.getReferenceLineColor ||
|
|
13150
|
-
|
|
13173
|
+
(() => 'rgb(0, 200, 0)');
|
|
13151
13174
|
this._getReferenceLineControllable =
|
|
13152
|
-
toolProps.configuration?.getReferenceLineControllable ||
|
|
13153
|
-
defaultReferenceLineControllable;
|
|
13175
|
+
toolProps.configuration?.getReferenceLineControllable || (() => true);
|
|
13154
13176
|
const viewportsInfo = (0,ToolGroupManager.getToolGroup)(this.toolGroupId)?.viewportsInfo;
|
|
13155
13177
|
esm.eventTarget.addEventListener(enums.Events.VOLUMECROPPING_TOOL_CHANGED, this._onSphereMoved);
|
|
13156
13178
|
if (viewportsInfo && viewportsInfo.length > 0) {
|
|
13157
13179
|
const { viewportId, renderingEngineId } = viewportsInfo[0];
|
|
13158
|
-
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
13159
13180
|
const renderingEngine = (0,esm.getRenderingEngine)(renderingEngineId);
|
|
13181
|
+
if (!renderingEngine) {
|
|
13182
|
+
return;
|
|
13183
|
+
}
|
|
13160
13184
|
const viewport = renderingEngine.getViewport(viewportId);
|
|
13185
|
+
if (!viewport) {
|
|
13186
|
+
return;
|
|
13187
|
+
}
|
|
13161
13188
|
const volumeActors = viewport.getActors();
|
|
13162
13189
|
if (!volumeActors || !volumeActors.length) {
|
|
13163
13190
|
console.warn(`VolumeCroppingControlTool: No volume actors found in viewport ${viewportId}.`);
|
|
@@ -13165,67 +13192,11 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13165
13192
|
}
|
|
13166
13193
|
const imageData = volumeActors[0].actor.getMapper().getInputData();
|
|
13167
13194
|
if (imageData) {
|
|
13168
|
-
const dimensions = imageData.getDimensions();
|
|
13169
|
-
const spacing = imageData.getSpacing();
|
|
13170
|
-
const origin = imageData.getOrigin();
|
|
13171
13195
|
this.seriesInstanceUID = imageData.seriesInstanceUID || 'unknown';
|
|
13172
|
-
const cropFactor = this.configuration.initialCropFactor ?? 0.2;
|
|
13173
|
-
this.toolCenter = [
|
|
13174
|
-
origin[0] + cropFactor * (dimensions[0] - 1) * spacing[0],
|
|
13175
|
-
origin[1] + cropFactor * (dimensions[1] - 1) * spacing[1],
|
|
13176
|
-
origin[2] + cropFactor * (dimensions[2] - 1) * spacing[2],
|
|
13177
|
-
];
|
|
13178
|
-
const maxCropFactor = 1 - cropFactor;
|
|
13179
|
-
this.toolCenterMin = [
|
|
13180
|
-
origin[0] + cropFactor * (dimensions[0] - 1) * spacing[0],
|
|
13181
|
-
origin[1] + cropFactor * (dimensions[1] - 1) * spacing[1],
|
|
13182
|
-
origin[2] + cropFactor * (dimensions[2] - 1) * spacing[2],
|
|
13183
|
-
];
|
|
13184
|
-
this.toolCenterMax = [
|
|
13185
|
-
origin[0] + maxCropFactor * (dimensions[0] - 1) * spacing[0],
|
|
13186
|
-
origin[1] + maxCropFactor * (dimensions[1] - 1) * spacing[1],
|
|
13187
|
-
origin[2] + maxCropFactor * (dimensions[2] - 1) * spacing[2],
|
|
13188
|
-
];
|
|
13189
13196
|
}
|
|
13190
13197
|
}
|
|
13191
13198
|
}
|
|
13192
|
-
_updateToolCentersFromViewport(viewport) {
|
|
13193
|
-
const volumeActors = viewport.getActors();
|
|
13194
|
-
if (!volumeActors || !volumeActors.length) {
|
|
13195
|
-
return;
|
|
13196
|
-
}
|
|
13197
|
-
const imageData = volumeActors[0].actor.getMapper().getInputData();
|
|
13198
|
-
if (!imageData) {
|
|
13199
|
-
return;
|
|
13200
|
-
}
|
|
13201
|
-
this.seriesInstanceUID = imageData.seriesInstanceUID || 'unknown';
|
|
13202
|
-
const dimensions = imageData.getDimensions();
|
|
13203
|
-
const spacing = imageData.getSpacing();
|
|
13204
|
-
const origin = imageData.getOrigin();
|
|
13205
|
-
const cropFactor = this.configuration.initialCropFactor ?? 0.2;
|
|
13206
|
-
const cropStart = cropFactor / 2;
|
|
13207
|
-
const cropEnd = 1 - cropFactor / 2;
|
|
13208
|
-
this.toolCenter = [
|
|
13209
|
-
origin[0] +
|
|
13210
|
-
((cropStart + cropEnd) / 2) * (dimensions[0] - 1) * spacing[0],
|
|
13211
|
-
origin[1] +
|
|
13212
|
-
((cropStart + cropEnd) / 2) * (dimensions[1] - 1) * spacing[1],
|
|
13213
|
-
origin[2] +
|
|
13214
|
-
((cropStart + cropEnd) / 2) * (dimensions[2] - 1) * spacing[2],
|
|
13215
|
-
];
|
|
13216
|
-
this.toolCenterMin = [
|
|
13217
|
-
origin[0] + cropStart * (dimensions[0] - 1) * spacing[0],
|
|
13218
|
-
origin[1] + cropStart * (dimensions[1] - 1) * spacing[1],
|
|
13219
|
-
origin[2] + cropStart * (dimensions[2] - 1) * spacing[2],
|
|
13220
|
-
];
|
|
13221
|
-
this.toolCenterMax = [
|
|
13222
|
-
origin[0] + cropEnd * (dimensions[0] - 1) * spacing[0],
|
|
13223
|
-
origin[1] + cropEnd * (dimensions[1] - 1) * spacing[1],
|
|
13224
|
-
origin[2] + cropEnd * (dimensions[2] - 1) * spacing[2],
|
|
13225
|
-
];
|
|
13226
|
-
}
|
|
13227
13199
|
onSetToolInactive() {
|
|
13228
|
-
console.debug(`VolumeCroppingControlTool: onSetToolInactive called for tool ${this.getToolName()}`);
|
|
13229
13200
|
}
|
|
13230
13201
|
onSetToolActive() {
|
|
13231
13202
|
const viewportsInfo = this._getViewportsInfo();
|
|
@@ -13241,7 +13212,7 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13241
13212
|
if (!anyAnnotationExists) {
|
|
13242
13213
|
this._unsubscribeToViewportNewVolumeSet(viewportsInfo);
|
|
13243
13214
|
this._subscribeToViewportNewVolumeSet(viewportsInfo);
|
|
13244
|
-
this.
|
|
13215
|
+
this._initializeViewports(viewportsInfo);
|
|
13245
13216
|
(0,esm.triggerEvent)(esm.eventTarget, enums.Events.VOLUMECROPPINGCONTROL_TOOL_CHANGED, {
|
|
13246
13217
|
toolGroupId: this.toolGroupId,
|
|
13247
13218
|
viewportsInfo: viewportsInfo,
|
|
@@ -13265,13 +13236,12 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13265
13236
|
}
|
|
13266
13237
|
}
|
|
13267
13238
|
onSetToolEnabled() {
|
|
13268
|
-
|
|
13269
|
-
const viewportsInfo = this._getViewportsInfo();
|
|
13239
|
+
esm.eventTarget.addEventListener(enums.Events.VOLUMECROPPING_TOOL_CHANGED, this._onSphereMoved);
|
|
13270
13240
|
}
|
|
13271
13241
|
onSetToolDisabled() {
|
|
13272
|
-
console.debug(`VolumeCroppingControlTool: onSetToolDisabled called for tool ${this.getToolName()}`);
|
|
13273
13242
|
const viewportsInfo = this._getViewportsInfo();
|
|
13274
13243
|
this._unsubscribeToViewportNewVolumeSet(viewportsInfo);
|
|
13244
|
+
esm.eventTarget.removeEventListener(enums.Events.VOLUMECROPPING_TOOL_CHANGED, this._onSphereMoved);
|
|
13275
13245
|
viewportsInfo.forEach(({ renderingEngineId, viewportId }) => {
|
|
13276
13246
|
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
13277
13247
|
if (!enabledElement) {
|
|
@@ -13285,176 +13255,24 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13285
13255
|
}
|
|
13286
13256
|
});
|
|
13287
13257
|
}
|
|
13288
|
-
_getOrientationFromNormal(normal) {
|
|
13289
|
-
if (!normal) {
|
|
13290
|
-
return null;
|
|
13291
|
-
}
|
|
13292
|
-
const canonical = {
|
|
13293
|
-
AXIAL: [0, 0, 1],
|
|
13294
|
-
CORONAL: [0, 1, 0],
|
|
13295
|
-
SAGITTAL: [1, 0, 0],
|
|
13296
|
-
};
|
|
13297
|
-
const tol = 1e-2;
|
|
13298
|
-
for (const [key, value] of Object.entries(canonical)) {
|
|
13299
|
-
if (Math.abs(normal[0] - value[0]) < tol &&
|
|
13300
|
-
Math.abs(normal[1] - value[1]) < tol &&
|
|
13301
|
-
Math.abs(normal[2] - value[2]) < tol) {
|
|
13302
|
-
return key;
|
|
13303
|
-
}
|
|
13304
|
-
if (Math.abs(normal[0] + value[0]) < tol &&
|
|
13305
|
-
Math.abs(normal[1] + value[1]) < tol &&
|
|
13306
|
-
Math.abs(normal[2] + value[2]) < tol) {
|
|
13307
|
-
return key;
|
|
13308
|
-
}
|
|
13309
|
-
}
|
|
13310
|
-
return null;
|
|
13311
|
-
}
|
|
13312
13258
|
_syncWithVolumeCroppingTool(originalClippingPlanes) {
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
(this.toolCenterMin[0] + this.toolCenterMax[0]) / 2,
|
|
13327
|
-
(this.toolCenterMin[1] + this.toolCenterMax[1]) / 2,
|
|
13328
|
-
(this.toolCenterMin[2] + this.toolCenterMax[2]) / 2,
|
|
13329
|
-
];
|
|
13330
|
-
const viewportsInfo = this._getViewportsInfo();
|
|
13331
|
-
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
13332
|
-
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
13333
|
-
if (enabledElement) {
|
|
13334
|
-
const annotations = this._getAnnotations(enabledElement);
|
|
13335
|
-
annotations.forEach((annotation) => {
|
|
13336
|
-
if (annotation.data &&
|
|
13337
|
-
annotation.data.handles &&
|
|
13338
|
-
annotation.data.orientation) {
|
|
13339
|
-
const orientation = annotation.data.orientation;
|
|
13340
|
-
if (orientation === 'AXIAL') {
|
|
13341
|
-
annotation.data.handles.toolCenterMin = [
|
|
13342
|
-
planes[0].origin[0],
|
|
13343
|
-
planes[2].origin[1],
|
|
13344
|
-
annotation.data.handles.toolCenterMin[2],
|
|
13345
|
-
];
|
|
13346
|
-
annotation.data.handles.toolCenterMax = [
|
|
13347
|
-
planes[1].origin[0],
|
|
13348
|
-
planes[3].origin[1],
|
|
13349
|
-
annotation.data.handles.toolCenterMax[2],
|
|
13350
|
-
];
|
|
13351
|
-
}
|
|
13352
|
-
else if (orientation === 'CORONAL') {
|
|
13353
|
-
annotation.data.handles.toolCenterMin = [
|
|
13354
|
-
planes[0].origin[0],
|
|
13355
|
-
annotation.data.handles.toolCenterMin[1],
|
|
13356
|
-
planes[4].origin[2],
|
|
13357
|
-
];
|
|
13358
|
-
annotation.data.handles.toolCenterMax = [
|
|
13359
|
-
planes[1].origin[0],
|
|
13360
|
-
annotation.data.handles.toolCenterMax[1],
|
|
13361
|
-
planes[5].origin[2],
|
|
13362
|
-
];
|
|
13363
|
-
}
|
|
13364
|
-
else if (orientation === 'SAGITTAL') {
|
|
13365
|
-
annotation.data.handles.toolCenterMin = [
|
|
13366
|
-
annotation.data.handles.toolCenterMin[0],
|
|
13367
|
-
planes[2].origin[1],
|
|
13368
|
-
planes[4].origin[2],
|
|
13369
|
-
];
|
|
13370
|
-
annotation.data.handles.toolCenterMax = [
|
|
13371
|
-
annotation.data.handles.toolCenterMax[0],
|
|
13372
|
-
planes[3].origin[1],
|
|
13373
|
-
planes[5].origin[2],
|
|
13374
|
-
];
|
|
13375
|
-
}
|
|
13376
|
-
annotation.data.handles.toolCenter = [
|
|
13377
|
-
(annotation.data.handles.toolCenterMin[0] +
|
|
13378
|
-
annotation.data.handles.toolCenterMax[0]) /
|
|
13379
|
-
2,
|
|
13380
|
-
(annotation.data.handles.toolCenterMin[1] +
|
|
13381
|
-
annotation.data.handles.toolCenterMax[1]) /
|
|
13382
|
-
2,
|
|
13383
|
-
(annotation.data.handles.toolCenterMin[2] +
|
|
13384
|
-
annotation.data.handles.toolCenterMax[2]) /
|
|
13385
|
-
2,
|
|
13386
|
-
];
|
|
13387
|
-
}
|
|
13388
|
-
});
|
|
13389
|
-
}
|
|
13390
|
-
});
|
|
13391
|
-
if (this._virtualAnnotations && this._virtualAnnotations.length > 0) {
|
|
13392
|
-
this._virtualAnnotations.forEach((annotation) => {
|
|
13393
|
-
if (annotation.data &&
|
|
13394
|
-
annotation.data.handles &&
|
|
13395
|
-
annotation.data.orientation) {
|
|
13396
|
-
const orientation = annotation.data.orientation.toUpperCase();
|
|
13397
|
-
if (orientation === 'AXIAL') {
|
|
13398
|
-
annotation.data.handles.toolCenterMin = [
|
|
13399
|
-
planes[0].origin[0],
|
|
13400
|
-
planes[2].origin[1],
|
|
13401
|
-
annotation.data.handles.toolCenterMin[2],
|
|
13402
|
-
];
|
|
13403
|
-
annotation.data.handles.toolCenterMax = [
|
|
13404
|
-
planes[1].origin[0],
|
|
13405
|
-
planes[3].origin[1],
|
|
13406
|
-
annotation.data.handles.toolCenterMax[2],
|
|
13407
|
-
];
|
|
13408
|
-
}
|
|
13409
|
-
else if (orientation === 'CORONAL') {
|
|
13410
|
-
annotation.data.handles.toolCenterMin = [
|
|
13411
|
-
planes[0].origin[0],
|
|
13412
|
-
annotation.data.handles.toolCenterMin[1],
|
|
13413
|
-
planes[4].origin[2],
|
|
13414
|
-
];
|
|
13415
|
-
annotation.data.handles.toolCenterMax = [
|
|
13416
|
-
planes[1].origin[0],
|
|
13417
|
-
annotation.data.handles.toolCenterMax[1],
|
|
13418
|
-
planes[5].origin[2],
|
|
13419
|
-
];
|
|
13420
|
-
}
|
|
13421
|
-
else if (orientation === 'SAGITTAL') {
|
|
13422
|
-
annotation.data.handles.toolCenterMin = [
|
|
13423
|
-
annotation.data.handles.toolCenterMin[0],
|
|
13424
|
-
planes[2].origin[1],
|
|
13425
|
-
planes[4].origin[2],
|
|
13426
|
-
];
|
|
13427
|
-
annotation.data.handles.toolCenterMax = [
|
|
13428
|
-
annotation.data.handles.toolCenterMax[0],
|
|
13429
|
-
planes[3].origin[1],
|
|
13430
|
-
planes[5].origin[2],
|
|
13431
|
-
];
|
|
13432
|
-
}
|
|
13433
|
-
annotation.data.handles.toolCenter = [
|
|
13434
|
-
(annotation.data.handles.toolCenterMin[0] +
|
|
13435
|
-
annotation.data.handles.toolCenterMax[0]) /
|
|
13436
|
-
2,
|
|
13437
|
-
(annotation.data.handles.toolCenterMin[1] +
|
|
13438
|
-
annotation.data.handles.toolCenterMax[1]) /
|
|
13439
|
-
2,
|
|
13440
|
-
(annotation.data.handles.toolCenterMin[2] +
|
|
13441
|
-
annotation.data.handles.toolCenterMax[2]) /
|
|
13442
|
-
2,
|
|
13443
|
-
];
|
|
13259
|
+
if (!originalClippingPlanes ||
|
|
13260
|
+
originalClippingPlanes.length < volumeCropping.NUM_CLIPPING_PLANES) {
|
|
13261
|
+
return;
|
|
13262
|
+
}
|
|
13263
|
+
this.clippingPlanes = (0,volumeCropping.copyClippingPlanes)(originalClippingPlanes);
|
|
13264
|
+
const viewportsInfo = this._getViewportsInfo();
|
|
13265
|
+
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
13266
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
13267
|
+
if (enabledElement) {
|
|
13268
|
+
const annotations = this._getAnnotations(enabledElement);
|
|
13269
|
+
annotations.forEach((annotation) => {
|
|
13270
|
+
if (annotation.data?.handles) {
|
|
13271
|
+
annotation.data.handles.clippingPlanes = (0,volumeCropping.copyClippingPlanes)(this.clippingPlanes);
|
|
13444
13272
|
}
|
|
13445
13273
|
});
|
|
13446
13274
|
}
|
|
13447
|
-
|
|
13448
|
-
}
|
|
13449
|
-
}
|
|
13450
|
-
setToolCenter(toolCenter, handleType) {
|
|
13451
|
-
if (handleType === 'min') {
|
|
13452
|
-
this.toolCenterMin = [...toolCenter];
|
|
13453
|
-
}
|
|
13454
|
-
else if (handleType === 'max') {
|
|
13455
|
-
this.toolCenterMax = [...toolCenter];
|
|
13456
|
-
}
|
|
13457
|
-
const viewportsInfo = this._getViewportsInfo();
|
|
13275
|
+
});
|
|
13458
13276
|
(0,triggerAnnotationRenderForViewportIds/* default */.A)(viewportsInfo.map(({ viewportId }) => viewportId));
|
|
13459
13277
|
}
|
|
13460
13278
|
addNewAnnotation(evt) {
|
|
@@ -13479,7 +13297,6 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13479
13297
|
continue;
|
|
13480
13298
|
}
|
|
13481
13299
|
viewportIdArray.push(otherViewport.id);
|
|
13482
|
-
i++;
|
|
13483
13300
|
}
|
|
13484
13301
|
data.activeViewportIds = [...viewportIdArray];
|
|
13485
13302
|
data.handles.activeOperation = OPERATION.DRAG;
|
|
@@ -13505,51 +13322,22 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13505
13322
|
element.addEventListener(esm.Enums.Events.VOLUME_VIEWPORT_NEW_VOLUME, this._onNewVolume);
|
|
13506
13323
|
});
|
|
13507
13324
|
}
|
|
13508
|
-
_applyDeltaShiftToSelectedViewportCameras(renderingEngine, viewportsAnnotationsToUpdate, delta) {
|
|
13509
|
-
viewportsAnnotationsToUpdate.forEach((annotation) => {
|
|
13510
|
-
this._applyDeltaShiftToViewportCamera(renderingEngine, annotation, delta);
|
|
13511
|
-
});
|
|
13512
|
-
}
|
|
13513
|
-
_applyDeltaShiftToViewportCamera(renderingEngine, annotation, delta) {
|
|
13514
|
-
const { data } = annotation;
|
|
13515
|
-
const viewport = renderingEngine.getViewport(data.viewportId);
|
|
13516
|
-
const camera = viewport.getCamera();
|
|
13517
|
-
const normal = camera.viewPlaneNormal;
|
|
13518
|
-
const dotProd = Core_Math/* default.dot */.Ay.dot(delta, normal);
|
|
13519
|
-
const projectedDelta = [...normal];
|
|
13520
|
-
Core_Math/* default.multiplyScalar */.Ay.multiplyScalar(projectedDelta, dotProd);
|
|
13521
|
-
if (Math.abs(projectedDelta[0]) > 1e-3 ||
|
|
13522
|
-
Math.abs(projectedDelta[1]) > 1e-3 ||
|
|
13523
|
-
Math.abs(projectedDelta[2]) > 1e-3) {
|
|
13524
|
-
const newFocalPoint = [0, 0, 0];
|
|
13525
|
-
const newPosition = [0, 0, 0];
|
|
13526
|
-
Core_Math/* default.add */.Ay.add(camera.focalPoint, projectedDelta, newFocalPoint);
|
|
13527
|
-
Core_Math/* default.add */.Ay.add(camera.position, projectedDelta, newPosition);
|
|
13528
|
-
viewport.setCamera({
|
|
13529
|
-
focalPoint: newFocalPoint,
|
|
13530
|
-
position: newPosition,
|
|
13531
|
-
});
|
|
13532
|
-
viewport.render();
|
|
13533
|
-
}
|
|
13534
|
-
}
|
|
13535
13325
|
_pointNearTool(element, annotation, canvasCoords, proximity) {
|
|
13536
13326
|
const { data } = annotation;
|
|
13537
13327
|
const referenceLines = data.referenceLines;
|
|
13538
13328
|
const viewportIdArray = [];
|
|
13539
13329
|
if (referenceLines) {
|
|
13540
13330
|
for (let i = 0; i < referenceLines.length; ++i) {
|
|
13541
|
-
const otherViewport = referenceLines[i]
|
|
13542
|
-
const
|
|
13543
|
-
const end1 = referenceLines[i][2];
|
|
13544
|
-
const type = referenceLines[i][3];
|
|
13545
|
-
const distance1 = math_line.distanceToPoint(start1, end1, [
|
|
13331
|
+
const [otherViewport, startPoint, endPoint, type, planeIndex] = referenceLines[i];
|
|
13332
|
+
const distance = math_line.distanceToPoint(startPoint, endPoint, [
|
|
13546
13333
|
canvasCoords[0],
|
|
13547
13334
|
canvasCoords[1],
|
|
13548
13335
|
]);
|
|
13549
|
-
if (
|
|
13336
|
+
if (distance <= proximity) {
|
|
13550
13337
|
viewportIdArray.push(otherViewport.id);
|
|
13551
|
-
data.handles.activeOperation =
|
|
13338
|
+
data.handles.activeOperation = OPERATION.DRAG;
|
|
13552
13339
|
data.handles.activeType = type;
|
|
13340
|
+
data.handles.activePlaneIndex = planeIndex;
|
|
13553
13341
|
}
|
|
13554
13342
|
}
|
|
13555
13343
|
}
|
|
@@ -13557,7 +13345,7 @@ class VolumeCroppingControlTool extends base/* AnnotationTool */.EC {
|
|
|
13557
13345
|
this.editData = {
|
|
13558
13346
|
annotation,
|
|
13559
13347
|
};
|
|
13560
|
-
return data.handles.activeOperation ===
|
|
13348
|
+
return data.handles.activeOperation === OPERATION.DRAG ? true : false;
|
|
13561
13349
|
}
|
|
13562
13350
|
}
|
|
13563
13351
|
VolumeCroppingControlTool.toolName = 'VolumeCroppingControl';
|
|
@@ -14439,6 +14227,8 @@ MIPJumpToClickTool.toolName = 'MIPJumpToClickTool';
|
|
|
14439
14227
|
|
|
14440
14228
|
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/MatrixBuilder.js
|
|
14441
14229
|
var MatrixBuilder = __webpack_require__(90364);
|
|
14230
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/math/vec2/liangBarksyClip.js
|
|
14231
|
+
var liangBarksyClip = __webpack_require__(35381);
|
|
14442
14232
|
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/CrosshairsTool.js
|
|
14443
14233
|
|
|
14444
14234
|
|
|
@@ -14457,11 +14247,11 @@ var MatrixBuilder = __webpack_require__(90364);
|
|
|
14457
14247
|
|
|
14458
14248
|
|
|
14459
14249
|
|
|
14460
|
-
const { RENDERING_DEFAULTS
|
|
14461
|
-
function
|
|
14250
|
+
const { RENDERING_DEFAULTS } = esm.CONSTANTS;
|
|
14251
|
+
function defaultReferenceLineColor() {
|
|
14462
14252
|
return 'rgb(0, 200, 0)';
|
|
14463
14253
|
}
|
|
14464
|
-
function
|
|
14254
|
+
function defaultReferenceLineControllable() {
|
|
14465
14255
|
return true;
|
|
14466
14256
|
}
|
|
14467
14257
|
function defaultReferenceLineDraggableRotatable() {
|
|
@@ -15571,10 +15361,10 @@ class CrosshairsTool extends base/* AnnotationTool */.EC {
|
|
|
15571
15361
|
slabThicknessValue += mod;
|
|
15572
15362
|
}
|
|
15573
15363
|
slabThicknessValue = Math.abs(slabThicknessValue);
|
|
15574
|
-
slabThicknessValue = Math.max(
|
|
15364
|
+
slabThicknessValue = Math.max(RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS, slabThicknessValue);
|
|
15575
15365
|
const near = this._pointNearReferenceLine(viewportAnnotation, canvasCoords, 6, otherViewport);
|
|
15576
15366
|
if (near) {
|
|
15577
|
-
slabThicknessValue =
|
|
15367
|
+
slabThicknessValue = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;
|
|
15578
15368
|
}
|
|
15579
15369
|
const toolGroup = (0,ToolGroupManager.getToolGroupForViewport)(otherViewport.id, renderingEngine.id);
|
|
15580
15370
|
const crosshairsInstance = toolGroup.getToolInstance(this.getToolName());
|
|
@@ -15799,10 +15589,10 @@ class CrosshairsTool extends base/* AnnotationTool */.EC {
|
|
|
15799
15589
|
};
|
|
15800
15590
|
this._getReferenceLineColor =
|
|
15801
15591
|
toolProps.configuration?.getReferenceLineColor ||
|
|
15802
|
-
|
|
15592
|
+
defaultReferenceLineColor;
|
|
15803
15593
|
this._getReferenceLineControllable =
|
|
15804
15594
|
toolProps.configuration?.getReferenceLineControllable ||
|
|
15805
|
-
|
|
15595
|
+
defaultReferenceLineControllable;
|
|
15806
15596
|
this._getReferenceLineDraggableRotatable =
|
|
15807
15597
|
toolProps.configuration?.getReferenceLineDraggableRotatable ||
|
|
15808
15598
|
defaultReferenceLineDraggableRotatable;
|
|
@@ -15978,7 +15768,7 @@ class CrosshairsTool extends base/* AnnotationTool */.EC {
|
|
|
15978
15768
|
actorUIDs = filterActorUIDsToSetSlabThickness;
|
|
15979
15769
|
}
|
|
15980
15770
|
let blendModeToUse = this.configuration.slabThicknessBlendMode;
|
|
15981
|
-
if (slabThickness ===
|
|
15771
|
+
if (slabThickness === RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS) {
|
|
15982
15772
|
blendModeToUse = esm.Enums.BlendModes.COMPOSITE;
|
|
15983
15773
|
}
|
|
15984
15774
|
const immediate = false;
|
|
@@ -29212,8 +29002,8 @@ PaintFillTool.toolName = 'PaintFill';
|
|
|
29212
29002
|
|
|
29213
29003
|
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Interaction/Widgets/OrientationMarkerWidget.js + 1 modules
|
|
29214
29004
|
var OrientationMarkerWidget = __webpack_require__(53489);
|
|
29215
|
-
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/AnnotatedCubeActor.js +
|
|
29216
|
-
var AnnotatedCubeActor = __webpack_require__(
|
|
29005
|
+
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/AnnotatedCubeActor.js + 1 modules
|
|
29006
|
+
var AnnotatedCubeActor = __webpack_require__(91960);
|
|
29217
29007
|
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/AxesActor.js + 4 modules
|
|
29218
29008
|
var AxesActor = __webpack_require__(10341);
|
|
29219
29009
|
// EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/IO/XML/XMLPolyDataReader.js + 4 modules
|
|
@@ -29506,6 +29296,425 @@ class OrientationMarkerTool extends base/* BaseTool */.oS {
|
|
|
29506
29296
|
OrientationMarkerTool.toolName = 'OrientationMarker';
|
|
29507
29297
|
/* harmony default export */ const tools_OrientationMarkerTool = ((/* unused pure expression or super */ null && (OrientationMarkerTool)));
|
|
29508
29298
|
|
|
29299
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/vtkjs/OrientationControllerWidget/index.js + 6 modules
|
|
29300
|
+
var OrientationControllerWidget = __webpack_require__(14770);
|
|
29301
|
+
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/OrientationControllerTool.js
|
|
29302
|
+
|
|
29303
|
+
|
|
29304
|
+
|
|
29305
|
+
|
|
29306
|
+
|
|
29307
|
+
|
|
29308
|
+
const ADD_MARKER_DELAY_MS = 500;
|
|
29309
|
+
const POSITION_RETRY_DELAY_MS = 1000;
|
|
29310
|
+
const FACE_COLOR_SCHEMES = {
|
|
29311
|
+
marker: {
|
|
29312
|
+
topBottom: [0, 0, 255],
|
|
29313
|
+
frontBack: [0, 255, 255],
|
|
29314
|
+
leftRight: [255, 255, 0],
|
|
29315
|
+
},
|
|
29316
|
+
gray: {
|
|
29317
|
+
topBottom: [180, 180, 180],
|
|
29318
|
+
frontBack: [180, 180, 180],
|
|
29319
|
+
leftRight: [180, 180, 180],
|
|
29320
|
+
},
|
|
29321
|
+
rgy: {
|
|
29322
|
+
topBottom: [255, 0, 0],
|
|
29323
|
+
frontBack: [0, 255, 0],
|
|
29324
|
+
leftRight: [255, 255, 0],
|
|
29325
|
+
},
|
|
29326
|
+
};
|
|
29327
|
+
const LETTER_COLOR_SCHEMES = {
|
|
29328
|
+
mixed: {
|
|
29329
|
+
zMinus: [255, 255, 255],
|
|
29330
|
+
zPlus: [255, 255, 255],
|
|
29331
|
+
yMinus: [255, 255, 255],
|
|
29332
|
+
yPlus: [255, 255, 255],
|
|
29333
|
+
xMinus: [0, 0, 0],
|
|
29334
|
+
xPlus: [0, 0, 0],
|
|
29335
|
+
},
|
|
29336
|
+
rgy: {
|
|
29337
|
+
zMinus: [255, 255, 255],
|
|
29338
|
+
zPlus: [255, 255, 255],
|
|
29339
|
+
yMinus: [255, 255, 255],
|
|
29340
|
+
yPlus: [255, 255, 255],
|
|
29341
|
+
xMinus: [0, 0, 0],
|
|
29342
|
+
xPlus: [0, 0, 0],
|
|
29343
|
+
},
|
|
29344
|
+
white: {
|
|
29345
|
+
zMinus: [255, 255, 255],
|
|
29346
|
+
zPlus: [255, 255, 255],
|
|
29347
|
+
yMinus: [255, 255, 255],
|
|
29348
|
+
yPlus: [255, 255, 255],
|
|
29349
|
+
xMinus: [255, 255, 255],
|
|
29350
|
+
xPlus: [255, 255, 255],
|
|
29351
|
+
},
|
|
29352
|
+
black: {
|
|
29353
|
+
zMinus: [0, 0, 0],
|
|
29354
|
+
zPlus: [0, 0, 0],
|
|
29355
|
+
yMinus: [0, 0, 0],
|
|
29356
|
+
yPlus: [0, 0, 0],
|
|
29357
|
+
xMinus: [0, 0, 0],
|
|
29358
|
+
xPlus: [0, 0, 0],
|
|
29359
|
+
},
|
|
29360
|
+
};
|
|
29361
|
+
const DEFAULT_FACE_COLOR_SCHEME = 'rgy';
|
|
29362
|
+
const DEFAULT_LETTER_COLOR_SCHEME = 'mixed';
|
|
29363
|
+
const ANIMATE_RESET_CAMERA_OPTIONS = {
|
|
29364
|
+
resetZoom: false,
|
|
29365
|
+
resetPan: true,
|
|
29366
|
+
resetToCenter: true,
|
|
29367
|
+
};
|
|
29368
|
+
class OrientationControllerTool extends base/* BaseTool */.oS {
|
|
29369
|
+
static { this.toolName = 'OrientationControllerTool'; }
|
|
29370
|
+
constructor(toolProps = {}, defaultToolProps = {
|
|
29371
|
+
supportedInteractionTypes: ['Mouse'],
|
|
29372
|
+
configuration: {
|
|
29373
|
+
enabled: true,
|
|
29374
|
+
opacity: 1.0,
|
|
29375
|
+
size: 0.04,
|
|
29376
|
+
position: 'bottom-right',
|
|
29377
|
+
colorScheme: 'rgy',
|
|
29378
|
+
letterColorScheme: 'mixed',
|
|
29379
|
+
showEdgeFaces: true,
|
|
29380
|
+
showCornerFaces: true,
|
|
29381
|
+
keepOrientationUp: true,
|
|
29382
|
+
},
|
|
29383
|
+
}) {
|
|
29384
|
+
super(toolProps, defaultToolProps);
|
|
29385
|
+
this.widget = new OrientationControllerWidget/* vtkOrientationControllerWidget */.C();
|
|
29386
|
+
this.resizeObservers = new Map();
|
|
29387
|
+
this.cameraHandlers = new Map();
|
|
29388
|
+
this._getViewportsInfo = () => {
|
|
29389
|
+
const viewports = (0,ToolGroupManager.getToolGroup)(this.toolGroupId)?.viewportsInfo;
|
|
29390
|
+
return viewports || [];
|
|
29391
|
+
};
|
|
29392
|
+
this.onSetToolConfiguration = () => {
|
|
29393
|
+
const viewportsInfo = this._getViewportsInfo();
|
|
29394
|
+
const hasActiveMarkers = viewportsInfo.some(({ viewportId }) => {
|
|
29395
|
+
return this.widget.getActors(viewportId) !== null;
|
|
29396
|
+
});
|
|
29397
|
+
if (hasActiveMarkers) {
|
|
29398
|
+
this.removeMarkers();
|
|
29399
|
+
this.addMarkers();
|
|
29400
|
+
}
|
|
29401
|
+
};
|
|
29402
|
+
this.onViewportAdded = (evt) => {
|
|
29403
|
+
const { viewportId, renderingEngineId, toolGroupId } = evt.detail;
|
|
29404
|
+
if (toolGroupId !== this.toolGroupId) {
|
|
29405
|
+
return;
|
|
29406
|
+
}
|
|
29407
|
+
if (this.widget.getActors(viewportId)) {
|
|
29408
|
+
return;
|
|
29409
|
+
}
|
|
29410
|
+
setTimeout(() => {
|
|
29411
|
+
this.addMarkerToViewport(viewportId, renderingEngineId);
|
|
29412
|
+
}, ADD_MARKER_DELAY_MS);
|
|
29413
|
+
};
|
|
29414
|
+
this.onViewportRemoved = (evt) => {
|
|
29415
|
+
const { viewportId, renderingEngineId, toolGroupId } = evt.detail;
|
|
29416
|
+
if (toolGroupId !== this.toolGroupId) {
|
|
29417
|
+
return;
|
|
29418
|
+
}
|
|
29419
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
29420
|
+
if (enabledElement) {
|
|
29421
|
+
const { viewport } = enabledElement;
|
|
29422
|
+
if (viewport.isOrientationChangeable()) {
|
|
29423
|
+
this.widget.removeActorsFromViewport(viewportId, viewport);
|
|
29424
|
+
}
|
|
29425
|
+
const cameraHandler = this.cameraHandlers.get(viewportId);
|
|
29426
|
+
if (cameraHandler) {
|
|
29427
|
+
viewport.element.removeEventListener(esm.Enums.Events.CAMERA_MODIFIED, cameraHandler);
|
|
29428
|
+
this.cameraHandlers.delete(viewportId);
|
|
29429
|
+
}
|
|
29430
|
+
}
|
|
29431
|
+
this.widget.cleanup(viewportId);
|
|
29432
|
+
const resizeObserver = this.resizeObservers.get(viewportId);
|
|
29433
|
+
if (resizeObserver) {
|
|
29434
|
+
resizeObserver.disconnect();
|
|
29435
|
+
this.resizeObservers.delete(viewportId);
|
|
29436
|
+
}
|
|
29437
|
+
};
|
|
29438
|
+
this.addMarkers = () => {
|
|
29439
|
+
const viewportsInfo = this._getViewportsInfo();
|
|
29440
|
+
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
29441
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
29442
|
+
if (!enabledElement) {
|
|
29443
|
+
return;
|
|
29444
|
+
}
|
|
29445
|
+
const { viewport } = enabledElement;
|
|
29446
|
+
if (!viewport.isOrientationChangeable()) {
|
|
29447
|
+
return;
|
|
29448
|
+
}
|
|
29449
|
+
if (this.widget.getActors(viewportId)) {
|
|
29450
|
+
return;
|
|
29451
|
+
}
|
|
29452
|
+
setTimeout(() => {
|
|
29453
|
+
this.addMarkerToViewport(viewportId, renderingEngineId);
|
|
29454
|
+
}, ADD_MARKER_DELAY_MS);
|
|
29455
|
+
});
|
|
29456
|
+
};
|
|
29457
|
+
this.onCameraModified = (evt) => {
|
|
29458
|
+
const { viewportId } = evt.detail;
|
|
29459
|
+
if (!viewportId) {
|
|
29460
|
+
return;
|
|
29461
|
+
}
|
|
29462
|
+
const actors = this.widget.getActors(viewportId);
|
|
29463
|
+
if (!actors) {
|
|
29464
|
+
return;
|
|
29465
|
+
}
|
|
29466
|
+
const viewportsInfo = this._getViewportsInfo();
|
|
29467
|
+
const viewportInfo = viewportsInfo.find((vp) => vp.viewportId === viewportId);
|
|
29468
|
+
if (!viewportInfo) {
|
|
29469
|
+
return;
|
|
29470
|
+
}
|
|
29471
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, viewportInfo.renderingEngineId);
|
|
29472
|
+
if (!enabledElement) {
|
|
29473
|
+
return;
|
|
29474
|
+
}
|
|
29475
|
+
const { viewport } = enabledElement;
|
|
29476
|
+
if (!viewport.isOrientationChangeable()) {
|
|
29477
|
+
return;
|
|
29478
|
+
}
|
|
29479
|
+
const volumeViewport = viewport;
|
|
29480
|
+
this.widget.positionActors(volumeViewport, actors, this.getPositionConfig());
|
|
29481
|
+
viewport.render();
|
|
29482
|
+
};
|
|
29483
|
+
}
|
|
29484
|
+
getPositionConfig() {
|
|
29485
|
+
return {
|
|
29486
|
+
position: this.configuration.position || 'bottom-right',
|
|
29487
|
+
size: this.configuration.size || 0.04,
|
|
29488
|
+
};
|
|
29489
|
+
}
|
|
29490
|
+
getFaceColors() {
|
|
29491
|
+
const colorScheme = this.configuration.colorScheme || 'rgy';
|
|
29492
|
+
if (this.configuration.faceColors) {
|
|
29493
|
+
const provided = this.configuration.faceColors;
|
|
29494
|
+
if (provided.topBottom && provided.frontBack && provided.leftRight) {
|
|
29495
|
+
return {
|
|
29496
|
+
topBottom: provided.topBottom,
|
|
29497
|
+
frontBack: provided.frontBack,
|
|
29498
|
+
leftRight: provided.leftRight,
|
|
29499
|
+
};
|
|
29500
|
+
}
|
|
29501
|
+
}
|
|
29502
|
+
return (FACE_COLOR_SCHEMES[colorScheme] ??
|
|
29503
|
+
FACE_COLOR_SCHEMES[DEFAULT_FACE_COLOR_SCHEME]);
|
|
29504
|
+
}
|
|
29505
|
+
getLetterColors() {
|
|
29506
|
+
const letterColorScheme = this.configuration.letterColorScheme || 'mixed';
|
|
29507
|
+
return (LETTER_COLOR_SCHEMES[letterColorScheme] ??
|
|
29508
|
+
LETTER_COLOR_SCHEMES[DEFAULT_LETTER_COLOR_SCHEME]);
|
|
29509
|
+
}
|
|
29510
|
+
onSetToolEnabled() {
|
|
29511
|
+
this.removeMarkers();
|
|
29512
|
+
this.addMarkers();
|
|
29513
|
+
esm.eventTarget.addEventListener(enums.Events.TOOLGROUP_VIEWPORT_ADDED, this.onViewportAdded);
|
|
29514
|
+
esm.eventTarget.addEventListener(enums.Events.TOOLGROUP_VIEWPORT_REMOVED, this.onViewportRemoved);
|
|
29515
|
+
}
|
|
29516
|
+
onSetToolDisabled() {
|
|
29517
|
+
this.removeMarkers();
|
|
29518
|
+
esm.eventTarget.removeEventListener(enums.Events.TOOLGROUP_VIEWPORT_ADDED, this.onViewportAdded);
|
|
29519
|
+
esm.eventTarget.removeEventListener(enums.Events.TOOLGROUP_VIEWPORT_REMOVED, this.onViewportRemoved);
|
|
29520
|
+
}
|
|
29521
|
+
removeMarkers() {
|
|
29522
|
+
const viewportsInfo = this._getViewportsInfo();
|
|
29523
|
+
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
29524
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
29525
|
+
if (enabledElement) {
|
|
29526
|
+
const { viewport } = enabledElement;
|
|
29527
|
+
if (viewport.isOrientationChangeable()) {
|
|
29528
|
+
this.widget.removeActorsFromViewport(viewportId, viewport);
|
|
29529
|
+
}
|
|
29530
|
+
const cameraHandler = this.cameraHandlers.get(viewportId);
|
|
29531
|
+
if (cameraHandler) {
|
|
29532
|
+
viewport.element.removeEventListener(esm.Enums.Events.CAMERA_MODIFIED, cameraHandler);
|
|
29533
|
+
this.cameraHandlers.delete(viewportId);
|
|
29534
|
+
}
|
|
29535
|
+
}
|
|
29536
|
+
const resizeObserver = this.resizeObservers.get(viewportId);
|
|
29537
|
+
if (resizeObserver) {
|
|
29538
|
+
resizeObserver.disconnect();
|
|
29539
|
+
this.resizeObservers.delete(viewportId);
|
|
29540
|
+
}
|
|
29541
|
+
});
|
|
29542
|
+
this.widget.cleanup();
|
|
29543
|
+
this.resizeObservers.forEach((observer) => observer.disconnect());
|
|
29544
|
+
this.resizeObservers.clear();
|
|
29545
|
+
this.cameraHandlers.clear();
|
|
29546
|
+
}
|
|
29547
|
+
createAnnotatedRhombActor() {
|
|
29548
|
+
const faceColors = this.getFaceColors();
|
|
29549
|
+
const letterColors = this.getLetterColors();
|
|
29550
|
+
return this.widget.createActors({
|
|
29551
|
+
faceColors,
|
|
29552
|
+
letterColors,
|
|
29553
|
+
opacity: this.configuration.opacity ?? 1.0,
|
|
29554
|
+
showEdgeFaces: this.configuration.showEdgeFaces !== false,
|
|
29555
|
+
showCornerFaces: this.configuration.showCornerFaces !== false,
|
|
29556
|
+
});
|
|
29557
|
+
}
|
|
29558
|
+
addMarkerToViewport(viewportId, renderingEngineId) {
|
|
29559
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
29560
|
+
if (!enabledElement) {
|
|
29561
|
+
console.warn('OrientationControllerTool: No enabled element found');
|
|
29562
|
+
return;
|
|
29563
|
+
}
|
|
29564
|
+
const { viewport } = enabledElement;
|
|
29565
|
+
if (!viewport.isOrientationChangeable()) {
|
|
29566
|
+
console.warn('OrientationControllerTool: Viewport does not support orientation changes');
|
|
29567
|
+
return;
|
|
29568
|
+
}
|
|
29569
|
+
const element = viewport.element;
|
|
29570
|
+
const volumeViewport = viewport;
|
|
29571
|
+
const actors = this.createAnnotatedRhombActor();
|
|
29572
|
+
this.widget.addActorsToViewport(viewportId, volumeViewport, actors);
|
|
29573
|
+
const positioned = this.widget.positionActors(volumeViewport, actors, this.getPositionConfig());
|
|
29574
|
+
if (!positioned) {
|
|
29575
|
+
console.warn('OrientationControllerTool: Initial positioning failed, retrying...');
|
|
29576
|
+
setTimeout(() => {
|
|
29577
|
+
const repositioned = this.widget.positionActors(volumeViewport, actors, this.getPositionConfig());
|
|
29578
|
+
if (repositioned) {
|
|
29579
|
+
viewport.render();
|
|
29580
|
+
}
|
|
29581
|
+
else {
|
|
29582
|
+
console.error('OrientationControllerTool: Retry positioning also failed');
|
|
29583
|
+
}
|
|
29584
|
+
}, POSITION_RETRY_DELAY_MS);
|
|
29585
|
+
}
|
|
29586
|
+
else {
|
|
29587
|
+
viewport.render();
|
|
29588
|
+
}
|
|
29589
|
+
this.widget.syncOverlayViewport(viewportId, volumeViewport);
|
|
29590
|
+
this.widget.setupPicker(viewportId, actors);
|
|
29591
|
+
this.widget.setupMouseHandlers(viewportId, element, volumeViewport, actors, {
|
|
29592
|
+
onFacePicked: (result) => {
|
|
29593
|
+
const orientation = this.widget.getOrientationForFace(result.cellId);
|
|
29594
|
+
if (orientation) {
|
|
29595
|
+
this.animateCameraToOrientation(volumeViewport, orientation.viewPlaneNormal, orientation.viewUp);
|
|
29596
|
+
}
|
|
29597
|
+
},
|
|
29598
|
+
onFaceHover: (result) => {
|
|
29599
|
+
if (result && result.actorIndex !== 0) {
|
|
29600
|
+
this.widget.highlightFace(result.pickedActor, result.cellId, volumeViewport, false);
|
|
29601
|
+
}
|
|
29602
|
+
else {
|
|
29603
|
+
this.widget.clearHighlight();
|
|
29604
|
+
}
|
|
29605
|
+
},
|
|
29606
|
+
});
|
|
29607
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
29608
|
+
this.updateMarkerPosition(viewportId, renderingEngineId);
|
|
29609
|
+
});
|
|
29610
|
+
resizeObserver.observe(element);
|
|
29611
|
+
this.resizeObservers.set(viewportId, resizeObserver);
|
|
29612
|
+
const cameraHandler = (evt) => {
|
|
29613
|
+
const detail = evt.detail;
|
|
29614
|
+
if (detail.viewportId === viewportId) {
|
|
29615
|
+
this.onCameraModified(evt);
|
|
29616
|
+
}
|
|
29617
|
+
};
|
|
29618
|
+
element.addEventListener(esm.Enums.Events.CAMERA_MODIFIED, cameraHandler);
|
|
29619
|
+
this.cameraHandlers.set(viewportId, cameraHandler);
|
|
29620
|
+
}
|
|
29621
|
+
updateMarkerPosition(viewportId, renderingEngineId) {
|
|
29622
|
+
const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
|
|
29623
|
+
if (!enabledElement) {
|
|
29624
|
+
return;
|
|
29625
|
+
}
|
|
29626
|
+
const actors = this.widget.getActors(viewportId);
|
|
29627
|
+
if (!actors) {
|
|
29628
|
+
return;
|
|
29629
|
+
}
|
|
29630
|
+
const { viewport } = enabledElement;
|
|
29631
|
+
if (!viewport.isOrientationChangeable()) {
|
|
29632
|
+
return;
|
|
29633
|
+
}
|
|
29634
|
+
this.widget.positionActors(viewport, actors, this.getPositionConfig());
|
|
29635
|
+
this.widget.syncOverlayViewport(viewportId, viewport);
|
|
29636
|
+
viewport.render();
|
|
29637
|
+
}
|
|
29638
|
+
animateCameraToOrientation(viewport, targetViewPlaneNormal, targetViewUp) {
|
|
29639
|
+
const keepOrientationUp = this.configuration.keepOrientationUp !== false;
|
|
29640
|
+
const renderer = viewport.getRenderer();
|
|
29641
|
+
const camera = renderer.getActiveCamera();
|
|
29642
|
+
const directionOfProjection = camera.getDirectionOfProjection();
|
|
29643
|
+
const startViewUpArray = camera.getViewUp();
|
|
29644
|
+
const startForward = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(-directionOfProjection[0], -directionOfProjection[1], -directionOfProjection[2]);
|
|
29645
|
+
const startUp = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(startViewUpArray[0], startViewUpArray[1], startViewUpArray[2]);
|
|
29646
|
+
const startRight = gl_matrix_esm/* vec3.create */.eR.create();
|
|
29647
|
+
gl_matrix_esm/* vec3.cross */.eR.cross(startRight, startUp, startForward);
|
|
29648
|
+
gl_matrix_esm/* vec3.normalize */.eR.normalize(startRight, startRight);
|
|
29649
|
+
const startMatrix = gl_matrix_esm/* mat4.fromValues */.pB.fromValues(startRight[0], startRight[1], startRight[2], 0, startUp[0], startUp[1], startUp[2], 0, startForward[0], startForward[1], startForward[2], 0, 0, 0, 0, 1);
|
|
29650
|
+
let targetUp;
|
|
29651
|
+
if (keepOrientationUp) {
|
|
29652
|
+
targetUp = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(targetViewUp[0], targetViewUp[1], targetViewUp[2]);
|
|
29653
|
+
}
|
|
29654
|
+
else {
|
|
29655
|
+
const currentUp = gl_matrix_esm/* vec3.normalize */.eR.normalize(gl_matrix_esm/* vec3.create */.eR.create(), startUp);
|
|
29656
|
+
const normalizedForward = gl_matrix_esm/* vec3.create */.eR.create();
|
|
29657
|
+
gl_matrix_esm/* vec3.normalize */.eR.normalize(normalizedForward, targetViewPlaneNormal);
|
|
29658
|
+
const dot = gl_matrix_esm/* vec3.dot */.eR.dot(currentUp, normalizedForward);
|
|
29659
|
+
targetUp = gl_matrix_esm/* vec3.create */.eR.create();
|
|
29660
|
+
gl_matrix_esm/* vec3.scaleAndAdd */.eR.scaleAndAdd(targetUp, currentUp, normalizedForward, -dot);
|
|
29661
|
+
gl_matrix_esm/* vec3.normalize */.eR.normalize(targetUp, targetUp);
|
|
29662
|
+
if (gl_matrix_esm/* vec3.length */.eR.length(targetUp) < 0.001) {
|
|
29663
|
+
if (Math.abs(normalizedForward[2]) < 0.9) {
|
|
29664
|
+
targetUp = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(0, 0, 1);
|
|
29665
|
+
}
|
|
29666
|
+
else {
|
|
29667
|
+
targetUp = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(0, 1, 0);
|
|
29668
|
+
}
|
|
29669
|
+
const dot2 = gl_matrix_esm/* vec3.dot */.eR.dot(targetUp, normalizedForward);
|
|
29670
|
+
gl_matrix_esm/* vec3.scaleAndAdd */.eR.scaleAndAdd(targetUp, targetUp, normalizedForward, -dot2);
|
|
29671
|
+
gl_matrix_esm/* vec3.normalize */.eR.normalize(targetUp, targetUp);
|
|
29672
|
+
}
|
|
29673
|
+
}
|
|
29674
|
+
const targetRight = gl_matrix_esm/* vec3.create */.eR.create();
|
|
29675
|
+
gl_matrix_esm/* vec3.cross */.eR.cross(targetRight, targetUp, targetViewPlaneNormal);
|
|
29676
|
+
gl_matrix_esm/* vec3.normalize */.eR.normalize(targetRight, targetRight);
|
|
29677
|
+
const targetMatrix = gl_matrix_esm/* mat4.fromValues */.pB.fromValues(targetRight[0], targetRight[1], targetRight[2], 0, targetUp[0], targetUp[1], targetUp[2], 0, targetViewPlaneNormal[0], targetViewPlaneNormal[1], targetViewPlaneNormal[2], 0, 0, 0, 0, 1);
|
|
29678
|
+
const startQuat = gl_matrix_esm/* mat4.getRotation */.pB.getRotation(gl_matrix_esm/* quat.create */.Yu.create(), startMatrix);
|
|
29679
|
+
const targetQuat = gl_matrix_esm/* mat4.getRotation */.pB.getRotation(gl_matrix_esm/* quat.create */.Yu.create(), targetMatrix);
|
|
29680
|
+
let dotProduct = gl_matrix_esm/* quat.dot */.Yu.dot(startQuat, targetQuat);
|
|
29681
|
+
if (dotProduct < 0) {
|
|
29682
|
+
gl_matrix_esm/* quat.scale */.Yu.scale(targetQuat, targetQuat, -1);
|
|
29683
|
+
dotProduct = -dotProduct;
|
|
29684
|
+
}
|
|
29685
|
+
const threshold = 0.99996;
|
|
29686
|
+
if (dotProduct > threshold) {
|
|
29687
|
+
return;
|
|
29688
|
+
}
|
|
29689
|
+
const steps = 10;
|
|
29690
|
+
const duration = 150;
|
|
29691
|
+
const stepDuration = duration / steps;
|
|
29692
|
+
let currentStep = 0;
|
|
29693
|
+
const animate = () => {
|
|
29694
|
+
currentStep++;
|
|
29695
|
+
const t = currentStep / steps;
|
|
29696
|
+
const easedT = t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
|
|
29697
|
+
const interpolatedQuat = gl_matrix_esm/* quat.create */.Yu.create();
|
|
29698
|
+
gl_matrix_esm/* quat.slerp */.Yu.slerp(interpolatedQuat, startQuat, targetQuat, easedT);
|
|
29699
|
+
const interpolatedMatrix = gl_matrix_esm/* mat4.create */.pB.create();
|
|
29700
|
+
gl_matrix_esm/* mat4.fromQuat */.pB.fromQuat(interpolatedMatrix, interpolatedQuat);
|
|
29701
|
+
const interpolatedForward = interpolatedMatrix.slice(8, 11);
|
|
29702
|
+
const interpolatedUp = interpolatedMatrix.slice(4, 7);
|
|
29703
|
+
viewport.setCamera({
|
|
29704
|
+
viewPlaneNormal: interpolatedForward,
|
|
29705
|
+
viewUp: interpolatedUp,
|
|
29706
|
+
});
|
|
29707
|
+
viewport.resetCamera(ANIMATE_RESET_CAMERA_OPTIONS);
|
|
29708
|
+
viewport.render();
|
|
29709
|
+
if (currentStep < steps) {
|
|
29710
|
+
setTimeout(animate, stepDuration);
|
|
29711
|
+
}
|
|
29712
|
+
};
|
|
29713
|
+
animate();
|
|
29714
|
+
}
|
|
29715
|
+
}
|
|
29716
|
+
/* harmony default export */ const tools_OrientationControllerTool = ((/* unused pure expression or super */ null && (OrientationControllerTool)));
|
|
29717
|
+
|
|
29509
29718
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/activeSegmentation.js + 1 modules
|
|
29510
29719
|
var segmentation_activeSegmentation = __webpack_require__(26228);
|
|
29511
29720
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/segmentIndex.js
|
|
@@ -30195,6 +30404,7 @@ class LabelMapEditWithContourTool extends PlanarFreehandContourSegmentationTool/
|
|
|
30195
30404
|
|
|
30196
30405
|
|
|
30197
30406
|
|
|
30407
|
+
|
|
30198
30408
|
|
|
30199
30409
|
|
|
30200
30410
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/math/rectangle/index.js
|
|
@@ -33822,6 +34032,7 @@ function normalizeSegmentationInput(segmentationInput) {
|
|
|
33822
34032
|
return {
|
|
33823
34033
|
segmentationId,
|
|
33824
34034
|
label: config?.label ?? null,
|
|
34035
|
+
fallbackLabel: config?.fallbackLabel ?? null,
|
|
33825
34036
|
cachedStats: config?.cachedStats ?? {},
|
|
33826
34037
|
segments: normalizedSegments,
|
|
33827
34038
|
representationData: {
|