VTK  9.7.20260915
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
53
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
69VTK_ABI_NAMESPACE_BEGIN
70template <typename TId, typename TED>
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
139template <typename IDType, typename EdgeData>
141{
142public:
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
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
263protected:
265
266 // Support BuildLocator usage pattern
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
284 std::vector<IDType> MergeOffsets;
285
286private:
288 void operator=(const vtkStaticEdgeLocatorTemplate&) = delete;
289};
290
291VTK_ABI_NAMESPACE_END
292#include "vtkStaticEdgeLocatorTemplate.txx"
293
294#endif
295// VTK-HeaderTest-Exclude: vtkStaticEdgeLocatorTemplate.h
IDType V0Range
Some convenient typedefs.
IDType MinV0
Some convenient typedefs.
vtkIdType NumEdgesPerBin
Some convenient typedefs.
IDType * EdgeOffsets
Some convenient typedefs.
const IDType * MergeEdges(vtkIdType numEdges, EdgeTupleType *edgeArray, vtkIdType &numUniqueEdges)
This method sorts (in place) an array of EdgeTupleType (of length numEdges) into separate groups,...
IDType GetNumberOfEdgesInBin(IDType bin) const
Some convenient typedefs.
IDType MaxV0
Some convenient typedefs.
~vtkStaticEdgeLocatorTemplate()
Delete internal offset array.
IDType IsInsertedEdge(IDType v0, IDType v1) const
Return the id of the edge indicated.
std::vector< IDType > MergeOffsets
Some convenient typedefs.
IDType HashBin(IDType v) const
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 BuildLocator(vtkIdType numEdges, EdgeTupleType *edgeArray)
This method constructs the edge locator to be used when searching for edges.
vtkIdType NumEdges
Some convenient typedefs.
EdgeTupleType * EdgeArray
Some convenient typedefs.
EdgeTuple< IDType, EdgeData > EdgeTupleType
Some convenient typedefs.
EdgeTupleType * MergeArray
Some convenient typedefs.
Definition of an edge tuple.
bool IsEdge(TId v0, TId v1) const
bool operator==(const EdgeTuple &et) const
EdgeTuple(TId v0, TId v1, TED data)
EdgeTuple()=default
bool operator<(const EdgeTuple &tup) const
bool operator!=(const EdgeTuple &et) const
void Define(TId v0, TId v1)
int vtkIdType
Definition vtkType.h:363