Threshold with Cell Set

In my last blog, I described a new type of unstructured grid which can be used to represent a subset of a structured dataset without explicit connectivity data structures. I mentioned that one very good application of such a dataset is a better implementation of the threshold filter. In the blog, we’ll go over such an implementation as shown here and here.

Let’s first quickly go over the original VTK implementation as can be found here. First notice that this filter accepts any vtkDataSet and produces an unstructured grid.

Next, let’s quickly take a look at RequestData. I added some comments in the excerpt to make it easier to follow. I also took out pieces that are not very relevant to our discussion. See the full source for details.

In our new filter, much of this will remain the same. In fact, to quickly develop it, I copied vtkThreshold to vtkThreshold3 and made a few changes. First, I change the filter to produce a vtkCellSet:

Next, I changed the part of the code that creates new points and cells to instead keep track of the ids of the cells that we want to threshold. So the following code

changes to

And the ids are used in creating the cell set as follows

Finally, we have to create an instance of vtkPoints for the output unstructured grid. This has to be handled specially in the cases where the input does not have its own vtkPoints (for example vtkImageData). Here is the code:

This is it! The output of this filter acts as an unstructured grid but does not store cells or points explicitly. As a bonus, the filter actually got simpler and performs better. We can exercise this filter as follows.

Careful readers probably noticed that there is a flaw in this approach: the output of the threshold filter contains all of the points of the input. Therefore, any point-based filters such as glyph and point statistics will incorrectly produce results based on all input points. With the current VTK data model, there is no easy way of fixing this issue. In the near future, we will add support for masking (blanking) of points and cells to all datasets. With this feature in place, one could easily keep track of all points touched by the output grid during tresholding and mask all others. In fact, if masking support was in the data model, we wouldn’t have to create a new unstructured grid but directly mask cells and points that are not needed. A blog for another time.

Questions or comments are always welcome!