How to preserve array data with vtkClipPolyData?

(normanius) #1

I’m using vtkClipPolyData to clip a vtkPolyData object.

Is it possible to preserve the array data stored in the source object? I noticed that after clipping, the output does not contain any point- or cell-data. If it’s really the case that vtkClipPolyData drops any array data, how to achieve that the result contains array data?

Thanks for your hints!

(normanius) #2

The reason why vtkClipPolyData drops point- or cell data is because it creates new points and cells. For these new elements, it is not immediately clear what data has to be assigned to them.

It would be cool (==> FEATURE REQUEST <== :wink:) if vtkClipPolyData supported a data-interpolation mode where array-data is updated by making use of available data through interpolation.

As of know, I circumvented that problem by applying a mask on the points, ignoring cells entirely. This was feasible for me, but of course does not solve the problem in general for all uses of vtkClipPolyData. (The mask here contains the information if a point is lying on one side of the clip-plane, which I precomputed in a separate step)

def maskPoints(source, mask):
    arrayName = ARRAY_NAME
    assert(len(mask)==source.GetNumberOfPoints())

    nPoints = np.sum(mask)
    maskedPoly = vtk.vtkPolyData()
    points = vtk.vtkPoints()
    cells = vtk.vtkCellArray()

    array = vtk.vtkDoubleArray()
    array.SetNumberOfComponents(1)
    array.SetNumberOfTuples(nPoints)
    array.SetName(arrayName)
    array.FillComponent(0,0.0)

    count = 0
    for i in range(source.GetNumberOfPoints()):
        point = [0.,0.,0.]
        source.GetPoint(i, point)
        arrayVal = source.GetPointData().GetArray(arrayName).GetTuple1(i)
        if mask[i]:
            points.InsertNextPoint(point)
            array.SetTuple1(count, arrayVal)
            cells.InsertNextCell(1)
            cells.InsertCellPoint(count)
            count +=1
    maskedPoly.SetPoints(points)
    maskedPoly.SetVerts(cells)
    maskedPoly.GetPointData().AddArray(array)
    return maskedPoly
(Bane Sullivan) #3

I’ve never experienced the vtkClipPolyData filter not preserving the point/cell data like you mention…

We use the vtkClipPolyData filter like so in PyVista:

import vtk
import pyvista as pv
from pyvista import examples

# get some poly data object - use PyVista eample with cell data present
poly_data = examples.download_doorman()

# Make some implicit function to clip with:
plane = vtk.vtkPlane()
plane.SetNormal([1,0,0])
plane.SetOrigin(poly_data.GetCenter())

alg = vtk.vtkClipPolyData()
alg.SetInputDataObject(poly_data)
alg.SetClipFunction(plane) # the the cutter to use the plane we made
alg.SetInsideOut(False) # invert the clip if needed
alg.Update() # Perfrom the Cut
clipped = alg.GetOutput()

# Plot it up... use PyVista because it's easy
pv.plot(clipped, scalars='m_doorMan_clothing')

1 Like
(normanius) #4

Oh my! I tried myself and indeed, I cannot reproduce the problem. :man_facepalming: :upside_down_face:

I assume that my problem was caused further downstream in my code, and I wrongly attributed the failure to vtkClipPolyData. Sorry for this!

pyvista - nice work! Will give it a closer look. Thanks for the hint!

1 Like