Commit 2545895b authored by Kenneth Vanhoey's avatar Kenneth Vanhoey

Merge cgogn:~cgogn/CGoGN

parents 794eef45 ed815783
......@@ -189,14 +189,6 @@ void StageShader::importMesh(std::string& filename)
else
position = myMap.getAttribute<PFP::VEC3>(VERTEX , attrNames[0]) ;
}
else
{
position = myMap.addAttribute<PFP::VEC3>(VERTEX, "position");
Algo::Modelisation::Primitive3D<PFP> prim(myMap, position);
prim.hexaGrid_topo(10,10,10);
prim.embedHexaGrid(1.0f,1.0f,1.0f);
}
updateVBOprimitives(Algo::Render::GL2::TRIANGLES | Algo::Render::GL2::LINES | Algo::Render::GL2::POINTS) ;
......@@ -316,6 +308,13 @@ int main(int argc, char** argv)
std::string filename(argv[1]) ;
sqt.importMesh(filename) ;
}
else
{
sqt.position = sqt.myMap.addAttribute<PFP::VEC3>(VERTEX, "position");
Algo::Modelisation::Primitive3D<PFP> prim(sqt.myMap, sqt.position);
prim.hexaGrid_topo(10,10,10);
prim.embedHexaGrid(1.0f,1.0f,1.0f);
}
sqt.initGUI() ;
......
......@@ -32,7 +32,7 @@ namespace IHM
{
/***************************************************
* ATTRIBUTES MANAGEMENT *
* ATTRIBUTES MANAGEMENT *
***************************************************/
template <typename T>
......@@ -64,7 +64,7 @@ AttributeHandler_IHM<T> ImplicitHierarchicalMap3::getAttribute(unsigned int orbi
}
/***************************************************
* MAP TRAVERSAL *
* MAP TRAVERSAL *
***************************************************/
inline Dart ImplicitHierarchicalMap3::newDart()
......
......@@ -51,7 +51,7 @@ namespace Import
* @return a boolean indicating if import was successfull
*/
template <typename PFP>
bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind = ImportSurfacique::UNKNOWNSURFACE);
bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind = ImportSurfacique::UNKNOWNSURFACE, bool mergeCloseVertices=false);
/**
* import a volumic mesh
......
......@@ -115,6 +115,8 @@ public:
bool importCTM(const std::string& filename, std::vector<std::string>& attrNames);
bool importASSIMP(const std::string& filename, std::vector<std::string>& attrNames);
bool mergeCloseVertices();
/**
* @param container container of vertex orbite
......
......@@ -23,6 +23,8 @@
*******************************************************************************/
#include "Algo/Import/importPlyData.h"
#include "Algo/Geometry/boundingbox.h"
#include "Topology/generic/autoAttributeHandler.h"
#include "openctm.h"
......@@ -433,7 +435,7 @@ bool MeshTablesSurface<PFP>::importObj(const std::string& filename, std::vector<
m_emb.reserve(verticesID.size()*8);
std::vector<int> table;
table.reserve(64); // 64 cotes pour une face devrait suffire
table.reserve(64); // NBV cotes pour une face devrait suffire
m_nbFaces = 0;
do
{
......@@ -931,6 +933,158 @@ bool MeshTablesSurface<PFP>::importASSIMP(const std::string& filename, std::vect
return true;
}
template<typename PFP>
bool MeshTablesSurface<PFP>::mergeCloseVertices()
{
const unsigned int NBV=64; // seems to be good
const int NEIGH[27]={
-NBV*NBV - NBV - 1, -NBV*NBV - NBV, -NBV*NBV - NBV + 1,
-NBV*NBV - 1, -NBV*NBV, -NBV*NBV + 1,
-NBV*NBV + NBV - 1, -NBV*NBV + NBV, - NBV*NBV + NBV + 1,
-NBV - 1, - NBV, -NBV + 1,
-1, 0, 1,
NBV - 1, NBV, NBV + 1,
NBV*NBV - NBV - 1, NBV*NBV - NBV, NBV*NBV - NBV + 1,
NBV*NBV - 1, NBV*NBV, NBV*NBV + 1,
NBV*NBV + NBV - 1, NBV*NBV + NBV, NBV*NBV + NBV + 1};
std::vector<unsigned int>** grid;
grid = new std::vector<unsigned int>*[NBV*NBV*NBV];
// init grid with null ptrs
for (unsigned int i=0; i<NBV*NBV*NBV; ++i)
grid[i]=NULL;
AttributeHandler<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position");
// compute BB
Geom::BoundingBox<typename PFP::VEC3> bb(positions[ positions.begin() ]) ;
for (unsigned int i = positions.begin(); i != positions.end(); positions.next(i))
{
bb.addPoint(positions[i]) ;
}
// add one voxel around to avoid testing
typename PFP::VEC3 bbsize = (bb.max() - bb.min());
typename PFP::VEC3 one = bbsize/(NBV-2);
one*= 1.001f;
bb.addPoint( bb.min() - one);
bb.addPoint( bb.max() + one);
bbsize = (bb.max() - bb.min());
AutoAttributeHandler<unsigned int> gridIndex(m_map,VERTEX, "gridIndex");
AutoAttributeHandler<unsigned int> newIndices(m_map,VERTEX, "newIndices");
// Store each vertex in the grid and store voxel index in vertex attribute
for (unsigned int i = positions.begin(); i != positions.end(); positions.next(i))
{
typename PFP::VEC3 P = positions[i];
P -= bb.min();
float pz = floor((P[2]/bbsize[2])*NBV);
float py = floor((P[1]/bbsize[1])*NBV);
float px = floor((P[0]/bbsize[0])*NBV);
unsigned int index = NBV*NBV*pz + NBV*py + px;
if (pz==63)
std::cout << "z 63 bb:"<<bb<<" P="<<positions[i]<< std::endl;
std::vector<unsigned int>* vox = grid[index];
if (vox==NULL)
{
grid[index] = new std::vector<unsigned int>();
grid[index]->reserve(8);
vox = grid[index];
}
vox->push_back(i);
gridIndex[i] = index;
newIndices[i] = 0xffffffff;
}
// compute EPSILON: average length of 50 of 100 first edges of first faces divide by 10000
int nb = 100;
if (m_nbEdges.size()< 100)
nb = m_nbEdges.size();
int k=0;
typename PFP::REAL d=0;
for (int i=0; i< nb; i+=2)
{
typename PFP::VEC3 e1 = positions[m_emb[k+1]] - positions[m_emb[k]];
d += e1.norm();
k += m_nbEdges[i];
}
d /= float(nb/2);
typename PFP::REAL EPSILON = d/10000.0f;
// traverse vertices
for (unsigned int i = positions.begin(); i != positions.end(); positions.next(i))
{
if (newIndices[i] == 0xffffffff)
{
const typename PFP::VEC3& P = positions[i];
for (unsigned int n=0; n<27; ++n)
{
std::vector<unsigned int>* voxel = grid[gridIndex[i]+NEIGH[n]];
if (voxel != NULL)
{
for (std::vector<unsigned int>::iterator v = voxel->begin(); v != voxel->end(); ++v)
{
if ((*v != i) && (*v != 0xffffffff))
{
typename PFP::VEC3 Q = positions[*v];
Q -= P;
typename PFP::REAL d2 = Q*Q;
if (d2 < EPSILON*EPSILON)
{
newIndices[*v] = i;
*v = 0xffffffff;
}
}
}
}
}
}
}
// update faces indices
for (std::vector<unsigned int>::iterator it = m_emb.begin(); it != m_emb.end(); ++it)
{
if (newIndices[*it] != 0xffffffff)
{
*it = newIndices[*it];
}
}
// delete embeddings
AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
for (unsigned int i = positions.begin(); i != positions.end(); positions.next(i))
{
if (newIndices[i] != 0xffffffff)
{
container.removeLine(i);
}
}
// release grid memory
for (unsigned int i=0; i<NBV*NBV*NBV; ++i)
if (grid[i]!=NULL)
delete grid[i];
delete[] grid;
return true;
}
} // namespace Import
} // namespace Algo
......
......@@ -425,12 +425,15 @@ bool importMesh(typename PFP::MAP& map, MeshTablesVolume<PFP>& mtv)
}
template <typename PFP>
bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind)
bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind, bool mergeCloseVertices)
{
MeshTablesSurface<PFP> mts(map);
if(!mts.importMesh(filename, attrNames, kind))
return false;
if (mergeCloseVertices)
mts.mergeCloseVertices();
return importMesh<PFP>(map, mts);
}
......
......@@ -170,7 +170,7 @@ void verticesRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& pos
* @param map the map we want to test
* @param rayA first point of ray (user side)
* @param rayAB vector of ray (directed ot the scene)
* @param vertex (out) dart of selected vertex (set to map.end() if no vertex selected)
* @param vertex (out) dart of selected vertex (set to NIL if no vertex selected)
*/
template<typename PFP>
void vertexRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::VEC3& rayA, const typename PFP::VEC3& rayAB, Dart& vertex, const FunctorSelect& good = SelectorTrue())
......@@ -191,9 +191,8 @@ void vertexRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& posit
distnint.resize(nbi);
for (unsigned int i = 0; i < nbi; ++i)
{
distnint[i].first = (iPoints[i] - rayA).norm2();
distnint[i].second = i;
typename PFP::VEC3 V = iPoints[i] - rayA;
distnint[i].first = V.norm2();
}
// sort the vector of pair dist/dart
......@@ -207,6 +206,7 @@ void vertexRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& posit
Dart d = vecFaces[first];
Dart it = d;
typename PFP::REAL minDist = (ip - position[it]).norm2();
vertex = it;
it = map.phi1(it);
while(it != d)
{
......@@ -220,7 +220,7 @@ void vertexRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& posit
}
}
else
vertex = map.end();
vertex = NIL;
}
/**
......
......@@ -33,8 +33,8 @@
#include <vector>
#include <map>
#include "Container/attributeContainer.h"
#include "Topology/generic/dart.h"
#include "Topology/generic/marker.h"
#include "Topology/generic/functor.h"
......
......@@ -55,10 +55,13 @@ class SimpleQT : public QMainWindow
public:
SimpleQT();
SimpleQT(const SimpleQT&) ;
virtual ~SimpleQT();
void operator=(const SimpleQT& v) ;
/**
* set the main widget of the dock
*/
......@@ -137,6 +140,13 @@ public:
// void contextMenuEvent(QContextMenuEvent *event);
/**
* set mouse tracking on the GLWidget
* if true : mouseMove events are generated for each mouse move
* if false : mouseMove events are only generated when a button is pressed
*/
void setGLWidgetMouseTracking(bool b);
protected:
GLWidget *m_glWidget;
......@@ -173,8 +183,6 @@ protected:
void keyReleaseEvent(QKeyEvent *e);
public:
void operator=(const SimpleQT& v) ;
/**
* set width and pos center of object to draw
*/
......@@ -317,7 +325,7 @@ public:
/**
* end of program, some things to clean ?
*/
virtual void cb_exit() { }
virtual void cb_exit() {}
/**
* Ask to Qt to update the GL widget.
......@@ -330,7 +338,6 @@ public:
*/
void updateGLMatrices();
/**
* apply rotation to transformation matrix
*/
......@@ -351,7 +358,6 @@ public:
*/
void pushTransfoMatrix();
/**
* pop the transfo matrix from stack
*/
......
......@@ -166,40 +166,6 @@ unsigned int ImplicitHierarchicalMap3::faceLevel(Dart d)
return fLevel ;
}
// Dart it = d ;
// Dart old = it ;
// unsigned int fLevel = edgeLevel(it) ;
// do
// {
// it = phi1(it) ;
// if(m_dartLevel[it] < m_dartLevel[old]) // in a first time, the level of a face
// old = it ; // is the minimum of the levels
// unsigned int l = edgeLevel(it) ; // of its edges
// fLevel = l < fLevel ? l : fLevel ;
// } while(it != d) ;
//
// unsigned int cur = m_curLevel ;
// m_curLevel = fLevel ;
//
// unsigned int nbSubd = 0 ;
// it = old ;
// unsigned int eId = m_edgeId[old] ; // the particular case of a face
// do // with all neighboring faces regularly subdivided
// { // but not the face itself
// ++nbSubd ; // is treated here
// it = phi1(it) ;
// } while(m_edgeId[it] == eId) ;
//
// while(nbSubd > 1)
// {
// nbSubd /= 2 ;
// --fLevel ;
// }
//
// m_curLevel = cur ;
//
// return fLevel ;
unsigned int ImplicitHierarchicalMap3::volumeLevel(Dart d)
{
......@@ -231,8 +197,6 @@ unsigned int ImplicitHierarchicalMap3::volumeLevel(Dart d)
{
Dart e = *face ;
//std::cout << "dart from face = " << e << std::endl;
// in a first time, the level of a face
//the level of the volume is the minimum of the
//levels of its faces
......@@ -298,7 +262,6 @@ unsigned int ImplicitHierarchicalMap3::volumeLevel(Dart d)
do
{
Dart ee = phi2(e) ;
//std::cout << "\t face a cote =" << ee << std::endl;
if(!mark.isMarked(ee)) // not already marked
{
visitedFaces.push_back(ee) ;
......@@ -308,7 +271,6 @@ unsigned int ImplicitHierarchicalMap3::volumeLevel(Dart d)
} while(e != *face) ;
}
//std::cout << "fin" << std::endl << std::endl;
//Second : the case of all faces regularly subdivided but not the volume itself
unsigned int cur = m_curLevel ;
......@@ -336,16 +298,6 @@ unsigned int ImplicitHierarchicalMap3::volumeLevel(Dart d)
return vLevel;
}
// unsigned int fLevel = faceLevel(e) ;
// vLevel = fLevel < vLevel ? fLevel : vLevel ;
//
// Dart old = faceOldestDart(e);
// if(m_dartLevel[old] < m_dartLevel[oldest])
// oldest = old ;
Dart ImplicitHierarchicalMap3::faceOldestDart(Dart d)
{
......
......@@ -40,8 +40,7 @@ namespace Utils
namespace QT
{
SimpleQT::SimpleQT():
m_dock(NULL)
SimpleQT::SimpleQT() : m_dock(NULL)
{
m_glWidget = new GLWidget(this);
setCentralWidget(m_glWidget);
......@@ -131,7 +130,8 @@ SimpleQT::~SimpleQT()
delete m_glWidget; // ??
}
void SimpleQT::operator=(const SimpleQT& sqt) {
void SimpleQT::operator=(const SimpleQT& sqt)
{
m_glWidget = new GLWidget(this);
setCentralWidget(m_glWidget) ;
......@@ -152,42 +152,48 @@ void SimpleQT::operator=(const SimpleQT& sqt) {
m_trans_z = sqt.m_trans_z ;
}
std::string SimpleQT::selectFile(const std::string& title, const std::string& dir, const std::string& filters)
void SimpleQT::setDock(QDockWidget *dock)
{
QString fileName = QFileDialog::getOpenFileName(this, tr(title.c_str()), tr(dir.c_str()), tr(filters.c_str()), 0, 0);
return fileName.toStdString();
m_dock = dock;
addDockWidget(Qt::RightDockWidgetArea, m_dock);
m_dock->show();
}
std::string SimpleQT::selectFileSave(const std::string& title, const std::string& dir, const std::string& filters)
QDockWidget* SimpleQT::dockWidget()
{
QString fileName = QFileDialog::getSaveFileName(this, tr(title.c_str()), tr(dir.c_str()), tr(filters.c_str()), 0, 0);
return fileName.toStdString();
return m_dock;
}
void SimpleQT::cb_about_cgogn()
void SimpleQT::setCallBack( const QObject* sender, const char* signal, const char* method)
{
QString str("CGoGN:\nCombinatorial and Geometric modeling\n"
"with Generic N-dimensional Maps\n"
"Web site: https://cgogn.u-strasbg.fr \n"
"Contact information: cgogn@unistra.fr");
QMessageBox::about(this, tr("About CGoGN"), str);
connect(sender, signal, this, method);
}
void SimpleQT::cb_about()
void SimpleQT::windowTitle(const char* windowTitle)
{
QMessageBox::about(this, tr("About App"), m_helpString.c_str());
setWindowTitle(tr(windowTitle));
}
void SimpleQT::setHelpMsg(const std::string& msg)
void SimpleQT::dockTitle(const char* dockTitle)
{
m_helpString = msg;
if (m_dock)
m_dock->setWindowTitle(tr(dockTitle));
}
void SimpleQT::glMousePosition(int& x, int& y)
void SimpleQT::statusMsg(const char* msg, int timeoutms)
{
QPoint xy = m_glWidget->mapFromGlobal(QCursor::pos());
x = xy.x();
y = m_glWidget->getHeight() - xy.y();
if (msg)
{
QString message = tr(msg);
statusBar()->showMessage(message,timeoutms);
}
else
{
if (statusBar()->isHidden())
statusBar()->show();
else
statusBar()->hide();
}
}
QDockWidget* SimpleQT::addEmptyDock()
......@@ -233,39 +239,30 @@ void SimpleQT::toggleVisibilityConsole()
m_dockConsole->hide();
}
void SimpleQT::windowTitle(const char* windowTitle)
void SimpleQT::add_menu_entry(const std::string label, const char* method)
{
setWindowTitle(tr(windowTitle));
QAction * action = new QAction(tr(label.c_str()), this);
connect(action, SIGNAL(triggered()), this, method);
m_appMenu->addAction(action);
}
void SimpleQT::dockTitle(const char* dockTitle)
void SimpleQT::init_app_menu()
{
if (m_dock)
m_dock->setWindowTitle(tr(dockTitle));
m_appMenu->clear();
}
void SimpleQT::statusMsg(const char* msg, int timeoutms)
void SimpleQT::setHelpMsg(const std::string& msg)
{
if (msg)
{
QString message = tr(msg);
statusBar()->showMessage(message,timeoutms);
}
else
{
if (statusBar()->isHidden())
statusBar()->show();
else
statusBar()->hide();
}
m_helpString = msg;
}
void SimpleQT::setCallBack( const QObject* sender, const char* signal, const char* method)
void SimpleQT::setGLWidgetMouseTracking(bool b)
{
connect(sender, signal, this, method);
m_glWidget->setMouseTracking(b);
}
void SimpleQT::closeEvent(QCloseEvent *event) {
void SimpleQT::closeEvent(QCloseEvent *event)
{
m_glWidget->closeEvent(event) ;
QWidget::closeEvent(event) ;
}
......@@ -283,7 +280,6 @@ void SimpleQT::keyPressEvent(QKeyEvent *e)
toggleVisibilityDock();
}
if (e->key() == Qt::Key_Escape)
close();
else
......@@ -297,51 +293,53 @@ void SimpleQT::keyReleaseEvent(QKeyEvent *e)
m_glWidget->keyReleaseEvent(e);
}
void SimpleQT::setDock(QDockWidget *dock)
void SimpleQT::glMousePosition(int& x, int& y)
{
m_dock = dock;
addDockWidget(Qt::RightDockWidgetArea, m_dock);
m_dock->show();
QPoint xy = m_glWidget->mapFromGlobal(QCursor::pos());
x = xy.x();
y = m_glWidget->getHeight() - xy.y();
}
QDockWidget* SimpleQT::dockWidget()
GLfloat SimpleQT::getOrthoScreenRay(int x, int y, Geom::Vec3f& rayA, Geom::Vec3f& rayB, int radius)
{
return m_dock;
}
// get Z from depth buffer
// int yy = m_glWidget->getHeight() - y;
int yy = y;
GLfloat depth;
glReadPixels(x, yy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
void SimpleQT::updateGL()
{
m_glWidget->updateGL();
}
glm::i32vec4 viewport;
glGetIntegerv(GL_VIEWPORT, &(viewport[0]));
void SimpleQT::updateGLMatrices()
{
m_glWidget->modelModified();
m_glWidget->updateGL();
}
glm::vec3 win(x, yy, 0.0f);
void SimpleQT::cb_updateMatrix()
{
if (GLSLShader::CURRENT_OGL_VERSION == 1)
{
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(m_projection_matrix));
glm::vec3 P = glm::unProject(win, m_modelView_matrix, m_projection_matrix, viewport);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(glm::value_ptr(m_modelView_matrix));
}
else
{
for(std::set< std::pair<void*, GLSLShader*> >::iterator it = GLSLShader::m_registeredShaders.begin();
it != GLSLShader::m_registeredShaders.end();
++it)
{
if ((it->first == NULL) || (it->first == this))
{
it->second->updateMatrices(m_projection_matrix, m_modelView_matrix);
}
}
}
rayA[0] = P[0];
rayA[1] = P[1];
rayA[2] = P[2];
win[2] = depth;
P = glm::unProject(win, m_modelView_matrix, m_projection_matrix, viewport);
rayB[0] = P[0];
rayB[1] = P[1];
rayB[2] = P[2