Commit 982a728e authored by untereiner's avatar untereiner

Merge branch 'develop' of cgogn:~kraemer/CGoGN into develop

parents 9e8736d8 c4af2be3
......@@ -508,8 +508,14 @@ int main(int argc, char **argv)
std::cout << "Compute Volume ->"<< std::endl;
ch.start();
float vol = Algo::Geometry::totalVolume<PFP>(myMap, position);
std::cout << ch.elapsed()<< " ms val="<<vol<< std::endl;
ch.start();
vol += Algo::Geometry::totalVolume<PFP>(myMap, position);
std::cout << ch.elapsed()<< " ms val="<<vol<< std::endl;
ch.start();
vol += Algo::Geometry::totalVolume<PFP>(myMap, position);
std::cout << ch.elapsed()<< " ms val="<<vol<< std::endl;
ch.start();
vol += Algo::Geometry::totalVolume<PFP>(myMap, position);
std::cout << ch.elapsed()<< " ms val="<<vol<< std::endl;
......
......@@ -42,6 +42,9 @@ target_link_libraries( traverse_cells ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS} )
add_executable( traverse_neighbours traverse_neighbours.cpp)
target_link_libraries( traverse_neighbours ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS} )
add_executable( traverse_attributes traverse_attributes.cpp)
target_link_libraries( traverse_attributes ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS} )
QT4_WRAP_UI( show_traversors_ui2 show_traversors2.ui )
QT4_WRAP_CPP(show_traversors_moc2 show_traversors2.h)
add_executable( show_traversors2 show_traversors2.cpp ${show_traversors_ui2} ${show_traversors_moc2})
......
......@@ -139,11 +139,9 @@ void MyQT::cb_Save()
}
template <unsigned int ORBIT>
void MyQT::colorizeCell(Dart d, float r,float g, float b)
void MyQT::colorizeCell(Cell<ORBIT> c, float r, float g, float b)
{
TraversorDartsOfOrbit<PFP::MAP, ORBIT>doo (myMap, d);
for (Dart e = doo.begin(); e != doo.end(); e = doo.next())
m_render_topo->setDartColor(e, r, g, b);
myMap.foreach_dart_of_orbit(c, [&] (Dart d) { m_render_topo->setDartColor(d, r, g, b); });
}
void MyQT::traverse2()
......
......@@ -117,7 +117,7 @@ protected:
void cb_mousePress(int button, int x, int y);
template <unsigned int ORBIT>
void colorizeCell(Dart d, float r,float g, float b);
void colorizeCell(Cell<ORBIT> c, float r,float g, float b);
void traverse2();
void dynamicMarkOrbit(unsigned int orb);
......
......@@ -189,11 +189,9 @@ void MyQT::cb_Save()
}
template <unsigned int ORBIT>
void MyQT::colorizeCell(Dart d, float r,float g, float b)
void MyQT::colorizeCell(Cell<ORBIT> c, float r, float g, float b)
{
TraversorDartsOfOrbit<PFP::MAP, ORBIT>doo (myMap, d);
for (Dart e = doo.begin(); e != doo.end(); e = doo.next())
m_render_topo->setDartColor(e, r, g, b);
myMap.foreach_dart_of_orbit(c, [&] (Dart d) { m_render_topo->setDartColor(d, r, g, b); });
}
void MyQT::traverse2()
......
......@@ -115,7 +115,7 @@ protected:
void cb_mousePress(int button, int x, int y);
template <unsigned int ORBIT>
void colorizeCell(Dart d, float r,float g, float b);
void colorizeCell(Cell<ORBIT> c, float r,float g, float b);
void traverse2();
void traverse3();
......
/*******************************************************************************
* 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 *
* *
*******************************************************************************/
#include "Topology/generic/parameters.h"
#include "Topology/map/embeddedMap2.h"
#include "Algo/Tiling/Surface/square.h"
using namespace CGoGN ;
/**
* Struct that contains some informations about the types of the manipulated objects
* Mainly here to be used by the algorithms that are parameterized by it
*/
struct PFP: public PFP_STANDARD
{
// definition of the type of the map
typedef EmbeddedMap2 MAP;
};
// some typedef shortcuts
typedef PFP::MAP MAP ; // map type
typedef PFP::MAP::IMPL MAP_IMPL ; // map implementation
typedef PFP::VEC3 VEC3 ; // type of R³ vector
int main()
{
// declare a map to handle the mesh
MAP myMap;
// add position attribute on vertices and get handler on it
VertexAttribute<VEC3, MAP_IMPL> position = myMap.addAttribute<VEC3, VERTEX>("position");
// create a topo grid of 2x2 squares
Algo::Surface::Tilings::Square::Grid<PFP> grid(myMap, 4, 4, true);
// and embed it using position attribute
grid.embedIntoGrid(position, 1.,1.,0.);
// traversal with begin/end/next on attribute handler
for (unsigned int id=position.begin(); id !=position.end(); position.next(id))
{
std::cout << id << " : " << position[id]<< " / ";
};
std::cout << std::endl;
//using foreach function (C++11 lambda expression)
foreach_attribute(position,[&](unsigned int id) // for each element of position
{
std::cout << id << " : " << position[id]<< " / ";
});
// using parallel foreach
// parameter position must be captured explicitly even if it used as first parameter of foreach !
Parallel::foreach_attribute(position,[&position](unsigned int id, unsigned int thread) // for each elt of the position attribute
{
position[id] *= 2.0f;
},4); // 4:4 thread, false for no need for markers in threaded code.
return 0;
}
......@@ -26,7 +26,7 @@
#include "Topology/generic/parameters.h"
#include "Topology/map/embeddedMap2.h"
#include "Algo/Tiling/Surface/square.h"
#include "Algo/Geometry/area.h"
using namespace CGoGN ;
......@@ -55,13 +55,11 @@ int main()
VertexAttribute<VEC3, MAP_IMPL> position = myMap.addAttribute<VEC3, VERTEX>("position");
// create a topo grid of 2x2 squares
Algo::Surface::Tilings::Square::Grid<PFP> grid(myMap, 2, 2, true);
Algo::Surface::Tilings::Square::Grid<PFP> grid(myMap, 4, 4, true);
// and embed it using position attribute
grid.embedIntoGrid(position, 1.,1.,0.);
// ALGO:
// foreach vertex of the map
// print position of the vertex
......@@ -106,9 +104,41 @@ int main()
{
std::cout << v << " : " << position[v]<< " / ";
});
// warning here v is a Vertex and not a Dart (but can cast automatically into)
std::cout << std::endl;
// warning here v is a Vertex and not a Dart (but can cast automatically into)
// example of parallel traversal of cells
Parallel::foreach_cell<VERTEX>(myMap,[&](Vertex v, unsigned int thread) // for each Vertex v of the MAP myMap
{
position[v] += VEC3(0.0,0.0,PFP::REAL(thread)*0.1f);
// WARNING thread vary here from 1 to 4 (and not from 0 to 3) !!!!
},4,false); // 4:4 thread, false for no need for markers in threaded code.
std::cout << "After // processing"<< std::endl;
foreach_cell<VERTEX>(myMap,[&](Vertex v) // for each Vertex v of the MAP myMap
{
std::cout << position[v]<< " / ";
});
std::cout << std::endl;
// Example with // accumulation
// computing the sum of area faces
// init nbthread values with 0
float surf[4]={0.0f,0.0f,0.0f,0.0f};
// traverse face in //
Parallel::foreach_cell<FACE>(myMap,[&](Face f, unsigned int thr)
{
// for each face add surface to accumulator (-1 because counter between 1-4 not 0-3)
surf[thr-1] += Algo::Surface::Geometry::convexFaceArea<PFP>(myMap,f,position);
},4,false);
std::cout << surf[0]<< "/"<< surf[1]<< "/"<< surf[2]<< "/"<< surf[3]<< "/"<< std::endl;
std::cout << "Total="<<surf[0]+surf[1]+surf[2]+surf[3]<< std::endl;
return 0;
}
......@@ -37,13 +37,13 @@ namespace Geometry
{
template <typename PFP>
typename PFP::REAL tetrahedronSignedVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position) ;
typename PFP::REAL tetrahedronSignedVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position) ;
template <typename PFP>
typename PFP::REAL tetrahedronVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position) ;
typename PFP::REAL tetrahedronVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position) ;
template <typename PFP>
typename PFP::REAL convexPolyhedronVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, unsigned int thread = 0) ;
typename PFP::REAL convexPolyhedronVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, unsigned int thread = 0) ;
template <typename PFP>
typename PFP::REAL totalVolume(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, unsigned int thread = 0) ;
......
......@@ -36,85 +36,87 @@ namespace Geometry
{
template <typename PFP>
typename PFP::REAL tetrahedronSignedVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position)
typename PFP::REAL tetrahedronSignedVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position)
{
typedef typename PFP::VEC3 VEC3;
VEC3 p1 = position[d] ;
VEC3 p2 = position[map.phi1(d)] ;
VEC3 p3 = position[map.phi_1(d)] ;
VEC3 p4 = position[map.phi_1(map.phi2(d))] ;
VEC3 p1 = position[v.dart] ;
VEC3 p2 = position[map.phi1(v)] ;
VEC3 p3 = position[map.phi_1(v)] ;
VEC3 p4 = position[map.phi_1(map.phi2(v))] ;
return Geom::tetraSignedVolume(p1, p2, p3, p4) ;
}
template <typename PFP>
typename PFP::REAL tetrahedronVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position)
typename PFP::REAL tetrahedronVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position)
{
typedef typename PFP::VEC3 VEC3;
VEC3 p1 = position[d] ;
VEC3 p2 = position[map.phi1(d)] ;
VEC3 p3 = position[map.phi_1(d)] ;
VEC3 p4 = position[map.phi_1(map.phi2(d))] ;
VEC3 p1 = position[v.dart] ;
VEC3 p2 = position[map.phi1(v)] ;
VEC3 p3 = position[map.phi_1(v)] ;
VEC3 p4 = position[map.phi_1(map.phi2(v))] ;
return Geom::tetraVolume(p1, p2, p3, p4) ;
}
template <typename PFP>
typename PFP::REAL convexPolyhedronVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, unsigned int thread)
typename PFP::REAL convexPolyhedronVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, unsigned int thread)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
if (Volume::Modelisation::Tetrahedralization::isTetrahedron<PFP>(map,d,thread))
return tetrahedronVolume<PFP>(map,d,position) ;
if (Volume::Modelisation::Tetrahedralization::isTetrahedron<PFP>(map, v, thread))
return tetrahedronVolume<PFP>(map, v, position) ;
else
{
typename PFP::REAL vol = 0 ;
VEC3 vCentroid = Algo::Surface::Geometry::volumeCentroid<PFP>(map, d, position, thread) ;
VEC3 vCentroid = Algo::Surface::Geometry::volumeCentroid<PFP>(map, v, position, thread) ;
DartMarkerStore<MAP> mark(map,thread); // Lock a marker
DartMarkerStore<MAP> mark(map, thread) ; // Lock a marker
std::vector<Dart> visitedFaces ;
std::vector<Face> visitedFaces ;
visitedFaces.reserve(100) ;
visitedFaces.push_back(d) ;
mark.template markOrbit<FACE>(d) ;
Face f(v.dart) ;
visitedFaces.push_back(f) ;
mark.markOrbit(f) ;
for(unsigned int iface = 0; iface != visitedFaces.size(); ++iface)
for(unsigned int iface = 0; iface != visitedFaces.size(); ++iface)
{
Dart e = visitedFaces[iface] ;
if(map.isCycleTriangle(e))
f = visitedFaces[iface] ;
if(map.isCycleTriangle(f))
{
VEC3 p1 = position[e] ;
VEC3 p2 = position[map.phi1(e)] ;
VEC3 p3 = position[map.phi_1(e)] ;
VEC3 p1 = position[f.dart] ;
VEC3 p2 = position[map.phi1(f)] ;
VEC3 p3 = position[map.phi_1(f)] ;
vol += Geom::tetraVolume(p1, p2, p3, vCentroid) ;
}
else
{
VEC3 fCentroid = Algo::Surface::Geometry::faceCentroid<PFP>(map, e, position) ;
Dart f = e ;
VEC3 fCentroid = Algo::Surface::Geometry::faceCentroid<PFP>(map, f, position) ;
Dart d = f.dart ;
do
{
VEC3 p1 = position[f] ;
VEC3 p2 = position[map.phi1(f)] ;
VEC3 p1 = position[d] ;
VEC3 p2 = position[map.phi1(d)] ;
vol += Geom::tetraVolume(p1, p2, fCentroid, vCentroid) ;
f = map.phi1(f) ;
} while(f != e) ;
d = map.phi1(d) ;
} while(d != f.dart) ;
}
Dart currentFace = e;
Dart d = f.dart;
do // add all face neighbours to the table
{
Dart ee = map.phi2(e) ;
if(!mark.isMarked(ee)) // not already marked
Dart dd = map.phi2(d) ;
if(!mark.isMarked(dd)) // not already marked
{
visitedFaces.push_back(ee) ;
mark.template markOrbit<FACE>(ee) ;
Face ff(dd);
visitedFaces.push_back(ff) ;
mark.markOrbit(ff) ;
}
e = map.phi1(e) ;
} while(e != currentFace) ;
d = map.phi1(d) ;
} while(d != f.dart) ;
}
return vol ;
......
......@@ -399,7 +399,7 @@ public:
//@}
template <unsigned int ORBIT>
unsigned int getEmbedding(Dart d) const;
unsigned int getEmbedding(Cell<ORBIT> c) const;
} ;
template <typename T, unsigned int ORBIT>
......
......@@ -579,10 +579,10 @@ inline unsigned int ImplicitHierarchicalMap3::edgeLevel(Dart d)
}
template <unsigned int ORBIT>
inline unsigned int ImplicitHierarchicalMap3::getEmbedding(Dart d) const
inline unsigned int ImplicitHierarchicalMap3::getEmbedding(Cell<ORBIT> c) const
{
unsigned int nbSteps = m_curLevel - vertexInsertionLevel(d);
unsigned int index = EmbeddedMap3::getEmbedding<ORBIT>(d);
unsigned int nbSteps = m_curLevel - vertexInsertionLevel(c.dart);
unsigned int index = EmbeddedMap3::getEmbedding(c);
unsigned int step = 0;
while(step < nbSteps)
......@@ -602,9 +602,9 @@ inline bool ImplicitHierarchicalMap3::isWellEmbedded()
//std::cout << "yeahhh ? " << std::endl;
TraversorV<ImplicitHierarchicalMap3> tv(*this);
for(Dart dv = tv.begin() ; dv != tv.end() ; dv = tv.next())
for(Vertex dv = tv.begin() ; dv.dart != tv.end() ; dv = tv.next())
{
unsigned int curem = this->getEmbedding<VERTEX>(dv);
unsigned int curem = this->getEmbedding(dv);
//std::cout << "current emb = " << curem << std::endl;
unsigned int count = 0;
......
......@@ -196,6 +196,9 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vecto
VertexAutoAttribute<NoTypeNameAttribute<std::vector<Dart> >, typename PFP::MAP::IMPL> vecDartsPerVertex(map, "incidents") ;
DartMarkerNoUnmark<typename PFP::MAP> m(map) ;
unsigned int vemb = EMBNULL;
auto fsetemb = [&] (Dart d) { map.template setDartEmbedding<VERTEX>(d, vemb); };
unsigned nbf = qt.roots.size() ;
// for each root face
......@@ -206,13 +209,12 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vecto
for (unsigned int j = 0; j < 3; ++j)
{
unsigned int idx = qt.roots[i]->indices[j] ;
unsigned int emb = qt.verticesID[idx] ;
vemb = qt.verticesID[idx] ;
FunctorSetEmb<typename PFP::MAP, VERTEX> fsetemb(map, emb) ;
map.template foreach_dart_of_orbit<PFP::MAP::VERTEX_OF_PARENT>(d, fsetemb) ;
m.mark(d) ; // mark on the fly to unmark on second loop
vecDartsPerVertex[emb].push_back(d) ; // store incident darts for fast adjacency reconstruction
vecDartsPerVertex[vemb].push_back(d) ; // store incident darts for fast adjacency reconstruction
d = map.phi1(d) ;
}
}
......
......@@ -470,12 +470,12 @@ Dart splitVertex(typename PFP::MAP& map, std::vector<Dart>& vd)
*************************************************************************************************/
template <typename PFP>
bool isTetrahedron(typename PFP::MAP& map, Dart d, unsigned int thread)
bool isTetrahedron(typename PFP::MAP& map, Vol v, unsigned int thread)
{
unsigned int nbFaces = 0;
//Test the number of faces end its valency
Traversor3WF<typename PFP::MAP> travWF(map, d, false, thread);
Traversor3WF<typename PFP::MAP> travWF(map, v, false, thread);
for(Dart dit = travWF.begin() ; dit != travWF.end(); dit = travWF.next())
{
//increase the number of faces
......@@ -484,7 +484,7 @@ bool isTetrahedron(typename PFP::MAP& map, Dart d, unsigned int thread)
return false;
//test the valency of this face
if(map.faceDegree(dit) != 3)
if(!map.isCycleTriangle(dit))
return false;
}
......
......@@ -133,7 +133,7 @@ public:
p1 *= 1.0 / 3.0 ;
p2 *= 1.0 / 3.0 ;
if(m_map.isBoundaryFace(d))
if(m_map.isFaceIncidentToBoundary(d))
{
Dart df = m_map.findBoundaryEdgeOfFace(d);
m_map.incCurrentLevel() ;
......
......@@ -167,7 +167,7 @@ void Map2MR<PFP>::addNewLevelSqrt3()
for (Dart dit = t.begin(); dit != t.end(); dit = t.next())
{
//if it is an even level (triadic refinement) and a boundary face
if((m_map.getCurrentLevel()%2 == 0) && m_map.isBoundaryFace(dit))
if((m_map.getCurrentLevel()%2 == 0) && m_map.isFaceIncidentToBoundary(dit))
{
//find the boundary edge
Dart df = m_map.findBoundaryEdgeOfFace(dit);
......
......@@ -45,20 +45,18 @@ public:
} ;
template <typename PFP>
unsigned int vertexLevel(typename PFP::MAP& map, Dart d)
unsigned int vertexLevel(typename PFP::MAP& map, Vertex v)
{
assert(map.getDartLevel(d) <= map.getCurrentLevel() || !"edgeLevel : called with a dart inserted after current level") ;
assert(map.getDartLevel(v.dart) <= map.getCurrentLevel() || !"vertexLevel : called with a dart inserted after current level") ;
unsigned int level = map.getMaxLevel();
TraversorDartsOfOrbit<typename PFP::MAP,VERTEX> tv(map,d);
for(Dart dit = tv.begin() ; dit != tv.end() ; dit = tv.next())
map.foreach_dart_of_orbit(v, [&] (Dart d)
{
unsigned int ldit = map.getDartLevel(dit) ;
unsigned int ldit = map.getDartLevel(d) ;
if(ldit < level)
level = ldit;
}
});
// Dart dit = d;
// do
......
......@@ -163,66 +163,15 @@ void foreach_cell(MAP& map, std::vector<FunctorMapThreaded<MAP>*>& funcs, bool n
for (unsigned int i = 0; i < nbth; ++i)
vd[i].reserve(SIZE_BUFFER_THREAD);
AttributeContainer* cont = NULL;
DartMarker<MAP>* dmark = NULL;
CellMarker<MAP, ORBIT>* cmark = NULL;
const AttributeMultiVector<Dart>* quickTraversal = map.template getQuickTraversal<ORBIT>() ;
// fill each vd buffers with SIZE_BUFFER_THREAD darts
Dart d;
unsigned int di=0;
if(quickTraversal != NULL)
unsigned int nb=0;
TraversorCell<MAP, ORBIT> trav(map);
Cell<ORBIT> cell = trav.begin();
Cell<ORBIT> c_end = trav.end();
while ((cell.dart != c_end.dart) && (nb < nbth*SIZE_BUFFER_THREAD) )
{
cont = &(map.template getAttributeContainer<ORBIT>()) ;
di = cont->begin();
unsigned int nb = 0;
while ((di != cont->end()) && (nb < nbth*SIZE_BUFFER_THREAD) )
{
d = quickTraversal->operator[](di);
vd[nb%nbth].push_back(d);
nb++;
cont->next(di);
}
}
else
{
if(map.template isOrbitEmbedded<ORBIT>())
{
cmark = new CellMarker<MAP, ORBIT>(map) ;
d = map.begin();
unsigned int nb = 0;
while ((d != map.end()) && (nb < nbth*SIZE_BUFFER_THREAD) )
{
if ((!map.template isBoundaryMarked<MAP::DIMENSION>(d)) && (!cmark->isMarked(d)))
{
cmark->mark(d);
vd[nb%nbth].push_back(d);
nb++;
}
map.next(d);
}
}
else
{
dmark = new DartMarker<MAP>(map) ;
d = map.begin();
unsigned int nb = 0;
while ((d != map.end()) && (nb < nbth*SIZE_BUFFER_THREAD) )
{
if ((!map.template isBoundaryMarked<MAP::DIMENSION>(d)) && (!dmark->isMarked(d)))
{
dmark->template markOrbit<ORBIT>(d);
vd[nb%nbth].push_back(d);
nb++;
}
map.next(d);
}
}
vd[nb%nbth].push_back(cell.dart);
nb++;
cell = trav.next();
}
boost::barrier sync1(nbth+1);
......@@ -244,8 +193,6 @@ void foreach_cell(MAP& map, std::vector<FunctorMapThreaded<MAP>*>& funcs, bool n
tfs[i] = new ThreadFunction<MAP>(funcs[i], vd[i],sync1,sync2, finished,1+i);
threads[i] = new boost::thread( boost::ref( *(tfs[i]) ) );
}