Skip to content

Commit d0130cf

Browse files
committed
feat(cellpicker): add edge picking support
1 parent 4f0d842 commit d0130cf

File tree

3 files changed

+86
-33
lines changed

3 files changed

+86
-33
lines changed

Sources/Common/DataModel/CellTypes/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ function isLinear(type) {
4040
);
4141
}
4242

43+
function hasSubCells(cellType) {
44+
return (
45+
cellType === CellType.VTK_TRIANGLE_STRIP ||
46+
cellType === CellType.VTK_POLY_LINE ||
47+
cellType === CellType.VTK_POLY_VERTEX
48+
);
49+
}
50+
4351
// ----------------------------------------------------------------------------
4452
// Static API
4553
// ----------------------------------------------------------------------------
@@ -48,6 +56,7 @@ export const STATIC = {
4856
getClassNameFromTypeId,
4957
getTypeIdFromClassName,
5058
isLinear,
59+
hasSubCells,
5160
};
5261

5362
// ----------------------------------------------------------------------------

Sources/Common/DataModel/Line/index.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,9 @@ function intersection(a1, a2, b1, b2, u, v) {
6363
v[0] = 0.0;
6464

6565
// Determine line vectors.
66-
a21[0] = a2[0] - a1[0];
67-
a21[1] = a2[1] - a1[1];
68-
a21[2] = a2[2] - a1[2];
69-
b21[0] = b2[0] - b1[0];
70-
b21[1] = b2[1] - b1[1];
71-
b21[2] = b2[2] - b1[2];
72-
b1a1[0] = b1[0] - a1[0];
73-
b1a1[1] = b1[1] - a1[1];
74-
b1a1[2] = b1[2] - a1[2];
66+
vtkMath.subtract(a2, a1, a21);
67+
vtkMath.subtract(b2, b1, b21);
68+
vtkMath.subtract(b1, a1, b1a1);
7569

7670
// Compute the system (least squares) matrix.
7771
const A = [];
@@ -217,6 +211,7 @@ function vtkLine(publicAPI, model) {
217211
}
218212
return outObj;
219213
};
214+
220215
publicAPI.evaluatePosition = (
221216
x,
222217
closestPoint,
@@ -225,6 +220,20 @@ function vtkLine(publicAPI, model) {
225220
dist2,
226221
weights
227222
) => {}; // virtual
223+
224+
publicAPI.evaluateLocation = (pcoords, x, weights) => {
225+
const a1 = [];
226+
const a2 = [];
227+
model.points.getPoint(0, a1);
228+
model.points.getPoint(1, a2);
229+
230+
for (let i = 0; i < 3; i++) {
231+
x[i] = a1[i] + pcoords[0] * (a2[i] - a1[i]);
232+
}
233+
234+
weights[0] = 1.0 - pcoords[0];
235+
weights[1] = pcoords[0];
236+
};
228237
}
229238

230239
// ----------------------------------------------------------------------------

Sources/Rendering/Core/CellPicker/index.js

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
import macro from 'vtk.js/Sources/macros';
2-
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
2+
import vtkCellTypes from 'vtk.js/Sources/Common/DataModel/CellTypes';
3+
import vtkLine from 'vtk.js/Sources/Common/DataModel/Line';
34
import vtkPicker from 'vtk.js/Sources/Rendering/Core/Picker';
4-
import vtkPoints from 'vtk.js/Sources/Common/Core/Points';
5+
import vtkPolyLine from 'vtk.js/Sources/Common/DataModel/PolyLine';
56
import vtkTriangle from 'vtk.js/Sources/Common/DataModel/Triangle';
6-
7+
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
8+
import { CellType } from 'vtk.js/Sources/Common/DataModel/CellTypes/Constants';
79
import { vec3 } from 'gl-matrix';
810

911
// ----------------------------------------------------------------------------
1012
// Global methods
1113
// ----------------------------------------------------------------------------
1214

15+
function createCellMap() {
16+
return {
17+
[CellType.VTK_LINE]: vtkLine.newInstance(),
18+
[CellType.VTK_POLY_LINE]: vtkPolyLine.newInstance(),
19+
[CellType.VTK_TRIANGLE]: vtkTriangle.newInstance(),
20+
};
21+
}
22+
1323
function clipLineWithPlane(mapper, matrix, p1, p2) {
1424
const outObj = { planeId: -1, t1: 0.0, t2: 1.0, intersect: 0 };
1525
const nbClippingPlanes = mapper.getNumberOfClippingPlanes();
@@ -238,8 +248,10 @@ function vtkCellPicker(publicAPI, model) {
238248
const minXYZ = [0, 0, 0];
239249
let pDistMin = Number.MAX_VALUE;
240250
const minPCoords = [0, 0, 0];
241-
let minCellId = -1;
242-
const minCell = vtkTriangle.newInstance();
251+
let minCellId = null;
252+
let minCell = null;
253+
let minCellType = null;
254+
let subId = null;
243255
const x = [];
244256
const data = mapper.getInputData();
245257
const isPolyData = 1;
@@ -263,31 +275,47 @@ function vtkCellPicker(publicAPI, model) {
263275
const locator = null;
264276
if (locator) {
265277
// TODO when cell locator will be implemented
266-
} else if (data.getPolys) {
267-
const cellObject = data.getPolys();
268-
const points = data.getPoints();
269-
const cellData = cellObject.getData();
270-
let cellId = 0;
271-
const pointsIdList = [-1, -1, -1];
272-
const cell = vtkTriangle.newInstance();
273-
const cellPoints = vtkPoints.newInstance();
274-
// cross all cells
275-
for (let i = 0; i < cellData.length; cellId++) {
278+
} else if (data.getCells) {
279+
if (!data.getCells()) {
280+
data.buildLinks();
281+
}
282+
283+
const tempCellMap = createCellMap();
284+
const minCellMap = createCellMap();
285+
286+
const numberOfCells = data.getNumberOfCells();
287+
288+
for (let cellId = 0; cellId < numberOfCells; cellId++) {
276289
const pCoords = [0, 0, 0];
277-
const nbPointsInCell = cellData[i++];
278290

279-
cellPoints.setNumberOfPoints(nbPointsInCell);
280-
// Extract cell points
281-
for (let j = 0; j < nbPointsInCell; j++) {
282-
pointsIdList[j] = cellData[i++];
291+
minCellType = data.getCellType(cellId);
292+
const cell = tempCellMap[minCellType];
293+
294+
if (cell == null) {
295+
// eslint-disable-next-line no-continue
296+
continue;
283297
}
284298

285-
// Create cell from points
286-
cell.initialize(points, pointsIdList);
299+
minCell = minCellMap[minCellType];
300+
301+
data.getCell(cellId, cell);
287302

288303
let cellPicked;
304+
289305
if (isPolyData) {
290-
cellPicked = cell.intersectWithLine(p1, p2, tol, x, pCoords);
306+
if (vtkCellTypes.hasSubCells(minCellType)) {
307+
cellPicked = cell.intersectWithLine(
308+
t1,
309+
t2,
310+
p1,
311+
p2,
312+
tol,
313+
x,
314+
pCoords
315+
);
316+
} else {
317+
cellPicked = cell.intersectWithLine(p1, p2, tol, x, pCoords);
318+
}
291319
} else {
292320
cellPicked = cell.intersectWithLine(q1, q2, tol, x, pCoords);
293321
if (t1 !== 0.0 || t2 !== 1.0) {
@@ -302,9 +330,11 @@ function vtkCellPicker(publicAPI, model) {
302330
cellPicked.t <= t2
303331
) {
304332
const pDist = cell.getParametricDistance(pCoords);
333+
305334
if (pDist < pDistMin || (pDist === pDistMin && cellPicked.t < tMin)) {
306335
tMin = cellPicked.t;
307336
pDistMin = pDist;
337+
subId = cellPicked.subId;
308338
minCellId = cellId;
309339
cell.deepCopy(minCell);
310340
for (let k = 0; k < 3; k++) {
@@ -324,7 +354,12 @@ function vtkCellPicker(publicAPI, model) {
324354
weights[i] = 0.0;
325355
}
326356
const point = [];
327-
minCell.evaluateLocation(minPCoords, point, weights);
357+
358+
if (vtkCellTypes.hasSubCells(minCellType)) {
359+
minCell.evaluateLocation(subId, minPCoords, point, weights);
360+
} else {
361+
minCell.evaluateLocation(minPCoords, point, weights);
362+
}
328363

329364
// Return the polydata to the user
330365
model.dataSet = data;

0 commit comments

Comments
 (0)