TTK
Loading...
Searching...
No Matches
ContourForestsTree.cpp
Go to the documentation of this file.
1/*
2 * file: ContourForestsTree.cpp
3 * description: ContourForestsTree processing package.
4 * author: Gueunet Charles
5 * date: Juin 2015
6 */
7
8#include <iterator>
9#include <string>
10
11#include "ContourForestsTree.h"
12
13using namespace std;
14using namespace ttk;
15using namespace cf;
16
17ContourForestsTree::ContourForestsTree(const std::shared_ptr<Params> &params,
18 const std::shared_ptr<Scalars> &scalars,
19 idPartition part)
20 : MergeTree(params, scalars, TreeType::Contour, part),
21 jt_(params, scalars, TreeType::Join, part),
22 st_(params, scalars, TreeType::Split, part) {
23}
24
26
27// Process
28// {
29
31 const SimplexId &seed0,
32 const SimplexId &seed1,
33 std::list<std::vector<std::pair<SimplexId, bool>>> &storage) {
34
35 queue<pair<bool, idNode>> growingNodes;
36 pair<bool, idNode> head;
37
38 MergeTree *xt = nullptr, *yt = nullptr;
39 idNode correspondingNodeId, parentId, node1, node2;
40 Node *currentNode, *parentNode;
41
42 const bool DEBUG = false;
43
44 // If a tree add only one leaf, the other tree is the result
45 SimplexId nbAddedleavesST = 0, nbAddedleavesJT = 0;
46
47 // Add leves to growing nodes
48 // We insert non hidden nodes, only those of the interface or those
49 // just beyond, linked to a crossing arc
50 for(const idNode &nId : st_.getLeaves()) {
51 if(!st_.getNode(nId)->isHidden()
52 && st_.getNode(nId)->getNumberOfSuperArcs()) {
53 growingNodes.emplace(false, nId);
54 ++nbAddedleavesST;
55 }
56 }
57
58 // filiform tree
59 if(nbAddedleavesST == 1) {
60 growingNodes.pop();
61 }
62
63 // count how many leaves can be added, if more than one : ok!
64 for(const idNode &nId : jt_.getLeaves()) {
65 if(!jt_.getNode(nId)->isHidden()
66 && jt_.getNode(nId)->getNumberOfSuperArcs()) {
67 ++nbAddedleavesJT;
68 }
69 if(nbAddedleavesJT > 1)
70 break;
71 }
72
73 if(nbAddedleavesJT > 1) {
74 for(const idNode &nId : jt_.getLeaves()) {
75 if(!jt_.getNode(nId)->isHidden()
76 && jt_.getNode(nId)->getNumberOfSuperArcs()) {
77 growingNodes.emplace(true, nId);
78 }
79 }
80 }
81
82 if(DEBUG) {
83 cout << "growingNodes : " << growingNodes.size() << endl;
84 }
85
86 if(nbAddedleavesST == 1 && nbAddedleavesJT == 1) {
87 // ultra simplistic case where both tree a filliform
88 clone(&jt_);
89 return 0;
90 }
91
92 // Warning, have a reserve here, can't make it at the begnining, need build
93 // output
94 treeData_.leaves.reserve(jt_.getLeaves().size() + st_.getLeaves().size());
95
96 if(growingNodes.empty()) {
97 cout << "[ContourForestsTree::combine ] Nothing to combine" << endl;
98 }
99
100 // seed : to keep crossing edges;
101 const SimplexId &s0
102 = (seed0 == -1) ? nullVertex : scalars_->sortedVertices[seed0];
103 const SimplexId &s1
104 = (seed1 >= scalars_->size) ? nullVertex : scalars_->sortedVertices[seed1];
105
106 while(!growingNodes.empty()) {
107 // i <- Get(Q)
108 head = growingNodes.front();
109
110 if(head.first) {
111 // node come from jt
112 xt = &jt_;
113 yt = &st_;
114 } else {
115 // node come from st
116 xt = &st_;
117 yt = &jt_;
118 }
119
120 currentNode = xt->getNode(head.second);
121
122 if(DEBUG) {
123 if(xt == &jt_)
124 cout << "JT ";
125 else
126 cout << "ST ";
127 cout << "node : " << currentNode->getVertexId() << endl;
128 }
129
130 correspondingNodeId
131 = yt->getCorrespondingNodeId(currentNode->getVertexId());
132
133 if(isCorrespondingNode(currentNode->getVertexId())) {
134 // already a node in the tree
135 node1 = getCorrespondingNodeId(currentNode->getVertexId());
136 } else {
137 // create a new node
138 node1 = makeNode(currentNode);
139
140 // check if leaf
141 if(!currentNode->getNumberOfDownSuperArcs()
142 || !currentNode->getNumberOfUpSuperArcs())
143 treeData_.leaves.emplace_back(node1);
144 }
145
146 // "choose a non-root leaf that is not a split in ST" so we ignore such
147 // nodes
148 if(currentNode->getNumberOfUpSuperArcs() == 0
149 || yt->getNode(correspondingNodeId)->getNumberOfDownSuperArcs() > 1) {
150
151 growingNodes.pop();
152
153 // if(currentNode->getNumberOfUpSuperArcs() == 0){
154 // if (DEBUG) {
155 // cout << "ignore orphan" << endl;
156 //}
157 // continue;
158 //}
159
160 if(yt->getNode(correspondingNodeId)->getNumberOfDownSuperArcs() > 1) {
161 if(DEBUG) {
162 cout << "re-enqueue and ignore " << yt->printNode(correspondingNodeId)
163 << endl;
164 }
165
166 growingNodes.emplace(head.first, head.second);
167 continue;
168 }
169
170 if(DEBUG) {
171 cout << " ignore" << endl;
172 }
173
174 continue;
175 }
176
177 // j <- GetAdj(XT, i)
178 idSuperArc curUpArc = currentNode->getUpSuperArcId(0);
179 if(xt->getSuperArc(curUpArc)->isMerged())
180 curUpArc = xt->getSuperArc(curUpArc)->getReplacantArcId();
181 parentId = xt->getSuperArc(curUpArc)->getUpNodeId();
182 if(parentId == nullNodes) {
183 // security : if not closed arc, close it here
184 // can append when 1 vertex is isolated
185 parentId = xt->makeNode(
186 xt->getSuperArc(currentNode->getUpSuperArcId(0))->getLastVisited());
187 // single not si not crossing anything
188 xt->closeSuperArc(
189 currentNode->getUpSuperArcId(0), parentId, false, false);
190 }
191
192 parentNode = xt->getNode(parentId);
193
194 // cout << " parent node :" << parentNode->getVertexId() << endl;
195
196 // HERE parent is null ...
197 if(isCorrespondingNode(parentNode->getVertexId())) {
198 // already a node in the tree
199 node2 = getCorrespondingNodeId(parentNode->getVertexId());
200 } else {
201 // create a new node
202 node2 = makeNode(parentNode);
203 if(!parentNode->getNumberOfUpSuperArcs())
204 treeData_.leaves.emplace_back(node2);
205 }
206
207 // AddArc(CT, ij)
208 pair<SimplexId, bool> *arcVertList = nullptr;
209 SimplexId arcVertSize = 0;
210 {
211 arcVertList
212 = xt->getSuperArc(currentNode->getUpSuperArcId(0))->getVertList();
213 arcVertSize
214 = xt->getSuperArc(currentNode->getUpSuperArcId(0))->getVertSize();
215
216 bool overlapB = false, overlapA = false;
217
218 // If the created arc cross tha above or below interface, keep this info
219 if(s0 != nullVertex) {
220 overlapB = (isHigher(currentNode->getVertexId(), s0)
221 != isHigher(parentNode->getVertexId(), s0));
222 }
223 if(s1 != nullVertex) {
224 overlapA = (isHigher(currentNode->getVertexId(), s1)
225 != isHigher(parentNode->getVertexId(), s1));
226 }
227
228 idSuperArc createdArc;
229 // create the arc
230 if(isLower(currentNode->getVertexId(),
231 parentNode->getVertexId())) { // take care of the order
232 createdArc = makeSuperArc(
233 node1, node2, overlapB, overlapA, arcVertList, arcVertSize);
234 } else {
235 createdArc = makeSuperArc(
236 node2, node1, overlapB, overlapA, arcVertList, arcVertSize);
237 }
238
239 if(overlapB) {
240 treeData_.arcsCrossingBelow.emplace_back(createdArc);
241 }
242 if(overlapA)
243 treeData_.arcsCrossingAbove.emplace_back(createdArc);
244
245 // Segmentation, update only if not already set, user vert2tree to check
246 SimplexId nbv = 0;
247 for(SimplexId vert = 0; vert < arcVertSize; vert++) {
248 const SimplexId &v = arcVertList[vert].first;
249 if(isCorrespondingNull(v)) {
250 updateCorrespondingArc(v, createdArc);
251 ++nbv;
252 } else {
253 getSuperArc(createdArc)->setMasqued(vert);
254 }
255 }
256
257 if(DEBUG) {
258 cout << " arc added : (segm: " << nbv << ") ";
259 cout << printArc(createdArc) << endl;
260 }
261 }
262
263 // DelNode(XT, i)
264 {
265 if(DEBUG) {
266 cout << " delete xt (" << (xt == &jt_)
267 << ") node :" << xt->getNode(head.second)->getVertexId() << endl;
268 }
269
270 xt->delNode(head.second, storage);
271 }
272
273 // DelNode(YT, i)
274 {
275 if(yt->getNode(correspondingNodeId)->getNumberOfDownSuperArcs() < 2) {
276 if(DEBUG) {
277 cout << " delete yt (" << head.first << ") node :";
278 cout << yt->getNode(correspondingNodeId)->getVertexId();
279 cout << " have : ";
280 cout << static_cast<unsigned>(
281 yt->getNode(correspondingNodeId)->getNumberOfDownSuperArcs());
282 cout << " down";
283 cout << " and : "
284 << static_cast<unsigned>(
285 yt->getNode(correspondingNodeId)->getNumberOfUpSuperArcs())
286 << " up" << endl;
287 }
288
289 yt->delNode(correspondingNodeId, storage, arcVertList, arcVertSize);
290 }
291 }
292
293 if(parentNode->getNumberOfDownSuperArcs() == 0
294 && parentNode->getNumberOfUpSuperArcs()) {
295 growingNodes.emplace(head.first, parentId);
296
297 if(DEBUG) {
298 cout << "will see : " << parentNode->getVertexId() << endl;
299 }
300 }
301
302 growingNodes.pop();
303 }
304
305 return 0;
306}
307
308//}
#define DEBUG(msg)
int combine(const SimplexId &seed0, const SimplexId &seed1, std::list< std::vector< std::pair< SimplexId, bool > > > &storage)
Combine tree with Natarajan's algorithm.
idNode makeNode(const SimplexId &vertexId, const SimplexId &linked=nullVertex)
void delNode(const idNode &node, std::list< std::vector< std::pair< SimplexId, bool > > > &storage, const std::pair< SimplexId, bool > *mv=nullptr, const SimplexId &nbm=0)
std::string printArc(const idSuperArc &a)
Definition MergeTree.h:580
std::shared_ptr< Scalars > scalars_
Definition MergeTree.h:44
std::shared_ptr< MergeTree > clone() const
bool isCorrespondingNode(const SimplexId &val) const
Definition MergeTree.h:298
idSuperArc makeSuperArc(const idNode &downNodeId, const idNode &upNodeId, const bool overlapB, const bool overlapA, std::pair< SimplexId, bool > *vertexList=nullptr, SimplexId vertexSize=-1)
void updateCorrespondingArc(const SimplexId &arc, const idSuperArc &val)
Definition MergeTree.h:348
bool isHigher(const SimplexId &a, const SimplexId &b) const
Definition MergeTree.h:649
idNode getCorrespondingNodeId(const SimplexId &val) const
Definition MergeTree.h:310
void closeSuperArc(const idSuperArc &superArcId, const idNode &upNodeId, const bool overlapB, const bool overlapA)
TreeData treeData_
Definition MergeTree.h:47
const std::vector< idNode > & getLeaves() const
Definition MergeTree.h:256
bool isCorrespondingNull(const SimplexId &val) const
Definition MergeTree.h:302
bool isLower(const SimplexId &a, const SimplexId &b) const
Definition MergeTree.h:645
const std::vector< SuperArc > & getSuperArc() const
Definition MergeTree.h:197
Node * getNode(const idNode &nodeId)
Definition MergeTree.h:244
SimplexId getVertexId() const
idSuperArc getNumberOfSuperArcs() const
idSuperArc getNumberOfUpSuperArcs() const
bool isHidden() const
idSuperArc getUpSuperArcId(const idSuperArc &neighborId) const
idSuperArc getNumberOfDownSuperArcs() const
numThread idPartition
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
unsigned int idNode
Node index in vect_nodes_.
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
std::vector< idSuperArc > arcsCrossingAbove
std::vector< idNode > leaves
std::vector< idSuperArc > arcsCrossingBelow