16MergeTree::MergeTree(std::shared_ptr<Params> params,
17 std::shared_ptr<Scalars> scalars,
20 : params_(std::move(params)), scalars_(std::move(scalars)) {
46 = [&](
const pair<SimplexId, bool> &a,
const pair<SimplexId, bool> &b) {
47 return isLower(a.first, b.first);
51 = [&](
const pair<SimplexId, bool> &a,
const pair<SimplexId, bool> &b) {
69 sort(segmentation, segmentation + segmSize, compH);
71 const SimplexId &vert = segmentation[i].first;
88 sort(segmentation, segmentation + segmSize, compL);
90 const SimplexId &vert = segmentation[i].first;
91 if(!segmentation[i].second) {
99 for(
idNode n = 0; n < nbNode; n++) {
109 = [&](
const pair<SimplexId, bool> &a,
const pair<SimplexId, bool> &b) {
110 return isLower(a.first, b.first);
114 = [&](
const pair<SimplexId, bool> &a,
const pair<SimplexId, bool> &b) {
120#ifdef TTK_ENABLE_OPENMP
121#pragma omp parallel for
135 sort(segmentation, segmentation + segmSize, compH);
136 for(
SimplexId i = 0; i < segmSize; i++) {
137 const SimplexId &vert = segmentation[i].first;
142#ifdef TTK_ENABLE_OPENMP
143#pragma omp parallel for
157 sort(segmentation, segmentation + segmSize, compL);
158 for(
SimplexId i = 0; i < segmSize; i++) {
159 const SimplexId &vert = segmentation[i].first;
160 if(!segmentation[i].second) {
168 for(
idNode n = 0; n < nbNode; n++) {
179#ifdef TTK_ENABLE_OPENMP
180#pragma omp parallel for num_threads(nbThreadValence)
182 for(
idNode n = 0; n < nbNodes; n++) {
183 short downVal = 0, upVal = 0;
215 const bool overlapA) {
216#ifndef TTK_ENABLE_KAMIKAZE
218 cout <<
"[Merge Tree] openSuperArc on a inexisting node !" << endl;
229 return newSuperArcId;
236 pair<SimplexId, bool> *vertexList,
240 if(downNodeId != upNodeId) {
258 return newSuperArcId;
264 const bool overlapA) {
265#ifndef TTK_ENABLE_KAMIKAZE
268 cout <<
"[Merge Tree] closeSuperArc on a inexisting arc !" << endl;
273 cout <<
"[Merge Tree] closeOpenedArc on a inexisting node !" << endl;
281 getNode(upNodeId)->getVertexId());
301 const pair<SimplexId, bool> &seed) {
303 = [&](
const pair<SimplexId, bool> &a,
const pair<SimplexId, bool> &b) {
304 return isLower(a.first, b.first);
315 = lower_bound(vertList, vertList + vertSize, seed, isLowerComp);
316 while(posVert < vertList + vertSize && posVert->second) {
320 if(posVert == vertList + vertSize) {
326 stitchVert = posVert->first;
345 const pair<SimplexId, bool> &seed,
346 const vector<idCorresp> &vert2treeOther) {
348 = [&](
const pair<SimplexId, bool> &a,
const pair<SimplexId, bool> &b) {
349 return isLower(a.first, b.first);
360 = lower_bound(vertList, vertList + vertSize, seed, isLowerComp);
361 if(posVert == vertList) {
367 && (posVert->second || vert2treeOther[posVert->first] == nullCorresp)) {
371 if(posVert == vertList) {
375 stitchVert = posVert->first;
497 const bool changeConnectivity) {
500 if(changeConnectivity) {
517#ifndef TTK_ENABLE_KAMIKAZE
518 if(vertexId < 0 || vertexId >=
scalars_->size) {
519 cout <<
"[Merge Tree] make node, wrong vertex :" << vertexId <<
" on "
542 std::list<std::vector<std::pair<SimplexId, bool>>> &storage,
543 const pair<SimplexId, bool> *markVertices,
553#ifndef TTK_ENABLE_KAMIKAZE
555 cout << endl <<
"[MergeTree]:delNode won't delete ";
556 cout << mainNode->
getVertexId() <<
" (root) with ";
596 if(markVertices !=
nullptr) {
611 for(
SimplexId i = nbMark - 1; i >= 0; --i) {
615 != markVertices[i].first) {
634 storage.emplace_back(upSize + downSize);
635 pair<SimplexId, bool> *newSegmentation = storage.back().data();
637 for(
SimplexId i = 0; i < downSize; i++) {
638 newSegmentation[i] = downSegm[i];
642 newSegmentation[i + downSize] = upSegm[i];
682 idNode upNodeId, newNodeId;
709 pair<SimplexId, bool> *newNodePosPtr
714 [&](
const pair<SimplexId, bool> &a,
715 const pair<SimplexId, bool> &b) {
721 [&](
const pair<SimplexId, bool> &a,
722 const pair<SimplexId, bool> &b) {
723 return isLower(a.first, b.first);
749 cout <<
"reverse insert don t deal with hidden" << endl;
754 idNode downNodeId, newNodeId;
783 pair<SimplexId, bool> *newNodePosPtr
788 [&](
const pair<SimplexId, bool> &a,
789 const pair<SimplexId, bool> &b) {
795 [&](
const pair<SimplexId, bool> &a,
796 const pair<SimplexId, bool> &b) {
797 return isLower(a.first, b.first);
832 vector<idNode> res(nbDown + nbUp);
840 res[currentPos++] = corNode;
847 res[currentPos++] = corNode;
857 vector<idNode> res(nbUp);
873 vector<idNode> res(nbDown);
876 for(
idNode i = 0; i < nbDown; i++) {
929 for(
idSuperArc aid = 0; aid < nbDown; aid++) {
938 if(
getNode(downNode)->getVertexId() == v) {
947 while(p != baseNode &&
getNode(p)->getUpValence()) {
949 if(
getNode(p)->getUpValence() != 1)
950 cout <<
"Noise with up valence ! (hide&clear Leading to)" << endl;
970#ifdef TTK_ENABLE_OPENMP
977 cout <<
"Nodes----------" << endl;
985 cout <<
"Arcs-----------" << endl;
993 cout <<
"Leaves" << endl;
998 cout <<
"Roots" << endl;
1007 auto newMT = std::make_shared<MergeTree>(
1048void MergeTree::hideAndMerge(
const idSuperArc &mergingArcId,
1050 const bool preserveNode) {
1063 mergeArc(mergingArcId, receptacleArcId);
1069 const idNode &parentNodeId) {
1071 const auto &curSegmenSize =
getSuperArc(mergingArcId)->getVertSize()
1072 + ufArray[curNodeId]->find()->getOrigin() + 2;
1076 if(ufArray[parentNodeId] ==
nullptr) {
1078 ufArray[parentNodeId] = ufArray[curNodeId]->find();
1079 ufArray[parentNodeId]->find()->setOrigin(curSegmenSize);
1083 const auto &oldSegmentationSize
1084 = ufArray[parentNodeId]->find()->getOrigin();
1086 ufArray[curNodeId]->find(), ufArray[parentNodeId]->find())
1087 ->
setOrigin(oldSegmentationSize + curSegmenSize);
1095 ufArray[parentNodeId]->find()->setData(-((
ufDataType)parentNodeId) - 1);
1099 vector<ExtendedUnionFind *> &ufArray) {
1112 || ufArray[curNodeId]->find() != ufArray[newUp]->find()) {
1123 vector<ExtendedUnionFind *> &ufArray) {
1135 if(!ufArray[newDown]
1136 || ufArray[curNodeId]->find() != ufArray[newDown]->find()) {
1146tuple<idNode, idNode, SimplexId> MergeTree::createReceptArc(
1149 vector<ExtendedUnionFind *> &ufArray,
1150 const vector<pair<idSuperArc, idSuperArc>> &valenceOffsets) {
1152 const bool DEBUG =
false;
1159 cout <<
" create receptarc for root : " <<
printNode(root) << endl;
1160 cout <<
" custom valence : " << valenceOffsets[root].first;
1161 cout <<
" + " << valenceOffsets[root].second << endl;
1171 while(
getNode(downNode)->getUpValence() - valenceOffsets[downNode].second == 1
1172 &&
getNode(downNode)->getDownValence() - valenceOffsets[downNode].first
1177 const idSuperArc &downArc = newDownArc(downNode, ufArray);
1180 segmentationSize +=
getSuperArc(downArc)->getVertSize() + 2;
1188 cout <<
" new segmentation : " << segmentationSize << endl;
1192 if(ufArray[downNode]) {
1193 segmentationSize += ufArray[downNode]->find()->getOrigin();
1195 if(ufArray[downNode]->find()->getData() < 0) {
1196 ufArray[downNode]->find()->setData(receptacleArcId);
1201 mergeArc(downArc, receptacleArcId,
false);
1206 cout <<
" continue receptarc for root : " <<
printNode(root) << endl;
1207 cout <<
" custom valence : " << valenceOffsets[root].first;
1208 cout <<
" + " << valenceOffsets[root].second << endl;
1213 while(
getNode(upNode)->getUpValence() - valenceOffsets[upNode].second == 1
1214 &&
getNode(upNode)->getDownValence() - valenceOffsets[upNode].first
1217 const idSuperArc &upArc = newUpArc(upNode, ufArray);
1219 segmentationSize +=
getSuperArc(upArc)->getVertSize() + 2;
1226 cout <<
" new segmentation : " << segmentationSize << endl;
1229 if(ufArray[upNode]) {
1230 segmentationSize += ufArray[upNode]->find()->getOrigin();
1232 if(ufArray[upNode]->find()->getData() < 0) {
1233 ufArray[upNode]->find()->setData(receptacleArcId);
1238 mergeArc(upArc, receptacleArcId,
false);
1244 if(upNode == downNode) {
1247 const idSuperArc tmpDown = newDownArc(downNode, ufArray);
1248 const idSuperArc tmpUp = newUpArc(upNode, ufArray);
1250 if(tmpDown == nullSuperArc) {
1252 if(ufArray[upNode]) {
1253 segmentationSize += ufArray[upNode]->find()->getOrigin();
1256 ufArray[upNode] = ufRoot->
find();
1261 if(ufArray[downNode]) {
1265 ufArray[downNode] = ufRoot->
find();
1270 if(tmpDown != nullSuperArc)
1271 segmentationSize +=
getSuperArc(tmpDown)->getVertSize() + 2;
1272 if(tmpUp != nullSuperArc)
1273 segmentationSize +=
getSuperArc(tmpUp)->getVertSize() + 2;
1278 return make_tuple(downNode, upNode, segmentationSize);
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
void setDebugMsgPrefix(const std::string &prefix)
void setOrigin(const SimplexId &origin)
const SimplexId & getOrigin() const
static ExtendedUnionFind * makeUnion(ExtendedUnionFind *uf0, ExtendedUnionFind *uf1)
ExtendedUnionFind * find()
void hideAndClearArcsBelow(const idNode &baseNode, const SimplexId &seed)
void hideArc(const idSuperArc &sa)
void updateCorrespondingNode(const SimplexId &vert, const idNode &val)
idSuperArc getNumberOfVisibleArcs() const
idNode makeNode(const SimplexId &vertexId, const SimplexId &linked=nullVertex)
Node * vertex2Node(const SimplexId &vert)
idSuperArc insertNode(Node *node, const bool segment)
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)
idNode getNumberOfNodes() const
idSuperArc openSuperArc(const idNode &downNodeId, const bool overlapB, const bool overlapA)
std::string printArc(const idSuperArc &a)
std::vector< idNode > getNodeNeighbors(const idNode &node)
void doSwap(MergeTree *mt)
std::shared_ptr< Scalars > scalars_
bool isCorrespondingArc(const SimplexId &val) const
void mergeArc(const idSuperArc &sa, const idSuperArc &recept, const bool changeConnectivity=true)
idNode getParent(const idNode &n)
void removeInternalDownArcs(const idNode &node)
void removeHiddenDownArcs(const idNode &n)
idSuperArc getNumberOfExternalDownArcs(const idNode &node)
std::shared_ptr< MergeTree > clone() const
void markThisArc(std::vector< ExtendedUnionFind * > &ufArray, const idNode &curNodeId, const idSuperArc &mergingArcId, const idNode &parentNodeId)
std::vector< idNode > getNodeUpNeighbors(const idNode &n)
idSuperArc getNumberOfSuperArcs() const
Node * getUpNode(const SuperArc *a)
bool isCorrespondingNode(const SimplexId &val) const
idSuperArc reverseInsertNode(Node *node, const bool segment)
SimplexId getVertBelowSeed(const idSuperArc &arc, const std::pair< SimplexId, bool > &seed, const std::vector< idCorresp > &vert2treeOther)
idSuperArc makeSuperArc(const idNode &downNodeId, const idNode &upNodeId, const bool overlapB, const bool overlapA, std::pair< SimplexId, bool > *vertexList=nullptr, SimplexId vertexSize=-1)
std::string printNode(const idNode &n)
void updateCorrespondingArc(const SimplexId &arc, const idSuperArc &val)
bool isHigher(const SimplexId &a, const SimplexId &b) const
idNode getCorrespondingNodeId(const SimplexId &val) const
idSuperArc getCorrespondingSuperArcId(const SimplexId &val) const
void closeSuperArc(const idSuperArc &superArcId, const idNode &upNodeId, const bool overlapB, const bool overlapA)
void hideNode(const idNode &node)
Node * getDownNode(const SuperArc *a)
void parallelUpdateSegmentation(const bool ct=false)
idSuperArc getNumberOfUnmergedDownArcs(const idNode &n)
bool isLower(const SimplexId &a, const SimplexId &b) const
void hideAndClearArcsAbove(const idNode &baseNode)
idSuperArc hideAndClearLeadingTo(const idNode &baseNode, const SimplexId &v)
SimplexId insertNodeAboveSeed(const idSuperArc &arc, const std::pair< SimplexId, bool > &seed)
bool alreadyExtLinked(const idNode &node, const idPartition &tree, const idNode &treeNode)
const std::vector< SuperArc > & getSuperArc() const
Node * getNode(const idNode &nodeId)
void parallelInitNodeValence(const int nbThreadValence)
void updateSegmentation()
std::shared_ptr< Params > params_
std::vector< idNode > getNodeDownNeighbors(const idNode &n)
SimplexId getVertexId() const
idSuperArc clearUpSuperArcs()
idSuperArc clearDownSuperArcs()
void removeDownSuperArc(const idSuperArc &idSa)
void addDownSuperArcId(const idSuperArc &downSuperArcId)
idSuperArc getDownSuperArcId(const idSuperArc &neighborId) const
idSuperArc getNumberOfUpSuperArcs() const
void setUpValence(const idSuperArc &v)
void removeUpSuperArc(const idSuperArc &idSa)
idSuperArc getUpSuperArcId(const idSuperArc &neighborId) const
void setDownValence(const idSuperArc &v)
void removeDownSuperArcPos(const idSuperArc &i)
idSuperArc getNumberOfDownSuperArcs() const
idPartition getDownCT() const
const idNode & getUpNodeId() const
const SimplexId & getVertSize()
void appendSegmentation(const std::vector< std::pair< SimplexId, bool > > &other)
std::vector< std::pair< SimplexId, bool > > & getSegmentation()
std::pair< SimplexId, bool > * getVertList()
void setVertList(std::pair< SimplexId, bool > *vl)
void setVertSize(const SimplexId &s)
const idSuperArc & getReplacantArcId() const
const idNode & getDownNodeId() const
idPartition getUpCT() const
std::ostream & operator<<(std::ostream &o, Node const &n)
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
long int ufDataType
type stored by UnionFind
unsigned int idNode
Node index in vect_nodes_.
int SimplexId
Identifier type for simplices of any dimension.
std::vector< idSuperArc > arcsCrossingAbove
std::vector< idNode > leaves
std::vector< Node > nodes
std::vector< SuperArc > superArcs
std::vector< idSuperArc > arcsCrossingBelow
std::vector< idNode > roots
std::vector< idCorresp > vert2tree