VTK  9.7.1
vtkStaticEdgeLocatorTemplate.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
54 #ifndef vtkStaticEdgeLocatorTemplate_h
55 #define vtkStaticEdgeLocatorTemplate_h
56 
57 #include "vtkABINamespace.h"
58 #include "vtkType.h" // For vtkIdType
59 
60 #include <algorithm>
61 #include <vector>
62 
69 VTK_ABI_NAMESPACE_BEGIN
70 template <typename TId, typename TED>
71 struct EdgeTuple
72 {
73  TId V0;
74  TId V1;
75  TED Data;
76 
77  // Default constructor - nothing needs to be done
78  EdgeTuple() = default;
79 
80  // Construct an edge and ensure that the edge tuple (vo,v1) is
81  // specified such that (v0<v1).
82  EdgeTuple(TId v0, TId v1, TED data)
83  : V0(v0)
84  , V1(v1)
85  , Data(data)
86  {
87  if (this->V0 > this->V1)
88  {
89  std::swap(this->V0, this->V1);
90  }
91  }
92 
93  void Define(TId v0, TId v1)
94  {
95  if (v0 < v1)
96  {
97  this->V0 = v0;
98  this->V1 = v1;
99  }
100  else
101  {
102  this->V0 = v1;
103  this->V1 = v0;
104  }
105  }
106 
107  bool operator==(const EdgeTuple& et) const { return this->V0 == et.V0 && this->V1 == et.V1; }
108 
109  bool operator!=(const EdgeTuple& et) const { return this->V0 != et.V0 || this->V1 != et.V1; }
110 
111  bool IsEdge(TId v0, TId v1) const
112  {
113  if (v0 < v1) // ordered properly
114  {
115  return this->V0 == v0 && this->V1 == v1;
116  }
117  else // swap comparison required
118  {
119  return this->V0 == v1 && this->V1 == v0;
120  }
121  }
122  // Sort on v0 first, then v1.
123  bool operator<(const EdgeTuple& tup) const
124  {
125  if (this->V0 < tup.V0)
126  return true;
127  if (tup.V0 < this->V0)
128  return false;
129  if (this->V1 < tup.V1)
130  return true;
131  return false;
132  }
133 };
134 
139 template <typename IDType, typename EdgeData>
141 {
142 public:
144 
149 
154  : NumEdges(0)
155  , NumEdgesPerBin(5)
156  , EdgeArray(nullptr)
157  , EdgeOffsets(nullptr)
158  , MinV0(-1)
159  , MaxV0(-1)
160  , V0Range(0)
161  , NDivs(0)
162  , MergeArray(nullptr)
163  {
164  }
165 
171 
175  IDType GetNumberOfEdges() { return this->NumEdges; }
176 
189  const IDType* MergeEdges(vtkIdType numEdges, EdgeTupleType* edgeArray, vtkIdType& numUniqueEdges);
190 
199  vtkIdType BuildLocator(vtkIdType numEdges, EdgeTupleType* edgeArray);
200 
207  IDType IsInsertedEdge(IDType v0, IDType v1) const
208  {
209  // Ensure that BuildLocator has been called by checking MinV0, MaxV0
210  if (this->MinV0 < 0 || this->MaxV0 < 0)
211  {
212  return -1;
213  }
214  // Ensure that data is consistent with what is expected.
215  if (v0 > v1)
216  {
217  std::swap(v0, v1);
218  }
219  if (v0 < this->MinV0 || v0 > this->MaxV0)
220  {
221  return -1;
222  }
223 
224  // Bin and search for matching edge. All edges sharing the vertex v0
225  // live in the same bin, so both scans below are bounded by the end of
226  // the bin: without the bound, a query absent from the locator could
227  // scan past the end of the edge array.
228  const IDType curBin = this->HashBin(v0);
229  const IDType num = this->GetNumberOfEdgesInBin(curBin);
230  // check if there are no edges
231  if (num < 1)
232  {
233  return -1;
234  }
235  IDType curId = this->EdgeOffsets[curBin];
236  const IDType binEnd = this->EdgeOffsets[curBin + 1];
237  while (curId < binEnd && this->EdgeArray[curId].V0 < v0)
238  {
239  curId++;
240  }
241  if (curId >= binEnd || this->EdgeArray[curId].V0 > v0)
242  {
243  return -1;
244  }
245  // matched v0, now find v1 among the edges sharing v0
246  while (curId < binEnd && this->EdgeArray[curId].V0 == v0 && this->EdgeArray[curId].V1 < v1)
247  {
248  curId++;
249  }
250  if (curId >= binEnd || this->EdgeArray[curId].V0 != v0 || this->EdgeArray[curId].V1 > v1)
251  {
252  return -1;
253  }
254  return curId;
255  }
256 
261  const EdgeTupleType& GetEdge(IDType i) const { return (*this->EdgeArray)[i]; }
262 
263 protected:
265 
266  // Support BuildLocator usage pattern
268  EdgeTupleType* EdgeArray;
269  IDType* EdgeOffsets;
270  IDType MinV0;
271  IDType MaxV0;
272  IDType V0Range;
273  int NDivs;
274 
275  IDType HashBin(IDType v) const { return ((v - this->MinV0) / this->NumEdgesPerBin); }
276 
277  IDType GetNumberOfEdgesInBin(IDType bin) const
278  {
279  return (this->EdgeOffsets[bin + 1] - this->EdgeOffsets[bin]);
280  }
281 
282  // Support MergeEdges usage pattern
283  EdgeTupleType* MergeArray;
284  std::vector<IDType> MergeOffsets;
285 
286 private:
288  void operator=(const vtkStaticEdgeLocatorTemplate&) = delete;
289 };
290 
291 VTK_ABI_NAMESPACE_END
292 #include "vtkStaticEdgeLocatorTemplate.txx"
293 
294 #endif
295 // VTK-HeaderTest-Exclude: vtkStaticEdgeLocatorTemplate.h
~vtkStaticEdgeLocatorTemplate()
Delete internal offset array.
bool IsEdge(TId v0, TId v1) const
IDType IsInsertedEdge(IDType v0, IDType v1) const
Return the id of the edge indicated.
Templated on types of ids defining an edge, and any data associated with the edge.
EdgeTuple()=default
const IDType * MergeEdges(vtkIdType numEdges, EdgeTupleType *edgeArray, vtkIdType &numUniqueEdges)
This method sorts (in place) an array of EdgeTupleType (of length numEdges) into separate groups...
void Define(TId v0, TId v1)
vtkIdType NumEdgesPerBin
Some convenient typedefs.
const EdgeTupleType & GetEdge(IDType i) const
Return the ith edge in the edge array.
IDType GetNumberOfEdges()
Return the number of edges in the edge array.
vtkIdType NumEdges
Some convenient typedefs.
bool operator<(const EdgeTuple &tup) const
int vtkIdType
Definition: vtkType.h:363
std::vector< IDType > MergeOffsets
Some convenient typedefs.
EdgeTuple< IDType, EdgeData > EdgeTupleType
Some convenient typedefs.
EdgeTupleType * EdgeArray
Some convenient typedefs.
EdgeTuple(TId v0, TId v1, TED data)
bool operator!=(const EdgeTuple &et) const
IDType MinV0
Some convenient typedefs.
vtkIdType BuildLocator(vtkIdType numEdges, EdgeTupleType *edgeArray)
This method constructs the edge locator to be used when searching for edges.
IDType GetNumberOfEdgesInBin(IDType bin) const
Some convenient typedefs.
EdgeTupleType * MergeArray
Some convenient typedefs.
bool operator==(const EdgeTuple &et) const
Definition of an edge tuple.
IDType * EdgeOffsets
Some convenient typedefs.
int NDivs
Some convenient typedefs.
IDType V0Range
Some convenient typedefs.
IDType HashBin(IDType v) const
Some convenient typedefs.
IDType MaxV0
Some convenient typedefs.