/*========================================================================= Program: Visualization Toolkit Module: vtkCellLinks.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 vtkCellLinks * @brief object represents upward pointers from points to list of cells using each point * * vtkCellLinks is a supplemental object to vtkCellArray and vtkCellTypes, * enabling access from points to the cells using the points. vtkCellLinks is * a list of cell ids, each such link representing a dynamic list of cell ids * using the point. The information provided by this object can be used to * determine neighbors and construct other local topological information. * * @warning * vtkCellLinks supports incremental (i.e., "editable") operations such as * inserting a new cell, or deleting a point. Because of this, it is less * memory efficient, and slower to construct and delete than static classes * such as vtkStaticCellLinks or vtkStaticCellLinksTemplate. However these * other classes are typically meant for one-time (static) construction. * * @sa * vtkCellArray vtkCellTypes vtkStaticCellLinks vtkStaticCellLinksTemplate */ #ifndef vtkCellLinks_h #define vtkCellLinks_h #include "vtkAbstractCellLinks.h" #include "vtkCommonDataModelModule.h" // For export macro class vtkDataSet; class vtkCellArray; class VTKCOMMONDATAMODEL_EXPORT vtkCellLinks : public vtkAbstractCellLinks { public: class Link { public: vtkIdType ncells; vtkIdType* cells; }; ///@{ /** * Standard methods to instantiate, print, and obtain type information. */ static vtkCellLinks* New(); vtkTypeMacro(vtkCellLinks, vtkAbstractCellLinks); void PrintSelf(ostream& os, vtkIndent indent) override; ///@} /** * Build the link list array. All subclasses of vtkAbstractCellLinks * must support this method. */ void BuildLinks(vtkDataSet* data) override; /** * Allocate the specified number of links (i.e., number of points) that * will be built. */ void Allocate(vtkIdType numLinks, vtkIdType ext = 1000); /** * Clear out any previously allocated data structures */ void Initialize() override; /** * Get a link structure given a point id. */ Link& GetLink(vtkIdType ptId) { return this->Array[ptId]; } /** * Get the number of cells using the point specified by ptId. */ vtkIdType GetNcells(vtkIdType ptId) { return this->Array[ptId].ncells; } /** * Return a list of cell ids using the point. */ vtkIdType* GetCells(vtkIdType ptId) { return this->Array[ptId].cells; } ///@{ /** * Select all cells with a point degree in the range [minDegree,maxDegree). * The degree is the number of cells using a point. The selection is * indicated through the provided unsigned char array, with a non-zero * value indicates selection. The memory allocated for cellSelection must * be the maximum cell id referenced in the links. */ void SelectCells(vtkIdType minMaxDegree[2], unsigned char* cellSelection) override; ///@} /** * Insert a new point into the cell-links data structure. The size parameter * is the initial size of the list. */ vtkIdType InsertNextPoint(int numLinks); /** * Insert a cell id into the list of cells (at the end) using the cell id * provided. (Make sure to extend the link list (if necessary) using the * method ResizeCellList().) */ void InsertNextCellReference(vtkIdType ptId, vtkIdType cellId); /** * Delete point (and storage) by destroying links to using cells. */ void DeletePoint(vtkIdType ptId); /** * Delete the reference to the cell (cellId) from the point (ptId). This * removes the reference to the cellId from the cell list, but does not * resize the list (recover memory with ResizeCellList(), if necessary). */ void RemoveCellReference(vtkIdType cellId, vtkIdType ptId); /** * Add the reference to the cell (cellId) from the point (ptId). This * adds a reference to the cellId from the cell list, but does not resize * the list (extend memory with ResizeCellList(), if necessary). */ void AddCellReference(vtkIdType cellId, vtkIdType ptId); /** * Change the length of a point's link list (i.e., list of cells using a * point) by the size specified. */ void ResizeCellList(vtkIdType ptId, int size); /** * Reclaim any unused memory. */ void Squeeze() override; /** * Reset to a state of no entries without freeing the memory. */ void Reset() override; /** * Return the memory in kibibytes (1024 bytes) consumed by this cell links array. * Used to support streaming and reading/writing data. The value * returned is guaranteed to be greater than or equal to the memory * required to actually represent the data represented by this object. * The information returned is valid only after the pipeline has * been updated. */ unsigned long GetActualMemorySize() override; /** * Standard DeepCopy method. Since this object contains no reference * to other objects, there is no ShallowCopy. */ void DeepCopy(vtkAbstractCellLinks* src) override; protected: vtkCellLinks() : Array(nullptr) , Size(0) , MaxId(-1) , Extend(1000) , NumberOfPoints(0) , NumberOfCells(0) { } ~vtkCellLinks() override; /** * Increment the count of the number of cells using the point. */ void IncrementLinkCount(vtkIdType ptId) { this->Array[ptId].ncells++; } void AllocateLinks(vtkIdType n); /** * Insert a cell id into the list of cells using the point. */ void InsertCellReference(vtkIdType ptId, vtkIdType pos, vtkIdType cellId); Link* Array; // pointer to data vtkIdType Size; // allocated size of data vtkIdType MaxId; // maximum index inserted thus far vtkIdType Extend; // grow array by this point Link* Resize(vtkIdType sz); // function to resize data // Some information recorded at build time vtkIdType NumberOfPoints; vtkIdType NumberOfCells; private: vtkCellLinks(const vtkCellLinks&) = delete; void operator=(const vtkCellLinks&) = delete; }; //---------------------------------------------------------------------------- inline void vtkCellLinks::InsertCellReference(vtkIdType ptId, vtkIdType pos, vtkIdType cellId) { this->Array[ptId].cells[pos] = cellId; } //---------------------------------------------------------------------------- inline void vtkCellLinks::DeletePoint(vtkIdType ptId) { this->Array[ptId].ncells = 0; delete[] this->Array[ptId].cells; this->Array[ptId].cells = nullptr; } //---------------------------------------------------------------------------- inline void vtkCellLinks::InsertNextCellReference(vtkIdType ptId, vtkIdType cellId) { this->Array[ptId].cells[this->Array[ptId].ncells++] = cellId; } //---------------------------------------------------------------------------- inline void vtkCellLinks::RemoveCellReference(vtkIdType cellId, vtkIdType ptId) { vtkIdType* cells = this->Array[ptId].cells; vtkIdType ncells = this->Array[ptId].ncells; for (vtkIdType i = 0; i < ncells; i++) { if (cells[i] == cellId) { for (vtkIdType j = i; j < (ncells - 1); j++) { cells[j] = cells[j + 1]; } this->Array[ptId].ncells--; break; } } } //---------------------------------------------------------------------------- inline void vtkCellLinks::AddCellReference(vtkIdType cellId, vtkIdType ptId) { this->Array[ptId].cells[this->Array[ptId].ncells++] = cellId; } //---------------------------------------------------------------------------- inline void vtkCellLinks::ResizeCellList(vtkIdType ptId, int size) { vtkIdType newSize = this->Array[ptId].ncells + size; vtkIdType* cells = new vtkIdType[newSize]; memcpy(cells, this->Array[ptId].cells, static_cast(this->Array[ptId].ncells) * sizeof(vtkIdType)); delete[] this->Array[ptId].cells; this->Array[ptId].cells = cells; } #endif