Commit df886b3c authored by Pierre Kraemer's avatar Pierre Kraemer

GMap3 on their way..

parent a3219fc5
......@@ -96,6 +96,11 @@ public:
*/
virtual void deleteFace(Dart d);
//! Delete a connected component of the map
/*! @param d a dart of the connected component
*/
virtual void deleteCC(Dart d) ;
//! Fill a hole with a face
/*! \pre Dart d is boundary marked
* @param d a dart of the face to fill
......@@ -341,6 +346,11 @@ public:
* Should be executed after import
*/
virtual bool check();
/**
* Check if a serie of darts is an oriented simple close path
*/
virtual bool checkSimpleOrientedPath(std::vector<Dart>& vd);
//@}
/*! @name Cell Functors
......
......@@ -161,6 +161,11 @@ inline bool GMap2::sameEdge(Dart d, Dart e)
return d == e || beta2(d) == e || beta0(d) == e || beta2(beta0(d)) == e ;
}
inline bool GMap2::isBoundaryEdge(Dart d)
{
return isBoundaryMarked(d) || isBoundaryMarked(beta2(d));
}
inline bool GMap2::sameOrientedFace(Dart d, Dart e)
{
return GMap1::sameOrientedFace(d, e) ;
......
......@@ -31,7 +31,7 @@ namespace CGoGN
{
/**
* The class of 2-GMap
* The class of 3-GMap
*/
class GMap3 : public GMap2
{
......@@ -71,22 +71,18 @@ public:
Dart alpha1(Dart d);
Dart alpha_1(Dart d);
Dart alpha2(Dart d);
Dart alpha_2(Dart d);
protected:
void beta3sew(Dart d, Dart e);
void beta3unsew(Dart d);
void phi3sew(Dart d, Dart e);
void phi3unsew(Dart d);
public:
/*! @name Generator and Deletor
* To generate or delete volumes in a 3-map
* To generate or delete volumes in a 3-G-map
*************************************************************************/
//@{
......@@ -95,32 +91,50 @@ public:
* @param d a dart of the volume
*/
void deleteVolume(Dart d);
//! Fill a hole with a volume
/*! \pre Dart d is boundary marked
* @param d a dart of the volume to fill
*/
virtual void fillHole(Dart d) ;
//@}
/*! @name Topological Operators
* Topological operations on 3-maps
* Topological operations on 3-G-maps
*************************************************************************/
//@{
//! Cut the edge of d
//! Delete the vertex of d
/*! All the faces around the vertex are merged into one face
* @param d a dart of the vertex to delete
* @return true if the deletion has been executed, false otherwise
*/
virtual Dart deleteVertex(Dart d);
//! Cut the edge of d (all darts around edge orbit are cut)
/*! @param d a dart of the edge to cut
*/
virtual void cutEdge(Dart d);
//! Uncut the edge of d (all darts around edge orbit are uncut)
/*! @param d a dart of the edge to uncut
*/
virtual bool uncutEdge(Dart d);
//! Split a face inserting an edge between two vertices
/*! \pre Dart d and e should belong to the same face and be distinct
* @param d dart of first vertex
* @param e dart of second vertex
* @return the dart of the new edge lying in the vertex of d after the cut
*/
virtual void splitFace(Dart d, Dart e);
//! Sew two oriented volumes along their faces.
/*! The oriented faces should not be phi3-linked and have the same length
/*! The oriented faces should not be beta3-linked and have the same degree
* @param d a dart of the first volume
* @param e a dart of the second volume
* @param withBoundary: if false, volumes must have beta3 fixed points (only for construction: import/primitives)
*/
void sewVolumes(Dart d, Dart e);
virtual void sewVolumes(Dart d, Dart e, bool withBoundary = true);
//! unsew two oriented volumes along their faces.
/*! @param d a dart of one volume
......@@ -131,8 +145,12 @@ public:
/*! @param d a dart of common face
*/
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<Dart>& vd);
//@}
/*! @name Topological Queries
* Return or set various topological information
......@@ -159,7 +177,7 @@ public:
//! Tell if the vertex of d is on the boundary
/*! @param d a dart
*/
virtual bool isBoundaryVertex(Dart d);
virtual bool isBoundaryVertex(Dart d) ;
//! Test if dart d and e belong to the same oriented edge
/*! @param d a dart
......@@ -176,23 +194,43 @@ public:
//! Compute the number of volumes around the edge of d
/*! @param d a dart
*/
unsigned int edgeDegree(Dart d);
unsigned int edgeDegree(Dart d) ;
/**
* tell if the edge of d is on the boundary of the map
*/
bool isBoundaryEdge(Dart d) ;
/**
* find the dart of edge that belong to the boundary
* return NIL if the edge is not on the boundary
*/
Dart findBoundaryFaceOfEdge(Dart d) ;
//!Test if dart d and e belong to the same oriented face
/*! @param d a dart
* @param e a dart
*/
bool sameOrientedFace(Dart d, Dart e);
bool sameOrientedFace(Dart d, Dart e) ;
//!Test if dart d and e belong to the same oriented face
/*! @param d a dart
* @param e a dart
*/
bool sameFace(Dart d, Dart e);
bool sameFace(Dart d, Dart e) ;
virtual bool check();
//@}
//! Test if the face is on the boundary
/*! @param d a dart from the face
*/
bool isBoundaryFace(Dart d) ;
//! Tell if a face of the volume is on the boundary
/* @param d a dart
*/
bool isBoundaryVolume(Dart d) ;
virtual bool check() ;
//@}
/*! @name Cell Functors
* Apply functors to all darts of a cell
......@@ -204,42 +242,55 @@ public:
* @param d a dart of the face
* @param fonct functor obj ref
*/
bool foreach_dart_of_oriented_vertex(Dart d, FunctorType& fonct, unsigned int thread=0);
bool foreach_dart_of_oriented_vertex(Dart d, FunctorType& fonct, unsigned int thread = 0);
/**
* Apply a functor on each dart of a vertex
* @param d a dart of the face
* @param fonct functor obj ref
*/
bool foreach_dart_of_vertex(Dart d, FunctorType& fonct, unsigned int thread=0);
bool foreach_dart_of_vertex(Dart d, FunctorType& fonct, unsigned int thread = 0);
/**
* Apply a functor on each dart of an edge
* @param d a dart of the oriented face
* @param fonct functor obj ref
*/
bool foreach_dart_of_edge(Dart d, FunctorType& fonct, unsigned int thread=0);
bool foreach_dart_of_edge(Dart d, FunctorType& fonct, unsigned int thread = 0);
//! Apply a functor on every dart of a face
/*! @param d a dart of the volume
* @param f the functor to apply
*/
bool foreach_dart_of_face(Dart d, FunctorType& fonct, unsigned int thread=0);
//! Apply a functor on every dart of a volume
/*! @param d a dart of the volume
* @param f the functor to apply
*/
bool foreach_dart_of_volume(Dart d, FunctorType& fonct, unsigned int thread=0);
bool foreach_dart_of_face(Dart d, FunctorType& fonct, unsigned int thread = 0);
/**
* Apply a functor on each dart of a cc
* @param d a dart of the cc
* @param fonct functor obj ref
*/
bool foreach_dart_of_cc(Dart d, FunctorType& fonct, unsigned int thread=0);
bool foreach_dart_of_cc(Dart d, FunctorType& fonct, unsigned int thread = 0);
//@}
/*! @name Close map after import or creation
* These functions must be used with care, generally only by import algorithms
*************************************************************************/
//@{
//! Close a topological hole (a sequence of connected fixed point of phi3). DO NOT USE, only for import/creation algorithm
/*! \pre dart d MUST be fixed point of phi3 relation
* Add a volume to the map that closes the hole.
* @param d a dart of the hole (with phi3(d)==d)
* @param forboundary tag the created face as boundary (default is true)
* @return the degree of the created volume
*/
virtual unsigned int closeHole(Dart d, bool forboundary = true);
//! Close the map removing topological holes: DO NOT USE, only for import/creation algorithm
/*! Add volumes to the map that close every existing hole.
* These faces are marked as boundary.
*/
void closeMap();
};
} // namespace CGoGN
......
......@@ -93,31 +93,9 @@ inline Dart GMap3::beta(const Dart d)
}
}
inline Dart GMap3::alpha2(Dart d)
{
Dart e = beta2(d);
Dart f = beta3(e);
if (f != e)
return f;
f = d;
e = beta3(f);
while (e != f)
{
f = beta2(e);
e = beta3(f);
}
return f;
}
inline Dart GMap3::phi3(Dart d)
{
Dart e = beta3(d) ;
if(e == d)
return d ;
else
return beta3(beta0(d)) ;
return beta3(beta0(d)) ;
}
template <int N>
......@@ -143,7 +121,25 @@ inline Dart GMap3::phi(Dart d)
}
}
inline Dart GMap3::alpha0(Dart d)
{
return beta3(beta0(d)) ;
}
inline Dart GMap3::alpha1(Dart d)
{
return beta3(beta1(d)) ;
}
inline Dart GMap3::alpha2(Dart d)
{
return beta3(beta2(d)) ;
}
inline Dart GMap3::alpha_2(Dart d)
{
return beta2(beta3(d)) ;
}
inline void GMap3::beta3sew(Dart d, Dart e)
{
......@@ -160,21 +156,27 @@ inline void GMap3::beta3unsew(Dart d)
(*m_beta3)[e.index] = e ;
}
inline void GMap3::phi3sew(Dart d, Dart e)
/*! @name Topological Queries
* Return or set various topological information
*************************************************************************/
inline bool GMap3::sameFace(Dart d, Dart e)
{
beta3sew(d, beta0(e)) ;
beta3sew(beta0(d), e) ;
return GMap2::sameFace(d, e) || GMap2::sameFace(beta3(d), e) ;
}
inline void GMap3::phi3unsew(Dart d)
inline bool GMap3::isBoundaryFace(Dart d)
{
beta3unsew(d) ;
beta3unsew(beta0(d)) ;
return isBoundaryMarked(d) || isBoundaryMarked(beta3(d));
}
/*! @name Cell Functors
* Apply functors to all darts of a cell
*************************************************************************/
inline bool GMap3::foreach_dart_of_face(Dart d, FunctorType& f, unsigned int thread)
{
return GMap2::foreach_dart_of_face(d, f, thread) || GMap2::foreach_dart_of_face(beta3(d), f, thread);
}
} // end namespace CGoGN
} // namespace CGoGN
......@@ -130,12 +130,12 @@ public:
*/
virtual Dart deleteVertex(Dart d);
//! Cut the edge of d (all darts around edge orbit are cutted)
//! Cut the edge of d (all darts around edge orbit are cut)
/*! @param d a dart of the edge to cut
*/
virtual void cutEdge(Dart d);
//! Uncut the edge of d (all darts around edge orbit are uncutted)
//! Uncut the edge of d (all darts around edge orbit are uncut)
/*! @param d a dart of the edge to uncut
*/
virtual bool uncutEdge(Dart d);
......@@ -144,12 +144,11 @@ public:
/*! \pre Dart d and e should belong to the same face and be distinct
* @param d dart of first vertex
* @param e dart of second vertex
* @return the dart of the new edge lying in the vertex of d after the cut
*/
virtual void splitFace(Dart d, Dart e);
//! Sew two oriented volumes along their faces.
/*! The oriented faces should not be phi3-linked and have the same length
/*! The oriented faces should not be phi3-linked and have the same degree
* @param d a dart of the first volume
* @param e a dart of the second volume
* @param withBoundary: if false, volumes must have phi3 fixed points (only for construction: import/primitives)
......@@ -191,7 +190,7 @@ public:
//! Tell if the vertex of d is on the boundary
/*! @param d a dart
*/
bool isBoundaryVertex(Dart d);
bool isBoundaryVertex(Dart d) ;
//! Test if dart d and e belong to the same oriented edge
/*! @param d a dart
......@@ -208,7 +207,7 @@ public:
//! Compute the number of volumes around the edge of d
/*! @param d a dart
*/
unsigned int edgeDegree(Dart d);
unsigned int edgeDegree(Dart d) ;
/**
* tell if the edge of d is on the boundary of the map
......@@ -219,26 +218,26 @@ public:
* find the dart of edge that belong to the boundary
* return NIL if the edge is not on the boundary
*/
Dart findBoundaryFaceOfEdge(Dart d);
Dart findBoundaryFaceOfEdge(Dart d) ;
//! Test if dart d and e belong to the same oriented face
/*! @param d a dart
* @param e a dart
*/
bool sameFace(Dart d, Dart e);
bool sameFace(Dart d, Dart e) ;
//! Test if the face is on the boundary
/*! @param d a dart from the face
*/
bool isBoundaryFace(Dart d);
bool isBoundaryFace(Dart d) ;
//! Tell if a face of the volume is on the boundary
/* @param d a dart
*/
bool isBoundaryVolume(Dart d);
bool isBoundaryVolume(Dart d) ;
// TODO a mettre dans algo ?
virtual bool check();
virtual bool check() ;
//@}
/*! @name Cell Functors
......
......@@ -66,10 +66,48 @@ void GMap2::deleteFace(Dart d)
GMap1::deleteFace(dd) ;
}
void GMap2::deleteCC(Dart d)
{
DartMarkerStore mark(*this);
std::vector<Dart> visited;
visited.reserve(1024) ;
visited.push_back(d);
mark.mark(d) ;
for (std::vector<Dart>::iterator it = visited.begin(); it != visited.end(); ++it)
{
Dart d0 = beta0(*it) ;
if(!mark.isMarked(d0))
{
visited.push_back(d0) ;
mark.mark(d0);
}
Dart d1 = beta1(*it) ;
if(!mark.isMarked(d1))
{
visited.push_back(d1) ;
mark.mark(d1);
}
Dart d2 = beta2(*it) ;
if(!mark.isMarked(d2))
{
visited.push_back(d2) ;
mark.mark(d2);
}
}
for(std::vector<Dart>::iterator it = visited.begin(); it != visited.end(); ++it)
deleteDart(*it) ;
}
void GMap2::fillHole(Dart d)
{
assert(isBoundaryMarked(d)) ;
boundaryUnmarkOrbit(FACE, d) ;
assert(isBoundaryEdge(d)) ;
Dart dd = d ;
if(!isBoundaryMarked(dd))
dd = phi2(dd) ;
boundaryUnmarkOrbit(FACE, dd) ;
}
/*! @name Topological Operators
......@@ -110,7 +148,7 @@ Dart GMap2::deleteVertex(Dart d)
vit = alpha1(vit) ;
} while(vit != d) ;
deleteFace(d) ;
GMap1::deleteFace(d) ;
return res ;
}
......@@ -321,9 +359,9 @@ void GMap2::unsewFaces(Dart d)
Dart e = newBoundaryFace(2);
Dart ee = phi1(e) ;
if (isBoundaryVertex(d))
Dart f = findBoundaryEdgeOfVertex(d) ;
if (f != NIL)
{
Dart f = findBoundaryEdgeOfVertex(d);
Dart f1 = beta1(f) ;
beta1unsew(ee) ;
beta1unsew(f) ;
......@@ -331,9 +369,9 @@ void GMap2::unsewFaces(Dart d)
beta1sew(f1, ee) ;
}
if (isBoundaryVertex(dd))
f = findBoundaryEdgeOfVertex(dd) ;
if (f != NIL)
{
Dart f = findBoundaryEdgeOfVertex(dd);
Dart f1 = beta1(f) ;
beta1unsew(e) ;
beta1unsew(f) ;
......@@ -486,7 +524,7 @@ bool GMap2::mergeVolumes(Dart d, Dart e)
{
assert(!isBoundaryMarked(d) && !isBoundaryMarked(e)) ;
if (isBoundaryFace(d) || isBoundaryFace(e))
if (GMap2::isBoundaryFace(d) || GMap2::isBoundaryFace(e))
return false;
// First traversal of both faces to check the face sizes
......@@ -519,7 +557,7 @@ bool GMap2::mergeVolumes(Dart d, Dart e)
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 d2 = phi2(*dIt); // Search the faces adjacent to dNext and eNext
Dart e2 = phi2(*eIt);
beta2unsew(d2); // Unlink the two adjacent faces from dNext and eNext
beta2unsew(beta0(d2));
......@@ -528,8 +566,8 @@ bool GMap2::mergeVolumes(Dart d, Dart e)
beta2sew(d2, beta0(e2)); // Link the two adjacent faces together
beta2sew(e2, beta0(d2));
}
deleteFace(d); // Delete the two alone faces
deleteFace(e);
GMap1::deleteFace(d); // Delete the two alone faces
GMap1::deleteFace(e);
return true ;
}
......@@ -586,12 +624,6 @@ Dart GMap2::findBoundaryEdgeOfVertex(Dart d)
return NIL ;
}
bool GMap2::isBoundaryEdge(Dart d)
{
Dart e = beta2(d);
return isBoundaryMarked(e) || isBoundaryMarked(d);
}
bool GMap2::isBoundaryFace(Dart d)
{
Dart it = d ;
......@@ -718,6 +750,27 @@ bool GMap2::check()
return true;
}
bool GMap2::checkSimpleOrientedPath(std::vector<Dart>& vd)
{
DartMarkerStore dm(*this) ;
for(std::vector<Dart>::iterator it = vd.begin() ; it != vd.end() ; ++it)
{
if(dm.isMarked(*it))
return false ;
dm.markOrbit(VERTEX, *it) ;
std::vector<Dart>::iterator prev ;
if(it == vd.begin())
prev = vd.end() - 1 ;
else
prev = it - 1 ;
if(!sameVertex(*it, phi1(*prev)))
return false ;
}
return true ;
}
/*! @name Cell Functors
* Apply functors to all darts of a cell
*************************************************************************/
......@@ -753,34 +806,34 @@ bool GMap2::foreach_dart_of_edge(Dart d, FunctorType& f, unsigned int thread)
bool GMap2::foreach_dart_of_oriented_volume(Dart d, FunctorType& f, unsigned int thread)
{
DartMarkerStore mark(*this,thread); // Lock a marker
DartMarkerStore mark(*this, thread); // Lock a marker
bool found = false; // Last functor return value
std::list<Dart> visitedFaces; // Faces that are traversed
std::vector<Dart> visitedFaces; // Faces that are traversed
visitedFaces.reserve(1024) ;
visitedFaces.push_back(d); // Start with the face of d
std::list<Dart>::iterator face;
// For every face added to the list
for (face = visitedFaces.begin(); !found && face != visitedFaces.end(); ++face)
for (std::vector<Dart>::iterator it = visitedFaces.begin(); !found && it != visitedFaces.end(); ++it)
{
if (!isBoundaryMarked(*face) && !mark.isMarked(*face)) // Face has not been visited yet
if (!mark.isMarked(*it)) // Face has not been visited yet
{
// Apply functor to the darts of the face
found = foreach_dart_of_oriented_face(*face, f);
found = foreach_dart_of_oriented_face(*it, f);
// If functor returns false then mark visited darts (current face)
// and add non visited adjacent faces to the list of face
if (!found)
{
Dart dNext = *face ;
Dart e = *it ;
do
{
mark.mark(dNext); // Mark
Dart adj = phi2(dNext); // Get adjacent face
if (!isBoundaryMarked(adj) && !mark.isMarked(adj))
mark.mark(e); // Mark
Dart adj = phi2(e); // Get adjacent face
if (!mark.isMarked(e))
visitedFaces.push_back(adj); // Add it
dNext = phi1(dNext);
} while(dNext != *face);
e = phi1(e);
} while(e != *it);
}
}
}
......@@ -825,16 +878,8 @@ unsigned int GMap2::closeHole(Dart d, bool forboundary)
}
} while (dPhi1 != d);
if (countEdges < 3)
{
countEdges = 0 ;
collapseDegeneratedFace(first); // if the closing face is 2-sided, collapse it
}
else
{
if(forboundary)
boundaryMarkOrbit(FACE, phi2(d));
}