@cornerstonejs/adapters 1.51.5 → 1.53.0
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/adapters.es.js +499 -129
- package/dist/adapters.es.js.map +1 -1
- package/package.json +5 -5
package/dist/adapters.es.js
CHANGED
|
@@ -38144,6 +38144,164 @@ function applyPointsToPiecewiseFunction(points, range, pwf) {
|
|
|
38144
38144
|
return rescaled;
|
|
38145
38145
|
}
|
|
38146
38146
|
|
|
38147
|
+
let PointsManager$2 = class PointsManager {
|
|
38148
|
+
constructor(configuration = {}) {
|
|
38149
|
+
this._dimensions = 3;
|
|
38150
|
+
this._length = 0;
|
|
38151
|
+
this._byteSize = 4;
|
|
38152
|
+
this.growSize = 128;
|
|
38153
|
+
const {
|
|
38154
|
+
initialSize = 1024,
|
|
38155
|
+
dimensions = 3,
|
|
38156
|
+
growSize = 128
|
|
38157
|
+
} = configuration;
|
|
38158
|
+
const itemLength = initialSize * dimensions;
|
|
38159
|
+
this.growSize = growSize;
|
|
38160
|
+
this.array = new ArrayBuffer(itemLength * this._byteSize);
|
|
38161
|
+
this.data = new Float32Array(this.array);
|
|
38162
|
+
this._dimensions = dimensions;
|
|
38163
|
+
}
|
|
38164
|
+
forEach(func) {
|
|
38165
|
+
for (let i = 0; i < this._length; i++) {
|
|
38166
|
+
func(this.getPoint(i), i);
|
|
38167
|
+
}
|
|
38168
|
+
}
|
|
38169
|
+
get length() {
|
|
38170
|
+
return this._length;
|
|
38171
|
+
}
|
|
38172
|
+
get dimensions() {
|
|
38173
|
+
return this._dimensions;
|
|
38174
|
+
}
|
|
38175
|
+
get dimensionLength() {
|
|
38176
|
+
return this._length * this._dimensions;
|
|
38177
|
+
}
|
|
38178
|
+
getPoint(index) {
|
|
38179
|
+
if (index < 0) {
|
|
38180
|
+
index += this._length;
|
|
38181
|
+
}
|
|
38182
|
+
if (index < 0 || index >= this._length) {
|
|
38183
|
+
return;
|
|
38184
|
+
}
|
|
38185
|
+
const offset = this._dimensions * index;
|
|
38186
|
+
return this.data.subarray(offset, offset + this._dimensions);
|
|
38187
|
+
}
|
|
38188
|
+
getPointArray(index) {
|
|
38189
|
+
const array = [];
|
|
38190
|
+
if (index < 0) {
|
|
38191
|
+
index += this._length;
|
|
38192
|
+
}
|
|
38193
|
+
if (index < 0 || index >= this._length) {
|
|
38194
|
+
return;
|
|
38195
|
+
}
|
|
38196
|
+
const offset = this._dimensions * index;
|
|
38197
|
+
for (let i = 0; i < this._dimensions; i++) {
|
|
38198
|
+
array.push(this.data[i + offset]);
|
|
38199
|
+
}
|
|
38200
|
+
return array;
|
|
38201
|
+
}
|
|
38202
|
+
grow(additionalSize = 1, growSize = this.growSize) {
|
|
38203
|
+
if (this.dimensionLength + additionalSize * this._dimensions <= this.data.length) {
|
|
38204
|
+
return;
|
|
38205
|
+
}
|
|
38206
|
+
const newSize = this.data.length + growSize;
|
|
38207
|
+
const newArray = new ArrayBuffer(newSize * this._dimensions * this._byteSize);
|
|
38208
|
+
const newData = new Float32Array(newArray);
|
|
38209
|
+
newData.set(this.data);
|
|
38210
|
+
this.data = newData;
|
|
38211
|
+
this.array = newArray;
|
|
38212
|
+
}
|
|
38213
|
+
reverse() {
|
|
38214
|
+
const midLength = Math.floor(this._length / 2);
|
|
38215
|
+
for (let i = 0; i < midLength; i++) {
|
|
38216
|
+
const indexStart = i * this._dimensions;
|
|
38217
|
+
const indexEnd = (this._length - 1 - i) * this._dimensions;
|
|
38218
|
+
for (let dimension = 0; dimension < this._dimensions; dimension++) {
|
|
38219
|
+
const valueStart = this.data[indexStart + dimension];
|
|
38220
|
+
this.data[indexStart + dimension] = this.data[indexEnd + dimension];
|
|
38221
|
+
this.data[indexEnd + dimension] = valueStart;
|
|
38222
|
+
}
|
|
38223
|
+
}
|
|
38224
|
+
}
|
|
38225
|
+
push(point) {
|
|
38226
|
+
this.grow(1);
|
|
38227
|
+
const offset = this.length * this._dimensions;
|
|
38228
|
+
for (let i = 0; i < this._dimensions; i++) {
|
|
38229
|
+
this.data[i + offset] = point[i];
|
|
38230
|
+
}
|
|
38231
|
+
this._length++;
|
|
38232
|
+
}
|
|
38233
|
+
map(f) {
|
|
38234
|
+
const mapData = [];
|
|
38235
|
+
for (let i = 0; i < this._length; i++) {
|
|
38236
|
+
mapData.push(f(this.getPoint(i), i));
|
|
38237
|
+
}
|
|
38238
|
+
return mapData;
|
|
38239
|
+
}
|
|
38240
|
+
get points() {
|
|
38241
|
+
return this.map(p => p);
|
|
38242
|
+
}
|
|
38243
|
+
toXYZ() {
|
|
38244
|
+
const xyz = {
|
|
38245
|
+
x: [],
|
|
38246
|
+
y: []
|
|
38247
|
+
};
|
|
38248
|
+
if (this._dimensions >= 3) {
|
|
38249
|
+
xyz.z = [];
|
|
38250
|
+
}
|
|
38251
|
+
const {
|
|
38252
|
+
x,
|
|
38253
|
+
y,
|
|
38254
|
+
z
|
|
38255
|
+
} = xyz;
|
|
38256
|
+
this.forEach(p => {
|
|
38257
|
+
x.push(p[0]);
|
|
38258
|
+
y.push(p[1]);
|
|
38259
|
+
if (z) {
|
|
38260
|
+
z.push(p[2]);
|
|
38261
|
+
}
|
|
38262
|
+
});
|
|
38263
|
+
return xyz;
|
|
38264
|
+
}
|
|
38265
|
+
static fromXYZ({
|
|
38266
|
+
x,
|
|
38267
|
+
y,
|
|
38268
|
+
z
|
|
38269
|
+
}) {
|
|
38270
|
+
const array = PointsManager.create3(x.length);
|
|
38271
|
+
let offset = 0;
|
|
38272
|
+
for (let i = 0; i < x.length; i++) {
|
|
38273
|
+
array.data[offset++] = x[i];
|
|
38274
|
+
array.data[offset++] = y[i];
|
|
38275
|
+
array.data[offset++] = z ? z[i] : 0;
|
|
38276
|
+
}
|
|
38277
|
+
array._length = x.length;
|
|
38278
|
+
return array;
|
|
38279
|
+
}
|
|
38280
|
+
subselect(count = 10, offset = 0) {
|
|
38281
|
+
const selected = new PointsManager({
|
|
38282
|
+
initialSize: count,
|
|
38283
|
+
dimensions: this._dimensions
|
|
38284
|
+
});
|
|
38285
|
+
for (let i = 0; i < count; i++) {
|
|
38286
|
+
const index = (offset + Math.floor(this.length * i / count)) % this.length;
|
|
38287
|
+
selected.push(this.getPoint(index));
|
|
38288
|
+
}
|
|
38289
|
+
return selected;
|
|
38290
|
+
}
|
|
38291
|
+
static create3(initialSize = 128) {
|
|
38292
|
+
return new PointsManager({
|
|
38293
|
+
initialSize,
|
|
38294
|
+
dimensions: 3
|
|
38295
|
+
});
|
|
38296
|
+
}
|
|
38297
|
+
static create2(initialSize = 128) {
|
|
38298
|
+
return new PointsManager({
|
|
38299
|
+
initialSize,
|
|
38300
|
+
dimensions: 2
|
|
38301
|
+
});
|
|
38302
|
+
}
|
|
38303
|
+
};
|
|
38304
|
+
|
|
38147
38305
|
const isMergeableObject = val => {
|
|
38148
38306
|
const nonNullObject = val && typeof val === 'object';
|
|
38149
38307
|
return nonNullObject && Object.prototype.toString.call(val) !== '[object RegExp]' && Object.prototype.toString.call(val) !== '[object Date]';
|
|
@@ -42216,6 +42374,7 @@ var colormap = /*#__PURE__*/Object.freeze({
|
|
|
42216
42374
|
|
|
42217
42375
|
var utilities = /*#__PURE__*/Object.freeze({
|
|
42218
42376
|
__proto__: null,
|
|
42377
|
+
PointsManager: PointsManager$2,
|
|
42219
42378
|
ProgressiveIterator: ProgressiveIterator,
|
|
42220
42379
|
VoxelManager: VoxelManager,
|
|
42221
42380
|
actorIsA: actorIsA,
|
|
@@ -45160,7 +45319,9 @@ class StackViewport extends Viewport$1 {
|
|
|
45160
45319
|
}
|
|
45161
45320
|
const csImgFrame = this.csImage?.imageFrame;
|
|
45162
45321
|
const imgFrame = image?.imageFrame;
|
|
45163
|
-
|
|
45322
|
+
const photometricInterpretation = csImgFrame?.photometricInterpretation || this.csImage?.photometricInterpretation;
|
|
45323
|
+
const newPhotometricInterpretation = imgFrame?.photometricInterpretation || image?.photometricInterpretation;
|
|
45324
|
+
if (photometricInterpretation !== newPhotometricInterpretation) {
|
|
45164
45325
|
this.stackInvalidated = true;
|
|
45165
45326
|
}
|
|
45166
45327
|
this._setCSImage(image);
|
|
@@ -47039,6 +47200,7 @@ var ChangeTypes;
|
|
|
47039
47200
|
ChangeTypes["StatsUpdated"] = "StatsUpdated";
|
|
47040
47201
|
ChangeTypes["InitialSetup"] = "InitialSetup";
|
|
47041
47202
|
ChangeTypes["Completed"] = "Completed";
|
|
47203
|
+
ChangeTypes["InterpolationUpdated"] = "InterpolationUpdated";
|
|
47042
47204
|
})(ChangeTypes || (ChangeTypes = {}));
|
|
47043
47205
|
var ChangeTypes$1 = ChangeTypes;
|
|
47044
47206
|
|
|
@@ -48208,6 +48370,100 @@ let AnnotationToPointData$1 = class AnnotationToPointData {
|
|
|
48208
48370
|
AnnotationToPointData$1.register(RectangleROIStartEndThreshold$1);
|
|
48209
48371
|
var AnnotationToPointData$2 = AnnotationToPointData$1;
|
|
48210
48372
|
|
|
48373
|
+
function getContourHolesDataWorld(annotation) {
|
|
48374
|
+
const childAnnotationUIDs = annotation.childAnnotationUIDs ?? [];
|
|
48375
|
+
return childAnnotationUIDs.map(uid => getAnnotation(uid).data.contour.polyline);
|
|
48376
|
+
}
|
|
48377
|
+
|
|
48378
|
+
function getContourHolesDataCanvas(annotation, viewport) {
|
|
48379
|
+
const worldHoleContours = getContourHolesDataWorld(annotation);
|
|
48380
|
+
const canvasHoleContours = [];
|
|
48381
|
+
worldHoleContours.forEach(worldHoleContour => {
|
|
48382
|
+
const numPoints = worldHoleContour.length;
|
|
48383
|
+
const canvasHoleContour = new Array(numPoints);
|
|
48384
|
+
for (let i = 0; i < numPoints; i++) {
|
|
48385
|
+
canvasHoleContour[i] = viewport.worldToCanvas(worldHoleContour[i]);
|
|
48386
|
+
}
|
|
48387
|
+
canvasHoleContours.push(canvasHoleContour);
|
|
48388
|
+
});
|
|
48389
|
+
return canvasHoleContours;
|
|
48390
|
+
}
|
|
48391
|
+
|
|
48392
|
+
function distanceToPointSquared(p1, p2) {
|
|
48393
|
+
if (p1.length !== p2.length) {
|
|
48394
|
+
throw Error('Both points should have the same dimensionality');
|
|
48395
|
+
}
|
|
48396
|
+
const [x1, y1, z1 = 0] = p1;
|
|
48397
|
+
const [x2, y2, z2 = 0] = p2;
|
|
48398
|
+
const dx = x2 - x1;
|
|
48399
|
+
const dy = y2 - y1;
|
|
48400
|
+
const dz = z2 - z1;
|
|
48401
|
+
return dx * dx + dy * dy + dz * dz;
|
|
48402
|
+
}
|
|
48403
|
+
|
|
48404
|
+
function getSignedArea(polyline) {
|
|
48405
|
+
const refPoint = polyline[0];
|
|
48406
|
+
let area = 0;
|
|
48407
|
+
for (let i = 0, len = polyline.length; i < len; i++) {
|
|
48408
|
+
const p1 = polyline[i];
|
|
48409
|
+
const p2Index = i === len - 1 ? 0 : i + 1;
|
|
48410
|
+
const p2 = polyline[p2Index];
|
|
48411
|
+
const aX = p1[0] - refPoint[0];
|
|
48412
|
+
const aY = p1[1] - refPoint[1];
|
|
48413
|
+
const bX = p2[0] - refPoint[0];
|
|
48414
|
+
const bY = p2[1] - refPoint[1];
|
|
48415
|
+
area += aX * bY - aY * bX;
|
|
48416
|
+
}
|
|
48417
|
+
area *= 0.5;
|
|
48418
|
+
return area;
|
|
48419
|
+
}
|
|
48420
|
+
|
|
48421
|
+
function getWindingDirection(polyline) {
|
|
48422
|
+
const signedArea = getSignedArea(polyline);
|
|
48423
|
+
return signedArea >= 0 ? 1 : -1;
|
|
48424
|
+
}
|
|
48425
|
+
|
|
48426
|
+
function updateContourPolyline(annotation, polylineData, transforms) {
|
|
48427
|
+
const {
|
|
48428
|
+
canvasToWorld
|
|
48429
|
+
} = transforms;
|
|
48430
|
+
const {
|
|
48431
|
+
data
|
|
48432
|
+
} = annotation;
|
|
48433
|
+
const {
|
|
48434
|
+
points: polyline,
|
|
48435
|
+
targetWindingDirection
|
|
48436
|
+
} = polylineData;
|
|
48437
|
+
let {
|
|
48438
|
+
closed
|
|
48439
|
+
} = polylineData;
|
|
48440
|
+
const numPoints = polyline.length;
|
|
48441
|
+
const polylineWorldPoints = new Array(numPoints);
|
|
48442
|
+
const currentWindingDirection = getWindingDirection(polyline);
|
|
48443
|
+
const parentAnnotation = getParentAnnotation(annotation);
|
|
48444
|
+
if (closed === undefined) {
|
|
48445
|
+
let currentClosedState = false;
|
|
48446
|
+
if (polyline.length > 3) {
|
|
48447
|
+
const lastToFirstDist = distanceToPointSquared(polyline[0], polyline[numPoints - 1]);
|
|
48448
|
+
currentClosedState = isEqual$2(0, lastToFirstDist);
|
|
48449
|
+
}
|
|
48450
|
+
closed = currentClosedState;
|
|
48451
|
+
}
|
|
48452
|
+
let windingDirection = parentAnnotation ? parentAnnotation.data.contour.windingDirection * -1 : targetWindingDirection;
|
|
48453
|
+
if (windingDirection === undefined) {
|
|
48454
|
+
windingDirection = currentWindingDirection;
|
|
48455
|
+
} else if (windingDirection !== currentWindingDirection) {
|
|
48456
|
+
polyline.reverse();
|
|
48457
|
+
}
|
|
48458
|
+
for (let i = 0; i < numPoints; i++) {
|
|
48459
|
+
polylineWorldPoints[i] = canvasToWorld(polyline[i]);
|
|
48460
|
+
}
|
|
48461
|
+
data.contour.polyline = polylineWorldPoints;
|
|
48462
|
+
data.contour.closed = closed;
|
|
48463
|
+
data.contour.windingDirection = windingDirection;
|
|
48464
|
+
invalidateAnnotation(annotation);
|
|
48465
|
+
}
|
|
48466
|
+
|
|
48211
48467
|
function getInterpolationData(viewportData, filterParams = []) {
|
|
48212
48468
|
const {
|
|
48213
48469
|
viewport,
|
|
@@ -48231,7 +48487,9 @@ function getInterpolationData(viewportData, filterParams = []) {
|
|
|
48231
48487
|
return value === x.value;
|
|
48232
48488
|
});
|
|
48233
48489
|
});
|
|
48234
|
-
|
|
48490
|
+
if (filteredInterpolatedAnnotations.length) {
|
|
48491
|
+
interpolationDatas.set(i, filteredInterpolatedAnnotations);
|
|
48492
|
+
}
|
|
48235
48493
|
}
|
|
48236
48494
|
return interpolationDatas;
|
|
48237
48495
|
}
|
|
@@ -48264,7 +48522,8 @@ function createPolylineToolData(polyline, handlePoints, referencedToolData) {
|
|
|
48264
48522
|
});
|
|
48265
48523
|
Object.assign(annotation.data, {
|
|
48266
48524
|
handles: {
|
|
48267
|
-
points: handlePoints || [],
|
|
48525
|
+
points: handlePoints.points || handlePoints || [],
|
|
48526
|
+
interpolationSources: handlePoints.sources,
|
|
48268
48527
|
activeHandleIndex: null,
|
|
48269
48528
|
textBox: {
|
|
48270
48529
|
hasMoved: false,
|
|
@@ -48334,7 +48593,7 @@ function _getSlicePositionOfToolData(interpolationData, annotationUID) {
|
|
|
48334
48593
|
}
|
|
48335
48594
|
function _sliceNeedsInterpolating(interpolationData, sliceIndex) {
|
|
48336
48595
|
const annotations = interpolationData.get(sliceIndex);
|
|
48337
|
-
return !annotations || annotations.length === 1 && annotations[0].autoGenerated;
|
|
48596
|
+
return !annotations?.length || annotations.length === 1 && annotations[0].autoGenerated;
|
|
48338
48597
|
}
|
|
48339
48598
|
function _appendInterpolationList(contourPair, interpolationList, itemIndex) {
|
|
48340
48599
|
const [startIndex] = contourPair;
|
|
@@ -48382,99 +48641,182 @@ function _getBoundingPair(sliceIndex, sliceRange, interpolationData) {
|
|
|
48382
48641
|
return annotationPair;
|
|
48383
48642
|
}
|
|
48384
48643
|
|
|
48385
|
-
|
|
48386
|
-
|
|
48387
|
-
|
|
48388
|
-
|
|
48389
|
-
|
|
48390
|
-
|
|
48391
|
-
|
|
48392
|
-
|
|
48393
|
-
|
|
48394
|
-
|
|
48395
|
-
|
|
48396
|
-
|
|
48397
|
-
|
|
48398
|
-
|
|
48399
|
-
|
|
48400
|
-
|
|
48401
|
-
|
|
48402
|
-
|
|
48403
|
-
|
|
48404
|
-
|
|
48405
|
-
|
|
48406
|
-
|
|
48407
|
-
|
|
48408
|
-
|
|
48409
|
-
|
|
48644
|
+
const {
|
|
48645
|
+
PointsManager: PointsManager$1
|
|
48646
|
+
} = utilities;
|
|
48647
|
+
function selectHandles(polyline, handleCount = 8) {
|
|
48648
|
+
const handles = PointsManager$1.create3(handleCount);
|
|
48649
|
+
handles.sources = [];
|
|
48650
|
+
const {
|
|
48651
|
+
sources: destPoints
|
|
48652
|
+
} = handles;
|
|
48653
|
+
const {
|
|
48654
|
+
length,
|
|
48655
|
+
sources: sourcePoints = []
|
|
48656
|
+
} = polyline;
|
|
48657
|
+
const distance = 6;
|
|
48658
|
+
if (length < distance * 3) {
|
|
48659
|
+
console.log('Adding subselect handles', handleCount, length);
|
|
48660
|
+
return polyline.subselect(handleCount);
|
|
48661
|
+
}
|
|
48662
|
+
const interval = Math.min(30, Math.floor(length / 3));
|
|
48663
|
+
sourcePoints.forEach(() => destPoints.push(PointsManager$1.create3(handleCount)));
|
|
48664
|
+
const dotValues = createDotValues(polyline, distance);
|
|
48665
|
+
const minimumRegions = findMinimumRegions(dotValues, handleCount);
|
|
48666
|
+
const indices = [];
|
|
48667
|
+
if (minimumRegions?.length > 2) {
|
|
48668
|
+
let lastHandle = -1;
|
|
48669
|
+
const thirdInterval = interval / 3;
|
|
48670
|
+
minimumRegions.forEach(region => {
|
|
48671
|
+
const [start,, end] = region;
|
|
48672
|
+
const midIndex = Math.ceil((start + end) / 2);
|
|
48673
|
+
if (end - lastHandle < thirdInterval) {
|
|
48674
|
+
return;
|
|
48675
|
+
}
|
|
48676
|
+
if (midIndex - start > 2 * thirdInterval) {
|
|
48677
|
+
addInterval(indices, lastHandle, start, interval, length);
|
|
48678
|
+
lastHandle = addInterval(indices, start, midIndex, interval, length);
|
|
48679
|
+
} else {
|
|
48680
|
+
lastHandle = addInterval(indices, lastHandle, midIndex, interval, length);
|
|
48681
|
+
}
|
|
48682
|
+
if (end - lastHandle > thirdInterval) {
|
|
48683
|
+
lastHandle = addInterval(indices, lastHandle, end, interval, length);
|
|
48410
48684
|
}
|
|
48685
|
+
});
|
|
48686
|
+
const firstHandle = indices[0];
|
|
48687
|
+
const lastDistance = indexValue(firstHandle + length - lastHandle, length);
|
|
48688
|
+
if (lastDistance > 2 * thirdInterval) {
|
|
48689
|
+
addInterval(indices, lastHandle, firstHandle - thirdInterval, interval, length);
|
|
48411
48690
|
}
|
|
48691
|
+
} else {
|
|
48692
|
+
const interval = Math.floor(length / handleCount);
|
|
48693
|
+
addInterval(indices, -1, length - interval, interval, length);
|
|
48412
48694
|
}
|
|
48413
|
-
|
|
48414
|
-
const
|
|
48415
|
-
|
|
48416
|
-
|
|
48695
|
+
indices.forEach(index => {
|
|
48696
|
+
const point = polyline.getPointArray(index);
|
|
48697
|
+
handles.push(point);
|
|
48698
|
+
sourcePoints.forEach((source, destSourceIndex) => destPoints[destSourceIndex].push(source.getPoint(index)));
|
|
48699
|
+
});
|
|
48700
|
+
return handles;
|
|
48701
|
+
}
|
|
48702
|
+
function createDotValues(polyline, distance = 6) {
|
|
48703
|
+
const {
|
|
48704
|
+
length
|
|
48705
|
+
} = polyline;
|
|
48706
|
+
const prevVec3 = vec3.create();
|
|
48707
|
+
const nextVec3 = vec3.create();
|
|
48708
|
+
const dotValues = new Float32Array(length);
|
|
48709
|
+
for (let i = 0; i < length; i++) {
|
|
48710
|
+
const point = polyline.getPoint(i);
|
|
48711
|
+
const prevPoint = polyline.getPoint(i - distance);
|
|
48712
|
+
const nextPoint = polyline.getPoint((i + distance) % length);
|
|
48713
|
+
vec3.sub(prevVec3, point, prevPoint);
|
|
48714
|
+
vec3.sub(nextVec3, nextPoint, point);
|
|
48715
|
+
const dot = vec3.dot(prevVec3, nextVec3) / (vec3.len(prevVec3) * vec3.len(nextVec3));
|
|
48716
|
+
dotValues[i] = dot;
|
|
48717
|
+
}
|
|
48718
|
+
return dotValues;
|
|
48719
|
+
}
|
|
48720
|
+
function findMinimumRegions(dotValues, handleCount) {
|
|
48721
|
+
const {
|
|
48722
|
+
max,
|
|
48723
|
+
deviation
|
|
48724
|
+
} = getStats(dotValues);
|
|
48725
|
+
const {
|
|
48726
|
+
length
|
|
48727
|
+
} = dotValues;
|
|
48728
|
+
if (deviation < 0.01 || length < handleCount * 3) {
|
|
48729
|
+
return [0, Math.floor(length / 3), Math.floor(length * 2 / 3)];
|
|
48730
|
+
}
|
|
48731
|
+
const inflection = [];
|
|
48732
|
+
let pair = null;
|
|
48733
|
+
let minValue;
|
|
48734
|
+
let minIndex = 0;
|
|
48735
|
+
for (let i = 0; i < length; i++) {
|
|
48736
|
+
const dot = dotValues[i];
|
|
48737
|
+
if (dot < max - deviation) {
|
|
48738
|
+
if (pair) {
|
|
48739
|
+
pair[2] = i;
|
|
48740
|
+
if (dot < minValue) {
|
|
48741
|
+
minValue = dot;
|
|
48742
|
+
minIndex = i;
|
|
48743
|
+
}
|
|
48744
|
+
pair[1] = minIndex;
|
|
48745
|
+
} else {
|
|
48746
|
+
minValue = dot;
|
|
48747
|
+
minIndex = i;
|
|
48748
|
+
pair = [i, i, i];
|
|
48749
|
+
}
|
|
48750
|
+
} else {
|
|
48751
|
+
if (pair) {
|
|
48752
|
+
inflection.push(pair);
|
|
48753
|
+
pair = null;
|
|
48754
|
+
}
|
|
48417
48755
|
}
|
|
48418
|
-
return mapData;
|
|
48419
48756
|
}
|
|
48420
|
-
|
|
48421
|
-
|
|
48422
|
-
|
|
48423
|
-
|
|
48424
|
-
|
|
48425
|
-
|
|
48426
|
-
|
|
48427
|
-
});
|
|
48428
|
-
let offset = 0;
|
|
48429
|
-
for (let i = 0; i < x.length; i++) {
|
|
48430
|
-
array.data[offset++] = x[i];
|
|
48431
|
-
array.data[offset++] = y[i];
|
|
48432
|
-
array.data[offset++] = z[i];
|
|
48757
|
+
if (pair) {
|
|
48758
|
+
if (inflection[0][0] === 0) {
|
|
48759
|
+
inflection[0][0] = pair[0];
|
|
48760
|
+
} else {
|
|
48761
|
+
pair[1] = minIndex;
|
|
48762
|
+
pair[2] = length - 1;
|
|
48763
|
+
inflection.push(pair);
|
|
48433
48764
|
}
|
|
48434
|
-
array.length = x.length;
|
|
48435
|
-
return array;
|
|
48436
48765
|
}
|
|
48766
|
+
return inflection;
|
|
48437
48767
|
}
|
|
48438
|
-
|
|
48439
|
-
|
|
48440
|
-
|
|
48441
|
-
...configuration,
|
|
48442
|
-
dimensions: 3
|
|
48443
|
-
});
|
|
48768
|
+
function addInterval(indices, start, finish, interval, length) {
|
|
48769
|
+
if (finish < start) {
|
|
48770
|
+
finish += length;
|
|
48444
48771
|
}
|
|
48445
|
-
|
|
48446
|
-
|
|
48447
|
-
|
|
48448
|
-
|
|
48449
|
-
|
|
48450
|
-
return;
|
|
48772
|
+
const distance = finish - start;
|
|
48773
|
+
const count = Math.ceil(distance / interval);
|
|
48774
|
+
if (count <= 0) {
|
|
48775
|
+
if (indices[indices.length - 1] !== finish) {
|
|
48776
|
+
indices.push(indexValue(finish, length));
|
|
48451
48777
|
}
|
|
48452
|
-
|
|
48453
|
-
point[0] = this.data[index2];
|
|
48454
|
-
point[1] = this.data[index2 + 1];
|
|
48455
|
-
point[2] = this.data[index2 + 2];
|
|
48456
|
-
return point;
|
|
48778
|
+
return finish;
|
|
48457
48779
|
}
|
|
48458
|
-
|
|
48459
|
-
|
|
48780
|
+
for (let i = 1; i <= count; i++) {
|
|
48781
|
+
const index = indexValue(start + i * distance / count, length);
|
|
48782
|
+
indices.push(index);
|
|
48460
48783
|
}
|
|
48461
|
-
|
|
48462
|
-
|
|
48463
|
-
|
|
48464
|
-
|
|
48465
|
-
|
|
48466
|
-
|
|
48467
|
-
|
|
48468
|
-
|
|
48469
|
-
|
|
48470
|
-
|
|
48471
|
-
|
|
48472
|
-
|
|
48473
|
-
|
|
48474
|
-
|
|
48784
|
+
return indices[indices.length - 1];
|
|
48785
|
+
}
|
|
48786
|
+
function indexValue(v, length) {
|
|
48787
|
+
return (Math.round(v) + length) % length;
|
|
48788
|
+
}
|
|
48789
|
+
function getStats(dotValues) {
|
|
48790
|
+
const {
|
|
48791
|
+
length
|
|
48792
|
+
} = dotValues;
|
|
48793
|
+
let sum = 0;
|
|
48794
|
+
let min = Infinity;
|
|
48795
|
+
let max = -Infinity;
|
|
48796
|
+
let sumSq = 0;
|
|
48797
|
+
for (let i = 0; i < length; i++) {
|
|
48798
|
+
const dot = dotValues[i];
|
|
48799
|
+
sum += dot;
|
|
48800
|
+
min = Math.min(min, dot);
|
|
48801
|
+
max = Math.max(max, dot);
|
|
48802
|
+
}
|
|
48803
|
+
const mean = sum / length;
|
|
48804
|
+
for (let i = 0; i < length; i++) {
|
|
48805
|
+
const valueDiff = dotValues[i] - mean;
|
|
48806
|
+
sumSq += valueDiff * valueDiff;
|
|
48475
48807
|
}
|
|
48808
|
+
return {
|
|
48809
|
+
mean,
|
|
48810
|
+
max,
|
|
48811
|
+
min,
|
|
48812
|
+
sumSq,
|
|
48813
|
+
deviation: Math.sqrt(sumSq / length)
|
|
48814
|
+
};
|
|
48476
48815
|
}
|
|
48477
48816
|
|
|
48817
|
+
const {
|
|
48818
|
+
PointsManager
|
|
48819
|
+
} = utilities;
|
|
48478
48820
|
const dP = 0.2;
|
|
48479
48821
|
let interpolating = false;
|
|
48480
48822
|
function interpolate(viewportData) {
|
|
@@ -48482,11 +48824,24 @@ function interpolate(viewportData) {
|
|
|
48482
48824
|
return;
|
|
48483
48825
|
}
|
|
48484
48826
|
interpolating = true;
|
|
48485
|
-
|
|
48486
|
-
|
|
48487
|
-
|
|
48488
|
-
|
|
48489
|
-
|
|
48827
|
+
const {
|
|
48828
|
+
isInterpolationUpdate,
|
|
48829
|
+
annotation
|
|
48830
|
+
} = viewportData;
|
|
48831
|
+
queueMicrotask(() => {
|
|
48832
|
+
try {
|
|
48833
|
+
if (isInterpolationUpdate) {
|
|
48834
|
+
annotation.isInterpolationUpdate = true;
|
|
48835
|
+
annotation.autoGenerated = false;
|
|
48836
|
+
}
|
|
48837
|
+
startInterpolation(viewportData);
|
|
48838
|
+
} finally {
|
|
48839
|
+
interpolating = false;
|
|
48840
|
+
if (isInterpolationUpdate) {
|
|
48841
|
+
annotation.autoGenerated = true;
|
|
48842
|
+
}
|
|
48843
|
+
}
|
|
48844
|
+
});
|
|
48490
48845
|
}
|
|
48491
48846
|
function startInterpolation(viewportData) {
|
|
48492
48847
|
const toolData = viewportData.annotation;
|
|
@@ -48526,6 +48881,8 @@ function _linearlyInterpolateBetween(indices, annotationPair, interpolationData,
|
|
|
48526
48881
|
c1Interp,
|
|
48527
48882
|
c2Interp
|
|
48528
48883
|
} = _generateInterpolationContourPair(c1, c2);
|
|
48884
|
+
c1Interp.kIndex = annotationPair[0];
|
|
48885
|
+
c2Interp.kIndex = annotationPair[1];
|
|
48529
48886
|
indices.forEach(function (index) {
|
|
48530
48887
|
_linearlyInterpolateContour(c1Interp, c2Interp, index, annotationPair, interpolationData, c1.x.length > c2.x.length, eventData);
|
|
48531
48888
|
});
|
|
@@ -48535,30 +48892,15 @@ function _linearlyInterpolateContour(c1Interp, c2Interp, sliceIndex, annotationP
|
|
|
48535
48892
|
const zInterp = (sliceIndex - startIndex) / (endIndex - startIndex);
|
|
48536
48893
|
const interpolated3DPoints = _generateInterpolatedOpenContour(c1Interp, c2Interp, zInterp, c1HasMoreNodes);
|
|
48537
48894
|
const nearestAnnotation = interpolationData.get(annotationPair[zInterp > 0.5 ? 1 : 0])[0];
|
|
48538
|
-
const
|
|
48539
|
-
const handlePoints = _subselect(interpolated3DPoints, handleCount);
|
|
48895
|
+
const handlePoints = selectHandles(interpolated3DPoints);
|
|
48540
48896
|
if (interpolationData.has(sliceIndex)) {
|
|
48541
48897
|
_editInterpolatedContour(interpolated3DPoints, handlePoints, sliceIndex, nearestAnnotation, eventData);
|
|
48542
48898
|
} else {
|
|
48543
48899
|
_addInterpolatedContour(interpolated3DPoints, handlePoints, sliceIndex, nearestAnnotation, eventData);
|
|
48544
48900
|
}
|
|
48545
48901
|
}
|
|
48546
|
-
function _subselect(points, count = 10) {
|
|
48547
|
-
const handles = [];
|
|
48548
|
-
const {
|
|
48549
|
-
length
|
|
48550
|
-
} = points.x;
|
|
48551
|
-
if (!length) {
|
|
48552
|
-
return handles;
|
|
48553
|
-
}
|
|
48554
|
-
for (let i = 0; i < count; i++) {
|
|
48555
|
-
const handleIndex = Math.floor(length * i / count);
|
|
48556
|
-
handles.push(vec3.fromValues(points.x[handleIndex], points.y[handleIndex], points.z[handleIndex]));
|
|
48557
|
-
}
|
|
48558
|
-
return handles;
|
|
48559
|
-
}
|
|
48560
48902
|
function _addInterpolatedContour(interpolated3DPoints, handlePoints, sliceIndex, referencedToolData, eventData) {
|
|
48561
|
-
const points =
|
|
48903
|
+
const points = interpolated3DPoints.points;
|
|
48562
48904
|
const {
|
|
48563
48905
|
viewport
|
|
48564
48906
|
} = eventData;
|
|
@@ -48569,7 +48911,7 @@ function _addInterpolatedContour(interpolated3DPoints, handlePoints, sliceIndex,
|
|
|
48569
48911
|
interpolatedAnnotation.metadata.referencedImageId = targetId;
|
|
48570
48912
|
interpolatedAnnotation.metadata.referencedSliceIndex = sliceIndex;
|
|
48571
48913
|
addAnnotation(interpolatedAnnotation, viewport.element);
|
|
48572
|
-
referencedToolData.
|
|
48914
|
+
referencedToolData.onInterpolationComplete?.(interpolatedAnnotation, referencedToolData);
|
|
48573
48915
|
}
|
|
48574
48916
|
function _editInterpolatedContour(interpolated3DPoints, handlePoints, sliceIndex, referencedToolData, eventData) {
|
|
48575
48917
|
const {
|
|
@@ -48589,26 +48931,37 @@ function _editInterpolatedContour(interpolated3DPoints, handlePoints, sliceIndex
|
|
|
48589
48931
|
return;
|
|
48590
48932
|
}
|
|
48591
48933
|
const oldToolData = annotations[toolDataIndex];
|
|
48592
|
-
const points =
|
|
48934
|
+
const points = interpolated3DPoints.points;
|
|
48593
48935
|
const interpolatedAnnotation = createPolylineToolData(points, handlePoints, oldToolData);
|
|
48594
48936
|
interpolatedAnnotation.annotationUID = oldToolData.annotationUID;
|
|
48595
48937
|
removeAnnotation(oldToolData.annotationUID);
|
|
48596
48938
|
addAnnotation(interpolatedAnnotation, viewport.element);
|
|
48597
48939
|
}
|
|
48598
48940
|
function _generateInterpolatedOpenContour(c1ir, c2ir, zInterp, c1HasMoreNodes) {
|
|
48599
|
-
const cInterp = {
|
|
48600
|
-
x: [],
|
|
48601
|
-
y: [],
|
|
48602
|
-
z: []
|
|
48603
|
-
};
|
|
48604
48941
|
const indices = c1HasMoreNodes ? c1ir.I : c2ir.I;
|
|
48942
|
+
const c1 = PointsManager.fromXYZ(c1ir);
|
|
48943
|
+
const c2 = PointsManager.fromXYZ(c2ir);
|
|
48944
|
+
const {
|
|
48945
|
+
length
|
|
48946
|
+
} = c1;
|
|
48947
|
+
const cInterp = PointsManager.create3(length);
|
|
48948
|
+
const vecSubtract = vec3.create();
|
|
48949
|
+
const vecResult = vec3.create();
|
|
48950
|
+
const c1Source = PointsManager.create3(length);
|
|
48951
|
+
c1Source.kIndex = c1ir.kIndex;
|
|
48952
|
+
const c2Source = PointsManager.create3(length);
|
|
48953
|
+
c2Source.kIndex = c2ir.kIndex;
|
|
48605
48954
|
for (let i = 0; i < c1ir.x.length; i++) {
|
|
48606
48955
|
if (indices[i]) {
|
|
48607
|
-
|
|
48608
|
-
|
|
48609
|
-
|
|
48956
|
+
const c1point = c1.getPoint(i);
|
|
48957
|
+
const c2point = c2.getPoint(i);
|
|
48958
|
+
c1Source.push(c1point);
|
|
48959
|
+
c2Source.push(c2point);
|
|
48960
|
+
vec3.sub(vecSubtract, c2point, c1point);
|
|
48961
|
+
cInterp.push(vec3.scaleAndAdd(vecResult, c1point, vecSubtract, zInterp));
|
|
48610
48962
|
}
|
|
48611
48963
|
}
|
|
48964
|
+
cInterp.sources = [c1Source, c2Source];
|
|
48612
48965
|
return cInterp;
|
|
48613
48966
|
}
|
|
48614
48967
|
function _generateInterpolationContourPair(c1, c2) {
|
|
@@ -48621,8 +48974,8 @@ function _generateInterpolationContourPair(c1, c2) {
|
|
|
48621
48974
|
const numNodes2 = interpNodes + c1.x.length;
|
|
48622
48975
|
const perim1Interp = _getInterpolatedPerim(numNodes1, cumPerim1Norm);
|
|
48623
48976
|
const perim2Interp = _getInterpolatedPerim(numNodes2, cumPerim2Norm);
|
|
48624
|
-
const perim1Ind = _getIndicatorArray(
|
|
48625
|
-
const perim2Ind = _getIndicatorArray(
|
|
48977
|
+
const perim1Ind = _getIndicatorArray(numNodes1 - 2, c1.x.length);
|
|
48978
|
+
const perim2Ind = _getIndicatorArray(numNodes2 - 2, c2.x.length);
|
|
48626
48979
|
const nodesPerSegment1 = _getNodesPerSegment(perim1Interp, perim1Ind);
|
|
48627
48980
|
const nodesPerSegment2 = _getNodesPerSegment(perim2Interp, perim2Ind);
|
|
48628
48981
|
const c1i = _getSuperSampledContour(c1, nodesPerSegment1);
|
|
@@ -48741,14 +49094,10 @@ function _getNodesPerSegment(perimInterp, perimInd) {
|
|
|
48741
49094
|
}
|
|
48742
49095
|
return nodesPerSegment;
|
|
48743
49096
|
}
|
|
48744
|
-
function _getIndicatorArray(
|
|
48745
|
-
const perimInd =
|
|
48746
|
-
|
|
48747
|
-
|
|
48748
|
-
}
|
|
48749
|
-
for (let i = 0; i < contour.x.length; i++) {
|
|
48750
|
-
perimInd.push(true);
|
|
48751
|
-
}
|
|
49097
|
+
function _getIndicatorArray(numFalse, numTrue) {
|
|
49098
|
+
const perimInd = new Array(numFalse + numTrue);
|
|
49099
|
+
perimInd.fill(false, 0, numFalse);
|
|
49100
|
+
perimInd.fill(true, numFalse, numFalse + numTrue);
|
|
48752
49101
|
return perimInd;
|
|
48753
49102
|
}
|
|
48754
49103
|
function _getInterpolatedPerim(numNodes, cumPerimNorm) {
|
|
@@ -48855,6 +49204,7 @@ function deleteRelatedAnnotations(viewportData) {
|
|
|
48855
49204
|
const {
|
|
48856
49205
|
uuidv4
|
|
48857
49206
|
} = utilities;
|
|
49207
|
+
const ChangeTypesForInterpolation = [ChangeTypes$1.HandlesUpdated, ChangeTypes$1.InterpolationUpdated];
|
|
48858
49208
|
class InterpolationManager {
|
|
48859
49209
|
static {
|
|
48860
49210
|
this.toolNames = [];
|
|
@@ -48868,7 +49218,8 @@ class InterpolationManager {
|
|
|
48868
49218
|
const {
|
|
48869
49219
|
toolNames,
|
|
48870
49220
|
segmentationId,
|
|
48871
|
-
segmentIndex
|
|
49221
|
+
segmentIndex,
|
|
49222
|
+
sliceIndex
|
|
48872
49223
|
} = selector;
|
|
48873
49224
|
for (const toolName of toolNames || InterpolationManager.toolNames) {
|
|
48874
49225
|
const annotations = getAnnotations(toolName, annotationGroupSelector);
|
|
@@ -48878,7 +49229,8 @@ class InterpolationManager {
|
|
|
48878
49229
|
for (const annotation of annotations) {
|
|
48879
49230
|
const {
|
|
48880
49231
|
data,
|
|
48881
|
-
autoGenerated
|
|
49232
|
+
autoGenerated,
|
|
49233
|
+
metadata
|
|
48882
49234
|
} = annotation;
|
|
48883
49235
|
if (!autoGenerated) {
|
|
48884
49236
|
continue;
|
|
@@ -48886,6 +49238,9 @@ class InterpolationManager {
|
|
|
48886
49238
|
if (segmentIndex && segmentIndex !== data.segmentation.segmentIndex) {
|
|
48887
49239
|
continue;
|
|
48888
49240
|
}
|
|
49241
|
+
if (sliceIndex !== undefined && metadata && sliceIndex !== metadata.referencedSliceIndex) {
|
|
49242
|
+
continue;
|
|
49243
|
+
}
|
|
48889
49244
|
if (segmentationId && segmentationId !== data.segmentation.segmentationId) {
|
|
48890
49245
|
continue;
|
|
48891
49246
|
}
|
|
@@ -48958,7 +49313,7 @@ class InterpolationManager {
|
|
|
48958
49313
|
const {
|
|
48959
49314
|
toolName
|
|
48960
49315
|
} = annotation.metadata;
|
|
48961
|
-
if (!this.toolNames.includes(toolName) || changeType
|
|
49316
|
+
if (!this.toolNames.includes(toolName) || !ChangeTypesForInterpolation.includes(changeType)) {
|
|
48962
49317
|
return;
|
|
48963
49318
|
}
|
|
48964
49319
|
const viewport = getViewportForAnnotation(annotation);
|
|
@@ -48972,7 +49327,8 @@ class InterpolationManager {
|
|
|
48972
49327
|
viewport,
|
|
48973
49328
|
sliceData,
|
|
48974
49329
|
annotation,
|
|
48975
|
-
interpolationUID: annotation.interpolationUID
|
|
49330
|
+
interpolationUID: annotation.interpolationUID,
|
|
49331
|
+
isInterpolationUpdate: changeType === ChangeTypes$1.InterpolationUpdated
|
|
48976
49332
|
};
|
|
48977
49333
|
interpolate(viewportData);
|
|
48978
49334
|
};
|
|
@@ -49070,8 +49426,11 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
49070
49426
|
detectContourHoles: detectContourHoles,
|
|
49071
49427
|
findHandlePolylineIndex: findHandlePolylineIndex,
|
|
49072
49428
|
generateContourSetsFromLabelmap: generateContourSetsFromLabelmap$2,
|
|
49429
|
+
getContourHolesDataCanvas: getContourHolesDataCanvas,
|
|
49430
|
+
getContourHolesDataWorld: getContourHolesDataWorld,
|
|
49073
49431
|
interpolation: index$1,
|
|
49074
|
-
mergePoints: mergePoints
|
|
49432
|
+
mergePoints: mergePoints,
|
|
49433
|
+
updateContourPolyline: updateContourPolyline
|
|
49075
49434
|
});
|
|
49076
49435
|
|
|
49077
49436
|
const MODES = [ToolModes$1.Active, ToolModes$1.Passive, ToolModes$1.Enabled];
|
|
@@ -49159,6 +49518,9 @@ function getAnnotations(toolName, annotationGroupSelector) {
|
|
|
49159
49518
|
const groupKey = manager.getGroupKey(annotationGroupSelector);
|
|
49160
49519
|
return manager.getAnnotations(groupKey, toolName);
|
|
49161
49520
|
}
|
|
49521
|
+
function getParentAnnotation(annotation) {
|
|
49522
|
+
return annotation.parentAnnotationUID ? getAnnotation(annotation.parentAnnotationUID) : undefined;
|
|
49523
|
+
}
|
|
49162
49524
|
function addAnnotation(annotation, annotationGroupSelector) {
|
|
49163
49525
|
if (!annotation.annotationUID) {
|
|
49164
49526
|
annotation.annotationUID = uuidv4$1();
|
|
@@ -49183,6 +49545,7 @@ function removeAnnotation(annotationUID) {
|
|
|
49183
49545
|
if (!annotation) {
|
|
49184
49546
|
return;
|
|
49185
49547
|
}
|
|
49548
|
+
annotation.childAnnotationUIDs?.forEach(childAnnotationUID => removeAnnotation(childAnnotationUID));
|
|
49186
49549
|
manager.removeAnnotation(annotationUID);
|
|
49187
49550
|
const eventType = Events$1.ANNOTATION_REMOVED;
|
|
49188
49551
|
const eventDetail = {
|
|
@@ -49196,6 +49559,13 @@ function getAnnotation(annotationUID) {
|
|
|
49196
49559
|
const annotation = manager.getAnnotation(annotationUID);
|
|
49197
49560
|
return annotation;
|
|
49198
49561
|
}
|
|
49562
|
+
function invalidateAnnotation(annotation) {
|
|
49563
|
+
let currAnnotation = annotation;
|
|
49564
|
+
while (currAnnotation) {
|
|
49565
|
+
currAnnotation.invalidated = true;
|
|
49566
|
+
currAnnotation = currAnnotation.parentAnnotationUID ? getAnnotation(currAnnotation.parentAnnotationUID) : undefined;
|
|
49567
|
+
}
|
|
49568
|
+
}
|
|
49199
49569
|
|
|
49200
49570
|
function getPatientModule(imageId, metadataProvider) {
|
|
49201
49571
|
var generalSeriesModule = metadataProvider.get("generalSeriesModule", imageId);
|