VTK  9.2.6
vtkCellArray.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkCellArray.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
141 #ifndef vtkCellArray_h
142 #define vtkCellArray_h
143 
144 #include "vtkCommonDataModelModule.h" // For export macro
145 #include "vtkObject.h"
146 
147 #include "vtkAOSDataArrayTemplate.h" // Needed for inline methods
148 #include "vtkCell.h" // Needed for inline methods
149 #include "vtkDataArrayRange.h" // Needed for inline methods
150 #include "vtkFeatures.h" // for VTK_USE_MEMKIND
151 #include "vtkSmartPointer.h" // For vtkSmartPointer
152 #include "vtkTypeInt32Array.h" // Needed for inline methods
153 #include "vtkTypeInt64Array.h" // Needed for inline methods
154 #include "vtkTypeList.h" // Needed for ArrayList definition
155 
156 #include <cassert> // for assert
157 #include <initializer_list> // for API
158 #include <type_traits> // for std::is_same
159 #include <utility> // for std::forward
160 
181 #define VTK_CELL_ARRAY_V2
182 
184 class vtkIdTypeArray;
185 
186 class VTKCOMMONDATAMODEL_EXPORT vtkCellArray : public vtkObject
187 {
188 public:
189  using ArrayType32 = vtkTypeInt32Array;
190  using ArrayType64 = vtkTypeInt64Array;
191 
193 
197  static vtkCellArray* New();
198  vtkTypeMacro(vtkCellArray, vtkObject);
199  void PrintSelf(ostream& os, vtkIndent indent) override;
200  void PrintDebug(ostream& os);
202 
212 
221  using InputArrayList =
224 
233  vtkTypeBool Allocate(vtkIdType sz, vtkIdType vtkNotUsed(ext) = 1000)
234  {
235  return this->AllocateExact(sz, sz) ? 1 : 0;
236  }
237 
247  bool AllocateEstimate(vtkIdType numCells, vtkIdType maxCellSize)
248  {
249  return this->AllocateExact(numCells, numCells * maxCellSize);
250  }
251 
261  bool AllocateExact(vtkIdType numCells, vtkIdType connectivitySize);
262 
273  {
274  return this->AllocateExact(other->GetNumberOfCells(), other->GetNumberOfConnectivityIds());
275  }
276 
286  bool ResizeExact(vtkIdType numCells, vtkIdType connectivitySize);
287 
291  void Initialize();
292 
296  void Reset();
297 
303  void Squeeze();
304 
315  bool IsValid();
316 
321  {
322  if (this->Storage.Is64Bit())
323  {
324  return this->Storage.GetArrays64().Offsets->GetNumberOfValues() - 1;
325  }
326  else
327  {
328  return this->Storage.GetArrays32().Offsets->GetNumberOfValues() - 1;
329  }
330  }
331 
337  {
338  if (this->Storage.Is64Bit())
339  {
340  return this->Storage.GetArrays64().Offsets->GetNumberOfValues();
341  }
342  else
343  {
344  return this->Storage.GetArrays32().Offsets->GetNumberOfValues();
345  }
346  }
347 
352  {
353  if (this->Storage.Is64Bit())
354  {
355  return this->Storage.GetArrays64().Offsets->GetValue(cellId);
356  }
357  else
358  {
359  return this->Storage.GetArrays32().Offsets->GetValue(cellId);
360  }
361  }
362 
370  {
371  if (this->Storage.Is64Bit())
372  {
373  return this->Storage.GetArrays64().Connectivity->GetNumberOfValues();
374  }
375  else
376  {
377  return this->Storage.GetArrays32().Connectivity->GetNumberOfValues();
378  }
379  }
380 
386  VTK_NEWINSTANCE vtkCellArrayIterator* NewIterator();
387 
388 #ifndef __VTK_WRAP__ // The wrappers have issues with some of these templates
389 
399  void SetData(vtkTypeInt32Array* offsets, vtkTypeInt32Array* connectivity);
400  void SetData(vtkTypeInt64Array* offsets, vtkTypeInt64Array* connectivity);
401  void SetData(vtkIdTypeArray* offsets, vtkIdTypeArray* connectivity);
402  void SetData(vtkAOSDataArrayTemplate<int>* offsets, vtkAOSDataArrayTemplate<int>* connectivity);
403  void SetData(vtkAOSDataArrayTemplate<long>* offsets, vtkAOSDataArrayTemplate<long>* connectivity);
404  void SetData(
407 #endif // __VTK_WRAP__
408 
421  bool SetData(vtkDataArray* offsets, vtkDataArray* connectivity);
422 
436  bool SetData(vtkIdType cellSize, vtkDataArray* connectivity);
437 
442  bool IsStorage64Bit() const { return this->Storage.Is64Bit(); }
443 
450  bool IsStorageShareable() const
451  {
452  if (this->Storage.Is64Bit())
453  {
455  }
456  else
457  {
459  }
460  }
461 
470  void Use32BitStorage();
471  void Use64BitStorage();
472  void UseDefaultStorage();
483  bool CanConvertTo32BitStorage() const;
484  bool CanConvertTo64BitStorage() const;
485  bool CanConvertToDefaultStorage() const;
504  bool ConvertTo32BitStorage();
505  bool ConvertTo64BitStorage();
506  bool ConvertToDefaultStorage();
507  bool ConvertToSmallestStorage();
516  {
517  if (this->Storage.Is64Bit())
518  {
519  return this->GetOffsetsArray64();
520  }
521  else
522  {
523  return this->GetOffsetsArray32();
524  }
525  }
537  {
538  if (this->Storage.Is64Bit())
539  {
540  return this->GetConnectivityArray64();
541  }
542  else
543  {
544  return this->GetConnectivityArray32();
545  }
546  }
559  vtkIdType IsHomogeneous();
560 
570  void InitTraversal();
571 
586  int GetNextCell(vtkIdType& npts, vtkIdType const*& pts) VTK_SIZEHINT(pts, npts);
587 
598  int GetNextCell(vtkIdList* pts);
599 
610  void GetCellAtId(vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints)
611  VTK_SIZEHINT(cellPoints, cellSize) VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
612 
622  void GetCellAtId(
623  vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints, vtkIdList* ptIds)
624  VTK_SIZEHINT(cellPoints, cellSize) VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
625 
631  void GetCellAtId(vtkIdType cellId, vtkIdList* pts)
632  VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
633 
637  vtkIdType GetCellSize(const vtkIdType cellId) const;
638 
642  vtkIdType InsertNextCell(vtkCell* cell);
643 
648  vtkIdType InsertNextCell(vtkIdType npts, const vtkIdType* pts) VTK_SIZEHINT(pts, npts);
649 
654  vtkIdType InsertNextCell(vtkIdList* pts);
655 
663  vtkIdType InsertNextCell(const std::initializer_list<vtkIdType>& cell)
664  {
665  return this->InsertNextCell(static_cast<vtkIdType>(cell.size()), cell.begin());
666  }
667 
674  vtkIdType InsertNextCell(int npts);
675 
680  void InsertCellPoint(vtkIdType id);
681 
686  void UpdateCellCount(int npts);
687 
695  vtkIdType GetTraversalCellId();
696  void SetTraversalCellId(vtkIdType cellId);
702  void ReverseCellAtId(vtkIdType cellId) VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells());
703 
712  void ReplaceCellAtId(vtkIdType cellId, vtkIdList* list);
713  void ReplaceCellAtId(vtkIdType cellId, vtkIdType cellSize, const vtkIdType* cellPoints)
714  VTK_EXPECTS(0 <= cellId && cellId < GetNumberOfCells()) VTK_SIZEHINT(cellPoints, cellSize);
724  void ReplaceCellAtId(vtkIdType cellId, const std::initializer_list<vtkIdType>& cell)
725  {
726  return this->ReplaceCellAtId(cellId, static_cast<vtkIdType>(cell.size()), cell.begin());
727  }
728 
733  int GetMaxCellSize();
734 
738  void DeepCopy(vtkCellArray* ca);
739 
743  void ShallowCopy(vtkCellArray* ca);
744 
748  void Append(vtkCellArray* src, vtkIdType pointOffset = 0);
749 
760  void ExportLegacyFormat(vtkIdTypeArray* data);
761 
773  void ImportLegacyFormat(vtkIdTypeArray* data);
774  void ImportLegacyFormat(const vtkIdType* data, vtkIdType len) VTK_SIZEHINT(data, len);
788  void AppendLegacyFormat(vtkIdTypeArray* data, vtkIdType ptOffset = 0);
789  void AppendLegacyFormat(const vtkIdType* data, vtkIdType len, vtkIdType ptOffset = 0)
790  VTK_SIZEHINT(data, len);
801  unsigned long GetActualMemorySize() const;
802 
803  // The following code is used to support
804 
805  // The wrappers get understandably confused by some of the template code below
806 #ifndef __VTK_WRAP__
807 
808  // Holds connectivity and offset arrays of the given ArrayType.
809  template <typename ArrayT>
810  struct VisitState
811  {
812  using ArrayType = ArrayT;
813  using ValueType = typename ArrayType::ValueType;
814  using CellRangeType = decltype(vtk::DataArrayValueRange<1>(std::declval<ArrayType>()));
815 
816  // We can't just use is_same here, since binary compatible representations
817  // (e.g. int and long) are distinct types. Instead, ensure that ValueType
818  // is a signed integer the same size as vtkIdType.
819  // If this value is true, ValueType pointers may be safely converted to
820  // vtkIdType pointers via reinterpret cast.
821  static constexpr bool ValueTypeIsSameAsIdType = std::is_integral<ValueType>::value &&
822  std::is_signed<ValueType>::value && (sizeof(ValueType) == sizeof(vtkIdType));
823 
824  ArrayType* GetOffsets() { return this->Offsets; }
825  const ArrayType* GetOffsets() const { return this->Offsets; }
826 
827  ArrayType* GetConnectivity() { return this->Connectivity; }
828  const ArrayType* GetConnectivity() const { return this->Connectivity; }
829 
830  vtkIdType GetNumberOfCells() const;
831 
832  vtkIdType GetBeginOffset(vtkIdType cellId) const;
833 
834  vtkIdType GetEndOffset(vtkIdType cellId) const;
835 
836  vtkIdType GetCellSize(vtkIdType cellId) const;
837 
838  CellRangeType GetCellRange(vtkIdType cellId);
839 
840  friend class vtkCellArray;
841 
842  protected:
844  {
845  this->Connectivity = vtkSmartPointer<ArrayType>::New();
846  this->Offsets = vtkSmartPointer<ArrayType>::New();
847  this->Offsets->InsertNextValue(0);
849  {
850  this->IsInMemkind = true;
851  }
852  }
853  ~VisitState() = default;
854  void* operator new(size_t nSize)
855  {
856  void* r;
857 #ifdef VTK_USE_MEMKIND
859 #else
860  r = malloc(nSize);
861 #endif
862  return r;
863  }
864  void operator delete(void* p)
865  {
866 #ifdef VTK_USE_MEMKIND
867  VisitState* a = static_cast<VisitState*>(p);
868  if (a->IsInMemkind)
869  {
871  }
872  else
873  {
874  free(p);
875  }
876 #else
877  free(p);
878 #endif
879  }
880 
883 
884  private:
885  VisitState(const VisitState&) = delete;
886  VisitState& operator=(const VisitState&) = delete;
887  bool IsInMemkind = false;
888  };
889 
890 private: // Helpers that allow Visit to return a value:
891  template <typename Functor, typename... Args>
892  using GetReturnType = decltype(
893  std::declval<Functor>()(std::declval<VisitState<ArrayType32>&>(), std::declval<Args>()...));
894 
895  template <typename Functor, typename... Args>
896  struct ReturnsVoid : std::is_same<GetReturnType<Functor, Args...>, void>
897  {
898  };
899 
900 public:
970  template <typename Functor, typename... Args,
971  typename = typename std::enable_if<ReturnsVoid<Functor, Args...>::value>::type>
972  void Visit(Functor&& functor, Args&&... args)
973  {
974  if (this->Storage.Is64Bit())
975  {
976  // If you get an error on the next line, a call to Visit(functor, Args...)
977  // is being called with arguments that do not match the functor's call
978  // signature. See the Visit documentation for details.
979  functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
980  }
981  else
982  {
983  // If you get an error on the next line, a call to Visit(functor, Args...)
984  // is being called with arguments that do not match the functor's call
985  // signature. See the Visit documentation for details.
986  functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
987  }
988  }
989 
990  template <typename Functor, typename... Args,
991  typename = typename std::enable_if<ReturnsVoid<Functor, Args...>::value>::type>
992  void Visit(Functor&& functor, Args&&... args) const
993  {
994  if (this->Storage.Is64Bit())
995  {
996  // If you get an error on the next line, a call to Visit(functor, Args...)
997  // is being called with arguments that do not match the functor's call
998  // signature. See the Visit documentation for details.
999  functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
1000  }
1001  else
1002  {
1003  // If you get an error on the next line, a call to Visit(functor, Args...)
1004  // is being called with arguments that do not match the functor's call
1005  // signature. See the Visit documentation for details.
1006  functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
1007  }
1008  }
1009 
1010  template <typename Functor, typename... Args,
1011  typename = typename std::enable_if<!ReturnsVoid<Functor, Args...>::value>::type>
1012  GetReturnType<Functor, Args...> Visit(Functor&& functor, Args&&... args)
1013  {
1014  if (this->Storage.Is64Bit())
1015  {
1016  // If you get an error on the next line, a call to Visit(functor, Args...)
1017  // is being called with arguments that do not match the functor's call
1018  // signature. See the Visit documentation for details.
1019  return functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
1020  }
1021  else
1022  {
1023  // If you get an error on the next line, a call to Visit(functor, Args...)
1024  // is being called with arguments that do not match the functor's call
1025  // signature. See the Visit documentation for details.
1026  return functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
1027  }
1028  }
1029  template <typename Functor, typename... Args,
1030  typename = typename std::enable_if<!ReturnsVoid<Functor, Args...>::value>::type>
1031  GetReturnType<Functor, Args...> Visit(Functor&& functor, Args&&... args) const
1032  {
1033  if (this->Storage.Is64Bit())
1034  {
1035  // If you get an error on the next line, a call to Visit(functor, Args...)
1036  // is being called with arguments that do not match the functor's call
1037  // signature. See the Visit documentation for details.
1038  return functor(this->Storage.GetArrays64(), std::forward<Args>(args)...);
1039  }
1040  else
1041  {
1042  // If you get an error on the next line, a call to Visit(functor, Args...)
1043  // is being called with arguments that do not match the functor's call
1044  // signature. See the Visit documentation for details.
1045  return functor(this->Storage.GetArrays32(), std::forward<Args>(args)...);
1046  }
1047  }
1048 
1051 #endif // __VTK_WRAP__
1052 
1053  //=================== Begin Legacy Methods ===================================
1054  // These should be deprecated at some point as they are confusing or very slow
1055 
1062  virtual void SetNumberOfCells(vtkIdType);
1063 
1075  vtkIdType EstimateSize(vtkIdType numCells, int maxPtsPerCell);
1076 
1085  vtkIdType GetSize();
1086 
1093  vtkIdType GetNumberOfConnectivityEntries();
1094 
1104  void GetCell(vtkIdType loc, vtkIdType& npts, const vtkIdType*& pts)
1105  VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries()) VTK_SIZEHINT(pts, npts);
1106 
1113  void GetCell(vtkIdType loc, vtkIdList* pts)
1114  VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries());
1115 
1122  vtkIdType GetInsertLocation(int npts);
1123 
1131  vtkIdType GetTraversalLocation();
1132  vtkIdType GetTraversalLocation(vtkIdType npts);
1133  void SetTraversalLocation(vtkIdType loc);
1143  void ReverseCell(vtkIdType loc) VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries());
1144 
1156  void ReplaceCell(vtkIdType loc, int npts, const vtkIdType pts[])
1157  VTK_EXPECTS(0 <= loc && loc < GetNumberOfConnectivityEntries()) VTK_SIZEHINT(pts, npts);
1158 
1173  void SetCells(vtkIdType ncells, vtkIdTypeArray* cells);
1174 
1186 
1187  //=================== End Legacy Methods =====================================
1188 
1189  friend class vtkCellArrayIterator;
1190 
1191 protected:
1192  vtkCellArray();
1193  ~vtkCellArray() override;
1194 
1195  // Encapsulates storage of the internal arrays as a discriminated union
1196  // between 32-bit and 64-bit storage.
1197  struct Storage
1198  {
1199  // Union type that switches 32 and 64 bit array storage
1200  union ArraySwitch {
1201  ArraySwitch() = default; // handled by Storage
1202  ~ArraySwitch() = default; // handle by Storage
1205  };
1206 
1208  {
1209 #ifdef VTK_USE_MEMKIND
1210  this->Arrays =
1212 #else
1213  this->Arrays = new ArraySwitch;
1214 #endif
1215 
1216  // Default to the compile-time setting:
1217 #ifdef VTK_USE_64BIT_IDS
1218 
1219  this->Arrays->Int64 = new VisitState<ArrayType64>;
1220  this->StorageIs64Bit = true;
1221 
1222 #else // VTK_USE_64BIT_IDS
1223 
1224  this->Arrays->Int32 = new VisitState<ArrayType32>;
1225  this->StorageIs64Bit = false;
1226 
1227 #endif // VTK_USE_64BIT_IDS
1228 #ifdef VTK_USE_MEMKIND
1230  {
1231  this->IsInMemkind = true;
1232  }
1233 #else
1234  (void)this->IsInMemkind; // comp warning workaround
1235 #endif
1236  }
1237 
1239  {
1240  if (this->StorageIs64Bit)
1241  {
1242  this->Arrays->Int64->~VisitState();
1243  delete this->Arrays->Int64;
1244  }
1245  else
1246  {
1247  this->Arrays->Int32->~VisitState();
1248  delete this->Arrays->Int32;
1249  }
1250 #ifdef VTK_USE_MEMKIND
1251  if (this->IsInMemkind)
1252  {
1254  }
1255  else
1256  {
1257  free(this->Arrays);
1258  }
1259 #else
1260  delete this->Arrays;
1261 #endif
1262  }
1263 
1264  // Switch the internal arrays to be 32-bit. Any old data is lost. Returns
1265  // true if the storage changes.
1267  {
1268  if (!this->StorageIs64Bit)
1269  {
1270  return false;
1271  }
1272 
1273  this->Arrays->Int64->~VisitState();
1274  delete this->Arrays->Int64;
1275  this->Arrays->Int32 = new VisitState<ArrayType32>;
1276  this->StorageIs64Bit = false;
1277 
1278  return true;
1279  }
1280 
1281  // Switch the internal arrays to be 64-bit. Any old data is lost. Returns
1282  // true if the storage changes.
1284  {
1285  if (this->StorageIs64Bit)
1286  {
1287  return false;
1288  }
1289 
1290  this->Arrays->Int32->~VisitState();
1291  delete this->Arrays->Int32;
1292  this->Arrays->Int64 = new VisitState<ArrayType64>;
1293  this->StorageIs64Bit = true;
1294 
1295  return true;
1296  }
1297 
1298  // Returns true if the storage is currently configured to be 64 bit.
1299  bool Is64Bit() const { return this->StorageIs64Bit; }
1300 
1301  // Get the VisitState for 32-bit arrays
1303  {
1304  assert(!this->StorageIs64Bit);
1305  return *this->Arrays->Int32;
1306  }
1307 
1309  {
1310  assert(!this->StorageIs64Bit);
1311  return *this->Arrays->Int32;
1312  }
1313 
1314  // Get the VisitState for 64-bit arrays
1316  {
1317  assert(this->StorageIs64Bit);
1318  return *this->Arrays->Int64;
1319  }
1320 
1322  {
1323  assert(this->StorageIs64Bit);
1324  return *this->Arrays->Int64;
1325  }
1326 
1327  private:
1328  // Access restricted to ensure proper union construction/destruction thru
1329  // API.
1330  ArraySwitch* Arrays;
1331  bool StorageIs64Bit;
1332  bool IsInMemkind = false;
1333  };
1334 
1337  vtkIdType TraversalCellId{ 0 };
1338 
1340 
1341 private:
1342  vtkCellArray(const vtkCellArray&) = delete;
1343  void operator=(const vtkCellArray&) = delete;
1344 };
1345 
1346 template <typename ArrayT>
1348 {
1349  return this->Offsets->GetNumberOfValues() - 1;
1350 }
1351 
1352 template <typename ArrayT>
1354 {
1355  return static_cast<vtkIdType>(this->Offsets->GetValue(cellId));
1356 }
1357 
1358 template <typename ArrayT>
1360 {
1361  return static_cast<vtkIdType>(this->Offsets->GetValue(cellId + 1));
1362 }
1363 
1364 template <typename ArrayT>
1366 {
1367  return this->GetEndOffset(cellId) - this->GetBeginOffset(cellId);
1368 }
1369 
1370 template <typename ArrayT>
1373 {
1374  return vtk::DataArrayValueRange<1>(
1375  this->GetConnectivity(), this->GetBeginOffset(cellId), this->GetEndOffset(cellId));
1376 }
1377 
1379 {
1380 
1382 {
1383  // Insert full cell
1384  template <typename CellStateT>
1385  vtkIdType operator()(CellStateT& state, const vtkIdType npts, const vtkIdType pts[])
1386  {
1387  using ValueType = typename CellStateT::ValueType;
1388  auto* conn = state.GetConnectivity();
1389  auto* offsets = state.GetOffsets();
1390 
1391  const vtkIdType cellId = offsets->GetNumberOfValues() - 1;
1392 
1393  offsets->InsertNextValue(static_cast<ValueType>(conn->GetNumberOfValues() + npts));
1394 
1395  for (vtkIdType i = 0; i < npts; ++i)
1396  {
1397  conn->InsertNextValue(static_cast<ValueType>(pts[i]));
1398  }
1399 
1400  return cellId;
1401  }
1402 
1403  // Just update offset table (for incremental API)
1404  template <typename CellStateT>
1405  vtkIdType operator()(CellStateT& state, const vtkIdType npts)
1406  {
1407  using ValueType = typename CellStateT::ValueType;
1408  auto* conn = state.GetConnectivity();
1409  auto* offsets = state.GetOffsets();
1410 
1411  const vtkIdType cellId = offsets->GetNumberOfValues() - 1;
1412 
1413  offsets->InsertNextValue(static_cast<ValueType>(conn->GetNumberOfValues() + npts));
1414 
1415  return cellId;
1416  }
1417 };
1418 
1419 // for incremental API:
1421 {
1422  template <typename CellStateT>
1423  void operator()(CellStateT& state, const vtkIdType npts)
1424  {
1425  using ValueType = typename CellStateT::ValueType;
1426 
1427  auto* offsets = state.GetOffsets();
1428  const ValueType cellBegin = offsets->GetValue(offsets->GetMaxId() - 1);
1429  offsets->SetValue(offsets->GetMaxId(), static_cast<ValueType>(cellBegin + npts));
1430  }
1431 };
1432 
1434 {
1435  template <typename CellStateT>
1436  vtkIdType operator()(CellStateT& state, const vtkIdType cellId)
1437  {
1438  return state.GetCellSize(cellId);
1439  }
1440 };
1441 
1443 {
1444  template <typename CellStateT>
1445  void operator()(CellStateT& state, const vtkIdType cellId, vtkIdList* ids)
1446  {
1447  using ValueType = typename CellStateT::ValueType;
1448 
1449  const auto cellPts = state.GetCellRange(cellId);
1450 
1451  ids->SetNumberOfIds(cellPts.size());
1452  vtkIdType* idPtr = ids->GetPointer(0);
1453 
1454  for (ValueType ptId : cellPts)
1455  {
1456  *idPtr++ = static_cast<vtkIdType>(ptId);
1457  }
1458  }
1459 
1460  // SFINAE helper to check if a VisitState's connectivity array's memory
1461  // can be used as a vtkIdType*.
1462  template <typename CellStateT>
1464  {
1465  private:
1466  using ValueType = typename CellStateT::ValueType;
1467  using ArrayType = typename CellStateT::ArrayType;
1469  static constexpr bool ValueTypeCompat = CellStateT::ValueTypeIsSameAsIdType;
1470  static constexpr bool ArrayTypeCompat = std::is_base_of<AOSArrayType, ArrayType>::value;
1471 
1472  public:
1473  static constexpr bool value = ValueTypeCompat && ArrayTypeCompat;
1474  };
1475 
1476  template <typename CellStateT>
1478  CellStateT& state, const vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints,
1479  vtkIdList* vtkNotUsed(temp))
1480  {
1481  const vtkIdType beginOffset = state.GetBeginOffset(cellId);
1482  const vtkIdType endOffset = state.GetEndOffset(cellId);
1483  cellSize = endOffset - beginOffset;
1484  // This is safe, see CanShareConnPtr helper above.
1485  cellPoints = reinterpret_cast<vtkIdType*>(state.GetConnectivity()->GetPointer(beginOffset));
1486  }
1487 
1488  template <typename CellStateT>
1490  CellStateT& state, const vtkIdType cellId, vtkIdType& cellSize, vtkIdType const*& cellPoints,
1491  vtkIdList* temp)
1492  {
1493  using ValueType = typename CellStateT::ValueType;
1494 
1495  const auto cellPts = state.GetCellRange(cellId);
1496  cellSize = cellPts.size();
1497 
1498  // ValueType differs from vtkIdType, so we have to copy into a temporary
1499  // buffer:
1500  temp->SetNumberOfIds(cellSize);
1501  vtkIdType* tempPtr = temp->GetPointer(0);
1502  for (ValueType ptId : cellPts)
1503  {
1504  *tempPtr++ = static_cast<vtkIdType>(ptId);
1505  }
1506 
1507  cellPoints = temp->GetPointer(0);
1508  }
1509 };
1510 
1512 {
1513  template <typename CellStateT>
1514  void operator()(CellStateT& state)
1515  {
1516  state.GetOffsets()->Reset();
1517  state.GetConnectivity()->Reset();
1518  state.GetOffsets()->InsertNextValue(0);
1519  }
1520 };
1521 
1522 } // end namespace vtkCellArray_detail
1523 
1524 //----------------------------------------------------------------------------
1526 {
1527  this->TraversalCellId = 0;
1528 }
1529 
1530 //----------------------------------------------------------------------------
1531 inline int vtkCellArray::GetNextCell(vtkIdType& npts, vtkIdType const*& pts) VTK_SIZEHINT(pts, npts)
1532 {
1533  if (this->TraversalCellId < this->GetNumberOfCells())
1534  {
1535  this->GetCellAtId(this->TraversalCellId, npts, pts);
1536  ++this->TraversalCellId;
1537  return 1;
1538  }
1539 
1540  npts = 0;
1541  pts = nullptr;
1542  return 0;
1543 }
1544 
1545 //----------------------------------------------------------------------------
1547 {
1548  if (this->TraversalCellId < this->GetNumberOfCells())
1549  {
1550  this->GetCellAtId(this->TraversalCellId, pts);
1551  ++this->TraversalCellId;
1552  return 1;
1553  }
1554 
1555  pts->Reset();
1556  return 0;
1557 }
1558 //----------------------------------------------------------------------------
1560 {
1561  return this->Visit(vtkCellArray_detail::GetCellSizeImpl{}, cellId);
1562 }
1563 
1564 //----------------------------------------------------------------------------
1565 inline void vtkCellArray::GetCellAtId(vtkIdType cellId, vtkIdType& cellSize,
1566  vtkIdType const*& cellPoints) VTK_SIZEHINT(cellPoints, cellSize)
1567 {
1568  this->Visit(vtkCellArray_detail::GetCellAtIdImpl{}, cellId, cellSize, cellPoints, this->TempCell);
1569 }
1570 
1571 //----------------------------------------------------------------------------
1572 inline void vtkCellArray::GetCellAtId(vtkIdType cellId, vtkIdType& cellSize,
1573  vtkIdType const*& cellPoints, vtkIdList* ptIds) VTK_SIZEHINT(cellPoints, cellSize)
1574 {
1575  this->Visit(vtkCellArray_detail::GetCellAtIdImpl{}, cellId, cellSize, cellPoints, ptIds);
1576 }
1577 
1578 //----------------------------------------------------------------------------
1580 {
1581  this->Visit(vtkCellArray_detail::GetCellAtIdImpl{}, cellId, pts);
1582 }
1583 
1584 //----------------------------------------------------------------------------
1586  VTK_SIZEHINT(pts, npts)
1587 {
1588  return this->Visit(vtkCellArray_detail::InsertNextCellImpl{}, npts, pts);
1589 }
1590 
1591 //----------------------------------------------------------------------------
1593 {
1594  return this->Visit(vtkCellArray_detail::InsertNextCellImpl{}, npts);
1595 }
1596 
1597 //----------------------------------------------------------------------------
1599 {
1600  if (this->Storage.Is64Bit())
1601  {
1602  using ValueType = typename ArrayType64::ValueType;
1603  this->Storage.GetArrays64().Connectivity->InsertNextValue(static_cast<ValueType>(id));
1604  }
1605  else
1606  {
1607  using ValueType = typename ArrayType32::ValueType;
1608  this->Storage.GetArrays32().Connectivity->InsertNextValue(static_cast<ValueType>(id));
1609  }
1610 }
1611 
1612 //----------------------------------------------------------------------------
1613 inline void vtkCellArray::UpdateCellCount(int npts)
1614 {
1616 }
1617 
1618 //----------------------------------------------------------------------------
1620 {
1621  return this->Visit(
1623 }
1624 
1625 //----------------------------------------------------------------------------
1627 {
1628  vtkIdList* pts = cell->GetPointIds();
1629  return this->Visit(
1631 }
1632 
1633 //----------------------------------------------------------------------------
1634 inline void vtkCellArray::Reset()
1635 {
1637 }
1638 
1639 #endif // vtkCellArray.h
ArrayType64 * GetConnectivityArray64()
Return the array used to store the point ids that define the cells' connectivity. ...
Definition: vtkCellArray.h:548
vtkTypeBool Allocate(vtkIdType sz, vtkIdType vtkNotUsed(ext)=1000)
Allocate memory.
Definition: vtkCellArray.h:233
ArrayType32 * GetConnectivityArray32()
Return the array used to store the point ids that define the cells' connectivity. ...
Definition: vtkCellArray.h:547
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:536
static vtkFreeingFunction GetAlternateFreeFunction()
ArrayType * GetConnectivity()
Definition: vtkCellArray.h:827
abstract base class for most VTK objects
Definition: vtkObject.h:62
Remove all duplicate types from TypeList TList, storing the new list in Result.
Definition: vtkTypeList.h:126
decltype(vtk::DataArrayValueRange< 1 >(std::declval< ArrayType >())) CellRangeType
Definition: vtkCellArray.h:814
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:450
vtkIdType operator()(CellStateT &state, const vtkIdType cellId)
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:320
void Reset()
Reset to an empty state but retain previously allocated memory.
Definition: vtkIdList.h:148
void InitTraversal()
vtkSmartPointer< ArrayType > Connectivity
Definition: vtkCellArray.h:881
const ArrayType * GetOffsets() const
Definition: vtkCellArray.h:825
vtkTypeList::Create< ArrayType32, ArrayType64 > StorageArrayList
List of possible array types used for storage.
Definition: vtkCellArray.h:211
ArrayType32 * GetOffsetsArray32()
Return the array used to store cell offsets.
Definition: vtkCellArray.h:526
dynamic, self-adjusting array of vtkIdType
int vtkIdType
Definition: vtkType.h:332
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
vtkIdType TraversalCellId
const ArrayType * GetConnectivity() const
Definition: vtkCellArray.h:828
typename vtkTypeList::detail::CreateImpl< Ts... >::type Create
Definition: vtkTypeList.h:177
bool AllocateCopy(vtkCellArray *other)
Pre-allocate memory in internal data structures to match the used size of the input vtkCellArray...
Definition: vtkCellArray.h:272
int vtkTypeBool
Definition: vtkABI.h:69
vtkNew< vtkIdList > TempCell
abstract class to specify cell behavior
Definition: vtkCell.h:60
static constexpr bool ValueTypeIsSameAsIdType
Definition: vtkCellArray.h:821
void Reset()
Reuse list.
void operator()(CellStateT &state, const vtkIdType npts)
a simple class to control print indentation
Definition: vtkIndent.h:39
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:33
vtkIdType GetOffset(vtkIdType cellId)
Get the offset (into the connectivity) for a specified cell id.
Definition: vtkCellArray.h:351
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:55
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:223
vtkIdType GetNumberOfConnectivityIds() const
Get the size of the connectivity array that stores the point ids.
Definition: vtkCellArray.h:369
vtkTypeInt64Array ArrayType64
Definition: vtkCellArray.h:190
vtkIdType GetNumberOfIds() const noexcept
Return the number of id's in the list.
Definition: vtkIdList.h:60
bool Is64Bit() const
vtkIdType GetEndOffset(vtkIdType cellId) const
#define VTK_SIZEHINT(...)
bool IsStorage64Bit() const
Definition: vtkCellArray.h:442
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 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:882
void Visit(Functor &&functor, Args &&...args)
Definition: vtkCellArray.h:972
VisitState< ArrayType64 > & GetArrays64()
vtkDataArray * GetOffsetsArray()
Return the array used to store cell offsets.
Definition: vtkCellArray.h:515
object to represent cell connectivity
Definition: vtkCellArray.h:186
vtkTypeInt32Array ArrayType32
Definition: vtkCellArray.h:189
ArrayType * GetOffsets()
Definition: vtkCellArray.h:824
typename ArrayType::ValueType ValueType
Definition: vtkCellArray.h:813
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:527
vtkIdList * GetPointIds()
Return the list of point ids defining the cell.
Definition: vtkCell.h:156
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
vtkIdType * GetPointer(const vtkIdType i)
Get a pointer to a particular data index.
Definition: vtkIdList.h:129
vtkIdType GetCellSize(const vtkIdType cellId) const
Return the size of the cell at cellId.
Encapsulate traversal logic for vtkCellArray.
Storage Storage
void Visit(Functor &&functor, Args &&...args) const
Definition: vtkCellArray.h:992
vtkIdType GetNumberOfOffsets() const
Get the number of elements in the offsets array.
Definition: vtkCellArray.h:336
void SetNumberOfIds(const vtkIdType number)
Specify the number of ids for this object to hold.
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:247
int GetNextCell(vtkIdType &npts, vtkIdType const *&pts)
const VisitState< ArrayType64 > & GetArrays64() const