Commit 1a280155 authored by untereiner's avatar untereiner

Merge cgogn:~thery/CGoGN

parents 88d5cd96 e8672e4d
......@@ -35,7 +35,8 @@ ObjView::ObjView():
m_texcoordVBO(NULL),
m_shader(NULL),
m_shader2(NULL),
m_RenderStyle(2)
m_RenderStyle(2),
m_currentGroupDrawn(0xffffffff)
{}
ObjView::~ObjView()
......@@ -69,6 +70,23 @@ void ObjView::cb_keyPress(int k)
case 't':
m_RenderStyle=2;
break;
case 'o':
m_currentGroupDrawn=0xffffffff;
break;
case 'O':
m_currentGroupDrawn=0;
std::cout << "Group "<< m_obj.objGroupName(m_currentGroupDrawn)<< std::endl;
break;
case '-':
m_currentGroupDrawn--;
std::cout << "Group "<< m_obj.objGroupName(m_currentGroupDrawn)<< std::endl;
break;
case '+':
m_currentGroupDrawn++;
std::cout << "Group "<< m_obj.objGroupName(m_currentGroupDrawn)<< std::endl;
break;
default:
break;
}
......@@ -81,6 +99,8 @@ void ObjView::cb_initGL()
// choose to use GL version 2
Utils::GLSLShader::setCurrentOGLVersion(2);
m_dr = new Utils::Drawer;
// create VBO for position
m_positionVBO = new Utils::VBO;
m_texcoordVBO = new Utils::VBO;
......@@ -105,22 +125,130 @@ void ObjView::cb_initGL()
m_obj.createGroupMatVBO_PTN(m_positionVBO,m_texcoordVBO,m_normalVBO);
}
void ObjView::drawBB( const Geom::BoundingBox<VEC3>& bb)
{
const VEC3& mi = bb.min();
const VEC3& ma = bb.max();
m_dr->newList(GL_COMPILE_AND_EXECUTE);
m_dr->lineWidth(3.0f);
m_dr->begin(GL_LINE_LOOP);
m_dr->color3f(1.0f,1.0f,0.0f);
m_dr->vertex3f(mi[0],mi[1],mi[2]);
m_dr->vertex3f(ma[0],mi[1],mi[2]);
m_dr->vertex3f(ma[0],ma[1],mi[2]);
m_dr->vertex3f(mi[0],ma[1],mi[2]);
m_dr->end();
m_dr->begin(GL_LINE_LOOP);
m_dr->color3f(1.0f,1.0f,0.0f);
m_dr->vertex3f(mi[0],mi[1],ma[2]);
m_dr->vertex3f(ma[0],mi[1],ma[2]);
m_dr->vertex3f(ma[0],ma[1],ma[2]);
m_dr->vertex3f(mi[0],ma[1],ma[2]);
m_dr->end();
m_dr->begin(GL_LINES);
m_dr->color3f(1.0f,1.0f,0.0f);
m_dr->vertex3f(mi[0],mi[1],mi[2]);
m_dr->vertex3f(mi[0],mi[1],ma[2]);
m_dr->vertex3f(mi[0],ma[1],mi[2]);
m_dr->vertex3f(mi[0],ma[1],ma[2]);
m_dr->vertex3f(ma[0],ma[1],mi[2]);
m_dr->vertex3f(ma[0],ma[1],ma[2]);
m_dr->vertex3f(ma[0],mi[1],mi[2]);
m_dr->vertex3f(ma[0],mi[1],ma[2]);
m_dr->end();
m_dr->endList();
}
void ObjView::cb_redraw()
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
unsigned int nb = m_obj.nbMatGroups();
const std::vector<Algo::Surface::Import::MaterialOBJ*>& mats = m_obj.getMaterials();
unsigned int nb = m_obj.nbObjGroups();
// const std::vector<Algo::Surface::Import::MaterialOBJ*>& mats = m_obj.getMaterials();
if (m_currentGroupDrawn<(nb-1))
{
std::cout << "Draw Object "<< m_currentGroupDrawn << std::endl;
unsigned int i = m_currentGroupDrawn;
drawBB(m_obj.getGroupBB(i));
std::cout << "BB drawn" << std::endl;
switch(m_RenderStyle)
{
case 0: // MONO
for (unsigned int j=0; j<m_obj.nbSubGroup(i);++j)
{
Geom::Vec4f v(0.2f,1.0f,0.4f,0.0f); // color here green
m_phongShader->setAmbiant(0.2f*v) ;
m_phongShader->setDiffuse(v) ;
m_phongShader->setSpecular(v) ;
m_phongShader->setShininess(10000.0) ;
m_phongShader->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_phongShader->disableVertexAttribs();
}
break;
case 1: // COLOR
for (unsigned int j=0; j<m_obj.nbSubGroup(i);++j)
{
const Algo::Surface::Import::MaterialOBJ* mat = m_obj.materialOf(i,j);
Geom::Vec4f v(mat->diffuseColor[0],mat->diffuseColor[1],mat->diffuseColor[2],0.0f);
m_phongShader->setAmbiant(0.2f*v) ;
m_phongShader->setDiffuse(v) ;
m_phongShader->setSpecular(v) ;
m_phongShader->setShininess(10000.0) ;
m_phongShader->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_phongShader->disableVertexAttribs();
}
default:
for (unsigned int j=0; j<m_obj.nbSubGroup(i);++j)
{
const Algo::Surface::Import::MaterialOBJ* mat = m_obj.materialOf(i,j);
if (mat->textureDiffuse != NULL)
{
m_shader2->setTexture(mat->textureDiffuse);
m_shader2->setShininess(mat->shininess);
m_shader2->setAmbient(0.8f);
m_shader2->activeTexture();
m_shader2->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_shader2->disableVertexAttribs();
}
else
{
Geom::Vec4f v;
v[0] = 0.5f; v[1] = 0.5f; v[2] = 0.5f; v[3] = 0.0f;
m_phongShader->setAmbiant(v) ;
v[0] = mat->diffuseColor[0]; v[1] = mat->diffuseColor[1]; v[2] = mat->diffuseColor[2]; v[3] = 0.0f;
m_phongShader->setDiffuse(v) ;
v[0] = mat->specularColor[0]; v[1] = mat->specularColor[1]; v[2] = mat->specularColor[2]; v[3] = 0.0f;
m_phongShader->setSpecular(v) ;
m_phongShader->setShininess(mat->shininess) ;
m_phongShader->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_phongShader->disableVertexAttribs();
}
}
}
}
else
for (unsigned int i=0; i<nb; ++i)
{
drawBB(m_obj.getGroupBB(i));
switch(m_RenderStyle)
{
case 0: // MONO
{
for (unsigned int j=0; j<m_obj.nbSubGroup(i);++j)
{
Geom::Vec4f v(0.2f,1.0f,0.4f,0.0f); // color here green
m_phongShader->setAmbiant(0.2f*v) ;
m_phongShader->setDiffuse(v) ;
......@@ -128,33 +256,39 @@ void ObjView::cb_redraw()
m_phongShader->setSpecular(v) ;
m_phongShader->setShininess(10000.0) ;
m_phongShader->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i), m_obj.nbIndices(i));
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_phongShader->disableVertexAttribs();
}
break;
case 1: // COLOR
{
Geom::Vec4f v(mats[i]->diffuseColor[0],mats[i]->diffuseColor[1],mats[i]->diffuseColor[2],0.0f);
for (unsigned int j=0; j<m_obj.nbSubGroup(i);++j)
{
const Algo::Surface::Import::MaterialOBJ* mat = m_obj.materialOf(i,j);
Geom::Vec4f v(mat->diffuseColor[0],mat->diffuseColor[1],mat->diffuseColor[2],0.0f);
m_phongShader->setAmbiant(0.2f*v) ;
m_phongShader->setDiffuse(v) ;
// v[0] = 1.0f; v[1] = 1.0f; v[2] = 1.0f; v[3] = 0.0f; // use this for specular effected
m_phongShader->setSpecular(v) ;
m_phongShader->setShininess(10000.0) ;
m_phongShader->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i), m_obj.nbIndices(i));
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_phongShader->disableVertexAttribs();
}
default:
{
if (mats[i]->textureDiffuse != NULL)
for (unsigned int j=0; j<m_obj.nbSubGroup(i);++j)
{
const Algo::Surface::Import::MaterialOBJ* mat = m_obj.materialOf(i,j);
if (mat->textureDiffuse != NULL)
{
m_shader2->setTexture(mats[i]->textureDiffuse);
m_shader2->setShininess(mats[i]->shininess);
m_shader2->setTexture(mat->textureDiffuse);
m_shader2->setShininess(mat->shininess);
m_shader2->setAmbient(0.8f);
m_shader2->activeTexture();
m_shader2->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i), m_obj.nbIndices(i));
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_shader2->disableVertexAttribs();
}
else
......@@ -162,13 +296,13 @@ void ObjView::cb_redraw()
Geom::Vec4f v;
v[0] = 0.5f; v[1] = 0.5f; v[2] = 0.5f; v[3] = 0.0f;
m_phongShader->setAmbiant(v) ;
v[0] = mats[i]->diffuseColor[0]; v[1] = mats[i]->diffuseColor[1]; v[2] = mats[i]->diffuseColor[2]; v[3] = 0.0f;
v[0] = mat->diffuseColor[0]; v[1] = mat->diffuseColor[1]; v[2] = mat->diffuseColor[2]; v[3] = 0.0f;
m_phongShader->setDiffuse(v) ;
v[0] = mats[i]->specularColor[0]; v[1] = mats[i]->specularColor[1]; v[2] = mats[i]->specularColor[2]; v[3] = 0.0f;
v[0] = mat->specularColor[0]; v[1] = mat->specularColor[1]; v[2] = mat->specularColor[2]; v[3] = 0.0f;
m_phongShader->setSpecular(v) ;
m_phongShader->setShininess(mats[i]->shininess) ;
m_phongShader->setShininess(mat->shininess) ;
m_phongShader->enableVertexAttribs();
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i), m_obj.nbIndices(i));
glDrawArrays(GL_TRIANGLES, m_obj.beginIndex(i,j), m_obj.nbIndices(i,j));
m_phongShader->disableVertexAttribs();
}
}
......
......@@ -30,6 +30,7 @@
//#include "Utils/Qt/qtSimple.h"
#include "Utils/Qt/qtQGLV.h"
#include "Utils/textures.h"
#include "Utils/drawer.h"
#include "Utils/Shaders/shaderSimpleTexture.h"
#include "Utils/Shaders/shaderPhongTexture.h"
#include "Utils/Shaders/shaderPhong.h"
......@@ -66,6 +67,10 @@ public:
MAP myMap ;
Algo::Surface::Import::OBJModel<PFP> m_obj;
Utils::Drawer* m_dr;
unsigned int m_currentGroupDrawn;
void drawBB( const Geom::BoundingBox<VEC3>& bb);
// VBO
Utils::VBO* m_positionVBO;
Utils::VBO* m_normalVBO;
......
......@@ -30,6 +30,17 @@ QT4_WRAP_CPP(tilings_moc tilings.h)
add_executable(tilings tilings.cpp ${tilings_moc})
target_link_libraries(tilings ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS})
QT4_WRAP_UI( test_traversor2_ui test_traversor2.ui )
QT4_WRAP_CPP(test_traversor2_moc test_traversor2.h)
add_executable(test_traversor2 test_traversor2.cpp ${test_traversor2_ui} ${test_traversor2_moc})
target_link_libraries(test_traversor2 ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS})
QT4_WRAP_UI( testPlaneCutting_ui testPlaneCutting.ui )
QT4_WRAP_CPP(testPlaneCutting_moc testPlaneCutting.h)
add_executable(testPlaneCutting testPlaneCutting.cpp ${testPlaneCutting_ui} ${testPlaneCutting_moc})
target_link_libraries(testPlaneCutting ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS})
# Example with Qt
#
#QT4_WRAP_CPP(tuto1_moc tuto1.h)
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009, 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 "testPlaneCutting.h"
#include "Algo/Geometry/distances.h"
#include "Algo/Modelisation/subdivision.h"
#include "Utils/chrono.h"
#include "Algo/Modelisation/planeCutting.h"
Viewer::Viewer() :
m_renderStyle(FLAT),
m_drawVertices(false),
m_drawEdges(false),
m_drawFaces(true),
m_drawNormals(false),
m_drawTopo(false),
m_drawBoundaryTopo(true),
m_render(NULL),
m_phongShader(NULL),
m_flatShader(NULL),
m_vectorShader(NULL),
m_simpleColorShader(NULL),
m_pointSprite(NULL)
{
normalScaleFactor = 1.0f ;
vertexScaleFactor = 0.1f ;
faceShrinkage = 1.0f ;
colClear = Geom::Vec4f(0.2f, 0.2f, 0.2f, 0.1f) ;
colDif = Geom::Vec4f(0.8f, 0.9f, 0.7f, 1.0f) ;
colSpec = Geom::Vec4f(0.9f, 0.9f, 0.9f, 1.0f) ;
colNormal = Geom::Vec4f(1.0f, 0.0f, 0.0f, 1.0f) ;
shininess = 80.0f ;
}
void Viewer::initGUI()
{
setDock(&dock) ;
dock.check_drawVertices->setChecked(false) ;
dock.check_drawEdges->setChecked(false) ;
dock.check_drawFaces->setChecked(true) ;
dock.check_drawNormals->setChecked(false) ;
dock.slider_verticesSize->setVisible(false) ;
dock.slider_normalsSize->setVisible(false) ;
dock.slider_verticesSize->setSliderPosition(50) ;
dock.slider_normalsSize->setSliderPosition(50) ;
setCallBack( dock.check_drawVertices, SIGNAL(toggled(bool)), SLOT(slot_drawVertices(bool)) ) ;
setCallBack( dock.slider_verticesSize, SIGNAL(valueChanged(int)), SLOT(slot_verticesSize(int)) ) ;
setCallBack( dock.check_drawEdges, SIGNAL(toggled(bool)), SLOT(slot_drawEdges(bool)) ) ;
setCallBack( dock.check_drawFaces, SIGNAL(toggled(bool)), SLOT(slot_drawFaces(bool)) ) ;
setCallBack( dock.combo_faceLighting, SIGNAL(currentIndexChanged(int)), SLOT(slot_faceLighting(int)) ) ;
setCallBack( dock.check_drawTopo, SIGNAL(toggled(bool)), SLOT(slot_drawTopo(bool)) ) ;
setCallBack( dock.check_drawNormals, SIGNAL(toggled(bool)), SLOT(slot_drawNormals(bool)) ) ;
setCallBack( dock.slider_normalsSize, SIGNAL(valueChanged(int)), SLOT(slot_normalsSize(int)) ) ;
}
void Viewer::cb_initGL()
{
Utils::GLSLShader::setCurrentOGLVersion(2) ;
m_render = new Algo::Render::GL2::MapRender() ;
m_topoRender = new Algo::Render::GL2::TopoRender() ;
m_topoRender->setInitialDartsColor(0.25f, 0.25f, 0.25f) ;
m_positionVBO = new Utils::VBO() ;
m_normalVBO = new Utils::VBO() ;
m_phongShader = new Utils::ShaderPhong() ;
m_phongShader->setAttributePosition(m_positionVBO) ;
m_phongShader->setAttributeNormal(m_normalVBO) ;
m_phongShader->setAmbiant(colClear) ;
m_phongShader->setDiffuse(colDif) ;
m_phongShader->setSpecular(colSpec) ;
m_phongShader->setShininess(shininess) ;
m_flatShader = new Utils::ShaderFlat() ;
m_flatShader->setAttributePosition(m_positionVBO) ;
m_flatShader->setAmbiant(colClear) ;
m_flatShader->setDiffuse(colDif) ;
m_flatShader->setExplode(faceShrinkage) ;
m_vectorShader = new Utils::ShaderVectorPerVertex() ;
m_vectorShader->setAttributePosition(m_positionVBO) ;
m_vectorShader->setAttributeVector(m_normalVBO) ;
m_vectorShader->setColor(colNormal) ;
m_simpleColorShader = new Utils::ShaderSimpleColor() ;
m_simpleColorShader->setAttributePosition(m_positionVBO) ;
Geom::Vec4f c(0.0f, 0.0f, 0.0f, 1.0f) ;
m_simpleColorShader->setColor(c) ;
m_pointSprite = new Utils::PointSprite() ;
m_pointSprite->setAttributePosition(m_positionVBO) ;
m_pointSprite->setColor(Geom::Vec4f(0.0f, 0.0f, 1.0f, 1.0f)) ;
registerShader(m_phongShader) ;
registerShader(m_flatShader) ;
registerShader(m_vectorShader) ;
registerShader(m_simpleColorShader) ;
registerShader(m_pointSprite) ;
}
void Viewer::cb_redraw()
{
if(m_drawVertices)
{
m_pointSprite->setSize(vertexScaleFactor) ;
m_render->draw(m_pointSprite, Algo::Render::GL2::POINTS) ;
}
if(m_drawEdges)
{
glLineWidth(1.0f) ;
m_render->draw(m_simpleColorShader, Algo::Render::GL2::LINES) ;
}
if(m_drawFaces)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ;
glEnable(GL_LIGHTING) ;
glEnable(GL_POLYGON_OFFSET_FILL) ;
glPolygonOffset(1.0f, 1.0f) ;
switch(m_renderStyle)
{
case FLAT :
m_flatShader->setExplode(faceShrinkage) ;
m_render->draw(m_flatShader, Algo::Render::GL2::TRIANGLES) ;
break ;
case PHONG :
m_render->draw(m_phongShader, Algo::Render::GL2::TRIANGLES) ;
break ;
}
glDisable(GL_POLYGON_OFFSET_FILL) ;
}
if(m_drawTopo)
{
m_topoRender->drawTopo() ;
}
if(m_drawNormals)
{
float size = normalBaseSize * normalScaleFactor ;
m_vectorShader->setScale(size) ;
glLineWidth(1.0f) ;
m_render->draw(m_vectorShader, Algo::Render::GL2::POINTS) ;
}
}
void Viewer::cb_Open()
{
std::string filters("all (*.*);; trian (*.trian);; ctm (*.ctm);; off (*.off);; ply (*.ply)") ;
std::string filename = selectFile("Open Mesh", "", filters) ;
if (filename.empty())
return ;
importMesh(filename) ;
updateGL() ;
}
void Viewer::cb_Save()
{
std::string filters("all (*.*);; map (*.map);; off (*.off);; ply (*.ply)") ;
std::string filename = selectFileSave("Save Mesh", "", filters) ;
if (!filename.empty())
exportMesh(filename) ;
}
void Viewer::cb_keyPress(int keycode)
{
switch(keycode)
{
case 'c' :
myMap.check();
break;
case 'p':
{
std::cout << "PlaneCut"<< std::endl;
Geom::Vec3f n(0.1,0.1,1.0);
Geom::Vec3f o = bb.center();
Geom::Plane3D<PFP::REAL> plan(n,o);
CellMarker<FACE> over(myMap);
Algo::Surface::Modelisation::planeCut<PFP>(myMap, position, plan, over, false,true);
std::cout << "PlaneCut Ok"<< std::endl;
n *= bb.diagSize()/20.0f;
TraversorV<PFP::MAP> trav(myMap);
for (Dart d=trav.begin(); d!=trav.end(); d=trav.next())
{
if (over.isMarked(d))
position[d]+= n;
}
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::TRIANGLES) ;
Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
m_positionVBO->updateData(position) ;
m_normalVBO->updateData(normal) ;
m_topoRender->updateData<PFP>(myMap, position, 0.85f, 0.85f, m_drawBoundaryTopo) ;
updateGL();
}
break;
case 'd':
{
Utils::Chrono ch;
ch.start();
VEC3 P(0.6f,0.55f,0.51f);
float dist = 10000.0f;
TraversorF<PFP::MAP> trav(myMap);
unsigned int nb=0;
for (Dart d=trav.begin(); d != trav.end(); d=trav.next())
{
nb++;
float d2 = Algo::Geometry::squaredDistancePoint2Face<PFP>(myMap,d,position,P);
if (d2<dist)
dist = d2;
}
std::cout << "Dist="<< sqrt(dist) << " of "<< nb << "faces in "<< ch.elapsed()<< " ms"<< std::endl;
}
break;
default:
break;
}
}
void Viewer::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<VEC3, VERTEX>("position") ;
}
else
{
std::vector<std::string> attrNames ;
if(!Algo::Surface::Import::importMesh<PFP>(myMap, filename.c_str(), attrNames))
{
CGoGNerr << "could not import " << filename << CGoGNendl ;
return;
}
position = myMap.getAttribute<PFP::VEC3, VERTEX>(attrNames[0]) ;
}
// myMap.enableQuickTraversal<VERTEX>() ;
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::TRIANGLES) ;
m_topoRender->updateData<PFP>(myMap, position, 0.85f, 0.85f, m_drawBoundaryTopo) ;
bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
normalBaseSize = bb.diagSize() / 100.0f ;
// vertexBaseSize = normalBaseSize / 5.0f ;
normal = myMap.getAttribute<VEC3, VERTEX>("normal") ;
if(!normal.isValid())
normal = myMap.addAttribute<VEC3, VERTEX>("normal") ;
Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
m_positionVBO->updateData(position) ;
m_normalVBO->updateData(normal) ;
setParamObject(bb.maxSize(), bb.center().data()) ;
updateGLMatrices() ;
}
void Viewer::exportMesh(std::string& filename, bool askExportMode)
{
<