Proposal
I would like to change vtkAlgorithm::SetInputArrayToProcess()
to optionally include a component index and add a method to fetch the component (if one has been specified) for a given input array.
I would also like to add a method to create a procedural single-component array (using vtkImplicitArray
) on demand that holds the single component specified (in cases where the array has multiple components).
Motivation
I’ve run into several use cases where
- a filter requires a single value per point or cell; rather than force users to create an array-calculator or other filter to extract a component from an existing array, it would be nice to accept vector/tensor arrays along with a component number; or
- a filter produces a vector or tensor array and I would like downstream filters to process a single component of it.
Details
When SetInputArrayToProcess()
is called, a vtkInformationVector
is set with
- the input port whose data holds the array (
INPUT_PORT
information key) - the input connection index whose data holds the array (
INPUT_CONNECTION
information key) - the array’s association (points/cells/rows/vertices/… via the
FIELD_ASSOCIATION
key), - the name (
FIELD_NAME
) or attribute-type (FIELD_ATTRIBUTE_TYPE
) of the array,
What I propose is to add an information key vtkDataObject::FIELD_COMPONENT
that is:
- unset when the entire array is to be used rather than a single component;
- set to a positive number when a single component of the given array is selected;
- set to a special value (
-1
orvtkDataObject::TupleL1Norm
) when the L₁ norm of a tuple should be used; - set to a special value (
-2
orvtkDataObject::TupleL2Norm
) when the L₂ norm of a tuple should be used.
Existing filters may safely ignore the array component when it is specified and continue to behave the way they currently do.
New SetInputArrayToProcess()
signatures would be added to accept an optional component-index (existing virtual
method signatures would not change for backwards compatibility):
void SetInputArrayToProcess(
const char* name, int fieldAssociation, int component = vtkDataObject::AllComponents);
virtual void SetInputArrayToProcess(
int idx, int port, int connection, int fieldAssociation, const char* name,
int component);
virtual void SetInputArrayToProcess(
int idx, int port, int connection, int fieldAssociation, int fieldAttributeType,
int component);
virtual void SetInputArrayToProcess(int idx, int port, int connection,
const char* fieldAssociation, const char* attributeTypeorName,
int component);
New or modified filters may call new methods on vtkAlgorithm
to fetch component information (no matter which SetInputArrayToProcess()
method was called):
virtual int GetInputArrayComponentToProcess(int idx);
virtual vtkSmartPointer<vtkAbstractArray> GetInputArray(
int idx, vtkInformationVector** inputInfo);
virtual vtkSmartPointer<vtkAbstractArray> GetInputArray(
int idx, vtkDataObject* data, int association);
The latter methods would return either a smart pointer to the original array (if it had an acceptable number of components) or a smart pointer to a vtkImplicitArray
that extracts the given component or norm from an original multi-component array as requested by the caller to SetInputArrayToProcess()
.