Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { vec3 } from 'gl-matrix'; import vtkPlane from 'vtk.js/Sources/Common/DataModel/Plane'; /** * Perform plane-line intersection, where the line is defined by two points (p1, p2), * and the plane is defined by the imageData and slice number. * * @param {Vector3} p1 * @param {Vector3} p2 * @param {vtkImageMapper|vtkImageArrayMapper} mapper */ function doPicking(p1, p2, mapper) { const imageData = mapper.getCurrentImage(); const extent = imageData.getExtent(); // Slice origin const ijk = [extent[0], extent[2], extent[4]]; const { ijkMode } = mapper.getClosestIJKAxis(); let nSlice = mapper.isA('vtkImageArrayMapper') ? mapper.getSubSlice() : mapper.getSlice(); Iif (ijkMode !== mapper.getSlicingMode()) { // If not IJK slicing, get the IJK slice from the XYZ position/slice nSlice = mapper.getSliceAtPosition(nSlice); } ijk[ijkMode] += nSlice; const worldOrigin = [0, 0, 0]; imageData.indexToWorld(ijk, worldOrigin); // Normal computation ijk[ijkMode] += 1; const worldNormal = [0, 0, 0]; imageData.indexToWorld(ijk, worldNormal); worldNormal[0] -= worldOrigin[0]; worldNormal[1] -= worldOrigin[1]; worldNormal[2] -= worldOrigin[2]; vec3.normalize(worldNormal, worldNormal); const intersect = vtkPlane.intersectWithLine( p1, p2, worldOrigin, worldNormal ); if (intersect.intersection) { const point = intersect.x; const absoluteIJK = [0, 0, 0]; imageData.worldToIndex(point, absoluteIJK); // `t` is the parametric position along the line // defined in Plane.intersectWithLine return { t: intersect.t, absoluteIJK, }; } return null; } /** * Implement point picking for image plane. * The plane is defined by the imageData and current slice number, * set in the input mapper. * * @param {Vector3} p1 * @param {Vector3} p2 * @param {vtkImageMapper|vtkImageArrayMapper} mapper */ export function intersectWithLineForPointPicking(p1, p2, mapper) { const pickingData = doPicking(p1, p2, mapper); if (pickingData) { const imageData = mapper.getCurrentImage(); const extent = imageData.getExtent(); // Get closer integer ijk // NB: point picking means closest slice, means rounding const ijk = [ Math.round(pickingData.absoluteIJK[0]), Math.round(pickingData.absoluteIJK[1]), Math.round(pickingData.absoluteIJK[2]), ]; // Are we outside our actual extent Iif ( ijk[0] < extent[0] || ijk[0] > extent[1] || ijk[1] < extent[2] || ijk[1] > extent[3] || ijk[2] < extent[4] || ijk[2] > extent[5] ) { return null; } return { t: pickingData.t, ijk, }; } return null; } /** * Implement cell picking for image plane. * The plane is defined by the imageData and current slice number, * set in the input mapper. * * @param {Vector3} p1 * @param {Vector3} p2 * @param {vtkImageMapper|vtkImageArrayMapper} mapper */ export function intersectWithLineForCellPicking(p1, p2, mapper) { const pickingData = doPicking(p1, p2, mapper); if (pickingData) { const imageData = mapper.getCurrentImage(); const extent = imageData.getExtent(); const absIJK = pickingData.absoluteIJK; // Get closer integer ijk // NB: cell picking means closest voxel, means flooring const ijk = [ Math.floor(absIJK[0]), Math.floor(absIJK[1]), Math.floor(absIJK[2]), ]; // Are we outside our actual extent Iif ( ijk[0] < extent[0] || ijk[0] > extent[1] - 1 || ijk[1] < extent[2] || ijk[1] > extent[3] - 1 || ijk[2] < extent[4] || // handle single-slice images ijk[2] > (extent[5] ? extent[5] - 1 : extent[5]) ) { return null; } // Parametric coordinates within cell const pCoords = [ absIJK[0] - ijk[0], absIJK[1] - ijk[1], absIJK[2] - ijk[2], ]; return { t: pickingData.t, ijk, pCoords, }; } return null; } |