Commit b0022134 authored by Sylvain Thery's avatar Sylvain Thery Committed by Pierre Kraemer
Browse files

map2 ... OK ?

parent 41a22040
...@@ -114,6 +114,12 @@ public: ...@@ -114,6 +114,12 @@ public:
*/ */
Dart newFace(unsigned int nbEdges) ; Dart newFace(unsigned int nbEdges) ;
//! Create an new face for boundary (marked)
/*! @param nbEdges the number of edges
* @return return a dart of the face
*/
Dart newBoundaryFace(unsigned nbEdges);
//! Delete an oriented face erasing all its darts //! Delete an oriented face erasing all its darts
/*! @param d a dart of the face /*! @param d a dart of the face
*/ */
......
...@@ -95,13 +95,15 @@ protected: ...@@ -95,13 +95,15 @@ protected:
*/ */
void phi2unsew(Dart d); void phi2unsew(Dart d);
//! merge a face that has been tag as boundary with existing boundary if needed //! merge a face that has been tag as boundary with existing boundary if needed
/* @param d a dart of the face /* @param d a dart of the face
*/ */
void mergeFacewithBoundary(Dart d); void mergeFacewithBoundary(Dart d);
/**
* merge two faces of boundary
*/
void mergeBoundaryFaces(Dart dd, Dart ee);
/*! @name Generator and Deletor /*! @name Generator and Deletor
* To generate or delete faces in a 2-map * To generate or delete faces in a 2-map
...@@ -256,7 +258,7 @@ public: ...@@ -256,7 +258,7 @@ public:
* create a symetric to construct a polyedron * create a symetric to construct a polyedron
* @param d a dart from the vertex * @param d a dart from the vertex
*/ */
void explodPolyhedron(Dart d); // void explodPolyhedron(Dart d); //TODO modification for new boundary managing method ???
//! Merge two volumes along two faces. //! Merge two volumes along two faces.
/*! Works only if the two faces have the same number of edges. /*! Works only if the two faces have the same number of edges.
...@@ -328,6 +330,17 @@ public: ...@@ -328,6 +330,17 @@ public:
*/ */
bool isBoundaryVertex(Dart d) ; bool isBoundaryVertex(Dart d) ;
/**
* find the dart of vertex that belong to the boundary
*/
Dart findBoundaryVertex(Dart d);
/**
* tell if the vertex of d is on the boundary of the map
*/
bool isBoundaryEdge(Dart d) ; // OK boundary
//! Follow the boundary of a surface as if it was a oriented face. //! Follow the boundary of a surface as if it was a oriented face.
/*! This operation alternate phi1 and phi2 operator until another /*! This operation alternate phi1 and phi2 operator until another
* boudary dart is reached. * boudary dart is reached.
...@@ -396,6 +409,31 @@ public: ...@@ -396,6 +409,31 @@ public:
bool foreach_dart_of_link(Dart d, unsigned int orbit, FunctorType& f, unsigned int thread=0); bool foreach_dart_of_link(Dart d, unsigned int orbit, FunctorType& f, unsigned int thread=0);
//@} //@}
//@{
//! Close a topological hole (a sequence of connected fixed point of phi2). DO NO USE, only for import algorithm
/*! \pre dart d MUST be fixed point of phi2 relation
* Add a face to the map that closes the hole.
* The darts of this face are marked with holeMarker.
* @param d a dart of the hole (with phi2(d)==d)
* @return the degree of the created face
*/
virtual unsigned int closeHole(Dart d);
//! Close the map removing topological holes: DO NO USE, only for import algorithm
/*! Add faces to the map that close every existing hole.
* These faces are marked.
* \warning The embeddings of vertices are not updated
*/
void closeMap();
// void closeMap(DartMarker& marker);
/**
* sew oriented face, DO NO USE, only for import algorithm
*/
void sewOrientedFaces(Dart d, Dart e);
//@}
}; };
} // namespace CGoGN } // namespace CGoGN
......
...@@ -40,6 +40,17 @@ Dart Map1::newOrientedFace(unsigned nbEdges) ...@@ -40,6 +40,17 @@ Dart Map1::newOrientedFace(unsigned nbEdges)
return d ; return d ;
} }
Dart Map1::newBoundaryFace(unsigned nbEdges)
{
assert(nbEdges > 0 || !"Cannot create a face with no edge") ;
Dart d = newDart() ; // Create the first edge
boundaryMark(d);
for (unsigned int i = 1 ; i < nbEdges ; ++i)
Map1::cutEdge(d) ; // Subdivide nbEdges-1 times this edge
return d ;
}
void Map1::deleteOrientedFace(Dart d) void Map1::deleteOrientedFace(Dart d)
{ {
Dart e = phi1(d) ; Dart e = phi1(d) ;
......
...@@ -31,6 +31,15 @@ namespace CGoGN ...@@ -31,6 +31,15 @@ namespace CGoGN
* To generate or delete faces in a 2-map * To generate or delete faces in a 2-map
*************************************************************************/ *************************************************************************/
void Map2::mergeBoundaryFaces(Dart dd, Dart ee)
{
if (ee != phi_1(dd))
phi1sew(ee, phi_1(dd)) ;
if (ee != phi_1(dd))
phi1sew(ee, phi_1(dd)) ;
Map1::deleteOrientedFace(dd) ;
}
void Map2::mergeFacewithBoundary(Dart d) void Map2::mergeFacewithBoundary(Dart d)
{ {
Dart e = d ; Dart e = d ;
...@@ -52,7 +61,6 @@ void Map2::mergeFacewithBoundary(Dart d) ...@@ -52,7 +61,6 @@ void Map2::mergeFacewithBoundary(Dart d)
} while (e != d) ; } while (e != d) ;
} }
void Map2::deleteOrientedFace(Dart d) void Map2::deleteOrientedFace(Dart d)
{ {
// tag face in boundary // tag face in boundary
...@@ -61,6 +69,13 @@ void Map2::deleteOrientedFace(Dart d) ...@@ -61,6 +69,13 @@ void Map2::deleteOrientedFace(Dart d)
} }
void Map2::sewOrientedFaces(Dart d, Dart e)
{
assert(phi2(d)==d && phi2(e)==e);
// sewing the faces
phi2sew(d, e);
}
/*! @name Topological Operators /*! @name Topological Operators
* Topological operations on 2-maps * Topological operations on 2-maps
*************************************************************************/ *************************************************************************/
...@@ -112,9 +127,6 @@ void Map2::cutEdge(Dart d) ...@@ -112,9 +127,6 @@ void Map2::cutEdge(Dart d)
// phi2sew(e, nd); // phi2sew(e, nd);
// } // }
// TODISCUSS: it is not allowed to cut an edge of boundary
assert(!isBoundaryMarked(d));
Map1::cutEdge(d); // Cut the 1-edge of d Map1::cutEdge(d); // Cut the 1-edge of d
Dart e = phi2(d); Dart e = phi2(d);
Map1::cutEdge(e); // Cut the 1-edge of phi2(d) Map1::cutEdge(e); // Cut the 1-edge of phi2(d)
...@@ -127,12 +139,6 @@ void Map2::cutEdge(Dart d) ...@@ -127,12 +139,6 @@ void Map2::cutEdge(Dart d)
phi2sew(d, ne); // Correct the phi2 links phi2sew(d, ne); // Correct the phi2 links
phi2sew(e, nd); phi2sew(e, nd);
if (isBoundaryMarked(e))
boundaryMark(ne);
// if (isBoundaryMarked(d))
// boundaryMark(nd);
} }
void Map2::uncutEdge(Dart d) void Map2::uncutEdge(Dart d)
...@@ -163,7 +169,6 @@ void Map2::uncutEdge(Dart d) ...@@ -163,7 +169,6 @@ void Map2::uncutEdge(Dart d)
phi2sew(d, e) ; phi2sew(d, e) ;
} }
Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces) Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces)
{ {
// Dart resV ; // Dart resV ;
...@@ -214,8 +219,8 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces) ...@@ -214,8 +219,8 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces)
// //
// return resV ; // return resV ;
Dart resV=Dart::nil() ; Dart resV=Dart::nil() ;
Dart e = phi2(d); Dart e = phi2(d);
phi2unsew(d); // Unlink the opposite edges phi2unsew(d); // Unlink the opposite edges
...@@ -223,6 +228,7 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces) ...@@ -223,6 +228,7 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces)
{ {
Dart f = phi1(e) ; Dart f = phi1(e) ;
Map1::collapseEdge(e) ; // Collapse edge e Map1::collapseEdge(e) ; // Collapse edge e
if (f!=e)
collapseDegeneratedFace(f) ;// and collapse its face if degenerated collapseDegeneratedFace(f) ;// and collapse its face if degenerated
} }
else else
...@@ -246,16 +252,25 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces) ...@@ -246,16 +252,25 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces)
Map1::collapseEdge(e) ; // Just collapse edge e Map1::collapseEdge(e) ; // Just collapse edge e
} }
if (isBoundaryMarked(d))
{
Dart f = phi1(d) ;
Map1::collapseEdge(d) ; // Collapse edge d
if (f!=d)
collapseDegeneratedFace(f) ;// and collapse its face if degenerated
}
else
{
Dart f = phi1(d) ; Dart f = phi1(d) ;
Dart g = phi_1(d) ; Dart g = phi_1(d) ;
if(resV == Dart::nil()) if(resV == Dart::nil())
{ {
if(!isFaceTriangle(d)) if(f != e && !isFaceTriangle(d))
resV = f ; resV = f ;
else if(phi2(g) != g) else if(phi2(g) != g)
resV = phi2(g) ; resV = phi2(g) ;
else if(phi2(f) != f) else if(f != e && phi2(f) != f)
resV = phi1(phi2(f)) ; resV = phi1(phi2(f)) ;
} }
...@@ -266,15 +281,16 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces) ...@@ -266,15 +281,16 @@ Dart Map2::collapseEdge(Dart d, bool delDegenerateFaces)
} }
else else
Map1::collapseEdge(d) ; // Just collapse edge d Map1::collapseEdge(d) ; // Just collapse edge d
}
return resV ; return resV ;
} }
bool Map2::flipEdge(Dart d) bool Map2::flipEdge(Dart d)
{ {
Dart e = phi2(d); // Test if an opposite if (!isBoundaryEdge(d))
if (!isBoundaryMarked(e)) // edge exists
{ {
Dart e = phi2(d);
Dart dNext = phi1(d); Dart dNext = phi1(d);
Dart eNext = phi1(e); Dart eNext = phi1(e);
Dart dPrev = phi_1(d); Dart dPrev = phi_1(d);
...@@ -290,9 +306,9 @@ bool Map2::flipEdge(Dart d) ...@@ -290,9 +306,9 @@ bool Map2::flipEdge(Dart d)
bool Map2::flipBackEdge(Dart d) bool Map2::flipBackEdge(Dart d)
{ {
Dart e = phi2(d); // Test if an opposite if (!isBoundaryEdge(d))
if (!isBoundaryMarked(e)) // edge exists
{ {
Dart e = phi2(d);
Dart dNext = phi1(d); Dart dNext = phi1(d);
Dart eNext = phi1(e); Dart eNext = phi1(e);
Dart dPrev = phi_1(d); Dart dPrev = phi_1(d);
...@@ -323,26 +339,41 @@ void Map2::removeEdgeFromVertex(Dart d) ...@@ -323,26 +339,41 @@ void Map2::removeEdgeFromVertex(Dart d)
void Map2::sewFaces(Dart d, Dart e) void Map2::sewFaces(Dart d, Dart e)
{ {
Dart dd = phi2(d); Dart dd = phi2(d);
Dart ee = phi2(ee); Dart ee = phi2(e);
// unsew from boundary // unsew from boundary
phi2unsew(d); phi2unsew(d);
phi2unsew(e); phi2unsew(e);
// remove boundary edge // remove boundary edge (could be a Map1::mergeFaces without assert ?)
if (ee != phi_1(dd)) mergeBoundaryFaces(dd,ee);
phi1sew(ee, phi_1(dd)) ;
if (ee != phi_1(dd))
phi1sew(ee, phi_1(dd)) ;
Map1::deleteOrientedFace(d) ;
// main sewing // sewing the faces
phi2sew(d, e); phi2sew(d, e);
} }
void Map2::unsewFaces(Dart d) void Map2::unsewFaces(Dart d)
{ {
// TODO Dart dd = phi2(d);
Dart e = newBoundaryFace(2);
if (isBoundaryVertex(d))
{
Dart f = findBoundaryVertex(d);
phi1sew(e,phi_1(f));
}
if (isBoundaryVertex(dd))
{
Dart f = findBoundaryVertex(dd);
phi1sew(phi_1(e),phi_1(f));
}
phi2unsew(d); phi2unsew(d);
// sew faces to the boundary
phi2sew(d,e);
phi2sew(dd,phi1(e));
} }
bool Map2::collapseDegeneratedFace(Dart d) bool Map2::collapseDegeneratedFace(Dart d)
...@@ -370,9 +401,9 @@ void Map2::splitFace(Dart d, Dart e) ...@@ -370,9 +401,9 @@ void Map2::splitFace(Dart d, Dart e)
bool Map2::mergeFaces(Dart d) bool Map2::mergeFaces(Dart d)
{ {
Dart e = phi2(d) ; if (!isBoundaryEdge(d))
if (!isBoundaryMarked(e))
{ {
Dart e = phi2(d) ;
phi2unsew(d); // unsew the face of d phi2unsew(d); // unsew the face of d
Map1::mergeFaces(d, e); // merge the two faces along edges of d and e Map1::mergeFaces(d, e); // merge the two faces along edges of d and e
return true ; return true ;
...@@ -382,7 +413,33 @@ bool Map2::mergeFaces(Dart d) ...@@ -382,7 +413,33 @@ bool Map2::mergeFaces(Dart d)
void Map2::extractTrianglePair(Dart d) void Map2::extractTrianglePair(Dart d)
{ {
// assert(isFaceTriangle(d)) ;
// Dart e = phi2(d) ;
// if(e != d)
// {
// assert(isFaceTriangle(e)) ;
// Dart e1 = phi2(phi1(e)) ;
// Dart e2 = phi2(phi_1(e)) ;
// phi2unsew(e1) ;
// phi2unsew(e2) ;
// phi2sew(e1, e2) ;
// }
// Dart d1 = phi2(phi1(d)) ;
// Dart d2 = phi2(phi_1(d)) ;
// phi2unsew(d1) ;
// phi2unsew(d2) ;
// phi2sew(d1, d2) ;
if (!isBoundaryMarked(d))
{
assert(isFaceTriangle(d)) ; assert(isFaceTriangle(d)) ;
Dart d1 = phi2(phi1(d)) ;
Dart d2 = phi2(phi_1(d)) ;
phi2unsew(d1) ;
phi2unsew(d2) ;
phi2sew(d1, d2) ;
}
Dart e = phi2(d) ; Dart e = phi2(d) ;
if (!isBoundaryMarked(e)) if (!isBoundaryMarked(e))
{ {
...@@ -393,20 +450,34 @@ void Map2::extractTrianglePair(Dart d) ...@@ -393,20 +450,34 @@ void Map2::extractTrianglePair(Dart d)
phi2unsew(e2) ; phi2unsew(e2) ;
phi2sew(e1, e2) ; phi2sew(e1, e2) ;
} }
Dart d1 = phi2(phi1(d)) ;
Dart d2 = phi2(phi_1(d)) ;
phi2unsew(d1) ;
phi2unsew(d2) ;
phi2sew(d1, d2) ;
} }
void Map2::insertTrianglePair(Dart d, Dart v1, Dart v2) void Map2::insertTrianglePair(Dart d, Dart v1, Dart v2)
{ {
// assert(sameOrientedVertex(v1, v2)) ;
// assert((v1 != v2 && phi2(d) != d) || (v1 == v2 && phi2(d) == d)) ;
// assert(isFaceTriangle(d) && phi2(phi1(d)) == phi1(d) && phi2(phi_1(d)) == phi_1(d)) ;
// Dart e = phi2(d) ;
// if(e != d && v1 != v2)
// {
// assert(isFaceTriangle(e) && phi2(phi1(e)) == phi1(e) && phi2(phi_1(e)) == phi_1(e)) ;
// Dart vv2 = phi2(v2) ;
// phi2unsew(v2) ;
// phi2sew(phi_1(e), v2) ;
// phi2sew(phi1(e), vv2) ;
// }
// Dart vv1 = phi2(v1) ;
// phi2unsew(v1) ;
// phi2sew(phi_1(d), v1) ;
// phi2sew(phi1(d), vv1) ;
assert(sameOrientedVertex(v1, v2)) ; assert(sameOrientedVertex(v1, v2)) ;
assert((v1 != v2 && !isBoundaryMarked(d)) || (v1 == v2 && isBoundaryMarked(d))) ; assert((v1 != v2 && !isBoundaryMarked(d)) || (v1 == v2 && isBoundaryMarked(d))) ;
assert(isFaceTriangle(d) && isBoundaryMarked(phi1(d)) && isBoundaryMarked(phi_1(d)) ) ; assert(isFaceTriangle(d) && isBoundaryMarked(phi1(d)) && isBoundaryMarked(phi_1(d)) ) ;
Dart e = phi2(d) ; Dart e = phi2(d) ;
if( !isBoundaryMarked(e) && v1 != v2) if (!isBoundaryEdge(d) && v1 != v2)
{ {
assert( isFaceTriangle(e) && isBoundaryMarked(phi1(e)) && isBoundaryMarked(phi_1(e)) ) ; assert( isFaceTriangle(e) && isBoundaryMarked(phi1(e)) && isBoundaryMarked(phi_1(e)) ) ;
Dart vv2 = phi2(v2) ; Dart vv2 = phi2(v2) ;
...@@ -440,10 +511,68 @@ void Map2::unsewAroundVertex(Dart d) ...@@ -440,10 +511,68 @@ void Map2::unsewAroundVertex(Dart d)
while(e != d); while(e != d);
} }
//void Map2::explodPolyhedron(Dart d)
//{
// unsewAroundVertex(d);
//// closeHole(phi1(d));
//
// //Recherche du (ou un des) sommet oppose
// //tourner autour du sommet
// //si quad alors sommet oppose
// //
// //si pas de quad alors un sommet du trian
//
// //
//}
bool Map2::mergeVolumes(Dart d, Dart e) bool Map2::mergeVolumes(Dart d, Dart e)
{ {
// // First traversal of both faces to check the face sizes
// // and stored their edges to efficiently access them further
// std::vector<Dart> dDarts;
// std::vector<Dart> eDarts;
// dDarts.reserve(16); // usual faces have less than 16 edges
// eDarts.reserve(16);
//
// Dart dFit = d ;
// Dart eFit = phi1(e) ; // must take phi1 because of the use
// do // of reverse iterator for sewing loop
// {
// dDarts.push_back(dFit) ;
// dFit = phi1(dFit) ;
// } while(dFit != d) ;
// do
// {
// eDarts.push_back(eFit) ;
// eFit = phi1(eFit) ;
// } while(eFit != phi1(e)) ;
//
// if(dDarts.size() != eDarts.size())
// return false ;
//
// // Make the sewing: take darts in initial order (clockwise) in first face
// // and take darts in reverse order (counter-clockwise) in the second face
// std::vector<Dart>::iterator dIt;
// std::vector<Dart>::reverse_iterator eIt;
// for (dIt = dDarts.begin(), eIt = eDarts.rbegin(); dIt != dDarts.end(); ++dIt, ++eIt)
// {
// Dart d2 = phi2(*dIt); // Search the faces adjacent to dNext and eNext
// Dart e2 = phi2(*eIt);
// if (d2 != *dIt) phi2unsew(d2); // Unlink the two adjacent faces from dNext and eNext
// if (e2 != *eIt) phi2unsew(e2);
// if (d2 != *dIt && e2 != *eIt) phi2sew(d2,e2); // Link the two adjacent faces together if they exists
// }
// Map1::deleteOrientedFace(d); // Delete the two alone faces
// Map1::deleteOrientedFace(e);
//
// return true ;
if (isBoundaryMarked(d) || isBoundaryMarked(e))
return false;
// First traversal of both faces to check the face sizes // First traversal of both faces to check the face sizes
// and stored their edges to efficiently access them further // and stored their edges to efficiently access them further
std::vector<Dart> dDarts; std::vector<Dart> dDarts;
std::vector<Dart> eDarts; std::vector<Dart> eDarts;
dDarts.reserve(16); // usual faces have less than 16 edges dDarts.reserve(16); // usual faces have less than 16 edges
...@@ -473,9 +602,11 @@ bool Map2::mergeVolumes(Dart d, Dart e) ...@@ -473,9 +602,11 @@ bool Map2::mergeVolumes(Dart d, Dart e)
{ {
Dart d2 = phi2(*dIt); // Search the faces adjacent to dNext and eNext Dart d2 = phi2(*dIt); // Search the faces adjacent to dNext and eNext
Dart e2 = phi2(*eIt); Dart e2 = phi2(*eIt);
if (d2 != *dIt) phi2unsew(d2); // Unlink the two adjacent faces from dNext and eNext phi2unsew(d2); // Unlink the two adjacent faces from dNext and eNext
if (e2 != *eIt) phi2unsew(e2); phi2unsew(e2);
if (d2 != *dIt && e2 != *eIt) phi2sew(d2,e2); // Link the two adjacent faces together if they exists phi2sew(d2,e2); // Link the two adjacent faces together
if (isBoundaryMarked(d2) && isBoundaryMarked(e2))
mergeBoundaryFaces(d2,e2);
} }
Map1::deleteOrientedFace(d); // Delete the two alone faces Map1::deleteOrientedFace(d); // Delete the two alone faces
Map1::deleteOrientedFace(e); Map1::deleteOrientedFace(e);
...@@ -520,15 +651,26 @@ unsigned int Map2::closeHole(Dart d) ...@@ -520,15 +651,26 @@ unsigned int Map2::closeHole(Dart d)
return countEdges ; return countEdges ;
} }
void Map2::closeMap(DartMarker& marker) //void Map2::closeMap(DartMarker& marker)
{ //{
// Search the map for topological holes (fixed point for phi2) // // Search the map for topological holes (fixed point for phi2)
// for (Dart d = begin(); d != end(); next(d))
// {
// if (phi2(d) == d)
// {
// closeHole(d);