/******************************************************************************* * 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 * * * *******************************************************************************/ namespace CGoGN { /**************************************** * DARTS TRAVERSALS * ****************************************/ template template unsigned int MapCommon::degree(Dart d) const { assert(ORBIT != INCIDENT || !"degree does not manage adjacency counting") ; Traversor* t = TraversorFactory >::createIncident(*this, d, this->dimension(), ORBIT, INCIDENT) ; FunctorCount fcount ; t->applyFunctor(fcount) ; delete t ; return fcount.getNb() ; } template template bool MapCommon::sameOrbit(Cell c1, Cell c2, unsigned int thread) const { TraversorDartsOfOrbit< MapCommon, ORBIT> tradoo(*this,c1.dart,thread); for (Dart x= tradoo.begin(); x!=tradoo.end();x=tradoo.next()) { if (x==c2.dart) return true; } return false; } /**************************************** * EMBEDDING MANAGEMENT * ****************************************/ template template inline unsigned int MapCommon::getEmbedding(Dart d) const { assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); if (ORBIT == DART) return this->dartIndex(d); return (*this->m_embeddings[ORBIT])[this->dartIndex(d)] ; } template template void MapCommon::setDartEmbedding(Dart d, unsigned int emb) { assert(this->template 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(this->m_attribs[ORBIT].unrefLine(old)) // then unref the old emb { for (unsigned int t = 0; t < this->m_nbThreads; ++t) // clear the markers if it was the (*this->m_markTables[ORBIT][t])[old].clear(); // last unref of the line } } if (emb != EMBNULL) this->m_attribs[ORBIT].refLine(emb); // ref the new emb (*this->m_embeddings[ORBIT])[this->dartIndex(d)] = emb ; // finally affect the embedding to the dart } template template void MapCommon::initDartEmbedding(Dart d, unsigned int emb) { assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); assert(getEmbedding(d) == EMBNULL || !"initDartEmbedding called on already embedded dart"); if(emb != EMBNULL) this->m_attribs[ORBIT].refLine(emb); // ref the new emb (*this->m_embeddings[ORBIT])[this->dartIndex(d)] = emb ; // affect the embedding to the dart } template template inline void MapCommon::copyDartEmbedding(Dart dest, Dart src) { assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); setDartEmbedding(dest, getEmbedding(src)); } template template inline void MapCommon::setOrbitEmbedding(Dart d, unsigned int em) { assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); FunctorSetEmb, ORBIT> fsetemb(*this, em); this->template foreach_dart_of_orbit(d, fsetemb); } template template inline void MapCommon::initOrbitEmbedding(Dart d, unsigned int em) { assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); FunctorInitEmb, ORBIT> finitemb(*this, em); this->template foreach_dart_of_orbit(d, finitemb); } template template inline unsigned int MapCommon::setOrbitEmbeddingOnNewCell(Dart d) { assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); unsigned int em = this->template newCell(); setOrbitEmbedding(d, em); return em; } template template inline unsigned int MapCommon::initOrbitEmbeddingOnNewCell(Dart d) { assert(this->template isOrbitEmbedded() || !"Invalid parameter: orbit not embedded"); unsigned int em = this->template newCell(); initOrbitEmbedding(d, em); return em; } template template inline void MapCommon::copyCell(Dart d, Dart e) { assert(this->template 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) ; this->m_attribs[ORBIT].copyLine(dE, eE) ; // copy the data // copyCell(dE, eE); } } /************************** * BOUNDARY MANAGEMENT * **************************/ template template inline void MapCommon::boundaryMark(Dart d) { this->m_markTables[DART][0]->operator[](this->dartIndex(d)).setMark(this->m_boundaryMarkers[DIM-2]); } template template inline void MapCommon::boundaryUnmark(Dart d) { this->m_markTables[DART][0]->operator[](this->dartIndex(d)).unsetMark(this->m_boundaryMarkers[DIM-2]); } template template void MapCommon::boundaryMarkOrbit(Dart d) { FunctorMark fm(*this, this->m_boundaryMarkers[DIM-2], this->m_markTables[DART][0]) ; this->template foreach_dart_of_orbit(d, fm, 0) ; } template template void MapCommon::boundaryUnmarkOrbit(Dart d) { FunctorUnmark fm(*this, this->m_boundaryMarkers[DIM-2], this->m_markTables[DART][0]) ; this->template foreach_dart_of_orbit(d, fm, 0) ; } template template inline bool MapCommon::isBoundaryMarked(Dart d) const { return this->m_markTables[DART][0]->operator[](this->dartIndex(d)).testMark(this->m_boundaryMarkers[DIM-2]); } template inline bool MapCommon::isBoundaryMarkedCurrent(Dart d) const { return this->m_markTables[DART][0]->operator[](this->dartIndex(d)).testMark(this->m_boundaryMarkers[this->dimension()-2]); } template inline bool MapCommon::isBoundaryMarked(unsigned int dim, Dart d) const { switch(dim) { case 2 : return isBoundaryMarked<2>(d) ; break ; case 3 : return isBoundaryMarked<3>(d) ; break ; default : return false ; break ; } } template template void MapCommon::boundaryUnmarkAll() { AttributeContainer& cont = this->m_attribs[DART] ; for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i)) this->m_markTables[DART][0]->operator[](i).unsetMark(this->m_boundaryMarkers[DIM-2]); } /**************************************** * ATTRIBUTES MANAGEMENT * ****************************************/ template template inline AttributeHandler MapCommon::addAttribute(const std::string& nameAttr) { if(!this->template isOrbitEmbedded()) this->template addEmbedding() ; AttributeMultiVector* amv = this->m_attribs[ORBIT].template addAttribute(nameAttr) ; return AttributeHandler(this, amv) ; } template template inline bool MapCommon::removeAttribute(AttributeHandler& attr) { assert(attr.isValid() || !"Invalid attribute handler") ; if(this->m_attribs[attr.getOrbit()].template removeAttribute(attr.getIndex())) { AttributeMultiVectorGen* amv = attr.getDataVector(); typedef std::multimap::iterator IT ; std::pair bounds = this->attributeHandlers.equal_range(amv) ; for(IT i = bounds.first; i != bounds.second; ++i) (*i).second->setInvalid() ; this->attributeHandlers.erase(bounds.first, bounds.second) ; return true ; } return false ; } template template inline AttributeHandler MapCommon::getAttribute(const std::string& nameAttr) { AttributeMultiVector* amv = this->m_attribs[ORBIT].template getDataVector(nameAttr) ; return AttributeHandler(this, amv) ; } template template inline AttributeHandler MapCommon::checkAttribute(const std::string& nameAttr) { AttributeHandler att = this->getAttribute(nameAttr); if (!att.isValid()) att = this->addAttribute(nameAttr); return att; } template template inline bool MapCommon::swapAttributes(AttributeHandler& attr1, AttributeHandler& attr2) { assert((attr1.isValid() && attr2.isValid()) || !"Invalid attribute handler") ; // assert(attr1.getOrbit() == attr2.getOrbit() || !"Cannot swap attributes of different orbits") ; // unsigned int orbit = attr1.getOrbit() ; unsigned int index1 = attr1.getIndex() ; unsigned int index2 = attr2.getIndex() ; if(index1 != index2) return this->m_attribs[ORBIT].swapAttributes(index1, index2) ; return false ; } template template inline bool MapCommon::copyAttribute(AttributeHandler& dst, AttributeHandler& src) { assert((dst.isValid() && src.isValid()) || !"Invalid attribute handler") ; // unsigned int orbit = dst.getOrbit() ; // assert(orbit == src.getOrbit() || !"Cannot copy attributes of different orbits") ; unsigned int index_dst = dst.getIndex() ; unsigned int index_src = src.getIndex() ; if(index_dst != index_src) return this->m_attribs[ORBIT].copyAttribute(index_dst, index_src) ; return false ; } template inline DartAttribute MapCommon::getInvolution(unsigned int i) { return DartAttribute(this, this->getInvolutionAttribute(i)); } template inline DartAttribute MapCommon::getPermutation(unsigned int i) { return DartAttribute(this, this->getPermutationAttribute(i)); } template inline DartAttribute MapCommon::getPermutationInv(unsigned int i) { return DartAttribute(this, this->getPermutationInvAttribute(i)); } /**************************************** * QUICK TRAVERSAL MANAGEMENT * ****************************************/ template template inline void MapCommon::enableQuickTraversal() { if(this->m_quickTraversal[ORBIT] == NULL) { if(!this->template isOrbitEmbedded()) this->template addEmbedding() ; this->m_quickTraversal[ORBIT] = this->m_attribs[ORBIT].template addAttribute("quick_traversal") ; } updateQuickTraversal() ; } template template inline void MapCommon::updateQuickTraversal() { assert(this->m_quickTraversal[ORBIT] != NULL || !"updateQuickTraversal on a disabled orbit") ; CellMarker, ORBIT> cm(*this) ; for(Dart d = this->begin(); d != this->end(); this->next(d)) { if(!cm.isMarked(d)) { cm.mark(d) ; (*this->m_quickTraversal[ORBIT])[getEmbedding(d)] = d ; } } } template template inline const AttributeMultiVector* MapCommon::getQuickTraversal() const { return this->m_quickTraversal[ORBIT] ; } template template inline void MapCommon::disableQuickTraversal() { if(this->m_quickTraversal[ORBIT] != NULL) { this->m_attribs[ORBIT].template removeAttribute(this->m_quickTraversal[ORBIT]->getIndex()) ; this->m_quickTraversal[ORBIT] = NULL ; } } template template inline void MapCommon::enableQuickIncidentTraversal() { if(this->m_quickLocalIncidentTraversal[ORBIT][INCI] == NULL) { if(!this->template isOrbitEmbedded()) this->template addEmbedding() ; std::stringstream ss; ss << "quickIncidentTraversal_" << INCI; this->m_quickLocalIncidentTraversal[ORBIT][INCI] = this->m_attribs[ORBIT].template addAttribute > >(ss.str()) ; } updateQuickIncidentTraversal() ; } template template inline void MapCommon::updateQuickIncidentTraversal() { assert(this->m_quickLocalIncidentTraversal[ORBIT][INCI] != NULL || !"updateQuickTraversal on a disabled orbit") ; AttributeMultiVector > >* ptrVD = this->m_quickLocalIncidentTraversal[ORBIT][INCI]; this->m_quickLocalIncidentTraversal[ORBIT][INCI] = NULL; std::vector buffer; buffer.reserve(100); TraversorCell, ORBIT> tra_glob(*this); for (Dart d = tra_glob.begin(); d != tra_glob.end(); d = tra_glob.next()) { buffer.clear(); Traversor* tra_loc = TraversorFactory >::createIncident(*this, d, this->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()); } this->m_quickLocalIncidentTraversal[ORBIT][INCI] = ptrVD; } template template inline const AttributeMultiVector > >* MapCommon::getQuickIncidentTraversal() const { return this->m_quickLocalIncidentTraversal[ORBIT][INCI] ; } template template inline void MapCommon::disableQuickIncidentTraversal() { if(this->m_quickLocalIncidentTraversal[ORBIT][INCI] != NULL) { this->m_attribs[ORBIT].removeAttribute(this->m_quickLocalIncidentTraversal[ORBIT][INCI]->getIndex()) ; this->m_quickLocalIncidentTraversal[ORBIT][INCI] = NULL ; } } template template inline void MapCommon::enableQuickAdjacentTraversal() { if(this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] == NULL) { if(!this->template isOrbitEmbedded()) this->template addEmbedding() ; std::stringstream ss; ss << "quickAdjacentTraversal" << ADJ; this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] = this->m_attribs[ORBIT].template addAttribute > >(ss.str()) ; } updateQuickAdjacentTraversal() ; } template template inline void MapCommon::updateQuickAdjacentTraversal() { assert(this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] != NULL || !"updateQuickTraversal on a disabled orbit") ; AttributeMultiVector > >* ptrVD = this->m_quickLocalAdjacentTraversal[ORBIT][ADJ]; this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] = NULL; std::vector buffer; buffer.reserve(100); TraversorCell, ORBIT> tra_glob(*this); for (Dart d = tra_glob.begin(); d != tra_glob.end(); d = tra_glob.next()) { buffer.clear(); Traversor* tra_loc = TraversorFactory >::createAdjacent(*this, d, this->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()); } this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] = ptrVD; } template template inline const AttributeMultiVector > >* MapCommon::getQuickAdjacentTraversal() const { return this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] ; } template template inline void MapCommon::disableQuickAdjacentTraversal() { if(this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] != NULL) { this->m_attribs[ORBIT].template removeAttribute(this->m_quickLocalAdjacentTraversal[ORBIT][ADJ]->getIndex()) ; this->m_quickLocalAdjacentTraversal[ORBIT][ADJ] = NULL ; } } } // namespace CGoGN