/*========================================================================= Program: Visualization Toolkit Module: vtkMergeFields.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkMergeFields * @brief Merge multiple fields into one. * * vtkMergeFields is used to merge multiple field into one. * The new field is put in the same field data as the original field. * For example * @verbatim * mf->SetOutputField("foo", vtkMergeFields::POINT_DATA); * mf->SetNumberOfComponents(2); * mf->Merge(0, "array1", 1); * mf->Merge(1, "array2", 0); * @endverbatim * will tell vtkMergeFields to use the 2nd component of array1 and * the 1st component of array2 to create a 2 component field called foo. * * @sa * vtkFieldData vtkDataSet vtkDataObjectToDataSetFilter * vtkDataSetAttributes vtkDataArray vtkRearrangeFields * vtkSplitField vtkAssignAttribute */ #ifndef vtkMergeFields_h #define vtkMergeFields_h #include "vtkDataSetAlgorithm.h" #include "vtkFiltersCoreModule.h" // For export macro class vtkDataArray; class vtkFieldData; class VTKFILTERSCORE_EXPORT vtkMergeFields : public vtkDataSetAlgorithm { public: vtkTypeMacro(vtkMergeFields, vtkDataSetAlgorithm); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Create a new vtkMergeFields. */ static vtkMergeFields* New(); /** * The output field will have the given name and it will be in * fieldLoc (the input fields also have to be in fieldLoc). */ void SetOutputField(const char* name, int fieldLoc); /** * Helper method used by the other language bindings. Allows the caller to * specify arguments as strings instead of enums.Returns an operation id * which can later be used to remove the operation. */ void SetOutputField(const char* name, const char* fieldLoc); /** * Add a component (arrayName,sourceComp) to the output field. */ void Merge(int component, const char* arrayName, int sourceComp); //@{ /** * Set the number of the components in the output field. * This has to be set before execution. Default value is 0. */ vtkSetMacro(NumberOfComponents, int); vtkGetMacro(NumberOfComponents, int); //@} enum FieldLocations { DATA_OBJECT = 0, POINT_DATA = 1, CELL_DATA = 2 }; struct Component { int Index; int SourceIndex; char* FieldName; Component* Next; // linked list void SetName(const char* name) { delete[] this->FieldName; this->FieldName = nullptr; if (name) { size_t len = strlen(name) + 1; this->FieldName = new char[len]; #ifdef _MSC_VER strncpy_s(this->FieldName, len, name, len - 1); #else strncpy(this->FieldName, name, len); #endif } } Component() { FieldName = nullptr; } ~Component() { delete[] FieldName; } }; protected: enum FieldType { NAME, ATTRIBUTE }; vtkMergeFields(); ~vtkMergeFields() override; int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; char* FieldName; int FieldLocation; int NumberOfComponents; int OutputDataType; static char FieldLocationNames[3][12]; int MergeArray(vtkDataArray* in, vtkDataArray* out, int inComp, int outComp); // Components are stored as a linked list. Component* Head; Component* Tail; // Methods to browse/modify the linked list. Component* GetNextComponent(Component* op) { return op->Next; } Component* GetFirst() { return this->Head; } void AddComponent(Component* op); Component* FindComponent(int index); void DeleteAllComponents(); void PrintComponent(Component* op, ostream& os, vtkIndent indent); void PrintAllComponents(ostream& os, vtkIndent indent); private: vtkMergeFields(const vtkMergeFields&) = delete; void operator=(const vtkMergeFields&) = delete; }; #endif