TTK
Loading...
Searching...
No Matches
ConnectedComponents.h
Go to the documentation of this file.
1
16
17#pragma once
18
19// base code includes
20#include <Debug.h>
21#include <Triangulation.h>
22
23#include <stack>
24
25namespace ttk {
26 class ConnectedComponents : virtual public Debug {
27
28 using TID = ttk::SimplexId;
29
30 private:
31 const int UNLABELED{-2};
32 const int IGNORE{-1};
33
34 public:
35 struct Component {
36 int id = -1;
37 float center[3]{0, 0, 0};
38 float size{0};
39 };
40
42 this->setDebugMsgPrefix("ConnectedComponents");
43 };
44 ~ConnectedComponents() override = default;
45
47 ttk::AbstractTriangulation *triangulation) const {
48 return triangulation->preconditionVertexNeighbors();
49 };
50
51 template <typename TT = ttk::AbstractTriangulation>
52 int computeFloodFill(int *labels,
53 std::vector<Component> &components,
54
55 const TT *triangulation,
56 const TID seed) const {
57 // get component id
58 const TID componentId = components.size();
59
60 std::stack<TID> stack;
61 stack.push(seed);
62 labels[seed] = componentId;
63 TID id = seed;
64
65 float size = 0;
66 float x, y, z;
67 float center[3] = {0, 0, 0};
68
69 while(!stack.empty()) {
70 const auto cIndex = stack.top();
71 stack.pop();
72
73 id = std::max(cIndex, id);
74
75 // update node data
76 triangulation->getVertexPoint(cIndex, x, y, z);
77 center[0] += x;
78 center[1] += y;
79 center[2] += z;
80 size++;
81
82 // add neihbors
83 size_t const nNeighbors
84 = triangulation->getVertexNeighborNumber(cIndex);
85 for(size_t i = 0; i < nNeighbors; i++) {
86 TID nIndex{-1};
87 triangulation->getVertexNeighbor(cIndex, i, nIndex);
88 if(labels[nIndex] == this->UNLABELED) {
89 labels[nIndex] = componentId;
90 stack.push(nIndex);
91 }
92 }
93 }
94 center[0] /= size;
95 center[1] /= size;
96 center[2] /= size;
97
98 // create component
99 components.resize(componentId + 1);
100 auto &c = components[componentId];
101 std::copy(center, center + 3, c.center);
102 c.id = id;
103 c.size = size;
104
105 return 1;
106 }
107
108 template <typename DT>
109 int initializeComponentIds(int *componentIds,
110 const TID nVertices,
111 const DT *featureMask = nullptr,
112 const DT backgroundThreshold = 0) const {
113 Timer timer;
114 std::string const msg
115 = "Initializing IDs"
116 + std::string(featureMask
117 ? (" with BT: " + std::to_string(backgroundThreshold))
118 : "");
119 this->printMsg(msg, 0, 0, 1, ttk::debug::LineMode::REPLACE);
120 if(featureMask) {
121 for(TID i = 0; i < nVertices; i++)
122 componentIds[i] = featureMask[i] > backgroundThreshold
123 ? this->UNLABELED
124 : this->IGNORE;
125 } else {
126 std::fill(componentIds, componentIds + nVertices, this->UNLABELED);
127 }
128 this->printMsg(msg, 1, timer.getElapsedTime(), 1);
129
130 return 1;
131 }
132
133 template <typename TT = ttk::AbstractTriangulation>
134 int computeConnectedComponents(std::vector<Component> &components,
135 int *componentIds,
136 const TT *triangulation) const {
137
138 TID const nVertices = triangulation->getNumberOfVertices();
139
140 Timer timer;
141 const std::string msg = "Computing Connected Components";
142 this->printMsg(msg, 0, 0, 1, ttk::debug::LineMode::REPLACE);
143
144 for(TID i = 0; i < nVertices; i++)
145 if(componentIds[i] == this->UNLABELED)
146 this->computeFloodFill<TT>(
147 componentIds, components, triangulation, i);
148
149 this->printMsg(msg, 1, timer.getElapsedTime(), 1);
150
151 return 1;
152 }
153
154 template <typename F, typename DT>
155 int mapData(std::vector<Component> &components,
156 const int *componentIds,
157 const int nVertices,
158 const F f,
159 DT *out) const {
160 for(TID i = 0; i < nVertices; i++)
161 out[i] = f(components, componentIds[i]);
162 return 1;
163 }
164 };
165} // namespace ttk
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
TTK connectedComponents processing package.
int computeFloodFill(int *labels, std::vector< Component > &components, const TT *triangulation, const TID seed) const
int preconditionTriangulation(ttk::AbstractTriangulation *triangulation) const
int computeConnectedComponents(std::vector< Component > &components, int *componentIds, const TT *triangulation) const
int initializeComponentIds(int *componentIds, const TID nVertices, const DT *featureMask=nullptr, const DT backgroundThreshold=0) const
int mapData(std::vector< Component > &components, const int *componentIds, const int nVertices, const F f, DT *out) const
~ConnectedComponents() override=default
Minimalist debugging class.
Definition Debug.h:88
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
double getElapsedTime()
Definition Timer.h:15
std::string to_string(__int128)
Definition ripserpy.cpp:99
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)