vtkFlyingEdgesPlaneCutter unexpected empty output on image data boundary
Using the vtkFlyingEdgesPlaneCutter
on a vtkImageData
with a plane at a boundary (so it is aligned with main axis) creates an empty output in some configuration.
Tested with current master and 9.3.0
Different filters may fall back to the flying edge implementation and thus are impacted. This implies:
- the generic
vtkCutter
vtkPlaneCutter
vtkStructuredDataPlaneCutter
- the
vtkAMRCutPlane
filter, that iterates over blocks and forwards tovtkCutter
in some cases - probably others
Here is a script to reproduce
import vtk
img = vtk.vtkImageData()
img.SetOrigin(0, 0, 0)
img.SetSpacing(1, 1, 1)
img.SetExtent(0, 2, 0, 2, 0, 2)
# somehow required for the FlyingEdges to work
data = vtk.vtkFloatArray()
data.SetName("data")
data.SetNumberOfTuples(img.GetNumberOfPoints())
for i in range(img.GetNumberOfPoints()):
data.InsertNextValue(42)
img.GetPointData().AddArray(data)
img.GetPointData().SetScalars(data)
source = vtk.vtkTrivialProducer()
source.SetOutput(img)
plane = vtk.vtkPlane()
plane.SetNormal(0, 0, 1)
useClassic = False
cutter = None
if useClassic:
cutter=vtk.vtkCutter()
cutter.SetCutFunction(plane)
cutter.SetInputConnection(source.GetOutputPort())
else:
cutter=vtk.vtkFlyingEdgesPlaneCutter()
cutter.SetPlane(plane)
cutter.ComputeNormalsOff()
cutter.SetInputConnection(source.GetOutputPort())
sliceZ = img.GetBounds()[4]
plane.SetOrigin(0, 0, sliceZ)
cutter.Update()
cut=cutter.GetOutput()
print("slice at z = ZMin = {}".format(img.GetBounds()[4]))
print("nb of points in slice: {}".format(cut.GetNumberOfPoints()))
sliceZ = img.GetBounds()[4]+1e-12
plane.SetOrigin(0, 0, sliceZ)
cutter.Update()
cut=cutter.GetOutput()
print("slice at z = ZMin + 1e-12 = {}".format(sliceZ))
print("nb of points in slice: {}".format(cut.GetNumberOfPoints()))
sliceZ = img.GetBounds()[5]
plane.SetOrigin(0, 0, sliceZ)
cutter.Update()
cut=cutter.GetOutput()
print("slice at z = ZMax = {}".format(sliceZ))
print("nb of points in slice: {}".format(cut.GetNumberOfPoints()))
output
$ ./bin/vtkpython vtkslice.py
slice at z = ZMin = 0.0
nb of points in slice: 0
slice at z = ZMin + 1e-12 = 1e-12
nb of points in slice: 9
slice at z = ZMax = 2.0
nb of points in slice: 9
In this script, we create a simple vtkImageData
, size 3^3 points. We slice it with a plane that is Z normal. Cutting on Zmin outputs nothing, cutting on ZMax has correct output, i.e. 9 points.