Commit e300c9f4 authored by David Cazier's avatar David Cazier

ajout de newPolyLines

parent c0b35bc7
...@@ -40,15 +40,12 @@ bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3> ...@@ -40,15 +40,12 @@ bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>
} }
template <typename PFP> template <typename PFP>
void mergeVertex(typename PFP::MAP& map, 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)) ; assert(positions[d].isNear(positions[e], precision) && !map.sameVertex(d, e)) ;
typedef typename PFP::VEC3 VEC3;
VEC3 p = positions[d] ;
bool notempty = true ; bool notempty = true ;
do // while vertex of e contains more than one dart do // While vertex of e contains more than one dart
{ {
Dart e1 = map.alpha1(e) ; // e1 stores next dart of vertex of e Dart e1 = map.alpha1(e) ; // e1 stores next dart of vertex of e
if (e1 == e) if (e1 == e)
...@@ -72,32 +69,32 @@ void mergeVertex(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& po ...@@ -72,32 +69,32 @@ void mergeVertex(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& po
d = e ; d = e ;
e = e1 ; e = e1 ;
} while (notempty) ; } while (notempty) ;
// 0-embed z on the merged vertex
positions[d] = p ;
} }
template <typename PFP> template <typename PFP>
void mergeVertices(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions) void mergeVertices(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions, int precision)
{ {
// TODO optimiser en triant les sommets // 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(d1);
vM.mark(d); TraversorV<typename PFP::MAP> travV2(map) ;
for(Dart dd = map.begin() ; dd != map.end() ; map.next(dd)) 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))
{ {
if (map.sameVertex(d,dd)) std::cout << "fusion: sameVertex" << std::endl ; if (map.sameVertex(d1,d2)) std::cout << "fusion: sameVertex" << std::endl ;
if (!map.sameVertex(d,dd)) mergeVertex<PFP>(map,positions,d,dd); if (!map.sameVertex(d1,d2)) mergeVertex<PFP>(map,positions,d1,d2,precision);
// vM.mark(d);
} }
} }
} }
} }
// map.template disableQuickTraversal<VERTEX>();
} }
} }
......
...@@ -310,10 +310,9 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib ...@@ -310,10 +310,9 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
//create broken lines //create broken lines
DartMarker brokenL(map); DartMarker brokenL(map);
unsigned int nbVertices = 0 ; typename std::vector<POLYGON >::iterator it;
std::vector<float >::iterator itW = allBrokenLinesWidth.begin(); std::vector<float >::iterator itW = allBrokenLinesWidth.begin();
for(typename std::vector<POLYGON >::iterator it = allBrokenLines.begin() ; it != allBrokenLines.end() ; ++it) for(it = allBrokenLines.begin() ; it != allBrokenLines.end() ; ++it, ++itW)
{ {
if(it->size()<2) if(it->size()<2)
{ {
...@@ -322,74 +321,48 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib ...@@ -322,74 +321,48 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
} }
else else
{ {
nbVertices += it->size() ; Dart d = map.newPolyLine(it->size()-1);
Dart d = map.newFace(it->size()*2-2,false); for(typename POLYGON::iterator emb = it->begin(); emb != it->end() ; emb++)
Dart d1=d;
Dart d_1=map.phi_1(d);
//build a degenerated "line" face
for(unsigned int i = 0; i<it->size() ; ++i)
{ {
brokenL.mark(d1); brokenL.mark(d);
brokenL.mark(d_1); brokenL.mark(map.phi2(d));
map.sewFaces(d1,d_1,false) ;
edgeWidth[d1] = *itW; edgeWidth[d] = *itW;
if (*itW == 0) if (*itW == 0)
std::cout << "importSVG : null path width" << std::endl ; std::cout << "importSVG : null path width" << std::endl ;
d1 = map.phi1(d1);
d_1 = map.phi_1(d_1);
}
// polygonsFaces.mark(d);
//embed the line
d1 = d;
for(typename POLYGON::iterator emb = it->begin(); emb != it->end() ; emb++)
{
bb->addPoint(*emb); bb->addPoint(*emb);
position[d1] = *emb; position[d] = *emb;
d1 = map.phi1(d1); d = map.phi1(d);
} }
} }
itW++;
} }
std::cout << "importSVG : broken lines created : " << std::endl;
std::cout << "importSVG : broken lines created : " << nbVertices << " vertices"<< std::endl;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Merge near vertices
Algo::BooleanOperator::mergeVertices<PFP>(map,position); Algo::BooleanOperator::mergeVertices<PFP>(map,position,1);
std::cout << "importSVG : Merging of vertices." << std::endl; std::cout << "importSVG : Merging of vertices." << std::endl;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
//create polygons //create polygons
typename std::vector<POLYGON >::iterator it;
for(it = allPoly.begin() ; it != allPoly.end() ; ++it) for(it = allPoly.begin() ; it != allPoly.end() ; ++it)
{ {
if(it->size()<4) if(it->size()<3)
{ {
it = allPoly.erase(it); it = allPoly.erase(it);
} }
else else
{ {
Dart d = map.newFace(it->size()); Dart d = map.newFace(it->size());
// std::cout << "newFace1 " << it->size()-1 << std::endl;
polygonsFaces.mark(d); polygonsFaces.mark(d);
Dart dd = d; for(typename POLYGON::iterator emb = it->begin(); emb != it->end() ; emb++)
typename POLYGON::iterator emb = it->begin();
do
{ {
bb->addPoint(*emb); bb->addPoint(*emb);
position[dd] = *emb; position[d] = *emb;
emb++; d = map.phi1(d);
dd = map.phi1(dd); }
} while(dd!=d);
} }
} }
...@@ -409,26 +382,6 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib ...@@ -409,26 +382,6 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
std::cout << "importSVG : Polygons generated." << std::endl; std::cout << "importSVG : Polygons generated." << std::endl;
/////////////////////////////////////////////////////////////////////////////////////////////
//simplify the edges to have a more regular sampling
float minDist = 20.0f ;
for (Dart d = map.begin() ; d != map.end() ; map.next(d))
{
if(!polygons.isMarked(d))
{
bool canSimplify = true ;
while ( canSimplify && ((position[map.phi1(d)] - position[d]).norm() < minDist) )
{
if (map.vertexDegree(map.phi1(d)) == 2) {
map.uncutEdge(d) ;
}
else canSimplify = false ;
}
}
}
std::cout << "importSVG : Downsampling of vertices." << std::endl;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
//cut the edges to have a more regular sampling //cut the edges to have a more regular sampling
float maxDist = 40.0f ; float maxDist = 40.0f ;
...@@ -464,7 +417,26 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib ...@@ -464,7 +417,26 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
} }
} }
} }
std::cout << "importSVG : Refinement of long edges." << std::endl; std::cout << "importSVG : Subdivision of long edges." << std::endl;
/////////////////////////////////////////////////////////////////////////////////////////////
//simplify the edges to have a more regular sampling
float minDist = 30.0f ;
for (Dart d = map.begin() ; d != map.end() ; map.next(d))
{
if(!polygons.isMarked(d))
{
bool canSimplify = true ;
while ( canSimplify && ((position[map.phi1(d)] - position[d]).norm() < minDist) )
{
if (map.vertexDegree(map.phi1(d)) == 2) {
map.uncutEdge(d) ;
}
else canSimplify = false ;
}
}
}
std::cout << "importSVG : Downsampling of vertices." << std::endl;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
//process broken lines //process broken lines
......
...@@ -152,13 +152,21 @@ public: ...@@ -152,13 +152,21 @@ public:
*/ */
bool isNormalized(const T& epsilon) const ; 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 * Tests if current and given vectors are orthogonal
* @param V a vector * @param V a vector
* @param epsilon tolerated error * @param epsilon tolerated error
* @return true if orthogonal * @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 */ /* STREAM OPERATORS */
...@@ -174,6 +182,22 @@ private: ...@@ -174,6 +182,22 @@ private:
T m_data[DIM] ; 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> template <unsigned int DIM, typename T>
Vector<DIM, T> operator*(T a, const Vector<DIM, T>& v) ; Vector<DIM, T> operator*(T a, const Vector<DIM, T>& v) ;
......
...@@ -315,9 +315,23 @@ inline bool Vector<DIM, T>::isNormalized(const T& epsilon) const ...@@ -315,9 +315,23 @@ inline bool Vector<DIM, T>::isNormalized(const T& epsilon) const
} }
template <unsigned int DIM, typename T> 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) ; 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
{
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 +354,39 @@ std::istream& operator>>(std::istream& in, Vector<DIM, T>& v) ...@@ -340,6 +354,39 @@ std::istream& operator>>(std::istream& in, Vector<DIM, T>& v)
return in ; 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> template <unsigned int DIM, typename T>
inline Vector<DIM, T> operator*(T a, const Vector<DIM, T>& v) inline Vector<DIM, T> operator*(T a, const Vector<DIM, T>& v)
{ {
......
...@@ -40,7 +40,10 @@ public: ...@@ -40,7 +40,10 @@ public:
typedef Map2 TOPO_MAP; typedef Map2 TOPO_MAP;
/* /*
* */
virtual Dart newPolyLine(unsigned int nbEdges) ;
/*
*/ */
virtual Dart newFace(unsigned int nbEdges, bool withBoundary = true) ; virtual Dart newFace(unsigned int nbEdges, bool withBoundary = true) ;
......
...@@ -125,6 +125,12 @@ public: ...@@ -125,6 +125,12 @@ public:
*************************************************************************/ *************************************************************************/
//@{ //@{
//! Create an new polyline of nbEdges, i.e 2*nbEdges darts pairewise 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 //! Create an new face of nbEdges
/*! @param nbEdges the number of edges /*! @param nbEdges the number of edges
* @param withBoundary create the face and its boundary (default true) * @param withBoundary create the face and its boundary (default true)
......
...@@ -30,6 +30,37 @@ ...@@ -30,6 +30,37 @@
namespace CGoGN 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 EmbeddedMap2::newFace(unsigned int nbEdges, bool withBoundary)
{ {
Dart d = Map2::newFace(nbEdges, withBoundary); Dart d = Map2::newFace(nbEdges, withBoundary);
......
...@@ -107,6 +107,22 @@ void Map2::compactTopoRelations(const std::vector<unsigned int>& oldnew) ...@@ -107,6 +107,22 @@ void Map2::compactTopoRelations(const std::vector<unsigned int>& oldnew)
* To generate or delete faces in a 2-map * 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 Map2::newFace(unsigned int nbEdges, bool withBoundary)
{ {
Dart d = Map1::newCycle(nbEdges); Dart d = Map1::newCycle(nbEdges);
......
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