@kitware/vtk.js 23.4.3 → 23.4.4
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/Math/Constants.js +12 -0
- package/Common/Core/Math/index.js +1 -1
- package/Common/Core/Math.js +1 -1
- package/Common/Core/ScalarsToColors/Constants.d.ts +18 -0
- package/Common/DataModel/AbstractPointLocator.d.ts +54 -0
- package/Common/DataModel/AbstractPointLocator.js +40 -0
- package/Common/DataModel/BoundingBox.d.ts +659 -0
- package/Common/DataModel/Collection.d.ts +118 -0
- package/Common/DataModel/Collection.js +113 -0
- package/Common/DataModel/DataSet/Constants.d.ts +27 -0
- package/Common/DataModel/EdgeLocator.d.ts +79 -0
- package/Common/DataModel/EdgeLocator.js +85 -0
- package/Common/DataModel/ITKHelper.d.ts +54 -0
- package/Common/DataModel/IncrementalOctreeNode.d.ts +297 -0
- package/Common/DataModel/IncrementalOctreeNode.js +640 -0
- package/Common/DataModel/IncrementalOctreePointLocator.d.ts +61 -0
- package/Common/DataModel/IncrementalOctreePointLocator.js +398 -0
- package/Common/DataModel/Locator.d.ts +43 -0
- package/Common/DataModel/Locator.js +37 -0
- package/Common/DataModel/Plane.js +1 -1
- package/Common/DataModel/PolyData/Constants.d.ts +6 -0
- package/Common/DataModel/PolyLine.d.ts +63 -0
- package/Common/DataModel/PolyLine.js +77 -0
- package/Common/DataModel/Polygon/Constants.js +12 -0
- package/Common/DataModel/Polygon.js +1 -1
- package/Common/DataModel/Quad/Constants.js +9 -0
- package/Common/DataModel/Quad.d.ts +91 -0
- package/Common/DataModel/Quad.js +235 -0
- package/Common/DataModel/SelectionNode/Constants.d.ts +27 -0
- package/Common/DataModel/Spline1D/Constants.js +17 -0
- package/Common/DataModel/Spline3D/Constants.d.ts +9 -0
- package/Common/Transform/Transform.js +51 -0
- package/Filters/Core/PolyDataNormals.js +124 -0
- package/Filters/General/ClipClosedSurface/Constants.js +10 -0
- package/Filters/General/ClipClosedSurface.d.ts +95 -0
- package/Filters/General/ClipClosedSurface.js +972 -0
- package/Filters/General/ContourTriangulator/Constants.js +6 -0
- package/Filters/General/ContourTriangulator/helper.js +1951 -0
- package/Filters/General/ContourTriangulator.d.ts +136 -0
- package/Filters/General/ContourTriangulator.js +202 -0
- package/Filters/General/ImageMarchingCubes.js +1 -1
- package/Filters/General/MoleculeToRepresentation.js +1 -1
- package/Filters/General/OBBTree/OBBNode.js +82 -0
- package/Filters/General/OBBTree/helper.js +92 -0
- package/Filters/General/OBBTree.js +1243 -0
- package/Filters/General/TubeFilter.js +1 -1
- package/Filters/Sources/LineSource.js +1 -1
- package/Filters/Sources/PlaneSource.js +1 -1
- package/Filters/Texture/TextureMapToPlane.js +1 -1
- package/Interaction/Manipulators/CompositeCameraManipulator.d.ts +68 -0
- package/Interaction/Manipulators/CompositeGestureManipulator.d.ts +168 -0
- package/Interaction/Manipulators/CompositeKeyboardManipulator.d.ts +48 -0
- package/Interaction/Manipulators/CompositeMouseManipulator.d.ts +149 -0
- package/Interaction/Manipulators/CompositeVRManipulator.d.ts +44 -0
- package/Interaction/Manipulators/GestureCameraManipulator.d.ts +34 -0
- package/Interaction/Manipulators/KeyboardCameraManipulator.js +1 -1
- package/Interaction/Manipulators/MouseBoxSelectorManipulator.d.ts +88 -0
- package/Interaction/Manipulators/MouseCameraAxisRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballMultiRotateManipulator.d.ts +32 -0
- package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.d.ts +33 -0
- package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.d.ts +33 -0
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.d.ts +67 -0
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballZoomManipulator.d.ts +45 -0
- package/Interaction/Manipulators/MouseCameraTrackballZoomToMouseManipulator.d.ts +26 -0
- package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseRangeManipulator.d.ts +53 -0
- package/Interaction/Style/InteractorStyleImage.d.ts +107 -0
- package/Interaction/Style/InteractorStyleMPRSlice.js +1 -1
- package/Interaction/Style/InteractorStyleManipulator.d.ts +348 -0
- package/Interaction/Style/InteractorStyleTrackballCamera.d.ts +170 -0
- package/Interaction/Widgets/ImageCroppingRegionsWidget.js +1 -1
- package/Interaction/Widgets/LabelRepresentation.js +1 -1
- package/Interaction/Widgets/OrientationMarkerWidget/Constants.d.ts +11 -0
- package/Interaction/Widgets/ResliceCursor/ResliceCursor.js +1 -1
- package/Interaction/Widgets/ResliceCursor/ResliceCursorLineRepresentation.js +1 -1
- package/Interaction/Widgets/ResliceCursor/ResliceCursorRepresentation.js +1 -1
- package/Proxy/Core/AbstractRepresentationProxy.d.ts +24 -0
- package/Proxy/Core/LookupTableProxy.d.ts +45 -0
- package/Proxy/Core/PiecewiseFunctionProxy.d.ts +62 -0
- package/Proxy/Core/ProxyManager.d.ts +115 -0
- package/Proxy/Core/SourceProxy.d.ts +22 -0
- package/Proxy/Core/View2DProxy.d.ts +7 -0
- package/Proxy/Core/View2DProxy.js +1 -1
- package/Proxy/Core/ViewProxy.d.ts +86 -0
- package/Proxy/Representations/SliceRepresentationProxy.d.ts +27 -0
- package/Proxy/Representations/VolumeRepresentationProxy.d.ts +44 -0
- package/README.md +2 -2
- package/Rendering/Core/AbstractImageMapper/helper.js +127 -0
- package/Rendering/Core/AbstractImageMapper.d.ts +82 -0
- package/Rendering/Core/AbstractImageMapper.js +44 -0
- package/Rendering/Core/Camera.js +1 -1
- package/Rendering/Core/CellPicker.js +1 -1
- package/Rendering/Core/ColorTransferFunction/ColorMaps.d.ts +24 -0
- package/Rendering/Core/ColorTransferFunction/Constants.d.ts +17 -0
- package/Rendering/Core/ColorTransferFunction.js +1 -1
- package/Rendering/Core/Coordinate/Constants.d.ts +14 -0
- package/Rendering/Core/Coordinate.js +1 -1
- package/Rendering/Core/Glyph3DMapper/Constants.d.ts +17 -0
- package/Rendering/Core/Glyph3DMapper.js +1 -1
- package/Rendering/Core/HardwareSelector.d.ts +84 -0
- package/Rendering/Core/ImageArrayMapper.d.ts +253 -0
- package/Rendering/Core/ImageArrayMapper.js +242 -0
- package/Rendering/Core/ImageMapper/Constants.d.ts +14 -0
- package/Rendering/Core/ImageMapper.js +1 -1
- package/Rendering/Core/ImageProperty/Constants.d.ts +9 -0
- package/Rendering/Core/ImageResliceMapper/Constants.d.ts +11 -0
- package/Rendering/Core/ImageResliceMapper/Constants.js +11 -0
- package/Rendering/Core/ImageResliceMapper.d.ts +245 -0
- package/Rendering/Core/ImageResliceMapper.js +70 -0
- package/Rendering/Core/InteractorObserver.d.ts +132 -0
- package/Rendering/Core/InteractorStyle/Constants.d.ts +16 -0
- package/Rendering/Core/InteractorStyle.d.ts +229 -0
- package/Rendering/Core/Light.js +1 -1
- package/Rendering/Core/Mapper/Constants.d.ts +26 -0
- package/Rendering/Core/Mapper.js +1 -1
- package/Rendering/Core/Picker.js +1 -1
- package/Rendering/Core/Prop/Constants.d.ts +9 -0
- package/Rendering/Core/Prop/Constants.js +9 -0
- package/Rendering/Core/Property/Constants.d.ts +24 -0
- package/Rendering/Core/Property2D/Constants.d.ts +9 -0
- package/Rendering/Core/RenderWindow.js +1 -1
- package/Rendering/Core/RenderWindowInteractor/Constants.d.ts +31 -0
- package/Rendering/Core/Renderer.js +1 -1
- package/Rendering/Core/VolumeMapper/Constants.d.ts +20 -0
- package/Rendering/Core/VolumeMapper.js +1 -1
- package/Rendering/Core/VolumeProperty/Constants.d.ts +16 -0
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager/CameraSynchronizer.js +129 -0
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager.js +131 -0
- package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.d.ts +80 -0
- package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.js +763 -0
- package/Rendering/OpenGL/HardwareSelector/Constants.d.ts +8 -0
- package/Rendering/OpenGL/HardwareSelector.d.ts +339 -0
- package/Rendering/OpenGL/ImageResliceMapper.js +996 -0
- package/Rendering/OpenGL/PolyDataMapper.js +1 -1
- package/Rendering/OpenGL/PolyDataMapper2D.js +1 -1
- package/Rendering/OpenGL/RenderWindow/Constants.d.ts +10 -0
- package/Rendering/OpenGL/RenderWindow/Constants.js +13 -0
- package/Rendering/OpenGL/RenderWindow/ContextProxy.js +70 -0
- package/Rendering/OpenGL/glsl/vtkImageResliceMapperFS.glsl.js +3 -0
- package/Rendering/OpenGL/glsl/vtkImageResliceMapperVS.glsl.js +3 -0
- package/Rendering/WebGPU/Actor2D.js +151 -0
- package/Rendering/WebGPU/BufferManager.js +1 -1
- package/Rendering/WebGPU/CellArrayMapper.js +853 -0
- package/Rendering/WebGPU/IndexBuffer.js +397 -0
- package/Rendering/WebGPU/PolyDataMapper2D.js +99 -0
- package/Rendering/WebGPU/SimpleMapper.js +290 -0
- package/Widgets/Core/AbstractWidget.d.ts +187 -0
- package/Widgets/Core/AbstractWidgetFactory.d.ts +131 -0
- package/Widgets/Core/StateBuilder/color3Mixin.js +24 -0
- package/Widgets/Core/StateBuilder/orientationMixin.js +1 -1
- package/Widgets/Core/StateBuilder.d.ts +29 -0
- package/Widgets/Core/WidgetManager/Constants.d.ts +27 -0
- package/Widgets/Core/WidgetManager.d.ts +231 -0
- package/Widgets/Core/WidgetState.d.ts +81 -0
- package/Widgets/Manipulators/AbstractManipulator.d.ts +221 -0
- package/Widgets/Manipulators/AbstractManipulator.js +57 -0
- package/Widgets/Manipulators/LineManipulator.js +1 -1
- package/Widgets/Manipulators/TrackballManipulator.js +1 -1
- package/Widgets/Representations/GlyphRepresentation.js +325 -0
- package/Widgets/Representations/LineHandleRepresentation.js +116 -0
- package/Widgets/Representations/ResliceCursorContextRepresentation.js +1 -1
- package/Widgets/Representations/WidgetRepresentation.js +1 -1
- package/Widgets/Widgets3D/AngleWidget.js +1 -1
- package/Widgets/Widgets3D/InteractiveOrientationWidget.d.ts +40 -0
- package/Widgets/Widgets3D/LabelWidget/behavior.js +157 -0
- package/Widgets/Widgets3D/LabelWidget/state.js +22 -0
- package/Widgets/Widgets3D/LabelWidget.js +78 -0
- package/Widgets/Widgets3D/LineWidget/behavior.js +1 -1
- package/Widgets/Widgets3D/LineWidget/helpers.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget.js +1 -1
- package/index.d.ts +133 -74
- package/package.json +1 -1
|
@@ -0,0 +1,1243 @@
|
|
|
1
|
+
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
|
|
2
|
+
import macro from '../../macros.js';
|
|
3
|
+
import vtkCellArray from '../../Common/Core/CellArray.js';
|
|
4
|
+
import vtkLine from '../../Common/DataModel/Line.js';
|
|
5
|
+
import { d as dot, j as cross, n as norm, t as jacobi, l as normalize, k as add } from '../../Common/Core/Math/index.js';
|
|
6
|
+
import vtkMatrixBuilder from '../../Common/Core/MatrixBuilder.js';
|
|
7
|
+
import vtkOBBNode from './OBBTree/OBBNode.js';
|
|
8
|
+
import vtkPoints from '../../Common/Core/Points.js';
|
|
9
|
+
import { CellType } from '../../Common/DataModel/CellTypes/Constants.js';
|
|
10
|
+
import vtkPolyData from '../../Common/DataModel/PolyData.js';
|
|
11
|
+
import vtkTriangle from '../../Common/DataModel/Triangle.js';
|
|
12
|
+
import { pushArray, getCellTriangles } from './OBBTree/helper.js';
|
|
13
|
+
import { mat4, vec4 } from 'gl-matrix';
|
|
14
|
+
|
|
15
|
+
var vtkErrorMacro = macro.vtkErrorMacro;
|
|
16
|
+
var VTK_DOUBLE_MAX = Number.MAX_SAFE_INTEGER; // ----------------------------------------------------------------------------
|
|
17
|
+
// vtkOBBTree methods
|
|
18
|
+
// ----------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
function vtkOBBTree(publicAPI, model) {
|
|
21
|
+
// Set our classname
|
|
22
|
+
model.classHierarchy.push('vtkOBBTree');
|
|
23
|
+
/**
|
|
24
|
+
* Compute an OBB from the list of cells given. This used to be
|
|
25
|
+
* public but should not have been. A public call has been added
|
|
26
|
+
* so that the functionality can be accessed.
|
|
27
|
+
* @param {Array} cells
|
|
28
|
+
* @param {Array[3]} corner
|
|
29
|
+
* @param {Array[3]} max
|
|
30
|
+
* @param {Array[3]} mid
|
|
31
|
+
* @param {Array[3]} min
|
|
32
|
+
* @param {Array[3]} size
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
function computeOBB(cells, corner, max, mid, min, size) {
|
|
36
|
+
model.OBBCount++;
|
|
37
|
+
model.pointsList = []; //
|
|
38
|
+
// Compute mean & moments
|
|
39
|
+
//
|
|
40
|
+
|
|
41
|
+
var numCells = cells.length;
|
|
42
|
+
var mean = [0, 0, 0];
|
|
43
|
+
var totMass = 0.0;
|
|
44
|
+
var a0 = [0, 0, 0];
|
|
45
|
+
var a1 = [0, 0, 0];
|
|
46
|
+
var a2 = [0, 0, 0];
|
|
47
|
+
var a = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
48
|
+
var dp0 = [0, 0, 0];
|
|
49
|
+
var dp1 = [0, 0, 0];
|
|
50
|
+
var c = [0, 0, 0];
|
|
51
|
+
var triMass = 0;
|
|
52
|
+
|
|
53
|
+
if (!model.dataset.getCells()) {
|
|
54
|
+
model.dataset.buildCells();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (var i = 0; i < numCells; i++) {
|
|
58
|
+
var cellId = cells[i];
|
|
59
|
+
var type = model.dataset.getCells().getCellType(cellId);
|
|
60
|
+
var ptIds = model.dataset.getCellPoints(cellId).cellPointIds;
|
|
61
|
+
var _numPts = ptIds.length;
|
|
62
|
+
|
|
63
|
+
for (var j = 0; j < _numPts - 2; j++) {
|
|
64
|
+
var cellsIds = getCellTriangles(ptIds, type, j);
|
|
65
|
+
var pId = cellsIds.ptId0;
|
|
66
|
+
var qId = cellsIds.ptId1;
|
|
67
|
+
var rId = cellsIds.ptId2;
|
|
68
|
+
|
|
69
|
+
if (pId < 0) {
|
|
70
|
+
// eslint-disable-next-line no-continue
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var p = [];
|
|
75
|
+
var q = [];
|
|
76
|
+
var r = [];
|
|
77
|
+
model.dataset.getPoints().getPoint(pId, p);
|
|
78
|
+
model.dataset.getPoints().getPoint(qId, q);
|
|
79
|
+
model.dataset.getPoints().getPoint(rId, r); // p, q, and r are the oriented triangle points.
|
|
80
|
+
// Compute the components of the moment of inertia tensor.
|
|
81
|
+
|
|
82
|
+
for (var k = 0; k < 3; k++) {
|
|
83
|
+
// two edge vectors
|
|
84
|
+
dp0[k] = q[k] - p[k];
|
|
85
|
+
dp1[k] = r[k] - p[k]; // centroid
|
|
86
|
+
|
|
87
|
+
c[k] = (p[k] + q[k] + r[k]) / 3;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var xp = cross(dp0, dp1, []);
|
|
91
|
+
triMass = 0.5 * norm(xp);
|
|
92
|
+
totMass += triMass;
|
|
93
|
+
|
|
94
|
+
for (var _k = 0; _k < 3; _k++) {
|
|
95
|
+
mean[_k] += triMass * c[_k];
|
|
96
|
+
} // on-diagonal terms
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
a0[0] += triMass * (9 * c[0] * c[0] + p[0] * p[0] + q[0] * q[0] + r[0] * r[0]) / 12;
|
|
100
|
+
a1[1] += triMass * (9 * c[1] * c[1] + p[1] * p[1] + q[1] * q[1] + r[1] * r[1]) / 12;
|
|
101
|
+
a2[2] += triMass * (9 * c[2] * c[2] + p[2] * p[2] + q[2] * q[2] + r[2] * r[2]) / 12; // off-diagonal terms
|
|
102
|
+
|
|
103
|
+
a0[1] += triMass * (9 * c[0] * c[1] + p[0] * p[1] + q[0] * q[1] + r[0] * r[1]) / 12;
|
|
104
|
+
a0[2] += triMass * (9 * c[0] * c[2] + p[0] * p[2] + q[0] * q[2] + r[0] * r[2]) / 12;
|
|
105
|
+
a1[2] += triMass * (9 * c[1] * c[2] + p[1] * p[2] + q[1] * q[2] + r[1] * r[2]) / 12;
|
|
106
|
+
} // end foreach triangle
|
|
107
|
+
// While computing cell moments, gather all the cell's
|
|
108
|
+
// point coordinates into a single list.
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
for (var _j = 0; _j < _numPts; _j++) {
|
|
112
|
+
if (model.insertedPoints[ptIds[_j]] !== model.OBBCount) {
|
|
113
|
+
model.insertedPoints[ptIds[_j]] = model.OBBCount;
|
|
114
|
+
var pt = [];
|
|
115
|
+
model.dataset.getPoints().getPoint(ptIds[_j], pt);
|
|
116
|
+
model.pointsList.push(pt);
|
|
117
|
+
}
|
|
118
|
+
} // for all points of this cell
|
|
119
|
+
|
|
120
|
+
} // end foreach cell
|
|
121
|
+
// normalize data
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
for (var _i = 0; _i < 3; _i++) {
|
|
125
|
+
mean[_i] /= totMass;
|
|
126
|
+
} // matrix is symmetric
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
a1[0] = a0[1];
|
|
130
|
+
a2[0] = a0[2];
|
|
131
|
+
a2[1] = a1[2];
|
|
132
|
+
a = [a0[0], a0[1], a0[2], a1[0], a1[1], a1[2], a2[0], a2[1], a2[2]]; // get covariance from moments
|
|
133
|
+
|
|
134
|
+
for (var _i2 = 0; _i2 < 3; _i2++) {
|
|
135
|
+
for (var _j2 = 0; _j2 < 3; _j2++) {
|
|
136
|
+
a[_i2 * 3 + _j2] = a[_i2 * 3 + _j2] / totMass - mean[_i2] * mean[_j2];
|
|
137
|
+
}
|
|
138
|
+
} //
|
|
139
|
+
// Extract axes (i.e., eigenvectors) from covariance matrix.
|
|
140
|
+
//
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
var v = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
144
|
+
jacobi(a, size, v);
|
|
145
|
+
max[0] = v[0];
|
|
146
|
+
max[1] = v[3];
|
|
147
|
+
max[2] = v[6];
|
|
148
|
+
mid[0] = v[1];
|
|
149
|
+
mid[1] = v[4];
|
|
150
|
+
mid[2] = v[7];
|
|
151
|
+
min[0] = v[2];
|
|
152
|
+
min[1] = v[5];
|
|
153
|
+
min[2] = v[8];
|
|
154
|
+
|
|
155
|
+
for (var _i3 = 0; _i3 < 3; _i3++) {
|
|
156
|
+
a[_i3] = mean[_i3] + max[_i3];
|
|
157
|
+
a[3 + _i3] = mean[_i3] + mid[_i3];
|
|
158
|
+
a[6 + _i3] = mean[_i3] + min[_i3];
|
|
159
|
+
} //
|
|
160
|
+
// Create oriented bounding box by projecting points onto eigenvectors.
|
|
161
|
+
//
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
var tMin = [VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX];
|
|
165
|
+
var tMax = [-VTK_DOUBLE_MAX, -VTK_DOUBLE_MAX, -VTK_DOUBLE_MAX];
|
|
166
|
+
var numPts = model.pointsList.length;
|
|
167
|
+
|
|
168
|
+
for (var ptId = 0; ptId < numPts; ptId++) {
|
|
169
|
+
var _p = model.pointsList[ptId];
|
|
170
|
+
|
|
171
|
+
for (var _i4 = 0; _i4 < 3; _i4++) {
|
|
172
|
+
var out = vtkLine.distanceToLine(_p, mean, a.slice(3 * _i4, 3 * (_i4 + 1)), []);
|
|
173
|
+
|
|
174
|
+
if (out.t < tMin[_i4]) {
|
|
175
|
+
tMin[_i4] = out.t;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (out.t > tMax[_i4]) {
|
|
179
|
+
tMax[_i4] = out.t;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
} // for all points
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
for (var _i5 = 0; _i5 < 3; _i5++) {
|
|
186
|
+
corner[_i5] = mean[_i5] + tMin[0] * max[_i5] + tMin[1] * mid[_i5] + tMin[2] * min[_i5];
|
|
187
|
+
max[_i5] *= tMax[0] - tMin[0];
|
|
188
|
+
mid[_i5] *= tMax[1] - tMin[1];
|
|
189
|
+
min[_i5] *= tMax[2] - tMin[2];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Build the OBB tree
|
|
194
|
+
* @param {Array} cells
|
|
195
|
+
* @param {vtkOBBNode} obbNode
|
|
196
|
+
* @param {Number} level
|
|
197
|
+
*/
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
function buildTree(cells, obbNode, level) {
|
|
201
|
+
var numCells = cells.length;
|
|
202
|
+
|
|
203
|
+
if (level > model.level) {
|
|
204
|
+
model.level = level;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
var axes = obbNode.getAxes();
|
|
208
|
+
var corner = obbNode.getCorner();
|
|
209
|
+
var size = [0, 0, 0];
|
|
210
|
+
computeOBB(cells, corner, axes[0], axes[1], axes[2], size);
|
|
211
|
+
obbNode.setAxes(axes);
|
|
212
|
+
obbNode.setCorner(corner); // Check whether to continue recursing; if so, create two children and
|
|
213
|
+
// assign cells to appropriate child.
|
|
214
|
+
|
|
215
|
+
if (level < model.maxLevel && numCells > model.numberOfCellsPerNode) {
|
|
216
|
+
var LHlist = [];
|
|
217
|
+
var RHlist = [];
|
|
218
|
+
var p = [0, 0, 0];
|
|
219
|
+
var n = [0, 0, 0]; // loop over three split planes to find acceptable one
|
|
220
|
+
|
|
221
|
+
for (var i = 0; i < 3; i++) {
|
|
222
|
+
// compute split point
|
|
223
|
+
p[i] = corner[i] + axes[0][i] / 2 + axes[1][i] / 2 + axes[2][i] / 2;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
var splitPlane = 0;
|
|
227
|
+
var splitAcceptable = 0;
|
|
228
|
+
var bestRatio = 1;
|
|
229
|
+
var foundBestSplit = 0;
|
|
230
|
+
var bestPlane = 0;
|
|
231
|
+
|
|
232
|
+
for (; !splitAcceptable && splitPlane < 3;) {
|
|
233
|
+
// compute split normal
|
|
234
|
+
for (var _i6 = 0; _i6 < 3; _i6++) {
|
|
235
|
+
n[_i6] = axes[splitPlane][_i6];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
normalize(n); // traverse cells, assigning to appropriate child list as necessary
|
|
239
|
+
|
|
240
|
+
var _loop = function _loop(_i7) {
|
|
241
|
+
var cellId = cells[_i7];
|
|
242
|
+
var pointsIDs = model.dataset.getCellPoints(cellId).cellPointIds;
|
|
243
|
+
var cellPts = [];
|
|
244
|
+
pointsIDs.forEach(function (id) {
|
|
245
|
+
var pt = [];
|
|
246
|
+
model.dataset.getPoints().getPoint(pointsIDs[id], pt);
|
|
247
|
+
cellPts.push(pt);
|
|
248
|
+
});
|
|
249
|
+
var c = [0, 0, 0];
|
|
250
|
+
var numPts = cellPts.length;
|
|
251
|
+
var negative = 0;
|
|
252
|
+
var positive = 0;
|
|
253
|
+
|
|
254
|
+
for (var j = 0; j < numPts; j++) {
|
|
255
|
+
var ptId = pointsIDs[j];
|
|
256
|
+
var x = model.dataset.getPoints().getPoint(ptId);
|
|
257
|
+
var val = n[0] * (x[0] - p[0]) + n[1] * (x[1] - p[1]) + n[2] * (x[2] - p[2]);
|
|
258
|
+
c[0] += x[0];
|
|
259
|
+
c[1] += x[1];
|
|
260
|
+
c[2] += x[2];
|
|
261
|
+
|
|
262
|
+
if (val < 0.0) {
|
|
263
|
+
negative = 1;
|
|
264
|
+
} else {
|
|
265
|
+
positive = 1;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (negative && positive) {
|
|
270
|
+
// Use centroid to decide straddle cases
|
|
271
|
+
c[0] /= numPts;
|
|
272
|
+
c[1] /= numPts;
|
|
273
|
+
c[2] /= numPts;
|
|
274
|
+
|
|
275
|
+
var _val = n[0] * (c[0] - p[0]) + n[1] * (c[1] - p[1]) + n[2] * (c[2] - p[2]);
|
|
276
|
+
|
|
277
|
+
if (_val < 0.0) {
|
|
278
|
+
LHlist.push(cellId);
|
|
279
|
+
} else {
|
|
280
|
+
RHlist.push(cellId);
|
|
281
|
+
}
|
|
282
|
+
} else if (negative) {
|
|
283
|
+
LHlist.push(cellId);
|
|
284
|
+
} else {
|
|
285
|
+
RHlist.push(cellId);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
for (var _i7 = 0; _i7 < numCells; _i7++) {
|
|
290
|
+
_loop(_i7);
|
|
291
|
+
} // for all cells
|
|
292
|
+
// evaluate this split
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
var numInLHnode = LHlist.length;
|
|
296
|
+
var numInRHnode = RHlist.length;
|
|
297
|
+
var ratio = Math.abs((numInRHnode - numInLHnode) / numCells); // see whether we've found acceptable split plane
|
|
298
|
+
|
|
299
|
+
if (ratio < 0.6 || foundBestSplit) {
|
|
300
|
+
// accept right off the bat
|
|
301
|
+
splitAcceptable = 1;
|
|
302
|
+
} else {
|
|
303
|
+
// not a great split try another
|
|
304
|
+
LHlist = [];
|
|
305
|
+
RHlist = [];
|
|
306
|
+
|
|
307
|
+
if (ratio < bestRatio) {
|
|
308
|
+
bestRatio = ratio;
|
|
309
|
+
bestPlane = splitPlane;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (++splitPlane === 3 && bestRatio < 0.95) {
|
|
313
|
+
// at closing time, even the ugly ones look good
|
|
314
|
+
splitPlane = bestPlane;
|
|
315
|
+
foundBestSplit = 1;
|
|
316
|
+
}
|
|
317
|
+
} // try another split
|
|
318
|
+
|
|
319
|
+
} // for each split
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
if (splitAcceptable) {
|
|
323
|
+
// otherwise recursion terminates
|
|
324
|
+
var LHnode = vtkOBBNode.newInstance();
|
|
325
|
+
var RHnode = vtkOBBNode.newInstance();
|
|
326
|
+
obbNode.setKids([LHnode, RHnode]);
|
|
327
|
+
LHnode.setParent(obbNode);
|
|
328
|
+
RHnode.setParent(obbNode);
|
|
329
|
+
cells.length = 0;
|
|
330
|
+
buildTree(LHlist, LHnode, level + 1);
|
|
331
|
+
buildTree(RHlist, RHnode, level + 1);
|
|
332
|
+
} else {
|
|
333
|
+
// free up local objects
|
|
334
|
+
LHlist = [];
|
|
335
|
+
RHlist = [];
|
|
336
|
+
}
|
|
337
|
+
} // if should build tree
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
if (cells && model.retainCellLists) {
|
|
341
|
+
obbNode.setCells(cells);
|
|
342
|
+
} else if (cells) {
|
|
343
|
+
cells.length = 0;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function generatePolygons(obbNode, level, repLevel, points, cells) {
|
|
348
|
+
if (level === repLevel || repLevel < 0 && obbNode.getKids()) {
|
|
349
|
+
var nbPoints = points.getNumberOfPoints();
|
|
350
|
+
var newPoints = [];
|
|
351
|
+
var newCells = [];
|
|
352
|
+
var cubeIds = [];
|
|
353
|
+
newPoints.push.apply(newPoints, _toConsumableArray(obbNode.getCorner()));
|
|
354
|
+
cubeIds[0] = nbPoints++;
|
|
355
|
+
var x = [];
|
|
356
|
+
newPoints.push.apply(newPoints, _toConsumableArray(add(obbNode.getCorner(), obbNode.getAxis(0), x)));
|
|
357
|
+
cubeIds[1] = nbPoints++;
|
|
358
|
+
var y = [];
|
|
359
|
+
newPoints.push.apply(newPoints, _toConsumableArray(add(obbNode.getCorner(), obbNode.getAxis(1), y)));
|
|
360
|
+
cubeIds[2] = nbPoints++;
|
|
361
|
+
var xy = [];
|
|
362
|
+
newPoints.push.apply(newPoints, _toConsumableArray(add(x, obbNode.getAxis(1), xy)));
|
|
363
|
+
cubeIds[3] = nbPoints++;
|
|
364
|
+
var z = [];
|
|
365
|
+
newPoints.push.apply(newPoints, _toConsumableArray(add(obbNode.getCorner(), obbNode.getAxis(2), z)));
|
|
366
|
+
cubeIds[4] = nbPoints++;
|
|
367
|
+
var xz = [];
|
|
368
|
+
newPoints.push.apply(newPoints, _toConsumableArray(add(x, obbNode.getAxis(2), xz)));
|
|
369
|
+
cubeIds[5] = nbPoints++;
|
|
370
|
+
var yz = [];
|
|
371
|
+
newPoints.push.apply(newPoints, _toConsumableArray(add(y, obbNode.getAxis(2), yz)));
|
|
372
|
+
cubeIds[6] = nbPoints++;
|
|
373
|
+
var xyz = [];
|
|
374
|
+
newPoints.push.apply(newPoints, _toConsumableArray(add(xy, obbNode.getAxis(2), xyz)));
|
|
375
|
+
cubeIds[7] = nbPoints++;
|
|
376
|
+
newCells.push(4, cubeIds[0], cubeIds[2], cubeIds[3], cubeIds[1]);
|
|
377
|
+
newCells.push(4, cubeIds[0], cubeIds[1], cubeIds[5], cubeIds[4]);
|
|
378
|
+
newCells.push(4, cubeIds[0], cubeIds[4], cubeIds[6], cubeIds[2]);
|
|
379
|
+
newCells.push(4, cubeIds[1], cubeIds[3], cubeIds[7], cubeIds[5]);
|
|
380
|
+
newCells.push(4, cubeIds[4], cubeIds[5], cubeIds[7], cubeIds[6]);
|
|
381
|
+
newCells.push(4, cubeIds[2], cubeIds[6], cubeIds[7], cubeIds[3]);
|
|
382
|
+
points.setData(pushArray(points.getData(), newPoints));
|
|
383
|
+
cells.setData(pushArray(cells.getData(), newCells));
|
|
384
|
+
} else if ((level < repLevel || repLevel < 0) && obbNode.getKids()) {
|
|
385
|
+
generatePolygons(obbNode.getKids()[0], level + 1, repLevel, points, cells);
|
|
386
|
+
generatePolygons(obbNode.getKids()[1], level + 1, repLevel, points, cells);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Transform the whole OBB tree by using input transform
|
|
391
|
+
* @param {Transform} transform vtkjs Transform object
|
|
392
|
+
*/
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
publicAPI.transform = function (transform) {
|
|
396
|
+
// Setup matrix used to transform vectors
|
|
397
|
+
var matrix = mat4.create();
|
|
398
|
+
mat4.copy(matrix, transform.getMatrix());
|
|
399
|
+
matrix[12] = 0;
|
|
400
|
+
matrix[13] = 0;
|
|
401
|
+
matrix[14] = 0;
|
|
402
|
+
matrix[15] = 1;
|
|
403
|
+
var transformVector = vtkMatrixBuilder.buildFromRadian().setMatrix(matrix);
|
|
404
|
+
var obbStack = new Array(model.level + 1);
|
|
405
|
+
obbStack[0] = model.tree;
|
|
406
|
+
var depth = 1;
|
|
407
|
+
|
|
408
|
+
while (depth > 0) {
|
|
409
|
+
depth -= 1;
|
|
410
|
+
var node = obbStack[depth];
|
|
411
|
+
var corner = node.getCorner();
|
|
412
|
+
var max = node.getAxis(0);
|
|
413
|
+
var mid = node.getAxis(1);
|
|
414
|
+
var min = node.getAxis(2);
|
|
415
|
+
transform.apply(corner);
|
|
416
|
+
transformVector.apply(max);
|
|
417
|
+
transformVector.apply(mid);
|
|
418
|
+
transformVector.apply(min);
|
|
419
|
+
node.setCorner(corner);
|
|
420
|
+
node.setAxes([max, mid, min]);
|
|
421
|
+
|
|
422
|
+
if (node.getKids() !== null) {
|
|
423
|
+
// push kids onto stack
|
|
424
|
+
obbStack[depth] = node.getKids()[0];
|
|
425
|
+
obbStack[depth + 1] = node.getKids()[1];
|
|
426
|
+
depth += 2;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
/**
|
|
431
|
+
* Deep copy input node into class attribute tree
|
|
432
|
+
* @param {vtkOBBNode} tree
|
|
433
|
+
* @returns
|
|
434
|
+
*/
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
publicAPI.deepCopy = function (tree) {
|
|
438
|
+
if (!tree) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
publicAPI.setLevel(tree.getLevel());
|
|
443
|
+
publicAPI.setRetainCellLists(tree.getRetainCellLists());
|
|
444
|
+
publicAPI.setDataset(tree.getDataset());
|
|
445
|
+
publicAPI.setAutomatic(tree.getAutomatic());
|
|
446
|
+
publicAPI.setNumberOfCellsPerNode(tree.getNumberOfCellsPerNode());
|
|
447
|
+
publicAPI.setTolerance(tree.getTolerance());
|
|
448
|
+
var root = tree.getTree();
|
|
449
|
+
|
|
450
|
+
if (root) {
|
|
451
|
+
model.tree = vtkOBBNode.newInstance();
|
|
452
|
+
model.tree.deepCopy(root);
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
/**
|
|
456
|
+
* A method to compute the OBB of a dataset without having to go through the
|
|
457
|
+
* Execute method; It does set
|
|
458
|
+
* @param {vtkPolyData} input
|
|
459
|
+
* @param {Array[3]} corner
|
|
460
|
+
* @param {Array[3]} max
|
|
461
|
+
* @param {Array[3]} mid
|
|
462
|
+
* @param {Array[3]} min
|
|
463
|
+
* @param {Array[3]} size
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
publicAPI.computeOBBFromDataset = function (input, corner, max, mid, min, size) {
|
|
468
|
+
if (!input) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
var numPts = input.getPoints().getNumberOfPoints();
|
|
473
|
+
var numCells = input.getNumberOfCells();
|
|
474
|
+
|
|
475
|
+
if (numPts < 1 || numCells < 1) {
|
|
476
|
+
vtkErrorMacro("Can't compute OBB - no data available!");
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
model.dataset = input;
|
|
481
|
+
model.OBBCount = 0;
|
|
482
|
+
model.insertedPoints = Array.from({
|
|
483
|
+
length: numPts
|
|
484
|
+
}, function (_) {
|
|
485
|
+
return 0;
|
|
486
|
+
});
|
|
487
|
+
model.pointsList = [];
|
|
488
|
+
var cellList = Array.from({
|
|
489
|
+
length: numCells
|
|
490
|
+
}, function (_, i) {
|
|
491
|
+
return i;
|
|
492
|
+
});
|
|
493
|
+
computeOBB(cellList, corner, max, mid, min, size);
|
|
494
|
+
};
|
|
495
|
+
/**
|
|
496
|
+
* Returns true if nodeB and nodeA are disjoint after optional
|
|
497
|
+
* transformation of nodeB with matrix XformBtoA
|
|
498
|
+
* @param {vtkOBBNode} nodeA
|
|
499
|
+
* @param {vtkOBBNode} nodeB
|
|
500
|
+
* @param {mat4} XformBtoA
|
|
501
|
+
*/
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
publicAPI.disjointOBBNodes = function (nodeA, nodeB, XformBtoA) {
|
|
505
|
+
if (!nodeA || !nodeB) {
|
|
506
|
+
return 5; // A and B are disjoint
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
var input = new Array(4);
|
|
510
|
+
var output = new Array(4);
|
|
511
|
+
var eps = model.tolerance;
|
|
512
|
+
var pA = nodeA;
|
|
513
|
+
var pB = vtkOBBNode.newInstance();
|
|
514
|
+
var dotAB = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
515
|
+
|
|
516
|
+
if (XformBtoA) {
|
|
517
|
+
// Here we assume that XformBtoA is an orthogonal matrix
|
|
518
|
+
input[0] = nodeB.getCorner()[0];
|
|
519
|
+
input[1] = nodeB.getCorner()[1];
|
|
520
|
+
input[2] = nodeB.getCorner()[2];
|
|
521
|
+
input[3] = 1.0;
|
|
522
|
+
vec4.transformMat4(output, input, XformBtoA);
|
|
523
|
+
pB.setCorner([output[0] / output[3], output[1] / output[3], output[2] / output[3]]); // Clean this up when the bug input MultiplyVectors is fixed!
|
|
524
|
+
|
|
525
|
+
for (var ii = 0; ii < 3; ii++) {
|
|
526
|
+
pB.getAxis(0)[ii] = nodeB.getCorner()[ii] + nodeB.getAxis(0)[ii];
|
|
527
|
+
pB.getAxis(1)[ii] = nodeB.getCorner()[ii] + nodeB.getAxis(1)[ii];
|
|
528
|
+
pB.getAxis(2)[ii] = nodeB.getCorner()[ii] + nodeB.getAxis(2)[ii];
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
for (var _ii = 0; _ii < 3; _ii++) {
|
|
532
|
+
input[0] = pB.getAxis(_ii)[0];
|
|
533
|
+
input[1] = pB.getAxis(_ii)[1];
|
|
534
|
+
input[2] = pB.getAxis(_ii)[2];
|
|
535
|
+
input[3] = 1.0;
|
|
536
|
+
vec4.transformMat4(output, input, XformBtoA);
|
|
537
|
+
pB.getAxis(_ii)[0] = output[0] / output[3];
|
|
538
|
+
pB.getAxis(_ii)[1] = output[1] / output[3];
|
|
539
|
+
pB.getAxis(_ii)[2] = output[2] / output[3];
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
for (var _ii2 = 0; _ii2 < 3; _ii2++) {
|
|
543
|
+
pB.getAxis(0)[_ii2] = pB.getAxis(0)[_ii2] - pB.getCorner()[_ii2];
|
|
544
|
+
pB.getAxis(1)[_ii2] = pB.getAxis(1)[_ii2] - pB.getCorner()[_ii2];
|
|
545
|
+
pB.getAxis(2)[_ii2] = pB.getAxis(2)[_ii2] - pB.getCorner()[_ii2];
|
|
546
|
+
}
|
|
547
|
+
} else {
|
|
548
|
+
pB = nodeB;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
var centerA = [0, 0, 0];
|
|
552
|
+
var centerB = [0, 0, 0];
|
|
553
|
+
var AtoB = [0, 0, 0];
|
|
554
|
+
|
|
555
|
+
for (var _ii3 = 0; _ii3 < 3; _ii3++) {
|
|
556
|
+
centerA[_ii3] = pA.getCorner()[_ii3] + 0.5 * (pA.getAxis(0)[_ii3] + pA.getAxis(1)[_ii3] + pA.getAxis(2)[_ii3]);
|
|
557
|
+
centerB[_ii3] = pB.getCorner()[_ii3] + 0.5 * (pB.getAxis(0)[_ii3] + pB.getAxis(1)[_ii3] + pB.getAxis(2)[_ii3]);
|
|
558
|
+
AtoB[_ii3] = centerB[_ii3] - centerA[_ii3];
|
|
559
|
+
} // Project maximal and minimal corners onto line between centers
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
var rangeAmin = dot(pA.getCorner(), AtoB);
|
|
563
|
+
var rangeAmax = rangeAmin;
|
|
564
|
+
var rangeBmin = dot(pB.getCorner(), AtoB);
|
|
565
|
+
var rangeBmax = rangeBmin;
|
|
566
|
+
var dotA = 0;
|
|
567
|
+
var dotB = 0;
|
|
568
|
+
|
|
569
|
+
for (var _ii4 = 0; _ii4 < 3; _ii4++) {
|
|
570
|
+
// compute A range
|
|
571
|
+
dotA = dot(pA.getAxis(_ii4), AtoB);
|
|
572
|
+
|
|
573
|
+
if (dotA > 0) {
|
|
574
|
+
rangeAmax += dotA;
|
|
575
|
+
} else {
|
|
576
|
+
rangeAmin += dotA;
|
|
577
|
+
} // compute B range
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
dotB = dot(pB.getAxis(_ii4), AtoB);
|
|
581
|
+
|
|
582
|
+
if (dotB > 0) {
|
|
583
|
+
rangeBmax += dotB;
|
|
584
|
+
} else {
|
|
585
|
+
rangeBmin += dotB;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
if (rangeAmax + eps < rangeBmin || rangeBmax + eps < rangeAmin) {
|
|
590
|
+
return 1; // A and B are Disjoint by the 1st test.
|
|
591
|
+
} // now check for a separation plane parallel to the faces of B
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
for (var _ii5 = 0; _ii5 < 3; _ii5++) {
|
|
595
|
+
// plane is normal to pB.getAxis(ii)
|
|
596
|
+
// computing B range is easy...
|
|
597
|
+
rangeBmin = dot(pB.getCorner(), pB.getAxis(_ii5));
|
|
598
|
+
rangeBmax = rangeBmin;
|
|
599
|
+
rangeBmax += dot(pB.getAxis(_ii5), pB.getAxis(_ii5)); // compute A range...
|
|
600
|
+
|
|
601
|
+
rangeAmin = dot(pA.getCorner(), pB.getAxis(_ii5));
|
|
602
|
+
rangeAmax = rangeAmin;
|
|
603
|
+
|
|
604
|
+
for (var jj = 0; jj < 3; jj++) {
|
|
605
|
+
// (note: we are saving all 9 dotproducts for future use)
|
|
606
|
+
dotA = dot(pB.getAxis(_ii5), pA.getAxis(jj));
|
|
607
|
+
dotAB[_ii5 * 3 + jj] = dotA;
|
|
608
|
+
|
|
609
|
+
if (dotA > 0) {
|
|
610
|
+
rangeAmax += dotA;
|
|
611
|
+
} else {
|
|
612
|
+
rangeAmin += dotA;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if (rangeAmax + eps < rangeBmin || rangeBmax + eps < rangeAmin) {
|
|
617
|
+
return 2; // A and B are Disjoint by the 3rd test.
|
|
618
|
+
}
|
|
619
|
+
} // now check for a separation plane parallel to the faces of A
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
for (var _ii6 = 0; _ii6 < 3; _ii6++) {
|
|
623
|
+
// plane is normal to pA.getAxis(ii)
|
|
624
|
+
// computing A range is easy...
|
|
625
|
+
rangeAmin = dot(pA.getCorner(), pA.getAxis(_ii6));
|
|
626
|
+
rangeAmax = rangeAmin;
|
|
627
|
+
rangeAmax += dot(pA.getAxis(_ii6), pA.getAxis(_ii6)); // compute B range...
|
|
628
|
+
|
|
629
|
+
rangeBmin = dot(pB.getCorner(), pA.getAxis(_ii6));
|
|
630
|
+
rangeBmax = rangeBmin;
|
|
631
|
+
|
|
632
|
+
for (var _jj = 0; _jj < 3; _jj++) {
|
|
633
|
+
// (note: we are using the 9 dotproducts computed earlier)
|
|
634
|
+
dotB = dotAB[_jj * 3 + _ii6];
|
|
635
|
+
|
|
636
|
+
if (dotB > 0) {
|
|
637
|
+
rangeBmax += dotB;
|
|
638
|
+
} else {
|
|
639
|
+
rangeBmin += dotB;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (rangeAmax + eps < rangeBmin || rangeBmax + eps < rangeAmin) {
|
|
644
|
+
return 3; // A and B are Disjoint by the 2nd test.
|
|
645
|
+
}
|
|
646
|
+
} // Bad luck: now we must look for a separation plane parallel
|
|
647
|
+
// to one edge from A and one edge from B.
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
for (var _ii7 = 0; _ii7 < 3; _ii7++) {
|
|
651
|
+
for (var _jj2 = 0; _jj2 < 3; _jj2++) {
|
|
652
|
+
// the plane is normal to pA.getAxis(ii) X pB.getAxis(jj)
|
|
653
|
+
cross(pA.getAxis(_ii7), pB.getAxis(_jj2), AtoB);
|
|
654
|
+
rangeAmin = dot(pA.getCorner(), AtoB);
|
|
655
|
+
rangeAmax = rangeAmin;
|
|
656
|
+
rangeBmin = dot(pB.getCorner(), AtoB);
|
|
657
|
+
rangeBmax = rangeBmin;
|
|
658
|
+
|
|
659
|
+
for (var kk = 0; kk < 3; kk++) {
|
|
660
|
+
// compute A range
|
|
661
|
+
dotA = dot(pA.getAxis(kk), AtoB);
|
|
662
|
+
|
|
663
|
+
if (dotA > 0) {
|
|
664
|
+
rangeAmax += dotA;
|
|
665
|
+
} else {
|
|
666
|
+
rangeAmin += dotA;
|
|
667
|
+
} // compute B range
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
dotB = dot(pB.getAxis(kk), AtoB);
|
|
671
|
+
|
|
672
|
+
if (dotB > 0) {
|
|
673
|
+
rangeBmax += dotB;
|
|
674
|
+
} else {
|
|
675
|
+
rangeBmin += dotB;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (rangeAmax + eps < rangeBmin || rangeBmax + eps < rangeAmin) {
|
|
680
|
+
return 4; // A and B are Disjoint by the 4th test.
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
} // if we fall through to here, the OBB's overlap
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
return 0;
|
|
687
|
+
};
|
|
688
|
+
/**
|
|
689
|
+
* Intersect this OBBTree with OBBTreeB (as transformed) and
|
|
690
|
+
* call processing function for each intersecting leaf node pair.
|
|
691
|
+
* If the processing function returns a negative integer, terminate.
|
|
692
|
+
* For each intersecting leaf node pair, call callback.
|
|
693
|
+
* OBBTreeB is optionally transformed by XformBtoA before testing
|
|
694
|
+
* @param {vtkOBBTree} obbTreeB
|
|
695
|
+
* @param {mat4|null|undefined} XformBtoA
|
|
696
|
+
* @param {function|null|undefined} callback Compared function that takes in argument:
|
|
697
|
+
* nodeA (vtkOBBNode), nodeB (vtkOBBNode), XForm (mat4), arg
|
|
698
|
+
*/
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
publicAPI.intersectWithOBBTree = function (obbTreeB, XformBtoA) {
|
|
702
|
+
var onIntersect = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {
|
|
703
|
+
return -1;
|
|
704
|
+
};
|
|
705
|
+
var maxDepth = model.level;
|
|
706
|
+
var minDepth = obbTreeB.getLevel();
|
|
707
|
+
|
|
708
|
+
if (minDepth > maxDepth) {
|
|
709
|
+
minDepth = maxDepth;
|
|
710
|
+
maxDepth = obbTreeB.getLevel();
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
var maxStackDepth = 3 * minDepth + 2 * (maxDepth - minDepth) + 1;
|
|
714
|
+
var OBBStackA = new Array(maxStackDepth);
|
|
715
|
+
var OBBStackB = new Array(maxStackDepth);
|
|
716
|
+
OBBStackA[0] = model.tree;
|
|
717
|
+
OBBStackB[0] = obbTreeB.getTree();
|
|
718
|
+
var depth = 1;
|
|
719
|
+
var count = 0;
|
|
720
|
+
var returnValue = 0; // simulate recursion without overhead of real recursion.
|
|
721
|
+
|
|
722
|
+
while (depth > 0 && returnValue > -1) {
|
|
723
|
+
depth--;
|
|
724
|
+
var nodeA = OBBStackA[depth];
|
|
725
|
+
var nodeB = OBBStackB[depth];
|
|
726
|
+
|
|
727
|
+
if (!publicAPI.disjointOBBNodes(nodeA, nodeB, XformBtoA)) {
|
|
728
|
+
// Collision
|
|
729
|
+
if (!nodeA.getKids()) {
|
|
730
|
+
if (!nodeB.getKids()) {
|
|
731
|
+
returnValue = onIntersect(nodeA, nodeB, XformBtoA);
|
|
732
|
+
count += Math.abs(returnValue);
|
|
733
|
+
} else {
|
|
734
|
+
// A is a leaf, but B goes deeper.
|
|
735
|
+
OBBStackA[depth] = nodeA;
|
|
736
|
+
OBBStackB[depth] = nodeB.getKids()[0];
|
|
737
|
+
OBBStackA[depth + 1] = nodeA;
|
|
738
|
+
OBBStackB[depth + 1] = nodeB.getKids()[1];
|
|
739
|
+
depth += 2;
|
|
740
|
+
}
|
|
741
|
+
} else if (!nodeB.getKids()) {
|
|
742
|
+
// B is a leaf, but A goes deeper.
|
|
743
|
+
OBBStackB[depth] = nodeB;
|
|
744
|
+
OBBStackA[depth] = nodeA.getKids()[0];
|
|
745
|
+
OBBStackB[depth + 1] = nodeB;
|
|
746
|
+
OBBStackA[depth + 1] = nodeA.getKids()[1];
|
|
747
|
+
depth += 2;
|
|
748
|
+
} else {
|
|
749
|
+
// neither A nor B are leaves. Go to the next level.
|
|
750
|
+
OBBStackA[depth] = nodeA.getKids()[0];
|
|
751
|
+
OBBStackB[depth] = nodeB.getKids()[0];
|
|
752
|
+
OBBStackA[depth + 1] = nodeA.getKids()[1];
|
|
753
|
+
OBBStackB[depth + 1] = nodeB.getKids()[0];
|
|
754
|
+
OBBStackA[depth + 2] = nodeA.getKids()[0];
|
|
755
|
+
OBBStackB[depth + 2] = nodeB.getKids()[1];
|
|
756
|
+
OBBStackA[depth + 3] = nodeA.getKids()[1];
|
|
757
|
+
OBBStackB[depth + 3] = nodeB.getKids()[1];
|
|
758
|
+
depth += 4;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
return count;
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
publicAPI.triangleIntersectsNode = function (nodeA, p0, p1, p2, XformBtoA) {
|
|
767
|
+
var eps = model.tolerance;
|
|
768
|
+
var pA = nodeA;
|
|
769
|
+
var pB = [_toConsumableArray(p0), _toConsumableArray(p1), _toConsumableArray(p2)];
|
|
770
|
+
|
|
771
|
+
if (XformBtoA) {
|
|
772
|
+
// Here we assume that XformBtoA is an orthogonal matrix
|
|
773
|
+
var input = [0, 0, 0, 1];
|
|
774
|
+
var output = [];
|
|
775
|
+
|
|
776
|
+
for (var ii = 0; ii < 3; ii++) {
|
|
777
|
+
input[0] = pB[ii][0];
|
|
778
|
+
input[1] = pB[ii][1];
|
|
779
|
+
input[2] = pB[ii][2];
|
|
780
|
+
vec4.transformMat4(output, input, XformBtoA);
|
|
781
|
+
pB[ii][0] = output[0] / output[3];
|
|
782
|
+
pB[ii][1] = output[1] / output[3];
|
|
783
|
+
pB[ii][2] = output[2] / output[3];
|
|
784
|
+
}
|
|
785
|
+
} // now check for a separation plane parallel to the triangle
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
var v0 = [];
|
|
789
|
+
var v1 = [];
|
|
790
|
+
|
|
791
|
+
for (var _ii8 = 0; _ii8 < 3; _ii8++) {
|
|
792
|
+
// plane is normal to the triangle
|
|
793
|
+
v0[_ii8] = pB[1][_ii8] - pB[0][_ii8];
|
|
794
|
+
v1[_ii8] = pB[2][_ii8] - pB[0][_ii8];
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
var xprod = cross(v0, v1, []); // computing B range is easy...
|
|
798
|
+
|
|
799
|
+
var rangeBmax = dot(pB[0], xprod);
|
|
800
|
+
var rangeBmin = rangeBmax; // compute A range...
|
|
801
|
+
|
|
802
|
+
var rangeAmax = dot(pA.getCorner(), xprod);
|
|
803
|
+
var rangeAmin = rangeAmax;
|
|
804
|
+
var dotA;
|
|
805
|
+
|
|
806
|
+
for (var jj = 0; jj < 3; jj++) {
|
|
807
|
+
dotA = dot(xprod, pA.getAxis(jj));
|
|
808
|
+
|
|
809
|
+
if (dotA > 0) {
|
|
810
|
+
rangeAmax += dotA;
|
|
811
|
+
} else {
|
|
812
|
+
rangeAmin += dotA;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (rangeAmax + eps < rangeBmin || rangeBmax + eps < rangeAmin) {
|
|
817
|
+
return 0; // A and B are Disjoint by the 1st test.
|
|
818
|
+
} // now check for a separation plane parallel to the faces of A
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
for (var _ii9 = 0; _ii9 < 3; _ii9++) {
|
|
822
|
+
// plane is normal to pA->Axes[ii]
|
|
823
|
+
// computing A range is easy...
|
|
824
|
+
rangeAmax = dot(pA.getCorner(), pA.getAxis(_ii9));
|
|
825
|
+
rangeAmin = rangeAmax;
|
|
826
|
+
rangeAmax += dot(pA.getAxis(_ii9), pA.getAxis(_ii9)); // compute B range...
|
|
827
|
+
|
|
828
|
+
rangeBmax = dot(pB[0], pA.getAxis(_ii9));
|
|
829
|
+
rangeBmin = rangeBmax;
|
|
830
|
+
|
|
831
|
+
var _dotB = dot(pB[1], pA.getAxis(_ii9));
|
|
832
|
+
|
|
833
|
+
if (_dotB > rangeBmax) {
|
|
834
|
+
rangeBmax = _dotB;
|
|
835
|
+
} else {
|
|
836
|
+
rangeBmin = _dotB;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
_dotB = dot(pB[2], pA.getAxis(_ii9));
|
|
840
|
+
|
|
841
|
+
if (_dotB > rangeBmax) {
|
|
842
|
+
rangeBmax = _dotB;
|
|
843
|
+
} else if (_dotB < rangeBmin) {
|
|
844
|
+
rangeBmin = _dotB;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if (rangeAmax + eps < rangeBmin || rangeBmax + eps < rangeAmin) {
|
|
848
|
+
return 0; // A and B are Disjoint by the 2nd test.
|
|
849
|
+
}
|
|
850
|
+
} // Bad luck: now we must look for a separation plane parallel
|
|
851
|
+
// to one edge from A and one edge from B.
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
var AtoB = [];
|
|
855
|
+
var dotB;
|
|
856
|
+
|
|
857
|
+
for (var _ii10 = 0; _ii10 < 3; _ii10++) {
|
|
858
|
+
for (var _jj3 = 0; _jj3 < 3; _jj3++) {
|
|
859
|
+
// the plane is normal to pA->Axes[ii] X (pB[jj+1]-pB[jj])
|
|
860
|
+
v0[0] = pB[(_jj3 + 1) % 3][0] - pB[_jj3][0];
|
|
861
|
+
v0[1] = pB[(_jj3 + 1) % 3][1] - pB[_jj3][1];
|
|
862
|
+
v0[2] = pB[(_jj3 + 1) % 3][2] - pB[_jj3][2];
|
|
863
|
+
cross(pA.getAxis(_ii10), v0, AtoB);
|
|
864
|
+
rangeAmax = dot(pA.getCorner(), AtoB);
|
|
865
|
+
rangeAmin = rangeAmax;
|
|
866
|
+
rangeBmax = dot(pB[_jj3], AtoB);
|
|
867
|
+
rangeBmin = rangeBmax;
|
|
868
|
+
|
|
869
|
+
for (var kk = 0; kk < 3; kk++) {
|
|
870
|
+
// compute A range
|
|
871
|
+
dotA = dot(pA.getAxis(kk), AtoB);
|
|
872
|
+
|
|
873
|
+
if (dotA > 0) {
|
|
874
|
+
rangeAmax += dotA;
|
|
875
|
+
} else {
|
|
876
|
+
rangeAmin += dotA;
|
|
877
|
+
}
|
|
878
|
+
} // compute B range
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
dotB = dot(pB[(_jj3 + 2) % 3], AtoB);
|
|
882
|
+
|
|
883
|
+
if (dotB > rangeBmax) {
|
|
884
|
+
rangeBmax = dotB;
|
|
885
|
+
} else {
|
|
886
|
+
rangeBmin = dotB;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
if (rangeAmax + eps < rangeBmin || rangeBmax + eps < rangeAmin) {
|
|
890
|
+
return 0; // A and B are Disjoint by the 3rd test.
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
} // if we fall through to here, the OBB overlaps the triangle.
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
return 1;
|
|
897
|
+
};
|
|
898
|
+
/**
|
|
899
|
+
*
|
|
900
|
+
* @param {*} info must be an object with { obbTree1, intersectionLines }
|
|
901
|
+
* @param {*} node0
|
|
902
|
+
* @param {*} node1
|
|
903
|
+
* @param {*} transform
|
|
904
|
+
* @returns the number of intersection lines found
|
|
905
|
+
*/
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
publicAPI.findTriangleIntersections = function (info, node0, node1, transform) {
|
|
909
|
+
// Set up local structures to hold Impl array information
|
|
910
|
+
// vtkOBBTree* obbTree1 = info->OBBTree1;
|
|
911
|
+
// vtkCellArray* intersectionLines = info->IntersectionLines;
|
|
912
|
+
// vtkIdTypeArray* intersectionSurfaceId = info->SurfaceId;
|
|
913
|
+
// vtkIdTypeArray* intersectionCellIds0 = info->CellIds[0];
|
|
914
|
+
// vtkIdTypeArray* intersectionCellIds1 = info->CellIds[1];
|
|
915
|
+
// vtkPointLocator* pointMerger = info->PointMerger;
|
|
916
|
+
// double tolerance = info->Tolerance;
|
|
917
|
+
var mesh0 = publicAPI.getDataset();
|
|
918
|
+
var mesh1 = info.obbTree1.getDataset();
|
|
919
|
+
var pointOffset = info.intersectionLines.getPoints().getNumberOfPoints();
|
|
920
|
+
var intersectionPoints = [];
|
|
921
|
+
var intersectionLines = []; // The number of cells in OBBTree
|
|
922
|
+
|
|
923
|
+
var numCells0 = node0.getCells().length;
|
|
924
|
+
|
|
925
|
+
for (var id0 = 0; id0 < numCells0; id0++) {
|
|
926
|
+
var cellId0 = node0.getCells()[id0];
|
|
927
|
+
var type0 = mesh0.getCellType(cellId0); // Make sure the cell is a triangle
|
|
928
|
+
|
|
929
|
+
if (type0 === CellType.VTK_TRIANGLE) {
|
|
930
|
+
var _mesh0$getCellPoints = mesh0.getCellPoints(cellId0),
|
|
931
|
+
triPtIds0 = _mesh0$getCellPoints.cellPointIds;
|
|
932
|
+
|
|
933
|
+
var triPts0 = [[], [], []];
|
|
934
|
+
|
|
935
|
+
for (var id = 0; id < triPtIds0.length; id++) {
|
|
936
|
+
mesh0.getPoints().getPoint(triPtIds0[id], triPts0[id]);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
if (info.obbTree1.triangleIntersectsNode(node1, triPts0[0], triPts0[1], triPts0[2], transform)) {
|
|
940
|
+
var numCells1 = node1.getCells().length;
|
|
941
|
+
|
|
942
|
+
for (var id1 = 0; id1 < numCells1; id1++) {
|
|
943
|
+
var cellId1 = node1.getCells()[id1];
|
|
944
|
+
var type1 = mesh1.getCellType(cellId1);
|
|
945
|
+
|
|
946
|
+
if (type1 === CellType.VTK_TRIANGLE) {
|
|
947
|
+
// See if the two cells actually intersect. If they do,
|
|
948
|
+
// add an entry into the intersection maps and add an
|
|
949
|
+
// intersection line.
|
|
950
|
+
var _mesh1$getCellPoints = mesh1.getCellPoints(cellId1),
|
|
951
|
+
triPtIds1 = _mesh1$getCellPoints.cellPointIds;
|
|
952
|
+
|
|
953
|
+
var triPts1 = [[], [], []];
|
|
954
|
+
|
|
955
|
+
for (var _id = 0; _id < triPtIds1.length; _id++) {
|
|
956
|
+
mesh1.getPoints().getPoint(triPtIds1[_id], triPts1[_id]);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
var _vtkTriangle$intersec = vtkTriangle.intersectWithTriangle.apply(vtkTriangle, triPts0.concat(triPts1, [model.tolerance])),
|
|
960
|
+
intersect = _vtkTriangle$intersec.intersect,
|
|
961
|
+
coplanar = _vtkTriangle$intersec.coplanar,
|
|
962
|
+
outpt0 = _vtkTriangle$intersec.pt1,
|
|
963
|
+
outpt1 = _vtkTriangle$intersec.pt2;
|
|
964
|
+
|
|
965
|
+
if (intersect && !coplanar) {
|
|
966
|
+
var pointId = intersectionPoints.length / 3;
|
|
967
|
+
intersectionPoints.push.apply(intersectionPoints, _toConsumableArray(outpt0).concat(_toConsumableArray(outpt1)));
|
|
968
|
+
intersectionLines.push(2, pointOffset + pointId, pointOffset + pointId + 1);
|
|
969
|
+
} // If actual intersection, add point and cell to edge, line,
|
|
970
|
+
// and surface maps!
|
|
971
|
+
|
|
972
|
+
/*
|
|
973
|
+
if (coplanar) {
|
|
974
|
+
// Coplanar triangle intersection is not handled.
|
|
975
|
+
// This intersection will not be included in the output. TODO
|
|
976
|
+
// vtkDebugMacro(<<"Coplanar");
|
|
977
|
+
intersects = false;
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
if (intersects)
|
|
981
|
+
{
|
|
982
|
+
vtkIdType lineId = info.intersectionLines->GetNumberOfCells();
|
|
983
|
+
vtkIdType ptId0, ptId1;
|
|
984
|
+
int unique[2];
|
|
985
|
+
unique[0] = pointMerger->InsertUniquePoint(outpt0, ptId0);
|
|
986
|
+
unique[1] = pointMerger->InsertUniquePoint(outpt1, ptId1);
|
|
987
|
+
int addline = 1;
|
|
988
|
+
if (ptId0 == ptId1)
|
|
989
|
+
{
|
|
990
|
+
addline = 0;
|
|
991
|
+
}
|
|
992
|
+
if (ptId0 == ptId1 && surfaceid[0] != surfaceid[1])
|
|
993
|
+
{
|
|
994
|
+
intersectionSurfaceId->InsertValue(ptId0, 3);
|
|
995
|
+
}
|
|
996
|
+
else
|
|
997
|
+
{
|
|
998
|
+
if (unique[0])
|
|
999
|
+
{
|
|
1000
|
+
intersectionSurfaceId->InsertValue(ptId0, surfaceid[0]);
|
|
1001
|
+
}
|
|
1002
|
+
else
|
|
1003
|
+
{
|
|
1004
|
+
if (intersectionSurfaceId->GetValue(ptId0) != 3)
|
|
1005
|
+
{
|
|
1006
|
+
intersectionSurfaceId->InsertValue(ptId0, surfaceid[0]);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
if (unique[1])
|
|
1010
|
+
{
|
|
1011
|
+
intersectionSurfaceId->InsertValue(ptId1, surfaceid[1]);
|
|
1012
|
+
}
|
|
1013
|
+
else
|
|
1014
|
+
{
|
|
1015
|
+
if (intersectionSurfaceId->GetValue(ptId1) != 3)
|
|
1016
|
+
{
|
|
1017
|
+
intersectionSurfaceId->InsertValue(ptId1, surfaceid[1]);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
info->IntersectionPtsMap[0]->insert(std::make_pair(ptId0, cellId0));
|
|
1022
|
+
info->IntersectionPtsMap[1]->insert(std::make_pair(ptId0, cellId1));
|
|
1023
|
+
info->IntersectionPtsMap[0]->insert(std::make_pair(ptId1, cellId0));
|
|
1024
|
+
info->IntersectionPtsMap[1]->insert(std::make_pair(ptId1, cellId1));
|
|
1025
|
+
// Check to see if duplicate line. Line can only be a duplicate
|
|
1026
|
+
// line if both points are not unique and they don't
|
|
1027
|
+
// equal each other
|
|
1028
|
+
if (!unique[0] && !unique[1] && ptId0 != ptId1)
|
|
1029
|
+
{
|
|
1030
|
+
vtkSmartPointer<vtkPolyData> lineTest = vtkSmartPointer<vtkPolyData>::New();
|
|
1031
|
+
lineTest->SetPoints(pointMerger->GetPoints());
|
|
1032
|
+
lineTest->SetLines(intersectionLines);
|
|
1033
|
+
lineTest->BuildLinks();
|
|
1034
|
+
int newLine = info->CheckLine(lineTest, ptId0, ptId1);
|
|
1035
|
+
if (newLine == 0)
|
|
1036
|
+
{
|
|
1037
|
+
addline = 0;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
if (addline)
|
|
1041
|
+
{
|
|
1042
|
+
// If the line is new and does not consist of two identical
|
|
1043
|
+
// points, add the line to the intersection and update
|
|
1044
|
+
// mapping information
|
|
1045
|
+
intersectionLines->InsertNextCell(2);
|
|
1046
|
+
intersectionLines->InsertCellPoint(ptId0);
|
|
1047
|
+
intersectionLines->InsertCellPoint(ptId1);
|
|
1048
|
+
intersectionCellIds0->InsertNextValue(cellId0);
|
|
1049
|
+
intersectionCellIds1->InsertNextValue(cellId1);
|
|
1050
|
+
info->PointCellIds[0]->InsertValue(ptId0, cellId0);
|
|
1051
|
+
info->PointCellIds[0]->InsertValue(ptId1, cellId0);
|
|
1052
|
+
info->PointCellIds[1]->InsertValue(ptId0, cellId1);
|
|
1053
|
+
info->PointCellIds[1]->InsertValue(ptId1, cellId1);
|
|
1054
|
+
info->IntersectionMap[0]->insert(std::make_pair(cellId0, lineId));
|
|
1055
|
+
info->IntersectionMap[1]->insert(std::make_pair(cellId1, lineId));
|
|
1056
|
+
// Check which edges of cellId0 and cellId1 outpt0 and
|
|
1057
|
+
// outpt1 are on, if any.
|
|
1058
|
+
int isOnEdge = 0;
|
|
1059
|
+
int m0p0 = 0, m0p1 = 0, m1p0 = 0, m1p1 = 0;
|
|
1060
|
+
for (vtkIdType edgeId = 0; edgeId < 3; edgeId++)
|
|
1061
|
+
{
|
|
1062
|
+
isOnEdge = info->AddToPointEdgeMap(
|
|
1063
|
+
0, ptId0, outpt0, mesh0, cellId0, edgeId, lineId, triPtIds0);
|
|
1064
|
+
if (isOnEdge != -1)
|
|
1065
|
+
{
|
|
1066
|
+
m0p0++;
|
|
1067
|
+
}
|
|
1068
|
+
isOnEdge = info->AddToPointEdgeMap(
|
|
1069
|
+
0, ptId1, outpt1, mesh0, cellId0, edgeId, lineId, triPtIds0);
|
|
1070
|
+
if (isOnEdge != -1)
|
|
1071
|
+
{
|
|
1072
|
+
m0p1++;
|
|
1073
|
+
}
|
|
1074
|
+
isOnEdge = info->AddToPointEdgeMap(
|
|
1075
|
+
1, ptId0, outpt0, mesh1, cellId1, edgeId, lineId, triPtIds1);
|
|
1076
|
+
if (isOnEdge != -1)
|
|
1077
|
+
{
|
|
1078
|
+
m1p0++;
|
|
1079
|
+
}
|
|
1080
|
+
isOnEdge = info->AddToPointEdgeMap(
|
|
1081
|
+
1, ptId1, outpt1, mesh1, cellId1, edgeId, lineId, triPtIds1);
|
|
1082
|
+
if (isOnEdge != -1)
|
|
1083
|
+
{
|
|
1084
|
+
m1p1++;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
// Special cases caught by tolerance and not from the Point
|
|
1088
|
+
// Merger
|
|
1089
|
+
if (m0p0 > 0 && m1p0 > 0)
|
|
1090
|
+
{
|
|
1091
|
+
intersectionSurfaceId->InsertValue(ptId0, 3);
|
|
1092
|
+
}
|
|
1093
|
+
if (m0p1 > 0 && m1p1 > 0)
|
|
1094
|
+
{
|
|
1095
|
+
intersectionSurfaceId->InsertValue(ptId1, 3);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
// Add information about origin surface to std::maps for
|
|
1099
|
+
// checks later
|
|
1100
|
+
if (intersectionSurfaceId->GetValue(ptId0) == 1)
|
|
1101
|
+
{
|
|
1102
|
+
info->IntersectionPtsMap[0]->insert(std::make_pair(ptId0, cellId0));
|
|
1103
|
+
}
|
|
1104
|
+
else if (intersectionSurfaceId->GetValue(ptId0) == 2)
|
|
1105
|
+
{
|
|
1106
|
+
info->IntersectionPtsMap[1]->insert(std::make_pair(ptId0, cellId1));
|
|
1107
|
+
}
|
|
1108
|
+
else
|
|
1109
|
+
{
|
|
1110
|
+
info->IntersectionPtsMap[0]->insert(std::make_pair(ptId0, cellId0));
|
|
1111
|
+
info->IntersectionPtsMap[1]->insert(std::make_pair(ptId0, cellId1));
|
|
1112
|
+
}
|
|
1113
|
+
if (intersectionSurfaceId->GetValue(ptId1) == 1)
|
|
1114
|
+
{
|
|
1115
|
+
info->IntersectionPtsMap[0]->insert(std::make_pair(ptId1, cellId0));
|
|
1116
|
+
}
|
|
1117
|
+
else if (intersectionSurfaceId->GetValue(ptId1) == 2)
|
|
1118
|
+
{
|
|
1119
|
+
info->IntersectionPtsMap[1]->insert(std::make_pair(ptId1, cellId1));
|
|
1120
|
+
}
|
|
1121
|
+
else
|
|
1122
|
+
{
|
|
1123
|
+
info->IntersectionPtsMap[0]->insert(std::make_pair(ptId1, cellId0));
|
|
1124
|
+
info->IntersectionPtsMap[1]->insert(std::make_pair(ptId1, cellId1));
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
*/
|
|
1128
|
+
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
if (intersectionPoints.length) {
|
|
1136
|
+
var points = vtkPoints.newInstance();
|
|
1137
|
+
points.setData(pushArray(info.intersectionLines.getPoints().getData(), intersectionPoints));
|
|
1138
|
+
info.intersectionLines.setPoints(points);
|
|
1139
|
+
var lines = vtkCellArray.newInstance();
|
|
1140
|
+
lines.setData(pushArray(info.intersectionLines.getLines().getData(), intersectionLines));
|
|
1141
|
+
info.intersectionLines.setLines(lines);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
return intersectionLines.length / 3;
|
|
1145
|
+
};
|
|
1146
|
+
/**
|
|
1147
|
+
* Create polygonal representation for OBB tree at specified level. If
|
|
1148
|
+
* level < 0, then the leaf OBB nodes will be gathered. The aspect ratio (ar)
|
|
1149
|
+
* and line diameter (d) are used to control the building of the
|
|
1150
|
+
* representation. If a OBB node edge ratio's are greater than ar, then the
|
|
1151
|
+
* dimension of the OBB is collapsed (OBB->plane->line). A "line" OBB will be
|
|
1152
|
+
* represented either as two crossed polygons, or as a line, depending on
|
|
1153
|
+
* the relative diameter of the OBB compared to the diameter (d).
|
|
1154
|
+
* @param {Number} level Level of the representation
|
|
1155
|
+
* @returns {vtkPolyData}
|
|
1156
|
+
*/
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
publicAPI.generateRepresentation = function (level) {
|
|
1160
|
+
if (!model.tree) {
|
|
1161
|
+
vtkErrorMacro('No tree to generate representation for');
|
|
1162
|
+
return null;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
var points = vtkPoints.newInstance();
|
|
1166
|
+
var polys = vtkCellArray.newInstance();
|
|
1167
|
+
generatePolygons(model.tree, 0, level, points, polys);
|
|
1168
|
+
var output = vtkPolyData.newInstance();
|
|
1169
|
+
output.setPoints(points);
|
|
1170
|
+
output.setPolys(polys);
|
|
1171
|
+
return output;
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
publicAPI.buildLocator = function () {
|
|
1175
|
+
if (model.dataset === null) {
|
|
1176
|
+
vtkErrorMacro("Can't build OBB tree - no data available!");
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
var numPts = model.dataset.getPoints().getNumberOfPoints();
|
|
1181
|
+
var numCells = model.dataset.getNumberOfCells();
|
|
1182
|
+
|
|
1183
|
+
if (numPts < 1 || numCells < 1) {
|
|
1184
|
+
vtkErrorMacro("Can't build OBB tree - no data available!");
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
model.OBBCount = 0; // Initialize an array of numPts elements set to value 0
|
|
1189
|
+
|
|
1190
|
+
model.insertedPoints = Array.from({
|
|
1191
|
+
length: numPts
|
|
1192
|
+
}, function (_) {
|
|
1193
|
+
return 0;
|
|
1194
|
+
});
|
|
1195
|
+
model.pointsList = [];
|
|
1196
|
+
var cellList = Array.from({
|
|
1197
|
+
length: numCells
|
|
1198
|
+
}, function (_, i) {
|
|
1199
|
+
return i;
|
|
1200
|
+
});
|
|
1201
|
+
model.tree = vtkOBBNode.newInstance();
|
|
1202
|
+
model.level = 0;
|
|
1203
|
+
buildTree(cellList, model.tree, 0);
|
|
1204
|
+
model.insertedPoints = [];
|
|
1205
|
+
model.pointsList = [];
|
|
1206
|
+
publicAPI.modified();
|
|
1207
|
+
};
|
|
1208
|
+
} // ----------------------------------------------------------------------------
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
var DEFAULT_VALUES = {
|
|
1212
|
+
tolerance: 0.01,
|
|
1213
|
+
automatic: true,
|
|
1214
|
+
numberOfCellsPerNode: 32,
|
|
1215
|
+
dataset: null,
|
|
1216
|
+
tree: null,
|
|
1217
|
+
pointsList: [],
|
|
1218
|
+
insertedPoints: [],
|
|
1219
|
+
OBBCount: 0,
|
|
1220
|
+
level: 8,
|
|
1221
|
+
maxLevel: 8,
|
|
1222
|
+
retainCellLists: 1
|
|
1223
|
+
}; // ----------------------------------------------------------------------------
|
|
1224
|
+
|
|
1225
|
+
function extend(publicAPI, model) {
|
|
1226
|
+
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1227
|
+
Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API
|
|
1228
|
+
|
|
1229
|
+
macro.setGet(publicAPI, model, ['tolerance', 'automatic', 'numberOfCellsPerNode', 'dataset', 'tree', 'maxLevel', 'level', 'retainCellLists']); // Make this a VTK object
|
|
1230
|
+
|
|
1231
|
+
macro.obj(publicAPI, model); // Object specific methods
|
|
1232
|
+
|
|
1233
|
+
vtkOBBTree(publicAPI, model);
|
|
1234
|
+
} // ----------------------------------------------------------------------------
|
|
1235
|
+
|
|
1236
|
+
var newInstance = macro.newInstance(extend, 'vtkOBBTree'); // ----------------------------------------------------------------------------
|
|
1237
|
+
|
|
1238
|
+
var vtkOBBTree$1 = {
|
|
1239
|
+
newInstance: newInstance,
|
|
1240
|
+
extend: extend
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
export { vtkOBBTree$1 as default, extend, newInstance };
|