VTK  9.2.6
vtkPolyDataInternals.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkPolyDataInternals.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 =========================================================================*/
15 
57 #ifndef vtkPolyDataInternals_h
58 #define vtkPolyDataInternals_h
59 
60 #include "vtkCommonDataModelModule.h" // For export macro
61 
62 #include "vtkCellType.h"
63 #include "vtkObject.h"
64 #include "vtkType.h"
65 
66 #include <cstdlib> // for std::size_t
67 #include <vector> // for CellMap implementation.
68 
70 {
71 
72 static constexpr vtkTypeUInt64 CELLID_MASK = 0x0fffffffffffffffull;
73 static constexpr vtkTypeUInt64 SHIFTED_TYPE_INDEX_MASK = 0xf000000000000000ull;
74 static constexpr vtkTypeUInt64 TARGET_MASK = 0x3ull << 62;
75 static constexpr vtkTypeUInt64 TYPE_VARIANT_MASK = 0x3ull << 60;
76 
77 // Enumeration of internal cell array targets.
78 enum class Target : vtkTypeUInt64
79 {
80  Verts = 0x0ull << 62,
81  Lines = 0x1ull << 62,
82  Polys = 0x2ull << 62,
83  Strips = 0x3ull << 62,
84 };
85 
86 // Enumeration of type variants.
87 enum class TypeVariant : vtkTypeUInt64
88 {
89  Dead = 0x0ull << 60,
90  Var1 = 0x1ull << 60,
91  Var2 = 0x2ull << 60,
92  Var3 = 0x3ull << 60,
93 };
94 
95 // Lookup table to convert a type index (TaggedCellId.GetTypeIndex()) into
96 // a VTK cell type.
97 // The type index is the highest four bits of the encoded value, eg. the
98 // target and type variant information.
99 static constexpr unsigned char TypeTable[16] = {
100  VTK_EMPTY_CELL, // 0000b | Verts | Dead
101  VTK_VERTEX, // 0001b | Verts | Var1
102  VTK_POLY_VERTEX, // 0010b | Verts | Var2
103  VTK_EMPTY_CELL, // 0011b | Verts | Var3
104  VTK_EMPTY_CELL, // 0100b | Lines | Dead
105  VTK_LINE, // 0101b | Lines | Var1
106  VTK_POLY_LINE, // 0110b | Lines | Var2
107  VTK_EMPTY_CELL, // 0111b | Lines | Var3
108  VTK_EMPTY_CELL, // 1000b | Polys | Dead
109  VTK_TRIANGLE, // 1001b | Polys | Var1
110  VTK_QUAD, // 1010b | Polys | Var2
111  VTK_POLYGON, // 1011b | Polys | Var3
112  VTK_EMPTY_CELL, // 1100b | Strips | Dead
113  VTK_TRIANGLE_STRIP, // 1101b | Strips | Var1
114  VTK_EMPTY_CELL, // 1110b | Strips | Var2
115  VTK_EMPTY_CELL, // 1111b | Strips | Var3
116 };
117 
118 // Convenience method to concatenate a target and type variant into the low
119 // four bits of a single byte. Used to build the TargetVarTable.
120 static constexpr unsigned char GenTargetVar(Target target, TypeVariant var) noexcept
121 {
122  return static_cast<unsigned char>(
123  (static_cast<vtkTypeUInt64>(target) | static_cast<vtkTypeUInt64>(var)) >> 60);
124 }
125 
126 // Lookup table that maps a VTK cell type (eg. VTK_TRIANGLE) into a target +
127 // type variant byte.
128 static constexpr unsigned char TargetVarTable[10] = {
129  GenTargetVar(Target::Verts, TypeVariant::Dead), // 0 | VTK_EMPTY_CELL
130  GenTargetVar(Target::Verts, TypeVariant::Var1), // 1 | VTK_VERTEX
131  GenTargetVar(Target::Verts, TypeVariant::Var2), // 2 | VTK_POLY_VERTEX
132  GenTargetVar(Target::Lines, TypeVariant::Var1), // 3 | VTK_LINE
133  GenTargetVar(Target::Lines, TypeVariant::Var2), // 4 | VTK_POLY_LINE
134  GenTargetVar(Target::Polys, TypeVariant::Var1), // 5 | VTK_TRIANGLE
135  GenTargetVar(Target::Strips, TypeVariant::Var1), // 6 | VTK_TRIANGLE_STRIP
136  GenTargetVar(Target::Polys, TypeVariant::Var3), // 7 | VTK_POLYGON
137  GenTargetVar(Target::Polys, TypeVariant::Var2), // 8 | VTK_PIXEL (treat as quad)
138  GenTargetVar(Target::Polys, TypeVariant::Var2), // 9 | VTK_QUAD
139 };
140 
141 // Thin wrapper around a vtkTypeUInt64 that encodes a target cell array,
142 // cell type, deleted status, and 60-bit cell id.
143 struct VTKCOMMONDATAMODEL_EXPORT TaggedCellId
144 {
145  // Encode a cell id and a VTK cell type (eg. VTK_TRIANGLE) into a
146  // vtkTypeUInt64.
147  static vtkTypeUInt64 Encode(vtkIdType cellId, VTKCellType type) noexcept
148  {
149  const size_t typeIndex = static_cast<size_t>(type);
150  return ((static_cast<vtkTypeUInt64>(cellId) & CELLID_MASK) |
151  (static_cast<vtkTypeUInt64>(TargetVarTable[typeIndex]) << 60));
152  }
153 
154  TaggedCellId() noexcept = default;
155 
156  // Create a TaggedCellId from a cellId and cell type (e.g. VTK_TRIANGLE).
157  TaggedCellId(vtkIdType cellId, VTKCellType cellType) noexcept
158  : Value(Encode(cellId, cellType))
159  {
160  }
161 
162  TaggedCellId(const TaggedCellId&) noexcept = default;
163  TaggedCellId(TaggedCellId&&) noexcept = default;
164  TaggedCellId& operator=(const TaggedCellId&) noexcept = default;
165  TaggedCellId& operator=(TaggedCellId&&) noexcept = default;
166 
167  // Get an enum value describing the internal vtkCellArray target used to
168  // store this cell.
169  Target GetTarget() const noexcept { return static_cast<Target>(this->Value & TARGET_MASK); }
170 
171  // Get the VTK cell type value (eg. VTK_TRIANGLE) as a single byte.
172  unsigned char GetCellType() const noexcept { return TypeTable[this->GetTypeIndex()]; }
173 
174  // Get the cell id used by the target vtkCellArray to store this cell.
175  vtkIdType GetCellId() const noexcept { return static_cast<vtkIdType>(this->Value & CELLID_MASK); }
176 
177  // Update the cell id. Most useful with the CellMap::InsertNextCell(type)
178  // signature.
179  void SetCellId(vtkIdType cellId) noexcept
180  {
181  this->Value &= SHIFTED_TYPE_INDEX_MASK;
182  this->Value |= (static_cast<vtkTypeUInt64>(cellId) & CELLID_MASK);
183  }
184 
185  // Mark this cell as deleted.
186  void MarkDeleted() noexcept { this->Value &= ~TYPE_VARIANT_MASK; }
187 
188  // Returns true if the cell has been deleted.
189  bool IsDeleted() const noexcept { return (this->Value & TYPE_VARIANT_MASK) == 0; }
190 
191 private:
192  vtkTypeUInt64 Value;
193 
194  // These shouldn't be needed outside of this struct. You're probably looking
195  // for GetCellType() instead.
196  TypeVariant GetTypeVariant() const noexcept
197  {
198  return static_cast<TypeVariant>(this->Value & TYPE_VARIANT_MASK);
199  }
200  std::size_t GetTypeIndex() const noexcept { return static_cast<std::size_t>(this->Value >> 60); }
201 };
202 
203 // Thin wrapper around a std::vector<TaggedCellId> to allow shallow copying, etc
204 class VTKCOMMONDATAMODEL_EXPORT CellMap : public vtkObject
205 {
206 public:
207  static CellMap* New();
208  vtkTypeMacro(CellMap, vtkObject);
209 
210  static bool ValidateCellType(VTKCellType cellType) noexcept
211  {
212  // 1-9 excluding 8 (VTK_PIXEL):
213  return cellType > 0 && cellType <= 10 && cellType != VTK_PIXEL;
214  }
215 
216  static bool ValidateCellId(vtkIdType cellId) noexcept
217  {
218  // is positive, won't truncate:
219  return (
220  (static_cast<vtkTypeUInt64>(cellId) & CELLID_MASK) == static_cast<vtkTypeUInt64>(cellId));
221  }
222 
223  void DeepCopy(CellMap* other)
224  {
225  if (other)
226  {
227  this->Map = other->Map;
228  }
229  else
230  {
231  this->Map.clear();
232  }
233  }
234 
235  void SetCapacity(vtkIdType numCells) { this->Map.reserve(static_cast<std::size_t>(numCells)); }
236 
237  TaggedCellId& GetTag(vtkIdType cellId) { return this->Map[static_cast<std::size_t>(cellId)]; }
238 
239  const TaggedCellId& GetTag(vtkIdType cellId) const
240  {
241  return this->Map[static_cast<std::size_t>(cellId)];
242  }
243 
244  // Caller must ValidateCellType first.
245  void InsertNextCell(vtkIdType cellId, VTKCellType cellType)
246  {
247  this->Map.emplace_back(cellId, cellType);
248  }
249 
250  // Caller must ValidateCellType and ValidateCellId first.
251  // useful for reusing the target lookup from cellType and then calling
252  // TaggedCellId::SetCellId later.
254  {
255  this->Map.emplace_back(vtkIdType(0), cellType);
256  return this->Map.back();
257  }
258 
259  vtkIdType GetNumberOfCells() const { return static_cast<vtkIdType>(this->Map.size()); }
260 
261  void Reset() { this->Map.clear(); }
262 
263  void Squeeze()
264  {
265  this->Map.shrink_to_fit(); // yaaaaay c++11
266  }
267 
268  // In rounded-up kibibytes, as is VTK's custom:
269  unsigned long GetActualMemorySize() const
270  {
271  return static_cast<unsigned long>(sizeof(TaggedCellId) * this->Map.capacity() + 1023) / 1024;
272  }
273 
274 protected:
275  CellMap();
276  ~CellMap() override;
277 
278  std::vector<TaggedCellId> Map;
279 
280 private:
281  CellMap(const CellMap&) = delete;
282  CellMap& operator=(const CellMap&) = delete;
283 };
284 
285 } // end namespace vtkPolyData_detail
286 
287 #endif // vtkPolyDataInternals.h
288 
289 // VTK-HeaderTest-Exclude: vtkPolyDataInternals.h
static constexpr unsigned char GenTargetVar(Target target, TypeVariant var) noexcept
const TaggedCellId & GetTag(vtkIdType cellId) const
abstract base class for most VTK objects
Definition: vtkObject.h:62
void SetCapacity(vtkIdType numCells)
static constexpr vtkTypeUInt64 CELLID_MASK
unsigned char GetCellType() const noexcept
static constexpr vtkTypeUInt64 TYPE_VARIANT_MASK
TaggedCellId & InsertNextCell(VTKCellType cellType)
static bool ValidateCellId(vtkIdType cellId) noexcept
void SetCellId(vtkIdType cellId) noexcept
int vtkIdType
Definition: vtkType.h:332
VTKCellType
Definition: vtkCellType.h:43
void InsertNextCell(vtkIdType cellId, VTKCellType cellType)
unsigned long GetActualMemorySize() const
boost::graph_traits< vtkGraph * >::vertex_descriptor target(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
TaggedCellId & GetTag(vtkIdType cellId)
static constexpr vtkTypeUInt64 TARGET_MASK
static vtkTypeUInt64 Encode(vtkIdType cellId, VTKCellType type) noexcept
std::vector< TaggedCellId > Map
static constexpr vtkTypeUInt64 SHIFTED_TYPE_INDEX_MASK
static constexpr unsigned char TargetVarTable[10]
static constexpr unsigned char TypeTable[16]
static bool ValidateCellType(VTKCellType cellType) noexcept
vtkIdType GetCellId() const noexcept