125 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			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 }
 |