delete point and cell from polydata

Hello, I am working on an interactive application and I need to delete individual points an, consequently, cells from polydata.

I figured out I can do like this (e.g. to remove the last point and cell from a polyline - polydata):

point_n = my_poly.GetNumberOfPoints()
my_poly.DeleteCell(point_n - 2) 
my_poly.DeletePoint(point_n - 1) 
my_poly.Modified()

However I always get a ‘Windows fatal exception: access violation’ error.

Thanks very much!

Quick update based on another post (https://discourse.vtk.org/t/python-seg-fault/3353).

If I do

my_poly.EditableOn()
my_poly.BuildLinks()
point_n = my_poly.GetNumberOfPoints()
my_poly.DeleteCell(point_n - 2) 
my_poly.DeletePoint(point_n - 1) 
my_poly.Modified()

I get no error, but the polydata is not modified. I tried also with Update() but it rises an error.

Thanks again!

Hello, excuse me but I was not able to solve this problem yet. Thanks in advance if you ca help!

Hi Bistek,

The DeleteCell() method just marks a cell for deletion. To actually delete the cells marked you need to call RemoveDeletedCells(). It’s better to think of it as a copy operation while omitting marked cells.

Look at Common\DataModel\Testing\Cxx\TestPolyDataRemoveDeletedCells.cxx for a code example.

If you’re trying to remove cells interactively, have a look at the classes vtkCellsFilter, vtkRemoveCellsFilter, vtkSelectCellsFilter here:https://github.com/glawlor/vtkbioeng/

hth,

Goodwin

Hello and thanks!

I’ve tried with DeleteCell() followed by RemoveDeletedCells(). It looks like it works just if you are removing all cells, like in:

my_poly.DeleteCell()
my_poly.RemoveDeletedCells()

But not specifying a particular cell:

id = 4
my_poly.DeleteCell(id)
my_poly.RemoveDeletedCells()

Now that I think about it, maybe I am doing something wrong when specifying the index of the cell to be deleted? I am using a simple integer but maybe I have to use a different syntax?

I was using this as a relevant example:

https://lorensen.github.io/VTKExamples/site/Cxx/PolyData/DeleteCells/

Thanks!

The method signature is “void DeleteCell(vtkIdType cellId)” - the integer id is required.

DeleteCells() just frees up the whole cell array - it’s not used with RemoveDeleteCells()

If you can post a small code example it might be easier to see where you’re going wrong.

Hi, and thanks again for feedback.
I am building an application where I digitize points with mouse clicks and add them to a polyline PolyData. Adding points is OK.

self is my PolyData-derived subclass in the following, and I have two methods:

def append_point(self, point_vector=None):
    """Appends a single point from Numpy point_vector at the end of the VTK point array"""
    point_vector = point_vector.flat[:]  # to be sure that point_vector is a row vector
    if self.GetNumberOfPoints() == 0:
        points = vtk.vtkPoints()
        points.InsertPoint(0, point_vector[0], point_vector[1], point_vector[2])
        self.SetPoints(points)
    else:
        self.GetPoints().InsertNextPoint(point_vector[0], point_vector[1], point_vector[2])

def append_cell(self, cell_array=None):
    """Appends a single line cell from Numpy array with vertex ids."""
    cell_array = cell_array.flat[:]  # to be sure that point_vector is a row vector
    line = vtk.vtkLine()
    line.GetPointIds().SetId(0, cell_array[0])
    line.GetPointIds().SetId(1, cell_array[1])
    if self.GetNumberOfCells() == 0:
        pline_cells = vtk.vtkCellArray()
    pline_cells.InsertNextCell(line)
    self.SetLines(pline_cells)
    self.GetLines().Modified()

Then I am able to incrementally add points and line cells with:

new_cell = np.asarray([[point_n - 1, point_n]])  # point_n is the present number of points
my_polyline.append_point(point_vector=new_point)  # new_point is a numpy 3x1 array with point coordinates from mouse interaction
my_polyline.append_cell(cell_array=new_cell)

This works flawlessly. I digitize with left clicks and end the digitization with a right click (with some mouse interactions omitted here).

Now I would like to undo the last point with a middle click (very handy when digitizing long lines). For this I need to delete the last point and line cell. I have tried different solutions but none works. I have also tried to delete all cells and points with self.Initialize(), then redefine all, but I always have crashes due to memory problems, or polylines with messed up topology.

Probably the solution is to filter the last cell and point out, but this leaves the problem of substituting the new PolyData obtained as output of the filter to the old one (the one that I am digitizing).

Do you know some example, possibly in Python, from which I could take some inspiration?

Thanks very much!

Hi Bistek,

Unfortuantely there aren’t many directly applicable examples. Here are some tips though:

  • An easy way to delete the last point (depending on your data structure) is to call “SetNumberOfPoints(n-1)” where n is the current number of points
  • Points->Reset() is an easy way to delete all points
  • In general, keep your data in vtk data structures only and don’t instantiate them in callbacks.
  • Use a single cell (but mulipoint) vtk polyline to represent a loop - not a collection of line cells
  • Have a look at the classes vtkSplineWidget/vtkSplineRepresentation or vtkPolylineWidget/vtkPolylineRepresentation - they may have the function you require.

hth

Goodwin

THANKS!!