diff --git a/include/Topology/map/embeddedMap3.h b/include/Topology/map/embeddedMap3.h index 7af6b46315a0701ab7b25e300be9893152d1cf37..3254c980bbf6fbf03c38fddcfa7790f19bbab89a 100644 --- a/include/Topology/map/embeddedMap3.h +++ b/include/Topology/map/embeddedMap3.h @@ -64,22 +64,22 @@ public: /*! * */ - virtual Dart cutSpike(Dart d); + virtual void sewVolumes(Dart d, Dart e); /*! * */ - virtual void sewVolumes(Dart d, Dart e); + virtual void unsewVolumes(Dart d); /*! * */ - virtual void unsewVolumes(Dart d); + virtual bool mergeVolumes(Dart d); /*! * */ - virtual bool mergeVolumes(Dart d); + virtual void splitVolume(std::vector& vd); /*! * diff --git a/include/Topology/map/map2.h b/include/Topology/map/map2.h index 6eacf1abc249abe0aac48abb5848b9c98688c22f..14cd0f513fdcc8d5068d944d3d9a82c994ac4d78 100644 --- a/include/Topology/map/map2.h +++ b/include/Topology/map/map2.h @@ -243,13 +243,6 @@ public: */ void unsewAroundVertex(Dart d) ; - /** - * Unsew the Umbrella aroud a vertex, close the hole and then - * create a symetric to construct a polyedron - * @param d a dart from the vertex - */ - void explodPolyhedron(Dart d); - //! Merge two volumes along two faces. /*! Works only if the two faces have the same number of edges. * The faces adjacent to the two given faces are pairwise phi2-linked diff --git a/include/Topology/map/map3.h b/include/Topology/map/map3.h index 3a349944c8bcdf1cd4e8b25c7d66137ac489f31b..23db8a4ae1bb36b1c47a1dc645fb465921b6ce67 100644 --- a/include/Topology/map/map3.h +++ b/include/Topology/map/map3.h @@ -143,11 +143,6 @@ public: */ virtual void splitFace(Dart d, Dart e); - //! Unsew the faces from the one-ring of the vertex of d - /*! @param d a dart - */ - virtual Dart cutSpike(Dart d); - //! Sew two oriented volumes along their faces. /*! The oriented faces should not be phi3-linked and have the same length * @param d a dart of the first volume @@ -165,6 +160,11 @@ public: */ virtual bool mergeVolumes(Dart d); + //! Split a volume into two volumes along a edge path + /*! @param vd a vector of darts + */ + virtual void splitVolume(std::vector& vd); + //@} /*! @name Topological Queries @@ -209,7 +209,7 @@ public: //! Compute the number of volumes around the edge of d /*! @param d a dart */ - int edgeDegree(Dart d); + unsigned int edgeDegree(Dart d); //! Test if dart d and e belong to the same oriented face /*! @param d a dart diff --git a/src/Topology/map/embeddedMap3.cpp b/src/Topology/map/embeddedMap3.cpp index 6d71ad0c49456035593dac32de383a8d8dd2b4e9..864954dd11996a247030ee1f8f1a4e5ebe6b31fd 100644 --- a/src/Topology/map/embeddedMap3.cpp +++ b/src/Topology/map/embeddedMap3.cpp @@ -32,6 +32,8 @@ namespace CGoGN bool EmbeddedMap3::deleteVertex(Dart d) { + //the merge volumes inside deleteVertex merges the volume embedding + return Map3::deleteVertex(d); } @@ -43,11 +45,13 @@ void EmbeddedMap3::cutEdge(Dart d) { Dart nd = phi1(d) ; - embedNewCell(EDGE, nd) ; - copyCell(EDGE, nd, d) ; - + //embed the new darts created in the cutted edge unsigned int vEmb = getEmbedding(EDGE, d); embedOrbit(EDGE, d, vEmb) ; + + //embed a new cell for the new edge and copy the embedding + embedNewCell(EDGE, nd) ; + copyCell(EDGE, nd, d) ; } if(isOrbitEmbedded(FACE)) @@ -89,18 +93,26 @@ void EmbeddedMap3::cutEdge(Dart d) void EmbeddedMap3::uncutEdge(Dart d) { Map3::uncutEdge(d); + + //embed all darts from the old two edges to one of the two edge embedding + if(isOrbitEmbedded(EDGE)) + { + unsigned int vEmb = getEmbedding(EDGE, d); + embedOrbit(EDGE, d, vEmb) ; + } } void EmbeddedMap3::splitFace(Dart d, Dart e) { Map3::splitFace(d,e); + //copy the vertex embedding to new darts (same vertex embedding for all darts) if(isOrbitEmbedded(VERTEX)) { copyDartEmbedding(VERTEX, phi2(phi_1(d)), d); copyDartEmbedding(VERTEX, phi2(phi_1(e)), e); - if(phi3(d) != d) + if(!isBoundaryFace(d)) { Dart d3 = phi3(d); Dart e3 = phi3(e); @@ -110,18 +122,20 @@ void EmbeddedMap3::splitFace(Dart d, Dart e) } } + //add a new face embedding to the created face if(isOrbitEmbedded(FACE)) { embedNewCell(FACE, phi2(phi_1(d))); copyCell(FACE, phi2(phi_1(d)), d); } + //copy the volume embedding to new darts (same volume embedding for all darts on the faces) if(isOrbitEmbedded(VOLUME)) { copyDartEmbedding(VOLUME, phi_1(d), d); copyDartEmbedding(VOLUME, phi2(phi_1(d)), d); - if(phi3(d) != d) + if(!isBoundaryFace(d)) { Dart d3 = phi3(d); @@ -131,12 +145,6 @@ void EmbeddedMap3::splitFace(Dart d, Dart e) } } -Dart EmbeddedMap3::cutSpike(Dart d) -{ - Dart e = Map3::cutSpike(d); - return e; -} - void EmbeddedMap3::sewVolumes(Dart d, Dart e) { //topological sewing @@ -178,39 +186,40 @@ void EmbeddedMap3::sewVolumes(Dart d, Dart e) void EmbeddedMap3::unsewVolumes(Dart d) { - Dart dd = phi1(phi3(d)); - - if(phi3(d)!=d) + if(!Map3::isBoundaryFace(d)) { Map3::unsewVolumes(d); - Dart ddd = d; + Dart dd = phi1(phi3(d)); + Dart dit = d; do { + //embed the unsewn vertex orbit with the vertex embedding if it is deconnected if(isOrbitEmbedded(VERTEX)) { - if(!sameVertex(ddd,dd)) + if(!sameVertex(dit,dd)) { embedNewCell(VERTEX, dd); - copyCell(VERTEX, dd, ddd); + copyCell(VERTEX, dd, dit); } } dd = phi_1(dd); + //embed the unsewn edge with the edge embedding if it is deconnected if(isOrbitEmbedded(EDGE)) { - if(!sameEdge(ddd,dd)) + if(!sameEdge(dit,dd)) { embedNewCell(EDGE, dd); - copyCell(VERTEX, dd, ddd); + copyCell(VERTEX, dd, dit); } } - ddd = phi1(ddd); - } while(ddd!=d); - + dit = phi1(dit); + } while(dit!=d); + //embed the unsewn face with the face embedding if (isOrbitEmbedded(FACE)) { embedNewCell(FACE, dd); @@ -222,20 +231,52 @@ void EmbeddedMap3::unsewVolumes(Dart d) bool EmbeddedMap3::mergeVolumes(Dart d) { Dart d2 = phi2(d); - Dart a_2 = phi3(phi2(d)); if(Map3::mergeVolumes(d)) { if (isOrbitEmbedded(VOLUME)) { unsigned int vEmb = getEmbedding(VOLUME, d2); - embedOrbit(VOLUME, a_2, vEmb) ; + embedOrbit(VOLUME, d2, vEmb) ; } return true; } return false; } +void EmbeddedMap3::splitVolume(std::vector& vd) +{ + Map3::splitVolume(vd); + + //follow the edge path a second time to embed the vertex, edge and volume orbits + for(std::vector::iterator it = vd.begin() ; it != vd.end() ; ++it) + { + Dart dit = *it; + Dart dit3 = alpha2(dit); + + //embed the vertex embedded from the origin volume to the new darts + if(isOrbitEmbedded(VERTEX)) + { + copyDartEmbedding(VERTEX, dit3, dit); + copyDartEmbedding(VERTEX, phi2(dit), phi2(dit3)); + } + + //embed the edge embedded from the origin volume to the new darts + if(isOrbitEmbedded(EDGE)) + { + copyDartEmbedding(EDGE, dit3, dit); + copyDartEmbedding(EDGE, phi2(dit), dit); + } + + //embed the volume embedded from the origin volume to the new darts + if(isOrbitEmbedded(VOLUME)) + { + copyDartEmbedding(EDGE, dit3, dit); + copyDartEmbedding(EDGE, phi2(dit), dit); + } + } +} + bool EmbeddedMap3::check() { bool topo = Map3::check() ; diff --git a/src/Topology/map/map3.cpp b/src/Topology/map/map3.cpp index 534a7bb441908a6da3b79580886ede0066f174c7..06b31e901ee6fe52e79418d2e94bc654f9fecb99 100644 --- a/src/Topology/map/map3.cpp +++ b/src/Topology/map/map3.cpp @@ -71,29 +71,38 @@ void Map3::deleteVolume(Dart d) bool Map3::deleteVertex(Dart d) { - //is boundary - if(phi3(d) != d) + //Save the darts around the vertex + //(one dart per face should be enough) + std::vector fstoretmp; + fstoretmp.reserve(100); + FunctorStore fs(fstoretmp); + foreach_dart_of_vertex(d, fs); + + //just one dart per face + std::vector fstore; + fstore.reserve(100); + DartMarker mf(*this); + for(std::vector::iterator it = fstoretmp.begin() ; it != fstoretmp.end() ; ++it) { - Dart e = d; - Dart d3 = phi2(phi3(d)); - - do + if(!mf.isMarked(*it)) { - unsewVolumes(e); - e = phi2(phi_1(e)); - }while(e != d); - - Map2::deleteVertex(d3); + mf.markOrbit(FACE, *it); + fstore.push_back(*it); + } } - Map2::deleteVertex(d); + for(std::vector::iterator it = fstore.begin() ; it != fstore.end() ; ++it) + { + if(!mergeVolumes(*it)) + return false; + } return true; } void Map3::cutEdge(Dart d) { - if(phi3(d) == d) + if(isBoundaryFace(d)) d = phi2(d); Dart prev = d; @@ -116,7 +125,7 @@ void Map3::cutEdge(Dart d) } } - if (phi3(d) != d) + if(!isBoundaryFace(d)) { Dart d3 = phi3(d); phi3unsew(d); @@ -127,7 +136,7 @@ void Map3::cutEdge(Dart d) void Map3::uncutEdge(Dart d) { - if(phi3(d) == d) + if(isBoundaryFace(d)) d = phi_1(phi2(d)); Dart prev = d; @@ -154,7 +163,7 @@ void Map3::splitFace(Dart d, Dart e) { Map2::splitFace(d,e); - if (phi3(d) != d) + if(!isBoundaryFace(d)) { Dart dd = phi1(phi3(d)); Dart ee = phi1(phi3(e)); @@ -166,70 +175,6 @@ void Map3::splitFace(Dart d, Dart e) } } -Dart Map3::cutSpike(Dart d) -{ - Dart e=d; - int nb=0; - Dart dNew; - int tet=0; - - //CGoGNout << "cut" << CGoGNendl; - - //count the valence of the vertex - do { - nb++; - e=phi1(phi2(e)); - } while (e!=d); - - if(nb<3) - { - CGoGNout << "Warning : cannot cut 2 volumes without creating a degenerated face " << CGoGNendl; - return d; - } - else - { - //triangulate around the vertex - do { - if(phi1(phi1(phi1(e)))!=e) - { - splitFace(phi_1(e),phi1(e)); - //CGoGNout << "split" << CGoGNendl; - } - else - tet++; - - e=phi1(phi2(e)); - } while (e!=d); - -// CGoGNout << "#tet= " << tet << CGoGNendl; -// CGoGNout << "#nb= " << nb << CGoGNendl; - - //si toute ces faces ne sont pas triangulaires (on insere une face) - if(tet != nb) { - //CGoGNout << "new face" << CGoGNendl; - dNew=newFace(nb); - Dart d3 = newFace(nb); - sewVolumes(dNew,d3); - - //sew a face following the triangles - Dart dTurn=dNew; - do { - Dart d1 = phi1(e); - Dart dSym = phi2(d1); - phi2unsew(d1); - phi2sew(dTurn,d1); - phi2sew(phi3(dTurn),dSym); - dTurn = phi1(dTurn); - e=phi1(phi2(e)); - }while(e!=d); - } - else - dNew = d; - } - - return dNew; -} - void Map3::sewVolumes(Dart d, Dart e) { assert(faceDegree(d) == faceDegree(e)); @@ -256,23 +201,40 @@ void Map3::unsewVolumes(Dart d) bool Map3::mergeVolumes(Dart d) { - Dart e = phi3(d) ; - if(e != d) + if(!isBoundaryFace(d)) { - unsewVolumes(d); + Dart e = phi3(d); + Map3::unsewVolumes(d); Map2::mergeVolumes(d, e); // merge the two volumes along common face return true ; } return false ; } +void Map3::splitVolume(std::vector& vd) +{ + Dart e = vd.front(); + Dart e2 = phi2(e); + + //unsew the edge path + for(std::vector::iterator it = vd.begin() ; it != vd.end() ; ++it) + Map2::unsewFaces(*it); + + //close the two holes + Map2::closeHole(e); + Map2::closeHole(e2); + + //sew the two connexe componnents + Map3::sewVolumes(phi2(e), phi2(e2)); +} + /*! @name Topological Queries * Return or set various topological information *************************************************************************/ bool Map3::sameOrientedVertex(Dart d, Dart e) { - return sameOrientedVertex(d,e); + return sameVertex(d,e); } bool Map3::sameVertex(Dart d, Dart e) @@ -316,7 +278,7 @@ bool Map3::sameVertex(Dart d, Dart e) unsigned int Map3::vertexDegree(Dart d) { - int count = 0; + unsigned int count = 0; DartMarkerStore mv(*this); // Lock a marker std::list darts_list; //Darts that are traversed @@ -401,7 +363,7 @@ bool Map3::isBoundaryVertex(Dart d) bool Map3::sameOrientedEdge(Dart d, Dart e) { - return sameOrientedEdge(d,e); + return sameEdge(d,e); } bool Map3::sameEdge(Dart d, Dart e) @@ -418,9 +380,9 @@ bool Map3::sameEdge(Dart d, Dart e) return false; } -int Map3::edgeDegree(Dart d) +unsigned int Map3::edgeDegree(Dart d) { - int deg = 0; + unsigned int deg = 0; Dart e = d; do @@ -555,6 +517,16 @@ bool Map3::check() std::cout << "nb vertex orbits" << getNbOrbits(VERTEX) << std::endl ; std::cout << "nb vertex cells" << m_attribs[VERTEX].size() << std::endl ; + std::cout << "nb edge orbits" << getNbOrbits(EDGE) << std::endl ; + std::cout << "nb edge cells" << m_attribs[EDGE].size() << std::endl ; + + std::cout << "nb face orbits" << getNbOrbits(FACE) << std::endl ; + std::cout << "nb face cells" << m_attribs[FACE].size() << std::endl ; + + std::cout << "nb volume orbits" << getNbOrbits(VOLUME) << std::endl ; + std::cout << "nb volume cells" << m_attribs[VOLUME].size() << std::endl ; + + return true; }