From 43efa6b8c298ac79bcc93abff00991286853e4e4 Mon Sep 17 00:00:00 2001 From: Pierre Kraemer Date: Fri, 10 Feb 2012 16:35:26 +0100 Subject: [PATCH] MRdarts and levels management --- include/Algo/Modelisation/triangulation.h | 3 +- include/Topology/generic/genericmap.h | 79 ++++++--- include/Topology/generic/genericmap.hpp | 197 ++++++++++++++++------ src/Topology/generic/genericmap.cpp | 152 ++++++++++------- src/Topology/map/map2MR/map2MR_Primal.cpp | 50 +++--- 5 files changed, 326 insertions(+), 155 deletions(-) diff --git a/include/Algo/Modelisation/triangulation.h b/include/Algo/Modelisation/triangulation.h index 4108b325..efdd3099 100644 --- a/include/Algo/Modelisation/triangulation.h +++ b/include/Algo/Modelisation/triangulation.h @@ -86,7 +86,7 @@ protected: bool inTriangle(const typename PFP::VEC3& P, const typename PFP::VEC3& normal, const typename PFP::VEC3& Ta, const typename PFP::VEC3& Tb, const typename PFP::VEC3& Tc); - void recompute2Ears( Dart d, const typename PFP::VEC3& normalPoly, bool convex); + void recompute2Ears( Dart d, const typename PFP::VEC3& normalPoly, bool convex); float computeEarInit(Dart d, const typename PFP::VEC3& normalPoly, float& val); @@ -101,7 +101,6 @@ public: void trianguleFace(Dart d); void triangule(const FunctorSelect& good = allDarts, unsigned int thread = 0); - }; } // namespace Modelisation diff --git a/include/Topology/generic/genericmap.h b/include/Topology/generic/genericmap.h index c147159c..0c5d63e1 100644 --- a/include/Topology/generic/genericmap.h +++ b/include/Topology/generic/genericmap.h @@ -127,6 +127,11 @@ protected: */ AttributeMultiVector* m_mrLevels ; + /** + * vector that stores the number of darts inserted on each resolution level + */ + std::vector m_mrNbDarts ; + /** * current level in multiresolution map */ @@ -146,11 +151,6 @@ public: virtual std::string mapTypeName() = 0 ; - /** - * initialize the multiresolution attribute container - */ - void initMR() ; - /** * Clear the map * @param removeAttrib @@ -168,6 +168,13 @@ public: * MULTIRES * ****************************************/ + void printMR() ; + + /** + * initialize the multiresolution attribute container + */ + void initMR() ; + /** * get the current resolution level (use only in MRMaps) */ @@ -178,6 +185,16 @@ public: */ void setCurrentLevel(unsigned int l) ; + /** + * increment the current resolution level (use only in MRMaps) + */ + void incCurrentLevel() ; + + /** + * decrement the current resolution level (use only in MRMaps) + */ + void decCurrentLevel() ; + /** * store current resolution level on a stack (use only in MRMaps) */ @@ -199,14 +216,9 @@ public: void addLevel() ; /** - * add a resolution level and duplicate all darts (use only in MRMaps) + * remove last resolution level (use only in MRMaps) */ - void addLevelDuplicate() ; - - /** - * get the insertion level of a dart (use only in MRMaps) - */ - unsigned int getDartLevel(Dart d) ; + void removeLevel() ; /**************************************** * DARTS MANAGEMENT * @@ -222,6 +234,14 @@ protected: */ void deleteDart(Dart d) ; +private: + /** + * internal functions + */ + void deleteDartLine(unsigned int index) ; + void copyDartLine(unsigned int dest, unsigned int src) ; + unsigned int newCopyOfDartLine(unsigned int index) ; + public: /** * get the index of dart in topological table @@ -229,15 +249,30 @@ public: unsigned int dartIndex(Dart d); /** - * return true if the dart d refers to a valid index + * get the insertion level of a dart (use only in MRMaps) */ - bool isDartValid(Dart d) ; + unsigned int getDartLevel(Dart d) ; + + /** + * get the number of darts inserted in the given leveldart (use only in MRMaps) + */ + unsigned int getNbInsertedDarts(unsigned int level) ; + + /** + * get the number of darts that define the map of the given leveldart (use only in MRMaps) + */ + unsigned int getNbDarts(unsigned int level) ; /** * @return the number of darts in the map */ unsigned int getNbDarts() ; + /** + * return true if the dart d refers to a valid index + */ + bool isDartValid(Dart d) ; + /**************************************** * EMBEDDING MANAGEMENT * ****************************************/ @@ -266,11 +301,11 @@ public: /** * Copy the index of the cell associated to a dart over an other dart - * @param d the dart to overwrite (dest) - * @param e the dart to copy (src) * @param orbit the id of orbit embedding + * @param dest the dart to overwrite + * @param src the dart to copy */ - void copyDartEmbedding(unsigned int orbit, Dart d, Dart e) ; + void copyDartEmbedding(unsigned int orbit, Dart dest, Dart src) ; /** * Allocation of some place in attrib table @@ -357,6 +392,11 @@ public: */ void initOrbitEmbedding(unsigned int orbit, bool realloc = false) ; + /** + * print attributes name of map in std::cout (for debugging) + */ + void viewAttributesTables() ; + protected: /**************************************** * EMBEDDING ATTRIBUTES MANAGEMENT * @@ -536,11 +576,6 @@ public: */ unsigned int getNbOrbits(unsigned int orbit, const FunctorSelect& good = allDarts) ; - /** - * print attributes name of map in std::cout (for debugging) - */ - void viewAttributesTables(); - protected: /// boundary marker Mark m_boundaryMarker; diff --git a/include/Topology/generic/genericmap.hpp b/include/Topology/generic/genericmap.hpp index a13a8f29..7607b086 100644 --- a/include/Topology/generic/genericmap.hpp +++ b/include/Topology/generic/genericmap.hpp @@ -25,13 +25,6 @@ namespace CGoGN { -inline unsigned int GenericMap::dartIndex(Dart d) -{ - if (m_isMultiRes) - return m_mrDarts[m_mrCurrentLevel]->operator[](d.index) ; - return d.index; -} - /**************************************** * MULTIRES * ****************************************/ @@ -49,6 +42,22 @@ inline void GenericMap::setCurrentLevel(unsigned int l) CGoGNout << "setCurrentLevel : try to access nonexistent resolution level" << CGoGNendl ; } +inline void GenericMap::incCurrentLevel() +{ + if(m_mrCurrentLevel < m_mrDarts.size()) + ++m_mrCurrentLevel ; + else + CGoGNout << "incCurrentLevel : already at maximum resolution level" << CGoGNendl ; +} + +inline void GenericMap::decCurrentLevel() +{ + if(m_mrCurrentLevel > 0) + --m_mrCurrentLevel ; + else + CGoGNout << "decCurrentLevel : already at minimum resolution level" << CGoGNendl ; +} + inline void GenericMap::pushLevel() { m_mrLevelStack.push_back(m_mrCurrentLevel) ; @@ -65,11 +74,6 @@ inline unsigned int GenericMap::getMaxLevel() return m_mrDarts.size() - 1 ; } -inline unsigned int GenericMap::getDartLevel(Dart d) -{ - return m_mrLevels->operator[](d.index) ; -} - /**************************************** * DARTS MANAGEMENT * ****************************************/ @@ -82,86 +86,173 @@ inline Dart GenericMap::newDart() if (m_embeddings[i]) (*m_embeddings[i])[di] = EMBNULL ; } + if (m_isMultiRes) { unsigned int mrdi = m_mrattribs.insertLine() ; - m_mrLevels->operator[](mrdi) = m_mrCurrentLevel ; + (*m_mrLevels)[mrdi] = m_mrCurrentLevel ; + m_mrNbDarts[m_mrCurrentLevel]++ ; for(unsigned int i = 0; i < m_mrCurrentLevel; ++i) - m_mrDarts[i]->operator[](mrdi) = MRNULL ; + (*m_mrDarts[i])[mrdi] = MRNULL ; - m_mrDarts[m_mrCurrentLevel]->operator[](mrdi) = di ; + (*m_mrDarts[m_mrCurrentLevel])[mrdi] = di ; for(unsigned int i = m_mrCurrentLevel + 1; i < m_mrDarts.size(); ++i) - { - unsigned int dj = m_attribs[DART].insertLine(); - for(unsigned int o = 0; o < NB_ORBITS; ++o) - { - if (m_embeddings[o]) - (*m_embeddings[o])[dj] = EMBNULL ; - } - m_mrDarts[i]->operator[](mrdi) = dj ; - } + (*m_mrDarts[i])[mrdi] = newCopyOfDartLine(di) ; + return Dart::create(mrdi) ; } + return Dart::create(di) ; } inline void GenericMap::deleteDart(Dart d) { - unsigned int d_index = dartIndex(d); - m_attribs[DART].removeLine(d_index) ; - for (unsigned int t = 0; t < m_nbThreads; ++t) - m_markTables[DART][t]->operator[](d_index).clear() ; + // hypothese : lors d'une suppression de brin, les attributs du brin supprimé + // sont identiques à tous les niveaux > au niveau où a lieu la suppression + if(m_isMultiRes) + { + // if a dart is deleted on its insertion level + // all the darts pointed in greater levels are deleted + // and then the MRdart is deleted + if((*m_mrLevels)[d.index] == m_mrCurrentLevel) + { + for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i) + deleteDartLine((*m_mrDarts[i])[d.index]) ; + m_mrattribs.removeLine(d.index) ; + m_mrNbDarts[m_mrCurrentLevel]-- ; + } + // if a dart is deleted after its insertion level + // the dart of previous level is copied in the greater levels + else + { + unsigned int dprev = (*m_mrDarts[m_mrCurrentLevel - 1])[d.index] ; + for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i) + copyDartLine((*m_mrDarts[i])[d.index], dprev) ; + } + } + else + deleteDartLine(dartIndex(d)) ; +} + +inline void GenericMap::deleteDartLine(unsigned int index) +{ + m_attribs[DART].removeLine(index) ; // free the dart line + + for (unsigned int t = 0; t < m_nbThreads; ++t) // clear markers of + (*m_markTables[DART][t])[index].clear() ; // the removed dart for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit) { - if (m_embeddings[orbit]) + if (m_embeddings[orbit]) // for each embedded orbit { - unsigned int emb = (*m_embeddings[orbit])[d_index] ; + unsigned int emb = (*m_embeddings[orbit])[index] ; // get the embedding of the dart if(emb != EMBNULL) { - if(m_attribs[orbit].unrefLine(emb)) + if(m_attribs[orbit].unrefLine(emb)) // unref the pointed embedding line { - for (unsigned int t = 0; t < m_nbThreads; ++t) - m_markTables[orbit][t]->operator[](emb).clear() ; + for (unsigned int t = 0; t < m_nbThreads; ++t) // and clear its markers if it was + (*m_markTables[orbit][t])[emb].clear() ; // its last unref (and was thus freed) } } } } +} - // hypothese : le brin MR pointe vers le même brin pour tous les niveaux >= au courant - if(m_isMultiRes) +inline void GenericMap::copyDartLine(unsigned int dest, unsigned int src) +{ + for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit) { - if(m_mrCurrentLevel == 0) - m_mrattribs.removeLine(d.index) ; - else + if (m_embeddings[orbit]) // for each embedded orbit { - unsigned int di = m_mrDarts[m_mrCurrentLevel - 1]->operator[](d.index) ; - for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i) - m_mrDarts[i]->operator[](d.index) = di ; + unsigned int emb = (*m_embeddings[orbit])[dest] ; // get the embedding of the destination dart + if(emb != EMBNULL) + { + if(m_attribs[orbit].unrefLine(emb)) // unref the pointed embedding line + { + for (unsigned int t = 0; t < m_nbThreads; ++t) // and clear its markers if it was + (*m_markTables[orbit][t])[emb].clear() ; // its last unref (and was thus freed) + } + } + } + } + + m_attribs[DART].copyLine(dest, src) ; + + for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit) + { + if (m_embeddings[orbit]) // for each embedded orbit + { + unsigned int emb = (*m_embeddings[orbit])[src] ; // add a ref to the pointed attributes + if(emb != EMBNULL) + m_attribs[orbit].refLine(emb) ; } } } -inline bool GenericMap::isDartValid(Dart d) +inline unsigned int GenericMap::newCopyOfDartLine(unsigned int index) { - return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ; + unsigned int newindex = m_attribs[DART].insertLine() ; + m_attribs[DART].copyLine(newindex, index) ; + for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit) + { + if (m_embeddings[orbit]) + { + unsigned int emb = (*m_embeddings[orbit])[newindex] ; // add a ref to the pointed attributes + if(emb != EMBNULL) + m_attribs[orbit].refLine(emb) ; + } + } + return newindex ; } -inline unsigned int GenericMap::getNbDarts() +inline unsigned int GenericMap::dartIndex(Dart d) { - if(m_isMultiRes) + if (m_isMultiRes) + return (*m_mrDarts[m_mrCurrentLevel])[d.index] ; + return d.index; +} + +inline unsigned int GenericMap::getDartLevel(Dart d) +{ + return (*m_mrLevels)[d.index] ; +} + +inline unsigned int GenericMap::getNbInsertedDarts(unsigned int level) +{ + if(level < m_mrDarts.size()) + return m_mrNbDarts[level] ; + else + return 0 ; +} + +inline unsigned int GenericMap::getNbDarts(unsigned int level) +{ + if(level < m_mrDarts.size()) { - unsigned int nbDarts = 0 ; - for(unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i)) - if(m_mrLevels->operator[](i) <= m_mrCurrentLevel) - ++nbDarts ; - return nbDarts ; + unsigned int nb = 0 ; + for(unsigned int i = 0; i <= level; ++i) + nb += m_mrNbDarts[i] ; + return nb ; } + else + return 0 ; +} + +inline unsigned int GenericMap::getNbDarts() +{ + if(m_isMultiRes) + return getNbDarts(m_mrCurrentLevel) ; + return m_attribs[DART].size() ; } +inline bool GenericMap::isDartValid(Dart d) +{ + return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ; +} + /**************************************** * EMBEDDING MANAGEMENT * ****************************************/ @@ -192,10 +283,10 @@ inline unsigned int GenericMap::getEmbedding(unsigned int orbit, Dart d) return (*m_embeddings[orbit])[d_index] ; } -inline void GenericMap::copyDartEmbedding(unsigned int orbit, Dart d, Dart e) +inline void GenericMap::copyDartEmbedding(unsigned int orbit, Dart dest, Dart src) { assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded"); - setDartEmbedding(orbit, d, getEmbedding(orbit, e)); + setDartEmbedding(orbit, dest, getEmbedding(orbit, src)); } inline unsigned int GenericMap::newCell(unsigned int orbit) @@ -313,7 +404,7 @@ inline AttributeMultiVector* GenericMap::addRelation(const std::string& na // set new relation to fix point for all the darts of the map for(unsigned int i = cont.begin(); i < cont.end(); cont.next(i)) - amv->operator[](i) = i ; + (*amv)[i] = i ; return amv ; } diff --git a/src/Topology/generic/genericmap.cpp b/src/Topology/generic/genericmap.cpp index 86bd9faf..17812755 100644 --- a/src/Topology/generic/genericmap.cpp +++ b/src/Topology/generic/genericmap.cpp @@ -122,23 +122,6 @@ GenericMap::~GenericMap() } } -void GenericMap::initMR() -{ -#ifndef CGoGN_FORCE_MR - m_isMultiRes = true; -#endif - - m_mrattribs.clear(true) ; - m_mrDarts.clear() ; - m_mrDarts.reserve(16) ; - m_mrLevelStack.clear() ; - m_mrLevelStack.reserve(16) ; - - m_mrLevels = m_mrattribs.addAttribute("MRLevel") ; - addLevel() ; - setCurrentLevel(0) ; -} - void GenericMap::clear(bool removeAttrib) { if (removeAttrib) @@ -155,9 +138,7 @@ void GenericMap::clear(bool removeAttrib) else { for(unsigned int i = 0; i < NB_ORBITS; ++i) - { m_attribs[i].clear(false) ; - } } if (m_isMultiRes) @@ -168,6 +149,42 @@ void GenericMap::clear(bool removeAttrib) * MULTIRES * ****************************************/ +void GenericMap::printMR() +{ + std::cout << std::endl ; + + for(unsigned int j = 0; j < m_mrNbDarts.size(); ++j) + std::cout << m_mrNbDarts[j] << " / " ; + std::cout << std::endl << "==========" << std::endl ; + + for(unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i)) + { + std::cout << (*m_mrLevels)[i] << " / " ; + for(unsigned int j = 0; j < m_mrDarts.size(); ++j) + std::cout << (*m_mrDarts[j])[i] << " ; " ; + std::cout << std::endl ; + } +} + +void GenericMap::initMR() +{ +#ifndef CGoGN_FORCE_MR + m_isMultiRes = true; +#endif + + m_mrattribs.clear(true) ; + m_mrDarts.clear() ; + m_mrDarts.reserve(16) ; + m_mrNbDarts.clear(); + m_mrNbDarts.reserve(16); + m_mrLevelStack.clear() ; + m_mrLevelStack.reserve(16) ; + + m_mrLevels = m_mrattribs.addAttribute("MRLevel") ; + addLevel() ; + setCurrentLevel(0) ; +} + void GenericMap::addLevel() { unsigned int newLevel = m_mrDarts.size() ; @@ -176,20 +193,41 @@ void GenericMap::addLevel() AttributeMultiVector* amvMR = m_mrattribs.addAttribute(ss.str()) ; m_mrDarts.push_back(amvMR) ; + m_mrNbDarts.push_back(0) ; - // copy the darts pointers of the previous level if(m_mrDarts.size() > 1) + { + // copy the darts indices of the previous level m_mrattribs.copyAttribute(amvMR->getIndex(), m_mrDarts[newLevel - 1]->getIndex()) ; - // duplicate all the darts in the new level - for(unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i)) + // duplicate all the darts in the new level + for(unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i)) + { + unsigned int oldi = (*amvMR)[i] ; // get the index of the dart in previous level + (*amvMR)[i] = newCopyOfDartLine(oldi) ; // copy the dart and affect it to the new level + } + } +} + +void GenericMap::removeLevel() +{ + if(!m_mrDarts.empty()) { - unsigned int oldi = amvMR->operator[](i) ; - unsigned int newi = m_attribs[DART].insertLine() ; - m_attribs[DART].copyLine(newi, oldi) ; - amvMR->operator[](i) = newi ; - for(unsigned int t = 0; t < m_nbThreads; ++t) - m_markTables[DART][t]->operator[](newi).clear() ; + unsigned int maxL = getMaxLevel() ; + AttributeMultiVector* amvMR = m_mrDarts[maxL] ; + for(unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i)) + { + deleteDartLine((*amvMR)[i]) ; + if((*m_mrLevels)[i] == maxL) + m_mrattribs.removeLine(i) ; + } + + m_mrattribs.removeAttribute(m_mrDarts[maxL]->getIndex()) ; + m_mrDarts.pop_back() ; + m_mrNbDarts.pop_back() ; + + if(m_mrCurrentLevel == maxL) + --m_mrCurrentLevel ; } } @@ -210,8 +248,8 @@ void GenericMap::setDartEmbedding(unsigned int orbit, Dart d, unsigned int emb) { if(m_attribs[orbit].unrefLine(old)) { - for (unsigned int t = 0; t < m_nbThreads; ++t) - m_markTables[orbit][t]->operator[](old).clear(); + for (unsigned int t = 0; t < m_nbThreads; ++t) // clear the markers if it was the + (*m_markTables[orbit][t])[old].clear(); // last unref of the line } } // ref the new emb @@ -287,6 +325,32 @@ void GenericMap::initOrbitEmbedding(unsigned int orbit, bool realloc) } } +void GenericMap::viewAttributesTables() +{ + std::cout << "======================="<< std::endl ; + for (unsigned int i = 0; i < NB_ORBITS; ++i) + { + std::cout << "ATTRIBUTE_CONTAINER " << i << std::endl ; + AttributeContainer& cont = m_attribs[i] ; + + // get the list of attributes + std::vector listeNames ; + cont.getAttributesNames(listeNames) ; + for (std::vector::iterator it = listeNames.begin(); it != listeNames.end(); ++it) + std::cout << " " << *it << std::endl ; + std::cout << "-------------------------" << std::endl ; + } + std::cout << "m_embeddings: " << std::hex ; + for (unsigned int i = 0; i < NB_ORBITS; ++i) + std::cout << (long)(m_embeddings[i]) << " / " ; + std::cout << std::endl << "-------------------------" << std::endl ; + + std::cout << "m_markTables: " ; + for (unsigned int i = 0; i < NB_ORBITS; ++i) + std::cout << (long)(m_markTables[i][0]) << " / " ; + std::cout << std::endl << "-------------------------" << std::endl << std::dec ; +} + /**************************************** * EMBEDDING ATTRIBUTES MANAGEMENT * ****************************************/ @@ -304,7 +368,7 @@ void GenericMap::addEmbedding(unsigned int orbit) // set new embedding to EMBNULL for all the darts of the map for(unsigned int i = dartCont.begin(); i < dartCont.end(); dartCont.next(i)) - amv->operator[](i) = EMBNULL ; + (*amv)[i] = EMBNULL ; } /**************************************** @@ -769,32 +833,6 @@ unsigned int GenericMap::getNbOrbits(unsigned int orbit, const FunctorSelect& go return fcount.getNb(); } -void GenericMap::viewAttributesTables() -{ - std::cout << "======================="<< std::endl; - for (unsigned int i = 0; i < NB_ORBITS; ++i) - { - std::cout << "ATTRIBUTE_CONTAINER " << i << std::endl; - AttributeContainer& cont = m_attribs[i] ; - - // get the list of attributes - std::vector listeNames; - cont.getAttributesNames(listeNames); - for (std::vector::iterator it = listeNames.begin(); it != listeNames.end(); ++it) - std::cout << " " << *it << std::endl; - std::cout << "-------------------------" << std::endl; - } - std::cout << "m_embeddings: " << std::hex; - for (unsigned int i = 0; i < NB_ORBITS; ++i) - std::cout << (long)(m_embeddings[i]) << " / "; - std::cout << std::endl << "-------------------------" << std::endl; - - std::cout << "m_markTables: "; - for (unsigned int i = 0; i < NB_ORBITS; ++i) - std::cout << (long)(m_markTables[i][0]) << " / "; - std::cout << std::endl << "-------------------------" << std::endl << std::dec; -} - void GenericMap::boundaryMark(Dart d) { m_markTables[DART][0]->operator[](dartIndex(d)).setMark(m_boundaryMarker); diff --git a/src/Topology/map/map2MR/map2MR_Primal.cpp b/src/Topology/map/map2MR/map2MR_Primal.cpp index 9f5b4808..67517679 100644 --- a/src/Topology/map/map2MR/map2MR_Primal.cpp +++ b/src/Topology/map/map2MR/map2MR_Primal.cpp @@ -137,9 +137,9 @@ bool Map2MR_Primal::edgeIsSubdivided(Dart d) return false ; Dart d2 = phi2(d) ; - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; Dart d2_l = phi2(d) ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; if(d2 != d2_l) return true ; else @@ -156,14 +156,14 @@ bool Map2MR_Primal::edgeCanBeCoarsened(Dart d) bool degree2 = false ; Dart d2 = phi2(d) ; - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; if(vertexDegree(phi1(d)) == 2) { degree2 = true ; if(edgeIsSubdivided(d) || edgeIsSubdivided(d2)) subdOnce = false ; } - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; return degree2 && subdOnce ; } @@ -183,10 +183,10 @@ bool Map2MR_Primal::faceIsSubdivided(Dart d) return false ; // the current level can not be subdivided to higher levels bool subd = false ; - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; if(getDartLevel(phi1(phi1(d))) == getCurrentLevel()) subd = true ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; return subd ; } @@ -205,28 +205,28 @@ bool Map2MR_Primal::faceIsSubdividedOnce(Dart d) bool subd = false ; bool subdOnce = true ; - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; if(getDartLevel(phi1(phi1(d))) == getCurrentLevel()) subd = true ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; if(subd) { - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; if(getCurrentLevel() == getMaxLevel()) { - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; return true ; } Dart fit = d ; do { - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; if(getDartLevel(phi1(phi1(fit))) == getCurrentLevel()) subdOnce = false ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; ++degree ; fit = phi1(fit) ; } while(subdOnce && fit != d) ; @@ -234,13 +234,13 @@ bool Map2MR_Primal::faceIsSubdividedOnce(Dart d) if(degree == 3 && subdOnce) { Dart cf = phi2(phi1(d)) ; - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; if(getDartLevel(phi1(phi1(cf))) == getCurrentLevel()) subdOnce = false ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; } - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; return subdOnce ; } @@ -332,9 +332,13 @@ void Map2MR_Primal::coarsenEdge(Dart d) assert(getDartLevel(d) <= getCurrentLevel() || !"coarsenEdge : called with a dart introduced after current level") ; assert(edgeCanBeCoarsened(d) || !"Trying to coarsen an edge that can not be coarsened") ; - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; uncutEdge(d) ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; + + unsigned int maxL = getMaxLevel() ; + if(getCurrentLevel() == maxL - 1 && getNbInsertedDarts(maxL) == 0) + removeLevel() ; } void Map2MR_Primal::coarsenFace(Dart d) @@ -355,21 +359,21 @@ void Map2MR_Primal::coarsenFace(Dart d) fit = d ; do { - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; Dart innerEdge = phi1(fit) ; setCurrentLevel(getMaxLevel()) ; mergeFaces(innerEdge) ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; fit = phi1(fit) ; } while(fit != d) ; } else { - setCurrentLevel(getCurrentLevel() + 1) ; + incCurrentLevel() ; Dart centralV = phi1(phi1(d)) ; setCurrentLevel(getMaxLevel()) ; deleteVertex(centralV) ; - setCurrentLevel(getCurrentLevel() - 1) ; + decCurrentLevel() ; } fit = d ; @@ -379,6 +383,10 @@ void Map2MR_Primal::coarsenFace(Dart d) coarsenEdge(fit) ; fit = phi1(fit) ; } while(fit != d) ; + + unsigned int maxL = getMaxLevel() ; + if(getCurrentLevel() == maxL - 1 && getNbInsertedDarts(maxL) == 0) + removeLevel() ; } } // namespace CGoGN -- GitLab