Field represents a function that outputs a value based on an arbitrary number of inputs. The inputs for a specific field evaluation are provided by a
A typical example is a field that computes a displacement vector for every vertex on a mesh based on its position. In this case the
FieldContext is the mesh with the position attribute.
Fields can be build, composed and evaluated at run-time. They are stored in a directed tree graph data structure, whereby each node is a
FieldNode and edges are dependencies. A
FieldNode has an arbitrary number of inputs and at least one output. A
Field is a specific output of a
FieldNode. The inputs of a
FieldNode are other fields. All fields are immutable once they are built.
There are two different types of field nodes:
FieldInput: Has no input and exactly one output. It represents an input to the entire field when it is evaluated. During evaluation, the value of this input is based on a
FieldOperation: Has an arbitrary number of field inputs and at least one output. Its main use is to compose multiple existing fields into new fields.
Given one or more fields and a
FieldContext, the fields can be evaluated using the
Generic and Typed Fields
Most of the time, when working with fields, they have a specific type that is known at compile time. In this case, the
Field<T> class should be used. This class is a wrapper around a more generic
GField class (where G stands for "generic"). A
GField is a field whose type is only known at run-time. When converting from a
GField to a
Field<T> there is a run-time assert that makes sure that the conversion is valid.