VTK  9.3.1
vtkCellArray.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
129 #ifndef vtkCellArray_h
130 #define vtkCellArray_h
131 
132 #include "vtkCommonDataModelModule.h" // For export macro
133 #include "vtkObject.h"
134 
135 #include "vtkAOSDataArrayTemplate.h" // Needed for inline methods
136 #include "vtkCell.h" // Needed for inline methods
137 #include "vtkDataArrayRange.h" // Needed for inline methods
138 #include "vtkFeatures.h" // for VTK_USE_MEMKIND
139 #include "vtkSmartPointer.h" // For vtkSmartPointer
140 #include "vtkTypeInt32Array.h" // Needed for inline methods
141 #include "vtkTypeInt64Array.h" // Needed for inline methods
142 #include "vtkTypeList.h" // Needed for ArrayList definition
143 
144 #include <cassert> // for assert
145 #include <initializer_list> // for API
146 #include <type_traits> // for std::is_same
147 #include <utility> // for std::forward
148 
169 #define VTK_CELL_ARRAY_V2
170 
171 VTK_ABI_NAMESPACE_BEGIN
173 class vtkIdTypeArray;
174 
175 class VTKCOMMONDATAMODEL_EXPORT vtkCellArray : public vtkObject
176 {
177 public:
178  using ArrayType32 = vtkTypeInt32Array;
179  using ArrayType64 = vtkTypeInt64Array;
180 
182 
186  static vtkCellArray* New();
187  vtkTypeMacro(vtkCellArray, vtkObject);
188  void PrintSelf(ostream& os, vtkIndent indent) override;
189  void PrintDebug(ostream& os);
191 
201 
210  using InputArrayList =
213 
222  vtkTypeBool Allocate(vtkIdType sz, vtkIdType vtkNotUsed(ext) = 1000)
223  {
224  return this->AllocateExact(sz, sz) ? 1 : 0;
225  }
226 
236  bool AllocateEstimate(vtkIdType numCells, vtkIdType maxCellSize)
237  {
238  return this->AllocateExact(numCells, numCells * maxCellSize);
239  }
240 
250  bool AllocateExact(vtkIdType numCells, vtkIdType connectivitySize);
251 
262  {
263  return this->AllocateExact(other->GetNumberOfCells(), other->GetNumberOfConnectivityIds());
264  }
265 
275  bool ResizeExact(vtkIdType numCells, vtkIdType connectivitySize);
276 
280  void Initialize();
281 
285  void Reset();
286 
292  void Squeeze();
293 
304  bool IsValid();
305 
310  {
311  if (this->Storage.Is64Bit())
312  {
313  return this->Storage.GetArrays64().Offsets->GetNumberOfValues() - 1;
314  }
315  else
316  {
317  return this->Storage.GetArrays32().Offsets->GetNumberOfValues() - 1;
318  }
319  }
320 
326  {
327  if (this->Storage.Is64Bit())
328  {
329  return this->Storage.GetArrays64().Offsets->GetNumberOfValues();
330  }
331  else
332  {
333  return this->Storage.GetArrays32().Offsets->GetNumberOfValues();
334  }
335  }
336 
341  {
342  if (this->Storage.Is64Bit())
343  {
344  return this->Storage.GetArrays64().Offsets->GetValue(cellId);
345  }
346  else
347  {
348  return this->Storage.GetArrays32().Offsets->GetValue(cellId);
349  }
350  }
351 
359  {
360  if (this->Storage.Is64Bit())
361  {
362  return this->Storage.GetArrays64().Connectivity->GetNumberOfValues();
363  }
364  else
365  {
366  return this->Storage.GetArrays32().Connectivity->GetNumberOfValues();
367  }
368  }
369 
375  VTK_NEWINSTANCE vtkCellArrayIterator* NewIterator();
376 
387  void SetData(vtkIdTypeArray* offsets, vtkIdTypeArray* connectivity);
388  void SetData(vtkAOSDataArrayTemplate<int>* offsets, vtkAOSDataArrayTemplate<int>* connectivity);
389  void SetData(vtkAOSDataArrayTemplate<long>* offsets, vtkAOSDataArrayTemplate<long>* connectivity);
390  void SetData(
392  void SetData(vtkTypeInt32Array* offsets, vtkTypeInt32Array* connectivity);
393  void SetData(vtkTypeInt64Array* offsets, vtkTypeInt64Array* connectivity);
408  bool SetData(vtkDataArray* offsets, vtkDataArray* connectivity);
409 
423  bool SetData(vtkIdType cellSize, vtkDataArray* connectivity);
424 
429  bool IsStorage64Bit() const { return this->Storage.Is64Bit(); }
430 
437  bool IsStorageShareable() const
438  {
439  if (this->Storage.Is64Bit())
440  {
442  }
443  else
444  {
446  }
447  }
448 
457  void Use32BitStorage();
458  void Use64BitStorage();
459  void UseDefaultStorage();
470  bool CanConvertTo32BitStorage() const;
471  bool CanConvertTo64BitStorage() const;
472  bool CanConvertToDefaultStorage() const;
491  bool ConvertTo32BitStorage();
492  bool ConvertTo64BitStorage();
493  bool ConvertToDefaultStorage();
494  bool ConvertToSmallestStorage();
503  {
504  if (this->Storage.Is64Bit())
505  {
506  return this->GetOffsetsArray64();
507  }
508  else
509  {
510  return this->GetOffsetsArray32();
511  }
512  }
524  {
525  if (this->Storage.Is64Bit())
526  {
527  return this->GetConnectivityArray64();
528  }
529  else
530  {
531  return this->GetConnectivityArray32();
532  }
533  }
546  vtkIdType IsHomogeneous();
547 
557  void InitTraversal();
558 
573  int GetNextCell(vtkIdType& npts, vtkIdType const*& pts) VTK_SIZEHINT(pts, npts);
574 
585  int GetNextCell(vtkIdList* pts);
586 
597  void GetCellAtId(vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints)
598  VTK_SIZEHINT(cellPoints, cellSize) VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
599 
609  void GetCellAtId(
610  vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints, vtkIdList* ptIds)
611  VTK_SIZEHINT(cellPoints, cellSize) VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
612 
618  void GetCellAtId(vtkIdType cellId, vtkIdList* pts)
619  VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
620 
624  vtkIdType GetCellSize(vtkIdType cellId) const;
625 
629  vtkIdType InsertNextCell(vtkCell* cell);
630 
635  vtkIdType InsertNextCell(vtkIdType npts, const vtkIdType* pts) VTK_SIZEHINT(pts, npts);
636 
641  vtkIdType InsertNextCell(vtkIdList* pts);
642 
650  vtkIdType InsertNextCell(const std::initializer_list<vtkIdType>& cell)
651  {
652  return this->InsertNextCell(static_cast<vtkIdType>(cell.size()), cell.begin());
653  }
654 
661  vtkIdType InsertNextCell(int npts);
662 
667  void InsertCellPoint(vtkIdType id);
668 
673  void UpdateCellCount(int npts);
674 
682  vtkIdType GetTraversalCellId();
683  void SetTraversalCellId(vtkIdType cellId);
689  void ReverseCellAtId(vtkIdType cellId) VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
690 
699  void ReplaceCellAtId(vtkIdType cellId, vtkIdList* list);
700  void ReplaceCellAtId(vtkIdType cellId, vtkIdType cellSize, const vtkIdType* cellPoints)
701  VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells()) VTK_SIZEHINT(cellPoints, cellSize);
711  void ReplaceCellPointAtId(vtkIdType cellId, vtkIdType cellPointIndex, vtkIdType newPointId);
712 
720  void ReplaceCellAtId(vtkIdType cellId, const std::initializer_list<vtkIdType>& cell)
721  {
722  return this->ReplaceCellAtId(cellId, static_cast<vtkIdType>(cell.size()), cell.begin());
723  }
724 
729  int GetMaxCellSize();
730 
734  void DeepCopy(vtkCellArray* ca);
735 
739  void ShallowCopy(vtkCellArray* ca);
740 
744  void Append(vtkCellArray* src, vtkIdType pointOffset = 0);
745 
756  void ExportLegacyFormat(vtkIdTypeArray* data);
757 
769  void ImportLegacyFormat(vtkIdTypeArray* data);
770  void ImportLegacyFormat(const vtkIdType* data, vtkIdType len) VTK_SIZEHINT(data, len);
784  void AppendLegacyFormat(vtkIdTypeArray* data, vtkIdType ptOffset = 0);
785  void AppendLegacyFormat(const vtkIdType* data, vtkIdType len, vtkIdType ptOffset = 0)
786  VTK_SIZEHINT(data, len);
797  unsigned long GetActualMemorySize() const;
798 
799  // The following code is used to support
800 
801  // The wrappers get understandably confused by some of the template code below
802 #ifndef __VTK_WRAP__
803 
804  // Holds connectivity and offset arrays of the given ArrayType.
805  template <typename ArrayT>
806  struct VisitState
807  {
808  using ArrayType = ArrayT;
809  using ValueType = typename ArrayType::ValueType;
810  using CellRangeType = decltype(vtk::DataArrayValueRange<1>(std::declval<ArrayType>()));
811 
812  // We can't just use is_same here, since binary compatible representations
813  // (e.g. int and long) are distinct types. Instead, ensure that ValueType
814  // is a signed integer the same size as vtkIdType.
815  // If this value is true, ValueType pointers may be safely converted to
816  // vtkIdType pointers via reinterpret cast.
817  static constexpr bool ValueTypeIsSameAsIdType = std::is_integral<ValueType>::value &&
818  std::is_signed<ValueType>::value && (sizeof(ValueType) == sizeof(vtkIdType));
819 
820  ArrayType* GetOffsets() { return this->Offsets; }
821  const ArrayType* GetOffsets() const { return this->Offsets; }
822 
823  ArrayType* GetConnectivity() { return this->Connectivity; }
824  const ArrayType* GetConnectivity() const { return this->Connectivity; }
825 
826  vtkIdType GetNumberOfCells() const;
827 
828  vtkIdType GetBeginOffset(vtkIdType cellId) const;
829 
830  vtkIdType GetEndOffset(vtkIdType cellId) const;
831 
832  vtkIdType GetCellSize(vtkIdType cellId) const;
833 
834  CellRangeType GetCellRange(vtkIdType cellId);
835 
836  friend class vtkCellArray;
837 
838  protected:
840  {
841  this->Connectivity = vtkSmartPointer<ArrayType>::New();
842  this->Offsets = vtkSmartPointer<ArrayType>::New();
843  this->Offsets->InsertNextValue(0);
845  {
846  this->IsInMemkind = true;
847  }
848  }
849  ~VisitState() = default;
850  void* operator new(size_t nSize)
851  {
852  void* r;
853 #ifdef VTK_USE_MEMKIND
855 #else
856  r = malloc(nSize);
857 #endif
858  return r;
859  }
860  void operator delete(void* p)
861  {
862 #ifdef VTK_USE_MEMKIND
863  VisitState* a = static_cast<VisitState*>(p);
864  if (a->IsInMemkind)
865  {
867  }
868  else
869  {
870  free(p);
871  }
872 #else
873  free(p);
874 #endif
875  }
876 
879 
880  private:
881  VisitState(const VisitState&) = delete;
882  VisitState& operator=(const VisitState&) = delete;
883  bool IsInMemkind = false;
884  };
885 
886 private: // Helpers that allow Visit to return a value:
887  template <typename Functor, typename... Args>
888  using GetReturnType = decltype(
889  std::declval<Functor>()(std::declval<VisitState<ArrayType32>&>(), std::declval<Args>()...));
890 
891  template <typename Functor, typename... Args>
892  struct ReturnsVoid : std::is_same<GetReturnType<Functor, Args...>, void>
893  {
894  };
895 
896 public:
966  template <typename Functor, typename... Args,
967  typename = typename std::enable_if<ReturnsVoid<Functor, Args...>::value>::type>
968  void Visit(Functor&& functor, Args&&... args)
969  {
970  if (this->Storage.Is64Bit())
971  {
972  // If you get an error on the next line, a call to Visit(functor, Args...)
973  // is being called with arguments that do not match the functor's call
974  // signature. See the Visit documentation for details.
975  functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
976  }
977  else
978  {
979  // If you get an error on the next line, a call to Visit(functor, Args...)
980  // is being called with arguments that do not match the functor's call
981  // signature. See the Visit documentation for details.
982  functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
983  }
984  }
985 
986  template <typename Functor, typename... Args,
987  typename = typename std::enable_if<ReturnsVoid<Functor, Args...>::value>::type>
988  void Visit(Functor&& functor, Args&&... args) const
989  {
990  if (this->Storage.Is64Bit())
991  {
992  // If you get an error on the next line, a call to Visit(functor, Args...)
993  // is being called with arguments that do not match the functor's call
994  // signature. See the Visit documentation for details.
995  functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
996  }
997  else
998  {
999  // If you get an error on the next line, a call to Visit(functor, Args...)
1000  // is being called with arguments that do not match the functor's call
1001  // signature. See the Visit documentation for details.
1002  functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
1003  }
1004  }
1005 
1006  template <typename Functor, typename... Args,
1007  typename = typename std::enable_if<!ReturnsVoid<Functor, Args...>::value>::type>
1008  GetReturnType<Functor, Args...> Visit(Functor&& functor, Args&&... args)
1009  {
1010  if (this->Storage.Is64Bit())
1011  {
1012  // If you get an error on the next line, a call to Visit(functor, Args...)
1013  // is being called with arguments that do not match the functor's call
1014  // signature. See the Visit documentation for details.
1015  return functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
1016  }
1017  else
1018  {
1019  // If you get an error on the next line, a call to Visit(functor, Args...)
1020  // is being called with arguments that do not match the functor's call
1021  // signature. See the Visit documentation for details.
1022  return functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
1023  }
1024  }
1025  template <typename Functor, typename... Args,
1026  typename = typename std::enable_if<!ReturnsVoid<Functor, Args...>::value>::type>
1027  GetReturnType<Functor, Args...> Visit(Functor&& functor, Args&&... args) const
1028  {
1029  if (this->Storage.Is64Bit())
1030  {
1031  // If you get an error on the next line, a call to Visit(functor, Args...)
1032  // is being called with arguments that do not match the functor's call
1033  // signature. See the Visit documentation for details.
1034  return functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
1035  }
1036  else
1037  {
1038  // If you get an error on the next line, a call to Visit(functor, Args...)
1039  // is being called with arguments that do not match the functor's call
1040  // signature. See the Visit documentation for details.
1041  return functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
1042  }
1043  }
1044 
1047 #endif // __VTK_WRAP__
1048 
1049  //=================== Begin Legacy Methods ===================================
1050  // These should be deprecated at some point as they are confusing or very slow
1051 
1058  virtual void SetNumberOfCells(vtkIdType);
1059 
1071  vtkIdType EstimateSize(vtkIdType numCells, int maxPtsPerCell);
1072 
1081  vtkIdType GetSize();
1082 
1089  vtkIdType GetNumberOfConnectivityEntries();
1090 
1100  void GetCell(vtkIdType loc, vtkIdType& npts, const vtkIdType*& pts)
1101  VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries()) VTK_SIZEHINT(pts, npts);
1102 
1109  void GetCell(vtkIdType loc, vtkIdList* pts)
1110  VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries());
1111 
1118  vtkIdType GetInsertLocation(int npts);
1119 
1127  vtkIdType GetTraversalLocation();
1128  vtkIdType GetTraversalLocation(vtkIdType npts);
1129  void SetTraversalLocation(vtkIdType loc);
1139  void ReverseCell(vtkIdType loc) VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries());
1140 
1152  void ReplaceCell(vtkIdType loc, int npts, const vtkIdType pts[])
1153  VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries()) VTK_SIZEHINT(pts, npts);
1154 
1169  void SetCells(vtkIdType ncells, vtkIdTypeArray* cells);
1170 
1182 
1183  //=================== End Legacy Methods =====================================
1184 
1185  friend class vtkCellArrayIterator;
1186 
1187 protected:
1188  vtkCellArray();
1189  ~vtkCellArray() override;
1190 
1191  // Encapsulates storage of the internal arrays as a discriminated union
1192  // between 32-bit and 64-bit storage.
1193  struct Storage
1194  {
1195  // Union type that switches 32 and 64 bit array storage
1196  union ArraySwitch {
1197  ArraySwitch() = default; // handled by Storage
1198  ~ArraySwitch() = default; // handle by Storage
1201  };
1202 
1204  {
1205 #ifdef VTK_USE_MEMKIND
1206  this->Arrays =
1208 #else
1209  this->Arrays = new ArraySwitch;
1210 #endif
1211 
1212  // Default to the compile-time setting:
1213 #ifdef VTK_USE_64BIT_IDS
1214 
1215  this->Arrays->Int64 = new VisitState<ArrayType64>;
1216  this->StorageIs64Bit = true;
1217 
1218 #else // VTK_USE_64BIT_IDS
1219 
1220  this->Arrays->Int32 = new VisitState<ArrayType32>;
1221  this->StorageIs64Bit = false;
1222 
1223 #endif // VTK_USE_64BIT_IDS
1224 #ifdef VTK_USE_MEMKIND
1226  {
1227  this->IsInMemkind = true;
1228  }
1229 #else
1230  (void)this->IsInMemkind; // comp warning workaround
1231 #endif
1232  }
1233 
1235  {
1236  if (this->StorageIs64Bit)
1237  {
1238  this->Arrays->Int64->~VisitState();
1239  delete this->Arrays->Int64;
1240  }
1241  else
1242  {
1243  this->Arrays->Int32->~VisitState();
1244  delete this->Arrays->Int32;
1245  }
1246 #ifdef VTK_USE_MEMKIND
1247  if (this->IsInMemkind)
1248  {
1250  }
1251  else
1252  {
1253  free(this->Arrays);
1254  }
1255 #else
1256  delete this->Arrays;
1257 #endif
1258  }
1259 
1260  // Switch the internal arrays to be 32-bit. Any old data is lost. Returns
1261  // true if the storage changes.
1263  {
1264  if (!this->StorageIs64Bit)
1265  {
1266  return false;
1267  }
1268 
1269  this->Arrays->Int64->~VisitState();
1270  delete this->Arrays->Int64;
1271  this->Arrays->Int32 = new VisitState<ArrayType32>;
1272  this->StorageIs64Bit = false;
1273 
1274  return true;
1275  }
1276 
1277  // Switch the internal arrays to be 64-bit. Any old data is lost. Returns
1278  // true if the storage changes.
1280  {
1281  if (this->StorageIs64Bit)
1282  {
1283  return false;
1284  }
1285 
1286  this->Arrays->Int32->~VisitState();
1287  delete this->Arrays->Int32;
1288  this->Arrays->Int64 = new VisitState<ArrayType64>;
1289  this->StorageIs64Bit = true;
1290 
1291  return true;
1292  }
1293 
1294  // Returns true if the storage is currently configured to be 64 bit.
1295  bool Is64Bit() const { return this->StorageIs64Bit; }
1296 
1297  // Get the VisitState for 32-bit arrays
1299  {
1300  assert(!this->StorageIs64Bit);
1301  return *this->Arrays->Int32;
1302  }
1303 
1305  {
1306  assert(!this->StorageIs64Bit);
1307  return *this->Arrays->Int32;
1308  }
1309 
1310  // Get the VisitState for 64-bit arrays
1312  {
1313  assert(this->StorageIs64Bit);
1314  return *this->Arrays->Int64;
1315  }
1316 
1318  {
1319  assert(this->StorageIs64Bit);
1320  return *this->Arrays->Int64;
1321  }
1322 
1323  private:
1324  // Access restricted to ensure proper union construction/destruction thru
1325  // API.
1326  ArraySwitch* Arrays;
1327  bool StorageIs64Bit;
1328  bool IsInMemkind = false;
1329  };
1330 
1333  vtkIdType TraversalCellId{ 0 };
1334 
1336 
1337 private:
1338  vtkCellArray(const vtkCellArray&) = delete;
1339  void operator=(const vtkCellArray&) = delete;
1340 };
1341 
1342 template <typename ArrayT>
1344 {
1345  return this->Offsets->GetNumberOfValues() - 1;
1346 }
1347 
1348 template <typename ArrayT>
1350 {
1351  return static_cast<vtkIdType>(this->Offsets->GetValue(cellId));
1352 }
1353 
1354 template <typename ArrayT>
1356 {
1357  return static_cast<vtkIdType>(this->Offsets->GetValue(cellId + 1));
1358 }
1359 
1360 template <typename ArrayT>
1362 {
1363  return this->GetEndOffset(cellId) - this->GetBeginOffset(cellId);
1364 }
1365 
1366 template <typename ArrayT>
1369 {
1370  return vtk::DataArrayValueRange<1>(
1371  this->GetConnectivity(), this->GetBeginOffset(cellId), this->GetEndOffset(cellId));
1372 }
1373 VTK_ABI_NAMESPACE_END
1374 
1376 {
1377 VTK_ABI_NAMESPACE_BEGIN
1378 
1380 {
1381  // Insert full cell
1382  template <typename CellStateT>
1383  vtkIdType operator()(CellStateT& state, const vtkIdType npts, const vtkIdType pts[])
1384  {
1385  using ValueType = typename CellStateT::ValueType;
1386  auto* conn = state.GetConnectivity();
1387  auto* offsets = state.GetOffsets();
1388 
1389  const vtkIdType cellId = offsets->GetNumberOfValues() - 1;
1390 
1391  offsets->InsertNextValue(static_cast<ValueType>(conn->GetNumberOfValues() + npts));
1392 
1393  for (vtkIdType i = 0; i < npts; ++i)
1394  {
1395  conn->InsertNextValue(static_cast<ValueType>(pts[i]));
1396  }
1397 
1398  return cellId;
1399  }
1400 
1401  // Just update offset table (for incremental API)
1402  template <typename CellStateT>
1403  vtkIdType operator()(CellStateT& state, const vtkIdType npts)
1404  {
1405  using ValueType = typename CellStateT::ValueType;
1406  auto* conn = state.GetConnectivity();
1407  auto* offsets = state.GetOffsets();
1408 
1409  const vtkIdType cellId = offsets->GetNumberOfValues() - 1;
1410 
1411  offsets->InsertNextValue(static_cast<ValueType>(conn->GetNumberOfValues() + npts));
1412 
1413  return cellId;
1414  }
1415 };
1416 
1417 // for incremental API:
1419 {
1420  template <typename CellStateT>
1421  void operator()(CellStateT& state, const vtkIdType npts)
1422  {
1423  using ValueType = typename CellStateT::ValueType;
1424 
1425  auto* offsets = state.GetOffsets();
1426  const ValueType cellBegin = offsets->GetValue(offsets->GetMaxId() - 1);
1427  offsets->SetValue(offsets->GetMaxId(), static_cast<ValueType>(cellBegin + npts));
1428  }
1429 };
1430 
1432 {
1433  template <typename CellStateT>
1434  vtkIdType operator()(CellStateT& state, vtkIdType cellId)
1435  {
1436  return state.GetCellSize(cellId);
1437  }
1438 };
1439 
1441 {
1442  template <typename CellStateT>
1443  void operator()(CellStateT& state, const vtkIdType cellId, vtkIdList* ids)
1444  {
1445  using ValueType = typename CellStateT::ValueType;
1446 
1447  const vtkIdType beginOffset = state.GetBeginOffset(cellId);
1448  const vtkIdType endOffset = state.GetEndOffset(cellId);
1449  const vtkIdType cellSize = endOffset - beginOffset;
1450  const auto cellConnectivity = state.GetConnectivity()->GetPointer(beginOffset);
1451 
1452  // ValueType differs from vtkIdType, so we have to copy into a temporary buffer:
1453  ids->SetNumberOfIds(cellSize);
1454  vtkIdType* idPtr = ids->GetPointer(0);
1455  for (ValueType i = 0; i < cellSize; ++i)
1456  {
1457  idPtr[i] = static_cast<vtkIdType>(cellConnectivity[i]);
1458  }
1459  }
1460 
1461  // SFINAE helper to check if a VisitState's connectivity array's memory
1462  // can be used as a vtkIdType*.
1463  template <typename CellStateT>
1465  {
1466  private:
1467  using ValueType = typename CellStateT::ValueType;
1468  using ArrayType = typename CellStateT::ArrayType;
1470  static constexpr bool ValueTypeCompat = CellStateT::ValueTypeIsSameAsIdType;
1471  static constexpr bool ArrayTypeCompat = std::is_base_of<AOSArrayType, ArrayType>::value;
1472 
1473  public:
1474  static constexpr bool value = ValueTypeCompat && ArrayTypeCompat;
1475  };
1476 
1477  template <typename CellStateT>
1479  CellStateT& state, const vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints,
1480  vtkIdList* vtkNotUsed(temp))
1481  {
1482  const vtkIdType beginOffset = state.GetBeginOffset(cellId);
1483  const vtkIdType endOffset = state.GetEndOffset(cellId);
1484  cellSize = endOffset - beginOffset;
1485  // This is safe, see CanShareConnPtr helper above.
1486  cellPoints = reinterpret_cast<vtkIdType*>(state.GetConnectivity()->GetPointer(beginOffset));
1487  }
1488 
1489  template <typename CellStateT>
1491  CellStateT& state, const vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints,
1492  vtkIdList* temp)
1493  {
1494  using ValueType = typename CellStateT::ValueType;
1495 
1496  const vtkIdType beginOffset = state.GetBeginOffset(cellId);
1497  const vtkIdType endOffset = state.GetEndOffset(cellId);
1498  cellSize = endOffset - beginOffset;
1499  const ValueType* cellConnectivity = state.GetConnectivity()->GetPointer(beginOffset);
1500 
1501  // ValueType differs from vtkIdType, so we have to copy into a temporary buffer:
1502  temp->SetNumberOfIds(cellSize);
1503  vtkIdType* tempPtr = temp->GetPointer(0);
1504  for (vtkIdType i = 0; i < cellSize; ++i)
1505  {
1506  tempPtr[i] = static_cast<vtkIdType>(cellConnectivity[i]);
1507  }
1508 
1509  cellPoints = temp->GetPointer(0);
1510  }
1511 };
1512 
1514 {
1515  template <typename CellStateT>
1516  void operator()(CellStateT& state)
1517  {
1518  state.GetOffsets()->Reset();
1519  state.GetConnectivity()->Reset();
1520  state.GetOffsets()->InsertNextValue(0);
1521  }
1522 };
1523 
1524 VTK_ABI_NAMESPACE_END
1525 } // end namespace vtkCellArray_detail
1526 
1527 VTK_ABI_NAMESPACE_BEGIN
1528 //----------------------------------------------------------------------------
1530 {
1531  this->TraversalCellId = 0;
1532 }
1533 
1534 //----------------------------------------------------------------------------
1535 inline int vtkCellArray::GetNextCell(vtkIdType& npts, vtkIdType const*& pts) VTK_SIZEHINT(pts, npts)
1536 {
1537  if (this->TraversalCellId < this->GetNumberOfCells())
1538  {
1539  this->GetCellAtId(this->TraversalCellId, npts, pts);
1540  ++this->TraversalCellId;
1541  return 1;
1542  }
1543 
1544  npts = 0;
1545  pts = nullptr;
1546  return 0;
1547 }
1548 
1549 //----------------------------------------------------------------------------
1551 {
1552  if (this->TraversalCellId < this->GetNumberOfCells())
1553  {
1554  this->GetCellAtId(this->TraversalCellId, pts);
1555  ++this->TraversalCellId;
1556  return 1;
1557  }
1558 
1559  pts->Reset();
1560  return 0;
1561 }
1562 //----------------------------------------------------------------------------
1564 {
1565  return this->Visit(vtkCellArray_detail::GetCellSizeImpl{}, cellId);
1566 }
1567 
1568 //----------------------------------------------------------------------------
1569 inline void vtkCellArray::GetCellAtId(vtkIdType cellId, vtkIdType& cellSize,
1570  vtkIdType const*& cellPoints) VTK_SIZEHINT(cellPoints, cellSize)
1571 {
1572  this->Visit(vtkCellArray_detail::GetCellAtIdImpl{}, cellId, cellSize, cellPoints, this->TempCell);
1573 }
1574 
1575 //----------------------------------------------------------------------------
1576 inline void vtkCellArray::GetCellAtId(vtkIdType cellId, vtkIdType& cellSize,
1577  vtkIdType const*& cellPoints, vtkIdList* ptIds) VTK_SIZEHINT(cellPoints, cellSize)
1578 {
1579  this->Visit(vtkCellArray_detail::GetCellAtIdImpl{}, cellId, cellSize, cellPoints, ptIds);
1580 }
1581 
1582 //----------------------------------------------------------------------------
1584 {
1585  this->Visit(vtkCellArray_detail::GetCellAtIdImpl{}, cellId, pts);
1586 }
1587 
1588 //----------------------------------------------------------------------------
1590  VTK_SIZEHINT(pts, npts)
1591 {
1592  return this->Visit(vtkCellArray_detail::InsertNextCellImpl{}, npts, pts);
1593 }
1594 
1595 //----------------------------------------------------------------------------
1597 {
1598  return this->Visit(vtkCellArray_detail::InsertNextCellImpl{}, npts);
1599 }
1600 
1601 //----------------------------------------------------------------------------
1603 {
1604  if (this->Storage.Is64Bit())
1605  {
1606  using ValueType = typename ArrayType64::ValueType;
1607  this->Storage.GetArrays64().Connectivity->InsertNextValue(static_cast<ValueType>(id));
1608  }
1609  else
1610  {
1611  using ValueType = typename ArrayType32::ValueType;
1612  this->Storage.GetArrays32().Connectivity->InsertNextValue(static_cast<ValueType>(id));
1613  }
1614 }
1615 
1616 //----------------------------------------------------------------------------
1617 inline void vtkCellArray::UpdateCellCount(int npts)
1618 {
1620 }
1621 
1622 //----------------------------------------------------------------------------
1624 {
1625  return this->Visit(
1627 }
1628 
1629 //----------------------------------------------------------------------------
1631 {
1632  vtkIdList* pts = cell->GetPointIds();
1633  return this->Visit(
1635 }
1636 
1637 //----------------------------------------------------------------------------
1638 inline void vtkCellArray::Reset()
1639 {
1641 }
1642 
1643 VTK_ABI_NAMESPACE_END
1644 #endif // vtkCellArray.h
ArrayType64 * GetConnectivityArray64()
Return the array used to store the point ids that define the cells' connectivity. ...
Definition: vtkCellArray.h:535
vtkIdType GetCellSize(vtkIdType cellId) const
Return the size of the cell at cellId.
vtkTypeBool Allocate(vtkIdType sz, vtkIdType vtkNotUsed(ext)=1000)
Allocate memory.
Definition: vtkCellArray.h:222
ArrayType32 * GetConnectivityArray32()
Return the array used to store the point ids that define the cells' connectivity. ...
Definition: vtkCellArray.h:534
vtkIdType operator()(CellStateT &state, const vtkIdType npts)
vtkDataArray * GetConnectivityArray()
Return the array used to store the point ids that define the cells' connectivity. ...
Definition: vtkCellArray.h:523
static vtkFreeingFunction GetAlternateFreeFunction()
ArrayType * GetConnectivity()
Definition: vtkCellArray.h:823
abstract base class for most VTK objects
Definition: vtkObject.h:51
Remove all duplicate types from TypeList TList, storing the new list in Result.
Definition: vtkTypeList.h:110
decltype(vtk::DataArrayValueRange< 1 >(std::declval< ArrayType >())) CellRangeType
Definition: vtkCellArray.h:810
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
vtkIdType GetNumberOfCells() const
void InsertCellPoint(vtkIdType id)
Used in conjunction with InsertNextCell(npts) to add another point to the list of cells...
bool IsStorageShareable() const
Definition: vtkCellArray.h:437
void operator()(CellStateT &state)
GetReturnType< Functor, Args... > Visit(Functor &&functor, Args &&...args)
vtkNew< vtkIdTypeArray > LegacyData
vtkIdType GetNumberOfCells() const
Get the number of cells in the array.
Definition: vtkCellArray.h:309
void Reset()
Reset to an empty state but retain previously allocated memory.
Definition: vtkIdList.h:134
void InitTraversal()
vtkSmartPointer< ArrayType > Connectivity
Definition: vtkCellArray.h:877
const ArrayType * GetOffsets() const
Definition: vtkCellArray.h:821
vtkTypeList::Create< ArrayType32, ArrayType64 > StorageArrayList
List of possible array types used for storage.
Definition: vtkCellArray.h:200
ArrayType32 * GetOffsetsArray32()
Return the array used to store cell offsets.
Definition: vtkCellArray.h:513
dynamic, self-adjusting array of vtkIdType
int vtkIdType
Definition: vtkType.h:315
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
vtkIdType TraversalCellId
const ArrayType * GetConnectivity() const
Definition: vtkCellArray.h:824
typename vtkTypeList::detail::CreateImpl< Ts... >::type Create
Definition: vtkTypeList.h:163
bool AllocateCopy(vtkCellArray *other)
Pre-allocate memory in internal data structures to match the used size of the input vtkCellArray...
Definition: vtkCellArray.h:261
int vtkTypeBool
Definition: vtkABI.h:64
vtkNew< vtkIdList > TempCell
abstract class to specify cell behavior
Definition: vtkCell.h:49
void Reset()
Reuse list.
void operator()(CellStateT &state, const vtkIdType npts)
a simple class to control print indentation
Definition: vtkIndent.h:28
void operator()(CellStateT &state, const vtkIdType cellId, vtkIdList *ids)
static bool GetUsingMemkind()
A global state flag that controls whether vtkObjects are constructed in the usual way (the default) o...
list of point or cell ids
Definition: vtkIdList.h:22
vtkIdType GetOffset(vtkIdType cellId)
Get the offset (into the connectivity) for a specified cell id.
Definition: vtkCellArray.h:340
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:44
typename vtkTypeList::Unique< vtkTypeList::Create< vtkAOSDataArrayTemplate< int >, vtkAOSDataArrayTemplate< long >, vtkAOSDataArrayTemplate< long long >>>::Result InputArrayList
List of possible ArrayTypes that are compatible with internal storage.
Definition: vtkCellArray.h:212
vtkIdType GetNumberOfConnectivityIds() const
Get the size of the connectivity array that stores the point ids.
Definition: vtkCellArray.h:358
vtkTypeInt64Array ArrayType64
Definition: vtkCellArray.h:179
vtkIdType GetNumberOfIds() const noexcept
Return the number of id's in the list.
Definition: vtkIdList.h:49
bool Is64Bit() const
vtkIdType GetEndOffset(vtkIdType cellId) const
#define VTK_SIZEHINT(...)
bool IsStorage64Bit() const
Definition: vtkCellArray.h:429
vtkSmartPointer< vtkDataArray > GetData(const Ioss::GroupingEntity *entity, const std::string &fieldname, Ioss::Transform *transform=nullptr, Cache *cache=nullptr, const std::string &cachekey=std::string())
Returns a VTK array for a given field (fieldname) on the chosen block (or set) entity.
void UpdateCellCount(int npts)
Used in conjunction with InsertNextCell(int npts) and InsertCellPoint() to update the number of point...
#define VTK_NEWINSTANCE
CellRangeType GetCellRange(vtkIdType cellId)
vtkIdType operator()(CellStateT &state, vtkIdType cellId)
vtkIdType InsertNextCell(vtkCell *cell)
Insert a cell object.
vtkSmartPointer< vtkCellArray > GetConnectivity(Ioss::GroupingEntity *group_entity, int &vtk_topology_type, Cache *cache=nullptr)
Read connectivity information from the group_entity.
std::enable_if< CanShareConnPtr< CellStateT >::value, void >::type operator()(CellStateT &state, const vtkIdType cellId, vtkIdType &cellSize, vtkIdType const *&cellPoints, vtkIdList *vtkNotUsed(temp))
vtkSmartPointer< ArrayType > Offsets
Definition: vtkCellArray.h:878
void Visit(Functor &&functor, Args &&...args)
Definition: vtkCellArray.h:968
VisitState< ArrayType64 > & GetArrays64()
vtkDataArray * GetOffsetsArray()
Return the array used to store cell offsets.
Definition: vtkCellArray.h:502
object to represent cell connectivity
Definition: vtkCellArray.h:175
vtkTypeInt32Array ArrayType32
Definition: vtkCellArray.h:178
ArrayType * GetOffsets()
Definition: vtkCellArray.h:820
typename ArrayType::ValueType ValueType
Definition: vtkCellArray.h:809
vtkIdType GetCellSize(vtkIdType cellId) const
std::enable_if<!CanShareConnPtr< CellStateT >::value, void >::type operator()(CellStateT &state, const vtkIdType cellId, vtkIdType &cellSize, vtkIdType const *&cellPoints, vtkIdList *temp)
ArrayType64 * GetOffsetsArray64()
Return the array used to store cell offsets.
Definition: vtkCellArray.h:514
vtkIdList * GetPointIds()
Return the list of point ids defining the cell.
Definition: vtkCell.h:145
VisitState< ArrayType32 > * Int32
void GetCellAtId(vtkIdType cellId, vtkIdType &cellSize, vtkIdType const *&cellPoints)
Return the point ids for the cell at cellId.
GetReturnType< Functor, Args... > Visit(Functor &&functor, Args &&...args) const
static vtkObject * New()
Create an object with Debug turned off, modified time initialized to zero, and reference counting on...
VisitState< ArrayType32 > & GetArrays32()
static vtkMallocingFunction GetCurrentMallocFunction()
#define VTK_EXPECTS(x)
VisitState< ArrayType64 > * Int64
vtkIdType operator()(CellStateT &state, const vtkIdType npts, const vtkIdType pts[])
vtkIdType GetBeginOffset(vtkIdType cellId) const
const VisitState< ArrayType32 > & GetArrays32() const
void SetNumberOfIds(vtkIdType number)
Specify the number of ids for this object to hold.
Encapsulate traversal logic for vtkCellArray.
Storage Storage
void Visit(Functor &&functor, Args &&...args) const
Definition: vtkCellArray.h:988
vtkIdType GetNumberOfOffsets() const
Get the number of elements in the offsets array.
Definition: vtkCellArray.h:325
STL-compatible iterable ranges that provide access to vtkDataArray elements.
bool AllocateEstimate(vtkIdType numCells, vtkIdType maxCellSize)
Pre-allocate memory in internal data structures.
Definition: vtkCellArray.h:236
int GetNextCell(vtkIdType &npts, vtkIdType const *&pts)
vtkIdType * GetPointer(vtkIdType i)
Get a pointer to a particular data index.
Definition: vtkIdList.h:115
const VisitState< ArrayType64 > & GetArrays64() const