Commit b102db67 authored by untereiner's avatar untereiner
Browse files

Merge cgogn:~kraemer/CGoGN

parents 03f47a06 11df28e3
......@@ -249,8 +249,11 @@ void MyQT::cb_keyPress(int code)
svg.setWidth(1.0f);
svg.setColor(Geom::Vec3f(0.0f,0.0f,0.5f));
Algo::Render::SVG::renderEdges<PFP>(svg,myMap,position);
svg.setColor(Geom::Vec3f(0.0f,0.8f,0.0f));
svg.setWidth(5.0f);
Algo::Render::SVG::renderVertices<PFP>(svg,myMap,position);
svg.setColor(Geom::Vec3f(1.0f,0.0f,0.0f));
m_strings->toSVG(svg);
//svg destruction close the file
}
if (code == 't')
......@@ -333,6 +336,7 @@ int main(int argc, char **argv)
sqt.m_selected = myMap.begin();
sqt.setGeometry(100,100,1024,1024);
sqt.show();
sqt.slider_balls(50);
......
......@@ -26,6 +26,9 @@
#include "Algo/Geometry/boundingbox.h"
#include "Algo/Modelisation/polyhedron.h"
#include "Algo/Geometry/centroid.h"
#include "Algo/Import/import.h"
#include "Algo/Export/export.h"
using namespace CGoGN ;
......@@ -164,14 +167,10 @@ void MyQT::createMap(int n)
grid.grid_topo(n,n);
grid.embedGrid(1.,1.,0.);
// bounding box of scene
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position);
float lWidthObj = std::max<PFP::REAL>(std::max<PFP::REAL>(bb.size(0), bb.size(1)), bb.size(2));
Geom::Vec3f lPosObj = (bb.min() + bb.max()) / PFP::REAL(2);
// send BB info to interface for centering on GL screen
setParamObject(lWidthObj, lPosObj.data());
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
setParamObject(bb.maxSize(), bb.center().data()) ;
m_shift = bb.maxSize()/200.0f;
// first show for be sure that GL context is binded
show();
......@@ -296,6 +295,30 @@ void MyQT::cb_keyPress(int keycode)
}
}
break;
case Qt::Key_Up:
if (m_selected!=NIL)
position[m_selected][1] +=m_shift;
updateMap();
updateGL();
break;
case Qt::Key_Down:
if (m_selected!=NIL)
position[m_selected][1] -= m_shift;
updateMap();
updateGL();
break;
case Qt::Key_Left:
if (m_selected!=NIL)
position[m_selected][0] -= m_shift;
updateMap();
updateGL();
break;
case Qt::Key_Right:
if (m_selected!=NIL)
position[m_selected][0] += m_shift;
updateMap();
updateGL();
break;
}
updateGL();
}
......@@ -306,6 +329,74 @@ void MyQT::svg()
m_render_topo->svgout2D(filename, modelViewMatrix(),projectionMatrix());
}
void MyQT::cb_Open()
{
std::string filters("all (*.*);; trian (*.trian);; off (*.off);; ply (*.ply);; map (*.map)") ;
std::string filename = selectFile("Open Mesh", "", filters) ;
if (!filename.empty())
importMesh(filename);
updateGL();
}
void MyQT::cb_Save()
{
std::string filename = selectFileSave("Export SVG file ",".","(*.off)");
Algo::Export::exportOFF<PFP>(myMap,position,filename.c_str());
}
void MyQT::importMesh(std::string& filename)
{
myMap.clear(true) ;
size_t pos = filename.rfind("."); // position of "." in filename
std::string extension = filename.substr(pos);
if (extension == std::string(".map"))
{
myMap.loadMapBin(filename);
position = myMap.getAttribute<PFP::VEC3>(VERTEX, "position") ;
}
else
{
std::vector<std::string> attrNames ;
if(!Algo::Import::importMesh<PFP>(myMap, filename.c_str(), attrNames))
{
CGoGNerr << "could not import " << filename << CGoGNendl ;
return;
}
position = myMap.getAttribute<PFP::VEC3>(VERTEX, attrNames[0]) ;
}
colorDarts = myMap.getAttribute<PFP::VEC3>(DART, "color");
if (!colorDarts.isValid())
{
colorDarts = myMap.addAttribute<PFP::VEC3>(DART, "color");
for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d))
{
if (dm.isMarked(d) && (!myMap.isBoundaryMarked(d)))
{
int n = random();
float r = float(n&0x7f)/255.0f + 0.25f;
float g = float((n>>8)&0x7f)/255.0f + 0.25f;
float b = float((n>>16)&0x7f)/255.0 + 0.25f;
colorDarts[d] = Geom::Vec3f(r,g,b);
m_render_topo->setDartColor(d,r,g,b);
}
}
}
m_selected = NIL;
m_selected2 = NIL;
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
setParamObject(bb.maxSize(), bb.center().data()) ;
m_shift = bb.maxSize()/200.0f;
updateMap();
updateGLMatrices() ;
}
void MyQT::width(int w)
{
m_render_topo->setDartWidth(w);
......
......@@ -67,12 +67,14 @@ class MyQT: public Utils::QT::SimpleQT
{
Q_OBJECT
public:
MyQT():nb(myMap),m_render_topo(NULL),m_selected(NIL),m_selected2(NIL),dm(myMap) {}
MyQT():nb(myMap),m_render_topo(NULL),m_selected(NIL),m_selected2(NIL),dm(myMap),m_shift(0.01f) {}
void cb_redraw();
void cb_initGL();
void cb_mousePress(int button, int x, int y);
void cb_keyPress(int code);
void cb_Open();
void cb_Save();
Utils::QT::uiDockInterface dock;
......@@ -90,6 +92,7 @@ protected:
Dart m_selected;
Dart m_selected2;
DartMarker dm;
float m_shift;
// just for more compact writing
inline Dart PHI1(Dart d) {return myMap.phi1(d);}
......@@ -102,6 +105,7 @@ public:
// example of simple map creation
void createMap(int n);
void updateMap();
void importMesh(std::string& filename);
public slots:
void operation(int x);
......
......@@ -42,7 +42,7 @@ template <typename PFP, typename EMBV, typename EMB>
EMB volumeCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs)
{
EMB center = AttribOps::zero<EMB,PFP>() ;
unsigned count = 0 ;
unsigned int count = 0 ;
Traversor3WV<typename PFP::MAP> tra(map,d);
for (Dart d = tra.begin(); d != tra.end(); d = tra.next())
......
......@@ -87,11 +87,11 @@ public:
Dart alpha_1(Dart d) ;
virtual Dart begin() ;
virtual Dart begin() const ;
virtual Dart end() ;
virtual Dart end() const ;
virtual Dart next(Dart& d) ;
virtual void next(Dart& d) const ;
virtual bool foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread = 0) ;
......
......@@ -139,7 +139,7 @@ inline Dart ImplicitHierarchicalMap::alpha_1(Dart d)
return Map2::alpha_1(d) ;
}
inline Dart ImplicitHierarchicalMap::begin()
inline Dart ImplicitHierarchicalMap::begin() const
{
Dart d = Map2::begin() ;
while(d != Map2::end() && m_dartLevel[d] > m_curLevel)
......@@ -147,18 +147,17 @@ inline Dart ImplicitHierarchicalMap::begin()
return d ;
}
inline Dart ImplicitHierarchicalMap::end()
inline Dart ImplicitHierarchicalMap::end() const
{
return Map2::end() ;
}
inline Dart ImplicitHierarchicalMap::next(Dart& d)
inline void ImplicitHierarchicalMap::next(Dart& d) const
{
do
{
Map2::next(d) ;
} while(d != Map2::end() && m_dartLevel[d] > m_curLevel) ;
return d;
}
inline bool ImplicitHierarchicalMap::foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread)
......
......@@ -360,11 +360,11 @@ public:
*************************************************************************/
//@{
virtual Dart begin() ;
virtual Dart begin() const;
virtual Dart end() ;
virtual Dart end() const;
virtual Dart next(Dart& d) ;
virtual void next(Dart& d) const ;
virtual bool foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread = 0) ;
......
......@@ -200,7 +200,7 @@ inline Dart ImplicitHierarchicalMap3::alpha_2(Dart d)
return phi2(phi3(d));
}
inline Dart ImplicitHierarchicalMap3::begin()
inline Dart ImplicitHierarchicalMap3::begin() const
{
Dart d = Map3::begin() ;
while(m_dartLevel[d] > m_curLevel)
......@@ -208,18 +208,17 @@ inline Dart ImplicitHierarchicalMap3::begin()
return d ;
}
inline Dart ImplicitHierarchicalMap3::end()
inline Dart ImplicitHierarchicalMap3::end() const
{
return Map3::end() ;
}
inline Dart ImplicitHierarchicalMap3::next(Dart& d)
inline void ImplicitHierarchicalMap3::next(Dart& d) const
{
do
{
Map3::next(d) ;
} while(d != Map3::end() && m_dartLevel[d] > m_curLevel) ;
return d;
}
inline bool ImplicitHierarchicalMap3::foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread)
......
......@@ -34,13 +34,14 @@ namespace Algo
namespace Import
{
template <typename PFP>
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames) ;
template <typename PFP>
class QuadTreeNode
{
public:
public:
unsigned int indices[3] ;
QuadTreeNode* children[4] ;
QuadTreeNode* parent ;
unsigned int level ;
QuadTreeNode()
{
for(unsigned int i = 0; i < 3; ++i)
......@@ -48,6 +49,7 @@ public:
for(unsigned int i = 0; i < 4; ++i)
children[i] = NULL ;
parent = NULL ;
level = 0 ;
}
~QuadTreeNode()
......@@ -59,11 +61,12 @@ public:
void subdivide()
{
assert(children[0] == NULL) ;
assert(!isSubdivided()) ;
for(unsigned int i = 0; i < 4; ++i)
{
children[i] = new QuadTreeNode() ;
children[i]->parent = this ;
children[i]->level = level + 1 ;
}
}
......@@ -72,86 +75,63 @@ public:
return children[0] != NULL ;
}
void embed(typename PFP::MAP& map, Dart d, std::vector<unsigned int>& vID, CellMarker& cm, bool CCW)
template <typename PFP>
void embed(typename PFP::MAP& map, Dart d, std::vector<unsigned int>& vID)
{
assert(map.getCurrentLevel() == level) ;
if(isSubdivided())
{
Dart d0 = map.phi1(d) ;
Dart d1, d2 ;
if(CCW)
{
d1 = map.phi_1(d) ;
d2 = d ;
}
else
{
d1 = d ;
d2 = map.phi_1(d) ;
}
map.incCurrentLevel() ;
unsigned int v0 = vID[indices[0]] ;
unsigned int v1 = vID[indices[1]] ;
// unsigned int v2 = vID[indices[2]] ;
unsigned int emb0 = vID[children[0]->indices[0]] ;
unsigned int e0 = map.getEmbedding(VERTEX, map.phi2(d0)) ;
if(!cm.isMarked(map.phi2(d0)))
{
assert(e0 == EMBNULL) ;
map.embedOrbit(VERTEX, map.phi2(d0), emb0) ;
cm.mark(map.phi2(d0)) ;
}
else
assert(e0 == emb0) ;
unsigned int emb1 = vID[children[0]->indices[1]] ;
unsigned int e1 = map.getEmbedding(VERTEX, map.phi2(d1)) ;
if(!cm.isMarked(map.phi2(d1)))
Dart it = d ;
do
{
assert(e1 == EMBNULL) ;
map.embedOrbit(VERTEX, map.phi2(d1), emb1) ;
cm.mark(map.phi2(d1)) ;
}
else
assert(e1 == emb1) ;
unsigned int emb2 = vID[children[0]->indices[2]] ;
unsigned int e2 = map.getEmbedding(VERTEX, map.phi2(d2)) ;
if(!cm.isMarked(map.phi2(d2)))
{
assert(e2 == EMBNULL) ;
map.embedOrbit(VERTEX, map.phi2(d2), emb2) ;
cm.mark(map.phi2(d2)) ;
}
else
assert(e2 == emb2) ;
map.decCurrentLevel() ;
Dart next = map.phi1(it) ;
unsigned int emb = map.getEmbedding(VERTEX, it) ;
unsigned int idx = emb == v0 ? 0 : emb == v1 ? 1 : 2 ;
map.incCurrentLevel() ;
Dart dd = map.phi1(next) ;
unsigned int oldEmb = map.getEmbedding(VERTEX, dd) ;
unsigned int newEmb = vID[children[0]->indices[idx]] ;
if(oldEmb == EMBNULL)
{
map.embedOrbit(VERTEX, dd, newEmb) ;
map.pushLevel() ;
for(unsigned int i = map.getCurrentLevel() + 1; i <= map.getMaxLevel(); ++i)
{
map.setCurrentLevel(i) ;
map.embedOrbit(VERTEX, dd, newEmb) ;
}
map.popLevel() ;
}
else
assert(oldEmb == newEmb) ;
map.decCurrentLevel() ;
it = next ;
} while(it != d) ;
Dart t0 = map.phi_1(d) ;
map.incCurrentLevel() ;
t0 = map.phi2(map.phi1(t0)) ;
children[0]->embed(map, t0, vID, cm, CCW) ;
Dart d0 = map.phi2(map.phi1(d)) ;
children[0]->embed<PFP>(map, d0, vID) ;
map.decCurrentLevel() ;
Dart t1 = d ;
map.incCurrentLevel() ;
children[1]->embed(map, t1, vID, cm, !CCW) ;
map.decCurrentLevel() ;
Dart t2 = map.phi1(d) ;
map.incCurrentLevel() ;
t2 = map.phi1(t2) ;
children[2]->embed(map, t2, vID, cm, !CCW) ;
map.decCurrentLevel() ;
Dart t3 = map.phi_1(d) ;
map.incCurrentLevel() ;
t3 = map.phi_1(t3) ;
children[3]->embed(map, t3, vID, cm, !CCW) ;
map.decCurrentLevel() ;
do
{
unsigned int emb = map.getEmbedding(VERTEX, it) ;
unsigned int idx = emb == v0 ? 0 : emb == v1 ? 1 : 2 ;
map.incCurrentLevel() ;
children[idx+1]->embed<PFP>(map, it, vID) ;
map.decCurrentLevel() ;
it = map.phi1(it) ;
} while(it != d) ;
}
else
{
if(map.getCurrentLevel() < map.getMaxLevel())
std::cout << "adaptive !!!!!!!" << std::endl ;
std::cout << "adaptive subdivision not managed yet" << std::endl ;
}
}
......@@ -164,18 +144,14 @@ public:
children[i]->print() ;
}
}
unsigned int indices[3] ;
QuadTreeNode* children[4] ;
QuadTreeNode* parent ;
} ;
template <typename PFP>
class QuadTree
{
public:
std::vector<QuadTreeNode<PFP>*> roots ;
std::vector<QuadTreeNode*> roots ;
std::vector<Dart> darts ;
std::vector<unsigned int> verticesID ;
~QuadTree()
{
......@@ -183,11 +159,11 @@ public:
delete roots[i] ;
}
void embed(typename PFP::MAP& map, std::vector<unsigned int>& vID)
template <typename PFP>
void embed(typename PFP::MAP& map)
{
CellMarker cm(map, VERTEX) ;
for(unsigned int i = 0; i < roots.size(); ++i)
roots[i]->embed(map, darts[i], vID, cm, true) ;
roots[i]->embed<PFP>(map, darts[i], verticesID) ;
}
void print()
......@@ -201,6 +177,9 @@ public:
}
} ;
template <typename PFP>
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, QuadTree& qt) ;
} // namespace Import
} // namespace Algo
......
......@@ -39,7 +39,7 @@ inline void nextNonEmptyLine(std::ifstream& fp, std::string& line)
}
template <typename PFP>
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames)
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, QuadTree& qt)
{
AttributeHandler<typename PFP::VEC3> position = map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
......@@ -77,7 +77,8 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vecto
oss >> s ;
oss >> depth ;
}
std::cout << "MR depth -> " << depth << std::endl ;
std::cout << " MR depth -> " << depth << std::endl ;
// read vertices
nextNonEmptyLine(fp, line) ;
......@@ -88,7 +89,11 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vecto
return false ;
}
std::vector<unsigned int> verticesID ;
std::cout << " Read vertices.." << std::flush ;
qt.roots.clear() ;
qt.darts.clear() ;
qt.verticesID.clear() ;
nextNonEmptyLine(fp, line) ;
while(line.rfind("Triangles") == std::string::npos)
......@@ -106,14 +111,18 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vecto
unsigned int id = container.insertLine() ;
position[id] = pos ;
verticesID.push_back(id) ;
qt.verticesID.push_back(id) ;
nextNonEmptyLine(fp, line) ;
}
QuadTree<PFP> qt ;
QuadTreeNode<PFP>* current = NULL ;
unsigned int prevNum = -1 ;
std::cout << "..done (nb vertices -> " << qt.verticesID.size() << ")" << std::endl ;
std::cout << " Read triangles (build quadtree).." << std::flush ;
QuadTreeNode* current = NULL ;
unsigned int currentLevel = -1 ;
std::vector<unsigned int> lastNum ;
lastNum.resize(depth + 1) ;
nextNonEmptyLine(fp, line) ;
while(line.rfind("end") == std::string::npos)
......@@ -133,17 +142,18 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vecto
if(root == 1)
{
assert(num == 0) ;
QuadTreeNode<PFP>* n = new QuadTreeNode<PFP>() ;
QuadTreeNode* n = new QuadTreeNode() ;
n->indices[0] = idx0 ;
n->indices[1] = idx1 ;
n->indices[2] = idx2 ;
qt.roots.push_back(n) ;
current = n ;
prevNum = 0 ;
currentLevel = 0 ;
lastNum[0] = 0 ;
}
else
{
if(num == prevNum + 1) // on lit un autre triangle du même niveau
if(num == lastNum[currentLevel] + 1) // on lit un autre triangle du même niveau
{
current = current->parent->children[num] ;
}
......@@ -153,25 +163,33 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vecto
{
current->subdivide() ;
current = current->children[0] ;
++currentLevel ;
}
else // on remonte d'un niveau
{
assert(prevNum == 3) ;
assert(current->parent->parent != NULL) ;
current = current->parent->parent->children[num] ;
assert(lastNum[currentLevel] == 3) ;
do
{