if you are trying to use Joe's answer above, you'll get:
traits.trait_errors.TraitError: The 'input' trait of an ImageMarchingCubes instance is 'read only'.
Here is the the required change and a diff showing how to fix it.
Modified Code:
import numpy as np
from tvtk.api import tvtk
from tvtk.common import configure_input
def main():
# Generate some data with anisotropic cells...
# x,y,and z will range from -2 to 2, but with a
# different (20, 15, and 5 for x, y, and z) number of steps
x, y, z = np.mgrid[-2:2:20j, -2:2:15j, -2:2:5j]
r = np.sqrt(x**2 + y**2 + z**2)
dx, dy, dz = [np.diff(it, axis=a)[0, 0, 0] for it, a in zip(
(x, y, z), (0, 1, 2))]
# Your actual data is a binary (logical) array
max_radius = 1.5
data = (r <= max_radius).astype(np.int8)
ideal_volume = 4.0 / 3 * max_radius**3 * np.pi
coarse_volume = data.sum() * dx * dy * dz
est_volume = vtk_volume(data, (dx, dy, dz), (x.min(), y.min(), z.min()))
coarse_error = 100 * (coarse_volume - ideal_volume) / ideal_volume
vtk_error = 100 * (est_volume - ideal_volume) / ideal_volume
print('Ideal volume', ideal_volume)
print('Coarse approximation', coarse_volume, 'Error', coarse_error, '%')
print('VTK approximation', est_volume, 'Error', vtk_error, '%')
def vtk_volume(data, spacing=(1, 1, 1), origin=(0, 0, 0)):
data[data == 0] = -1
grid = tvtk.ImageData(spacing=spacing, origin=origin)
grid.point_data.scalars = data.T.ravel() # It wants fortran order???
grid.point_data.scalars.name = 'scalars'
grid.dimensions = data.shape
iso = tvtk.ImageMarchingCubes()
configure_input(iso, grid) # <== will work
# iso = tvtk.ImageMarchingCubes(input=grid)
mass = tvtk.MassProperties()
configure_input(mass, iso)
# mass = tvtk.MassProperties(input=iso.output)
return mass.volume
if __name__ == '__main__':
main()
Diff of changes I made
2a3,4
> from tvtk.common import configure_input
>
6c8
< # x,y,and z will range from -2 to 2, but with a
---
> # x,y,and z will range from -2 to 2, but with a
8c10
< x,y,z = np.mgrid[-2:2:20j, -2:2:15j, -2:2:5j]
---
> x, y, z = np.mgrid[-2:2:20j, -2:2:15j, -2:2:5j]
11c13,14
< dx, dy, dz = [np.diff(it, axis=a)[0,0,0] for it, a in zip((x,y,z),(0,1,2))]
---
> dx, dy, dz = [np.diff(it, axis=a)[0, 0, 0] for it, a in zip(
> (x, y, z), (0, 1, 2))]
24,26c27,30
< print 'Ideal volume', ideal_volume
< print 'Coarse approximation', coarse_volume, 'Error', coarse_error, '%'
< print 'VTK approximation', est_volume, 'Error', vtk_error, '%'
---
> print('Ideal volume', ideal_volume)
> print('Coarse approximation', coarse_volume, 'Error', coarse_error, '%')
> print('VTK approximation', est_volume, 'Error', vtk_error, '%')
>
28c32
< def vtk_volume(data, spacing=(1,1,1), origin=(0,0,0)):
---
> def vtk_volume(data, spacing=(1, 1, 1), origin=(0, 0, 0)):
31c35
< grid.point_data.scalars = data.T.ravel() # It wants fortran order???
---
> grid.point_data.scalars = data.T.ravel() # It wants fortran order???
35,36c39,44
< iso = tvtk.ImageMarchingCubes(input=grid)
< mass = tvtk.MassProperties(input=iso.output)
---
> iso = tvtk.ImageMarchingCubes()
> configure_input(iso, grid) # <== will work
> # iso = tvtk.ImageMarchingCubes(input=grid)
> mass = tvtk.MassProperties()
> configure_input(mass, iso)
> # mass = tvtk.MassProperties(input=iso.output)
39c47,49
< main()
---
>
> if __name__ == '__main__':
> main()
Itemized list of changes:
- Ran it through 2to3 so it can be run in python 3
- Fixed the code for PEP8 compliance according to autopep8 (syntax, length, spacing changes)
- Import configure_imput due to These changes in TVTK (Github code change)
- Modify the
input= kwarg in the ImageMarchingCubes constructor
- Modify the
input= kwargs in the MassProperties constructor
- Wrap the call to main() in a direct call (to prevent execution if imported) #BestPractices
nx * dx * ny * dy * nz * dz, but I'm pretty sure you didn't mean that... Do you want the volume inside an isosurface?pickle.dumppickle.dump(data, f, pickle.HIGHEST_PROTOCOL)Alternately, you can just usenumpy.save. Also, we can't load your data because you pickled some sort ofdataStructuresobject, and without your code, we can't unpickle it. Try pickling just the numpy array and a tuple of(dx, dy, dz).