20 #ifndef MIRTK_EdgeTable_H 21 #define MIRTK_EdgeTable_H 23 #include "mirtk/SparseMatrix.h" 25 #include "mirtk/Memory.h" 26 #include "mirtk/Parallel.h" 28 #include "vtkSmartPointer.h" 29 #include "vtkDataSet.h" 49 mirtkReadOnlyAttributeMacro(vtkSmartPointer<vtkDataSet>, Mesh);
81 template <
class IdType1,
class IdType2>
82 bool IsEdge(IdType1, IdType2)
const;
87 template <
class IdType1,
class IdType2>
88 int EdgeId(IdType1, IdType2)
const;
91 template <
class EdgeIdType,
class IdType1,
class IdType2>
92 bool GetEdge(EdgeIdType, IdType1 &ptId1, IdType2 &ptId2)
const;
95 template <
class IdType>
119 template <
class IdType1,
class IdType2>
122 return static_cast<bool>(
Get(static_cast<int>(ptId1), static_cast<int>(ptId2)));
126 template <
class IdType1,
class IdType2>
129 return Get(static_cast<int>(ptId1), static_cast<int>(ptId2)) - 1;
133 template <
class EdgeIdType,
class IdType1,
class IdType2>
136 const int eid =
static_cast<int>(edgeId) + 1;
137 if (eid <= 0)
return false;
140 const int *row =
_Row;
141 const int *col =
_Col;
142 if (_Layout == CRS) swap(row, col);
145 for (ptId2 = 0; ptId2 < npoints; ++ptId2) {
146 for (i = col[ptId2], j = col[ptId2 + 1]; i < j; ++i) {
147 ptId1 =
static_cast<IdType1
>(row[i]);
148 if (
_Data[i] == eid)
return true;
149 if (ptId1 > ptId2)
break;
153 ptId1 =
static_cast<IdType1
>(-1);
154 ptId2 =
static_cast<IdType2
>(-1);
159 template <
class IdType>
162 if (_Layout == CCS) {
172 if (_Layout == CCS) {
173 numAdjPts =
_Col[ptId+1] -
_Col[ptId];
174 adjPtIds =
_Row + _Col[ptId];
176 numAdjPts =
_Row[ptId+1] -
_Row[ptId];
177 adjPtIds =
_Col + _Row[ptId];
184 if (_Layout == CCS) {
186 end =
_Row + _Col[ptId + 1];
189 end =
_Col + _Row[ptId + 1];
205 const int *_PointId1;
214 _Table(table), _EdgeId(-1), _EndId(-1),
215 _PointId1(NULL), _ListEnd(NULL), _PointId2(-1)
223 InitTraversal(begin, end);
237 _EndId = ((end < 0 || end > _Table.NumberOfEdges()) ? _Table.NumberOfEdges() : end);
238 if (_EndId > _EdgeId) {
239 for (_PointId2 = 0; _PointId2 < _Table.
NumberOfPoints(); ++_PointId2) {
241 while (_PointId1 != _ListEnd) {
242 if (*_PointId1 > _PointId2) {
243 _PointId1 = _ListEnd;
246 if (begin == 0)
break;
247 ++_PointId1, --begin;
249 if (begin == 0 && _PointId1 != _ListEnd)
break;
252 _PointId1 = _ListEnd = NULL;
258 template <
class IdType>
261 InitTraversal(static_cast<int>(re.begin()), static_cast<int>(re.end()));
270 template <
class IdType>
273 if (_EdgeId >= _EndId)
return -1;
274 ptId1 =
static_cast<IdType
>(*_PointId1);
275 ptId2 =
static_cast<IdType
>(_PointId2);
276 int edgeId = _EdgeId;
277 if (++_EdgeId < _EndId) {
278 if (++_PointId1 == _ListEnd || (*_PointId1) > _PointId2) {
281 }
while (_PointId1 == _ListEnd || (*_PointId1) > _PointId2);
291 #endif // MIRTK_EdgeTable_H
int GetNextEdge(IdType &ptId1, IdType &ptId2)
bool IsEdge(IdType1, IdType2) const
Determine whether two nodes are connected by an edge.
bool GetEdge(EdgeIdType, IdType1 &ptId1, IdType2 &ptId2) const
Get IDs of edge nodes (ptId1 < ptId2)
int NumberOfEdges(vtkDataSet *, const EdgeTable *=nullptr)
Number of edges.
int MaxNumberOfAdjacentPoints() const
Get maximum number of adjacent points.
EntryType Get(int, int=-1) const
Get value.
void InitTraversal(int begin=0, int end=-1)
int NumberOfPoints() const
Number of nodes.
virtual void Clear()
Clear edge table.
EntryType * _Data
Non-zero entries.
virtual ~EdgeTable()
Destructor.
void GetAdjacentPoints(int, int &, const int *&) const
Access list of adjacent nodes (thread-safe)
void InitTraversal(const blocked_range< IdType > &re)
Initialize traversal of edges in range.
EdgeIterator(const EdgeTable &table, int begin, int end=-1)
Constructor.
int EdgeId(IdType1, IdType2) const
void Initialize(vtkDataSet *)
Initialize edge table from given dataset.
int NumberOfAdjacentPoints(IdType) const
Get number of adjacent points.
EdgeIterator(const EdgeTable &table)
Constructor.
EdgeTable & operator=(const EdgeTable &)
Assignment operator.
EdgeTable(vtkDataSet *=nullptr)
Construct edge table for given dataset.