/******************************************************************************* * 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 #include #include "Topology/gmap/embeddedGMap2.h" #include "Topology/generic/traversor/traversor2.h" #include "Algo/Topo/basic.h" namespace CGoGN { Dart EmbeddedGMap2::newFace(unsigned int nbEdges, bool withBoundary) { Dart d = GMap2::newFace(nbEdges, withBoundary); if(withBoundary) { if (isOrbitEmbedded()) { Traversor2FV t(*this, d); for(Dart it = t.begin(); it != t.end(); it = t.next()) initOrbitEmbeddingOnNewCell(it) ; } if(isOrbitEmbedded()) { Traversor2FE t(*this, d); for(Dart it = t.begin(); it != t.end(); it = t.next()) initOrbitEmbeddingOnNewCell(it) ; } if(isOrbitEmbedded()) { initOrbitEmbeddingOnNewCell(d) ; initOrbitEmbeddingOnNewCell(phi2(d)) ; } } // else // { // if (isOrbitEmbedded()) // { // Traversor2FV t(*this, d); // for(Dart it = t.begin(); it != t.end(); it = t.next()) // initOrbitEmbeddingNewCell(it) ; // } // if(isOrbitEmbedded()) // initOrbitEmbeddingNewCell(d) ; // } return d ; } void EmbeddedGMap2::splitVertex(Dart d, Dart e) { Dart dd = phi2(d) ; Dart ee = phi2(e) ; GMap2::splitVertex(d, e) ; if (isOrbitEmbedded()) { unsigned int vEmb = getEmbedding(d) ; setDartEmbedding(phi1(dd), vEmb) ; setDartEmbedding(beta2(phi1(dd)), vEmb) ; setDartEmbedding(beta0(dd), vEmb) ; setOrbitEmbeddingOnNewCell(e) ; copyCellAttributes(e, d) ; } if(isOrbitEmbedded()) { initOrbitEmbeddingOnNewCell(phi1(dd)) ; } if(isOrbitEmbedded()) { unsigned int f1Emb = getEmbedding(dd) ; setDartEmbedding(phi1(dd), f1Emb) ; setDartEmbedding(beta0(phi1(dd)), f1Emb) ; unsigned int f2Emb = getEmbedding(ee) ; setDartEmbedding(phi1(ee), f2Emb) ; setDartEmbedding(beta0(phi1(ee)), f2Emb) ; } } Dart EmbeddedGMap2::deleteVertex(Dart d) { Dart f = GMap2::deleteVertex(d) ; if(f != NIL) { if (isOrbitEmbedded()) { setOrbitEmbedding(f, getEmbedding(f)) ; } } return f ; } Dart EmbeddedGMap2::cutEdge(Dart d) { Dart nd = GMap2::cutEdge(d) ; if(isOrbitEmbedded()) { initOrbitEmbeddingOnNewCell(nd) ; } if (isOrbitEmbedded()) { unsigned int eEmb = getEmbedding(d) ; setDartEmbedding(phi2(d), eEmb) ; setDartEmbedding(beta0(d), eEmb) ; setOrbitEmbeddingOnNewCell(nd) ; copyCellAttributes(nd, d) ; } if(isOrbitEmbedded()) { unsigned int f1Emb = getEmbedding(d) ; setDartEmbedding(phi1(d), f1Emb) ; setDartEmbedding(beta0(d), f1Emb) ; Dart e = phi2(nd) ; unsigned int f2Emb = getEmbedding(d) ; setDartEmbedding(phi1(e), f2Emb) ; setDartEmbedding(beta0(e), f2Emb) ; } return nd ; } bool EmbeddedGMap2::uncutEdge(Dart d) { if(GMap2::uncutEdge(d)) { if(isOrbitEmbedded()) { unsigned int eEmb = getEmbedding(d) ; setDartEmbedding(phi2(d), eEmb) ; setDartEmbedding(beta0(d), eEmb) ; } return true ; } return false ; } bool EmbeddedGMap2::edgeCanCollapse(Dart d) { if(isBoundaryVertex(d) || isBoundaryVertex(phi1(d))) return false ; unsigned int val_v1 = vertexDegree(d) ; unsigned int val_v2 = vertexDegree(phi1(d)) ; if(val_v1 + val_v2 < 8 || val_v1 + val_v2 > 14) return false ; if(faceDegree(d) == 3) { if(vertexDegree(phi_1(d)) < 4) return false ; } Dart dd = phi2(d) ; if(faceDegree(dd) == 3) { if(vertexDegree(phi_1(dd)) < 4) return false ; } // Check vertex sharing condition std::vector vu1 ; vu1.reserve(32) ; Dart vit1 = alpha1(alpha1(d)) ; Dart end = phi1(dd) ; do { unsigned int ve = getEmbedding(phi2(vit1)) ; vu1.push_back(ve) ; vit1 = alpha1(vit1) ; } while(vit1 != end) ; end = phi1(d) ; Dart vit2 = alpha1(alpha1(dd)) ; do { unsigned int ve = getEmbedding(phi2(vit2)) ; std::vector::iterator it = std::find(vu1.begin(), vu1.end(), ve) ; if(it != vu1.end()) return false ; vit2 = alpha1(vit2) ; } while(vit2 != end) ; return true ; } Dart EmbeddedGMap2::collapseEdge(Dart d, bool delDegenerateFaces) { unsigned int vEmb = EMBNULL ; if (isOrbitEmbedded()) { vEmb = getEmbedding(d) ; } Dart dV = GMap2::collapseEdge(d, delDegenerateFaces); if (isOrbitEmbedded()) { setOrbitEmbedding(dV, vEmb) ; } return dV ; } bool EmbeddedGMap2::flipEdge(Dart d) { if(GMap2::flipEdge(d)) { Dart e = phi2(d) ; if (isOrbitEmbedded()) { unsigned int v1Emb = getEmbedding(beta1(d)) ; setDartEmbedding(d, v1Emb) ; setDartEmbedding(beta2(d), v1Emb) ; unsigned int v2Emb = getEmbedding(beta1(e)) ; setDartEmbedding(e, v2Emb) ; setDartEmbedding(beta2(e), v2Emb) ; } if (isOrbitEmbedded()) { unsigned int f1Emb = getEmbedding(d) ; setDartEmbedding(phi_1(d), f1Emb) ; setDartEmbedding(beta1(d), f1Emb) ; unsigned int f2Emb = getEmbedding(e) ; setDartEmbedding(phi_1(e), f2Emb) ; setDartEmbedding(beta1(e), f2Emb) ; } return true ; } return false ; } bool EmbeddedGMap2::flipBackEdge(Dart d) { if(GMap2::flipBackEdge(d)) { Dart e = phi2(d) ; if (isOrbitEmbedded()) { unsigned int v1Emb = getEmbedding(beta1(d)) ; setDartEmbedding(d, v1Emb) ; setDartEmbedding(beta2(d), v1Emb) ; unsigned int v2Emb = getEmbedding(beta1(e)) ; setDartEmbedding(e, v2Emb) ; setDartEmbedding(beta2(e), v2Emb) ; } if (isOrbitEmbedded()) { unsigned int f1Emb = getEmbedding(d) ; setDartEmbedding(phi1(d), f1Emb) ; setDartEmbedding(beta0(phi1(d)), f1Emb) ; unsigned int f2Emb = getEmbedding(e) ; setDartEmbedding(phi1(e), f2Emb) ; setDartEmbedding(beta0(phi1(e)), f2Emb) ; } return true ; } return false ; } //void EmbeddedGMap2::insertEdgeInVertex(Dart d, Dart e) //{ // GMap2::insertEdgeInVertex(d, e); // // if (isOrbitEmbedded()) // { // copyDartEmbedding(e, d) ; // copyDartEmbedding(beta2(e), d) ; // } // // if (isOrbitEmbedded()) // { // if(!sameFace(d,e)) // { // setOrbitEmbeddingOnNewCell(e); // copyCell(e, d) ; // } // else // { // setOrbitEmbedding(d, getEmbedding(d)) ; // } // } //} // //void EmbeddedGMap2::removeEdgeFromVertex(Dart d) //{ // Dart dPrev = alpha_1(d); // // GMap2::removeEdgeFromVertex(d); // // if (isOrbitEmbedded()) // { // setOrbitEmbeddingOnNewCell(d); // copyCell(d, dPrev); // } // // if (isOrbitEmbedded()) // { // if(!sameFace(d, dPrev)) // { // setOrbitEmbeddingOnNewCell(d); // copyCell(d, dPrev) ; // } // else // { // setOrbitEmbedding(d, getEmbedding(d)) ; // } // } //} void EmbeddedGMap2::sewFaces(Dart d, Dart e, bool withBoundary) { // for fixed point construction (import & primitives) if (!withBoundary) { GMap2::sewFaces(d, e, false) ; if(isOrbitEmbedded()) { initOrbitEmbeddingOnNewCell(d) ; } return ; } GMap2::sewFaces(d, e, true) ; if (isOrbitEmbedded()) { setOrbitEmbedding(d, getEmbedding(d)) ; setOrbitEmbedding(e, getEmbedding(beta0(d))) ; } if (isOrbitEmbedded()) { setOrbitEmbedding(e, getEmbedding(d)) ; } } void EmbeddedGMap2::unsewFaces(Dart d) { Dart e = beta2(d); GMap2::unsewFaces(d); if (isOrbitEmbedded()) { if(!sameVertex(d,e)) { setOrbitEmbeddingOnNewCell(e); copyCellAttributes(e, d); } d = beta0(d); e = beta0(e); if(!sameVertex(d,e)) { setOrbitEmbeddingOnNewCell(e); copyCellAttributes(e, d); } } if (isOrbitEmbedded()) { setOrbitEmbeddingOnNewCell(e); copyCellAttributes(e, d); } } bool EmbeddedGMap2::collapseDegeneratedFace(Dart d) { Dart e = beta2(d) ; bool updateEdgeEmb = false ; if(phi1(d) != d) updateEdgeEmb = true ; if(GMap2::collapseDegeneratedFace(d)) { if (isOrbitEmbedded() && updateEdgeEmb) { unsigned int eEmb = getEmbedding(e) ; setDartEmbedding(beta2(e), eEmb) ; setDartEmbedding(phi2(e), eEmb) ; } return true ; } return false ; } void EmbeddedGMap2::splitFace(Dart d, Dart e) { GMap2::splitFace(d, e) ; if (isOrbitEmbedded()) { unsigned int v1Emb = getEmbedding(d) ; setDartEmbedding(phi_1(e), v1Emb) ; setDartEmbedding(beta1(d), v1Emb) ; setDartEmbedding(beta1(phi_1(e)), v1Emb) ; unsigned int v2Emb = getEmbedding(e) ; setDartEmbedding(phi_1(d), v2Emb) ; setDartEmbedding(beta1(e), v2Emb) ; setDartEmbedding(beta1(phi_1(d)), v2Emb) ; } if(isOrbitEmbedded()) { initOrbitEmbeddingOnNewCell(beta1(d)) ; } if (isOrbitEmbedded()) { unsigned int fEmb = getEmbedding(d) ; setDartEmbedding(phi_1(d), fEmb) ; setDartEmbedding(beta1(phi_1(d)), fEmb) ; setOrbitEmbeddingOnNewCell(e) ; copyCellAttributes(e, d) ; } } bool EmbeddedGMap2::mergeFaces(Dart d) { Dart dNext = phi1(d) ; if(GMap2::mergeFaces(d)) { if (isOrbitEmbedded()) { setOrbitEmbedding(dNext, getEmbedding(dNext)) ; } return true ; } return false ; } bool EmbeddedGMap2::mergeVolumes(Dart d, Dart e) { std::vector darts ; std::vector vEmb ; std::vector eEmb ; darts.reserve(32) ; vEmb.reserve(32) ; eEmb.reserve(32) ; Dart fit = d ; do { darts.push_back(phi2(fit)) ; if (isOrbitEmbedded()) { vEmb.push_back(getEmbedding(phi2(fit))) ; } if (isOrbitEmbedded()) { eEmb.push_back(getEmbedding(fit)) ; } fit = phi1(fit) ; } while (fit != d) ; if(GMap2::mergeVolumes(d, e)) { for(unsigned int i = 0; i < darts.size(); ++i) { if (isOrbitEmbedded()) { setOrbitEmbedding(darts[i], vEmb[i]) ; } if (isOrbitEmbedded()) { setOrbitEmbedding(darts[i], eEmb[i]) ; } } return true ; } return false ; } unsigned int EmbeddedGMap2::closeHole(Dart d, bool forboundary) { unsigned int nbE = GMap2::closeHole(d) ; Dart dd = phi2(d) ; Dart it = dd ; do { if (isOrbitEmbedded()) { copyDartEmbedding(it, beta2(it)) ; copyDartEmbedding(beta0(it), phi2(it)) ; } if (isOrbitEmbedded()) { unsigned int eEmb = getEmbedding(beta2(it)) ; setDartEmbedding(it, eEmb) ; setDartEmbedding(beta0(it), eEmb) ; } it = phi1(it) ; } while(it != dd) ; if(isOrbitEmbedded()) { initOrbitEmbeddingOnNewCell(dd) ; } return nbE ; } bool EmbeddedGMap2::check() { bool topo = GMap2::check() ; if (!topo) return false ; CGoGNout << "Check: embedding begin" << CGoGNendl ; for(Dart d = begin(); d != end(); next(d)) { if (isOrbitEmbedded()) { if (getEmbedding(d) != getEmbedding(alpha1(d))) { CGoGNout << "Check: different embeddings on vertex" << CGoGNendl ; return false ; } } if (isOrbitEmbedded()) { if (getEmbedding(d) != getEmbedding(phi2(d))) { CGoGNout << "Check: different embeddings on edge" << CGoGNendl ; return false ; } } if (isOrbitEmbedded()) { if (getEmbedding(d) != getEmbedding(phi1(d))) { CGoGNout << "Check: different embeddings on face" << CGoGNendl ; return false ; } } } CGoGNout << "Check: embedding ok" << CGoGNendl ; std::cout << "nb vertex orbits : " << Algo::Topo::getNbOrbits(*this) << std::endl ; std::cout << "nb vertex cells : " << m_attribs[VERTEX].size() << std::endl ; std::cout << "nb edge orbits : " << Algo::Topo::getNbOrbits(*this) << std::endl ; std::cout << "nb edge cells : " << m_attribs[EDGE].size() << std::endl ; std::cout << "nb face orbits : " << Algo::Topo::getNbOrbits(*this) << std::endl ; std::cout << "nb face cells : " << m_attribs[FACE].size() << std::endl ; return true ; } } // namespace CGoGN