Commit 20067814 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge branch 'develop' of cgogn:~thery/CGoGNMR into develop

parents 7c7c8ab3 1083e150
...@@ -241,7 +241,7 @@ void Viewer::cb_keyPress(int keycode) ...@@ -241,7 +241,7 @@ void Viewer::cb_keyPress(int keycode)
if(!pos2.isValid()) if(!pos2.isValid())
pos2 = myMap.addAttribute<VEC3, VERTEX>("pos2") ; pos2 = myMap.addAttribute<VEC3, VERTEX>("pos2") ;
for (int i=0; i< 10; ++i) for (int i=0; i< 6; ++i)
{ {
foreach_cell<VERTEX>(myMap, [&] (Vertex d) foreach_cell<VERTEX>(myMap, [&] (Vertex d)
{ {
...@@ -263,7 +263,46 @@ void Viewer::cb_keyPress(int keycode) ...@@ -263,7 +263,46 @@ void Viewer::cb_keyPress(int keycode)
updateGL(); updateGL();
} }
break; break;
case 'B':
{
Utils::Chrono ch;
ch.start();
VertexAttribute<VEC3,MAP_IMPL> pos2 = myMap.getAttribute<VEC3, VERTEX>("pos2") ;
if(!pos2.isValid())
pos2 = myMap.addAttribute<VEC3, VERTEX>("pos2") ;
foreach_cell_EvenOddd<VERTEX>(myMap, [&] (Vertex d)
{
pos2[d] = VEC3(0,0,0);
int nb=0;
foreach_adjacent2<FACE>(myMap,d,[&](Vertex e)
{
pos2[d] += position[e];
nb++;
});
pos2[d]/=nb;
},
[&] (Vertex d)
{
position[d] = VEC3(0,0,0);
int nb=0;
foreach_adjacent2<FACE>(myMap,d,[&](Vertex e)
{
position[d] += pos2[e];
nb++;
});
position[d]/=nb;
},
3);
std::cout << "Even/Odd "<< ch.elapsed()<< " ms "<< std::endl;
Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
m_positionVBO->updateData(position) ;
m_normalVBO->updateData(normal) ;
updateGL();
}
break;
case 'e': case 'e':
{ {
...@@ -330,6 +369,49 @@ void Viewer::cb_keyPress(int keycode) ...@@ -330,6 +369,49 @@ void Viewer::cb_keyPress(int keycode)
} }
break; break;
case'A':
{
Utils::Chrono ch;
ch.start();
TraversorCell<MAP, VERTEX> trav(myMap,true);
for(unsigned int i=0; i<10; ++i)
{
for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
{
// normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap, v, position) ;
normal[v][0] = 0.0f;
}
}
std::cout << "Timing 10 traversors "<< ch.elapsed()<< " ms "<< std::endl;
}
break;
case'Z':
{
Utils::Chrono ch;
ch.start();
TraversorCell<MAP, VERTEX> trav(myMap,true);
TraversorCellEven<MAP, VERTEX> tr1(trav);
TraversorCellOdd<MAP, VERTEX> tr2(trav);
for(unsigned int i=0; i<5; ++i)
{
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;
}
}
std::cout << "Timing 5 traversors even/odd "<< ch.elapsed()<< " ms "<< std::endl;
}
break;
default: default:
...@@ -360,7 +442,7 @@ void Viewer::importMesh(std::string& filename) ...@@ -360,7 +442,7 @@ void Viewer::importMesh(std::string& filename)
position = myMap.getAttribute<PFP::VEC3, VERTEX>(attrNames[0]) ; position = myMap.getAttribute<PFP::VEC3, VERTEX>(attrNames[0]) ;
} }
myMap.enableQuickTraversal<VERTEX>() ; // myMap.enableQuickTraversal<VERTEX>() ;
m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::POINTS) ; m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::POINTS) ;
m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::LINES) ; m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::LINES) ;
......
...@@ -50,7 +50,13 @@ typedef PFP::VEC4 VEC4; ...@@ -50,7 +50,13 @@ typedef PFP::VEC4 VEC4;
/** /**
* Example of function that work with any kin of Vertex Attribute * Example of function that work with any kind of Vertex Attribute (normal/2/3/4)
*
* operators on multi-attribute are limited to:
* affectation
* +, -, +=, -=
* *(double) /(double) *=(double) /=(double)
*
*/ */
template <typename MAP, typename ATT> template <typename MAP, typename ATT>
typename ATT::DATA_TYPE smooth(MAP& map, Vertex v, const ATT& attributs) typename ATT::DATA_TYPE smooth(MAP& map, Vertex v, const ATT& attributs)
......
...@@ -46,10 +46,11 @@ typedef PFP::MAP::IMPL MAP_IMPL ; // map implementation ...@@ -46,10 +46,11 @@ typedef PFP::MAP::IMPL MAP_IMPL ; // map implementation
typedef PFP::VEC3 VEC3 ; // type of R³ vector typedef PFP::VEC3 VEC3 ; // type of R³ vector
/** /**
* @brief get attribute * @brief test if map has a Vertex Attribute of VEC3 named name
* @param map * @param map the map
* @param name name of attribute
*/ */
void byNames(MAP& map, const std::string& name) void testVAbyNames(MAP& map, const std::string& name)
{ {
VertexAttribute<VEC3, MAP_IMPL> testPos = map.getAttribute<VEC3, VERTEX>(name); VertexAttribute<VEC3, MAP_IMPL> testPos = map.getAttribute<VEC3, VERTEX>(name);
if (testPos.isValid()) if (testPos.isValid())
...@@ -60,6 +61,7 @@ void byNames(MAP& map, const std::string& name) ...@@ -60,6 +61,7 @@ void byNames(MAP& map, const std::string& name)
/** /**
* @brief computeLengthEdges * @brief computeLengthEdges
* Demonstrate usage of 2 attributes on 2 differents orbits.
* @param map the map * @param map the map
* @param pos attribute handler of position of vertices * @param pos attribute handler of position of vertices
* @param len attribute handler of length of edges * @param len attribute handler of length of edges
...@@ -76,10 +78,12 @@ void computeLengthEdges(MAP& map,const VertexAttribute<VEC3, MAP_IMPL>& pos, Edg ...@@ -76,10 +78,12 @@ void computeLengthEdges(MAP& map,const VertexAttribute<VEC3, MAP_IMPL>& pos, Edg
}); });
} }
/**
* @brief computeNewPositions Demonstrate the usage of AutoAttributes
*/
void computeNewPositions(MAP& map, VertexAttribute<VEC3, MAP_IMPL>& pos) void computeNewPositions(MAP& map, VertexAttribute<VEC3, MAP_IMPL>& pos)
{ {
// here we need new and old positions simultaneously so create temporary position // here we need new and old positions simultaneously so create temporary attribute position
VertexAutoAttribute<VEC3, MAP_IMPL> pos2(map); VertexAutoAttribute<VEC3, MAP_IMPL> pos2(map);
...@@ -96,7 +100,10 @@ void computeNewPositions(MAP& map, VertexAttribute<VEC3, MAP_IMPL>& pos) ...@@ -96,7 +100,10 @@ void computeNewPositions(MAP& map, VertexAttribute<VEC3, MAP_IMPL>& pos)
}); });
// swap attribute position with temporary (constant complexity !) // swap attribute position with temporary (constant complexity !)
// only possible with same type and same orbit attribute.
map.swapAttributes(pos,pos2); map.swapAttributes(pos,pos2);
// destruction of VertexAutoAttribute handller remove the attribute from the map.
} }
/** /**
...@@ -134,6 +141,8 @@ int main() ...@@ -134,6 +141,8 @@ int main()
grid.embedIntoGrid(positionAtt, 1.,1.,0.); grid.embedIntoGrid(positionAtt, 1.,1.,0.);
// ATTRIBUTE DECLARATION
// add an attribute of type float on orbit EDGE // add an attribute of type float on orbit EDGE
EdgeAttribute<float, MAP_IMPL> lengthAtt = myMap.addAttribute<float, EDGE>("length"); EdgeAttribute<float, MAP_IMPL> lengthAtt = myMap.addAttribute<float, EDGE>("length");
if (!lengthAtt.isValid()) if (!lengthAtt.isValid())
...@@ -157,6 +166,9 @@ int main() ...@@ -157,6 +166,9 @@ int main()
// define a face from a dart // define a face from a dart
Face f(d); Face f(d);
// ATTRIBUTE ACCESS
// [] operator can take a dart, a cell (only same off attribute), or an unsigned inf // [] operator can take a dart, a cell (only same off attribute), or an unsigned inf
// access to any attributes with darts // access to any attributes with darts
std::cout << positionAtt[d]<< std::endl; std::cout << positionAtt[d]<< std::endl;
...@@ -173,11 +185,15 @@ int main() ...@@ -173,11 +185,15 @@ int main()
// access to FaceAttribute with a Face // access to FaceAttribute with a Face
std::cout << nameAtt[f]<< std::endl; std::cout << nameAtt[f]<< std::endl;
// following line does not compile because of wrong cell type // following line does not compile because of wrong cell type
// std::cout << positionAtt[f]<< std::endl; // std::cout << positionAtt[f]<< std::endl;
// possible to bypass using dart access // possible to bypass using dart access
std::cout << positionAtt[f.dart]<< std::endl; std::cout << positionAtt[f.dart]<< std::endl;
// access with unsigned int is dangerous, index must be obtain with begin/end/next (see dumpAttribute)
// COPY, REMOVE, SWAP
// possible to have any number of attribute a same ORBIT // possible to have any number of attribute a same ORBIT
VertexAttribute<VEC3, MAP_IMPL> position2Att = myMap.addAttribute<VEC3, VERTEX>("other_position"); VertexAttribute<VEC3, MAP_IMPL> position2Att = myMap.addAttribute<VEC3, VERTEX>("other_position");
...@@ -187,14 +203,16 @@ int main() ...@@ -187,14 +203,16 @@ int main()
positionAtt[v] += VEC3(0,0,1); positionAtt[v] += VEC3(0,0,1);
computeNewPositions(myMap,positionAtt); computeNewPositions(myMap,positionAtt);
dumpAttribute(positionAtt); dumpAttribute(positionAtt);
byNames(myMap,"position"); //check if there is a Vertex Attribute of VEC3 named position => yes
testVAbyNames(myMap,"position");
myMap.removeAttribute<VEC3, VERTEX>(positionAtt); // remove the attribute
myMap.removeAttribute(positionAtt);
byNames(myMap,"position"); //check if there is a Vertex Attribute of VEC3 named position => no
testVAbyNames(myMap,"position");
return 0; return 0;
......
...@@ -140,5 +140,28 @@ int main() ...@@ -140,5 +140,28 @@ int main()
std::cout << "Total="<<surf[0]+surf[1]+surf[2]+surf[3]<< std::endl; std::cout << "Total="<<surf[0]+surf[1]+surf[2]+surf[3]<< std::endl;
TraversorV<MAP> tv0(myMap);
TraversorCellEven<MAP,VERTEX> tv1(tv0);
TraversorCellOdd<MAP,VERTEX> tv2(tv0);
std::cout << "PAIR:";
for (Dart d=tv1.begin(); d!=tv1.end(); d=tv1.next())// traverse all vertices (d one dart of each vertex)
std::cout << d << " / ";
std::cout << std::endl;
std::cout << "IMPPAIR:";
for (Dart d=tv2.begin(); d!=tv2.end(); d=tv2.next())// traverse all vertices (d one dart of each vertex)
std::cout << d << " / ";
std::cout << std::endl;
std::cout << "PAIR:";
for (Dart d=tv1.begin(); d!=tv1.end(); d=tv1.next())// traverse all vertices (d one dart of each vertex)
std::cout << d << " / ";
std::cout << std::endl;
std::cout << "IMPPAIR:";
for (Dart d=tv2.begin(); d!=tv2.end(); d=tv2.next())// traverse all vertices (d one dart of each vertex)
std::cout << d << " / ";
std::cout << std::endl;
return 0; return 0;
} }
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
#include "Topology/generic/cellmarker.h" #include "Topology/generic/cellmarker.h"
#include "Topology/generic/traversor/traversorCell.h" #include "Topology/generic/traversor/traversorCell.h"
//#include "Utils/vbo.h"
#include "Geometry/intersection.h" #include "Geometry/intersection.h"
#include "Algo/Geometry/normal.h" #include "Algo/Geometry/normal.h"
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __SIMPLEX__
#define __SIMPLEX__
#include "Topology/generic/cells.h"
namespace CGoGN
{
namespace Algo
{
namespace Topo
{
template <typename MAP, unsigned int ORBIT>
bool isSimplex(const MAP& map, Dart d)
{
if (ORBIT==VOLUME)
{
Dart d1 = map.phi2(d);
Dart e = map.phi1(d);
Dart d2 = map.phi2(e);
e = map.phi1(e);
Dart d3 = map.phi2(d);
if (map.phi1(e) != d) // check that face of d is a triangle
return false;
if (map.phi_1(d1) != map.template phi<12>(d2))
return false;
if (map.phi_1(d2) != map.template phi<12>(d3))
return false;
if (map.phi_1(d3) != map.template phi<12>(d1))
return false;
if (! map.isCycleTriangle(d1))
return false;
if (! map.isCycleTriangle(d2))
return false;
if (! map.isCycleTriangle(d3))
return false;
return true;
}
if (ORBIT==FACE)
{
return map.isCycleTriangle(d);
}
return true;
}
} // namespace Topo
} // namespace Algo
} // namespace CGoGN
#endif
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <iostream> #include <iostream>
#include "cells.h" #include "cells.h"
#include "Algo/Topo/Generic/simplex.h" #include "Algo/Topo/simplex.h"
namespace CGoGN namespace CGoGN
{ {
......
...@@ -39,7 +39,7 @@ namespace CGoGN ...@@ -39,7 +39,7 @@ namespace CGoGN
template <typename MAP, unsigned int ORBIT> template <typename MAP, unsigned int ORBIT>
class TraversorCell //: public Traversor<MAP> class TraversorCell //: public Traversor<MAP>
{ {
private: protected:
const MAP& m ; const MAP& m ;
unsigned int dimension ; unsigned int dimension ;
...@@ -53,6 +53,9 @@ private: ...@@ -53,6 +53,9 @@ private:
Cell<ORBIT> current ; Cell<ORBIT> current ;
bool firstTraversal ; bool firstTraversal ;
// just for odd/even versions
TraversorCell(const TraversorCell<MAP, ORBIT>& tc);
public: public:
TraversorCell(const MAP& map, bool forceDartMarker = false, unsigned int thread = 0) ; TraversorCell(const MAP& map, bool forceDartMarker = false, unsigned int thread = 0) ;
...@@ -65,10 +68,40 @@ public: ...@@ -65,10 +68,40 @@ public:
inline Cell<ORBIT> next() ; inline Cell<ORBIT> next() ;
inline void skip(Cell<ORBIT> c); inline void skip(Cell<ORBIT> c);
inline unsigned int nbCells();
} ;
template <typename MAP, unsigned int ORBIT>
class TraversorCellEven : public TraversorCell<MAP,ORBIT>
{
public:
TraversorCellEven(const TraversorCell<MAP,ORBIT>& tra):
TraversorCell<MAP,ORBIT>(tra) {}
~TraversorCellEven() { this->cmark = NULL; this->dmark=NULL; }
inline Cell<ORBIT> begin() ;
} ;
template <typename MAP, unsigned int ORBIT>
class TraversorCellOdd : public TraversorCell<MAP,ORBIT>
{
public:
TraversorCellOdd(const TraversorCell<MAP,ORBIT>& tra):
TraversorCell<MAP,ORBIT>(tra) {}
~TraversorCellOdd() {this->cmark = NULL; this->dmark=NULL; }
inline Cell<ORBIT> begin() ;
inline Cell<ORBIT> next() ;
} ; } ;
/* /*
* Executes function f on each ORBIT * Executes function f on each ORBIT
*/ */
...@@ -92,10 +125,34 @@ inline void foreach_cell_until(const MAP& map, FUNC f, bool forceDartMarker = fa ...@@ -92,10 +125,34 @@ inline void foreach_cell_until(const MAP& map, FUNC f, bool forceDartMarker = fa
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)
{
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)
{
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);
}
}
namespace Parallel namespace Parallel
{ {
template <unsigned int ORBIT, typename MAP, typename FUNC> template <unsigned int ORBIT, typename MAP, typename FUNC>
void foreach_cell(MAP& map, FUNC func, unsigned int nbth=0, bool needMarkers=true); void foreach_cell(MAP& map, FUNC func, unsigned int nbth=0, bool needMarkers=true);
template <unsigned int ORBIT, typename MAP, typename FUNC_E, typename FUNC_O>
void foreach_cell_EO(MAP& map, FUNC_E funcEven, FUNC_O funcOdd,unsigned int nbth=0, bool needMarkers=true);
} }
template <typename MAP> template <typename MAP>
......
...@@ -54,6 +54,25 @@ TraversorCell<MAP, ORBIT>::TraversorCell(const MAP& map, bool forceDartMarker, u ...@@ -54,6 +54,25 @@ TraversorCell<MAP, ORBIT>::TraversorCell(const MAP& map, bool forceDartMarker, u
} }
} }
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) :
m(tc.m), dmark(tc.dmark), cmark(tc.cmark),
quickTraversal(tc.quickTraversal), current(tc.current), firstTraversal(tc.firstTraversal),
dimension(tc.dimension)
{
}
template <typename MAP, unsigned int ORBIT> template <typename MAP, unsigned int ORBIT>
TraversorCell<MAP, ORBIT>::~TraversorCell() TraversorCell<MAP, ORBIT>::~TraversorCell()
{ {
...@@ -166,6 +185,94 @@ void TraversorCell<MAP, ORBIT>::skip(Cell<ORBIT> c) ...@@ -166,6 +185,94 @@ void TraversorCell<MAP, ORBIT>::skip(Cell<ORBIT> c)
template <typename MAP, unsigned int ORBIT>
Cell<ORBIT> TraversorCellEven<MAP, ORBIT>::begin()
{
Cell<ORBIT> c = TraversorCell<MAP, ORBIT>::begin();
this->firstTraversal = true;
return c;
}
template <typename MAP, unsigned int ORBIT>
Cell<ORBIT> TraversorCellOdd<MAP, ORBIT>::begin()
{
if(this->quickTraversal != NULL)
{
this->qCurrent = this->cont->begin() ;
this->current.dart = this->quickTraversal->operator[](this->qCurrent);
}
else
{
this->current.dart = this->m.begin() ;
while(this->current.dart != this->m.end() && (this->m.isBoundaryMarked(this->dimension, this->current.dart) ))
this->m.next(this->current.dart) ;
if(this->current.dart == this->m.end())
this->current.dart = NIL ;
else
{
if(this->dmark)
this->dmark->template unmarkOrbit<ORBIT>(this->current.dart) ;
else