import macro from 'vtk.js/Sources/macros'; import * as vtkMath from 'vtk.js/Sources/Common/Core/Math'; import vtkPicker from 'vtk.js/Sources/Rendering/Core/Picker';
const { vtkErrorMacro } = macro;
function vtkPointPicker(publicAPI, model) { model.classHierarchy.push('vtkPointPicker');
model.intersectWithLine = (p1, p2, tolerance, prop, mapper) => { let tMin = Number.MAX_VALUE;
if (mapper.isA('vtkImageMapper') || mapper.isA('vtkImageArrayMapper')) { const pickData = mapper.intersectWithLineForPointPicking(p1, p2); if (pickData) { tMin = pickData.t; model.pointIJK = pickData.ijk; } } else if (mapper.isA('vtkMapper')) { tMin = model.intersectActorWithLine(p1, p2, tolerance, mapper); }
return tMin; };
model.intersectActorWithLine = (p1, p2, tolerance, mapper) => { const input = mapper.getInputData();
let ptId = 0; const numPts = input.getPoints().getNumberOfPoints();
if (numPts <= ptId) { return 2.0; }
const ray = []; for (let i = 0; i < 3; i++) { ray[i] = p2[i] - p1[i]; }
const rayFactor = vtkMath.dot(ray, ray); if (rayFactor === 0.0) { vtkErrorMacro('Cannot process points'); return 2.0; }
let t; let minPtId = -1; let tMin = Number.MAX_VALUE; let minPtDist = Number.MAX_VALUE; const projXYZ = []; const minXYZ = []; const x = []; const points = input.getPoints();
if (model.useCells) { const cellData = input.getPolys().getData(); const nbPointsPerCell = cellData[0]; const nbCells = input.getPolys().getNumberOfCells();
for (let cellID = 0; cellID < nbCells; cellID++) { const firstPointIndex = cellID * nbPointsPerCell + 1; const lastPointIndex = firstPointIndex + nbPointsPerCell;
for ( let pointIndex = firstPointIndex; pointIndex < lastPointIndex; pointIndex++ ) { const pointDataIndex = cellData[pointIndex]; points.getPoint(pointDataIndex, x);
t = (ray[0] * (x[0] - p1[0]) + ray[1] * (x[1] - p1[1]) + ray[2] * (x[2] - p1[2])) / rayFactor;
if (t >= 0.0 && t <= 1.0 && t <= tMin + model.tolerance) { let maxDist = 0.0; for (let i = 0; i < 3; i++) { projXYZ[i] = p1[i] + t * ray[i]; const dist = Math.abs(x[i] - projXYZ[i]); if (dist > maxDist) { maxDist = dist; } } if (maxDist <= tolerance && maxDist < minPtDist) { minPtId = ptId; minXYZ[0] = x[0]; minXYZ[1] = x[1]; minXYZ[2] = x[2]; minPtDist = maxDist; tMin = t; } } } } } else { for (ptId = 0; ptId < numPts; ptId++) { points.getPoint(ptId, x);
t = (ray[0] * (x[0] - p1[0]) + ray[1] * (x[1] - p1[1]) + ray[2] * (x[2] - p1[2])) / rayFactor;
if (t >= 0.0 && t <= 1.0 && t <= tMin + model.tolerance) { let maxDist = 0.0; for (let i = 0; i < 3; i++) { projXYZ[i] = p1[i] + t * ray[i]; const dist = Math.abs(x[i] - projXYZ[i]); if (dist > maxDist) { maxDist = dist; } } if (maxDist <= tolerance && maxDist < minPtDist) { minPtId = ptId; minXYZ[0] = x[0]; minXYZ[1] = x[1]; minXYZ[2] = x[2]; minPtDist = maxDist; tMin = t; } } } }
if (minPtId > -1 && tMin < model.globalTMin) { model.globalTMin = tMin; model.pointId = minPtId; } return tMin; }; }
const DEFAULT_VALUES = { pointId: -1, pointIJK: [], useCells: false, };
export function extend(publicAPI, model, initialValues = {}) { Object.assign(model, DEFAULT_VALUES, initialValues);
vtkPicker.extend(publicAPI, model, initialValues);
macro.getArray(publicAPI, model, ['pointIJK']); macro.get(publicAPI, model, ['pointId']); macro.setGet(publicAPI, model, ['useCells']);
vtkPointPicker(publicAPI, model); }
export const newInstance = macro.newInstance(extend, 'vtkPointPicker');
export default { newInstance, extend };
|