/******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation; either version 2.1 of the License, or (at your * * option) any later version. * * * * This library is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this library; if not, write to the Free Software Foundation, * * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * Web site: http://cgogn.unistra.fr/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ #include "Topology/generic/dartmarker.h" #include "Topology/generic/traversorCell.h" #include "Topology/generic/traversorFactory.h" namespace CGoGN { /**************************************** * MULTIRES * ****************************************/ inline unsigned int GenericMap::getCurrentLevel() { return m_mrCurrentLevel ; } inline void GenericMap::setCurrentLevel(unsigned int l) { if(l < m_mrDarts.size()) m_mrCurrentLevel = l ; else CGoGNout << "setCurrentLevel : try to access nonexistent resolution level" << CGoGNendl ; } inline void GenericMap::incCurrentLevel() { if(m_mrCurrentLevel < m_mrDarts.size() - 1) ++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) ; } inline void GenericMap::popLevel() { m_mrCurrentLevel = m_mrLevelStack.back() ; m_mrLevelStack.pop_back() ; } inline unsigned int GenericMap::getMaxLevel() { return m_mrDarts.size() - 1 ; } /**************************************** * DARTS MANAGEMENT * ****************************************/ inline Dart GenericMap::newDart() { unsigned int di = m_attribs[DART].insertLine(); // insert a new dart line for(unsigned int i = 0; i < NB_ORBITS; ++i) { if (m_embeddings[i]) // set all its embeddings (*m_embeddings[i])[di] = EMBNULL ; // to EMBNULL } if (m_isMultiRes) { unsigned int mrdi = m_mrattribs.insertLine() ; // insert a new MRdart line (*m_mrLevels)[mrdi] = m_mrCurrentLevel ; // set the introduction level of the dart m_mrNbDarts[m_mrCurrentLevel]++ ; for(unsigned int i = 0; i < m_mrCurrentLevel; ++i) // for all previous levels (*m_mrDarts[i])[mrdi] = MRNULL ; // this MRdart does not exist for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i) // for all levels from current to max (*m_mrDarts[i])[mrdi] = di ; // make this MRdart point to the new dart line return Dart::create(mrdi) ; } return Dart::create(di) ; } inline void GenericMap::deleteDart(Dart d) { if(m_isMultiRes) { unsigned int index = (*m_mrDarts[m_mrCurrentLevel])[d.index] ; if(getDartLevel(d) > m_mrCurrentLevel) { unsigned int di = (*m_mrDarts[m_mrCurrentLevel + 1])[d.index]; // si le brin de niveau i pointe sur le meme brin que le niveau i-1 if(di != index) { if(isDartValid(d))//index)) deleteDartLine(index) ; } (*m_mrDarts[m_mrCurrentLevel])[d.index] = MRNULL ; return; } // a MRdart can only be deleted on its insertion level if(getDartLevel(d) == m_mrCurrentLevel) { if(isDartValid(d)) { deleteDartLine(index) ; m_mrattribs.removeLine(d.index); m_mrNbDarts[m_mrCurrentLevel]--; } } else { unsigned int di = (*m_mrDarts[m_mrCurrentLevel - 1])[d.index]; // si le brin de niveau i pointe sur le meme brin que le niveau i-1 if(di != index) { if(isDartValid(d))//index)) deleteDartLine(index) ; } for(unsigned int i = m_mrCurrentLevel; i <= getMaxLevel(); ++i) // for all levels from current to max { (*m_mrDarts[i])[d.index] = di ; //copy the index from previous level } } } 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]) // for each embedded orbit { unsigned int emb = (*m_embeddings[orbit])[index] ; // get the embedding of the 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) } } } } } inline unsigned int GenericMap::copyDartLine(unsigned int index) { unsigned int newindex = m_attribs[DART].insertLine() ; // create a new dart line m_attribs[DART].copyLine(newindex, index) ; // copy the given dart line 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 cells pointed if(emb != EMBNULL) // by the new dart line m_attribs[orbit].refLine(emb) ; } } return newindex ; } inline void GenericMap::duplicateDart(Dart d) { assert(getDartLevel(d) <= m_mrCurrentLevel || !"duplicateDart : called with a dart inserted after current level") ; if(getDartLevel(d) == m_mrCurrentLevel) // no need to duplicate return ; // a dart from its insertion level unsigned int oldindex = dartIndex(d) ; if(m_mrCurrentLevel > 0) { if((*m_mrDarts[m_mrCurrentLevel - 1])[d.index] != oldindex) // no need to duplicate if the dart is already return ; // duplicated with respect to previous level } unsigned int newindex = copyDartLine(oldindex) ; for(unsigned int i = m_mrCurrentLevel; i <= getMaxLevel(); ++i) // for all levels from current to max { assert((*m_mrDarts[i])[d.index] == oldindex || !"duplicateDart : dart was already duplicated on a greater level") ; (*m_mrDarts[i])[d.index] = newindex ; // make this MRdart points to the new dart line } } inline void GenericMap::duplicateDartAtOneLevel(Dart d, unsigned int level) { (*m_mrDarts[level])[d.index] = copyDartLine(dartIndex(d)) ; } inline unsigned int GenericMap::dartIndex(Dart d) const { if (m_isMultiRes) return (*m_mrDarts[m_mrCurrentLevel])[d.index] ; return d.index; } inline unsigned int GenericMap::getDartLevel(Dart d) const { return (*m_mrLevels)[d.index] ; } inline void GenericMap::incDartLevel(Dart d) const { ++((*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 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 * ****************************************/ template inline bool GenericMap::isOrbitEmbedded() const { return (ORBIT == DART) || (m_embeddings[ORBIT] != NULL) ; } inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const { return (orbit == DART) || (m_embeddings[orbit] != NULL) ; } template inline unsigned int GenericMap::getEmbedding(Dart d) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); unsigned int d_index = dartIndex(d); if (ORBIT == DART) return d_index; return (*m_embeddings[ORBIT])[d_index] ; } template void GenericMap::setDartEmbedding(Dart d, unsigned int emb) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); unsigned int old = getEmbedding(d); if (old == emb) // if same emb return; // nothing to do if (old != EMBNULL) // if different { if(m_attribs[ORBIT].unrefLine(old)) // then unref the old emb { 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 } } if (emb != EMBNULL) m_attribs[ORBIT].refLine(emb); // ref the new emb (*m_embeddings[ORBIT])[dartIndex(d)] = emb ; // finally affect the embedding to the dart } template void GenericMap::initDartEmbedding(Dart d, unsigned int emb) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); assert(getEmbedding(d) == EMBNULL || !"initDartEmbedding called on already embedded dart"); if(emb != EMBNULL) m_attribs[ORBIT].refLine(emb); // ref the new emb (*m_embeddings[ORBIT])[dartIndex(d)] = emb ; // affect the embedding to the dart } template inline void GenericMap::copyDartEmbedding(Dart dest, Dart src) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); setDartEmbedding(dest, getEmbedding(src)); } template inline unsigned int GenericMap::newCell() { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); return m_attribs[ORBIT].insertLine(); } template inline void GenericMap::setOrbitEmbedding(Dart d, unsigned int em) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); FunctorSetEmb fsetemb(*this, em); foreach_dart_of_orbit(d, fsetemb); } template inline void GenericMap::initOrbitEmbedding(Dart d, unsigned int em) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); FunctorInitEmb fsetemb(*this, em); foreach_dart_of_orbit(d, fsetemb); } template inline unsigned int GenericMap::setOrbitEmbeddingOnNewCell(Dart d) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); unsigned int em = newCell(); setOrbitEmbedding(d, em); return em; } template inline unsigned int GenericMap::initOrbitEmbeddingNewCell(Dart d) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); unsigned int em = newCell(); initOrbitEmbedding(d, em); return em; } template inline void GenericMap::copyCell(Dart d, Dart e) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); unsigned int dE = getEmbedding(d) ; unsigned int eE = getEmbedding(e) ; if(eE != EMBNULL) // if the source is NULL, nothing to copy { if(dE == EMBNULL) // if the dest is NULL, create a new cell dE = setOrbitEmbeddingOnNewCell(d) ; m_attribs[ORBIT].copyLine(dE, eE) ; // copy the data } } template inline void GenericMap::copyCell(unsigned int i, unsigned int j) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); m_attribs[ORBIT].copyLine(i, j) ; } template inline void GenericMap::initCell(unsigned int i) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); m_attribs[ORBIT].initLine(i) ; } template void GenericMap::initAllOrbitsEmbedding(bool realloc) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded") ; DartMarker mark(*this) ; for(Dart d = begin(); d != end(); next(d)) { if(!mark.isMarked(d)) { mark.markOrbit(d) ; if(realloc || getEmbedding(d) == EMBNULL) setOrbitEmbeddingOnNewCell(d) ; } } } /**************************************** * QUICK TRAVERSAL MANAGEMENT * ****************************************/ template inline void GenericMap::enableQuickTraversal() { if(m_quickTraversal[ORBIT] == NULL) { if(!isOrbitEmbedded()) addEmbedding() ; m_quickTraversal[ORBIT] = m_attribs[ORBIT].addAttribute("quick_traversal") ; } updateQuickTraversal() ; } template inline void GenericMap::updateQuickTraversal() { assert(m_quickTraversal[ORBIT] != NULL || !"updateQuickTraversal on a disabled orbit") ; CellMarker cm(*this) ; for(Dart d = begin(); d != end(); next(d)) { if(!cm.isMarked(d)) { cm.mark(d) ; (*m_quickTraversal[ORBIT])[getEmbedding(d)] = d ; } } } template inline AttributeMultiVector* GenericMap::getQuickTraversal() { return m_quickTraversal[ORBIT] ; } template inline void GenericMap::disableQuickTraversal() { if(m_quickTraversal[ORBIT] != NULL) { m_attribs[ORBIT].removeAttribute(m_quickTraversal[ORBIT]->getIndex()) ; m_quickTraversal[ORBIT] = NULL ; } } template inline void GenericMap::enableQuickIncidentTraversal() { if(m_quickLocalIncidentTraversal[ORBIT][INCI] == NULL) { if(!isOrbitEmbedded()) addEmbedding() ; std::stringstream ss; ss << "quickLocalIncidentTraversal_" << INCI; m_quickLocalIncidentTraversal[ORBIT][INCI] = m_attribs[ORBIT].addAttribute > >(ss.str()) ; } updateQuickIncidentTraversal() ; } template inline void GenericMap::updateQuickIncidentTraversal() { assert(m_quickLocalIncidentTraversal[ORBIT][INCI] != NULL || !"updateQuickTraversal on a disabled orbit") ; AttributeMultiVector > >* ptrVD = m_quickLocalIncidentTraversal[ORBIT][INCI]; m_quickLocalIncidentTraversal[ORBIT][INCI] = NULL; std::vector buffer; buffer.reserve(100); MAP& map = static_cast(*this); TraversorCell tra_glob(map); for (Dart d = tra_glob.begin(); d != tra_glob.end(); d = tra_glob.next()) { buffer.clear(); Traversor* tra_loc = TraversorFactory::createIncident(map, d, map.dimension(), ORBIT, INCI); for (Dart e = tra_loc->begin(); e != tra_loc->end(); e = tra_loc->next()) buffer.push_back(e); delete tra_loc; buffer.push_back(NIL); std::vector& vd = (*ptrVD)[getEmbedding(d)]; vd.reserve(buffer.size()); vd.assign(buffer.begin(),buffer.end()); } m_quickLocalIncidentTraversal[ORBIT][INCI] = ptrVD; } template inline AttributeMultiVector > >* GenericMap::getQuickIncidentTraversal() { return m_quickLocalIncidentTraversal[ORBIT][INCI] ; } template inline void GenericMap::disableQuickIncidentTraversal() { if(m_quickLocalIncidentTraversal[ORBIT][INCI] != NULL) { m_attribs[ORBIT].removeAttribute(m_quickLocalIncidentTraversal[ORBIT][INCI]->getIndex()) ; m_quickLocalIncidentTraversal[ORBIT][INCI] = NULL ; } } template inline void GenericMap::enableQuickAdjacentTraversal() { if(m_quickLocalAdjacentTraversal[ORBIT][ADJ] == NULL) { if(!isOrbitEmbedded()) addEmbedding() ; std::stringstream ss; ss << "quickLocalAdjacentTraversal" << ADJ; m_quickLocalAdjacentTraversal[ORBIT][ADJ] = m_attribs[ORBIT].addAttribute > >(ss.str()) ; } updateQuickAdjacentTraversal() ; } template inline void GenericMap::updateQuickAdjacentTraversal() { assert(m_quickLocalAdjacentTraversal[ORBIT][ADJ] != NULL || !"updateQuickTraversal on a disabled orbit") ; AttributeMultiVector > >* ptrVD = m_quickLocalAdjacentTraversal[ORBIT][ADJ]; m_quickLocalAdjacentTraversal[ORBIT][ADJ] = NULL; MAP& map = static_cast(*this); std::vector buffer; buffer.reserve(100); TraversorCell tra_glob(map); for (Dart d = tra_glob.begin(); d != tra_glob.end(); d = tra_glob.next()) { buffer.clear(); Traversor* tra_loc = TraversorFactory::createAdjacent(map, d, map.dimension(), ORBIT, ADJ); for (Dart e = tra_loc->begin(); e != tra_loc->end(); e = tra_loc->next()) buffer.push_back(e); buffer.push_back(NIL); delete tra_loc; std::vector& vd = (*ptrVD)[getEmbedding(d)]; vd.reserve(buffer.size()); vd.assign(buffer.begin(),buffer.end()); } m_quickLocalAdjacentTraversal[ORBIT][ADJ] = ptrVD; } template inline AttributeMultiVector > >* GenericMap::getQuickAdjacentTraversal() { return m_quickLocalAdjacentTraversal[ORBIT][ADJ] ; } template inline void GenericMap::disableQuickAdjacentTraversal() { if(m_quickLocalAdjacentTraversal[ORBIT][ADJ] != NULL) { m_attribs[ORBIT].removeAttribute(m_quickLocalAdjacentTraversal[ORBIT][ADJ]->getIndex()) ; m_quickLocalAdjacentTraversal[ORBIT][ADJ] = NULL ; } } /**************************************** * ATTRIBUTES MANAGEMENT * ****************************************/ inline unsigned int GenericMap::getNbCells(unsigned int orbit) { return m_attribs[orbit].size() ; } template inline AttributeContainer& GenericMap::getAttributeContainer() { return m_attribs[ORBIT] ; } inline AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit) { return m_attribs[orbit] ; } template inline AttributeMultiVector* GenericMap::getMarkVector(unsigned int thread) { assert(isOrbitEmbedded() || !"Invalid parameter: orbit not embedded") ; return m_markTables[ORBIT][thread] ; } template inline AttributeMultiVector* GenericMap::getEmbeddingAttributeVector() { return m_embeddings[ORBIT] ; } inline AttributeContainer& GenericMap::getMRAttributeContainer() { return m_mrattribs ; } inline AttributeMultiVector* GenericMap::getMRDartAttributeVector(unsigned int level) { assert(level <= getMaxLevel() || !"Invalid parameter: level does not exist"); return m_mrDarts[level] ; } inline AttributeMultiVector* GenericMap::getMRLevelAttributeVector() { return m_mrLevels ; } template bool GenericMap::registerAttribute(const std::string &nameType) { RegisteredBaseAttribute* ra = new RegisteredAttribute; if (ra == NULL) { CGoGNerr << "Erreur enregistrement attribut" << CGoGNendl; return false; } ra->setTypeName(nameType); m_attributes_registry_map->insert(std::pair(nameType,ra)); return true; } /**************************************** * EMBEDDING ATTRIBUTES MANAGEMENT * ****************************************/ template void GenericMap::addEmbedding() { assert(!isOrbitEmbedded() || !"Invalid parameter: orbit already embedded") ; std::ostringstream oss; oss << "EMB_" << ORBIT; AttributeContainer& dartCont = m_attribs[DART] ; AttributeMultiVector* amv = dartCont.addAttribute(oss.str()) ; m_embeddings[ORBIT] = amv ; // 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)[i] = EMBNULL ; } /**************************************** * DARTS TRAVERSALS * ****************************************/ inline Dart GenericMap::realBegin() const { if (m_isMultiRes) { unsigned int d = m_mrattribs.begin() ; if(d != m_mrattribs.end()) { while (getDartLevel(d) > m_mrCurrentLevel) m_mrattribs.next(d) ; } return Dart::create(d) ; } return Dart::create(m_attribs[DART].begin()) ; } inline Dart GenericMap::realEnd() const { if (m_isMultiRes) return Dart::create(m_mrattribs.end()) ; return Dart::create(m_attribs[DART].end()) ; } inline void GenericMap::realNext(Dart& d) const { if (m_isMultiRes) { do { m_mrattribs.next(d.index) ; } while (d.index != m_mrattribs.end() && getDartLevel(d) > m_mrCurrentLevel) ; } else { m_attribs[DART].next(d.index) ; } } inline Dart GenericMap::begin() const { if (m_currentBrowser != NULL) return m_currentBrowser->begin(); return GenericMap::realBegin(); } inline Dart GenericMap::end() const { if (m_currentBrowser != NULL) return m_currentBrowser->end(); return GenericMap::realEnd(); } inline void GenericMap::next(Dart& d) const { if (m_currentBrowser != NULL) m_currentBrowser->next(d); else realNext(d); } //inline Dart GenericMap::begin() const //{ // if (m_isMultiRes) // { // unsigned int d = m_mrattribs.begin() ; // if(d != m_mrattribs.end()) // { // while (getDartLevel(d) > m_mrCurrentLevel) // m_mrattribs.next(d) ; // } // return Dart::create(d) ; // } // if (m_currentBrowser != NULL) // return m_currentBrowser->begin(); // return Dart::create(m_attribs[DART].begin()) ; //} //inline Dart GenericMap::end() const //{ // if (m_isMultiRes) // return Dart::create(m_mrattribs.end()) ; // if (m_currentBrowser != NULL) // return m_currentBrowser->end(); // return Dart::create(m_attribs[DART].end()) ; //} //inline void GenericMap::next(Dart& d) const //{ // if (m_isMultiRes) // { // do // { // m_mrattribs.next(d.index) ; // } while (d.index != m_mrattribs.end() && getDartLevel(d) > m_mrCurrentLevel) ; // } // else // { // if (m_currentBrowser != NULL) // return m_currentBrowser->next(d); // else // m_attribs[DART].next(d.index) ; // } //} template bool GenericMap::foreach_dart_of_orbit(Dart d, FunctorType& f, unsigned int thread) { switch(ORBIT) { case DART: return f(d); case VERTEX: return foreach_dart_of_vertex(d, f, thread); case EDGE: return foreach_dart_of_edge(d, f, thread); case FACE: return foreach_dart_of_face(d, f, thread); case VOLUME: return foreach_dart_of_volume(d, f, thread); case VERTEX1: return foreach_dart_of_vertex1(d, f, thread); case EDGE1: return foreach_dart_of_edge1(d, f, thread); case VERTEX2: return foreach_dart_of_vertex2(d, f, thread); case EDGE2: return foreach_dart_of_edge2(d, f, thread); case FACE2: return foreach_dart_of_face2(d, f, thread); default: assert(!"Cells of this dimension are not handled"); break; } return false; } template bool GenericMap::foreach_orbit(FunctorType& fonct, unsigned int thread) { TraversorCell trav(*this, true, thread); bool found = false; for (Dart d = trav.begin(); !found && d != trav.end(); d = trav.next()) { if ((fonct)(d)) found = true; } return found; } template unsigned int GenericMap::getNbOrbits() { FunctorCount fcount; foreach_orbit(fcount); return fcount.getNb(); } template unsigned int GenericMap::degree(Dart d) { assert(ORBIT != INCIDENT || !"degree does not manage adjacency counting") ; Traversor* t = TraversorFactory::createIncident(*(reinterpret_cast(this)), d, dimension(), ORBIT, INCIDENT) ; FunctorCount fcount ; t->applyFunctor(fcount) ; delete t ; return fcount.getNb() ; } /**************************************** * TOPOLOGICAL ATTRIBUTES MANAGEMENT * ****************************************/ inline AttributeMultiVector* GenericMap::addRelation(const std::string& name) { AttributeContainer& cont = m_attribs[DART] ; AttributeMultiVector* amv = cont.addAttribute(name) ; // 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)[i] = i ; return amv ; } inline AttributeMultiVector* GenericMap::getRelation(const std::string& name) { AttributeContainer& cont = m_attribs[DART] ; AttributeMultiVector* amv = cont.getDataVector(cont.getAttributeIndex(name)) ; return amv ; } /************************** * BOUNDARY MANAGEMENT * **************************/ template inline void GenericMap::boundaryMark(Dart d) { m_markTables[DART][0]->operator[](dartIndex(d)).setMark(m_boundaryMarkers[D-2]); } template inline void GenericMap::boundaryUnmark(Dart d) { m_markTables[DART][0]->operator[](dartIndex(d)).unsetMark(m_boundaryMarkers[D-2]); } template inline bool GenericMap::isBoundaryMarked(Dart d) const { return m_markTables[DART][0]->operator[](dartIndex(d)).testMark(m_boundaryMarkers[D-2]); } inline bool GenericMap::isBoundaryMarkedCurrent(Dart d) const { return m_markTables[DART][0]->operator[](dartIndex(d)).testMark(m_boundaryMarkers[this->dimension()-2]); } inline void GenericMap::boundaryMark2(Dart d) { boundaryMark<2>(d); } inline void GenericMap::boundaryUnmark2(Dart d) { boundaryUnmark<2>(d); } inline bool GenericMap::isBoundaryMarked2(Dart d) const { return isBoundaryMarked<2>(d); } inline void GenericMap::boundaryMark3(Dart d) { boundaryMark<3>(d); } inline void GenericMap::boundaryUnmark3(Dart d) { boundaryUnmark<3>(d); } inline bool GenericMap::isBoundaryMarked3(Dart d) const { return isBoundaryMarked<3>(d); } template void GenericMap::boundaryMarkOrbit(Dart d) { FunctorMark fm(*this, m_boundaryMarkers[DIM-2], m_markTables[DART][0]) ; foreach_dart_of_orbit(d, fm, 0) ; } template void GenericMap::boundaryUnmarkOrbit(Dart d) { FunctorUnmark fm(*this, m_boundaryMarkers[DIM-2], m_markTables[DART][0]) ; foreach_dart_of_orbit(d, fm, 0) ; } template void GenericMap::boundaryUnmarkAll() { AttributeContainer& cont = getAttributeContainer() ; for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i)) m_markTables[DART][0]->operator[](i).unsetMark(m_boundaryMarkers[DIM-2]); } } //namespace CGoGN