% -*- latex -*-

\chapter{Filter Type Reference}
\label{chap:FilterTypeReference}

\index{filter!implementation|(}

In Chapters \ref{chap:SimpleWorklets} and \ref{chap:WorkletTypeReference} we discuss how to implement an algorithm in the \VTKm framework by creating a worklet.
For simplicity, worklet algorithms are wrapped in what are called filter objects for general usage.
Chapter \ref{chap:RunningFilters} introduces the concept of filters and documents those that come with the \VTKm library.
Chapter \ref{chap:BasicFilterImpl} gives a brief introduction on implementing filters.
This chapter elaborates on building new filter objects by introducing new filter types.
These will be used to wrap filters around the extended worklet examples in Chapter \ref{chap:WorkletTypeReference}.

Unsurprisingly, the base filter objects are contained in the \vtkmfilter{} package.
In particular, all filter objects inherit from \vtkmfilter{NewFilter}, either directly or indirectly.
The filter implementation must override the protected pure virtual method \classmember{NewFilter}{DoExecute}.
The base class will call this method to run the operation of the filter.

The \classmember*{NewFilter}{DoExecute} method has a single argument that is a \vtkmcont{DataSet}.
The \textidentifier{DataSet} contains the data on which the filter will operate.
\classmember*{NewFilter}{DoExecute} must then return a new \textidentifier{DataSet} containing the derived data.
The \textidentifier{DataSet} should be created with one of the \classmember{NewFilter}{CreateResult} methods.

A filter implementation may also optionally override the \classmember*{NewFilter}{DoExecutePartitions}.
This method is similar to \classmember*{NewFilter}{DoExecute} except that it takes and returns a \vtkmcont{PartitionedDataSet} object.
If a filter does not provide a \classmember*{NewFilter}{DoExecutePartitions} method, then if given a \textidentifier{PartitionedDataSet}, the base class will call \classmember*{NewFilter}{DoExecute} on each of the partitions and build a \textidentifier{PartitionedDataSet} with the results.

In addition to (or instead of) operating on the geometric structure of a \textidentifier{DataSet}, a filter will commonly take one or more fields from the input \textidentifier{DataSet} and write one or more fields to the result.
For this common occurrence, \VTKm provides the \vtkmfilter{NewFilterField} base class.
\textidentifier{NewFilterField} inherits from \textidentifier{NewField}; it provides all the same features and expects subclasses to implement algorithms in the same way.
But, \textidentifier{NewFilterField} provides convenience methods to select input fields and output field names.
It also provides a method named \classmember*{NewFilterField}{GetFieldFromDataSet} that can be used to get the input fields from the \textidentifier{DataSet} passed to \classmember*{NewFilterField}{DoExecute}.

Because \textidentifier{NewFilterField} subclasses must read fields from the input and/or write fields to the output, \textidentifier{NewFilterField} provides some convenience methods on top of those provided by \textidentifier{NewFilter}.
When getting a field with \classmember*{NewFilterField}{GetFieldFromDataSet}, you get a \vtkmcont{Field} object.
Before you can operate on the \textidentifier{Field}, you have to convert it to a \vtkmcont{ArrayHandle}.
\classmember{NewFilterField}{CastAndCallScalarField} can be used to do this conversion.
It takes the field object as the first argument and attempts to convert it to an \textidentifier{ArrayHandle} of different types.
When it finds the correct type, it calls the provided functor with the appropriate \textidentifier{ArrayHandle}.
The similar \classmember{NewFilterField}{CastAndCallVecField} does the same thing to find an \textidentifier{ArrayHandle} with \vtkm{Vec}s of a selected length.

\textidentifier{NewFilterField} also provides a \classmember*{NewFilterField}{CreateResultField} in addition to the \classmember*{NewFilter}{CreateResult} provided by its superclass.
\classmember*{NewFilterField}{CreateResultField} takes the \textidentifier{DataSet} provided to \classmember*{NewFilter}{DoExecute} and the specification for a field that has been generated and produces a resulting \textidentifier{DataSet} with the same structure as the input with the provided field added.

The remainder of this chapter will provide some common patterns of filter operation based on the data they use and generate.


\section{Deriving Fields from other Fields}
\label{sec:Filters:DerivingFields}

\index{filter!field|(}
\index{field filter|(}

A common type of filter is one that generates a new field that is derived from one or more existing fields or point coordinates on the data set.
For example, mass, volume, and density are interrelated, and any one can be derived from the other two.

Filters of this nature should be implemented in classes that derive the \vtkmfilter{NewFilterField} base class.
As described previously, \textidentifier{NewFilterField} provides facilities to manage input and output fields.
Typically, you would use \classmember{NewFilterField}{GetFieldFromDataSet} to retrieve the input fields, one of the \classmember{NewFilterField}{CastAndCall} methods to resolve the array type of the field, and finally use \classmember{NewFilterField}{CreateResultField} to produce the output.

In this section we provide an example implementation of a field filter that wraps the ``magnitude'' worklet provided in Example~\ref{ex:UseWorkletMapField} (listed on page~\pageref{ex:UseWorkletMapField}).
By C++ convention, object implementations are split into two files.
The first file is a standard header file with a \textfilename{.h} extension that contains the declaration of the filter class without the implementation.
So we would expect the following code to be in a file named \textfilename{FieldMagnitude.h}.

\vtkmlisting[ex:MagnitudeFilterDeclaration]{Header declaration for a field filter.}{UseFilterField.cxx}

\index{export macro}
\index{filter!export macro}
You may notice in Example \ref{ex:MagnitudeFilterDeclaration} line \ref{ex:UseFilterField.cxx:Export} there is a special macro names \textmacro{VTKM\_FILTER\_VECTOR\_CALCULUS\_EXPORT}.
This macro tells the C++ compiler that the class \textcode{FieldMagnitude} is going to be exported from a library.
More specifically, the CMake for \VTKm's build will generate a header file containing this export macro for the associated library.
By \VTKm's convention, a filter in the \namespace{vtkm}{filter}{vector\_calculus} will be defined in the \textfilename{vtkm/filter/vector\_calculus} directory and placed in a library named \textfilename{vtkm\_filter\_vector\_calculus}.
When defining the targets for this library, CMake will create a header file named \textfilename{vtkm\_filter\_vector\_calculus.h} that contains the macro named \textmacro{VTKM\_FILTER\_VECTOR\_CALCULUS\_EXPORT}.
This macro will provide the correct modifiers for the particular C++ compiler being used to export the class from the library.
If this macro is left out, then the library will work on some platforms, but on other platforms will produce a linker error for missing symbols.

Once the filter class is declared in the \textfilename{.h} file, the implementation filter is by convention given in a separate \textfilename{.cxx} file.
So the continuation of our example that follows would be expected in a file named \textfilename{FieldMagnitude.cxx}.

\vtkmlisting[ex:FilterFieldImpl.cxx]{Implementation of a field filter.}{FilterFieldImpl.cxx}

The implementation of \classmember*{NewFilter}{DoExecute} first pulls the input field from the provided \textidentifier{DataSet} using \classmember{NewFilterField}{GetFieldFromDataSet}.
It then uses \classmember{NewFilterField}{CastAndCallVecField} to determine what type of \textidentifier{ArrayHandle} is contained in the input field.
That calls a lambda function that invokes a worklet to create the output field.
Finally, \classmember{NewFilterField}{CreateResultField} generates the output of the filter.

\begin{didyouknow}
  The filter implemented in Example \ref{ex:FilterFieldImpl.cxx} is limited to only find the magnitude of \vtkm{Vec}s with 3 components.
  It may be the case you wish to implement a filter that operates on \vtkm{Vec}s of multiple sizes (or perhaps even any size).
  Chapter \ref{chap:UnknownArrayHandle} discusses how you can use the \vtkmcont{UnknownArrayHandle} contained in the \textidentifier{Field} to more expressively decide what types to check for.
\end{didyouknow}

Note that all fields need a unique name, which is the reason for the second argument to \textidentifier{CreateResult}.
The \vtkmfilter{NewFilterField} base class contains a pair of methods named \classmember*{NewFilterField}{SetOutputFieldName} and \classmember*{NewFilterField}{GetOutputFieldName} to allow users to specify the name of output fields.
The \classmember*{NewFilter}{DoExecute} method should respect the given output field name.
However, it is also good practice for the filter to have a default name if none is given.
This might be simply specifying a name in the constructor, but it is worthwhile for many filters to derive a name based on the name of the input field.

\section{Deriving Fields from Topology}
\label{sec:Filters:DerivingFieldsFromTopology}

\index{filter!field!using cells|(}
\index{field filter!using cells|(}

The previous example performed a simple operation on each element of a field independently.
However, it is also common for a ``field'' filter to take into account the topology of a data set.
In this case, the implementation involves pulling a \vtkmcont{CellSet} from the input \vtkmcont{DataSet} and performing operations on fields associated with different topological elements.
The steps involve calling \classmember{DataSet}{GetCellSet} to get access to the \textidentifier{CellSet} object and then using topology-based worklets, described in Section \ref{sec:TopologyMaps}, to operate on them.

In this section we provide an example implementation of a field filter on cells that wraps the ``cell center'' worklet provided in Example~\ref{ex:UseWorkletVisitCellsWithPoints} (listed on page~\pageref{ex:UseWorkletVisitCellsWithPoints}).

\vtkmlisting[ex:CellCenterFilterDeclaration]{Header declaration for a field filter using cell topology.}{UseFilterFieldWithCells.cxx}

\begin{didyouknow}
  \index{filter!supported types} You may have noticed that Example~\ref{ex:MagnitudeFilterDeclaration} provided a specification for \supportedtypes but Example~\ref{ex:CellCenterFilterDeclaration} provides no such specification.
  This demonstrates that declaring \supportedtypes is optional.
  If a filter only works on some limited number of types, then it can use \supportedtypes to specify the specific types it supports.
  But if a filter is generally applicable to many field types, it can simply use the default filter types.
\end{didyouknow}

As with any subclass of \textidentifier{NewFilter}, the filter implements \classmember*{NewFilter}{DoExecute}, which in this case invokes a worklet to compute a new field array and then return a newly constructed \vtkmcont{DataSet} object.

\vtkmlisting[ex:CellCenterFilterImplementation]{Implementation of a field filter using cell topology.}{FilterFieldWithCellsImpl.cxx}

\fix{TODO: The CastAndCall is too complex here. Probably should add a CastAndCallScalarOrVec to NewFilterField.}

\index{field filter!using cells|)}
\index{filter!field!using cells|)}

\index{field filter|)}
\index{filter!field|)}

\section{Data Set Filters}
\label{sec:CreatingDataSetFilters}

\index{filter!data set|(}
\index{data set filter|(}

Sometimes, a filter will generate a data set with a new cell set based off the cells of an input data set.
For example, a data set can be significantly altered by adding, removing, or replacing cells.

As with any filter, data set filters can be implemented in classes that derive the \vtkmfilter{NewFilter} base class and implement its \classmember*{NewFilter}{DoExecute} method.

In this section we provide an example implementation of a data set filter that wraps the functionality of extracting the edges from a data set as line elements.
Many variations of implementing this functionality are given in Chapter~\ref{chap:GeneratingCellSets}.
Suffice it to say that a pair of worklets will be used to create a new \vtkmcont{CellSet}, and this \textidentifier{CellSet} will be used to create the result \textidentifier{DataSet}.
Details on how the worklets work are given in Section \ref{sec:GeneratingCellSets:SingleType}.

Because the operation of this edge extraction depends only on \textidentifier{CellSet} in a provided \textidentifier{DataSet}, the filter class is a simple subclass of \vtkmfilter{NewFilter}.

\vtkmlisting[ex:ExtractEdgesFilterDeclaration.cxx]{Header declaration for a data set filter.}{ExtractEdgesFilterDeclaration.cxx}

The implementation of \classmember*{NewFilter}{DoExecute} first gets the \textidentifier{CellSet} and calls the worklet methods to generate a new \textidentifier{CellSet} class.
It then uses a form of \classmember{NewFilter}{CreateResult} to generate the resulting \textidentifier{DataSet}.

\vtkmlisting[ex:ExtractEdgesFilterDoExecute]{Implementation of the \classmember*{NewFilterDataSet}{DoExecute} method of a data set filter.}{ExtractEdgesFilterDoExecute.cxx}

The form of \classmember*{NewFilter}{CreateResult} used (line \ref{ex:ExtractEdgesFilterDoExecute.cxx:CreateResult}) takes as input a \textidentifier{CellSet} to use in the generated data.
In forms of \classmember*{NewFilter}{CreateResult} used in previous examples of this chapter, the cell structure of the output was created from the cell structure of the input.
Because these cell structures were the same, coordinate systems and fields needed to be changed.
However, because we are providing a new \textidentifier{CellSet}, we need to also specify how the coordinate systems and fields change.

The last two arguments to \classmember*{NewFilter}{CreateResult} are providing this information.
The second-to-last argument is a \textcode{std::vector} of the \textidentifier{CoordinateSystem}s to use.
Because this filter does not actually change the points in the data set, the \textidentifier{CoordinateSystem}s can just be copied over.
The last argument provides a functor that maps a field from the input to the output.
The functor takes two arguments: the output \textidentifier{DataSet} to modify and the input \textidentifier{Field} to map.
In this example, the functor is defined as a lambda function (line \ref{ex:ExtractEdgesFilterDoExecute.cxx:FieldMapper}).

\begin{didyouknow}
  The field mapper in Example \ref{ex:ExtractEdgesFilterDeclaration.cxx} uses a helper function named \vtkmfilter{MapFieldPermutation}.
  In the case of this example, every cell in the output comes from one cell in the input.
  For this common case, the values in the field arrays just need to be permuted so that each input value gets to the right output value.
  \textidentifier{MapFieldPermutation} will do this shuffling for you.

  \VTKm also comes with a similar helper function \vtkmfilter{MapFieldAverage} that can be used when each output cell (or point) was constructed from multiple inputs.
  In this case, \textidentifier{MapFieldAverage} can do a simple average for each output value of all input values that contributed.
\end{didyouknow}

\index{data set filter|)}
\index{filter!data set|)}

\section{Data Set with Field Filters}
\label{sec:CreatingDataSetWithFieldFilters}

\index{filter!data set with field|(}
\index{data set with field filter|(}

Sometimes, a filter will generate a data set with a new cell set based off the cells of an input data set along with the data in at least one field.
For example, a field might determine how each cell is culled, clipped, or sliced.

These type of filters are implemented in classes that derive the \vtkmfilter{NewFilterField} base class and override its \classmember*{NewFilter}{DoExecute} method.

In this section we provide an example implementation of a data set with field filter that blanks the cells in a data set based on a field that acts as a mask (or stencil).
Any cell associated with a mask value of zero will be removed.
For simplicity of this example, we will use the \textidentifier{Threshold} filter internally for the implementation.

\vtkmlisting[ex:BlankCellsFilterDeclaration]{Header declaration for a data set with field filter.}{BlankCellsFilterDeclaration.cxx}

The implementation of \classmember*{NewFilter}{DoExecute} first derives an array that contains a flag whether the input array value is zero or non-zero.
This is simply to guarantee the range for the threshold filter.
After that a threshold filter is set up and run to generate the result.

\vtkmlisting[ex:BlankCellsFilterDoExecute]{Implementation of the \classmember*{NewFilter}{DoExecute} method of a data set with field filter.}{BlankCellsFilterDoExecute.cxx}

\index{data set with field filter|)}
\index{filter!data set with field|)}


\index{filter!implementation|)}
