EdgeConnectivity.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_EdgeConnectivity_H
21 #define MIRTK_EdgeConnectivity_H
22 
23 #include "mirtk/SparseMatrix.h"
24 
25 #include "vtkDataSet.h"
26 
27 
28 namespace mirtk {
29 
30 
31 // Table of adjacent nodes
32 class EdgeTable;
33 
34 
35 /**
36  * Table of edge-connectivities / n-connected neighbors
37  *
38  * The entries of this sparse matrix represent the minimum number of edges
39  * that connect two given nodes. Unlike an EdgeTable, which stores a
40  * unique ID for each edge connecting adjacent nodes (1-connected), this
41  * table can be used to store a larger neighborhood of not only adjacent
42  * nodes. It can, however, not be used to iterate the edges/paths in a
43  * certain order. An irtkNeighborsTable is instead used to simply iterate
44  * over the n-connected neighbors of a given node, e.g., to compute the
45  * irtkMetricDistortion.
46  *
47  * Alternatively, this table can be used to query the edge-connectivity
48  * for every pair of mesh nodes. If two nodes are not connected,
49  # the edge-connectivity is zero.
50  */
52 {
53  mirtkObjectMacro(EdgeConnectivity);
54 
55  /// Maximum (considered) edge-connectivity
56  mirtkReadOnlyAttributeMacro(int, Maximum);
57 
58 public:
59 
60  /// Construct edge-connectivity table for given dataset
61  EdgeConnectivity(vtkDataSet * = nullptr, int n = 3, const EdgeTable * = nullptr);
62 
63  /// Construct edge-connectivity table for given dataset
64  EdgeConnectivity(vtkDataSet *, double r, const EdgeTable * = nullptr);
65 
66  /// Copy constructor
68 
69  /// Assignment operator
71 
72  /// Destructor
73  virtual ~EdgeConnectivity();
74 
75  /// Initialize edge-connectivity table from given dataset
76  void Initialize(vtkDataSet *, int n = 3, const EdgeTable * = nullptr);
77 
78  /// Initialize edge-connectivity table from given dataset
79  void Initialize(vtkDataSet *, double r, const EdgeTable * = nullptr);
80 
81  /// Clear edge-connectivity table
82  virtual void Clear();
83 
84  /// Number of nodes
85  int NumberOfPoints() const;
86 
87  /// Get number of nodes with edge-connectivity less or equal to n
88  int NumberOfConnectedPoints(int, int n = -1) const;
89 
90  /// Get number of adjacent nodes, i.e., nodes with edge-connectivity equal one
91  int NumberOfAdjacentPoints(int) const;
92 
93  /// Access list of nodes with edge-connectivity less or equal to n (thread-safe)
94  void GetConnectedPoints(int, int &, const int *&, int n = -1) const;
95 
96  /// Get start and end pointer into list of nodes with edge-connectivity
97  /// less or equal to n (thread-safe)
98  void GetConnectedPoints(int, const int *&, const int *&, int n = -1) const;
99 
100  /// Access list of adjacent (i.e. 1-connected) nodes (thread-safe)
101  void GetAdjacentPoints(int, int &, const int *&) const;
102 
103  /// Get start and end pointer into list of adjacent (i.e. 1-connected) nodes (thread-safe)
104  void GetAdjacentPoints(int, const int *&, const int *&) const;
105 };
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 // Inline definitions
109 ////////////////////////////////////////////////////////////////////////////////
110 
111 // -----------------------------------------------------------------------------
113 {
114  return Rows();
115 }
116 
117 // -----------------------------------------------------------------------------
118 inline int EdgeConnectivity::NumberOfConnectedPoints(int ptId, int n) const
119 {
120  if (n == 0) return 0;
121  if (n < 0 || n == _Maximum) {
122  if (_Layout == CCS) {
123  return _Col[ptId+1] - _Col[ptId];
124  } else {
125  return _Row[ptId+1] - _Row[ptId];
126  }
127  } else {
128  int count = 0;
129  if (_Layout == CCS) {
130  for (int i = _Col[ptId], j = _Col[ptId+1]; i != j; ++i) {
131  if (_Data[i] > n) break;
132  ++count;
133  }
134  } else {
135  for (int i = _Row[ptId], j = _Row[ptId+1]; i != j; ++i) {
136  if (_Data[i] > n) break;
137  ++count;
138  }
139  }
140  return count;
141  }
142 }
143 
144 // -----------------------------------------------------------------------------
146 {
147  return NumberOfConnectedPoints(ptId, 1);
148 }
149 
150 // -----------------------------------------------------------------------------
151 inline void EdgeConnectivity
152 ::GetConnectedPoints(int ptId, const int *&begin, const int *&end, int n) const
153 {
154  if (n == 0) {
155  if (_Layout == CCS) {
156  begin = end = _Row;
157  } else {
158  begin = end = _Col;
159  }
160  } else if (n < 0 || n == _Maximum) {
161  if (_Layout == CCS) {
162  begin = _Row + _Col[ptId];
163  end = _Row + _Col[ptId + 1];
164  } else {
165  begin = _Col + _Row[ptId];
166  end = _Col + _Row[ptId + 1];
167  }
168  } else {
169  if (_Layout == CCS) {
170  int i = _Col[ptId ];
171  int j = _Col[ptId+1];
172  begin = end = _Row + i;
173  while (i != j && *end <= n) ++i, ++end;
174  } else {
175  int i = _Row[ptId ];
176  int j = _Row[ptId+1];
177  begin = end = _Col + i;
178  while (i != j && *end <= n) ++i, ++end;
179  }
180  }
181 }
182 
183 // -----------------------------------------------------------------------------
184 inline void EdgeConnectivity
185 ::GetConnectedPoints(int ptId, int &numNbrPts, const int *&nbrPtIds, int n) const
186 {
187  const int *end;
188  GetConnectedPoints(ptId, nbrPtIds, end, n);
189  numNbrPts = end - nbrPtIds;
190 }
191 
192 // -----------------------------------------------------------------------------
193 inline void EdgeConnectivity
194 ::GetAdjacentPoints(int ptId, int &numAdjPts, const int *&adjPtIds) const
195 {
196  return GetConnectedPoints(ptId, numAdjPts, adjPtIds, 1);
197 }
198 
199 // -----------------------------------------------------------------------------
200 inline void EdgeConnectivity
201 ::GetAdjacentPoints(int ptId, const int *&begin, const int *&end) const
202 {
203  return GetConnectedPoints(ptId, begin, end, 1);
204 }
205 
206 
207 } // namespace mirtk
208 
209 #endif // MIRTK_EdgeConnectivity_H
int NumberOfPoints() const
Number of nodes.
EdgeConnectivity(vtkDataSet *=nullptr, int n=3, const EdgeTable *=nullptr)
Construct edge-connectivity table for given dataset.
void GetAdjacentPoints(int, int &, const int *&) const
Access list of adjacent (i.e. 1-connected) nodes (thread-safe)
int NumberOfConnectedPoints(int, int n=-1) const
Get number of nodes with edge-connectivity less or equal to n.
Definition: IOConfig.h:41
virtual ~EdgeConnectivity()
Destructor.
int NumberOfAdjacentPoints(int) const
Get number of adjacent nodes, i.e., nodes with edge-connectivity equal one.
EdgeConnectivity & operator=(const EdgeConnectivity &)
Assignment operator.
void Initialize(vtkDataSet *, int n=3, const EdgeTable *=nullptr)
Initialize edge-connectivity table from given dataset.
EntryType * _Data
Non-zero entries.
Definition: SparseMatrix.h:104
virtual void Clear()
Clear edge-connectivity table.
void GetConnectedPoints(int, int &, const int *&, int n=-1) const
Access list of nodes with edge-connectivity less or equal to n (thread-safe)