Commit 4040a77e authored by Sylvain Thery's avatar Sylvain Thery

Merge branch 'master' of cgogn:/home/maire/CGoGN

Conflicts:
	src/Utils/Shaders/shaderPhong.cpp
parents 78e96120 13e149b1
SET(EXECUTABLE_OUTPUT_PATH ${CGoGN_ROOT_DIR}/bin)
SET (COMMON_LIBS ${GLUT_LIBRARY} ${OPENGL_LIBRARY} ${GLEW_LIBRARY} ${DEVIL_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBXML2_LIBRARIES} gzstream AntTweakBar openctm assimp)
BOOST_LIBS(boost_regex_lib_lists "boost_regex-mt")
SET (COMMON_LIBS ${GLUT_LIBRARY} ${OPENGL_LIBRARY} ${GLEW_LIBRARY} ${DEVIL_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBXML2_LIBRARIES} ${boost_regex_lib_lists} gzstream AntTweakBar openctm assimp)
SET(CGoGN_LIBS_R topology algo container utils)
......
......@@ -59,3 +59,9 @@ add_executable( viewerD ../viewer.cpp ${viewer_moc} ${viewer_ui})
target_link_libraries( viewerD
${CGoGN_LIBS_D} ${NUMERICAL_LIBS} ${COMMON_LIBS} ${QT_LIBRARIES} )
QT4_WRAP_UI( clipping_ui ../clipping.ui )
QT4_WRAP_CPP( clipping_moc ../clipping.h )
add_executable( clippingD ../clipping.cpp ${clipping_ui} ${clipping_moc})
target_link_libraries( clippingD
${CGoGN_LIBS_D} ${COMMON_LIBS} ${QT_LIBRARIES} )
......@@ -63,3 +63,9 @@ add_executable( viewer ../viewer.cpp ${viewer_moc} ${viewer_ui})
target_link_libraries( viewer
${CGoGN_LIBS_R} ${NUMERICAL_LIBS} ${COMMON_LIBS} ${QT_LIBRARIES} )
QT4_WRAP_UI( clipping_ui ../clipping.ui )
QT4_WRAP_CPP( clipping_moc ../clipping.h )
add_executable( clipping ../clipping.cpp ${clipping_ui} ${clipping_moc})
target_link_libraries( clipping
${CGoGN_LIBS_D} ${COMMON_LIBS} ${QT_LIBRARIES} )
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2011, 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.u-strasbg.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#include "clipping.h"
#include "Utils/static_assert.h"
/*******************************************************************************
* MISCELLANOUS
*******************************************************************************/
void computeBasisFromVector(const Geom::Vec3f& vec1, Geom::Vec3f& vec2, Geom::Vec3f& vec3)
{
const float epsilon = 0.0001f;
// Check if the given vector length is acceptable
if (vec1.norm() < epsilon)
return;
// First take a non colinear second vector to cross product with vec1
// (by default (0.0, 0.0, 1.0)
Geom::Vec3f tempVec (0.0, 0.0, 1.0);
// Construct second vector, check other vectors non colinearity at the same time
vec2 = vec1 ^ tempVec;
float sinAngle = vec2.norm() / (vec1.norm() + tempVec.norm());
if (sinAngle < epsilon) // f:x->sin(x) ~ f:x->x when x ~ 0
{
tempVec = Geom::Vec3f (1.0, 0.0, 0.0);
vec2 = vec1 ^ tempVec;
}
// Get third vector
vec3 = vec1 ^ vec2;
}
/*******************************************************************************
* SLOTS
*******************************************************************************/
void Clipping::slot_drawTopo(bool b)
{
m_drawTopo = b;
updateGL();
}
void Clipping::slot_drawVertices(bool b)
{
m_drawVertices = b;
updateGL();
}
void Clipping::slot_drawLines(bool b)
{
m_drawLines = b;
updateGL();
}
void Clipping::slot_drawFaces(bool b)
{
m_drawFaces = b;
updateGL();
}
void Clipping::slot_explodTopoPhi1(double c)
{
m_coeffTopoExplod[0] = (float)c;
m_render_topo->updateData<PFP>(myMap, allDarts, position, m_coeffTopoExplod[0], m_coeffTopoExplod[1], m_coeffTopoExplod[2]);
updateGL();
}
void Clipping::slot_explodTopoPhi2(double c)
{
m_coeffTopoExplod[1] = (float)c;
m_render_topo->updateData<PFP>(myMap, allDarts, position, m_coeffTopoExplod[0], m_coeffTopoExplod[1], m_coeffTopoExplod[2]);
updateGL();
}
void Clipping::slot_explodTopoPhi3(double c)
{
m_coeffTopoExplod[2] = (float)c;
m_render_topo->updateData<PFP>(myMap, allDarts, position, m_coeffTopoExplod[0], m_coeffTopoExplod[1], m_coeffTopoExplod[2]);
updateGL();
}
void Clipping::slot_pushButton_addPlane()
{
// Create clipping and pickable objects
unsigned int newPlaneId = m_shader->addClipPlane();
Utils::Pickable* pickable = new Utils::Pickable(m_planeDrawable, newPlaneId);
m_pickablePlanes.push_back(pickable);
// Set params
m_shader->setClipPlaneParamsOrigin(newPlaneId, m_bb.center());
pickable->translate(m_bb.center());
pickable->scale(Geom::Vec3f(m_bb.maxSize()*0.5));
// Update shader sources edits
dock.vertexEdit->setPlainText(QString(m_shader->getVertexShaderSrc()));
dock.fragmentEdit->setPlainText(QString(m_shader->getFragmentShaderSrc()));
updateGLMatrices();
}
void Clipping::slot_spinBox_GridResolution(int i)
{
m_planeDrawable->updatePrecisionDrawing(i);
updateGL();
}
void Clipping::slot_pushButton_changePlanesColor()
{
QColor NewColor;
QColorDialog ColDialog;
NewColor = ColDialog.getColor();
int r, g, b;
NewColor.getRgb(&r, &g, &b);
m_planeDrawable->setColor(Geom::Vec4f((float)r/255.0, (float)g/255.0, (float)b/255.0, 1.0));
}
void Clipping::slot_pushButton_addSphere()
{
// Create clipping and pickable objects
unsigned int newSphereId = m_shader->addClipSphere();
Utils::Pickable* pickable = new Utils::Pickable(m_sphereDrawable, newSphereId);
m_pickableSpheres.push_back(pickable);
// Set params
m_shader->setClipSphereParamsCenter(newSphereId, m_bb.center());
m_shader->setClipSphereParamsRadius(newSphereId, (m_bb.maxSize())*0.5);
pickable->translate(m_bb.center());
pickable->scale(Geom::Vec3f(m_bb.maxSize()*0.5));
// Update shader sources edits
dock.vertexEdit->setPlainText(QString(m_shader->getVertexShaderSrc()));
dock.fragmentEdit->setPlainText(QString(m_shader->getFragmentShaderSrc()));
updateGLMatrices();
}
void Clipping::slot_spinBox_SphereResolution(int i)
{
m_sphereDrawable->updatePrecisionDrawing(i);
updateGL();
}
void Clipping::slot_pushButton_changeSpheresColor()
{
QColor NewColor;
QColorDialog ColDialog;
NewColor = ColDialog.getColor();
int r, g, b;
NewColor.getRgb(&r, &g, &b);
m_sphereDrawable->setColor(Geom::Vec4f((float)r/255.0, (float)g/255.0, (float)b/255.0, 1.0));
}
void Clipping::slot_doubleSpinBox_ColorAttenuationFactor(double c)
{
m_shader->setClipColorAttenuationFactorAbsolute((float)c);
updateGL();
}
void Clipping::slot_radioButton_ClippingMode(bool b)
{
if (b)
m_shader->setClipMode(Utils::ClippingShader::CLIPPING_MODE_AND);
else
m_shader->setClipMode(Utils::ClippingShader::CLIPPING_MODE_OR);
dock.vertexEdit->setPlainText(QString(m_shader->getVertexShaderSrc()));
dock.fragmentEdit->setPlainText(QString(m_shader->getFragmentShaderSrc()));
updateGLMatrices();
}
void Clipping::slot_radioButton_ColorAttenuationMode(bool b)
{
if (b)
m_shader->setClipColorAttenuationMode(Utils::ClippingShader::COLOR_ATTENUATION_MODE_LINEAR);
else
m_shader->setClipColorAttenuationMode(Utils::ClippingShader::COLOR_ATTENUATION_MODE_QUADRATIC);
dock.vertexEdit->setPlainText(QString(m_shader->getVertexShaderSrc()));
dock.fragmentEdit->setPlainText(QString(m_shader->getFragmentShaderSrc()));
updateGLMatrices();
}
void Clipping::slot_pushButton_deleteSelectedObject()
{
if (m_lastPickedObject)
{
// Delete clipping object
if (m_lastPickedObject->checkType<Utils::Grid>())
m_shader->deleteClipPlane(m_lastPickedObject->id());
else if (m_lastPickedObject->checkType<Utils::Sphere>())
m_shader->deleteClipSphere(m_lastPickedObject->id());
// Delete pickable
if (m_lastPickedObject->checkType<Utils::Grid>())
{
for (size_t i = 0; i < m_pickablePlanes.size(); i++)
{
if (m_pickablePlanes[i] == m_lastPickedObject)
{
delete m_pickablePlanes[i];
m_pickablePlanes.erase(m_pickablePlanes.begin() + i);
}
}
}
else if (m_lastPickedObject->checkType<Utils::Sphere>())
{
for (size_t i = 0; i < m_pickableSpheres.size(); i++)
{
if (m_pickableSpheres[i] == m_lastPickedObject)
{
delete m_pickableSpheres[i];
m_pickableSpheres.erase(m_pickableSpheres.begin() + i);
}
}
}
m_lastPickedObject = NULL;
// Update shader sources edits
dock.vertexEdit->setPlainText(QString(m_shader->getVertexShaderSrc()));
dock.fragmentEdit->setPlainText(QString(m_shader->getFragmentShaderSrc()));
updateGLMatrices();
}
}
void Clipping::slot_pushButton_applyClippingPreset()
{
// Create and apply preset
Utils::ClippingPreset *preset = NULL;
switch (dock.comboBox_ClippingPresets->currentIndex())
{
case 0 : // Dual planes
{
using namespace CGoGN::Utils::QT;
double centerX = (double)m_bb.center()[0];
double centerY = (double)m_bb.center()[1];
double centerZ = (double)m_bb.center()[2];
double size = (double)m_bb.maxSize()*0.75;
int axis = 0;
bool facing = false;
if (inputValues(VarDbl(centerX - 100.0, centerX + 100.0, centerX, "Center X",
VarDbl(centerY - 100.0, centerY + 100.0, centerY, "Center Y",
VarDbl(centerZ - 100.0, centerZ + 100.0, centerZ, "Center Z",
VarDbl(size - 100.0, size + 100.0, size, "Size",
VarSlider(0, 2, axis, "Axis",
VarBool(facing, "Facing"
)))))), "Preset Setup"))
preset = Utils::ClippingPreset::CreateDualPlanesPreset(Geom::Vec3f((float)centerX, (float)centerY, (float)centerZ), (float)size, axis, facing);
}
break;
case 1 : // Cube
{
using namespace CGoGN::Utils::QT;
double centerX = (double)m_bb.center()[0];
double centerY = (double)m_bb.center()[1];
double centerZ = (double)m_bb.center()[2];
double size = (double)m_bb.maxSize()*0.75;
bool facing = false;
if (inputValues(VarDbl(centerX - 100.0, centerX + 100.0, centerX, "Center X",
VarDbl(centerY - 100.0, centerY + 100.0, centerY, "Center Y",
VarDbl(centerZ - 100.0, centerZ + 100.0, centerZ, "Center Z",
VarDbl(size - 100.0, size + 100.0, size, "Size",
VarBool(facing, "Facing"
))))), "Preset Setup"))
preset = Utils::ClippingPreset::CreateCubePreset(Geom::Vec3f((float)centerX, (float)centerY, (float)centerZ), (float)size, facing);
}
break;
case 2 : // Tube
{
using namespace CGoGN::Utils::QT;
double centerX = (double)m_bb.center()[0];
double centerY = (double)m_bb.center()[1];
double centerZ = (double)m_bb.center()[2];
double size = (double)m_bb.maxSize()*0.75;
int axis = 0;
int precision = 1;
bool facing = false;
if (inputValues(VarDbl(centerX - 100.0, centerX + 100.0, centerX, "Center X",
VarDbl(centerY - 100.0, centerY + 100.0, centerY, "Center Y",
VarDbl(centerZ - 100.0, centerZ + 100.0, centerZ, "Center Z",
VarDbl(size - 100.0, size + 100.0, size, "Size",
VarSlider(0, 2, axis, "Axis",
VarSlider(1, 30, precision, "Precision",
VarBool(facing, "Facing"
))))))), "Preset Setup"))
preset = Utils::ClippingPreset::CreateTubePreset(Geom::Vec3f((float)centerX, (float)centerY, (float)centerZ), (float)size, axis, precision, facing);
}
break;
case 3 : // Molecule
{
using namespace CGoGN::Utils::QT;
double centerX = (double)m_bb.center()[0];
double centerY = (double)m_bb.center()[1];
double centerZ = (double)m_bb.center()[2];
double size = (double)m_bb.maxSize()*0.75;
double atomsRadiuses = (double)m_bb.maxSize()*0.25;
bool orClipping = true;
if (inputValues(VarDbl(centerX - 100.0, centerX + 100.0, centerX, "Center X",
VarDbl(centerY - 100.0, centerY + 100.0, centerY, "Center Y",
VarDbl(centerZ - 100.0, centerZ + 100.0, centerZ, "Center Z",
VarDbl(size - 100.0, size + 100.0, size, "Size",
VarDbl(atomsRadiuses - 100.0, atomsRadiuses + 100.0, atomsRadiuses, "Atoms radiuses",
VarBool(orClipping, "OR clipping mode"
)))))), "Preset Setup"))
preset = Utils::ClippingPreset::CreateMoleculePreset(Geom::Vec3f((float)centerX, (float)centerY, (float)centerZ), (float)size, atomsRadiuses, orClipping);
}
break;
}
std::vector<unsigned int> planesIds;
std::vector<unsigned int> spheresIds;
preset->apply(m_shader, &planesIds, &spheresIds);
delete preset;
// Cleanup of pickables before adding new ones
m_lastPickedObject = NULL;
for (size_t i = 0; i < m_pickablePlanes.size(); i++)
delete m_pickablePlanes[i];
m_pickablePlanes.resize(0);
for (size_t i = 0; i < m_pickableSpheres.size(); i++)
delete m_pickableSpheres[i];
m_pickableSpheres.resize(0);
// Add new pickable objects
for (size_t i = 0; i < planesIds.size(); i++)
{
Utils::Pickable* pickable = new Utils::Pickable(m_planeDrawable, planesIds[i]);
pickable->translate(m_shader->getClipPlaneParamsOrigin(planesIds[i]));
Geom::Vec3f vec1, vec2, vec3;
vec1 = m_shader->getClipPlaneParamsNormal(planesIds[i]);
computeBasisFromVector(vec1, vec2, vec3);
glm::mat4& transfoMat = pickable->transfo();
for (int i = 0; i < 3; i++)
{
transfoMat[0][i] = vec2[i];
transfoMat[1][i] = vec3[i];
transfoMat[2][i] = vec1[i];
}
m_pickablePlanes.push_back(pickable);
}
for (size_t i = 0; i < spheresIds.size(); i++)
{
Utils::Pickable* pickable = new Utils::Pickable(m_sphereDrawable, spheresIds[i]);
pickable->translate(m_shader->getClipSphereParamsCenter(spheresIds[i]));
pickable->scale(m_shader->getClipSphereParamsRadius(spheresIds[i]));
m_pickableSpheres.push_back(pickable);
}
// Update shader sources edits
dock.vertexEdit->setPlainText(QString(m_shader->getVertexShaderSrc()));
dock.fragmentEdit->setPlainText(QString(m_shader->getFragmentShaderSrc()));
// Update clipping parameters in interface
Utils::ClippingShader::clippingMode clipMode = m_shader->getClipMode();
if (clipMode == Utils::ClippingShader::CLIPPING_MODE_AND)
dock.radioButton_ClippingModeAnd->setChecked(true);
else if (clipMode == Utils::ClippingShader::CLIPPING_MODE_OR)
dock.radioButton_ClippingModeOr->setChecked(true);
updateGLMatrices();
}
void Clipping::button_compile()
{
QString st1 = dynamic_cast<Utils::QT::uiDockInterface*>(dockWidget())->vertexEdit->toPlainText();
QString st2 = dynamic_cast<Utils::QT::uiDockInterface*>(dockWidget())->fragmentEdit->toPlainText();
m_shader->reloadVertexShaderFromMemory(st1.toStdString().c_str());
m_shader->reloadFragmentShaderFromMemory(st2.toStdString().c_str());
m_shader->recompile();
updateGLMatrices();
}
/*******************************************************************************
* Init Functions
*******************************************************************************/
Clipping::Clipping():
m_drawVertices(false),
m_drawLines(true),
m_drawFaces(true),
m_drawTopo(false),
m_render(NULL),
m_render_topo(NULL),
m_positionVBO(NULL),
m_shader(NULL)
{
m_coeffTopoExplod = Geom::Vec3f(0.9,0.9,0.9);
}
void Clipping::initGUI()
{
CGoGNStream::allToConsole(this) ;
CGoGNStream::allToStd(true) ;
setDock(&dock);
dock.setWindowFlags(Qt::WindowMinimizeButtonHint);
setCallBack(dock.checkBox_vertices, SIGNAL(toggled(bool)), SLOT(slot_drawVertices(bool)));
setCallBack(dock.checkBox_lines, SIGNAL(toggled(bool)), SLOT(slot_drawLines(bool)));
setCallBack(dock.checkBox_faces, SIGNAL(toggled(bool)), SLOT(slot_drawFaces(bool)));
setCallBack(dock.groupBox_topo, SIGNAL(toggled(bool)), SLOT(slot_drawTopo(bool)));
setCallBack(dock.explod_phi1, SIGNAL(valueChanged(double)), SLOT(slot_explodTopoPhi1(double)));
setCallBack(dock.explod_phi2, SIGNAL(valueChanged(double)), SLOT(slot_explodTopoPhi2(double)));
setCallBack(dock.explod_phi3, SIGNAL(valueChanged(double)), SLOT(slot_explodTopoPhi3(double)));
setCallBack(dock.pushButton_addPlane, SIGNAL(clicked()), SLOT(slot_pushButton_addPlane()));
setCallBack(dock.spinBox_GridResolution, SIGNAL(valueChanged(int)), SLOT(slot_spinBox_GridResolution(int)));
setCallBack(dock.pushButton_changePlanesColor, SIGNAL(clicked()), SLOT(slot_pushButton_changePlanesColor()));
setCallBack(dock.compileButton, SIGNAL(clicked()), SLOT(button_compile()));
dock.vertexEdit->setPlainText(QString(m_shader->getVertexShaderSrc()));
dock.fragmentEdit->setPlainText(QString(m_shader->getFragmentShaderSrc()));
unsigned int planesPrecision1, planesPrecision2;
m_planeDrawable->getPrecisionDrawing(planesPrecision1, planesPrecision2);
dock.spinBox_GridResolution->setValue(planesPrecision1);
setCallBack(dock.pushButton_addSphere, SIGNAL(clicked()), SLOT(slot_pushButton_addSphere()));
setCallBack(dock.spinBox_SphereResolution, SIGNAL(valueChanged(int)), SLOT(slot_spinBox_SphereResolution(int)));
setCallBack(dock.pushButton_changeSpheresColor, SIGNAL(clicked()), SLOT(slot_pushButton_changeSpheresColor()));
unsigned int spheresPrecision1, spheresPrecision2;
m_sphereDrawable->getPrecisionDrawing(spheresPrecision1, spheresPrecision2);
dock.spinBox_SphereResolution->setValue(spheresPrecision1);
setCallBack(dock.doubleSpinBox_ColorAttenuationFactor, SIGNAL(valueChanged(double)), SLOT(slot_doubleSpinBox_ColorAttenuationFactor(double)));
setCallBack(dock.radioButton_ClippingModeAnd, SIGNAL(toggled(bool)), SLOT(slot_radioButton_ClippingMode(bool)));
setCallBack(dock.radioButton_ColorAttenuationModeLinear, SIGNAL(toggled(bool)), SLOT(slot_radioButton_ColorAttenuationMode(bool)));
dock.doubleSpinBox_ColorAttenuationFactor->setValue(m_shader->getClipColorAttenuationFactor());
Utils::ClippingShader::clippingMode clipMode = m_shader->getClipMode();
if (clipMode == Utils::ClippingShader::CLIPPING_MODE_AND)
dock.radioButton_ClippingModeAnd->setChecked(true);
else if (clipMode == Utils::ClippingShader::CLIPPING_MODE_OR)
dock.radioButton_ClippingModeOr->setChecked(true);
Utils::ClippingShader::colorAttenuationMode colorAttMode = m_shader->getClipColorAttenuationMode();
if (colorAttMode == Utils::ClippingShader::COLOR_ATTENUATION_MODE_LINEAR)
dock.radioButton_ColorAttenuationModeLinear->setChecked(true);
else if (colorAttMode == Utils::ClippingShader::COLOR_ATTENUATION_MODE_QUADRATIC)
dock.radioButton_ColorAttenuationModeQuadratic->setChecked(true);
setCallBack(dock.PushButton_ApplyClippingPreset, SIGNAL(clicked()), SLOT(slot_pushButton_applyClippingPreset()));
dock.comboBox_ClippingPresets->addItem("Dual Planes");
dock.comboBox_ClippingPresets->addItem("Cube");
dock.comboBox_ClippingPresets->addItem("Tube");
dock.comboBox_ClippingPresets->addItem("Molecule");
}
void Clipping::cb_Open()
{
std::string filters("all (*.*)") ;
std::string filename = selectFile("Open Mesh", "", filters) ;
importMesh(filename) ;
updateGL() ;
}
void Clipping::importMesh(std::string& filename)
{
std::vector<std::string> attrNames ;
std::string extension;
size_t pos;
pos = filename.rfind("."); // position of "." in filename
extension = filename.substr(pos);
if(extension == std::string(".tet"))
{
if(!Algo::Import::importTet<PFP>(myMap,filename.c_str(),attrNames))
{
CGoGNerr << "could not import " << filename << CGoGNendl ;
return;
}
else
position = myMap.getAttribute<PFP::VEC3>(VERTEX , attrNames[0]) ;
}
else if(extension == std::string(".ts"))
{
if(!Algo::Import::importTs<PFP>(myMap,filename.c_str(),attrNames))
{
CGoGNerr << "could not import " << filename << CGoGNendl ;
return;
}
else
position = myMap.getAttribute<PFP::VEC3>(VERTEX , attrNames[0]) ;
}
updateVBOprimitives(Algo::Render::GL2::TRIANGLES | Algo::Render::GL2::LINES | Algo::Render::GL2::POINTS) ;
m_render_topo->updateData<PFP>(myMap, allDarts, position, m_coeffTopoExplod[0], m_coeffTopoExplod[1], m_coeffTopoExplod[2]);
m_bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
gPosObj = m_bb.center() ;
float tailleX = m_bb.size(0) ;
float tailleY = m_bb.size(1) ;
float tailleZ = m_bb.size(2) ;
gWidthObj = std::max<float>(std::max<float>(tailleX, tailleY), tailleZ) ;
m_positionVBO->updateData(position) ;
setParamObject(gWidthObj, gPosObj.data()) ;