DataSetAttributes

Introduction

vtkDataSetAttributes is a class that is used to represent and manipulate
attribute data (e.g., scalars, vectors, normals, texture coordinates,
tensors, global ids, pedigree ids, and field data).

This adds to vtkFieldData the ability to pick one of the arrays from the
field as the currently active array for each attribute type. In other words,
you pick one array to be called “THE” Scalars, and then filters down the
pipeline will treat that array specially. For example vtkContourFilter will
contour “THE” Scalar array unless a different array is asked for.

Additionally vtkDataSetAttributes provides methods that filters call to pass
data through, copy data into, and interpolate from Fields. PassData passes
entire arrays from the source to the destination. Copy passes through some
subset of the tuples from the source to the destination. Interpolate
interpolates from the chosen tuple(s) in the source data, using the provided
weights, to produce new tuples in the destination. Each attribute type has
pass, copy and interpolate “copy” flags that can be set in the destination to
choose which attribute arrays will be transferred from the source to the
destination.

Finally this class provides a mechanism to determine which attributes a group
of sources have in common, and to copy tuples from a source into the
destination, for only those attributes that are held by all.

Methods

checkNumberOfComponents

Argument Type Required Description
x Yes

copyGlobalIdsOff

copyGlobalIdsOn

copyNormalsOff

copyNormalsOn

copyPedigreeIdsOff

copyPedigreeIdsOn

copyScalarsOff

copyScalarsOn

copyTCoordsOff

copyTCoordsOn

copyTensorsOff

copyTensorsOn

copyVectorsOff

copyVectorsOn

extend

Method used to decorate a given object (publicAPI+model) with vtkDataSetAttributes characteristics.

Argument Type Required Description
publicAPI Yes object on which methods will be bounds (public)
model Yes object on which data structure will be bounds (protected)
initialValues IDataSetAttributesInitialValues No (default: {})

getActiveAttribute

Argument Type Required Description
attType string Yes

getActiveGlobalIds

getActiveNormals

getActivePedigreeIds

getActiveScalars

getActiveTCoords

getActiveTensors

getActiveVectors

getAttributes

Get a list of attribute names that the given array
is for this vtkDataSetAttributes.

Argument Type Required Description
arr vtkDataArray Yes

Returns

Type Description
Array.

getGlobalIds

Get the global id data.

getNormals

Get the normal data.

getPedigreeIds

Get the pedigree id data.

getScalars

Get the scalar data.

getTCoords

Get the texture coordinate data.

getTensors

Get the tensors data.

getVectors

Get the vectors data.

initializeAttributeCopyFlags

newInstance

Method used to create a new instance of vtkDataSetAttributes.

Argument Type Required Description
initialValues IDataSetAttributesInitialValues No for pre-setting some of its content

removeAllArrays

Override to allow proper handling of active attributes

removeArray

Override to allow proper handling of active attributes

Argument Type Required Description
arrayName string Yes The name of the array.

removeArrayByIndex

Override to allow proper handling of active attributes

Argument Type Required Description
arrayIdx Number Yes The index of the array.

setActiveAttributeByIndex

Argument Type Required Description
arrayIdx Number Yes
uncleanAttType Yes

setActiveAttributeByName

Argument Type Required Description
arrayName string Yes
attType Yes

setActiveGlobalIds

Argument Type Required Description
arrayName string Yes The name of the array to activate.

setActiveGlobalIds

Argument Type Required Description
activeGlobalIds Number Yes

setActiveNormals

Argument Type Required Description
arrayName string Yes The name of the array to activate.

setActiveNormals

Argument Type Required Description
activeNormals Number Yes

setActivePedigreeIds

Argument Type Required Description
arrayName string Yes The name of the array to activate.

setActivePedigreeIds

Argument Type Required Description
activePedigreeIds Number Yes

setActiveScalars

Argument Type Required Description
arrayName string Yes The name of the array to activate.

setActiveScalars

Argument Type Required Description
activeScalars Number Yes

setActiveTCoords

Argument Type Required Description
arrayName string Yes The name of the array to activate.

setActiveTCoords

Argument Type Required Description
activeTCoords Number Yes

setActiveTensors

Argument Type Required Description
arrayName string Yes The name of the array to activate.

setActiveTensors

Argument Type Required Description
activeTensors Number Yes

setActiveVectors

Argument Type Required Description
arrayName string Yes The name of the array to activate.

setActiveVectors

Argument Type Required Description
activeVectors Number Yes

setAttribute

Argument Type Required Description
arr Yes
uncleanAttType Yes

setGlobalIds

Set the global id data.

Argument Type Required Description
globalIds vtkDataArray Yes The global id data.

setNormals

Set the normal data.

Argument Type Required Description
normals vtkDataArray Yes The normal data.

setPedigreeIds

Set the pedigree id data.

Argument Type Required Description
pedigreeids vtkDataArray Yes The pedigree id data.

setScalars

Set the scalar data.

Argument Type Required Description
scalars vtkDataArray Yes The scalar data.

setTCoords

Set the texture coordinate data.

Argument Type Required Description
tcoords vtkDataArray Yes The texture coordinate data.

setTensors

Set the tensor data.

Argument Type Required Description
tensors vtkDataArray Yes The tensor data.

setVectors

Set the vector data.

Argument Type Required Description
vectors vtkDataArray Yes The vector data.

shallowCopy

Try to copy the state of the other to ourselves by just using references.

Argument Type Required Description
other Yes instance to copy the reference from
debug Yes (default: false) if true feedback will be provided when mismatch happen

Source

Constants.js
export const AttributeTypes = {
SCALARS: 0,
VECTORS: 1,
NORMALS: 2,
TCOORDS: 3,
TENSORS: 4,
GLOBALIDS: 5,
PEDIGREEIDS: 6,
EDGEFLAG: 7,
NUM_ATTRIBUTES: 8,
};

export const AttributeLimitTypes = {
MAX: 0,
EXACT: 1,
NOLIMIT: 2,
};

export const CellGhostTypes = {
DUPLICATECELL: 1, // the cell is present on multiple processors
HIGHCONNECTIVITYCELL: 2, // the cell has more neighbors than in a regular mesh
LOWCONNECTIVITYCELL: 4, // the cell has less neighbors than in a regular mesh
REFINEDCELL: 8, // other cells are present that refines it.
EXTERIORCELL: 16, // the cell is on the exterior of the data set
HIDDENCELL: 32, // the cell is needed to maintain connectivity, but the data values should be ignored.
};

export const PointGhostTypes = {
DUPLICATEPOINT: 1, // the cell is present on multiple processors
HIDDENPOINT: 2, // the point is needed to maintain connectivity, but the data values should be ignored.
};

export const AttributeCopyOperations = {
COPYTUPLE: 0,
INTERPOLATE: 1,
PASSDATA: 2,
ALLCOPY: 3, // all of the above
};

export const ghostArrayName = 'vtkGhostType';

export const DesiredOutputPrecision = {
DEFAULT: 0, // use the point type that does not truncate any data
SINGLE: 1, // use Float32Array
DOUBLE: 2, // use Float64Array
};

export default {
AttributeCopyOperations,
AttributeLimitTypes,
AttributeTypes,
CellGhostTypes,
DesiredOutputPrecision,
PointGhostTypes,
ghostArrayName,
};
FieldData.d.ts
import { vtkObject } from "../../../interfaces" ;
import { Nullable } from "../../../types";
import type vtkDataArray from "../../Core/DataArray";

/**
*
*/
export interface IFieldDataInitialValues {
arrays?: vtkDataArray[];
copyFieldFlags?: Array<any>;
doCopyAllOn?: boolean;
doCopyAllOff?: boolean;
}

/**
*
*/
interface IArrayWithIndex {
array: vtkDataArray,
index: number;
}

export interface vtkFieldData extends vtkObject {

/**
*
*/
initialize(): void;

/**
*
*/
initializeFields(): void;

/**
*
* @param {vtkFieldData} other
*/
copyStructure(other: vtkFieldData): void;

/**
* Get the number of arrays.
*/
getNumberOfArrays(): number;

/**
* Get the number of active arrays.
*/
getNumberOfActiveArrays(): number;

/**
* Add a new array.
* If an array with the same name already exists, it is replaced instead.
* @param {vtkDataArray} arr
*/
addArray(arr: vtkDataArray): number;

/**
* Remove all the arrays.
*/
removeAllArrays(): void;

/**
* Remove an array.
* @param {String} arrayName The name of the array.
*/
removeArray(arrayName: string): void;

/**
* Remove an array by its index.
* @param {Number} arrayIdx The index of the array to remove.
*/
removeArrayByIndex(arrayIdx: number): void;

/**
* Get all arrays.
*/
getArrays(): vtkDataArray[];

/**
*
* @param {number | string} arraySpec index or name of the array
*/
getArray(arraySpec: number | string): Nullable<vtkDataArray>;

/**
* Get an array by its name.
* @param {String} arrayName The name of the array.
*/
getArrayByName(arrayName: string): Nullable<vtkDataArray>;

/**
*
* @param {String} arrayName The name of the array.
*/
getArrayWithIndex(arrayName: string): IArrayWithIndex;

/**
* Get an array by its index.
* @param {Number} idx The index of the array.
*/
getArrayByIndex(idx: number): Nullable<vtkDataArray>;

/**
* Return true if there exists an array with the given arraName. False otherwise.
* @param {String} arrayName The name of the array.
*/
hasArray(arrayName: string): boolean;

/**
* Get the name of an array at the given index.
* @param {Number} idx The index of the array.
*/
getArrayName(idx: number): string;

/**
*
*/
getCopyFieldFlags(): object;

/**
* Get the flag of the array that has the given name.
* @param {String} arrayName The name of the array.
*/
getFlag(arrayName: string): boolean;

/**
* Pass data from one fieldData to another at the given index.
* @param {vtkFieldData} other
* @param {Number} [fromId] (default: -1)
* @param {Number} [toId] (default: -1)
*/
passData(other: vtkFieldData, fromId?: number, toId?: number): void;

/**
* Works like passData, but interpolates the values between the two given fromIds.
* @param {vtkFieldData} other
* @param {Number} [fromId1] (default: -1)
* @param {Number} [fromId2] (default: -1)
* @param {Number} [toId] (default: -1)
* @param {Number} [t] (default: 0.5)
*/
interpolateData(other: vtkFieldData, fromId1?: number, fromId2?: number, toId?: number, t?: number): void;

/**
*
* @param {String} arrayName The name of the array.
*/
copyFieldOn(arrayName: string): void;

/**
*
* @param {String} arrayName The name of the array.
*/
copyFieldOff(arrayName: string): void;

/**
*
*/
copyAllOn(): void;

/**
*
*/
copyAllOff(): void;

/**
*
*/
clearFieldFlags(): void;

/**
*
* @param {vtkFieldData} other
*/
deepCopy(other: vtkFieldData): void;

/**
*
* @param {vtkFieldData} other
*/
copyFlags(other: vtkFieldData): void;

/**
* TODO: publicAPI.squeeze = () => model.arrays.forEach(entry => entry.data.squeeze());
*/
reset(): void;

/**
* Return the `Modified Time` which is a monotonic increasing integer
* global for all vtkObjects.
*
* This allow to solve a question such as:
* - Is that object created/modified after another one?
* - Do I need to re-execute this filter, or not? ...
*
* @return {Number} the global modified time.
*/
getMTime(): number;

/**
* TODO: publicAPI.getField = (ids, other) => { copy ids from other into this model's arrays }
* TODO: publicAPI.getArrayContainingComponent = (component) => ...
*/
getNumberOfComponents(): number;

/**
*
*/
getNumberOfTuples(): number;

/**
*
*/
getState(): object;
}

/**
* Method used to decorate a given object (publicAPI+model) with vtkFieldData characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {IFieldDataInitialValues} [initialValues] (default: {})
*/
export function extend(publicAPI: object, model: object, initialValues?: IFieldDataInitialValues): void;

/**
* Method used to create a new instance of vtkFieldData.
* @param {IFieldDataInitialValues} [initialValues] for pre-setting some of its content
*/
export function newInstance(initialValues?: IFieldDataInitialValues): vtkFieldData;

/**
*
*/
export declare const vtkFieldData: {
newInstance: typeof newInstance,
extend: typeof extend,
};
export default vtkFieldData;
FieldData.js
import vtk from 'vtk.js/Sources/vtk';
import macro from 'vtk.js/Sources/macros';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';

const { vtkErrorMacro, vtkWarningMacro } = macro;

// ----------------------------------------------------------------------------
// vtkFieldData methods
// ----------------------------------------------------------------------------

function vtkFieldData(publicAPI, model) {
model.classHierarchy.push('vtkFieldData');
const superGetState = publicAPI.getState;

// Decode serialized data if any
if (model.arrays) {
model.arrays = model.arrays.map((item) => ({ data: vtk(item.data) }));
}

publicAPI.initialize = () => {
publicAPI.initializeFields();
publicAPI.copyAllOn();
publicAPI.clearFieldFlags();
};

publicAPI.initializeFields = () => {
model.arrays = [];
model.copyFieldFlags = {};
publicAPI.modified();
};

publicAPI.copyStructure = (other) => {
publicAPI.initializeFields();
model.copyFieldFlags = other.getCopyFieldFlags().map((x) => x); // Deep-copy
model.arrays = other.arrays().map((x) => ({ array: x })); // Deep-copy
// TODO: Copy array information objects (once we support information objects)
};

publicAPI.getNumberOfArrays = () => model.arrays.length;
publicAPI.getNumberOfActiveArrays = () => model.arrays.length;
publicAPI.addArray = (arr) => {
const name = arr.getName();
const { array, index } = publicAPI.getArrayWithIndex(name);
if (array != null) {
model.arrays[index] = { data: arr };
return index;
}
model.arrays = [].concat(model.arrays, { data: arr });
return model.arrays.length - 1;
};
publicAPI.removeAllArrays = () => {
model.arrays = [];
};
publicAPI.removeArray = (arrayName) => {
model.arrays = model.arrays.filter(
(entry) => arrayName !== entry.data.getName()
);
};
publicAPI.removeArrayByIndex = (arrayIdx) => {
model.arrays = model.arrays.filter((entry, idx) => idx !== arrayIdx);
};
publicAPI.getArrays = () => model.arrays.map((entry) => entry.data);
publicAPI.getArray = (arraySpec) =>
typeof arraySpec === 'number'
? publicAPI.getArrayByIndex(arraySpec)
: publicAPI.getArrayByName(arraySpec);
publicAPI.getArrayByName = (arrayName) =>
model.arrays.reduce(
(a, b, i) => (b.data.getName() === arrayName ? b.data : a),
null
);
publicAPI.getArrayWithIndex = (arrayName) =>
model.arrays.reduce(
(a, b, i) =>
b.data && b.data.getName() === arrayName
? { array: b.data, index: i }
: a,
{ array: null, index: -1 }
);
publicAPI.getArrayByIndex = (idx) =>
idx >= 0 && idx < model.arrays.length ? model.arrays[idx].data : null;
publicAPI.hasArray = (arrayName) =>
publicAPI.getArrayWithIndex(arrayName).index >= 0;
publicAPI.getArrayName = (idx) => {
const arr = model.arrays[idx];
return arr ? arr.data.getName() : '';
};
publicAPI.getCopyFieldFlags = () => model.copyFieldFlags;
publicAPI.getFlag = (arrayName) => model.copyFieldFlags[arrayName];
publicAPI.passData = (other, fromId = -1, toId = -1) => {
other.getArrays().forEach((arr) => {
const copyFlag = publicAPI.getFlag(arr.getName());
if (
copyFlag !== false &&
!(model.doCopyAllOff && copyFlag !== true) &&
arr
) {
let destArr = publicAPI.getArrayByName(arr.getName());
if (!destArr) {
if (fromId < 0 || fromId > arr.getNumberOfTuples()) {
// TBD: should this be a deep or a shallow copy?
publicAPI.addArray(arr);
other.getAttributes(arr).forEach((attrType) => {
publicAPI.setAttribute(arr, attrType);
});
} else {
const ncomps = arr.getNumberOfComponents();
let newSize = arr.getNumberOfValues();
const tId = toId > -1 ? toId : fromId;
if (newSize <= tId * ncomps) {
newSize = (tId + 1) * ncomps;
}
destArr = vtkDataArray.newInstance({
name: arr.getName(),
dataType: arr.getDataType(),
numberOfComponents: ncomps,
values: macro.newTypedArray(arr.getDataType(), newSize),
size: 0,
});
destArr.insertTuple(tId, arr.getTuple(fromId));
publicAPI.addArray(destArr);
other.getAttributes(arr).forEach((attrType) => {
publicAPI.setAttribute(destArr, attrType);
});
}
} else if (
arr.getNumberOfComponents() === destArr.getNumberOfComponents()
) {
if (fromId > -1 && fromId < arr.getNumberOfTuples()) {
const tId = toId > -1 ? toId : fromId;
destArr.insertTuple(tId, arr.getTuple(fromId));
} else {
// if `fromId` is not provided, just copy all (or as much possible)
// from `arr` to `destArr`.
destArr.insertTuples(0, arr.getTuples());
}
} else {
vtkErrorMacro('Unhandled case in passData');
}
}
});
};

publicAPI.interpolateData = (
other,
fromId1 = -1,
fromId2 = -1,
toId = -1,
t = 0.5
) => {
other.getArrays().forEach((arr) => {
const copyFlag = publicAPI.getFlag(arr.getName());
if (
copyFlag !== false &&
!(model.doCopyAllOff && copyFlag !== true) &&
arr
) {
let destArr = publicAPI.getArrayByName(arr.getName());
if (!destArr) {
if (fromId1 < 0 || fromId2 < 0 || fromId1 > arr.getNumberOfTuples()) {
// TBD: should this be a deep or a shallow copy?
publicAPI.addArray(arr);
other.getAttributes(arr).forEach((attrType) => {
publicAPI.setAttribute(arr, attrType);
});
} else {
const ncomps = arr.getNumberOfComponents();
let newSize = arr.getNumberOfValues();
// TODO: Is this supposed to happen?
const tId = toId > -1 ? toId : fromId1;
if (newSize <= tId * ncomps) {
newSize = (tId + 1) * ncomps;
}
destArr = vtkDataArray.newInstance({
name: arr.getName(),
dataType: arr.getDataType(),
numberOfComponents: ncomps,
values: macro.newTypedArray(arr.getDataType(), newSize),
size: 0,
});
destArr.interpolateTuple(tId, arr, fromId1, arr, fromId2, t);
publicAPI.addArray(destArr);
other.getAttributes(arr).forEach((attrType) => {
publicAPI.setAttribute(destArr, attrType);
});
}
} else if (
arr.getNumberOfComponents() === destArr.getNumberOfComponents()
) {
if (fromId1 > -1 && fromId1 < arr.getNumberOfTuples()) {
const tId = toId > -1 ? toId : fromId1;
destArr.interpolateTuple(tId, arr, fromId1, arr, fromId2, t);
vtkWarningMacro('Unexpected case in interpolateData');
} else {
// if `fromId` is not provided, just copy all (or as much possible)
// from `arr` to `destArr`.
destArr.insertTuples(arr.getTuples());
}
} else {
vtkErrorMacro('Unhandled case in interpolateData');
}
}
});
};
publicAPI.copyFieldOn = (arrayName) => {
model.copyFieldFlags[arrayName] = true;
};
publicAPI.copyFieldOff = (arrayName) => {
model.copyFieldFlags[arrayName] = false;
};
publicAPI.copyAllOn = () => {
if (!model.doCopyAllOn || model.doCopyAllOff) {
model.doCopyAllOn = true;
model.doCopyAllOff = false;
publicAPI.modified();
}
};
publicAPI.copyAllOff = () => {
if (model.doCopyAllOn || !model.doCopyAllOff) {
model.doCopyAllOn = false;
model.doCopyAllOff = true;
publicAPI.modified();
}
};
publicAPI.clearFieldFlags = () => {
model.copyFieldFlags = {};
};
publicAPI.deepCopy = (other) => {
model.arrays = other.getArrays().map((arr) => {
const arrNew = arr.newClone();
arrNew.deepCopy(arr);
return { data: arrNew };
});
};
publicAPI.copyFlags = (other) => other.getCopyFieldFlags().map((x) => x);
// TODO: publicAPI.squeeze = () => model.arrays.forEach(entry => entry.data.squeeze());
publicAPI.reset = () => model.arrays.forEach((entry) => entry.data.reset());
// TODO: getActualMemorySize
publicAPI.getMTime = () =>
model.arrays.reduce(
(a, b) => (b.data.getMTime() > a ? b.data.getMTime() : a),
model.mtime
);
// TODO: publicAPI.getField = (ids, other) => { copy ids from other into this model's arrays }
// TODO: publicAPI.getArrayContainingComponent = (component) => ...
publicAPI.getNumberOfComponents = () =>
model.arrays.reduce((a, b) => a + b.data.getNumberOfComponents(), 0);
publicAPI.getNumberOfTuples = () =>
model.arrays.length > 0 ? model.arrays[0].getNumberOfTuples() : 0;

publicAPI.getState = () => {
const result = superGetState();
if (result) {
result.arrays = model.arrays.map((item) => ({
data: item.data.getState(),
}));
}
return result;
};
}

const DEFAULT_VALUES = {
arrays: [],
copyFieldFlags: [], // fields not to copy
doCopyAllOn: true,
doCopyAllOff: false,
};

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);

macro.obj(publicAPI, model);

vtkFieldData(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkFieldData');

// ----------------------------------------------------------------------------

export default { newInstance, extend };
index.d.ts
import { vtkObject } from "../../../interfaces" ;
import { IFieldDataInitialValues, vtkFieldData } from './FieldData';
import vtkDataArray from '../../Core/DataArray';

export enum AttributeTypes {
SCALARS,
VECTORS,
NORMALS,
TCOORDS,
TENSORS,
GLOBALIDS,
PEDIGREEIDS,
EDGEFLAG,
NUM_ATTRIBUTES,
}

export enum AttributeLimitTypes {
MAX,
EXACT,
NOLIMIT,
}

export enum CellGhostTypes {
/**
* The cell is present on multiple processors
*/
DUPLICATECELL,
/**
* The cell has more neighbors than in a regular mesh
*/
HIGHCONNECTIVITYCELL,
/**
* The cell has less neighbors than in a regular mesh
*/
LOWCONNECTIVITYCELL,
/**
* Tther cells are present that refines it.
*/
REFINEDCELL,
/**
* The cell is on the exterior of the data set
*/
EXTERIORCELL,
/**
* The cell is needed to maintain connectivity, but the data values should be ignored.
*/
HIDDENCELL,
}

export enum PointGhostTypes {
/**
* The cell is present on multiple processors
*/
DUPLICATEPOINT,
/**
* The point is needed to maintain connectivity, but the data values should be ignored.
*/
HIDDENPOINT
}

export enum AttributeCopyOperations {
COPYTUPLE,
INTERPOLATE,
PASSDATA,
/**
* All of the above
*/
ALLCOPY,
}

export const ghostArrayName: string;

export enum DesiredOutputPrecision {
/**
* Use the point type that does not truncate any data
*/
DEFAULT,
/**
* Use Float32Array
*/
SINGLE,
/**
* Use Float64Array
*/
DOUBLE,
}

/**
*
*/
export interface IDataSetAttributesInitialValues extends IFieldDataInitialValues {
activeScalars?: number;
activeVectors?: number;
activeTensors?: number;
activeNormals?: number;
activeTCoords?: number;
activeGlobalIds?: number;
activePedigreeIds?: number;
}

export interface vtkDataSetAttributes extends vtkFieldData {

/**
* @todo No yet Implemented
* @param x
*/
checkNumberOfComponents(x: any): boolean;

/**
*
* @param {string} attType
*/
getActiveAttribute(attType: string): any;

/**
* Get a list of attribute names that the given array
* is for this vtkDataSetAttributes.
* @param {vtkDataArray} arr
* @returns {String[]}
*/
getAttributes(arr: vtkDataArray): string[];

/**
*
*/
getActiveScalars(): number;

/**
*
*/
getActiveVectors(): number;

/**
*
*/
getActiveTensors(): number;

/**
*
*/
getActiveNormals(): number;

/**
*
*/
getActiveTCoords(): number;

/**
*
*/
getActiveGlobalIds(): number;

/**
*
*/
getActivePedigreeIds(): number;

/**
* Get the scalar data.
*/
getScalars(): vtkDataArray;

/**
* Get the vectors data.
*/
getVectors(): vtkDataArray;

/**
* Get the normal data.
*/
getNormals(): vtkDataArray;

/**
* Get the texture coordinate data.
*/
getTCoords(): vtkDataArray;

/**
* Get the tensors data.
*/
getTensors(): vtkDataArray;

/**
* Get the global id data.
*/
getGlobalIds(): vtkDataArray;

/**
* Get the pedigree id data.
*/
getPedigreeIds(): vtkDataArray;

/**
*
* @param arr
* @param uncleanAttType
*/
setAttribute(arr: any, uncleanAttType: string): number;

/**
*
* @param {string} arrayName
* @param attType
*/
setActiveAttributeByName(arrayName: string, attType: any): number;

/**
*
* @param {Number} arrayIdx
* @param uncleanAttType
*/
setActiveAttributeByIndex(arrayIdx: number, uncleanAttType: string): number;

/**
* Override to allow proper handling of active attributes
*/
removeAllArrays(): void;

/**
* Override to allow proper handling of active attributes
* @param {string} arrayName The name of the array.
*/
removeArray(arrayName: string): void;

/**
* Override to allow proper handling of active attributes
* @param {Number} arrayIdx The index of the array.
*/
removeArrayByIndex(arrayIdx: number): void;

/**
*
*/
initializeAttributeCopyFlags(): void;

/**
*
* @param {Number} activeScalars
*/
setActiveScalars(activeScalars: number): boolean;

/**
*
* @param {Number} activeVectors
*/
setActiveVectors(activeVectors: number): boolean;

/**
*
* @param {Number} activeTensors
*/
setActiveTensors(activeTensors: number): boolean;

/**
*
* @param {Number} activeNormals
*/
setActiveNormals(activeNormals: number): boolean;

/**
*
* @param {Number} activeTCoords
*/
setActiveTCoords(activeTCoords: number): boolean;

/**
*
* @param {Number} activeGlobalIds
*/
setActiveGlobalIds(activeGlobalIds: number): boolean;

/**
*
* @param {Number} activePedigreeIds
*/
setActivePedigreeIds(activePedigreeIds: number): boolean;

/**
* Try to copy the state of the other to ourselves by just using references.
*
* @param other instance to copy the reference from
* @param debug (default: false) if true feedback will be provided when mismatch happen
* @override
*/
shallowCopy(other: vtkObject, debug?: boolean): void;

/**
*
* @param {string} arrayName The name of the array to activate.
*/
setActiveScalars(arrayName: string): boolean;

/**
*
* @param {string} arrayName The name of the array to activate.
*/
setActiveVectors(arrayName: string): boolean;

/**
*
* @param {string} arrayName The name of the array to activate.
*/
setActiveNormals(arrayName: string): boolean;

/**
*
* @param {string} arrayName The name of the array to activate.
*/
setActiveTCoords(arrayName: string): boolean;

/**
*
* @param {string} arrayName The name of the array to activate.
*/
setActiveTensors(arrayName: string): boolean;

/**
*
* @param {string} arrayName The name of the array to activate.
*/
setActiveGlobalIds(arrayName: string): boolean;

/**
*
* @param {string} arrayName The name of the array to activate.
*/
setActivePedigreeIds(arrayName: string): boolean;

/**
* Set the scalar data.
* @param {vtkDataArray} scalars The scalar data.
*/
setScalars(scalars: vtkDataArray): boolean;

/**
* Set the vector data.
* @param {vtkDataArray} vectors The vector data.
*/
setVectors(vectors: vtkDataArray): boolean;

/**
* Set the normal data.
* @param {vtkDataArray} normals The normal data.
*/
setNormals(normals: vtkDataArray): boolean;

/**
* Set the texture coordinate data.
* @param {vtkDataArray} tcoords The texture coordinate data.
*/
setTCoords(tcoords: vtkDataArray): boolean;

/**
* Set the tensor data.
* @param {vtkDataArray} tensors The tensor data.
*/
setTensors(tensors: vtkDataArray): boolean;

/**
* Set the global id data.
* @param {vtkDataArray} globalIds The global id data.
*/
setGlobalIds(globalIds: vtkDataArray): boolean;

/**
* Set the pedigree id data.
* @param {vtkDataArray} pedigreeids The pedigree id data.
*/
setPedigreeIds(pedigreeIds: vtkDataArray): boolean;

/**
*
*/
copyScalarsOn(): void;

/**
*
*/
copyVectorsOn(): void;

/**
*
*/
copyNormalsOn(): void;

/**
*
*/
copyTCoordsOn(): void;

/**
*
*/
copyTensorsOn(): void;

/**
*
*/
copyGlobalIdsOn(): void;

/**
*
*/
copyPedigreeIdsOn(): void;

/**
*
*/
copyScalarsOff(): void;

/**
*
*/
copyVectorsOff(): void;

/**
*
*/
copyNormalsOff(): void;

/**
*
*/
copyTCoordsOff(): void;

/**
*
*/
copyTensorsOff(): void;

/**
*
*/
copyGlobalIdsOff(): void;

/**
*
*/
copyPedigreeIdsOff(): void;

}

/**
* Method used to decorate a given object (publicAPI+model) with vtkDataSetAttributes characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {IDataSetAttributesInitialValues} [initialValues] (default: {})
*/
export function extend(publicAPI: object, model: object, initialValues?: IDataSetAttributesInitialValues): void;

/**
* Method used to create a new instance of vtkDataSetAttributes.
* @param {IDataSetAttributesInitialValues} [initialValues] for pre-setting some of its content
*/
export function newInstance(initialValues?: IDataSetAttributesInitialValues): vtkDataSetAttributes;

/**
* vtkDataSetAttributes is a class that is used to represent and manipulate
* attribute data (e.g., scalars, vectors, normals, texture coordinates,
* tensors, global ids, pedigree ids, and field data).
*
* This adds to vtkFieldData the ability to pick one of the arrays from the
* field as the currently active array for each attribute type. In other words,
* you pick one array to be called "THE" Scalars, and then filters down the
* pipeline will treat that array specially. For example vtkContourFilter will
* contour "THE" Scalar array unless a different array is asked for.
*
* Additionally vtkDataSetAttributes provides methods that filters call to pass
* data through, copy data into, and interpolate from Fields. PassData passes
* entire arrays from the source to the destination. Copy passes through some
* subset of the tuples from the source to the destination. Interpolate
* interpolates from the chosen tuple(s) in the source data, using the provided
* weights, to produce new tuples in the destination. Each attribute type has
* pass, copy and interpolate "copy" flags that can be set in the destination to
* choose which attribute arrays will be transferred from the source to the
* destination.
*
* Finally this class provides a mechanism to determine which attributes a group
* of sources have in common, and to copy tuples from a source into the
* destination, for only those attributes that are held by all.
*/
export declare const vtkDataSetAttributes: {
newInstance: typeof newInstance,
extend: typeof extend,
};
export default vtkDataSetAttributes;
index.js
import macro from 'vtk.js/Sources/macros';
import vtkFieldData from 'vtk.js/Sources/Common/DataModel/DataSetAttributes/FieldData';
import Constants from 'vtk.js/Sources/Common/DataModel/DataSetAttributes/Constants';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';

const { AttributeTypes, AttributeCopyOperations } = Constants;
const { vtkWarningMacro } = macro;

// ----------------------------------------------------------------------------
// vtkDataSetAttributes methods
// ----------------------------------------------------------------------------

function vtkDataSetAttributes(publicAPI, model) {
const attrTypes = [
'Scalars',
'Vectors',
'Normals',
'TCoords',
'Tensors',
'GlobalIds',
'PedigreeIds',
];

function cleanAttributeType(attType) {
// Given an integer or string, convert the result to one of the
// strings in the "attrTypes" array above or null (if
// no match is found)
let cleanAttType = attrTypes.find(
(ee) =>
AttributeTypes[ee.toUpperCase()] === attType ||
(typeof attType !== 'number' &&
ee.toLowerCase() === attType.toLowerCase())
);
if (typeof cleanAttType === 'undefined') {
cleanAttType = null;
}
return cleanAttType;
}

// Set our className
model.classHierarchy.push('vtkDataSetAttributes');

publicAPI.checkNumberOfComponents = (x) => true; // TODO

publicAPI.setAttribute = (arr, uncleanAttType) => {
const attType = cleanAttributeType(uncleanAttType);
if (
arr &&
attType.toUpperCase() === 'PEDIGREEIDS' &&
!arr.isA('vtkDataArray')
) {
vtkWarningMacro(
`Cannot set attribute ${attType}. The attribute must be a vtkDataArray.`
);
return -1;
}
if (arr && !publicAPI.checkNumberOfComponents(arr, attType)) {
vtkWarningMacro(
`Cannot set attribute ${attType}. Incorrect number of components.`
);
return -1;
}
let currentAttribute = model[`active${attType}`];
if (currentAttribute >= 0 && currentAttribute < model.arrays.length) {
if (model.arrays[currentAttribute] === arr) {
return currentAttribute;
}
publicAPI.removeArrayByIndex(currentAttribute);
}

if (arr) {
currentAttribute = publicAPI.addArray(arr);
model[`active${attType}`] = currentAttribute;
} else {
model[`active${attType}`] = -1;
}
publicAPI.modified();
return model[`active${attType}`];
};

publicAPI.getAttributes = (arr) =>
attrTypes.filter((attrType) => publicAPI[`get${attrType}`]() === arr);

publicAPI.setActiveAttributeByName = (arrayName, attType) =>
publicAPI.setActiveAttributeByIndex(
publicAPI.getArrayWithIndex(arrayName).index,
attType
);

publicAPI.setActiveAttributeByIndex = (arrayIdx, uncleanAttType) => {
const attType = cleanAttributeType(uncleanAttType);
if (arrayIdx >= 0 && arrayIdx < model.arrays.length) {
if (attType.toUpperCase() !== 'PEDIGREEIDS') {
const arr = publicAPI.getArrayByIndex(arrayIdx);
if (!arr.isA('vtkDataArray')) {
vtkWarningMacro(
`Cannot set attribute ${attType}. Only vtkDataArray subclasses can be set as active attributes.`
);
return -1;
}
if (!publicAPI.checkNumberOfComponents(arr, attType)) {
vtkWarningMacro(
`Cannot set attribute ${attType}. Incorrect number of components.`
);
return -1;
}
}
model[`active${attType}`] = arrayIdx;
publicAPI.modified();
return arrayIdx;
}

if (arrayIdx === -1) {
model[`active${attType}`] = arrayIdx;
publicAPI.modified();
}

return -1;
};

publicAPI.getActiveAttribute = (attType) => {
// Given an integer enum value or a string (with random capitalization),
// find the matching string in attrTypes.
const cleanAttType = cleanAttributeType(attType);
return publicAPI[`get${cleanAttType}`]();
};

// Override to allow proper handling of active attributes
publicAPI.removeAllArrays = () => {
model.arrays = [];
attrTypes.forEach((attType) => {
model[`active${attType}`] = -1;
});
};

// Override to allow proper handling of active attributes
publicAPI.removeArray = (arrayName) => {
model.arrays = model.arrays.filter((entry, idx) => {
if (arrayName === entry.data.getName()) {
// Found the array to remove, but is it an active attribute?
attrTypes.forEach((attType) => {
if (idx === model[`active${attType}`]) {
model[`active${attType}`] = -1;
}
});
return false;
}
return true;
});
};

// Override to allow proper handling of active attributes
publicAPI.removeArrayByIndex = (arrayIdx) => {
model.arrays = model.arrays.filter((entry, idx) => idx !== arrayIdx);
attrTypes.forEach((attType) => {
if (arrayIdx === model[`active${attType}`]) {
model[`active${attType}`] = -1;
}
});
};

attrTypes.forEach((value) => {
const activeVal = `active${value}`;
publicAPI[`get${value}`] = () =>
publicAPI.getArrayByIndex(model[activeVal]);
publicAPI[`set${value}`] = (da) => publicAPI.setAttribute(da, value);
publicAPI[`setActive${value}`] = (arrayName) =>
publicAPI.setActiveAttributeByIndex(
publicAPI.getArrayWithIndex(arrayName).index,
value
);
publicAPI[`copy${value}Off`] = () => {
const attType = value.toUpperCase();
model.copyAttributeFlags[AttributeCopyOperations.PASSDATA][
AttributeTypes[attType]
] = false;
};
publicAPI[`copy${value}On`] = () => {
const attType = value.toUpperCase();
model.copyAttributeFlags[AttributeCopyOperations.PASSDATA][
AttributeTypes[attType]
] = true;
};
});

publicAPI.initializeAttributeCopyFlags = () => {
// Default to copying all attributes in every circumstance:
model.copyAttributeFlags = [];
Object.keys(AttributeCopyOperations)
.filter((op) => op !== 'ALLCOPY')
.forEach((attCopyOp) => {
model.copyAttributeFlags[AttributeCopyOperations[attCopyOp]] =
Object.keys(AttributeTypes)
.filter((ty) => ty !== 'NUM_ATTRIBUTES')
.reduce((a, b) => {
a[AttributeTypes[b]] = true;
return a;
}, []);
});
// Override some operations where we don't want to copy:
model.copyAttributeFlags[AttributeCopyOperations.COPYTUPLE][
AttributeTypes.GLOBALIDS
] = false;
model.copyAttributeFlags[AttributeCopyOperations.INTERPOLATE][
AttributeTypes.GLOBALIDS
] = false;
model.copyAttributeFlags[AttributeCopyOperations.COPYTUPLE][
AttributeTypes.PEDIGREEIDS
] = false;
};

publicAPI.initialize = macro.chain(
publicAPI.initialize,
publicAPI.initializeAttributeCopyFlags
);

// Process dataArrays if any
if (model.dataArrays && Object.keys(model.dataArrays).length) {
Object.keys(model.dataArrays).forEach((name) => {
if (
!model.dataArrays[name].ref &&
model.dataArrays[name].type === 'vtkDataArray'
) {
publicAPI.addArray(vtkDataArray.newInstance(model.dataArrays[name]));
}
});
}

const superShallowCopy = publicAPI.shallowCopy;
publicAPI.shallowCopy = (other, debug) => {
superShallowCopy(other, debug);
model.arrays = other.getArrays().map((arr) => {
const arrNew = arr.newClone();
arrNew.shallowCopy(arr, debug);
return { data: arrNew };
});
};

publicAPI.initializeAttributeCopyFlags();
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
activeScalars: -1,
activeVectors: -1,
activeTensors: -1,
activeNormals: -1,
activeTCoords: -1,
activeGlobalIds: -1,
activePedigreeIds: -1,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);

// Object methods
vtkFieldData.extend(publicAPI, model, initialValues);
macro.setGet(publicAPI, model, [
'activeScalars',
'activeNormals',
'activeTCoords',
'activeVectors',
'activeTensors',
'activeGlobalIds',
'activePedigreeIds',
]);

if (!model.arrays) {
model.arrays = {};
}

// Object specific methods
vtkDataSetAttributes(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkDataSetAttributes');

// ----------------------------------------------------------------------------

export default { newInstance, extend, ...Constants };