Commit 45129066 authored by Sylvain Thery's avatar Sylvain Thery

newFace et sewFaces avec parametre par defaut (withBoundary), utiliser false...

newFace et sewFaces avec parametre par defaut (withBoundary), utiliser false pour creer et coudre des faces avec points fixes
Map1::xxxFace devient xxxCycle
Ajout de la fonction bijectiveOrbitEmbedding
Utilisation dans importMesh pour eviter le partage d'embedding par les sommets topo
parent fc85be46
......@@ -447,7 +447,7 @@ void MyQT::cb_keyPress(int keycode)
ss << "dart:" << darts[0].index<<" /phi1:"<< d1.index<<" /phi2:"<< d2.index;
const PFP::VEC3& P = position[darts[0]];
ss << " /Emb:" << P;
ss << " /Emb:" << myMap.getEmbedding(VERTEX, darts[0])<< "/"<<P;
statusMsg(ss.str().c_str());
}
break;
......
......@@ -74,7 +74,7 @@ bool importMesh(typename PFP::MAP& map, MeshTablesSurface<PFP>& mts)
nbe = edgesBuffer.size();
if (nbe > 2)
{
Dart d = map.newOrientedFace(nbe);
Dart d = map.newFace(nbe,false);
for (unsigned int j = 0; j < nbe; ++j)
{
unsigned int em = edgesBuffer[j]; // get embedding
......@@ -97,7 +97,7 @@ bool importMesh(typename PFP::MAP& map, MeshTablesSurface<PFP>& mts)
std::vector<Dart>& vec = vecDartsPerVertex[map.phi1(d)];
unsigned int embd = map.getEmbedding(VERTEX, d);
Dart good_dart;
Dart good_dart=NIL;
for (typename std::vector<Dart>::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it)
{
if (map.getEmbedding(VERTEX, map.phi1(*it)) == embd)
......@@ -108,7 +108,7 @@ bool importMesh(typename PFP::MAP& map, MeshTablesSurface<PFP>& mts)
{
if (good_dart == map.phi2(good_dart))
{
map.sewOrientedFaces(d, good_dart);
map.sewFaces(d, good_dart,false);
m.unmarkOrbit(EDGE, d);
}
}
......@@ -124,6 +124,9 @@ bool importMesh(typename PFP::MAP& map, MeshTablesSurface<PFP>& mts)
{
map.closeMap();
CGoGNout << "Map closed (" << nbnm << " boundary edges)" << CGoGNendl;
// ensure bijection between topo a embedding
map.bijectiveOrbitEmbedding(VERTEX);
}
return true ;
......
This diff is collapsed.
......@@ -92,7 +92,8 @@ public:
m_position = map.template getAttribute<typename PFP::VEC3>(VERTEX,"position");
}
void trianguleFace( Dart d, DartMarker& mark);
// void trianguleFace( Dart d, DartMarker& mark);
void trianguleFace( Dart d);
void triangule(const FunctorSelect& good = allDarts, unsigned int thread=0);
......
......@@ -155,7 +155,9 @@ float EarTriangulation<PFP>::computeEarInit(Dart d, const typename PFP::VEC3& no
template<typename PFP>
void EarTriangulation<PFP>::trianguleFace(Dart d, DartMarker& mark)
//void EarTriangulation<PFP>::trianguleFace(Dart d, DartMarker& mark)
void EarTriangulation<PFP>::trianguleFace(Dart d)
{
// compute normal to polygon
typename PFP::VEC3 normalPoly = Algo::Geometry::newellNormal<PFP>(m_map, d, m_position);
......@@ -167,7 +169,7 @@ void EarTriangulation<PFP>::trianguleFace(Dart d, DartMarker& mark)
if (m_map.template phi<111>(d) ==d)
{
mark.markOrbit(FACE, d); // mark the face
// mark.markOrbit(FACE, d); // mark the face
return;
}
......@@ -196,7 +198,7 @@ void EarTriangulation<PFP>::trianguleFace(Dart d, DartMarker& mark)
Dart e2 = m_map.phi_1(d_e);
m_map.splitFace(e1,e2);
mark.markOrbit(FACE, d_e);
// mark.markOrbit(FACE, d_e);
nbv--;
if (nbv>3) // do not recompute if only one triangle left
......@@ -211,8 +213,8 @@ void EarTriangulation<PFP>::trianguleFace(Dart d, DartMarker& mark)
convex = (m_ears.rbegin()->angle) < 5.0f;
}
else
mark.markOrbit(FACE, e1); // mark last face
// else
// mark.markOrbit(FACE, e1); // mark last face
}
m_ears.clear();
......@@ -222,18 +224,27 @@ void EarTriangulation<PFP>::trianguleFace(Dart d, DartMarker& mark)
template<typename PFP>
void EarTriangulation<PFP>::triangule( const FunctorSelect& good, unsigned int thread)
{
DartMarker m(m_map, thread);
for(Dart d = m_map.begin(); d != m_map.end(); m_map.next(d))
// DartMarker m(m_map, thread);
//
// for(Dart d = m_map.begin(); d != m_map.end(); m_map.next(d))
// {
// if(!m.isMarked(d) && good(d))
// {
// Dart e = m_map.template phi<111>(d);
// if (e!=d)
// trianguleFace(d, m);
// }
// }
// m.unmarkAll();
TraversorF<typename PFP::MAP> trav(m_map,good,thread);
for(Dart d = trav.begin(); d != trav.end(); d = trav.next())
{
if(!m.isMarked(d) && good(d))
{
Dart e = m_map.template phi<111>(d);
if (e!=d)
trianguleFace(d, m);
}
Dart e = m_map.template phi<111>(d);
if (e!=d)
trianguleFace(d);
}
m.unmarkAll();
}
......
#ifndef __OPTIMIZED_MAP_
#define __OPTIMIZED_MAP_
#include "Topology/generic/functor.h"
namespace CGoGN
{
namespace Algo
{
namespace Optimiz
{
#define OPT_MAX_THREAD 8
template <typename MAP>
class OptimizedMap2
{
typedef typename MAP::Dart Dart;
protected:
Dart m_firstVertex[OPT_MAX_THREAD];
int m_nbVertices;
Dart m_firstFace[OPT_MAX_THREAD];
Dart m_endMap;
Dart m_beginMap;
int m_nbFaces;
public:
OptimizedMap2():m_nbVertices(0),m_nbFaces(0) {}
void OptimizedForFaces(MAP& the_map);
void OptimizedForVertices(MAP& the_map);
void OptimizedBoth(MAP& the_map);
void foreachFace(FunctorType& funct);
void foreachVertex(FunctorType& funct);
void prepareForMT(MAP& the_map);
void foreachFaceMT2(FunctorType& funct);
void foreachFaceMT4(FunctorType& funct);
void foreachFaceMT8(FunctorType& funct);
void foreachFaceMT2multi(FunctorType& funct1, FunctorType& funct2);
void foreachFaceMT4multi( FunctorType& funct1,FunctorType& funct2, FunctorType& funct3, FunctorType& funct4);
};
template<typename MAP>
void OptimizedMap2<MAP>::prepareForMT(MAP& the_map)
{
int nbfbt = m_nbFaces/OPT_MAX_THREAD;
if (m_nbFaces>0)
{
for (int i=1; i<OPT_MAX_THREAD; ++i)
{
Dart& d = m_firstFace[i];
d = m_firstFace[i-1];
for (int i=0;i<nbfbt; ++i)
{
d++;
}
}
}
if (m_nbVertices>0)
{
for (int i=1; i<OPT_MAX_THREAD; ++i)
{
Dart& d = m_firstVertex[i];
d = m_firstVertex[i-1];
for (int i=0;i<nbfbt; ++i)
{
d++;
}
}
}
}
template<typename MAP>
void OptimizedMap2<MAP>::OptimizedForFaces(MAP& the_map)
{
m_endMap = the_map.end();
m_beginMap = the_map.begin();
m_nbVertices=0;
m_nbFaces=0;
Marker mf = the_map.getNewMarker();
for (Dart d =the_map.begin(); d != the_map.end(); /* ++ inside */)
{
if (!the_map.isMarkedDart(d,mf))
{
the_map.markOrbit(2,d,mf);
Dart dd = d;
the_map.next(d) ;
the_map.splice(the_map.begin(), the_map, dd);
m_nbFaces++;
}
else
the_map.next(d) ;
}
m_firstVertex[0] = the_map.end();
m_firstFace[0] = the_map.begin();
the_map.unmarkAll(mf);
the_map.releaseMarker(mf);
}
template<typename MAP>
void OptimizedMap2<MAP>::OptimizedForVertices(MAP& the_map)
{
m_endMap = the_map.end();
m_beginMap = the_map.begin();
m_nbFaces=0;
m_nbVertices=0;
Marker mv = the_map.getNewMarker();
for (Dart d =the_map.begin(); d != the_map.end(); /* ++ inside */)
{
if (!the_map.isMarkedDart(d,mv))
{
the_map.markOrbit(0,d,mv);
Dart dd = d;
the_map.next(d) ;
the_map.splice(the_map.begin(), the_map, dd);
m_nbVertices++;
}
else
the_map.next(d) ;
}
m_firstVertex[0] = the_map.begin();
m_firstFace[0] = the_map.end();
the_map.unmarkAll(mv);
the_map.releaseMarker(mv);
}
template<typename MAP>
void OptimizedMap2<MAP>::OptimizedBoth(MAP& the_map)
{
m_endMap = the_map.end();
m_beginMap = the_map.begin();
// dart just afer faces only
Dart X = the_map.newDart();
// dart just afer faces & vertices
Dart Y= the_map.newDart();
// dart just afer vertices only
Dart Z= the_map.newDart();
the_map.splice(the_map.begin(), the_map, Z);
the_map.splice(the_map.begin(), the_map, Y);
the_map.splice(the_map.begin(), the_map, X);
// ...faces ...X .... faces & vertices .... Y vertices .... Z ... others
m_nbFaces=0;
m_nbVertices=0;
// put one dart per face before X
Marker mf = the_map.getNewMarker();
Dart d = Z; d++;
while ( d != the_map.end())
{
if (!the_map.isMarkedDart(d,mf))
{
the_map.markOrbit(2,d,mf);
Dart dd = d;
the_map.next(d) ;
the_map.splice(X, the_map, dd);
m_nbFaces++;
}
else
the_map.next(d) ;
}
// put one dart per vertex before Z
Marker mv = the_map.getNewMarker();
d = Z; d++;
while ( d != the_map.end())
{
if (!the_map.isMarkedDart(d,mv))
{
the_map.markOrbit(0,d,mv);
Dart dd = d;
the_map.next(d) ;
the_map.splice(Z, the_map, dd);
m_nbVertices++;
}
else
the_map.next(d) ;
}
CGoGNout << "Dart vert before "<< m_nbVertices<<CGoGNendl;
// move dart of faces that are not maked before Y
d = the_map.begin() ;
while ( d != X)
{
if (!the_map.isMarkedDart(d,mv))
{
the_map.markOrbit(0,d,mv);
Dart dd = d;
the_map.next(d) ;
the_map.splice(Y, the_map, dd);
m_nbVertices++;
}
else
the_map.next(d) ;
}
CGoGNout << "Dart vert "<< m_nbVertices<<CGoGNendl;
m_firstFace[0] = the_map.begin();
d = X;
the_map.next(d) ;
m_firstVertex[0] = d;
the_map.erase(X);
the_map.erase(Y);
the_map.erase(Z);
the_map.unmarkAll(mf+mv);
the_map.releaseMarker(mv);
the_map.releaseMarker(mf);
}
template<typename MAP>
void OptimizedMap2<MAP>::foreachFace(FunctorType& funct)
{
Dart d = m_firstFace[0];
for (int i=0; i<m_nbFaces; ++i)
{
if (funct(d)) return;
d++;
}
}
template<typename MAP>
void OptimizedMap2<MAP>::foreachVertex(FunctorType& funct)
{
Dart d = m_firstVertex[0];
for (int i=0; i<m_nbVertices; ++i)
{
if (funct(d)) return;
d++;
}
}
template<typename MAP>
class ThreadFunctor
{
typedef typename MAP::Dart Dart;
protected:
Dart m_first;
int m_nb;
FunctorType& m_func;
public:
ThreadFunctor(Dart d, int n, FunctorType& f):
m_first(d), m_nb(n), m_func(f) {}
void operator()()
{
Dart d = m_first;
for (int i=m_nb; i>0; --i)
{
if (m_func(d)) return;
d++;
}
}
};
template<typename MAP>
void OptimizedMap2<MAP>::foreachFaceMT2( FunctorType& funct)
{
int n = m_nbFaces/2;
boost::thread th1( ThreadFunctor<MAP>(m_firstFace[0],n,funct) );
n = n + m_nbFaces%2;
boost::thread th2( ThreadFunctor<MAP>(m_firstFace[4],n,funct) );
th1.join();
th2.join();
}
template<typename MAP>
void OptimizedMap2<MAP>::foreachFaceMT4( FunctorType& funct)
{
int n = m_nbFaces/4;
boost::thread th1( ThreadFunctor<MAP>(m_firstFace[0],n,funct) );
boost::thread th2( ThreadFunctor<MAP>(m_firstFace[2],n,funct) );
boost::thread th3( ThreadFunctor<MAP>(m_firstFace[4],n,funct) );
n = n + m_nbFaces%4;
boost::thread th4( ThreadFunctor<MAP>(m_firstFace[6],n,funct) );
th1.join();
th2.join();
th3.join();
th4.join();
}
template<typename MAP>
void OptimizedMap2<MAP>::foreachFaceMT8( FunctorType& funct)
{
int n = m_nbFaces/8;
boost::thread th1( ThreadFunctor<MAP>(m_firstFace[0],n,funct) );
boost::thread th2( ThreadFunctor<MAP>(m_firstFace[1],n,funct) );
boost::thread th3( ThreadFunctor<MAP>(m_firstFace[2],n,funct) );
boost::thread th4( ThreadFunctor<MAP>(m_firstFace[3],n,funct) );
boost::thread th5( ThreadFunctor<MAP>(m_firstFace[4],n,funct) );
boost::thread th6( ThreadFunctor<MAP>(m_firstFace[5],n,funct) );
boost::thread th7( ThreadFunctor<MAP>(m_firstFace[6],n,funct) );
n = n + m_nbFaces%8;
boost::thread th8( ThreadFunctor<MAP>(m_firstFace[7],n,funct) );
th1.join();
th2.join();
th3.join();
th4.join();
th5.join();
th6.join();
th7.join();
th8.join();
}
template<typename MAP>
void OptimizedMap2<MAP>::foreachFaceMT2multi( FunctorType& funct1,FunctorType& funct2)
{
int n = m_nbFaces/2;
boost::thread th1( ThreadFunctor<MAP>(m_firstFace[0],n,funct1) );
n = n + m_nbFaces%2;
boost::thread th2( ThreadFunctor<MAP>(m_firstFace[4],n,funct2) );
th1.join();
th2.join();
}
template<typename MAP>
void OptimizedMap2<MAP>::foreachFaceMT4multi( FunctorType& funct1,FunctorType& funct2, FunctorType& funct3, FunctorType& funct4)
{
int n = m_nbFaces/4;
boost::thread th1( ThreadFunctor<MAP>(m_firstFace[0],n,funct1) );
boost::thread th2( ThreadFunctor<MAP>(m_firstFace[2],n,funct2) );
boost::thread th3( ThreadFunctor<MAP>(m_firstFace[4],n,funct3) );
n = n + m_nbFaces%4;
boost::thread th4( ThreadFunctor<MAP>(m_firstFace[6],n,funct4) );
th1.join();
th2.join();
th3.join();
th4.join();
}
}//endnamespace
}//endnamespace
}//endnamespace
#endif
......@@ -350,7 +350,7 @@ void MapRender::initTrianglesOptimized(typename PFP::MAP& map, const FunctorSele
{
if (!m.isMarked(f))
{
if (good(f) && !map.isBoundaryMarked(dd))
if (good(f) && !map.isBoundaryMarked(f))
addTri<PFP>(map, f, tableIndices);
m.markOrbit(FACE, f);
bound.push_back(map.phi1(f));
......
......@@ -104,6 +104,12 @@ public:
* @return the number of cells of the orbit
*/
unsigned int computeIndexCells(AttributeHandler<unsigned int>& idx) ;
/**
* ensure that each orbit as one embedding and that each embedding is handle by only one orbit
*/
void bijectiveOrbitEmbedding(unsigned int orbit);
} ;
} // namespace CGoGN
......
......@@ -168,7 +168,7 @@ public:
/**
* initialize all the lines of the attribute with the given value
*/
void setAllValues(T& v) ;
void setAllValues(const T& v) ;
/**
* begin of table
......
......@@ -171,7 +171,7 @@ inline unsigned int AttributeHandler<T>::newElt()
}
template <typename T>
inline void AttributeHandler<T>::setAllValues(T& v)
inline void AttributeHandler<T>::setAllValues(const T& v)
{
for(unsigned int i = begin(); i != end(); next(i))
m_attrib->operator[](i) = v ;
......
......@@ -107,7 +107,7 @@ public:
* 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
*/
virtual void sewFaces(Dart d, Dart e) ;
virtual void sewFaces(Dart d, Dart e, bool withBoundary=true) ;
/**
* The attributes attached to the vertices of the old edge of d are duplicated on the vertices of both resulting edges
......@@ -140,7 +140,7 @@ public:
/**
* No attribute is attached to the new face
*/
virtual unsigned int closeHole(Dart d);
virtual unsigned int closeHole(Dart d, bool withBoundary=true);
virtual bool check() ;
} ;
......
......@@ -89,9 +89,10 @@ public:
/**
* create a face
* @param n the number of sides of face
* @param withBoundary not used, for compatibility with Map
* @return a dart of the edge
*/
Dart newFace(unsigned int n);
Dart newFace(unsigned int n, bool withBoundary=true);
//! Delete a face erasing all its darts
/*! @param d a dart of the face
......
......@@ -167,8 +167,9 @@ public:
/*! \pre Darts d & e MUST be fixed point of phi2 relation
* @param d a dart of the first face
* @param e a dart of the second face
* @param withBoundary not used only for compatibility with Map
*/
virtual void sewFaces(Dart d, Dart e);
virtual void sewFaces(Dart d, Dart e, bool withBoundary=true);
//! Unsew two faces along an edges
/*! @param d a dart of one face
......
......@@ -107,7 +107,7 @@ public:
* 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