1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
|
/*=========================================================================
Program: Visualization Toolkit
Module: vtkCellArrayIterator.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 vtkCellArrayIterator
* @brief Encapsulate traversal logic for vtkCellArray.
*
* This is iterator for thread-safe traversal of a vtkCellArray. It provides
* random access and forward iteration. Typical usage for forward iteration
* looks like:
*
* ```
* auto iter = vtk::TakeSmartPointer(cellArray->NewIterator());
* for (iter->GoToFirstCell(); !iter->IsDoneWithTraversal(); iter->GoToNextCell())
* {
* // do work with iter
* iter->GetCurrentCell(numCellPts, cellPts);
* }
* ```
*
* Typical usage for random access looks like:
*
* ```
* auto iter = vtk::TakeSmartPointer(cellArray->NewIterator());
* iter->GetCellAtId(cellId, numCellPts, cellPts);
* ```
*
* Here @a cellId is the id of the ith cell in the vtkCellArray;
* @a numCellPts is the number of points defining the cell represented
* as vtkIdType; and @a cellPts is a pointer to the point ids defined
* as vtkIdType const*&.
*
* Internally the iterator may copy data from the vtkCellArray, or reference
* the internal vtkCellArray storage. This depends on the relationship of
* vtkIdType to the type and structure of internal storage. If the type of
* storage is the same as vtkIdType, and the storage is a single-component
* AOS array (i.e., a 1D array), then shared access to the vtkCellArray
* storage is provided. Otherwise, the data from storage is copied into an
* internal iterator buffer. (Of course copying is slower and can result in
* 3-4x reduction in traversal performance. On the other hand, the
* vtkCellArray can use the appropriate storage to save memory, perform
* zero-copy, and/or efficiently represent the cell connectivity
* information.) Note that referencing internal vtkCellArray storage has
* implications on the validity of the iterator. If the underlying
* vtkCellArray storage changes while iterating, and the iterator is
* referencing this storage, unpredictable and catastrophic results are
* likely - hence do not modify the vtkCellArray while iterating.
*
* @sa
* vtkCellArray
*/
#ifndef vtkCellArrayIterator_h
#define vtkCellArrayIterator_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h"
#include "vtkCellArray.h" // Needed for inline methods
#include "vtkIdList.h" // Needed for inline methods
#include "vtkSmartPointer.h" // For vtkSmartPointer
#include <cassert> // for assert
#include <type_traits> // for std::enable_if
class VTKCOMMONDATAMODEL_EXPORT vtkCellArrayIterator : public vtkObject
{
public:
//@{
/**
* Standard methods for instantiation, type information, and printing.
*/
vtkTypeMacro(vtkCellArrayIterator, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent) override;
static vtkCellArrayIterator* New();
//@}
/**
* Return the vtkCellArray object over which iteration is occuring.
*/
vtkCellArray* GetCellArray() { return this->CellArray; }
/**
* Intialize the iterator to a specific cell. This will revalidate the
* iterator if the underlying vtkCellArray has been modified. This method
* can always be used to set the starting location for forward iteration,
* and it is also used to support random access.
*/
void GoToCell(vtkIdType cellId)
{
this->CurrentCellId = cellId;
this->NumberOfCells = this->CellArray->GetNumberOfCells();
assert(cellId <= this->NumberOfCells);
}
/**
* The following are methods supporting random access iteration.
*/
//@{
/**
* Initialize the iterator to a specific cell and return the cell. Note
* that methods passing vtkIdLists always copy data from the vtkCellArray
* storage buffer into the vtkIdList. Otherwise, a fastpath returning
* (numCellPts,cellPts) which may return a pointer to internal vtkCellArray
* storage is possible, if vtkIdType is the same as the vtkCellArray buffer
* (which is typical).
*/
void GetCellAtId(vtkIdType cellId, vtkIdType& numCellPts, vtkIdType const*& cellPts)
{
this->GoToCell(cellId);
this->GetCurrentCell(numCellPts, cellPts);
}
void GetCellAtId(vtkIdType cellId, vtkIdList* cellIds)
{
this->GoToCell(cellId);
this->GetCurrentCell(cellIds);
}
vtkIdList* GetCellAtId(vtkIdType cellId)
{
this->GoToCell(cellId);
return this->GetCurrentCell();
}
//@}
/**
* The following are methods supporting forward iteration.
*/
/**
* Initialize the iterator for forward iteration. This will revalidate the
* iterator if the underlying vtkCellArray has been modified.
*/
void GoToFirstCell()
{
this->CurrentCellId = 0;
this->NumberOfCells = this->CellArray->GetNumberOfCells();
}
/**
* Advance the forward iterator to the next cell.
*/
void GoToNextCell() { ++this->CurrentCellId; }
/**
* Returns true if the iterator has completed the traversal.
*/
bool IsDoneWithTraversal() { return this->CurrentCellId >= this->NumberOfCells; }
/**
* Returns the id of the current cell during forward iteration.
*/
vtkIdType GetCurrentCellId() const { return this->CurrentCellId; }
//@}
/**
* Returns the definition of the current cell during forward
* traversal. Note that methods passing vtkIdLists always copy data from
* the vtkCellArray storage buffer into the vtkIdList. Otherwise, a
* fastpath returning (numCellPts,cellPts) - which may return a pointer to
* internal vtkCellArray storage - is possible, if vtkIdType is the same as
* the vtkCellArray storage (which is typical).
*/
void GetCurrentCell(vtkIdType& cellSize, vtkIdType const*& cellPoints)
{
assert(this->CurrentCellId < this->NumberOfCells);
// Either refer to vtkCellArray storage buffer, or copy into local buffer
if (this->CellArray->IsStorageShareable())
{
this->CellArray->GetCellAtId(this->CurrentCellId, cellSize, cellPoints);
}
else // or copy into local iterator buffer.
{
this->CellArray->GetCellAtId(this->CurrentCellId, this->TempCell);
cellSize = this->TempCell->GetNumberOfIds();
cellPoints = this->TempCell->GetPointer(0);
}
}
void GetCurrentCell(vtkIdList* ids)
{
assert(this->CurrentCellId < this->NumberOfCells);
this->CellArray->GetCellAtId(this->CurrentCellId, ids);
}
vtkIdList* GetCurrentCell()
{
assert(this->CurrentCellId < this->NumberOfCells);
this->CellArray->GetCellAtId(this->CurrentCellId, this->TempCell);
return this->TempCell;
}
//@}
/**
* Specialized methods for performing operations on the vtkCellArray.
*/
/**
* Replace the current cell with the ids in `list`. Note that this method
* CANNOT change the number of points in the cell, it can only redefine the
* ids (e.g. `list` must contain the same number of entries as the current
* cell's points).
*/
void ReplaceCurrentCell(vtkIdList* list)
{
assert(this->CurrentCellId < this->NumberOfCells);
this->CellArray->ReplaceCellAtId(this->CurrentCellId, list);
}
/**
* Replace the current cell with the ids in `pts`. Note that this method
* CANNOT change the number of points in the cell, it can only redefine the
* ids (e.g. `npts` must equal the current cell's number of points).
*/
void ReplaceCurrentCell(vtkIdType npts, const vtkIdType* pts)
{
assert(this->CurrentCellId < this->NumberOfCells);
this->CellArray->ReplaceCellAtId(this->CurrentCellId, npts, pts);
}
/**
* Reverses the order of the point ids in the current cell.
*/
void ReverseCurrentCell()
{
assert(this->CurrentCellId < this->NumberOfCells);
this->CellArray->ReverseCellAtId(this->CurrentCellId);
}
friend class vtkCellArray;
protected:
vtkCellArrayIterator() = default;
~vtkCellArrayIterator() override = default;
vtkSetMacro(CellArray, vtkCellArray*);
vtkSmartPointer<vtkCellArray> CellArray;
vtkNew<vtkIdList> TempCell;
vtkIdType CurrentCellId;
vtkIdType NumberOfCells;
private:
vtkCellArrayIterator(const vtkCellArrayIterator&) = delete;
void operator=(const vtkCellArrayIterator&) = delete;
};
#endif // vtkCellArrayIterator_h
|