irc_web/.svn/pristine/46/464f20cae23bd571f7cc6b1d99b...

125 lines
3.5 KiB
Plaintext

import { vec3 } from 'gl-matrix'
/**
* For each point in the image (If boundsIJK is not provided, otherwise, for each
* point in the provided bounding box), It runs the provided callback IF the point
* passes the provided criteria to be inside the shape (which is defined by the
* provided pointInShapeFn)
*
* @param imageData - The image data object.
* @param dimensions - The dimensions of the image.
* @param pointInShapeFn - A function that takes a point in LPS space and returns
* true if the point is in the shape and false if it is not.
* @param callback - A function that will be called for
* every point in the shape.
* @param boundsIJK - The bounds of the volume in IJK coordinates.
*/
function pointInShapeCallback(
imageData,
pointInShapeFn,
callback,
boundsIJK
) {
let iMin, iMax, jMin, jMax, kMin, kMax
let scalarData
// if getScalarData is a method on imageData
if ((imageData).getScalarData) {
scalarData = (ImageData).getScalarData()
} else {
scalarData = (imageData)
.getPointData()
.getScalars()
.getData()
}
const dimensions = imageData.getDimensions()
if (!boundsIJK) {
iMin = 0
iMax = dimensions[0]
jMin = 0
jMax = dimensions[1]
kMin = 0
kMax = dimensions[2]
} else {
[[iMin, iMax], [jMin, jMax], [kMin, kMax]] = boundsIJK
}
const start = vec3.fromValues(iMin, jMin, kMin)
const direction = imageData.getDirection()
const rowCosines = direction.slice(0, 3)
const columnCosines = direction.slice(3, 6)
const scanAxisNormal = direction.slice(6, 9)
const spacing = imageData.getSpacing()
const [rowSpacing, columnSpacing, scanAxisSpacing] = spacing
// @ts-ignore will be fixed in vtk-master
const worldPosStart = imageData.indexToWorld(start)
const rowStep = vec3.fromValues(
rowCosines[0] * rowSpacing,
rowCosines[1] * rowSpacing,
rowCosines[2] * rowSpacing
)
const columnStep = vec3.fromValues(
columnCosines[0] * columnSpacing,
columnCosines[1] * columnSpacing,
columnCosines[2] * columnSpacing
)
const scanAxisStep = vec3.fromValues(
scanAxisNormal[0] * scanAxisSpacing,
scanAxisNormal[1] * scanAxisSpacing,
scanAxisNormal[2] * scanAxisSpacing
)
const yMultiple = dimensions[0]
const zMultiple = dimensions[0] * dimensions[1]
const pointsInShape = []
for (let k = kMin; k <= kMax; k++) {
for (let j = jMin; j <= jMax; j++) {
for (let i = iMin; i <= iMax; i++) {
const pointIJK = [i, j, k]
const dI = i - iMin
const dJ = j - jMin
const dK = k - kMin
const startWorld = worldPosStart
const pointLPS = [
startWorld[0] +
dI * rowStep[0] +
dJ * columnStep[0] +
dK * scanAxisStep[0],
startWorld[1] +
dI * rowStep[1] +
dJ * columnStep[1] +
dK * scanAxisStep[1],
startWorld[2] +
dI * rowStep[2] +
dJ * columnStep[2] +
dK * scanAxisStep[2]
]
if (pointInShapeFn(pointLPS, pointIJK)) {
const index = k * zMultiple + j * yMultiple + i
const value = scalarData[index]
pointsInShape.push({ value, index, pointIJK, pointLPS })
if (callback !== null) {
callback({ value, index, pointIJK, pointLPS })
}
}
}
}
}
return pointsInShape
}
export { pointInShapeCallback }