Table of Contents

Data and arrays

A data set is points, cells and fields, each held in VTK arrays. C# fills and reads them in bulk: one native copy per array, not a call per value.

An unstructured grid from C# arrays

// two unit cubes side by side along x: 12 points, x fastest, then y, then z
double[] coordinates =
[
  0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0,
  0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1,
];

// a hexahedron's corners: the bottom face counterclockwise, then the top; offsets mark where
// each cell's corners start in the connectivity, and where the last one ends
long[] connectivity = [0, 1, 4, 3, 6, 7, 10, 9, 1, 2, 5, 4, 7, 8, 11, 10];
long[] offsets = [0, 8, 16];

using var grid = new vtkUnstructuredGrid();
using (var points = new vtkPoints())
using (var pointArray = vtkDoubleArray.FromArray(coordinates, 3))
{
  points.SetData(pointArray);
  grid.SetPoints(points);
}

using (var offsetArray = vtkIdTypeArray.FromArray(offsets))
using (var connectivityArray = vtkIdTypeArray.FromArray(connectivity))
using (var cells = new vtkCellArray())
{
  cells.SetData(offsetArray, connectivityArray);
  grid.SetCells((int)VTKCellType.VTK_HEXAHEDRON, cells);
}
  • Points: a vtkDoubleArray of 3 components, as a vtkPoints' data.
  • Cells: vtkCellArray.SetData(offsets, connectivity), both vtkIdTypeArray: offsets has one entry more than there are cells. SetCells(type, cells) gives all cells one type (VTKCellType, cast to int).
  • Corner order is VTK's per cell type: see vtkHexahedron, vtkTetra and the others in the class index.

Fields

// a value per point: a temperature, and the one VTK colours by when nothing else is chosen
using var pointData = grid.GetPointData();
using (var temperature = vtkDoubleArray.FromArray(
         [20, 30, 40, 20, 30, 40, 20, 30, 40, 20, 30, 40]))
{
  temperature.SetName("temperature");
  pointData.AddArray(temperature);
}

pointData.SetActiveScalars("temperature");

// a value per cell: a vector of 3 components each
using var cellData = grid.GetCellData();
using (var velocity = vtkFloatArray.FromArray([1f, 0f, 0f, 3f, 4f, 0f], 3))
{
  velocity.SetName("velocity");
  cellData.AddArray(velocity);
}

A point field has a tuple per point (GetPointData()), a cell field one per cell (GetCellData()). SetActiveScalars makes a field the point data's GetScalars(); mappers and filters also take fields by name, see Results.

Reading fields back

// GetArray gives any field as a vtkDataArray, null for a name that isn't there
using var points = grid.GetPointData();
using var temperature = points.GetArray("temperature");
double[] values = temperature.ToDoubleArray(); // every value, converted to double
double[] range = temperature.GetRange();       // smallest and largest

// a vector's components one after another; GetRange(-1) is the magnitudes' range
using var cells = grid.GetCellData();
using var velocity = cells.GetArray("velocity");
double[] components = velocity.ToDoubleArray(); // 1, 0, 0, 3, 4, 0
double[] speeds = velocity.GetRange(-1);        // 1, 5

// the typed array, for a copy without conversion
using var typed = vtkFloatArray.SafeDownCast(velocity);
float[] floats = typed.ToArray();

Bulk copies

Copies and views of an array's values Copies and views of an array's values
// FromArray: a new array with a copy of the values, in tuples of the components given
using var displacement = vtkDoubleArray.FromArray([0.0, 0.0, -0.1, 0.0, 0.0, -0.2], 3);

// ToArray: a copy of all values; CopyFrom: replaces them, whole tuples, resizing the array
double[] copy = displacement.ToArray();
displacement.CopyFrom([0.0, 0.0, -0.1, 0.0, 0.0, -0.2, 0.0, 0.0, -0.3]);

// AsSpan (.NET 6 and later): the array's own memory, no copy; valid while the array lives
// and isn't resized. Tell VTK when the values changed, so pipelines run again
Span<double> values = displacement.AsSpan();
values[2] = -0.15;
displacement.Modified();
Member On Does
FromArray(values, components) the typed arrays a new array with a copy, in tuples of components (default 1)
ToArray() the typed arrays a copy of all values, no conversion
CopyFrom(values) the typed arrays replaces the values, resizing the array; a partial tuple throws ArgumentException
AsSpan() the typed arrays, .NET 6+ the array's own memory, no copy
ToDoubleArray() any vtkDataArray all values, converted to double: a typed loop for VTK's arrays, value by value for the others

The typed arrays are those deriving from vtkAOSDataArrayTemplate<T>: vtkDoubleArray, vtkFloatArray, vtkIntArray, vtkIdTypeArray, vtkUnsignedCharArray and the other fixed-width ones. vtkLongArray and vtkUnsignedLongArray (C long, whose width differs between platforms) derive from vtkDataArray in C#: ToDoubleArray() only.

Warning

Writing through AsSpan() doesn't mark the array modified: call Modified(), or the pipelines that use it won't run again.

// whatever the array stores: bytes, ints, floats, ids
using var labels = vtkUnsignedCharArray.FromArray([0, 128, 255]);
double[] values = labels.ToDoubleArray(); // 0, 128, 255