# -*- coding: utf-8 -*-
"""
.. module:: voxel_array_utils
:synopsis: helper module for voxel-array
"""
import numpy as np
from scipy.interpolate import griddata
import vtk
from vtk.util import numpy_support as nps
[docs]def getCoordsInConvexHull(p):
"""Create the convex hull for a list of points and the list of coorindates internal to it.
:param np.ndarray p: N x 3 list of coordinates for which to calculate the cinvex hull. Coordinates should be integer
:return: M x 3 array of cooridnates, where M is the number of points internal to the convex hull
:rtype: np.ndarray
"""
# Get minimum and maximum coordinates
xMin, yMin, zMin = p.min(axis=0)
xMax, yMax, zMax = p.max(axis=0)
# Create coordinates between maximim and minimum
xCube, yCube, zCube = getCubeCoords(([xMin,xMax],[yMin,yMax],[zMin,zMax]))
ci = np.array((xCube, yCube, zCube)).T
# Linear interpolation
vi = griddata(p, np.ones((p.shape[0],)), ci, method='linear', fill_value=0)
# Delete points outside the convex hull
idx = np.nonzero(vi == 0)[0]
cInternal = np.delete(ci, idx, axis=0)
return cInternal
[docs]def getCubeCoords(S):
if hasattr(S,'__len__') == False:
l1, l2 = -(S-1)/2, (S+1)/2
xx, yy, zz = np.mgrid[l1:l2,l1:l2,l1:l2]
else:
xx, yy, zz = np.mgrid[S[0][0]:S[0][1],S[1][0]:S[1][1],S[2][0]:S[2][1]]
cx = xx.flatten()
cy = yy.flatten()
cz = zz.flatten()
return cx, cy, cz
[docs]def idx2xyz(idx, xl, yl, zl):
z = np.floor(idx / (xl*yl))
r = np.remainder(idx, xl*yl)
y = np.floor(r / xl)
x = np.remainder(r, xl)
return x, y, z
[docs]def xyz2idx(x, y, z, xl, yl, zl):
x[x >= xl] = xl-1
y[y >= yl] = yl-1
z[z >= zl] = zl-1
x[x < 0] = 0
y[y < 0] = 0
z[z < 0] = 0
idx = x + y * xl + z * (xl * yl)
return idx
[docs]def nparray2vtkImageData(v, d, s, vtkScalarType):
# Create source
source = vtk.vtkImageData()
source.SetDimensions(d[0], d[1], d[2])
source.SetNumberOfScalarComponents(1)
source.SetScalarType(vtkScalarType)
source.AllocateScalars()
source.SetSpacing(s[0], s[1], s[2])
# Copy numpy voxel array to vtkDataArray
dataArray = nps.numpy_to_vtk(v, deep=0, array_type=None)
source.GetPointData().GetScalars().DeepCopy(dataArray)
return source
[docs]def vtkImageData2vti(filePath, source):
writer = vtk.vtkXMLImageDataWriter()
writer.SetFileName(filePath)
writer.SetInput(source)
writer.Write()