Commit 015335b1 authored by Sylvain Thery's avatar Sylvain Thery

specialized/optimized version of Traversor & foreach_cell

parent 70470eec
......@@ -371,19 +371,87 @@ void Viewer::cb_keyPress(int keycode)
case'A':
{
myMap.disableQuickTraversal<VERTEX>() ;
#define NBLOOP 5
Utils::Chrono ch;
ch.start();
{
TraversorCell<MAP, VERTEX,FORCE_CELL_MARKING> trav(myMap,true);
for(unsigned int i=0; i<NBLOOP; ++i)
{
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
{
normal[v][0] = 0.0f;
}
}
std::cout << "FORCE_CELL_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
}
TraversorCell<MAP, VERTEX> trav(myMap,true);
for(unsigned int i=0; i<10; ++i)
ch.start();
{
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
TraversorCell<MAP, VERTEX> trav(myMap);
for(unsigned int i=0; i<NBLOOP; ++i)
{
// normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap, v, position) ;
normal[v][0] = 0.0f;
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
{
normal[v][0] = 0.0f;
}
}
std::cout << "auto "<< ch.elapsed()<< " ms "<< std::endl;
}
std::cout << "Timing 10 traversors "<< ch.elapsed()<< " ms "<< std::endl;
ch.start();
{
TraversorCell<MAP, VERTEX> trav(myMap,true);
for(unsigned int i=0; i<NBLOOP; ++i)
{
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
{
normal[v][0] = 0.0f;
}
}
std::cout << "auto forcedart "<< ch.elapsed()<< " ms "<< std::endl;
}
ch.start();
{
TraversorCell<MAP, VERTEX,FORCE_DART_MARKING> trav(myMap,true);
for(unsigned int i=0; i<NBLOOP; ++i)
{
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
{
normal[v][0] = 0.0f;
}
}
std::cout << "FORCE_DART_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
}
myMap.enableQuickTraversal<VERTEX>() ;
ch.start();
{
TraversorCell<MAP, VERTEX> trav(myMap);
for(unsigned int i=0; i<NBLOOP; ++i)
{
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
{
normal[v][0] = 0.0f;
}
}
std::cout << "auto (quick) "<< ch.elapsed()<< " ms "<< std::endl;
}
ch.start();
{
TraversorCell<MAP, VERTEX,FORCE_QUICK_TRAVERSAL> trav(myMap);
for(unsigned int i=0; i<NBLOOP; ++i)
{
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
{
normal[v][0] = 0.0f;
}
}
std::cout << "FORCE_QUICK_TRAVERSAL "<< ch.elapsed()<< " ms "<< std::endl;
}
}
break;
......@@ -400,12 +468,10 @@ void Viewer::cb_keyPress(int keycode)
{
for (Cell<VERTEX> v = tr1.begin(), e = tr1.end(); v.dart != e.dart; v = tr1.next())
{
// normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap, v, position) ;
normal[v][0] = 0.0f;
}
for (Cell<VERTEX> v = tr2.begin(), e = tr2.end(); v.dart != e.dart; v = tr2.next())
{
// normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap, v, position) ;
normal[v][0] = 0.0f;
}
}
......
......@@ -152,7 +152,7 @@ void computeAreaFaces(typename PFP::MAP& map, const VertexAttribute<typename PFP
{
face_area[f] = convexFaceArea<PFP>(map, f, position) ;
}
,false,thread);
,AUTO,thread);
}
......@@ -170,7 +170,7 @@ void computeOneRingAreaVertices(typename PFP::MAP& map, const VertexAttribute<ty
vertex_area[v] += areas[f];
});
}
,false,thread);
,FORCE_CELL_MARKING,thread);
}
......@@ -182,7 +182,7 @@ void computeBarycentricAreaVertices(typename PFP::MAP& map, const VertexAttribut
{
vertex_area[v] = vertexBarycentricArea<PFP>(map, v, position) ;
}
,false,thread);
,FORCE_CELL_MARKING,thread);
}
template <typename PFP>
......@@ -193,7 +193,7 @@ void computeVoronoiAreaVertices(typename PFP::MAP& map, const VertexAttribute<ty
{
vertex_area[v] = vertexVoronoiArea<PFP>(map, v, position) ;
}
,false,thread);
,FORCE_CELL_MARKING,thread);
}
......
......@@ -142,7 +142,7 @@ void computeCentroidFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT&
{
face_centroid[f] = faceCentroid<PFP,V_ATT>(map, f, position) ;
}
,false,thread);
,AUTO,thread);
}
template <typename PFP, typename V_ATT, typename F_ATT>
......@@ -152,7 +152,7 @@ void computeCentroidELWFaces(typename PFP::MAP& map, const V_ATT& position, F_AT
{
face_centroid[f] = faceCentroidELW<PFP,V_ATT>(map, f, position) ;
}
,false,thread);
,AUTO,thread);
}
template <typename PFP, typename V_ATT>
......@@ -162,7 +162,7 @@ void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& po
{
vertex_centroid[v] = vertexNeighborhoodCentroid<PFP,V_ATT>(map, v, position) ;
}
,false,thread);
,AUTO,thread);
}
......@@ -287,7 +287,7 @@ void computeCentroidVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT
{
vol_centroid[v] = Surface::Geometry::volumeCentroid<PFP,V_ATT>(map, v, position,thread) ;
}
,false,thread);
,AUTO,thread);
}
template <typename PFP, typename V_ATT, typename W_ATT>
......@@ -300,7 +300,7 @@ void computeCentroidELWVolumes(typename PFP::MAP& map, const V_ATT& position, W_
{
vol_centroid[v] = Surface::Geometry::volumeCentroidELW<PFP,V_ATT>(map, v, position,thread) ;
}
,false,thread);
,AUTO,thread);
}
template <typename PFP, typename V_ATT>
......@@ -313,7 +313,7 @@ void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& po
{
vertex_centroid[v] = Volume::Geometry::vertexNeighborhoodCentroid<PFP,V_ATT>(map, v, position) ;
}
,false,thread);
,AUTO,thread);
}
......
......@@ -159,7 +159,7 @@ void computeNormalVertices(typename PFP::MAP& map, const V_ATT& position, V_ATT&
{
normal[v] = vertexNormal<PFP>(map, v, position) ;
},
false, thread);
FORCE_CELL_MARKING, thread);
}
......
......@@ -311,7 +311,7 @@ void MapRender::initTriangles(typename PFP::MAP& map, std::vector<GLuint>& table
foreach_cell<FACE>(map, [&] (Face f)
{
addTri<PFP>(map, f, tableIndices);
}, false, thread);
}, AUTO, thread);
}
else
{
......@@ -321,7 +321,7 @@ void MapRender::initTriangles(typename PFP::MAP& map, std::vector<GLuint>& table
addTri<PFP>(map, f, tableIndices);
else
addEarTri<PFP>(map, f, tableIndices, position);
}, false, thread);
}, AUTO, thread);
}
}
......@@ -412,7 +412,7 @@ void MapRender::initLines(typename PFP::MAP& map, std::vector<GLuint>& tableIndi
tableIndices.push_back(map.template getEmbedding<VERTEX>(e.dart));
tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(e)));
}
,false,thread);
,AUTO,thread);
}
template<typename PFP>
......@@ -430,7 +430,7 @@ void MapRender::initBoundaries(typename PFP::MAP& map, std::vector<GLuint>& tabl
tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(e)));
}
}
,false,thread);
,AUTO,thread);
}
template<typename PFP>
......@@ -490,7 +490,7 @@ void MapRender::initPoints(typename PFP::MAP& map, std::vector<GLuint>& tableInd
{
tableIndices.push_back(map.getEmbedding(v));
}
,false,thread);
,FORCE_CELL_MARKING,thread); //
}
template<typename PFP>
......
......@@ -41,7 +41,7 @@ template <unsigned int ORBIT, typename MAP>
unsigned int getNbOrbits(const MAP& map)
{
unsigned int cpt = 0;
foreach_cell<ORBIT>(map, [&] (Cell<ORBIT>) { ++cpt; }, true);
foreach_cell<ORBIT>(map, [&] (Cell<ORBIT>) { ++cpt; }, FORCE_DART_MARKING);
return cpt;
}
......@@ -122,7 +122,7 @@ void bijectiveOrbitEmbedding(MAP& map)
counter[d]++ ;
}
},
true);
FORCE_DART_MARKING);
map.removeAttribute(counter) ;
}
......
......@@ -35,9 +35,18 @@
namespace CGoGN
{
/**
* Travsersor class
* template params:
* - MAP type of map
* - ORBIT orbit of the cell
* - OPT type of optimization
*/
enum TraversalOptim {AUTO=0, FORCE_DART_MARKING, FORCE_CELL_MARKING, FORCE_QUICK_TRAVERSAL};
template <typename MAP, unsigned int ORBIT>
class TraversorCell //: public Traversor<MAP>
template <typename MAP, unsigned int ORBIT, TraversalOptim OPT=AUTO>
class TraversorCell
{
protected:
const MAP& m ;
......@@ -54,7 +63,7 @@ protected:
bool firstTraversal ;
// just for odd/even versions
TraversorCell(const TraversorCell<MAP, ORBIT>& tc);
TraversorCell(const TraversorCell<MAP, ORBIT,OPT>& tc);
public:
TraversorCell(const MAP& map, bool forceDartMarker = false, unsigned int thread = 0) ;
......@@ -75,23 +84,23 @@ public:
template <typename MAP, unsigned int ORBIT>
class TraversorCellEven : public TraversorCell<MAP,ORBIT>
template <typename MAP, unsigned int ORBIT, TraversalOptim OPT=AUTO>
class TraversorCellEven : public TraversorCell<MAP,ORBIT,OPT>
{
public:
TraversorCellEven(const TraversorCell<MAP,ORBIT>& tra):
TraversorCell<MAP,ORBIT>(tra) {}
TraversorCellEven(const TraversorCell<MAP,ORBIT,OPT>& tra):
TraversorCell<MAP,ORBIT,OPT>(tra) {}
~TraversorCellEven() { this->cmark = NULL; this->dmark=NULL; }
inline Cell<ORBIT> begin() ;
} ;
template <typename MAP, unsigned int ORBIT>
class TraversorCellOdd : public TraversorCell<MAP,ORBIT>
template <typename MAP, unsigned int ORBIT, TraversalOptim OPT=AUTO>
class TraversorCellOdd : public TraversorCell<MAP,ORBIT,OPT>
{
public:
TraversorCellOdd(const TraversorCell<MAP,ORBIT>& tra):
TraversorCell<MAP,ORBIT>(tra) {}
TraversorCellOdd(const TraversorCell<MAP,ORBIT,OPT>& tra):
TraversorCell<MAP,ORBIT,OPT>(tra) {}
~TraversorCellOdd() {this->cmark = NULL; this->dmark=NULL; }
inline Cell<ORBIT> begin() ;
inline Cell<ORBIT> next() ;
......@@ -105,41 +114,175 @@ public:
/*
* Executes function f on each ORBIT
*/
//template <unsigned int ORBIT, typename MAP, typename FUNC>
//inline void foreach_cell(const MAP& map, FUNC f, bool forceDartMarker = false, unsigned int thread = 0)
//{
// TraversorCell<MAP, ORBIT> trav(map, forceDartMarker, thread);
// for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
// f(c);
//}
template <unsigned int ORBIT, typename MAP, typename FUNC>
inline void foreach_cell(const MAP& map, FUNC f, bool forceDartMarker = false, unsigned int thread = 0)
inline void foreach_cell(const MAP& map, FUNC f, TraversalOptim opt = AUTO, unsigned int thread = 0)
{
TraversorCell<MAP, ORBIT> trav(map, forceDartMarker, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
switch(opt)
{
case FORCE_DART_MARKING:
{
TraversorCell<MAP, ORBIT,FORCE_DART_MARKING> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
}
break;
case FORCE_CELL_MARKING:
{
TraversorCell<MAP, ORBIT,FORCE_CELL_MARKING> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
}
break;
case FORCE_QUICK_TRAVERSAL:
{
TraversorCell<MAP, ORBIT,FORCE_QUICK_TRAVERSAL> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
}
break;
case AUTO:
default:
{
TraversorCell<MAP, ORBIT,AUTO> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
}
break;
}
}
/*
* Executes function f on each ORBIT until f returns false
*/
//template <unsigned int ORBIT, typename MAP, typename FUNC>
//inline void foreach_cell_until(const MAP& map, FUNC f, bool forceDartMarker = false, unsigned int thread = 0)
//{
// TraversorCell<MAP, ORBIT> trav(map, forceDartMarker, thread);
// for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
// if (!f(c))
// break;
//}
template <unsigned int ORBIT, typename MAP, typename FUNC>
inline void foreach_cell_until(const MAP& map, FUNC f, bool forceDartMarker = false, unsigned int thread = 0)
inline void foreach_cell_until(const MAP& map, FUNC f, TraversalOptim opt = AUTO, unsigned int thread = 0)
{
TraversorCell<MAP, ORBIT> trav(map, forceDartMarker, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
if (!f(c))
break;
switch(opt)
{
case FORCE_DART_MARKING:
{
TraversorCell<MAP, ORBIT,FORCE_DART_MARKING> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
if (!f(c))
break;
}
break;
case FORCE_CELL_MARKING:
{
TraversorCell<MAP, ORBIT,FORCE_CELL_MARKING> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
if (!f(c))
break;
}
break;
case FORCE_QUICK_TRAVERSAL:
{
TraversorCell<MAP, ORBIT,FORCE_QUICK_TRAVERSAL> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
if (!f(c))
break;
}
break;
case AUTO:
default:
{
TraversorCell<MAP, ORBIT,AUTO> trav(map, false, thread);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
if (!f(c))
break;
}
break;
}
}
template <unsigned int ORBIT, typename MAP, typename FUNC, typename FUNC2>
inline void foreach_cell_EvenOddd(const MAP& map, FUNC f, FUNC2 g, unsigned int nbpasses=1, bool forceDartMarker = false, unsigned int thread = 0)
inline void foreach_cell_EvenOddd(const MAP& map, FUNC f, FUNC2 g, unsigned int nbpasses=1, TraversalOptim opt = AUTO, unsigned int thread = 0)
{
TraversorCell<MAP, ORBIT> trav(map, forceDartMarker, thread);
TraversorCellEven<MAP, VERTEX> tr1(trav);
TraversorCellOdd<MAP, VERTEX> tr2(trav);
for (unsigned int i=0; i<nbpasses; ++i)
switch(opt)
{
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
g(c);
case FORCE_DART_MARKING:
{
TraversorCell<MAP,ORBIT,FORCE_DART_MARKING> trav(map, false, thread);
TraversorCellEven<MAP,ORBIT,FORCE_DART_MARKING> tr1(trav);
TraversorCellOdd<MAP,ORBIT,FORCE_DART_MARKING> tr2(trav);
for (unsigned int i=0; i<nbpasses; ++i)
{
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
g(c);
}
}
break;
case FORCE_CELL_MARKING:
{
TraversorCell<MAP,ORBIT,FORCE_CELL_MARKING> trav(map, false, thread);
TraversorCellEven<MAP,ORBIT,FORCE_CELL_MARKING> tr1(trav);
TraversorCellOdd<MAP,ORBIT, FORCE_CELL_MARKING> tr2(trav);
for (unsigned int i=0; i<nbpasses; ++i)
{
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
g(c);
}
}
break;
case FORCE_QUICK_TRAVERSAL:
{
TraversorCell<MAP,ORBIT,FORCE_QUICK_TRAVERSAL> trav(map, false, thread);
TraversorCellEven<MAP,ORBIT,FORCE_QUICK_TRAVERSAL> tr1(trav);
TraversorCellOdd<MAP,ORBIT,FORCE_QUICK_TRAVERSAL> tr2(trav);
for (unsigned int i=0; i<nbpasses; ++i)
{
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
g(c);
}
}
break;
case AUTO:
default:
{
TraversorCell<MAP,ORBIT,AUTO> trav(map, false, thread);
TraversorCellEven<MAP,ORBIT,AUTO> tr1(trav);
TraversorCellOdd<MAP,ORBIT,AUTO> tr2(trav);
for (unsigned int i=0; i<nbpasses; ++i)
{
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
f(c);
for (Cell<ORBIT> c = trav.begin(), e = trav.end(); c.dart != e.dart; c = trav.next())
g(c);
}
}
break;
}
}
......
......@@ -28,42 +28,52 @@
namespace CGoGN
{
template <typename MAP, unsigned int ORBIT>
TraversorCell<MAP, ORBIT>::TraversorCell(const MAP& map, bool forceDartMarker, unsigned int thread) :
template <typename MAP, unsigned int ORBIT, TraversalOptim OPT>
TraversorCell<MAP, ORBIT,OPT>::TraversorCell(const MAP& map, bool forceDartMarker, unsigned int thread) :
m(map), dmark(NULL), cmark(NULL), quickTraversal(NULL), current(NIL), firstTraversal(true)
{
dimension = map.dimension();
if(forceDartMarker)
dmark = new DartMarker<MAP>(map, thread) ;
else
switch(OPT)
{
case FORCE_DART_MARKING:
dmark = new DartMarker<MAP>(map, thread) ;
break;
case FORCE_CELL_MARKING:
cmark = new CellMarker<MAP, ORBIT>(map, thread) ;
break;
case FORCE_QUICK_TRAVERSAL:
quickTraversal = map.template getQuickTraversal<ORBIT>() ;
if(quickTraversal != NULL)
{
cont = &(map.template getAttributeContainer<ORBIT>()) ;
}
assert(quickTraversal != NULL);
cont = &(map.template getAttributeContainer<ORBIT>()) ;
break;
case AUTO:
if(forceDartMarker)
dmark = new DartMarker<MAP>(map, thread) ;
else
{
if(map.template isOrbitEmbedded<ORBIT>())
cmark = new CellMarker<MAP, ORBIT>(map, thread) ;
quickTraversal = map.template getQuickTraversal<ORBIT>() ;
if(quickTraversal != NULL)
{
cont = &(map.template getAttributeContainer<ORBIT>()) ;
}
else
dmark = new DartMarker<MAP>(map, thread) ;
{
if(map.template isOrbitEmbedded<ORBIT>())
cmark = new CellMarker<MAP, ORBIT>(map, thread) ;
else
dmark = new DartMarker<MAP>(map, thread) ;
}
}
default:
break;
}
}
template <typename MAP, unsigned int ORBIT>
unsigned int TraversorCell<MAP, ORBIT>::nbCells()
{
return m.template getAttributeContainer<ORBIT>().size();
}
template <typename MAP, unsigned int ORBIT>
TraversorCell<MAP, ORBIT>::TraversorCell(const TraversorCell<MAP, ORBIT>& tc) :
template <typename MAP, unsigned int ORBIT, TraversalOptim OPT>
TraversorCell<MAP, ORBIT,OPT>::TraversorCell(const TraversorCell<MAP, ORBIT,OPT>& tc) :
m(tc.m), dmark(tc.dmark), cmark(tc.cmark),
quickTraversal(tc.quickTraversal), current(tc.current), firstTraversal(tc.firstTraversal),
dimension(tc.dimension)
......@@ -73,32 +83,52 @@ TraversorCell<MAP, ORBIT>::TraversorCell(const TraversorCell<MAP, ORBIT>& tc) :
template <typename MAP, unsigned int ORBIT>
TraversorCell<MAP, ORBIT>::~TraversorCell()
template <typename MAP, unsigned int ORBIT, TraversalOptim OPT>
TraversorCell<MAP, ORBIT,OPT>::~TraversorCell()
{
if(dmark)
switch(OPT)
{
case FORCE_DART_MARKING:
delete dmark ;
else if(cmark)
break;