14 std::vector<std::vector<int>> regions) {
16 nodes = std::vector<std::shared_ptr<ttk::cta::CTNode>>();
17 arcs = std::vector<std::shared_ptr<ttk::cta::CTEdge>>();
19 float minVal = FLT_MAX;
20 float maxVal = -FLT_MAX;
22 for(
size_t i = 0; i < nVertices; i++) {
23 auto node = std::make_shared<ttk::cta::CTNode>();
24 node->scalarValue = scalars[i];
25 node->edgeList = std::vector<int>();
27 nodes.push_back(node);
28 if(node->scalarValue > maxVal)
29 maxVal = node->scalarValue;
30 if(node->scalarValue < minVal)
31 minVal = node->scalarValue;
34 for(
size_t i = 0; i < nEdges; i++) {
35 auto edge = std::make_shared<ttk::cta::CTEdge>();
36 edge->area = regionSizes[i];
37 edge->segId = segmentationIds[i];
39 edge->region = regions[segmentationIds[i]];
40 std::sort(edge->region.begin(), edge->region.end());
43 edge->node1Idx = topology[j + 0];
44 nodes[topology[j + 0]]->edgeList.push_back(i);
45 edge->node2Idx = topology[j + 1];
46 nodes[topology[j + 1]]->edgeList.push_back(i);
47 edge->scalardistance = std::abs(nodes[edge->node1Idx]->scalarValue
48 - nodes[edge->node2Idx]->scalarValue);
49 edge->volume = edge->area * edge->scalardistance;
54 for(
const std::shared_ptr<ttk::cta::CTNode> &node : nodes) {
55 if(node->edgeList.size() == 0)
56 std::cout <<
"wtf?\n" << std::flush;
57 if(node->edgeList.size() > 1)
60 const std::shared_ptr<ttk::cta::CTEdge> edge = arcs[node->edgeList[0]];
61 const std::shared_ptr<ttk::cta::CTNode> neighbor
62 = nodes[edge->node1Idx] == node ? nodes[edge->node2Idx]
63 : nodes[edge->node1Idx];
64 if(neighbor->scalarValue > node->scalarValue)
72 for(
const std::shared_ptr<ttk::cta::CTNode> &node : nodes) {
73 if(node->edgeList.size() > 3)
80std::shared_ptr<ttk::cta::Tree> ContourTree::computeRootedTree(
81 const std::shared_ptr<ttk::cta::CTNode> &node,
82 const std::shared_ptr<ttk::cta::CTEdge> &parent,
86 auto t = std::make_shared<Tree>();
102 if(parent ==
nullptr)
103 t->children = std::vector<std::shared_ptr<Tree>>(node->edgeList.size());
105 t->children = std::vector<std::shared_ptr<Tree>>(node->edgeList.size() - 1);
107 bool parentVisited =
false;
110 for(
size_t i = 0; i < node->edgeList.size(); i++) {
112 const std::shared_ptr<ttk::cta::CTEdge> edge = arcs[node->edgeList[i]];
114 parentVisited =
true;
118 const std::shared_ptr<ttk::cta::CTNode> child
119 = nodes[edge->node1Idx] == node ? nodes[edge->node2Idx]
120 : nodes[edge->node1Idx];
122 const std::shared_ptr<Tree> childTree = computeRootedTree(child, edge,
id);
124 t->children[i - (parentVisited ? 1 : 0)] = childTree;
126 t->size += childTree->size;
128 if(childTree->height + 1 > t->height)
129 t->height = childTree->height + 1;
133 if(parent ==
nullptr) {
134 t->scalardistanceParent = 0.0001;
137 t->scalardistanceParent = parent->scalardistance;
138 t->volume = t->scalardistanceParent * parent->area;
144std::shared_ptr<ttk::cta::BinaryTree> ContourTree::computeRootedTree_binary(
145 const std::shared_ptr<ttk::cta::CTNode> &node,
146 const std::shared_ptr<ttk::cta::CTEdge> &parent,
150 auto t = std::make_shared<BinaryTree>();
157 t->type = node->type;
158 std::shared_ptr<ttk::cta::CTEdge> edge = arcs[node->edgeList[0]];
160 = nodes[edge->node1Idx] == node ? edge->node1Idx : edge->node2Idx;
161 t->nodeRefs = std::vector<std::pair<int, int>>();
162 t->nodeRefs.emplace_back(-1, nodeIdx);
163 t->arcRefs = std::vector<std::pair<int, int>>();
166 if(parent !=
nullptr) {
167 const int arcRef = arcs[node->edgeList[0]] == parent ? node->edgeList[0]
168 : arcs[node->edgeList[1]] == parent ? node->edgeList[1]
170 t->arcRefs.emplace_back(-1, arcRef);
179 std::vector<std::shared_ptr<BinaryTree>> children;
182 for(
size_t i = 0; i < node->edgeList.size(); i++) {
184 edge = arcs[node->edgeList[i]];
188 const std::shared_ptr<ttk::cta::CTNode> child
189 = nodes[edge->node1Idx] == node ? nodes[edge->node2Idx]
190 : nodes[edge->node1Idx];
192 const std::shared_ptr<BinaryTree> childTree
193 = computeRootedTree_binary(child, edge,
id);
195 children.push_back(childTree);
197 t->size += childTree->size;
199 if(childTree->height + 1 > t->height)
200 t->height = childTree->height + 1;
205 t->child1 = children.size() > 0 ? children[0] :
nullptr;
206 t->child2 = children.size() > 1 ? children[1] :
nullptr;
210 t->scalarValue = node->scalarValue;
213 if(parent ==
nullptr) {
214 t->scalardistanceParent = 10000;
217 t->region = std::vector<int>(1, -1);
219 t->scalardistanceParent = parent->scalardistance;
220 t->area = parent->area;
221 t->volume = t->scalardistanceParent * parent->area;
222 t->region = parent->region;
231 float maxVal = -FLT_MAX;
232 std::shared_ptr<ttk::cta::CTNode> globalMax =
nullptr;
234 for(
const std::shared_ptr<ttk::cta::CTNode> &node : nodes) {
235 if(node->scalarValue > maxVal) {
237 maxVal = node->scalarValue;
243 return computeRootedTree_binary(globalMax,
nullptr,
id);
246std::shared_ptr<ttk::cta::BinaryTree>
252 return computeRootedTree_binary(root,
nullptr,
id);
263 for(
size_t i = 1; i < nodes.size(); i++) {
264 if(nodes[minIdx]->scalarValue > nodes[i]->scalarValue)
269 const int nextIdx = arcs[nodes[minIdx]->edgeList[0]]->node1Idx == minIdx
270 ? arcs[nodes[minIdx]->edgeList[0]]->node2Idx
271 : arcs[nodes[minIdx]->edgeList[0]]->node1Idx;
272 std::vector<int> maxPath_ = pathToMax(nextIdx, minIdx).second;
273 std::vector<int> maxPath;
274 maxPath.push_back(minIdx);
275 maxPath.insert(maxPath.end(), maxPath_.begin(), maxPath_.end());
278 nodes[minIdx]->branchID = 0;
279 std::stack<std::vector<int>> q;
284 std::vector<int> path = q.top();
287 for(
size_t i = 1; i < path.size() - 1; i++) {
289 const int idx = path[i];
291 for(
const int cE : nodes[idx]->edgeList) {
294 = arcs[cE]->node1Idx == idx ? arcs[cE]->node2Idx : arcs[cE]->node1Idx;
295 if(cIdx == path[i - 1])
297 if(cIdx == path[i + 1])
300 if(nodes[cIdx]->scalarValue > nodes[idx]->scalarValue) {
301 std::vector<int> newPath_ = pathToMax(cIdx, idx).second;
302 std::vector<int> newPath;
303 newPath.push_back(idx);
304 newPath.insert(newPath.end(), newPath_.begin(), newPath_.end());
307 std::vector<int> newPath_ = pathToMin(cIdx, idx).second;
308 std::vector<int> newPath;
309 newPath.push_back(idx);
310 newPath.insert(newPath.end(), newPath_.begin(), newPath_.end());
315 nodes[idx]->branchID = currID;
319 nodes[path.back()]->branchID = currID;
324std::pair<float, std::vector<int>> ContourTree::pathToMax(
int root,
327 std::vector<int> path;
328 path.push_back(root);
330 if(nodes[root]->edgeList.size() == 1) {
331 return std::make_pair(nodes[root]->scalarValue, path);
334 std::vector<int> bestPath;
335 float bestVal = -FLT_MAX;
337 for(
const int cE : nodes[root]->edgeList) {
340 = arcs[cE]->node1Idx == root ? arcs[cE]->node2Idx : arcs[cE]->node1Idx;
341 if(parent == nextIdx)
343 if(nodes[nextIdx]->scalarValue < nodes[root]->scalarValue)
346 auto p = pathToMax(nextIdx, root);
347 if(p.first > bestVal) {
353 path.insert(path.end(), bestPath.begin(), bestPath.end());
355 return std::make_pair(bestVal, path);
358std::pair<float, std::vector<int>> ContourTree::pathToMin(
int root,
361 std::vector<int> path;
362 path.push_back(root);
364 if(nodes[root]->edgeList.size() == 1) {
365 return std::make_pair(nodes[root]->scalarValue, path);
368 std::vector<int> bestPath;
369 float bestVal = FLT_MAX;
371 for(
const int cE : nodes[root]->edgeList) {
374 = arcs[cE]->node1Idx == root ? arcs[cE]->node2Idx : arcs[cE]->node1Idx;
375 if(parent == nextIdx)
377 if(nodes[nextIdx]->scalarValue > nodes[root]->scalarValue)
380 auto p = pathToMin(nextIdx, root);
381 if(p.first < bestVal) {
387 path.insert(path.end(), bestPath.begin(), bestPath.end());
389 return std::make_pair(bestVal, path);
392std::pair<std::vector<std::shared_ptr<ttk::cta::CTNode>>,
393 std::vector<std::shared_ptr<ttk::cta::CTEdge>>>
395 return std::make_pair(nodes, arcs);
Contour Tree Data Structure for an unrooted contour tree of unbounded degree for internal use from th...
~ContourTree()
Destructor of internal contour tree class.
std::pair< std::vector< std::shared_ptr< CTNode > >, std::vector< std::shared_ptr< CTEdge > > > getGraph()
ContourTree(float *scalars, int *regionSizes, int *segmentationIds, long long *topology, size_t nVertices, size_t nEdges, std::vector< std::vector< int > > regions={})
std::shared_ptr< BinaryTree > rootAtMax()
std::shared_ptr< BinaryTree > rootAtNode(const std::shared_ptr< CTNode > &root)