Commit 7e9a2472 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge cgogn:~jund/CGoGN

parents d8f993a0 412ec0b9
......@@ -42,10 +42,10 @@ template <typename PFP>
bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e, Dart f) ;
template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e);
void mergeVertex(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e);
template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions);
void mergeVertices(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions);
}
......
......@@ -40,55 +40,61 @@ bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>
}
template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e)
void mergeVertex(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e, int precision)
{
assert(Geom::arePointsEquals(positions[d],positions[e]) && !map.sameVertex(d,e));
// d1 traverses the vertex of d (following the alpha1 permutation)
// y is a temporay buffer to stop the loop
Dart d1=d;
// e1 traverses the vertex of e (following the alpha1 permutation)
Dart e1=e;
bool notempty = true;
do {
if (map.phi2_1(e1) == e1) notempty = false;
// detach z from its vertex
map.removeEdgeFromVertex(e1);
// Searchs the dart of the vertex of x where tz may be inserted
Dart nd1 = d1;
do {
if (CGoGN::Algo::BooleanOperator::isBetween<PFP>(map,positions,e1,d1,map.phi2_1(d1))) break;
d1 = map.phi2_1(d1);
} while (d1 != nd1);
map.insertEdgeInVertex(d1,e1);
d1 = e1;
} while (notempty);
assert(positions[d].isNear(positions[e], precision) && !map.sameVertex(d, e)) ;
// 0-embed z on the vertex of x without copy of the vertex
// positions[d] = ;
}
bool notempty = true ;
do // While vertex of e contains more than one dart
{
Dart e1 = map.alpha1(e) ; // e1 stores next dart of vertex of e
if (e1 == e)
notempty = false ; // last dart of vertex of e
else {
map.removeEdgeFromVertex(e) ; // detach e from its vertex
}
// Searchs where e may be inserted in the vertex of d
Dart d1 = d ;
do
{
if (CGoGN::Algo::BooleanOperator::isBetween<PFP>(map, positions, e, d,
map.alpha1(d))) break ;
d = map.alpha1(d) ;
} while (d != d1) ;
// Inserted e in the correct place (after d)
map.insertEdgeInVertex(d, e) ;
// Go on with next darts
d = e ;
e = e1 ;
} while (notempty) ;
}
template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions)
void mergeVertices(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions, int precision)
{
// TODO optimiser en triant les sommets
for(Dart d = map.begin() ; d != map.end() ; map.next(d))
// map.template enableQuickTraversal<VERTEX>();
TraversorV<typename PFP::MAP> travV1(map) ;
CellMarker<VERTEX> vM(map);
for(Dart d1 = travV1.begin() ; d1 != travV1.end() ; d1 = travV1.next())
{
CellMarker<VERTEX> vM(map);
vM.mark(d);
std::cout << "." ; std::cout.flush() ;
for(Dart dd = map.begin() ; dd != map.end() ; map.next(dd))
vM.mark(d1);
TraversorV<typename PFP::MAP> travV2(map) ;
for(Dart d2 = travV2.begin() ; d2 != travV2.end() ; d2 = travV2.next())
{
if(!vM.isMarked(dd))
if(!vM.isMarked(d2))
{
if(Geom::arePointsEquals(positions[d],positions[dd]))
if(positions[d1].isNear(positions[d2], precision))
{
mergeVertex<PFP>(map,positions,d,dd);
if (map.sameVertex(d1,d2)) std::cout << "fusion: sameVertex" << std::endl ;
if (!map.sameVertex(d1,d2)) mergeVertex<PFP>(map,positions,d1,d2,precision);
}
}
}
}
// map.template disableQuickTraversal<VERTEX>();
}
}
......
This diff is collapsed.
......@@ -173,9 +173,6 @@ Dart revolution(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>&
* @param the_map the map in which include created surface
* @param d a dart of the face to extrude
* @param N the vector use to extrude face center (point) of axis revolution
* @param axis direction of axis revolution
* @param profile_closed profile is a closed polygon or not ?
* @param nbSide number of steps around the revolution
*/
template<typename PFP>
Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>& positions,
......@@ -185,10 +182,7 @@ Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>
* Face extrusion
* @param the_map the map in which include created surface
* @param d a dart of the face to extrude
* @param N the vector use to extrude face center (point) of axis revolution
* @param axis direction of axis revolution
* @param profile_closed profile is a closed polygon or not ?
* @param nbSide number of steps around the revolution
* @param dist the height to extrude face
*/
template<typename PFP>
Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>& positions,
......
......@@ -450,36 +450,42 @@ void LoopSubdivision(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>
template <typename PFP, typename EMBV, typename EMB>
void TwoNPlusOneSubdivision(typename PFP::MAP& map, EMBV& attributs, const FunctorSelect& selected)
{
EdgeAutoAttribute<Dart> tablePred(map);
CellMarker<EDGE> m0(map);
CellMarker<FACE> m1(map);
std::vector<Dart> dOrig;
std::vector<EMB> cOrig;
m0.unmarkAll();
m1.unmarkAll();
//first pass cut edge
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
if(selected(d))
{
if(!m0.isMarked(d)) {
dOrig.push_back(d);
Dart dd = d;
do {
if(!m0.isMarked(dd)) {
EMB e1 = attributs[dd];
EMB e2 = attributs[map.phi1(dd)];
map.cutEdge(dd);
attributs[map.phi1(dd)] = e1*2.0f/3.0f+e2/3.0f;
map.cutEdge(map.phi1(dd));
attributs[map.phi1(map.phi1(dd))] = e2*2.0f/3.0f+e1/3.0f;
m0.mark(dd);
m0.mark(map.phi1(dd));
m0.mark(map.template phi<11>(dd));
}
dd = map.template phi<111>(dd);
} while(dd!=d);
if(!m0.isMarked(d))
{
if(!m1.isMarked(d))
{
m1.mark(d);
dOrig.push_back(d);
}
if(selected(map.phi2(d)) && !m1.isMarked(map.phi2(d)))
{
m1.mark(map.phi2(d));
dOrig.push_back(map.phi2(d));
}
EMB e1 = attributs[d];
EMB e2 = attributs[map.phi1(d)];
map.cutEdge(d);
attributs[map.phi1(d)] = e1*2.0f/3.0f+e2/3.0f;
map.cutEdge(map.phi1(d));
attributs[map.phi1(map.phi1(d))] = e2*2.0f/3.0f+e1/3.0f;
m0.mark(d);
m0.mark(map.phi1(d));
m0.mark(map.template phi<11>(d));
}
}
}
......
......@@ -117,7 +117,7 @@ void Plane3D<T>::project(Vector<3,T>& p) const
{
#define PRECISION 1e-10
T d = -distance(p) ;
if(abs(d) > PRECISION)
if(std::abs(d) > PRECISION)
{
Vector<3,T> v = m_normal * d ;
p += v ;
......
......@@ -127,8 +127,16 @@ public:
double norm() const ;
/*
* normalize the vector and returns its norm
*/
double normalize() ;
/*
* Return a normalized copy
*/
Vector<DIM, T> normalized() const;
// dot product
T operator*(const Vector<DIM, T> v) const ;
......@@ -152,13 +160,21 @@ public:
*/
bool isNormalized(const T& epsilon) const ;
/**
* Tests if current and given vectors are near within 1/precision (equal if precision is zero)
* @param V a vector
* @param epsilon tolerated error
* @return true if orthogonal
*/
bool isNear(const Vector<DIM, T>& v, int precision) const ;
/**
* Tests if current and given vectors are orthogonal
* @param V a vector
* @param epsilon tolerated error
* @return true if orthogonal
*/
bool isOrthogonal(const Vector<DIM, T>& V, const T& epsilon = 1e-5) const ;
bool isOrthogonal(const Vector<DIM, T>& v, const T& epsilon = 1e-5) const ;
/**********************************************/
/* STREAM OPERATORS */
......@@ -174,6 +190,22 @@ private:
T m_data[DIM] ;
} ;
/***
* Test if x is null within precision.
* Two cases are possible :
* - precision == 0 : x is null if (x == 0)
* - precision > 0 : x is null if (|x| < 1/precision) or (precision * |x| < 1)
*/
template <typename T>
bool isNull(T x, int precision = 0) ;
/***
* Test if the square root of x is null within precision.
* In other words, test if x is null within precision*precision
*/
template <typename T>
bool isNull2(T x, int precision = 0) ;
template <unsigned int DIM, typename T>
Vector<DIM, T> operator*(T a, const Vector<DIM, T>& v) ;
......
......@@ -256,6 +256,14 @@ inline double Vector<DIM, T>::normalize()
return n ;
}
template <unsigned int DIM, typename T>
inline Vector<DIM, T> Vector<DIM, T>::normalized() const
{
Vector<DIM, T> v(*this);
v.normalize();
return v;
}
template <unsigned int DIM, typename T>
inline T Vector<DIM, T>::operator*(const Vector<DIM, T> v) const
{
......@@ -315,9 +323,23 @@ inline bool Vector<DIM, T>::isNormalized(const T& epsilon) const
}
template <unsigned int DIM, typename T>
inline bool Vector<DIM, T>::isOrthogonal(const Vector<DIM, T>& V, const T& epsilon) const
inline bool Vector<DIM, T>::isOrthogonal(const Vector<DIM, T>& v, const T& epsilon) const
{
return (fabs(v * (*this)) < epsilon) ;
}
template <unsigned int DIM, typename T>
inline bool Vector<DIM, T>::isNear(const Vector<DIM, T>& v, int precision) const
{
return (fabs(V * (*this)) < epsilon) ;
T diff ;
T norm2(0) ;
for (unsigned int i = 0 ; i < DIM ; ++i)
{
diff = m_data[i] - v[i] ;
if (!isNull(diff, precision)) return false ;
norm2 += diff * diff ;
}
return isNull2(norm2, precision) ;
}
/**********************************************/
......@@ -340,6 +362,39 @@ std::istream& operator>>(std::istream& in, Vector<DIM, T>& v)
return in ;
}
/***
* Test if x is null within precision.
* 3 cases are possible :
* - precision = 0 : x is null <=> (x == 0)
* - precision > 0 : x is null <=> (|x| < precision)
* - precision < 0 : x is null <=> (|x| < 1/precision) <=> (precision * |x| < 1)
*/
template <typename T>
inline bool isNull(T x, int precision)
{
if (precision == 0)
return (x == 0) ;
else if (precision > 0)
return (fabs(x) < precision) ;
else
return (precision * fabs(x) < 1) ;
}
/***
* Test if the square root of x is null within precision.
* In other words, test if x is null within precision*precision
*/
template <typename T>
inline bool isNull2(T x, int precision)
{
if (precision == 0)
return (x == 0) ;
else if (precision > 0)
return (isNull(x, precision * precision)) ;
else
return (isNull(x, - (precision * precision))) ;
}
template <unsigned int DIM, typename T>
inline Vector<DIM, T> operator*(T a, const Vector<DIM, T>& v)
{
......
......@@ -40,7 +40,10 @@ public:
typedef Map2 TOPO_MAP;
/*
*
*/
virtual Dart newPolyLine(unsigned int nbEdges) ;
/*
*/
virtual Dart newFace(unsigned int nbEdges, bool withBoundary = true) ;
......@@ -93,6 +96,18 @@ public:
*/
virtual void swapEdges(Dart d, Dart e);
/**
* The attributes attached to the vertex of dart d are kept on the resulting vertex
* The attributes attached to the face of dart d are overwritten on the face of dart e
*/
virtual void insertEdgeInVertex(Dart d, Dart e);
/**
* The attributes attached to the vertex of dart d are kept on the resulting vertex
* The attributes attached to the face of dart d are overwritten on the face of dart e
*/
virtual bool removeEdgeFromVertex(Dart d);
/**
* The attributes attached to the vertices of the edge of d are kept on the vertices of the resulting edge
* The attributes attached to the edge of d are kept on the resulting edge
......
......@@ -125,16 +125,22 @@ public:
*************************************************************************/
//@{
//! Create an new polyline of nbEdges, i.e 2*nbEdges darts pairwise sewn by phi2
/*! @param nbEdges the number of edges
* @return return a dart of the face
*/
virtual Dart newPolyLine(unsigned int nbEdges) ;
//! Create an new face of nbEdges
/*! @param nbEdges the number of edges
* @param withBoudary create the face and its boundary (default true)
* @param withBoundary create the face and its boundary (default true)
* @return return a dart of the face
*/
virtual Dart newFace(unsigned int nbEdges, bool withBoundary = true) ;
//! Delete the face of d
/*! @param d a dart of the face
* @param withBoudary create or extend boundary face instead of fixed points (default true)
* @param withBoundary create or extend boundary face instead of fixed points (default true)
*/
virtual void deleteFace(Dart d, bool withBoundary = true) ;
......@@ -216,6 +222,18 @@ public:
*/
void swapEdges(Dart d, Dart e);
// * @param d dart of the vertex
// * @param e dart of the edge
// */
virtual void insertEdgeInVertex(Dart d, Dart e);
//
// //! Remove an edge from a vertex orbit
// /*! \pre Dart d must be phi2 sewed
// * @param d the dart of the edge to remove from the vertex
// * @return true if the removal has been executed, false otherwise
// */
virtual bool removeEdgeFromVertex(Dart d);
//! Sew two oriented faces along oriented edges
/*! \pre Edges of darts d & e MUST be boundary edges
* @param d a dart of the first face
......@@ -463,7 +481,7 @@ public:
* These faces are marked as boundary.
* @return the number of closed holes
*/
unsigned int closeMap();
unsigned int closeMap(bool forboundary = true);
//@}
};
......
......@@ -30,6 +30,37 @@
namespace CGoGN
{
Dart EmbeddedMap2::newPolyLine(unsigned int nbEdges)
{
Dart d = Map2::newPolyLine(nbEdges) ;
if (isOrbitEmbedded<VERTEX>())
{
Dart e = d ;
for (unsigned int i = 0 ; i <= nbEdges ; ++i)
{
initOrbitEmbeddingNewCell<VERTEX>(e) ;
e = this->phi1(e) ;
}
}
if (isOrbitEmbedded<EDGE>())
{
Dart e = d ;
for (unsigned int i = 0 ; i < nbEdges ; ++i)
{
initOrbitEmbeddingNewCell<EDGE>(e) ;
e = this->phi1(e) ;
}
}
if (isOrbitEmbedded<FACE>())
{
initOrbitEmbeddingNewCell<FACE>(d) ;
}
return d ;
}
Dart EmbeddedMap2::newFace(unsigned int nbEdges, bool withBoundary)
{
Dart d = Map2::newFace(nbEdges, withBoundary);
......@@ -310,6 +341,58 @@ void EmbeddedMap2::swapEdges(Dart d, Dart e)
setOrbitEmbeddingOnNewCell<VOLUME>(d);
}
void EmbeddedMap2::insertEdgeInVertex(Dart d, Dart e)
{
Map2::insertEdgeInVertex(d, e);
if (isOrbitEmbedded<VERTEX>())
{
copyDartEmbedding<VERTEX>(e, d) ;
}
if (isOrbitEmbedded<FACE>())
{
if(!sameFace(d,e))
{
setOrbitEmbeddingOnNewCell<FACE>(e);
copyCell<FACE>(e, d);
}
else
{
setOrbitEmbedding<FACE>(d, getEmbedding<FACE>(d)) ;
}
}
}
bool EmbeddedMap2::removeEdgeFromVertex(Dart d)
{
Dart dPrev = alpha_1(d);
if (dPrev == d) return false ;
bool b = Map2::removeEdgeFromVertex(d);
if (isOrbitEmbedded<VERTEX>())
{
setOrbitEmbeddingOnNewCell<VERTEX>(d);
copyCell<VERTEX>(d, dPrev);
}
if (isOrbitEmbedded<FACE>())
{
if(!sameFace(d, dPrev))
{
setOrbitEmbeddingOnNewCell<FACE>(d);
copyCell<FACE>(d, dPrev);
}
else
{
setDartEmbedding<FACE>(d, getEmbedding<FACE>(d)) ;
}
}
return b ;
}
void EmbeddedMap2::sewFaces(Dart d, Dart e, bool withBoundary)
{
if (!withBoundary)
......
......@@ -107,6 +107,22 @@ void Map2::compactTopoRelations(const std::vector<unsigned int>& oldnew)
* To generate or delete faces in a 2-map
*************************************************************************/
Dart Map2::newPolyLine(unsigned int nbEdges)
{
Dart d = Map1::newCycle(2*nbEdges);
{
Dart it1 = d;
Dart it2 = phi_1(d);
for(unsigned int i = 0; i<nbEdges ; ++i)
{
phi2sew(it1, it2);
it1 = phi1(it1);
it2 = phi_1(it2);
}
}
return d;
}
Dart Map2::newFace(unsigned int nbEdges, bool withBoundary)
{
Dart d = Map1::newCycle(nbEdges);
......@@ -340,6 +356,23 @@ void Map2::swapEdges(Dart d, Dart e)
//phi2sew(d2, e2);
}
void Map2::insertEdgeInVertex(Dart d, Dart e)
{
assert(!sameVertex(d,e));
assert(phi2(e) == phi_1(e));
phi1sew(phi_1(d), phi_1(e));
}
bool Map2::removeEdgeFromVertex(Dart d)
{
if (!isBoundaryEdge(d))
{
phi1sew(phi_1(d), phi2(d)) ;
return true ;
}
return false ;
}
void Map2::sewFaces(Dart d, Dart e, bool withBoundary)
{
// if sewing with fixed points
......@@ -873,7 +906,7 @@ unsigned int Map2::closeHole(Dart d, bool forboundary)
return countEdges ;
}
unsigned int Map2::closeMap()
unsigned int Map2::closeMap(bool forboundary)
{
// Search the map for topological holes (fix points of phi2)
unsigned int nb = 0 ;
......@@ -882,7 +915,7 @@ unsigned int Map2::closeMap()
if (phi2(d) == d)
{
++nb ;
closeHole(d);
closeHole(d, forboundary);
}
}
return nb ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment