It’s a bit tricky to use vtkExtractVOI, because when it crops the volume, it also changes the indexing.  Take this simple example in Python:
a = vtkImageData()
a.SetDimensions(100,100,100)
a.AllocateScalars(VTK_UNSIGNED_CHAR,1)
v = vtkExtractVOI()
v.SetInputData(a)
v.SetVOI(25,50,25,50,25,50)
v.Update()
# cropped output
b = v.GetOutput()
b.GetExtent()
(25, 50, 25, 50, 25, 50)
b.GetOrigin()
(0, 0, 0)
The vtkExtractVOI filter has changed the indexing of the volume so that the indexing starts at i=25,j=25,k=25.  In order to adjust the volume so that the indexing starts at zero, use vtkImageChangeInformation like this:
c = vtkImageChangeInformation()
c.SetInputData(b)
c.SetOutputExtentStart(0,0,0)
c.Update()
c.GetOutput().GetExtent()
(0, 25, 0, 25, 0, 25)
c.GetOutput().GetOrigin()
(0.0, 0.0, 0.0)
Note that SetOutputExtentStart() and SetOutputOrigin() have complementary effects: they do similar things, but in different coordinate systems.  The best way that I can explain it is this:
- Changing the Extentchanges how the volume’s voxels are indexed
- Changing the Origin(andSpacingandDirection) change how the indices map to what we call VTK’s “Data Coordinates” (some people prefer to call them “Physical Coordinates”)
For convenience, the vtkImageData method GetIndexToPhysicalMatrix() will return a matrix that can be used to map from the i,j,k indices to the Data Coordinates.
I’m pretty sure that vtkImageChangeInformation is the filter that you want to use, and if you’re using it after vtkExtractVOI, you might have to change both the Origin and the Extent of the volume in order to make things work the way you expect.
The mapping from Data Coordinates to World Coordinates is controlled by the vtkProp3D class (this is the base class for vtkActor, vtkVolume, etc).  Only subclasses of vtkProp3D can adjust the mapping from Data to World.  With these classes, use GetMatrix() to get the 4x4 matrix that maps from Data Coordinates to World Coordinates.