// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause /** * @class vtkUnstructuredGrid * @brief dataset represents arbitrary combinations of * all possible cell types * * vtkUnstructuredGrid is a data object that is a concrete implementation of * vtkDataSet. vtkUnstructuredGrid represents any combinations of any cell * types. This includes 0D (e.g., points), 1D (e.g., lines, polylines), 2D * (e.g., triangles, polygons), and 3D (e.g., hexahedron, tetrahedron, * polyhedron, etc.). vtkUnstructuredGrid provides random access to cells, as * well as topological information (such as lists of cells using each point). */ #ifndef vtkUnstructuredGrid_h #define vtkUnstructuredGrid_h #include "vtkAbstractCellLinks.h" // For vtkAbstractCellLinks #include "vtkCellArray.h" // inline GetCellPoints() #include "vtkCommonDataModelModule.h" // For export macro #include "vtkIdTypeArray.h" // inline GetCellPoints() #include "vtkUnstructuredGridBase.h" #include "vtkWrappingHints.h" // For VTK_MARSHALMANUAL #include "vtkSmartPointer.h" // for smart pointer VTK_ABI_NAMESPACE_BEGIN class vtkCellArray; class vtkIdList; class vtkIdTypeArray; class vtkUnsignedCharArray; class vtkIdTypeArray; class VTKCOMMONDATAMODEL_EXPORT VTK_MARSHALMANUAL vtkUnstructuredGrid : public vtkUnstructuredGridBase { public: /** * Standard instantiation method. */ static vtkUnstructuredGrid* New(); static vtkUnstructuredGrid* ExtendedNew(); ///@{ /** * Standard methods for type information and printing. */ vtkTypeMacro(vtkUnstructuredGrid, vtkUnstructuredGridBase); void PrintSelf(ostream& os, vtkIndent indent) override; ///@} /** * Standard vtkDataSet API methods. See vtkDataSet for more information. */ int GetDataObjectType() override { return VTK_UNSTRUCTURED_GRID; } /** * @brief Pre-allocate memory in internal data structures. Does not change * the number of cells, only the array capacities. Existing data is NOT * preserved. * @param numCells The number of expected cells in the dataset. * @param maxCellSize The number of points per cell to allocate memory for. * @return True if allocation succeeds. * @sa Squeeze(); */ bool AllocateEstimate(vtkIdType numCells, vtkIdType maxCellSize) { return this->AllocateExact(numCells, numCells * maxCellSize); } /** * @brief Pre-allocate memory in internal data structures. Does not change * the number of cells, only the array capacities. Existing data is NOT * preserved. * @param numCells The number of expected cells in the dataset. * @param connectivitySize The total number of pointIds stored for all cells. * @return True if allocation succeeds. * @sa Squeeze(); */ bool AllocateExact(vtkIdType numCells, vtkIdType connectivitySize); /** * Method allocates initial storage for the cell connectivity. Use this * method before the method InsertNextCell(). The array capacity is * doubled when the inserting a cell exceeds the current capacity. * extSize is no longer used. * * @note Prefer AllocateExact or AllocateEstimate, which give more control * over how allocations are distributed. */ void Allocate(vtkIdType numCells = 1000, int vtkNotUsed(extSize) = 1000) override { this->AllocateExact(numCells, numCells); } ///@{ /** * Standard vtkDataSet methods; see vtkDataSet.h for documentation. */ void Reset(); void CopyStructure(vtkDataSet* ds) override; vtkIdType GetNumberOfCells() override; using vtkDataSet::GetCell; vtkCell* GetCell(vtkIdType cellId) override; void GetCell(vtkIdType cellId, vtkGenericCell* cell) override; void GetCellBounds(vtkIdType cellId, double bounds[6]) override; void GetCellPoints(vtkIdType cellId, vtkIdList* ptIds) override; void GetPointCells(vtkIdType ptId, vtkIdList* cellIds) override; vtkCellIterator* NewCellIterator() override; ///@} /** * Get the type of the cell with the given cellId. */ int GetCellType(vtkIdType cellId) override; /** * Get the size of the cell with given cellId. */ vtkIdType GetCellSize(vtkIdType cellId) override; /** * Get a list of types of cells in a dataset. The list consists of an array * of types (not necessarily in any order), with a single entry per type. * For example a dataset with 5 triangles, 3 lines, and 100 hexahedra would * result in a list of three entries, corresponding to the types VTK_TRIANGLE, * VTK_LINE, and VTK_HEXAHEDRON. This override implements an optimization that * recomputes cell types only when the types of cells may have changed. * * THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND * THE DATASET IS NOT MODIFIED */ void GetCellTypes(vtkCellTypes* types) override; /** * Get a list of types of cells in a dataset. The list consists of an array * of types (not necessarily in any order), with a single entry per type. * For example a dataset with 5 triangles, 3 lines, and 100 hexahedra would * result in a list of three entries, corresponding to the types VTK_TRIANGLE, * VTK_LINE, and VTK_HEXAHEDRON. This override implements an optimization that * recomputes cell types only when the types of cells may have changed. * This method never returns `nullptr`. * * THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND * THE DATASET IS NOT MODIFIED */ vtkUnsignedCharArray* GetDistinctCellTypesArray(); /** * A higher-performing variant of the virtual vtkDataSet::GetCellPoints() * for unstructured grids. Given a cellId, return the number of defining * points and the list of points defining the cell. * * @warning Subsequent calls to this method may invalidate previous call * results. * * The @a pts pointer must not be modified. * * Note: This method MAY NOT be thread-safe. (See GetCellAtId at vtkCellArray) */ void GetCellPoints(vtkIdType cellId, vtkIdType& npts, vtkIdType const*& pts) { this->Connectivity->GetCellAtId(cellId, npts, pts); } /** * A higher-performing variant of the virtual vtkDataSet::GetCellPoints() * for unstructured grids. Given a cellId, return the number of defining * points and the list of points defining the cell. * * This function MAY use ptIds, which is an object that is created by each thread, * to guarantee thread safety. * * @warning Subsequent calls to this method may invalidate previous call * results. * * The @a pts pointer must not be modified. * * Note: This method is thread-safe. */ void GetCellPoints( vtkIdType cellId, vtkIdType& npts, vtkIdType const*& pts, vtkIdList* ptIds) override { this->Connectivity->GetCellAtId(cellId, npts, pts, ptIds); } ///@{ /** * Special (efficient) operation to return the list of cells using the * specified point ptId. Use carefully (i.e., make sure that BuildLinks() * has been called). */ void GetPointCells(vtkIdType ptId, vtkIdType& ncells, vtkIdType*& cells) VTK_SIZEHINT(cells, ncells); ///@} /** * Get the array of all cell types in the grid. Each single-component * tuple in the array at an index that corresponds to the type of the cell * with the same index. To get an array of only the distinct cell types in * the dataset, use GetCellTypes(). */ vtkUnsignedCharArray* GetCellTypesArray(); /** * Squeeze all arrays in the grid to conserve memory. */ void Squeeze() override; /** * Reset the grid to an empty state and free any memory. */ void Initialize() override; /** * Get the size, in number of points, of the largest cell. */ int GetMaxCellSize() override; /** * Get the maximum spatial dimensionality of the data * which is the maximum dimension of all cells. */ int GetMaxSpatialDimension() override; /** * Build topological links from points to lists of cells that use each point. * See vtkAbstractCellLinks for more information. */ void BuildLinks(); ///@{ /** * Set/Get the links that you created possibly without using BuildLinks. */ vtkSetSmartPointerMacro(Links, vtkAbstractCellLinks); vtkGetSmartPointerMacro(Links, vtkAbstractCellLinks); ///@} /** * Get the cell links. The cell links will be one of nullptr=0; * vtkCellLinks=1; vtkStaticCellLinksTemplate=2; * vtkStaticCellLinksTemplate=3; * vtkStaticCellLinksTemplate=4. (See enum types defined in * vtkAbstractCellLinks.) */ VTK_DEPRECATED_IN_9_3_0("Use GetLinks() instead.") vtkAbstractCellLinks* GetCellLinks(); /** * Get the face stream of a polyhedron cell in the following format: * (numCellFaces, numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...). * If the requested cell is not a polyhedron, then the standard GetCellPoints * is called to return a list of unique point ids (id1, id2, id3, ...). * This function is threadsafe. */ void GetFaceStream(vtkIdType cellId, vtkIdList* ptIds); /** * Get the number of faces and the face stream of a polyhedral cell. * The output \a ptIds has the following format: * (numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...). * If the requested cell is not a polyhedron, then the standard GetCellPoints * is called to return the number of points and a list of unique point ids * (id1, id2, id3, ...). * This function is NOT THREADSAFE. */ VTK_DEPRECATED_IN_9_4_0("Use the threadsafe GetFaceStream or GetPolyhedronFaces.") void GetFaceStream(vtkIdType cellId, vtkIdType& nfaces, vtkIdType const*& ptIds); ///@{ /** * Provide cell information to define the dataset. * * Cells like vtkPolyhedron require points plus a list of faces. To handle * vtkPolyhedron, use SetPolyhedralCells() * SetPolyhedralCells requires a faces vtkCellArray that will describe * the faces use by the polyhedral cells. * SetPolyhedralCells also requires a faceLocations vtkCellArray to fully describe a polyhedron * cell The faceLocations is a collection of face ids pointing to the faces vtkCellArray. */ void SetCells(int type, vtkCellArray* cells); void SetCells(int* types, vtkCellArray* cells); void SetCells(vtkUnsignedCharArray* cellTypes, vtkCellArray* cells); void SetPolyhedralCells(vtkUnsignedCharArray* cellTypes, vtkCellArray* cells, vtkCellArray* faceLocations, vtkCellArray* faces); VTK_DEPRECATED_IN_9_4_0("This function is deprecated, use SetPolyhedralCells") void SetCells(vtkUnsignedCharArray* cellTypes, vtkCellArray* cells, vtkIdTypeArray* faceLocations, vtkIdTypeArray* faces); ///@} /** * Return the unstructured grid connectivity array. */ vtkCellArray* GetCells() { return this->Connectivity; } ///@{ /** * A topological inquiry to retrieve all of the cells using list of points * exclusive of the current cell specified (e.g., cellId). THIS METHOD IS * THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND THE DATASET IS NOT * MODIFIED. */ void GetCellNeighbors(vtkIdType cellId, vtkIdList* ptIds, vtkIdList* cellIds) override { this->GetCellNeighbors(cellId, ptIds->GetNumberOfIds(), ptIds->GetPointer(0), cellIds); } void GetCellNeighbors( vtkIdType cellId, vtkIdType npts, const vtkIdType* ptIds, vtkIdList* cellIds); ///@} ///@{ /** * A topological inquiry to determine whether a topological entity (e.g., * point, edge, or face) defined by the point ids (ptIds of length npts) is * a boundary entity of a specified cell (indicated by cellId). A boundary * entity is a topological feature used by exactly one cell. This method is * related to GetCellNeighbors() except that it simply indicates whether a * topological feature is boundary - hence the method is faster. * THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A * SINGLE THREAD AND THE DATASET IS NOT MODIFIED. */ bool IsCellBoundary( vtkIdType cellId, vtkIdType npts, const vtkIdType* ptIds, vtkIdType& neighborCellId); bool IsCellBoundary(vtkIdType cellId, vtkIdType npts, const vtkIdType* ptIds) { vtkIdType neighborCellId; return this->IsCellBoundary(cellId, npts, ptIds, neighborCellId); } VTK_DEPRECATED_IN_9_3_0("Use the overload that doesn't take a vtkIdList instead.") bool IsCellBoundary( vtkIdType cellId, vtkIdType npts, const vtkIdType* ptIds, vtkIdList* vtkNotUsed(cellIds)) { return this->IsCellBoundary(cellId, npts, ptIds); } ///@} ///@{ /** * Use these methods only if the dataset has been specified as * Editable. See vtkPointSet for more information. */ vtkIdType InsertNextLinkedCell(int type, int npts, const vtkIdType pts[]) VTK_SIZEHINT(pts, npts); void RemoveReferenceToCell(vtkIdType ptId, vtkIdType cellId); void AddReferenceToCell(vtkIdType ptId, vtkIdType cellId); void ResizeCellList(vtkIdType ptId, int size); ///@} ///@{ /** * Set / Get the piece and the number of pieces. Similar to extent in 3D. */ virtual int GetPiece(); virtual int GetNumberOfPieces(); ///@} /** * Get the ghost level. */ virtual int GetGhostLevel(); /** * Return the actual size of the data in kibibytes (1024 bytes). This number * is valid only after the pipeline has updated. The memory size * returned is guaranteed to be greater than or equal to the * memory required to represent the data (e.g., extra space in * arrays, etc. are not included in the return value). THIS METHOD * IS THREAD SAFE. */ unsigned long GetActualMemorySize() override; ///@{ /** * Shallow and Deep copy. */ void ShallowCopy(vtkDataObject* src) override; void DeepCopy(vtkDataObject* src) override; ///@} /** * Fill vtkIdTypeArray container with list of cell Ids. This * method traverses all cells and, for a particular cell type, * inserts the cell Id into the container. */ void GetIdsOfCellsOfType(int type, vtkIdTypeArray* array) override; /** * Returns whether cells are all of the same type. */ int IsHomogeneous() override; /** * This method will remove any cell that is marked as ghost * (has the vtkDataSetAttributes::DUPLICATECELL or * the vtkDataSetAttributes::HIDDENCELL bit set). */ void RemoveGhostCells(); ///@{ /** * Retrieve an instance of this class from an information object. */ static vtkUnstructuredGrid* GetData(vtkInformation* info); static vtkUnstructuredGrid* GetData(vtkInformationVector* v, int i = 0); ///@} /** * Special support for polyhedron. Return nullptr for all other cell types. */ VTK_DEPRECATED_IN_9_4_0("Use GetPolyhedronFaces instead.") vtkIdType* GetFaces(vtkIdType cellId); /** * Special support for polyhedron. Do not handle all other cell types. */ void GetPolyhedronFaces(vtkIdType cellId, vtkCellArray* faces); ///@{ /** * Get pointer to faces and facelocations. Support for polyhedron cells. * Use an internal cache to handle legacy layout */ VTK_DEPRECATED_IN_9_4_0("Use GetPolyhedronFaces instead.") vtkIdTypeArray* GetFaces(); VTK_DEPRECATED_IN_9_4_0("Use GetPolyhedronFaceLocations instead.") vtkIdTypeArray* GetFaceLocations(); /** * Get pointer to faces and facelocations for polyhedron cells. * This is a direct access to internal vtkCellArray structures without any copy. */ vtkCellArray* GetPolyhedronFaces(); vtkCellArray* GetPolyhedronFaceLocations(); ///@} /** * Special function used by vtkUnstructuredGridReader. * By default vtkUnstructuredGrid does not contain face information, which is * only used by polyhedron cells. If so far no polyhedron cells have been * added, Faces and FaceLocations pointers will be nullptr. In this case, need to * initialize the arrays and assign values to the previous non-polyhedron cells. */ int InitializeFacesRepresentation(vtkIdType numPrevCells); /** * Return the mesh (geometry/topology) modification time. * This time is different from the usual MTime which also takes into * account the modification of data arrays. This function can be used to * track the changes on the mesh separately from the data arrays * (eg. static mesh over time with transient data). */ vtkMTimeType GetMeshMTime() override; /** * A static method for converting a polyhedron vtkCellArray of format * [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] * into three components: (1) an integer indicating the number of faces * (2) a standard vtkCellArray storing point ids [nCell0Pts, i, j, k] * and (3) an vtkIdTypeArray storing face connectivity in format * [nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] * Note: input is assumed to contain only one polyhedron cell. * Outputs (2) and (3) will be stacked at the end of the input * cellArray and faces. The original data in the input will not * be touched. */ static void DecomposeAPolyhedronCell(vtkCellArray* polyhedronCellArray, vtkIdType& nCellpts, vtkIdType& nCellfaces, vtkCellArray* cellArray, vtkIdTypeArray* faces); static void DecomposeAPolyhedronCell(const vtkIdType* polyhedronCellStream, vtkIdType& nCellpts, vtkIdType& nCellfaces, vtkCellArray* cellArray, vtkIdTypeArray* faces); /** * A static method for converting an input polyhedron cell stream of format * [nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] * into three components: (1) an integer indicating the number of faces * (2) a standard vtkCellArray storing point ids [nCell0Pts, i, j, k] * and (3) an vtkIdTypeArray storing face connectivity in format * [nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] * Note: input is assumed to contain only one polyhedron cell. * Outputs (2) and (3) will be stacked at the end of the input * cellArray and faces. The original data in the input will not * be touched. */ static void DecomposeAPolyhedronCell(vtkIdType nCellFaces, const vtkIdType* inFaceStream, vtkIdType& nCellpts, vtkCellArray* cellArray, vtkIdTypeArray* faces); /** * Convert pid in a face stream into idMap[pid]. The face stream is of format * [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...]. The user is * responsible to make sure all the Ids in faceStream do not exceed the * range of idMap. */ static void ConvertFaceStreamPointIds(vtkIdList* faceStream, vtkIdType* idMap); /** * Convert pid in a face stream into idMap[pid]. The face stream is of format * [nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...]. The user is responsible to * make sure all the Ids in faceStream do not exceed the range of idMap. */ static void ConvertFaceStreamPointIds(vtkIdType nfaces, vtkIdType* faceStream, vtkIdType* idMap); /** * Convert pid in a face stream into idMap[pid]. The face stream is of format * vtkCellArray. The user is responsible to make sure all the Ids * in faceStream do not exceed the range of idMap. */ static void ConvertFaceStreamPointIds(vtkCellArray* faces, vtkIdType* idMap); //====================== Begin Legacy Methods ================================ /** * Get the array of all the starting indices of cell definitions * in the cell array. * * @warning vtkCellArray supports random access now. This array is no * longer used. */ vtkIdTypeArray* GetCellLocationsArray(); ///@{ /** * Special methods specific to vtkUnstructuredGrid for defining the cells * composing the dataset. Most cells require just arrays of cellTypes, * cellLocations and cellConnectivities which implicitly define the set of * points in each cell and their ordering. In those cases the * cellConnectivities are of the format * (numFace0Pts, id1, id2, id3, numFace1Pts, id1, id2, id3...). However, some * cells like vtkPolyhedron require points plus a list of faces. To handle * vtkPolyhedron, SetCells() support a special input cellConnectivities format * (numCellFaces, numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...) * The functions use vtkPolyhedron::DecomposeAPolyhedronCell() to convert * polyhedron cells into standard format. * * @warning The cellLocations array is no longer used; this information * is stored in vtkCellArray. Use the other SetCells overloads. */ void SetCells( vtkUnsignedCharArray* cellTypes, vtkIdTypeArray* cellLocations, vtkCellArray* cells); void SetCells(vtkUnsignedCharArray* cellTypes, vtkIdTypeArray* cellLocations, vtkCellArray* cells, vtkIdTypeArray* faceLocations, vtkIdTypeArray* faces); ///@} //====================== End Legacy Methods ================================== protected: vtkUnstructuredGrid(); ~vtkUnstructuredGrid() override; void ReportReferences(vtkGarbageCollector*) override; // Points derived from vtkPointSet. // Attribute data (i.e., point and cell data (i.e., scalars, vectors, normals, tcoords) // derived from vtkDataSet. // The heart of the data representation. The points are managed by the // superclass vtkPointSet. A cell is defined by its connectivity (i.e., the // point ids that define the cell) and the cell type, represented by the // Connectivity and Types arrays. // Finally, when certain topological information is needed (e.g., // all the cells that use a point), the cell links array is built. vtkSmartPointer Connectivity; vtkSmartPointer Links; vtkSmartPointer Types; // Set of all cell types present in the grid. All entries are unique. vtkSmartPointer DistinctCellTypes; // The DistinctCellTypes is cached, so we keep track of the last time it was // updated so we can compare it to the modified time of the Types array. vtkMTimeType DistinctCellTypesUpdateMTime; /** * Special support for polyhedra/cells with explicit face representations. * The Faces class represents polygonal faces using a vtkCellArray structure. * The FaceLocations store a polyhedron as a list of faces defined in Faces using a vtkCellArray * structure. */ vtkSmartPointer Faces; vtkSmartPointer FaceLocations; // Legacy support -- stores the old-style cell array locations. vtkSmartPointer CellLocations; vtkIdType InternalInsertNextCell(int type, vtkIdType npts, const vtkIdType ptIds[]) override; vtkIdType InternalInsertNextCell(int type, vtkIdList* ptIds) override; vtkIdType InternalInsertNextCell( int type, vtkIdType npts, const vtkIdType ptIds[], vtkIdType nfaces, const vtkIdType faces[]); vtkIdType InternalInsertNextCell( int type, vtkIdType npts, const vtkIdType pts[], vtkCellArray* faces) override; void InternalReplaceCell(vtkIdType cellId, int npts, const vtkIdType pts[]) override; /** * Legacy support -- stores the old-style Faces && FaceLocations * Special support for polyhedra/cells with explicit face representations. * * The Faces class represents polygonal faces using a modified vtkCellArray * structure. Each cell face list begins with the total number of faces in * the cell, followed by a vtkCellArray data organization * (n,i,j,k,n,i,j,k,...). * * @warning The Faces and FaceLocations arrays are no longer used; this information * is stored in vtkCellArrays ElementFaces and ElementFaceLocations. Use SetPolyhedralCells. */ vtkSmartPointer LegacyFaces; vtkSmartPointer LegacyFaceLocations; /** * Legacy backward compatibility for GetFaceStream * This member should be removed simultaneously with the deprecated GetFaceStream */ VTK_DEPRECATED_IN_9_4_0("This member is deprecated.") vtkSmartPointer LegacyPointIdsBuffer; /** * A static method for converting an input polyhedron cell stream of format * [nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] * into three components: (1) an integer indicating the number of faces * (2) a standard vtkCellArray storing point ids [nCell0Pts, i, j, k] * and (3) an vtkIdTypeArray storing face connectivity in format * [nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] * Note: input is assumed to contain only one polyhedron cell. * Outputs (2) and (3) will be stacked at the end of the input * cellArray and faces. The original data in the input will not * be touched. */ static void DecomposeAPolyhedronCell(const vtkIdType* cellStream, vtkIdType& numCellPts, vtkIdType& nCellFaces, vtkCellArray* cellArray, vtkCellArray* faces); static void DecomposeAPolyhedronCell(vtkIdType nCellFaces, const vtkIdType* cellStream, vtkIdType& numCellPts, vtkCellArray* cellArray, vtkCellArray* facesArray); static void DecomposeAPolyhedronCell(vtkCellArray* polyhedronCell, vtkIdType& numCellPts, vtkIdType& nCellfaces, vtkCellArray* cellArray, vtkCellArray* faces); static void DecomposeAPolyhedronCell(const vtkIdType* cellStream, vtkIdType& numCellPts, vtkIdType& nCellFaces, vtkCellArray* cellArray, vtkCellArray* faces, vtkCellArray* faceLocations); static void DecomposeAPolyhedronCell(vtkIdType nCellFaces, const vtkIdType* cellStream, vtkIdType& numCellPts, vtkCellArray* cellArray, vtkCellArray* faces, vtkCellArray* faceLocations); /** * Backward compatibility function to convert new polyhedron storage to legacy */ static int CopyPolyhedronToFaceStream(vtkCellArray* faceArray, vtkCellArray* faceLocationArray, vtkIdTypeArray* faceStream, vtkIdTypeArray* faceLocation); private: // Hide these from the user and the compiler. vtkUnstructuredGrid(const vtkUnstructuredGrid&) = delete; void operator=(const vtkUnstructuredGrid&) = delete; void Cleanup(); }; VTK_ABI_NAMESPACE_END #endif