@kitware/vtk.js 34.10.0 → 34.11.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/Common/Core/Points.d.ts +8 -0
- package/Common/Core/Points.js +2 -2
- package/Common/DataModel/AbstractPointLocator.d.ts +2 -2
- package/Common/DataModel/BoundingBox.d.ts +42 -3
- package/Common/DataModel/BoundingBox.js +181 -1
- package/Common/DataModel/Locator.d.ts +97 -5
- package/Common/DataModel/MergePoints.d.ts +64 -0
- package/Common/DataModel/MergePoints.js +130 -0
- package/Common/DataModel/PointLocator.d.ts +217 -0
- package/Common/DataModel/PointLocator.js +751 -0
- package/Filters/Sources/FrustumSource.d.ts +111 -0
- package/Filters/Sources/FrustumSource.js +248 -0
- package/Rendering/OpenGL/Glyph3DMapper.js +16 -0
- package/Rendering/OpenGL/glsl/vtkVolumeVS.glsl.js +1 -1
- package/index.d.ts +3 -0
- package/package.json +1 -1
package/Common/Core/Points.d.ts
CHANGED
|
@@ -81,6 +81,14 @@ export interface vtkPoints extends vtkDataArray {
|
|
|
81
81
|
* @returns {Number} Index of the inserted point.
|
|
82
82
|
*/
|
|
83
83
|
insertNextPoint(x: number, y: number, z: number): number;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Insert the [x,y,z] coordinates of a point at the given index.
|
|
87
|
+
* @param {Number} ptId The index of point.
|
|
88
|
+
* @param {Number[]} point The [x, y, z] coordinates of the point.
|
|
89
|
+
* @returns {Number} The index of the inserted point.
|
|
90
|
+
*/
|
|
91
|
+
insertPoint(ptId: number, point: number[]): number;
|
|
84
92
|
}
|
|
85
93
|
|
|
86
94
|
/**
|
package/Common/Core/Points.js
CHANGED
|
@@ -35,6 +35,7 @@ function vtkPoints(publicAPI, model) {
|
|
|
35
35
|
publicAPI.getPoint = publicAPI.getTuple;
|
|
36
36
|
publicAPI.findPoint = publicAPI.findTuple;
|
|
37
37
|
publicAPI.insertNextPoint = (x, y, z) => publicAPI.insertNextTuple([x, y, z]);
|
|
38
|
+
publicAPI.insertPoint = (ptId, point) => publicAPI.insertTuple(ptId, point);
|
|
38
39
|
publicAPI.getBounds = () => {
|
|
39
40
|
if (publicAPI.getNumberOfComponents() === 3) {
|
|
40
41
|
const xRange = publicAPI.getRange(0);
|
|
@@ -49,8 +50,7 @@ function vtkPoints(publicAPI, model) {
|
|
|
49
50
|
return model.bounds;
|
|
50
51
|
}
|
|
51
52
|
if (publicAPI.getNumberOfComponents() !== 2) {
|
|
52
|
-
vtkErrorMacro(`getBounds called on an array with components of
|
|
53
|
-
${publicAPI.getNumberOfComponents()}`);
|
|
53
|
+
vtkErrorMacro(`getBounds called on an array with components of ${publicAPI.getNumberOfComponents()}`);
|
|
54
54
|
return INVALID_BOUNDS;
|
|
55
55
|
}
|
|
56
56
|
const xRange = publicAPI.getRange(0);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { vtkObject } from './../../interfaces';
|
|
2
2
|
import { Bounds } from './../../types';
|
|
3
|
-
import { ILocatorInitialValues } from './Locator';
|
|
3
|
+
import vtkLocator, { ILocatorInitialValues } from './Locator';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
@@ -11,7 +11,7 @@ export interface IAbstractPointLocatorInitialValues
|
|
|
11
11
|
numberOfBuckets: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export interface vtkAbstractPointLocator extends
|
|
14
|
+
export interface vtkAbstractPointLocator extends vtkLocator {
|
|
15
15
|
/**
|
|
16
16
|
* Set the bounds of this object.
|
|
17
17
|
* @param {Bounds} input
|
|
@@ -325,6 +325,37 @@ export function cutWithPlane(
|
|
|
325
325
|
normal: Vector3
|
|
326
326
|
): boolean;
|
|
327
327
|
|
|
328
|
+
/**
|
|
329
|
+
* Clamp the divisions to ensure the total number doesn't exceed targetBins
|
|
330
|
+
* @param {Number} targetBins - Maximum number of bins allowed
|
|
331
|
+
* @param {Number[]} divs - Divisions array to adjust [divX, divY, divZ]
|
|
332
|
+
*/
|
|
333
|
+
export function clampDivisions(targetBins: number, divs: number[]): void;
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Compute the number of divisions given the current bounding box and a
|
|
337
|
+
* target number of buckets/bins. Handles degenerate bounding boxes properly.
|
|
338
|
+
* @param {Bounds} bounds - The bounding box
|
|
339
|
+
* @param {Number} totalBins - Target number of bins
|
|
340
|
+
* @param {Number[]} divs - Output array to store divisions [divX, divY, divZ]
|
|
341
|
+
* @param {Bounds} [adjustedBounds] - Output array to store adjusted bounds if needed
|
|
342
|
+
* @returns {Number} The actual total number of bins
|
|
343
|
+
*/
|
|
344
|
+
export function computeDivisions(
|
|
345
|
+
bounds: Bounds,
|
|
346
|
+
totalBins: number,
|
|
347
|
+
divs: number[],
|
|
348
|
+
adjustedBounds?: Bounds
|
|
349
|
+
): number;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Calculate the squared distance from point x to the specified bounds.
|
|
353
|
+
* @param {Vector3} x The point coordinates
|
|
354
|
+
* @param {Bounds} bounds The bounding box coordinates
|
|
355
|
+
* @returns {Number} The squared distance to the bounds
|
|
356
|
+
*/
|
|
357
|
+
export function distance2ToBounds(x: Vector3, bounds: Bounds): number;
|
|
358
|
+
|
|
328
359
|
declare class BoundingBox {
|
|
329
360
|
getBounds(): Bounds;
|
|
330
361
|
/**
|
|
@@ -409,10 +440,9 @@ declare class BoundingBox {
|
|
|
409
440
|
|
|
410
441
|
/**
|
|
411
442
|
* Inflates a bounding box.
|
|
412
|
-
* @param {
|
|
413
|
-
* @param {number} delta
|
|
443
|
+
* @param {number} [delta] The amount to inflate the bounding box by.
|
|
414
444
|
*/
|
|
415
|
-
inflate(
|
|
445
|
+
inflate(delta?: number): Bounds;
|
|
416
446
|
|
|
417
447
|
/**
|
|
418
448
|
* Scales a bounding box.
|
|
@@ -611,6 +641,14 @@ declare class BoundingBox {
|
|
|
611
641
|
* @param {Vector3} normal
|
|
612
642
|
*/
|
|
613
643
|
cutWithPlane(bounds: Bounds, origin: Vector3, normal: Vector3): boolean;
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Calculate the squared distance from point x to the specified bounds.
|
|
647
|
+
* @param {Vector3} x The point coordinates
|
|
648
|
+
* @param {Bounds} bounds The bounding box coordinates
|
|
649
|
+
* @returns {Number} The squared distance to the bounds
|
|
650
|
+
*/
|
|
651
|
+
distance2ToBounds(x: Vector3, bounds: Bounds): number;
|
|
614
652
|
}
|
|
615
653
|
|
|
616
654
|
export interface IBoundingBoxInitialValues {
|
|
@@ -653,6 +691,7 @@ declare const vtkBoundingBox: {
|
|
|
653
691
|
intersects: typeof intersects;
|
|
654
692
|
containsPoint: typeof containsPoint;
|
|
655
693
|
contains: typeof contains;
|
|
694
|
+
distance2ToBounds: typeof distance2ToBounds;
|
|
656
695
|
INIT_BOUNDS: Bounds;
|
|
657
696
|
};
|
|
658
697
|
|
|
@@ -96,6 +96,10 @@ function setMaxPoint(bounds, x, y, z) {
|
|
|
96
96
|
return xMax !== x || yMax !== y || zMax !== z;
|
|
97
97
|
}
|
|
98
98
|
function inflate(bounds, delta) {
|
|
99
|
+
if (delta == null) {
|
|
100
|
+
// eslint-disable-next-line no-use-before-define
|
|
101
|
+
return minInflate(bounds);
|
|
102
|
+
}
|
|
99
103
|
bounds[0] -= delta;
|
|
100
104
|
bounds[1] += delta;
|
|
101
105
|
bounds[2] -= delta;
|
|
@@ -104,6 +108,33 @@ function inflate(bounds, delta) {
|
|
|
104
108
|
bounds[5] += delta;
|
|
105
109
|
return bounds;
|
|
106
110
|
}
|
|
111
|
+
function minInflate(bounds) {
|
|
112
|
+
const nonZero = [0, 0, 0];
|
|
113
|
+
let maxIdx = -1;
|
|
114
|
+
let max = 0.0;
|
|
115
|
+
let w = 0.0;
|
|
116
|
+
for (let i = 0; i < 3; ++i) {
|
|
117
|
+
w = bounds[i * 2 + 1] - bounds[i * 2];
|
|
118
|
+
if (w > max) {
|
|
119
|
+
max = w;
|
|
120
|
+
maxIdx = i;
|
|
121
|
+
}
|
|
122
|
+
nonZero[i] = w > 0.0 ? 1 : 0;
|
|
123
|
+
}
|
|
124
|
+
if (maxIdx < 0) {
|
|
125
|
+
return inflate(bounds, 0.5);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Any zero width sides are bumped out 1% of max side
|
|
129
|
+
for (let i = 0; i < 3; ++i) {
|
|
130
|
+
if (!nonZero[i]) {
|
|
131
|
+
const d = 0.005 * max;
|
|
132
|
+
bounds[i * 2] -= d;
|
|
133
|
+
bounds[i * 2 + 1] += d;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return bounds;
|
|
137
|
+
}
|
|
107
138
|
function scale(bounds, sx, sy, sz) {
|
|
108
139
|
if (!isValid(bounds)) {
|
|
109
140
|
return false;
|
|
@@ -513,6 +544,145 @@ function cutWithPlane(bounds, origin, normal) {
|
|
|
513
544
|
return true;
|
|
514
545
|
}
|
|
515
546
|
|
|
547
|
+
/**
|
|
548
|
+
* Clamp the divisions to ensure the total number doesn't exceed targetBins
|
|
549
|
+
* @param {Number} targetBins - Maximum number of bins allowed
|
|
550
|
+
* @param {Array} divs - Divisions array to adjust [divX, divY, divZ]
|
|
551
|
+
*/
|
|
552
|
+
function clampDivisions(targetBins, divs) {
|
|
553
|
+
for (let i = 0; i < 3; ++i) {
|
|
554
|
+
divs[i] = divs[i] < 1 ? 1 : divs[i];
|
|
555
|
+
}
|
|
556
|
+
let numBins = divs[0] * divs[1] * divs[2];
|
|
557
|
+
while (numBins > targetBins) {
|
|
558
|
+
for (let i = 0; i < 3; ++i) {
|
|
559
|
+
divs[i] = divs[i] > 1 ? divs[i] - 1 : 1;
|
|
560
|
+
}
|
|
561
|
+
numBins = divs[0] * divs[1] * divs[2];
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Compute the number of divisions given the current bounding box and a
|
|
567
|
+
* target number of buckets/bins. Handles degenerate bounding boxes properly.
|
|
568
|
+
* @param {Bounds} bounds - The bounding box
|
|
569
|
+
* @param {Number} totalBins - Target number of bins
|
|
570
|
+
* @param {Array} divs - Output array to store divisions [divX, divY, divZ]
|
|
571
|
+
* @param {Array} [adjustedBounds] - Output array to store adjusted bounds if needed
|
|
572
|
+
* @returns {Number} The actual total number of bins
|
|
573
|
+
*/
|
|
574
|
+
function computeDivisions(bounds, totalBins, divs) {
|
|
575
|
+
let adjustedBounds = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
|
|
576
|
+
// This will always produce at least one bin
|
|
577
|
+
// eslint-disable-next-line no-param-reassign
|
|
578
|
+
totalBins = totalBins <= 0 ? 1 : totalBins;
|
|
579
|
+
|
|
580
|
+
// First determine the maximum length of the side of the bounds. Keep track
|
|
581
|
+
// of zero width sides of the bounding box.
|
|
582
|
+
let numNonZero = 0;
|
|
583
|
+
const nonZero = [0, 0, 0];
|
|
584
|
+
let maxIdx = -1;
|
|
585
|
+
let max = 0.0;
|
|
586
|
+
const lengths = getLengths(bounds);
|
|
587
|
+
|
|
588
|
+
// Use a finite tolerance when detecting zero width sides
|
|
589
|
+
const totLen = lengths[0] + lengths[1] + lengths[2];
|
|
590
|
+
const zeroDetectionTolerance = totLen * (0.001 / 3.0);
|
|
591
|
+
for (let i = 0; i < 3; ++i) {
|
|
592
|
+
if (lengths[i] > max) {
|
|
593
|
+
maxIdx = i;
|
|
594
|
+
max = lengths[i];
|
|
595
|
+
}
|
|
596
|
+
if (lengths[i] > zeroDetectionTolerance) {
|
|
597
|
+
nonZero[i] = 1;
|
|
598
|
+
numNonZero++;
|
|
599
|
+
} else {
|
|
600
|
+
nonZero[i] = 0;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Get min and max points
|
|
605
|
+
const minPoint = getMinPoint(bounds);
|
|
606
|
+
const maxPoint = getMaxPoint(bounds);
|
|
607
|
+
|
|
608
|
+
// If the bounding box is degenerate, then one bin of arbitrary size
|
|
609
|
+
if (numNonZero < 1) {
|
|
610
|
+
divs[0] = 1;
|
|
611
|
+
divs[1] = 1;
|
|
612
|
+
divs[2] = 1;
|
|
613
|
+
adjustedBounds[0] = minPoint[0] - 0.5;
|
|
614
|
+
adjustedBounds[1] = maxPoint[0] + 0.5;
|
|
615
|
+
adjustedBounds[2] = minPoint[1] - 0.5;
|
|
616
|
+
adjustedBounds[3] = maxPoint[1] + 0.5;
|
|
617
|
+
adjustedBounds[4] = minPoint[2] - 0.5;
|
|
618
|
+
adjustedBounds[5] = maxPoint[2] + 0.5;
|
|
619
|
+
return 1;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Compute the divisions roughly in proportion to the bounding box edge lengths
|
|
623
|
+
let f = totalBins;
|
|
624
|
+
f /= nonZero[0] ? lengths[0] / totLen : 1.0;
|
|
625
|
+
f /= nonZero[1] ? lengths[1] / totLen : 1.0;
|
|
626
|
+
f /= nonZero[2] ? lengths[2] / totLen : 1.0;
|
|
627
|
+
f **= 1.0 / numNonZero;
|
|
628
|
+
for (let i = 0; i < 3; ++i) {
|
|
629
|
+
divs[i] = nonZero[i] ? Math.floor(f * lengths[i] / totLen) : 1;
|
|
630
|
+
divs[i] = divs[i] < 1 ? 1 : divs[i];
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Make sure that we do not exceed the totalBins
|
|
634
|
+
clampDivisions(totalBins, divs);
|
|
635
|
+
|
|
636
|
+
// Now compute the final bounds, making sure it is a non-zero volume
|
|
637
|
+
const delta = 0.5 * lengths[maxIdx] / divs[maxIdx];
|
|
638
|
+
for (let i = 0; i < 3; ++i) {
|
|
639
|
+
if (nonZero[i]) {
|
|
640
|
+
adjustedBounds[2 * i] = minPoint[i];
|
|
641
|
+
adjustedBounds[2 * i + 1] = maxPoint[i];
|
|
642
|
+
} else {
|
|
643
|
+
adjustedBounds[2 * i] = minPoint[i] - delta;
|
|
644
|
+
adjustedBounds[2 * i + 1] = maxPoint[i] + delta;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return divs[0] * divs[1] * divs[2];
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Calculate the squared distance from point x to the specified bounds.
|
|
652
|
+
* @param {Vector3} x The point coordinates
|
|
653
|
+
* @param {Bounds} bounds The bounding box coordinates
|
|
654
|
+
* @returns {Number} The squared distance to the bounds
|
|
655
|
+
*/
|
|
656
|
+
function distance2ToBounds(x, bounds) {
|
|
657
|
+
// Are we within the bounds?
|
|
658
|
+
if (x[0] >= bounds[0] && x[0] <= bounds[1] && x[1] >= bounds[2] && x[1] <= bounds[3] && x[2] >= bounds[4] && x[2] <= bounds[5]) {
|
|
659
|
+
return 0.0;
|
|
660
|
+
}
|
|
661
|
+
const deltas = [0.0, 0.0, 0.0];
|
|
662
|
+
|
|
663
|
+
// dx
|
|
664
|
+
if (x[0] < bounds[0]) {
|
|
665
|
+
deltas[0] = bounds[0] - x[0];
|
|
666
|
+
} else if (x[0] > bounds[1]) {
|
|
667
|
+
deltas[0] = x[0] - bounds[1];
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// dy
|
|
671
|
+
if (x[1] < bounds[2]) {
|
|
672
|
+
deltas[1] = bounds[2] - x[1];
|
|
673
|
+
} else if (x[1] > bounds[3]) {
|
|
674
|
+
deltas[1] = x[1] - bounds[3];
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// dz
|
|
678
|
+
if (x[2] < bounds[4]) {
|
|
679
|
+
deltas[2] = bounds[4] - x[2];
|
|
680
|
+
} else if (x[2] > bounds[5]) {
|
|
681
|
+
deltas[2] = x[2] - bounds[5];
|
|
682
|
+
}
|
|
683
|
+
return dot(deltas, deltas);
|
|
684
|
+
}
|
|
685
|
+
|
|
516
686
|
// ----------------------------------------------------------------------------
|
|
517
687
|
// Light Weight class
|
|
518
688
|
// ----------------------------------------------------------------------------
|
|
@@ -630,6 +800,13 @@ class BoundingBox {
|
|
|
630
800
|
contains(otherBounds) {
|
|
631
801
|
return intersects(this.bounds, otherBounds);
|
|
632
802
|
}
|
|
803
|
+
computeDivisions(totalBins, divs) {
|
|
804
|
+
let adjustedBounds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
805
|
+
return computeDivisions(this.bounds, totalBins, divs, adjustedBounds);
|
|
806
|
+
}
|
|
807
|
+
distance2ToBounds(x) {
|
|
808
|
+
return distance2ToBounds(x, this.bounds);
|
|
809
|
+
}
|
|
633
810
|
}
|
|
634
811
|
function newInstance(initialValues) {
|
|
635
812
|
const bounds = initialValues && initialValues.bounds;
|
|
@@ -675,6 +852,9 @@ const STATIC = {
|
|
|
675
852
|
intersects,
|
|
676
853
|
containsPoint,
|
|
677
854
|
contains,
|
|
855
|
+
computeDivisions,
|
|
856
|
+
clampDivisions,
|
|
857
|
+
distance2ToBounds,
|
|
678
858
|
INIT_BOUNDS
|
|
679
859
|
};
|
|
680
860
|
var vtkBoundingBox = {
|
|
@@ -682,4 +862,4 @@ var vtkBoundingBox = {
|
|
|
682
862
|
...STATIC
|
|
683
863
|
};
|
|
684
864
|
|
|
685
|
-
export { STATIC, addBounds, addPoint, addPoints, computeCornerPoints, computeLocalBounds, computeScale3, contains, containsPoint, cutWithPlane, vtkBoundingBox as default, equals, getCenter, getCorners, getDiagonalLength, getLength, getLengths, getMaxLength, getMaxPoint, getMinPoint, getXRange, getYRange, getZRange,
|
|
865
|
+
export { STATIC, addBounds, addPoint, addPoints, clampDivisions, computeCornerPoints, computeDivisions, computeLocalBounds, computeScale3, contains, containsPoint, cutWithPlane, vtkBoundingBox as default, distance2ToBounds, equals, getCenter, getCorners, getDiagonalLength, getLength, getLengths, getMaxLength, getMaxPoint, getMinPoint, getXRange, getYRange, getZRange, intersect, intersectBox, intersectPlane, intersects, isValid, reset, scale, scaleAboutCenter, setBounds, setMaxPoint, setMinPoint, transformBounds };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { vtkObject } from './../../interfaces';
|
|
2
|
+
import vtkDataSet from './DataSet';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
*
|
|
5
6
|
*/
|
|
6
7
|
export interface ILocatorInitialValues {
|
|
7
|
-
dataSet?:
|
|
8
|
+
dataSet?: vtkDataSet;
|
|
8
9
|
maxLevel?: number;
|
|
9
10
|
level?: number;
|
|
10
11
|
automatic?: boolean;
|
|
@@ -12,7 +13,97 @@ export interface ILocatorInitialValues {
|
|
|
12
13
|
useExistingSearchStructure?: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
export interface vtkLocator extends vtkObject {
|
|
16
|
+
export interface vtkLocator extends vtkObject {
|
|
17
|
+
/**
|
|
18
|
+
* Get whether locator depth/resolution of locator is computed automatically
|
|
19
|
+
* from average number of entities in bucket.
|
|
20
|
+
*/
|
|
21
|
+
getAutomatic(): boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get the dataset associated with this locator.
|
|
25
|
+
*
|
|
26
|
+
* @returns {vtkDataSet} The dataset associated with this locator.
|
|
27
|
+
*/
|
|
28
|
+
getDataSet(): vtkDataSet;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get the current level of the locator.
|
|
32
|
+
*
|
|
33
|
+
* @returns {Number} The current level of the locator.
|
|
34
|
+
*/
|
|
35
|
+
getLevel(): number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get the maximum level of the locator.
|
|
39
|
+
*
|
|
40
|
+
* @returns {Number} The maximum level of the locator.
|
|
41
|
+
*/
|
|
42
|
+
getMaxLevel(): number;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get the tolerance used for the locator.
|
|
46
|
+
*
|
|
47
|
+
* @returns {Number} The tolerance value.
|
|
48
|
+
*/
|
|
49
|
+
getTolerance(): number;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get whether to use an existing search structure.
|
|
53
|
+
*
|
|
54
|
+
* @returns {Boolean} Whether an existing search structure is used.
|
|
55
|
+
*/
|
|
56
|
+
getUseExistingSearchStructure(): boolean;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Set whether locator depth/resolution of locator is computed automatically
|
|
60
|
+
* from average number of entities in bucket.
|
|
61
|
+
*
|
|
62
|
+
* @param {Boolean} automatic - The automatic flag.
|
|
63
|
+
* @returns {Boolean} Whether the operation was successful.
|
|
64
|
+
*/
|
|
65
|
+
setAutomatic(automatic: boolean): boolean;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Set the dataset associated with this locator.
|
|
69
|
+
*
|
|
70
|
+
* @param {vtkDataSet} dataSet - The dataset to associate with this locator.
|
|
71
|
+
* @returns {Boolean} Whether the operation was successful.
|
|
72
|
+
*/
|
|
73
|
+
setDataSet(dataSet: vtkDataSet): boolean;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Set the current level of the locator.
|
|
77
|
+
*
|
|
78
|
+
* @param {Number} level - The level to set.
|
|
79
|
+
* @returns {Boolean} Whether the operation was successful.
|
|
80
|
+
*/
|
|
81
|
+
setLevel(level: number): boolean;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Set the maximum level of the locator.
|
|
85
|
+
*
|
|
86
|
+
* @param {Number} maxLevel - The maximum level to set.
|
|
87
|
+
* @returns {Boolean} Whether the operation was successful.
|
|
88
|
+
*/
|
|
89
|
+
setMaxLevel(maxLevel: number): boolean;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Set the tolerance used for the locator.
|
|
93
|
+
*
|
|
94
|
+
* @param {Number} tolerance - The tolerance value to set.
|
|
95
|
+
* @returns {Boolean} Whether the operation was successful.
|
|
96
|
+
*/
|
|
97
|
+
setTolerance(tolerance: number): boolean;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Set whether to use an existing search structure.
|
|
101
|
+
*
|
|
102
|
+
* @param {Boolean} useExistingSearchStructure - Whether to use an existing search structure.
|
|
103
|
+
* @returns {Boolean} Whether the operation was successful.
|
|
104
|
+
*/
|
|
105
|
+
setUseExistingSearchStructure(useExistingSearchStructure: boolean): boolean;
|
|
106
|
+
}
|
|
16
107
|
|
|
17
108
|
// ----------------------------------------------------------------------------
|
|
18
109
|
// Static API
|
|
@@ -31,10 +122,11 @@ export function extend(
|
|
|
31
122
|
initialValues?: ILocatorInitialValues
|
|
32
123
|
): void;
|
|
33
124
|
|
|
34
|
-
// ----------------------------------------------------------------------------
|
|
35
|
-
|
|
36
125
|
/**
|
|
37
|
-
* vtkLocator
|
|
126
|
+
* vtkLocator is an abstract base class for spatial search objects, or locators.
|
|
127
|
+
* The principle behind locators is that they divide 3-space into small regions
|
|
128
|
+
* (or "buckets") that can be quickly found in response to queries about point
|
|
129
|
+
* location, line intersection, or object-object intersection.
|
|
38
130
|
*/
|
|
39
131
|
export declare const vtkLocator: {
|
|
40
132
|
extend: typeof extend;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Vector3 } from './../../types';
|
|
2
|
+
import vtkPointLocator, {
|
|
3
|
+
IInsertPointResult,
|
|
4
|
+
IPointLocatorInitialValues,
|
|
5
|
+
} from './PointLocator';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Initial values for vtkMergePoints.
|
|
9
|
+
*/
|
|
10
|
+
export interface IMergePointsInitialValues extends IPointLocatorInitialValues {
|
|
11
|
+
bucketSize?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface vtkMergePoints extends vtkPointLocator {
|
|
15
|
+
/**
|
|
16
|
+
* Check if a point is already inserted in the merge points structure.
|
|
17
|
+
*
|
|
18
|
+
* @param {Vector3} x The point to check.
|
|
19
|
+
* @returns {Number} The ID of the point if it exists, otherwise -1.
|
|
20
|
+
*/
|
|
21
|
+
isInsertedPoint(x: Vector3): number;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Insert a point into the merge points structure.
|
|
25
|
+
* If the point is already present, it returns the existing ID.
|
|
26
|
+
* Otherwise, it inserts the point and returns a new ID.
|
|
27
|
+
*
|
|
28
|
+
* @param {Vector3} x The point to insert as an array of 3 numbers.
|
|
29
|
+
* @returns {IInsertPointResult} An object indicating if the point was inserted and its ID.
|
|
30
|
+
*/
|
|
31
|
+
insertUniquePoint(x: Vector3): IInsertPointResult;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Method used to decorate a given object (publicAPI+model) with vtkMergePoints characteristics.
|
|
36
|
+
*
|
|
37
|
+
* @param publicAPI object on which methods will be bounds (public)
|
|
38
|
+
* @param model object on which data structure will be bounds (protected)
|
|
39
|
+
* @param {IMergePointsInitialValues} [initialValues] (default: {})
|
|
40
|
+
*/
|
|
41
|
+
export function extend(
|
|
42
|
+
publicAPI: object,
|
|
43
|
+
model: object,
|
|
44
|
+
initialValues?: IMergePointsInitialValues
|
|
45
|
+
): void;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Method used to create a new instance of vtkMergePoints.
|
|
49
|
+
* @param {IMergePointsInitialValues} [initialValues] for pre-setting some of its content
|
|
50
|
+
*/
|
|
51
|
+
export function newInstance(
|
|
52
|
+
initialValues?: IMergePointsInitialValues
|
|
53
|
+
): vtkMergePoints;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* vtkMergePoints merge exactly coincident points.
|
|
57
|
+
*
|
|
58
|
+
* vtkMergePoints is a locator object to quickly locate points in 3D.
|
|
59
|
+
*/
|
|
60
|
+
export declare const vtkMergePoints: {
|
|
61
|
+
newInstance: typeof newInstance;
|
|
62
|
+
extend: typeof extend;
|
|
63
|
+
};
|
|
64
|
+
export default vtkMergePoints;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { m as macro } from '../../macros2.js';
|
|
2
|
+
import vtkPointLocator from './PointLocator.js';
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
vtkErrorMacro
|
|
6
|
+
} = macro;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Search for a point in the array using indices from bucketIds
|
|
10
|
+
* @param {Number[]} bucketIds - The list of point IDs in the bucket.
|
|
11
|
+
* @param {vtkPoints} points - The vtkPoints object containing the points.
|
|
12
|
+
* @param {Vector3} x - The point to check.
|
|
13
|
+
* @returns {Number} - The ID of the point if it exists, otherwise -1.
|
|
14
|
+
*/
|
|
15
|
+
function findPointInBucket(bucketIds, points, x) {
|
|
16
|
+
const data = points.getData();
|
|
17
|
+
for (let i = 0; i < bucketIds.length; ++i) {
|
|
18
|
+
const ptId = bucketIds[i];
|
|
19
|
+
const idx = ptId * 3;
|
|
20
|
+
if (x[0] === data[idx] && x[1] === data[idx + 1] && x[2] === data[idx + 2]) {
|
|
21
|
+
return ptId;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return -1;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ----------------------------------------------------------------------------
|
|
28
|
+
// vtkMergePoints methods
|
|
29
|
+
// ----------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
function vtkMergePoints(publicAPI, model) {
|
|
32
|
+
// Set our className
|
|
33
|
+
model.classHierarchy.push('vtkMergePoints');
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if a point is already inserted in the merge points structure.
|
|
37
|
+
*
|
|
38
|
+
* @param {Vector3} x The point to check.
|
|
39
|
+
* @returns {Number} The ID of the point if it exists, otherwise -1.
|
|
40
|
+
*/
|
|
41
|
+
publicAPI.isInsertedPoint = x => {
|
|
42
|
+
const idx = publicAPI.getBucketIndex(x);
|
|
43
|
+
const bucketIds = model.hashTable.get(idx);
|
|
44
|
+
if (bucketIds) {
|
|
45
|
+
return findPointInBucket(bucketIds, model.points, x);
|
|
46
|
+
}
|
|
47
|
+
return -1;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Insert a point into the merge points structure.
|
|
52
|
+
* If the point is already present, it returns the existing ID.
|
|
53
|
+
* Otherwise, it inserts the point and returns a new ID.
|
|
54
|
+
*
|
|
55
|
+
* @param {Vector3} x The point to insert as an array of 3 numbers.
|
|
56
|
+
* @returns {IInsertPointResult} An object indicating if the point was inserted and its ID.
|
|
57
|
+
*/
|
|
58
|
+
publicAPI.insertUniquePoint = x => {
|
|
59
|
+
if (!x || x.length !== 3) {
|
|
60
|
+
vtkErrorMacro('Point must be a Vector3.');
|
|
61
|
+
return {
|
|
62
|
+
inserted: false,
|
|
63
|
+
id: -1
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const idx = publicAPI.getBucketIndex(x);
|
|
67
|
+
let bucketIds = model.hashTable.get(idx);
|
|
68
|
+
let id = null;
|
|
69
|
+
if (bucketIds !== undefined) {
|
|
70
|
+
const ptId = findPointInBucket(bucketIds, model.points, x);
|
|
71
|
+
if (ptId !== -1) {
|
|
72
|
+
id = ptId;
|
|
73
|
+
return {
|
|
74
|
+
inserted: false,
|
|
75
|
+
id
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
bucketIds = [];
|
|
80
|
+
model.hashTable.set(idx, bucketIds);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Insert new point
|
|
84
|
+
bucketIds.push(model.insertionPointId);
|
|
85
|
+
model.points.insertNextPoint(...x);
|
|
86
|
+
id = model.insertionPointId++;
|
|
87
|
+
return {
|
|
88
|
+
inserted: true,
|
|
89
|
+
id
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ----------------------------------------------------------------------------
|
|
95
|
+
// Object factory
|
|
96
|
+
// ----------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
function defaultValues(initialValues) {
|
|
99
|
+
return {
|
|
100
|
+
// points: null,
|
|
101
|
+
// hashTable: null,
|
|
102
|
+
...initialValues
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ----------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
function extend(publicAPI, model) {
|
|
109
|
+
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
110
|
+
vtkPointLocator.extend(publicAPI, model, defaultValues(initialValues));
|
|
111
|
+
|
|
112
|
+
// Make this a VTK object
|
|
113
|
+
macro.obj(publicAPI, model);
|
|
114
|
+
|
|
115
|
+
// Object specific methods
|
|
116
|
+
vtkMergePoints(publicAPI, model);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ----------------------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
const newInstance = macro.newInstance(extend, 'vtkMergePoints');
|
|
122
|
+
|
|
123
|
+
// ----------------------------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
var index = {
|
|
126
|
+
newInstance,
|
|
127
|
+
extend
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export { index as default, extend, newInstance };
|