@kitware/vtk.js 25.6.0 → 25.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/Core/CellArray.d.ts +20 -8
- package/Common/Core/CellArray.js +25 -6
- package/Common/Core/DataArray.d.ts +159 -15
- package/Common/Core/DataArray.js +181 -26
- package/Common/Core/Math/index.js +1 -1
- package/Common/Core/Math.js +1 -1
- package/Common/Core/Points.d.ts +6 -5
- package/Common/Core/Points.js +8 -4
- package/Common/DataModel/AbstractPointLocator.d.ts +54 -0
- package/Common/DataModel/AbstractPointLocator.js +40 -0
- package/Common/DataModel/DataSetAttributes/FieldData.d.ts +33 -22
- package/Common/DataModel/DataSetAttributes/FieldData.js +91 -9
- package/Common/DataModel/DataSetAttributes.d.ts +44 -0
- package/Common/DataModel/DataSetAttributes.js +11 -0
- package/Common/DataModel/IncrementalOctreeNode.d.ts +282 -0
- package/Common/DataModel/IncrementalOctreeNode.js +621 -0
- package/Common/DataModel/IncrementalOctreePointLocator.d.ts +61 -0
- package/Common/DataModel/IncrementalOctreePointLocator.js +342 -0
- package/Common/DataModel/Line.js +1 -1
- 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/Polygon/Constants.js +12 -0
- package/Common/DataModel/Polygon.d.ts +38 -4
- package/Common/DataModel/Polygon.js +210 -6
- 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/Triangle.d.ts +106 -81
- package/Common/DataModel/Triangle.js +1 -1
- package/Common/Transform/LandmarkTransform.js +1 -1
- package/Filters/Core/PolyDataNormals.js +1 -1
- package/Filters/General/ClipClosedSurface/Constants.js +10 -0
- package/Filters/General/ClipClosedSurface/ccsEdgeLocator.js +40 -0
- package/Filters/General/ClipClosedSurface.d.ts +95 -0
- package/Filters/General/ClipClosedSurface.js +971 -0
- package/Filters/General/ContourTriangulator/Constants.js +6 -0
- package/Filters/General/ContourTriangulator/helper.js +1951 -0
- package/Filters/General/ContourTriangulator.d.ts +122 -0
- package/Filters/General/ContourTriangulator.js +200 -0
- package/Filters/General/ImageMarchingCubes.js +1 -1
- package/Filters/General/MoleculeToRepresentation.js +1 -1
- package/Filters/General/OBBTree.js +1 -1
- package/Filters/General/TubeFilter.js +1 -1
- package/Filters/General/WindowedSincPolyDataFilter.js +1 -1
- package/Filters/Sources/PlaneSource.js +1 -1
- package/Filters/Texture/TextureMapToPlane.js +1 -1
- package/Interaction/Manipulators/KeyboardCameraManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraAxisRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
- package/Interaction/Style/InteractorStyleMPRSlice.js +1 -1
- package/Proxy/Core/View2DProxy.js +1 -1
- package/Rendering/Core/AbstractMapper.d.ts +7 -5
- package/Rendering/Core/AbstractMapper.js +6 -0
- package/Rendering/Core/Camera.js +1 -1
- package/Rendering/Core/CellPicker.js +3 -2
- package/Rendering/Core/Light.js +1 -1
- package/Rendering/Core/Picker.js +1 -1
- package/Rendering/OpenGL/PolyDataMapper.js +1 -1
- package/Rendering/WebGPU/BufferManager.js +1 -1
- package/Widgets/Core/StateBuilder/orientationMixin.js +1 -1
- package/Widgets/Manipulators/LineManipulator.js +1 -1
- package/Widgets/Manipulators/TrackballManipulator.js +1 -1
- package/Widgets/Representations/ResliceCursorContextRepresentation.js +1 -1
- 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/Widgets/Widgets3D/ShapeWidget/behavior.js +1 -1
- package/index.d.ts +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,971 @@
|
|
|
1
|
+
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
2
|
+
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
|
|
3
|
+
import macro from '../../macros.js';
|
|
4
|
+
import { d as dot, f as distance2BetweenPoints } from '../../Common/Core/Math/index.js';
|
|
5
|
+
import vtkCellArray from '../../Common/Core/CellArray.js';
|
|
6
|
+
import vtkDataArray from '../../Common/Core/DataArray.js';
|
|
7
|
+
import { VtkDataTypes } from '../../Common/Core/DataArray/Constants.js';
|
|
8
|
+
import vtkPoints from '../../Common/Core/Points.js';
|
|
9
|
+
import vtkDataSetAttributes from '../../Common/DataModel/DataSetAttributes.js';
|
|
10
|
+
import vtkPolyData from '../../Common/DataModel/PolyData.js';
|
|
11
|
+
import vtkContourTriangulator from './ContourTriangulator.js';
|
|
12
|
+
import Constants from './ClipClosedSurface/Constants.js';
|
|
13
|
+
import CCSEdgeLocator from './ClipClosedSurface/ccsEdgeLocator.js';
|
|
14
|
+
|
|
15
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
16
|
+
|
|
17
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
18
|
+
var vtkErrorMacro = macro.vtkErrorMacro,
|
|
19
|
+
capitalize = macro.capitalize;
|
|
20
|
+
var ScalarMode = Constants.ScalarMode;
|
|
21
|
+
|
|
22
|
+
function vtkClipClosedSurface(publicAPI, model) {
|
|
23
|
+
// Set our className
|
|
24
|
+
model.classHierarchy.push('vtkClipClosedSurface');
|
|
25
|
+
|
|
26
|
+
publicAPI.getMTime = function () {
|
|
27
|
+
return model.clippingPlanes.reduce(function (a, b) {
|
|
28
|
+
return b.getMTime() > a ? b.getMTime() : a;
|
|
29
|
+
}, model.mtime);
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Take three colors as doubles, and convert to unsigned char.
|
|
33
|
+
*
|
|
34
|
+
* @param {Number} color1
|
|
35
|
+
* @param {Number} color2
|
|
36
|
+
* @param {Number} color3
|
|
37
|
+
* @param {Number[3][3]} colors
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
function createColorValues(color1, color2, color3, colors) {
|
|
42
|
+
var dcolors = [color1, color2, color3];
|
|
43
|
+
|
|
44
|
+
var clamp = function clamp(n, min, max) {
|
|
45
|
+
return Math.min(Math.max(n, min), max);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
for (var i = 0; i < 3; i++) {
|
|
49
|
+
for (var j = 0; j < 3; j++) {
|
|
50
|
+
colors[i][j] = Math.round(clamp(dcolors[i][j], 0, 1) * 255);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Point interpolation for clipping and contouring, given the scalar
|
|
56
|
+
* values (v0, v1) for the two endpoints (p0, p1). The use of this
|
|
57
|
+
* function guarantees perfect consistency in the results.
|
|
58
|
+
*
|
|
59
|
+
* @param {vtkPoints} points
|
|
60
|
+
* @param {vtkDataArray} pointData
|
|
61
|
+
* @param {CCSEdgeLocator} locator
|
|
62
|
+
* @param {Number} tol
|
|
63
|
+
* @param {Number} i0
|
|
64
|
+
* @param {Number} i1
|
|
65
|
+
* @param {Number} v0
|
|
66
|
+
* @param {Number} v1
|
|
67
|
+
* @param {Number} i
|
|
68
|
+
* @returns {Number}
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
function interpolateEdge(points, pointData, locator, tol, i0, i1, v0, v1) {
|
|
73
|
+
// This swap guarantees that exactly the same point is computed
|
|
74
|
+
// for both line directions, as long as the endpoints are the same.
|
|
75
|
+
if (v1 > 0) {
|
|
76
|
+
// eslint-disable-next-line no-param-reassign
|
|
77
|
+
var _ref = [i1, i0];
|
|
78
|
+
i0 = _ref[0];
|
|
79
|
+
i1 = _ref[1];
|
|
80
|
+
var _ref2 = [v1, v0];
|
|
81
|
+
v0 = _ref2[0];
|
|
82
|
+
v1 = _ref2[1];
|
|
83
|
+
} // After the above swap, i0 will be kept, and i1 will be clipped
|
|
84
|
+
// Check to see if this point has already been computed
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
var node = locator.insertUniqueEdge(i0, i1);
|
|
88
|
+
|
|
89
|
+
if (node.edgeId !== -1) {
|
|
90
|
+
return node.edgeId;
|
|
91
|
+
} // Get the edge and interpolate the new point
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
var p0 = [];
|
|
95
|
+
var p1 = [];
|
|
96
|
+
points.getPoint(i0, p0);
|
|
97
|
+
points.getPoint(i1, p1);
|
|
98
|
+
var f = v0 / (v0 - v1);
|
|
99
|
+
var s = 1.0 - f;
|
|
100
|
+
var t = 1.0 - s;
|
|
101
|
+
var p = [s * p0[0] + t * p1[0], s * p0[1] + t * p1[1], s * p0[2] + t * p1[2]];
|
|
102
|
+
var tol2 = tol * tol; // Make sure that new point is far enough from kept point
|
|
103
|
+
|
|
104
|
+
if (distance2BetweenPoints(p, p0) < tol2) {
|
|
105
|
+
node.edgeId = i0;
|
|
106
|
+
return i0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (distance2BetweenPoints(p, p1) < tol2) {
|
|
110
|
+
node.edgeId = i1;
|
|
111
|
+
return i1;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
node.edgeId = points.insertNextTuple(p);
|
|
115
|
+
pointData.interpolateData(pointData, i0, i1, node.edgeId, t);
|
|
116
|
+
return node.edgeId;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Method for clipping lines and copying the scalar data.
|
|
120
|
+
*
|
|
121
|
+
* @param {vtkPoints} points
|
|
122
|
+
* @param {vtkDataArray} pointScalars
|
|
123
|
+
* @param {vtvtkDataSetAttributesk} pointData
|
|
124
|
+
* @param {CCSEdgeLocator} edgeLocator
|
|
125
|
+
* @param {vtkCellArray} inputLines
|
|
126
|
+
* @param {vtkCellArray} outputLines
|
|
127
|
+
* @param {vtkDataSetAttributes} inLineData
|
|
128
|
+
* @param {vtkDataSetAttributes} outLineData
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
function clipLines(points, pointScalars, pointData, edgeLocator, inputLines, outputLines, inLineData, outLineData) {
|
|
133
|
+
var numPts;
|
|
134
|
+
var i0;
|
|
135
|
+
var i1;
|
|
136
|
+
var v0;
|
|
137
|
+
var v1;
|
|
138
|
+
var c0;
|
|
139
|
+
var c1;
|
|
140
|
+
var linePts = [];
|
|
141
|
+
var values = inputLines.getData();
|
|
142
|
+
var cellId = 0;
|
|
143
|
+
|
|
144
|
+
for (var i = 0; i < values.length; i += numPts + 1, cellId++) {
|
|
145
|
+
numPts = values[i];
|
|
146
|
+
i1 = values[i + 1];
|
|
147
|
+
v1 = pointScalars.getData()[i1];
|
|
148
|
+
c1 = v1 > 0;
|
|
149
|
+
|
|
150
|
+
for (var j = 2; j <= numPts; j++) {
|
|
151
|
+
i0 = i1;
|
|
152
|
+
v0 = v1;
|
|
153
|
+
c0 = c1;
|
|
154
|
+
i1 = values[i + j];
|
|
155
|
+
v1 = pointScalars.getData()[i1];
|
|
156
|
+
c1 = v1 > 0; // If at least one point wasn't clipped
|
|
157
|
+
|
|
158
|
+
if (c0 || c1) {
|
|
159
|
+
// If only one end was clipped, interpolate new point
|
|
160
|
+
if (c0 ? !c1 : c1) {
|
|
161
|
+
linePts[c0 ? 1 : 0] = interpolateEdge(points, pointData, edgeLocator, model.tolerance, i0, i1, v0, v1);
|
|
162
|
+
} // If endpoints are different, insert the line segment
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
if (i0 !== i1) {
|
|
166
|
+
linePts[0] = i0;
|
|
167
|
+
linePts[1] = i1;
|
|
168
|
+
var newCellId = outputLines.insertNextCell(linePts); // outLineData.copyData(inLineData, cellId, newCellId);
|
|
169
|
+
|
|
170
|
+
outLineData.passData(inLineData, cellId, newCellId);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Break polylines into individual lines, copying scalar values from
|
|
178
|
+
* inputScalars starting at firstLineScalar. If inputScalars is zero,
|
|
179
|
+
* then scalars will be set to color. If scalars is zero, then no
|
|
180
|
+
* scalars will be generated.
|
|
181
|
+
*
|
|
182
|
+
* @param {vtkCellArray} inputLines
|
|
183
|
+
* @param {vtkCellArray} outputLines
|
|
184
|
+
* @param {vtkDataArray} inputScalars
|
|
185
|
+
* @param {Number} firstLineScalar
|
|
186
|
+
* @param {vtkDataArray} scalars
|
|
187
|
+
* @param {Vector3} color
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
function breakPolylines(inputLines, outputLines, inputScalars, firstLineScalar, scalars, color) {
|
|
192
|
+
var cellColor = _toConsumableArray(color);
|
|
193
|
+
|
|
194
|
+
var cellId = 0;
|
|
195
|
+
var values = inputLines.getData();
|
|
196
|
+
var numPts;
|
|
197
|
+
|
|
198
|
+
for (var i = 0; i < values.length; i += numPts + 1) {
|
|
199
|
+
numPts = values[i];
|
|
200
|
+
|
|
201
|
+
if (inputScalars) {
|
|
202
|
+
inputScalars.getTuple(firstLineScalar + cellId++, cellColor);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
for (var j = 1; j < numPts; j++) {
|
|
206
|
+
outputLines.insertNextCell([values[i + j], values[i + j + 1]]);
|
|
207
|
+
|
|
208
|
+
if (scalars) {
|
|
209
|
+
scalars.insertNextTuple(cellColor);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Copy polygons and their associated scalars to a new array.
|
|
216
|
+
* If inputScalars is set to zero, set polyScalars to color instead.
|
|
217
|
+
* If polyScalars is set to zero, don't generate scalars.
|
|
218
|
+
*
|
|
219
|
+
* @param {vtkCellArray} inputPolys
|
|
220
|
+
* @param {vtkCellArray} outputPolys
|
|
221
|
+
* @param {vtkDataArray} inputScalars
|
|
222
|
+
* @param {Number} firstPolyScalar
|
|
223
|
+
* @param {vtkDataArray} polyScalars
|
|
224
|
+
* @param {Vector3} color
|
|
225
|
+
*/
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
function copyPolygons(inputPolys, outputPolys, inputScalars, firstPolyScalar, polyScalars, color) {
|
|
229
|
+
if (!inputPolys) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
outputPolys.deepCopy(inputPolys);
|
|
234
|
+
|
|
235
|
+
if (polyScalars) {
|
|
236
|
+
var scalarValue = _toConsumableArray(color);
|
|
237
|
+
|
|
238
|
+
var n = outputPolys.getNumberOfCells();
|
|
239
|
+
polyScalars.insertTuple(n - 1, scalarValue);
|
|
240
|
+
|
|
241
|
+
if (inputScalars) {
|
|
242
|
+
for (var i = 0; i < n; i++) {
|
|
243
|
+
inputScalars.getTuple(i + firstPolyScalar, scalarValue);
|
|
244
|
+
polyScalars.setTuple(i, scalarValue);
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
for (var _i = 0; _i < n; _i++) {
|
|
248
|
+
polyScalars.setTuple(_i, scalarValue);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function breakTriangleStrips(inputStrips, polys, inputScalars, firstStripScalar, polyScalars, color) {
|
|
255
|
+
if (inputStrips.getNumberOfCells() === 0) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
var values = inputStrips.getData();
|
|
260
|
+
var cellId = firstStripScalar;
|
|
261
|
+
var numPts;
|
|
262
|
+
|
|
263
|
+
for (var i = 0; i < values.length; i += numPts + 1, cellId++) {
|
|
264
|
+
numPts = values[i]; // vtkTriangleStrip.decomposeStrip(numPts, values, polys);
|
|
265
|
+
|
|
266
|
+
var p1 = values[i + 1];
|
|
267
|
+
var p2 = values[i + 2];
|
|
268
|
+
|
|
269
|
+
for (var j = 0; j < numPts - 2; j++) {
|
|
270
|
+
var p3 = values[i + j + 3];
|
|
271
|
+
|
|
272
|
+
if (j % 2) {
|
|
273
|
+
polys.insertNextCell([p2, p1, p3]);
|
|
274
|
+
} else {
|
|
275
|
+
polys.insertNextCell([p1, p2, p3]);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
p1 = p2;
|
|
279
|
+
p2 = p3;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (polyScalars) {
|
|
283
|
+
var scalarValue = _toConsumableArray(color);
|
|
284
|
+
|
|
285
|
+
if (inputScalars) {
|
|
286
|
+
// If there are input scalars, use them instead of "color"
|
|
287
|
+
inputScalars.getTuple(cellId, scalarValue);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
var n = numPts - 3;
|
|
291
|
+
var m = polyScalars.getNumberOfTuples();
|
|
292
|
+
|
|
293
|
+
if (n >= 0) {
|
|
294
|
+
// First insert is just to allocate space
|
|
295
|
+
polyScalars.insertTuple(m + n, scalarValue);
|
|
296
|
+
|
|
297
|
+
for (var k = 0; k < n; k++) {
|
|
298
|
+
polyScalars.setTuple(m + k, scalarValue);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Given some closed contour lines, create a triangle mesh that
|
|
306
|
+
* fills those lines. The input lines must be single-segment lines,
|
|
307
|
+
* not polylines. The input lines do not have to be in order.
|
|
308
|
+
* Only lines from firstLine to will be used. Specify the normal
|
|
309
|
+
* of the clip plane, which will be opposite the normals
|
|
310
|
+
* of the polys that will be produced. If outCD has scalars, then color
|
|
311
|
+
* scalars will be added for each poly that is created.
|
|
312
|
+
*
|
|
313
|
+
* @param {vtkPolyData} polyData
|
|
314
|
+
* @param {Number} firstLine
|
|
315
|
+
* @param {Number} numLines
|
|
316
|
+
* @param {vtkCellArray} outputPolys
|
|
317
|
+
* @param {Vector3} normal
|
|
318
|
+
*/
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
function triangulateContours(polyData, firstLine, numLines, outputPolys, normal) {
|
|
322
|
+
// If no cut lines were generated, there's nothing to do
|
|
323
|
+
if (numLines <= 0) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
var triangulationError = !vtkContourTriangulator.triangulateContours(polyData, firstLine, numLines, outputPolys, [-normal[0], -normal[1], -normal[2]]);
|
|
328
|
+
|
|
329
|
+
if (triangulationError && model.triangulationErrorDisplay) {
|
|
330
|
+
vtkErrorMacro('Triangulation failed, polyData may not be watertight.');
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Break polylines into individual lines, copying scalar values from
|
|
335
|
+
* inputScalars starting at firstLineScalar. If inputScalars is zero,
|
|
336
|
+
* then scalars will be set to color. If scalars is zero, then no
|
|
337
|
+
* scalars will be generated.
|
|
338
|
+
*
|
|
339
|
+
* @param {Number[]} polygon
|
|
340
|
+
* @param {vtkPoints} points
|
|
341
|
+
* @param {vtkCellArray} triangles
|
|
342
|
+
* @returns {Boolean}
|
|
343
|
+
*/
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
function triangulatePolygon(polygon, points, triangles) {
|
|
347
|
+
return vtkContourTriangulator.triangulatePolygon(polygon, points, triangles);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Clip and contour polys in one step, in order to guarantee
|
|
351
|
+
* that the contour lines exactly match the new free edges of
|
|
352
|
+
* the clipped polygons. This exact correspondence is necessary
|
|
353
|
+
* in order to guarantee that the surface remains closed.
|
|
354
|
+
*
|
|
355
|
+
* @param {vtkPoints} points
|
|
356
|
+
* @param {vtkDataArray} pointScalars
|
|
357
|
+
* @param {vtkDataSetAttributes} pointData
|
|
358
|
+
* @param {CCSEdgeLocator} edgeLocator
|
|
359
|
+
* @param {Number} triangulate
|
|
360
|
+
* @param {vtkCellArray} inputPolys
|
|
361
|
+
* @param {vtkCellArray} outputPolys
|
|
362
|
+
* @param {vtkCellArray} outputLines
|
|
363
|
+
* @param {vtkDataSetAttributes} inCellData
|
|
364
|
+
* @param {vtkDataSetAttributes} outPolyData
|
|
365
|
+
* @param {vtkDataSetAttributes} outLineData
|
|
366
|
+
*/
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
function clipAndContourPolys(points, pointScalars, pointData, edgeLocator, triangulate, inputPolys, outputPolys, outputLines, inCellData, outPolyData, outLineData) {
|
|
370
|
+
var idList = model._idList; // How many sides for output polygons?
|
|
371
|
+
|
|
372
|
+
var polyMax = Number.MAX_VALUE;
|
|
373
|
+
|
|
374
|
+
if (triangulate) {
|
|
375
|
+
if (triangulate < 4) {
|
|
376
|
+
// triangles only
|
|
377
|
+
polyMax = 3;
|
|
378
|
+
} else if (triangulate === 4) {
|
|
379
|
+
// allow triangles and quads
|
|
380
|
+
polyMax = 4;
|
|
381
|
+
}
|
|
382
|
+
} // eslint-disable-next-line prefer-const
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
var triangulationFailure = false; // Go through all cells and clip them
|
|
386
|
+
|
|
387
|
+
var values = inputPolys.getData();
|
|
388
|
+
var linePts = [];
|
|
389
|
+
var cellId = 0;
|
|
390
|
+
var numPts;
|
|
391
|
+
|
|
392
|
+
for (var i = 0; i < values.length; i += numPts + 1, cellId++) {
|
|
393
|
+
numPts = values[i];
|
|
394
|
+
var i1 = values[i + numPts];
|
|
395
|
+
var v1 = pointScalars.getData()[i1];
|
|
396
|
+
var c1 = v1 > 0; // The ids for the current edge: init j0 to -1 if i1 will be clipped
|
|
397
|
+
|
|
398
|
+
var j0 = c1 ? i1 : -1;
|
|
399
|
+
var j1 = 0; // To store the ids of the contour line
|
|
400
|
+
|
|
401
|
+
linePts[0] = 0;
|
|
402
|
+
linePts[1] = 0;
|
|
403
|
+
var idListIdx = 0;
|
|
404
|
+
|
|
405
|
+
for (var j = 1; j <= numPts; j++) {
|
|
406
|
+
// Save previous point info
|
|
407
|
+
var i0 = i1;
|
|
408
|
+
var v0 = v1;
|
|
409
|
+
var c0 = c1; // Generate new point info
|
|
410
|
+
|
|
411
|
+
i1 = values[i + j];
|
|
412
|
+
v1 = pointScalars.getData()[i1];
|
|
413
|
+
c1 = v1 > 0; // If at least one edge end point wasn't clipped
|
|
414
|
+
|
|
415
|
+
if (c0 || c1) {
|
|
416
|
+
// If only one end was clipped, interpolate new point
|
|
417
|
+
if (c0 ? !c1 : c1) {
|
|
418
|
+
j1 = interpolateEdge(points, pointData, edgeLocator, model.tolerance, i0, i1, v0, v1);
|
|
419
|
+
|
|
420
|
+
if (j1 !== j0) {
|
|
421
|
+
idList[idListIdx++] = j1;
|
|
422
|
+
j0 = j1;
|
|
423
|
+
} // Save as one end of the contour line
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
linePts[c0 ? 1 : 0] = j1;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (c1) {
|
|
430
|
+
j1 = i1;
|
|
431
|
+
|
|
432
|
+
if (j1 !== j0) {
|
|
433
|
+
idList[idListIdx++] = j1;
|
|
434
|
+
j0 = j1;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
} // Insert the clipped poly
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
var numPoints = idListIdx;
|
|
442
|
+
idList.length = numPoints;
|
|
443
|
+
|
|
444
|
+
if (model.triangulatePolys && numPoints > polyMax) {
|
|
445
|
+
// TODO: Support triangulatePolygon
|
|
446
|
+
var newCellId = outputPolys.getNumberOfCells(); // Triangulate the poly and insert triangles into output.
|
|
447
|
+
|
|
448
|
+
var success = triangulatePolygon(idList, points, outputPolys);
|
|
449
|
+
|
|
450
|
+
if (!success) {
|
|
451
|
+
triangulationFailure = true;
|
|
452
|
+
} // Copy the attribute data to the triangle cells
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
var ncells = outputPolys.getNumberOfCells();
|
|
456
|
+
|
|
457
|
+
for (; newCellId < ncells; newCellId++) {
|
|
458
|
+
outPolyData.passData(inCellData, cellId, newCellId);
|
|
459
|
+
}
|
|
460
|
+
} else if (numPoints > 2) {
|
|
461
|
+
// Insert the polygon without triangulating it
|
|
462
|
+
var _newCellId = outputPolys.insertNextCell(idList);
|
|
463
|
+
|
|
464
|
+
outPolyData.passData(inCellData, cellId, _newCellId);
|
|
465
|
+
} // Insert the contour line if one was created
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
if (linePts[0] !== linePts[1]) {
|
|
469
|
+
var _newCellId2 = outputLines.insertNextCell(linePts);
|
|
470
|
+
|
|
471
|
+
outLineData.passData(inCellData, cellId, _newCellId2);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (triangulationFailure && model.triangulationErrorDisplay) {
|
|
476
|
+
vtkErrorMacro('Triangulation failed, output may not be watertight');
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Squeeze the points and store them in the output. Only the points that
|
|
481
|
+
* are used by the cells will be saved, and the pointIds of the cells will
|
|
482
|
+
* be modified.
|
|
483
|
+
*
|
|
484
|
+
* @param {vtkPolyData} output
|
|
485
|
+
* @param {vtkPoints} points
|
|
486
|
+
* @param {vtkDataSetAttributes} pointData
|
|
487
|
+
* @param {String} outputPointDataType
|
|
488
|
+
*/
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
function squeezeOutputPoints(output, points, pointData, outputPointDataType) {
|
|
492
|
+
// Create a list of points used by cells
|
|
493
|
+
var n = points.getNumberOfPoints();
|
|
494
|
+
var numNewPoints = 0;
|
|
495
|
+
var outPointData = output.getPointData();
|
|
496
|
+
var pointMap = [];
|
|
497
|
+
pointMap.length = n;
|
|
498
|
+
var cellArrays = [output.getVerts(), output.getLines(), output.getPolys(), output.getStrips()]; // Find all the newPoints that are used by cells
|
|
499
|
+
|
|
500
|
+
cellArrays.forEach(function (cellArray) {
|
|
501
|
+
if (!cellArray) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
var values = cellArray.getData();
|
|
506
|
+
var numPts;
|
|
507
|
+
var pointId;
|
|
508
|
+
|
|
509
|
+
for (var i = 0; i < values.length; i += numPts + 1) {
|
|
510
|
+
numPts = values[i];
|
|
511
|
+
|
|
512
|
+
for (var j = 1; j <= numPts; j++) {
|
|
513
|
+
pointId = values[i + j];
|
|
514
|
+
|
|
515
|
+
if (pointMap[pointId] === undefined) {
|
|
516
|
+
pointMap[pointId] = numNewPoints++;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}); // Create exactly the number of points that are required
|
|
521
|
+
|
|
522
|
+
var newPoints = vtkPoints.newInstance({
|
|
523
|
+
size: numNewPoints * 3,
|
|
524
|
+
dataType: outputPointDataType
|
|
525
|
+
}); // outPointData.copyAllocate(pointData, numNewPoints, 0);
|
|
526
|
+
|
|
527
|
+
var p = [];
|
|
528
|
+
var newPointId;
|
|
529
|
+
|
|
530
|
+
for (var pointId = 0; pointId < n; pointId++) {
|
|
531
|
+
newPointId = pointMap[pointId];
|
|
532
|
+
|
|
533
|
+
if (newPointId !== undefined) {
|
|
534
|
+
points.getPoint(pointId, p);
|
|
535
|
+
newPoints.setTuple(newPointId, p);
|
|
536
|
+
outPointData.passData(pointData, pointId, newPointId); // outPointData.copyData(pointData, pointId, newPointId);
|
|
537
|
+
}
|
|
538
|
+
} // Change the cell pointIds to reflect the new point array
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
cellArrays.forEach(function (cellArray) {
|
|
542
|
+
if (!cellArray) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
var values = cellArray.getData();
|
|
547
|
+
var numPts;
|
|
548
|
+
var pointId;
|
|
549
|
+
|
|
550
|
+
for (var i = 0; i < values.length; i += numPts + 1) {
|
|
551
|
+
numPts = values[i];
|
|
552
|
+
|
|
553
|
+
for (var j = 1; j <= numPts; j++) {
|
|
554
|
+
pointId = values[i + j];
|
|
555
|
+
values[i + j] = pointMap[pointId];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
output.setPoints(newPoints);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
publicAPI.requestData = function (inData, outData) {
|
|
563
|
+
var _input$getVerts, _input$getStrips;
|
|
564
|
+
|
|
565
|
+
// implement requestData
|
|
566
|
+
var input = inData[0];
|
|
567
|
+
var output = vtkPolyData.newInstance();
|
|
568
|
+
outData[0] = output;
|
|
569
|
+
|
|
570
|
+
if (!input) {
|
|
571
|
+
vtkErrorMacro('Invalid or missing input');
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if (model._idList == null) {
|
|
576
|
+
model._idList = [];
|
|
577
|
+
} else {
|
|
578
|
+
model._idList.length = 0;
|
|
579
|
+
} // Get the input points
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
var inputPoints = input.getPoints();
|
|
583
|
+
var numPts = 0;
|
|
584
|
+
var inputPointsType = VtkDataTypes.FLOAT;
|
|
585
|
+
|
|
586
|
+
if (inputPoints) {
|
|
587
|
+
numPts = inputPoints.getNumberOfPoints();
|
|
588
|
+
inputPointsType = inputPoints.getDataType();
|
|
589
|
+
} // Force points to double precision, copy the point attributes
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
var points = vtkPoints.newInstance({
|
|
593
|
+
size: numPts * 3,
|
|
594
|
+
dataType: VtkDataTypes.DOUBLE
|
|
595
|
+
});
|
|
596
|
+
var pointData = vtkDataSetAttributes.newInstance();
|
|
597
|
+
var inPointData = null;
|
|
598
|
+
|
|
599
|
+
if (model.passPointData) {
|
|
600
|
+
inPointData = input.getPointData(); // pointData.interpolateAllocate(inPointData, numPts, 0);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
var point = [];
|
|
604
|
+
|
|
605
|
+
for (var ptId = 0; ptId < numPts; ptId++) {
|
|
606
|
+
inputPoints.getPoint(ptId, point);
|
|
607
|
+
points.setTuple(ptId, point);
|
|
608
|
+
|
|
609
|
+
if (inPointData) {
|
|
610
|
+
// pointData.copyData(inPointData, ptId, ptId);
|
|
611
|
+
pointData.passData(inPointData, ptId, ptId);
|
|
612
|
+
}
|
|
613
|
+
} // An edge locator to avoid point duplication while clipping
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
var edgeLocator = new CCSEdgeLocator(); // A temporary polydata for the contour lines that are triangulated
|
|
617
|
+
|
|
618
|
+
var tmpContourData = vtkPolyData.newInstance(); // The cell scalars
|
|
619
|
+
|
|
620
|
+
var lineScalars;
|
|
621
|
+
var polyScalars;
|
|
622
|
+
var inputScalars; // For input scalars: the offsets to the various cell types
|
|
623
|
+
|
|
624
|
+
var firstLineScalar = 0;
|
|
625
|
+
var firstPolyScalar = 0;
|
|
626
|
+
var firstStripScalar = 0; // Make the colors to be used on the data
|
|
627
|
+
|
|
628
|
+
var numberOfScalarComponents = 1;
|
|
629
|
+
var colors = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
|
|
630
|
+
|
|
631
|
+
if (model.scalarMode === ScalarMode.COLORS) {
|
|
632
|
+
numberOfScalarComponents = 3;
|
|
633
|
+
createColorValues(model.baseColor, model.clipColor, model.activePlaneColor, colors);
|
|
634
|
+
} else if (model.scalarMode === ScalarMode.LABELS) {
|
|
635
|
+
colors[0][0] = 0;
|
|
636
|
+
colors[1][0] = 1;
|
|
637
|
+
colors[2][0] = 2;
|
|
638
|
+
} // This is set if we have to work with scalars. The input scalars
|
|
639
|
+
// will be copied if they are unsigned char with 3 components, otherwise
|
|
640
|
+
// new scalars will be generated.
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
var numVerts = ((_input$getVerts = input.getVerts()) === null || _input$getVerts === void 0 ? void 0 : _input$getVerts.getNumberOfCells()) || 0;
|
|
644
|
+
var inputLines = input.getLines();
|
|
645
|
+
var numLines = (inputLines === null || inputLines === void 0 ? void 0 : inputLines.getNumberOfCells()) || 0;
|
|
646
|
+
var inputPolys = input.getPolys();
|
|
647
|
+
var numPolys = (inputPolys === null || inputPolys === void 0 ? void 0 : inputPolys.getNumberOfCells()) || 0;
|
|
648
|
+
var numStrips = ((_input$getStrips = input.getStrips()) === null || _input$getStrips === void 0 ? void 0 : _input$getStrips.getNumberOfCells()) || 0;
|
|
649
|
+
|
|
650
|
+
if (model.scalarMode !== ScalarMode.NONE) {
|
|
651
|
+
lineScalars = vtkDataArray.newInstance({
|
|
652
|
+
dataType: VtkDataTypes.UNSIGNED_CHAR,
|
|
653
|
+
empty: true,
|
|
654
|
+
// size: 0,
|
|
655
|
+
// values: new Uint8Array(numLines * 3),
|
|
656
|
+
numberOfComponents: numberOfScalarComponents
|
|
657
|
+
});
|
|
658
|
+
var tryInputScalars = input.getCellData().getScalars(); // Get input scalars if they are RGB color scalars
|
|
659
|
+
|
|
660
|
+
if (tryInputScalars && tryInputScalars.getDataType() === VtkDataTypes.UNSIGNED_CHAR && numberOfScalarComponents === 3 && tryInputScalars.getNumberOfComponents() === 3) {
|
|
661
|
+
inputScalars = input.getCellData().getScalars();
|
|
662
|
+
firstLineScalar = numVerts;
|
|
663
|
+
firstPolyScalar = numVerts + numLines;
|
|
664
|
+
firstStripScalar = numVerts + numLines + numPolys;
|
|
665
|
+
}
|
|
666
|
+
} // Break the input lines into segments, generate scalars for lines
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
var lines;
|
|
670
|
+
|
|
671
|
+
if (numLines > 0) {
|
|
672
|
+
lines = vtkCellArray.newInstance({
|
|
673
|
+
dataType: inputLines.getDataType(),
|
|
674
|
+
values: new Uint8Array(numLines * 3),
|
|
675
|
+
// we will have at least that amount of lines
|
|
676
|
+
size: 0
|
|
677
|
+
});
|
|
678
|
+
breakPolylines(inputLines, lines, inputScalars, firstLineScalar, lineScalars, colors[0]);
|
|
679
|
+
} else {
|
|
680
|
+
lines = vtkCellArray.newInstance({
|
|
681
|
+
empty: true
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
var polys = null;
|
|
686
|
+
var polyMax = 3;
|
|
687
|
+
|
|
688
|
+
if (numPolys > 0 || numStrips > 0) {
|
|
689
|
+
// If there are line scalars, then poly scalars are needed too
|
|
690
|
+
if (lineScalars) {
|
|
691
|
+
polyScalars = vtkDataArray.newInstance({
|
|
692
|
+
dataType: VtkDataTypes.UNSIGNED_CHAR,
|
|
693
|
+
empty: true,
|
|
694
|
+
// size: 0,
|
|
695
|
+
// values: new Uint8Array(inputPolys.getNumberOfCells(false) * 3),
|
|
696
|
+
numberOfComponents: numberOfScalarComponents
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
polys = vtkCellArray.newInstance();
|
|
701
|
+
copyPolygons(inputPolys, polys, inputScalars, firstPolyScalar, polyScalars, colors[0]); // TODO: Support triangle strips
|
|
702
|
+
|
|
703
|
+
breakTriangleStrips(input.getStrips(), polys, inputScalars, firstStripScalar, polyScalars, colors[0]); // Check if the input has polys and quads or just triangles
|
|
704
|
+
|
|
705
|
+
polyMax = inputPolys.getCellSizes().reduce(function (a, b) {
|
|
706
|
+
return a > b ? a : b;
|
|
707
|
+
}, 0);
|
|
708
|
+
} // Arrays for storing the clipped lines and polys
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
var newLines = vtkCellArray.newInstance({
|
|
712
|
+
dataType: lines.getDataType(),
|
|
713
|
+
empty: true
|
|
714
|
+
});
|
|
715
|
+
var newPolys = null;
|
|
716
|
+
|
|
717
|
+
if (polys) {
|
|
718
|
+
newPolys = vtkCellArray.newInstance({
|
|
719
|
+
dataType: polys.getDataType(),
|
|
720
|
+
empty: true
|
|
721
|
+
});
|
|
722
|
+
} // The line scalars, for coloring the outline
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
var inLineData = vtkDataSetAttributes.newInstance();
|
|
726
|
+
inLineData.copyScalarsOn();
|
|
727
|
+
inLineData.setScalars(lineScalars); // The poly scalars, for coloring the faces
|
|
728
|
+
|
|
729
|
+
var inPolyData = vtkDataSetAttributes.newInstance();
|
|
730
|
+
inPolyData.copyScalarsOn();
|
|
731
|
+
inPolyData.setScalars(polyScalars); // Also create output attribute data
|
|
732
|
+
|
|
733
|
+
var outLineData = vtkDataSetAttributes.newInstance();
|
|
734
|
+
outLineData.copyScalarsOn();
|
|
735
|
+
var outPolyData = vtkDataSetAttributes.newInstance();
|
|
736
|
+
outPolyData.copyScalarsOn();
|
|
737
|
+
var planes = model.clippingPlanes; // Go through the clipping planes and clip the input with each plane
|
|
738
|
+
|
|
739
|
+
for (var planeId = 0; planeId < planes.length; planeId++) {
|
|
740
|
+
var plane = planes[planeId];
|
|
741
|
+
var triangulate = 5;
|
|
742
|
+
|
|
743
|
+
if (planeId === planes.length - 1) {
|
|
744
|
+
triangulate = polyMax;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
var active = planeId === model.activePlaneId; // Convert the plane into an easy-to-evaluate function
|
|
748
|
+
|
|
749
|
+
var pc = plane.getNormal(); // OK to modify pc because vtkPlane.getNormal() returns a copy
|
|
750
|
+
|
|
751
|
+
pc[3] = -dot(pc, plane.getOrigin()); // Create the clip scalars by evaluating the plane at each point
|
|
752
|
+
|
|
753
|
+
var numPoints = points.getNumberOfPoints(); // The point scalars, needed for clipping (not for the output!)
|
|
754
|
+
|
|
755
|
+
var pointScalars = vtkDataArray.newInstance({
|
|
756
|
+
dataType: VtkDataTypes.DOUBLE,
|
|
757
|
+
size: numPoints
|
|
758
|
+
});
|
|
759
|
+
var pointScalarsData = pointScalars.getData();
|
|
760
|
+
var pointsData = points.getData();
|
|
761
|
+
var i = 0;
|
|
762
|
+
|
|
763
|
+
for (var pointId = 0; pointId < numPoints; pointId) {
|
|
764
|
+
pointScalarsData[pointId++] = pointsData[i++] * pc[0] + pointsData[i++] * pc[1] + pointsData[i++] * pc[2] + pc[3];
|
|
765
|
+
} // Prepare the output scalars
|
|
766
|
+
// outLineData.copyAllocate(inLineData, 0, 0);
|
|
767
|
+
// outPolyData.copyAllocate(inPolyData, 0, 0);
|
|
768
|
+
// Reset the locator
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
edgeLocator.initialize(); // Clip the lines
|
|
772
|
+
|
|
773
|
+
clipLines(points, pointScalars, pointData, edgeLocator, lines, newLines, inLineData, outLineData); // Clip the polys
|
|
774
|
+
|
|
775
|
+
if (polys) {
|
|
776
|
+
// Get the number of lines remaining after the clipping
|
|
777
|
+
var numClipLines = newLines.getNumberOfCells(); // Cut the polys to generate more lines
|
|
778
|
+
|
|
779
|
+
clipAndContourPolys(points, pointScalars, pointData, edgeLocator, triangulate, polys, newPolys, newLines, inPolyData, outPolyData, outLineData); // Add scalars for the newly-created contour lines
|
|
780
|
+
|
|
781
|
+
var _scalars = outLineData.getScalars();
|
|
782
|
+
|
|
783
|
+
if (_scalars) {
|
|
784
|
+
// Set the color to the active color if plane is active
|
|
785
|
+
var color = colors[1 + (active ? 1 : 0)];
|
|
786
|
+
var activeColor = colors[2];
|
|
787
|
+
var numNewLines = newLines.getNumberOfCells();
|
|
788
|
+
var oldColor = [];
|
|
789
|
+
|
|
790
|
+
for (var lineId = numClipLines; lineId < numNewLines; lineId++) {
|
|
791
|
+
_scalars.getTuple(lineId, oldColor);
|
|
792
|
+
|
|
793
|
+
if (numberOfScalarComponents !== 3 || oldColor[0] !== activeColor[0] || oldColor[1] !== activeColor[1] || oldColor[2] !== activeColor[2]) {
|
|
794
|
+
_scalars.setTuple(lineId, color);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
} // Generate new polys from the cut lines
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
var cellId = newPolys.getNumberOfCells();
|
|
801
|
+
var numClipAndContourLines = newLines.getNumberOfCells(); // Create a polydata for the lines
|
|
802
|
+
|
|
803
|
+
tmpContourData.setPoints(points);
|
|
804
|
+
tmpContourData.setLines(newLines);
|
|
805
|
+
tmpContourData.buildCells();
|
|
806
|
+
triangulateContours(tmpContourData, numClipLines, numClipAndContourLines - numClipLines, newPolys, pc); // Add scalars for the newly-created polys
|
|
807
|
+
|
|
808
|
+
_scalars = outPolyData.getScalars();
|
|
809
|
+
|
|
810
|
+
if (_scalars) {
|
|
811
|
+
var _color = colors[1 + (active ? 1 : 0)];
|
|
812
|
+
var numCells = newPolys.getNumberOfCells();
|
|
813
|
+
|
|
814
|
+
if (numCells > cellId) {
|
|
815
|
+
// The insert allocates space up to numCells - 1
|
|
816
|
+
_scalars.insertTuple(numCells - 1, _color);
|
|
817
|
+
|
|
818
|
+
for (; cellId < numCells; cellId++) {
|
|
819
|
+
_scalars.setTuple(cellId, _color);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
} // Add scalars to any diagnostic lines that added by
|
|
823
|
+
// triangulateContours(). In usual operation, no lines are added.
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
_scalars = outLineData.getScalars();
|
|
827
|
+
|
|
828
|
+
if (_scalars) {
|
|
829
|
+
var _color2 = [0, 255, 255];
|
|
830
|
+
|
|
831
|
+
var _numCells = newLines.getNumberOfCells();
|
|
832
|
+
|
|
833
|
+
if (_numCells > numClipAndContourLines) {
|
|
834
|
+
// The insert allocates space up to numCells - 1
|
|
835
|
+
_scalars.insertTuple(_numCells - 1, _color2);
|
|
836
|
+
|
|
837
|
+
for (var lineCellId = numClipAndContourLines; lineCellId < _numCells; lineCellId++) {
|
|
838
|
+
_scalars.setTuple(lineCellId, _color2);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
} // Swap the lines, points, etcetera: old output becomes new input
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
var _ref3 = [newLines, lines];
|
|
846
|
+
lines = _ref3[0];
|
|
847
|
+
newLines = _ref3[1];
|
|
848
|
+
newLines.initialize();
|
|
849
|
+
|
|
850
|
+
if (polys) {
|
|
851
|
+
var _ref4 = [newPolys, polys];
|
|
852
|
+
polys = _ref4[0];
|
|
853
|
+
newPolys = _ref4[1];
|
|
854
|
+
newPolys.initialize();
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
var _ref5 = [outLineData, inLineData];
|
|
858
|
+
inLineData = _ref5[0];
|
|
859
|
+
outLineData = _ref5[1];
|
|
860
|
+
outLineData.initialize();
|
|
861
|
+
var _ref6 = [outPolyData, inPolyData];
|
|
862
|
+
inPolyData = _ref6[0];
|
|
863
|
+
outPolyData = _ref6[1];
|
|
864
|
+
outPolyData.initialize();
|
|
865
|
+
} // Get the line scalars
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
var scalars = inLineData.getScalars();
|
|
869
|
+
|
|
870
|
+
if (model.generateOutline) {
|
|
871
|
+
output.setLines(lines);
|
|
872
|
+
} else if (scalars) {
|
|
873
|
+
scalars.initialize();
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
if (model.generateFaces) {
|
|
877
|
+
output.setPolys(polys);
|
|
878
|
+
|
|
879
|
+
if (polys && scalars) {
|
|
880
|
+
var pScalars = inPolyData.getScalars();
|
|
881
|
+
var m = scalars.getNumberOfTuples();
|
|
882
|
+
var n = pScalars.getNumberOfTuples();
|
|
883
|
+
|
|
884
|
+
if (n > 0) {
|
|
885
|
+
var _color3 = [0, 0, 0]; // This is just to expand the array
|
|
886
|
+
|
|
887
|
+
scalars.insertTuple(n + m - 1, _color3); // Fill in the poly scalars
|
|
888
|
+
|
|
889
|
+
for (var _i2 = 0; _i2 < n; _i2++) {
|
|
890
|
+
pScalars.getTuple(_i2, _color3);
|
|
891
|
+
scalars.setTuple(_i2 + m, _color3);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
if (scalars && model.scalarMode === ScalarMode.COLORS) {
|
|
898
|
+
scalars.setName('Colors');
|
|
899
|
+
output.getCellData().setScalars(scalars);
|
|
900
|
+
} else if (model.scalarMode === ScalarMode.LABELS) {
|
|
901
|
+
// Don't use VTK_UNSIGNED_CHAR or they will look like color scalars
|
|
902
|
+
// const categories = vtkSignedCharArray.newInstance();
|
|
903
|
+
// categories.deepCopy(scalars);
|
|
904
|
+
// categories.setName("Labels");
|
|
905
|
+
// output.getCellData().setScalars(categories);
|
|
906
|
+
// categories.delete();
|
|
907
|
+
// TODO: Check
|
|
908
|
+
var categories = scalars.newClone();
|
|
909
|
+
categories.setData(scalars.getData().slice());
|
|
910
|
+
categories.setName('Labels');
|
|
911
|
+
output.getCellData().setScalars(categories);
|
|
912
|
+
} else {
|
|
913
|
+
output.getCellData().setScalars(null);
|
|
914
|
+
} // Finally, store the points in the output
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
squeezeOutputPoints(output, points, pointData, inputPointsType); // TODO: Check
|
|
918
|
+
// output.squeeze();
|
|
919
|
+
|
|
920
|
+
outData[0] = output;
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
Object.keys(ScalarMode).forEach(function (key) {
|
|
924
|
+
var name = capitalize(key.toLowerCase());
|
|
925
|
+
|
|
926
|
+
publicAPI["setScalarModeTo".concat(name)] = function () {
|
|
927
|
+
model.scalarMode = ScalarMode[key];
|
|
928
|
+
};
|
|
929
|
+
});
|
|
930
|
+
} // ----------------------------------------------------------------------------
|
|
931
|
+
// Object factory
|
|
932
|
+
// ----------------------------------------------------------------------------
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
var DEFAULT_VALUES = {
|
|
936
|
+
clippingPlanes: null,
|
|
937
|
+
tolerance: 1e-6,
|
|
938
|
+
passPointData: false,
|
|
939
|
+
triangulatePolys: false,
|
|
940
|
+
scalarMode: ScalarMode.NONE,
|
|
941
|
+
generateOutline: false,
|
|
942
|
+
generateFaces: true,
|
|
943
|
+
activePlaneId: -1,
|
|
944
|
+
baseColor: null,
|
|
945
|
+
clipColor: null,
|
|
946
|
+
activePlaneColor: null,
|
|
947
|
+
triangulationErrorDisplay: false // _idList: null,
|
|
948
|
+
|
|
949
|
+
}; // ----------------------------------------------------------------------------
|
|
950
|
+
|
|
951
|
+
function extend(publicAPI, model) {
|
|
952
|
+
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
953
|
+
Object.assign(model, DEFAULT_VALUES, initialValues); // Make this a VTK object
|
|
954
|
+
|
|
955
|
+
macro.obj(publicAPI, model); // Also make it an algorithm with one input and one output
|
|
956
|
+
|
|
957
|
+
macro.algo(publicAPI, model, 1, 1);
|
|
958
|
+
macro.setGet(publicAPI, model, ['clippingPlanes', 'tolerance', 'passPointData', 'triangulatePolys', 'scalarMode', 'generateOutline', 'generateFaces', 'activePlaneId', 'triangulationErrorDisplay']);
|
|
959
|
+
macro.setGetArray(publicAPI, model, ['baseColor', 'clipColor', 'activePlaneColor'], 3); // Object specific methods
|
|
960
|
+
|
|
961
|
+
vtkClipClosedSurface(publicAPI, model);
|
|
962
|
+
} // ----------------------------------------------------------------------------
|
|
963
|
+
|
|
964
|
+
var newInstance = macro.newInstance(extend, 'vtkClipClosedSurface'); // ----------------------------------------------------------------------------
|
|
965
|
+
|
|
966
|
+
var index = _objectSpread({
|
|
967
|
+
newInstance: newInstance,
|
|
968
|
+
extend: extend
|
|
969
|
+
}, Constants);
|
|
970
|
+
|
|
971
|
+
export { index as default, extend, newInstance };
|