Commit e66c4530 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge branch 'develop' into 'develop'

Develop

add spherical harmonics + surface radiance shader & SCHNApps plugin

See merge request !34
parents 562b8f4d c32aa9d5
......@@ -31,6 +31,8 @@ find_package(SuiteSparse REQUIRED)
#find_package(SuperLU REQUIRED)
add_definitions(-DWITH_QT)
SET( QT_USE_QTOPENGL TRUE )
SET( QT_USE_QTXML TRUE )
SET( QT_USE_QTDESIGNER TRUE )
......
......@@ -12,6 +12,7 @@ ADD_SUBDIRECTORY(surface_deformation)
ADD_SUBDIRECTORY(surface_modelisation)
#ADD_SUBDIRECTORY(surface_tilings)
ADD_SUBDIRECTORY(surface_distance)
ADD_SUBDIRECTORY(surface_radiance)
ADD_SUBDIRECTORY(volume_import)
#ADD_SUBDIRECTORY(volume_render)
cmake_minimum_required(VERSION 2.8)
SET( PLUGIN_NAME Surface_Radiance )
SET( PLUGIN_ROOT_DIR ${SCHNApps_ROOT_DIR}/Plugins/surface_radiance )
INCLUDE_DIRECTORIES(
${PLUGIN_ROOT_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}
)
file(
GLOB_RECURSE
PLUGIN_FILES
${PLUGIN_ROOT_DIR}/src/*.cpp
${PLUGIN_ROOT_DIR}/include/*.h
${PLUGIN_ROOT_DIR}/include/*.hpp
)
file(
GLOB_RECURSE
PLUGIN_UI_FILES
${PLUGIN_ROOT_DIR}/forms/*.ui
)
SET(
PLUGIN_QOBJECT_FILES
${PLUGIN_ROOT_DIR}/include/surface_radiance.h
${PLUGIN_ROOT_DIR}/include/surface_radiance_dockTab.h
)
include( ${SCHNApps_ROOT_DIR}/Plugins/plugins_cmake.txt )
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Surface_Radiance_TabWidget</class>
<widget class="QWidget" name="Surface_Radiance_TabWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Position :</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="combo_positionVBO">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>- select VBO -</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Normal :</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="combo_normalVBO">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>- select VBO -</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
This diff is collapsed.
#ifndef _SURFACE_RADIANCE_DOCK_TAB_H_
#define _SURFACE_RADIANCE_DOCK_TAB_H_
#include "ui_surface_radiance.h"
#include "Utils/vbo.h"
namespace CGoGN
{
namespace SCHNApps
{
class SCHNApps;
class Surface_Radiance_Plugin;
struct MapParameters;
class Surface_Radiance_DockTab : public QWidget, public Ui::Surface_Radiance_TabWidget
{
Q_OBJECT
friend class Surface_Radiance_Plugin;
public:
Surface_Radiance_DockTab(SCHNApps* s, Surface_Radiance_Plugin* p);
private:
SCHNApps* m_schnapps;
Surface_Radiance_Plugin* m_plugin;
MapParameters* m_currentParams;
bool b_updatingUI;
private slots:
void positionVBOChanged(int index);
void normalVBOChanged(int index);
private:
void addPositionVBO(QString name);
void removePositionVBO(QString name);
void addNormalVBO(QString name);
void removeNormalVBO(QString name);
void updateMapParameters();
};
} // namespace SCHNApps
} // namespace CGoGN
#endif
#include "surface_radiance.h"
#include "mapHandler.h"
#include "camera.h"
#include <QFileDialog>
#include <QFileInfo>
namespace CGoGN
{
namespace SCHNApps
{
bool Surface_Radiance_Plugin::enable()
{
// magic line that init static variables of GenericMap in the plugins
GenericMap::copyAllStatics(m_schnapps->getStaticPointers());
m_dockTab = new Surface_Radiance_DockTab(m_schnapps, this);
m_schnapps->addPluginDockTab(this, m_dockTab, "Surface_Radiance");
connect(m_schnapps, SIGNAL(selectedViewChanged(View*, View*)), this, SLOT(selectedViewChanged(View*, View*)));
connect(m_schnapps, SIGNAL(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)), this, SLOT(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)));
connect(m_schnapps, SIGNAL(mapAdded(MapHandlerGen*)), this, SLOT(mapAdded(MapHandlerGen*)));
connect(m_schnapps, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(mapRemoved(MapHandlerGen*)));
foreach(MapHandlerGen* map, m_schnapps->getMapSet().values())
mapAdded(map);
m_dockTab->updateMapParameters();
m_importAction = new QAction("import", this);
m_schnapps->addMenuAction(this, "Radiance;Import", m_importAction);
connect(m_importAction, SIGNAL(triggered()), this, SLOT(importFromFileDialog()));
return true;
}
void Surface_Radiance_Plugin::disable()
{
disconnect(m_schnapps, SIGNAL(selectedViewChanged(View*, View*)), this, SLOT(selectedViewChanged(View*, View*)));
disconnect(m_schnapps, SIGNAL(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)), this, SLOT(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)));
disconnect(m_schnapps, SIGNAL(mapAdded(MapHandlerGen*)), this, SLOT(mapAdded(MapHandlerGen*)));
disconnect(m_schnapps, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(mapRemoved(MapHandlerGen*)));
foreach(MapHandlerGen* map, m_schnapps->getMapSet().values())
mapRemoved(map);
}
void Surface_Radiance_Plugin::drawMap(View* view, MapHandlerGen* map)
{
const MapParameters& p = h_mapParameterSet[map];
if(p.positionVBO && p.normalVBO)
{
p.radiancePerVertexShader->setAttributePosition(p.positionVBO);
p.radiancePerVertexShader->setAttributeNormal(p.normalVBO);
qglviewer::Vec c = view->getCurrentCamera()->position();
PFP2::VEC3 camera(c.x, c.y, c.z);
p.radiancePerVertexShader->setCamera(camera);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0f, 1.0f);
map->draw(p.radiancePerVertexShader, Algo::Render::GL2::TRIANGLES);
glDisable(GL_POLYGON_OFFSET_FILL);
}
}
void Surface_Radiance_Plugin::selectedViewChanged(View *prev, View *cur)
{
m_dockTab->updateMapParameters();
}
void Surface_Radiance_Plugin::selectedMapChanged(MapHandlerGen *prev, MapHandlerGen *cur)
{
m_dockTab->updateMapParameters();
if (cur == NULL)
m_dockTab->setDisabled(true);
else
m_dockTab->setDisabled(false);
}
void Surface_Radiance_Plugin::mapAdded(MapHandlerGen* map)
{
connect(map, SIGNAL(vboAdded(Utils::VBO*)), this, SLOT(vboAdded(Utils::VBO*)));
connect(map, SIGNAL(vboRemoved(Utils::VBO*)), this, SLOT(vboRemoved(Utils::VBO*)));
connect(map, SIGNAL(attributeModified(unsigned int, QString)), this, SLOT(attributeModified(unsigned int, QString)));
}
void Surface_Radiance_Plugin::mapRemoved(MapHandlerGen* map)
{
disconnect(map, SIGNAL(vboAdded(Utils::VBO*)), this, SLOT(vboAdded(Utils::VBO*)));
disconnect(map, SIGNAL(vboRemoved(Utils::VBO*)), this, SLOT(vboRemoved(Utils::VBO*)));
disconnect(map, SIGNAL(attributeModified(unsigned int, QString)), this, SLOT(attributeModified(unsigned int, QString)));
}
void Surface_Radiance_Plugin::vboAdded(Utils::VBO *vbo)
{
MapHandlerGen* map = static_cast<MapHandlerGen*>(QObject::sender());
if(map == m_schnapps->getSelectedMap())
{
if(vbo->dataSize() == 3)
{
m_dockTab->addPositionVBO(QString::fromStdString(vbo->name()));
m_dockTab->addNormalVBO(QString::fromStdString(vbo->name()));
}
}
}
void Surface_Radiance_Plugin::vboRemoved(Utils::VBO *vbo)
{
MapHandlerGen* map = static_cast<MapHandlerGen*>(QObject::sender());
if(map == m_schnapps->getSelectedMap())
{
if(vbo->dataSize() == 3)
{
m_dockTab->removePositionVBO(QString::fromStdString(vbo->name()));
m_dockTab->removeNormalVBO(QString::fromStdString(vbo->name()));
}
}
MapParameters& mapParam = h_mapParameterSet[map];
if(mapParam.positionVBO == vbo)
{
mapParam.positionVBO = NULL;
}
if(mapParam.normalVBO == vbo)
{
mapParam.normalVBO = NULL;
}
}
void Surface_Radiance_Plugin::attributeModified(unsigned int orbit, QString nameAttr)
{
if(orbit == VERTEX)
{
}
}
void Surface_Radiance_Plugin::importFromFileDialog()
{
QStringList fileNames = QFileDialog::getOpenFileNames(m_schnapps, "Import surface with radiance", m_schnapps->getAppPath(), "Surface with radiance Files (*.ply)");
QStringList::Iterator it = fileNames.begin();
while(it != fileNames.end()) {
importFromFile(*it);
++it;
}
}
void Surface_Radiance_Plugin::changePositionVBO(const QString& map, const QString& vbo)
{
MapHandlerGen* m = m_schnapps->getMap(map);
if(m)
{
Utils::VBO* vbuf = m->getVBO(vbo);
h_mapParameterSet[m].positionVBO = vbuf;
if(m->isSelectedMap())
m_dockTab->updateMapParameters();
}
}
void Surface_Radiance_Plugin::changeNormalVBO(const QString& map, const QString& vbo)
{
MapHandlerGen* m = m_schnapps->getMap(map);
if(m)
{
Utils::VBO* vbuf = m->getVBO(vbo);
h_mapParameterSet[m].normalVBO = vbuf;
if(m->isSelectedMap())
m_dockTab->updateMapParameters();
}
}
MapHandlerGen* Surface_Radiance_Plugin::importFromFile(const QString& fileName)
{
QFileInfo fi(fileName);
if(fi.exists())
{
MapHandlerGen* mhg = m_schnapps->addMap(fi.baseName(), 2);
if(mhg)
{
MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(mhg);
PFP2::MAP* map = mh->getMap();
MeshTablesSurface_Radiance importer(*map);
if (!importer.importPLY<SH_TYPE>(fileName.toStdString()))
{
std::cout << "could not import " << fileName.toStdString() << std::endl;
return NULL;
}
CGoGN::Algo::Surface::Import::importMesh<PFP2>(*map, importer);
// get vertex position attribute
VertexAttribute<PFP2::VEC3, PFP2::MAP> position = map->getAttribute<PFP2::VEC3, VERTEX, PFP2::MAP>("position") ;
VertexAttribute<PFP2::VEC3, PFP2::MAP> normal = map->getAttribute<PFP2::VEC3, VERTEX, PFP2::MAP>("normal");
mh->registerAttribute(position);
mh->registerAttribute(normal);
// update corresponding VBO & emit attribute update signal
mh->notifyAttributeModification(position);
mh->notifyAttributeModification(normal);
MapParameters& mapParams = h_mapParameterSet[mhg];
mapParams.radiance = map->getAttribute<SH_TYPE, VERTEX, PFP2::MAP>("radiance") ;
mapParams.radianceTexture = new Utils::Texture<2, Geom::Vec3f>(GL_FLOAT);
mapParams.param = map->checkAttribute<Geom::Vec2i, VERTEX, PFP2::MAP>("param");
// create texture
unsigned int nbv_nbc = Algo::Topo::getNbOrbits<VERTEX>(*map) * SH_TYPE::get_nb_coefs();
unsigned int size = 1;
while (size * size < nbv_nbc)
size <<= 1;
mapParams.radianceTexture->create(Geom::Vec2i(size, size));
// fill texture
unsigned int count = 0;
foreach_cell<VERTEX>(*map, [&] (Vertex v)
{
unsigned int i = count / size;
unsigned int j = count % size;
mapParams.param[v] = Geom::Vec2i(i, j) ; // first index for current vertex
for (int l = 0 ; l <= SH_TYPE::get_resolution() ; ++l)
{
for (int m = -l ; m <= l ; ++m)
{
i = count / size;
j = count % size;
(*(mapParams.radianceTexture))(i,j) = mapParams.radiance[v].get_coef(l, m);
++count;
}
}
}) ;
// resulting texture : SH00_vx0, SH1-1_vx0, ..., SHlm_vx0, SH00_vx1, SH1-1_vx1, ..., SHlm_vx1, etc.
// resulting param : param[vxI] points to SH00_vxI
// the size of the texture is needed to know where to do the divisions and modulos.
mapParams.radianceTexture->update();
mapParams.paramVBO = new Utils::VBO();
mapParams.paramVBO->updateData(mapParams.param);
mapParams.radiancePerVertexShader = new Utils::ShaderRadiancePerVertex();
registerShader(mapParams.radiancePerVertexShader);
mapParams.radiancePerVertexShader->compile(SH_TYPE::get_resolution());
mapParams.radiancePerVertexShader->setAttributeRadiance(mapParams.paramVBO, mapParams.radianceTexture, GL_TEXTURE1);
// compute map bounding box
mh->updateBB(position);
}
return mhg;
}
else
return NULL;
}
Q_EXPORT_PLUGIN2(Surface_Radiance_Plugin, Surface_Radiance_Plugin)
} // namespace SCHNApps
} // namespace CGoGN
#include "surface_radiance_dockTab.h"
#include "surface_radiance.h"
#include "schnapps.h"
#include "mapHandler.h"
namespace CGoGN
{
namespace SCHNApps
{
Surface_Radiance_DockTab::Surface_Radiance_DockTab(SCHNApps* s, Surface_Radiance_Plugin* p) :
m_schnapps(s),
m_plugin(p),
b_updatingUI(false)
{
setupUi(this);
connect(combo_positionVBO, SIGNAL(currentIndexChanged(int)), this, SLOT(positionVBOChanged(int)));
connect(combo_normalVBO, SIGNAL(currentIndexChanged(int)), this, SLOT(normalVBOChanged(int)));
}
void Surface_Radiance_DockTab::positionVBOChanged(int index)
{
if(!b_updatingUI)
{
MapHandlerGen* map = m_schnapps->getSelectedMap();
if(map)
{
m_plugin->h_mapParameterSet[map].positionVBO = map->getVBO(combo_positionVBO->currentText());
}
}
}
void Surface_Radiance_DockTab::normalVBOChanged(int index)
{
if(!b_updatingUI)
{
MapHandlerGen* map = m_schnapps->getSelectedMap();
if(map)
{
m_plugin->h_mapParameterSet[map].normalVBO = map->getVBO(combo_normalVBO->currentText());
}
}
}
void Surface_Radiance_DockTab::addPositionVBO(QString name)
{
b_updatingUI = true;
combo_positionVBO->addItem(name);
b_updatingUI = false;
}
void Surface_Radiance_DockTab::removePositionVBO(QString name)
{
b_updatingUI = true;
int curIndex = combo_positionVBO->currentIndex();
int index = combo_positionVBO->findText(name, Qt::MatchExactly);
if(curIndex == index)
combo_positionVBO->setCurrentIndex(0);
combo_positionVBO->removeItem(index);
b_updatingUI = false;
}
void Surface_Radiance_DockTab::addNormalVBO(QString name)
{
b_updatingUI = true;
combo_normalVBO->addItem(name);
b_updatingUI = false;
}
void Surface_Radiance_DockTab::removeNormalVBO(QString name)
{
b_updatingUI = true;
int curIndex = combo_normalVBO->currentIndex();
int index = combo_normalVBO->findText(name, Qt::MatchExactly);
if(curIndex == index)
combo_normalVBO->setCurrentIndex(0);
combo_normalVBO->removeItem(index);
b_updatingUI = false;
}
void Surface_Radiance_DockTab::updateMapParameters()
{
b_updatingUI = true;
combo_positionVBO->clear();
combo_positionVBO->addItem("- select VBO -");
combo_normalVBO->clear();
combo_normalVBO->addItem("- select VBO -");
MapHandlerGen* map = m_schnapps->getSelectedMap();
if(map)
{
const MapParameters& p = m_plugin->h_mapParameterSet[map];
unsigned int i = 1;
foreach(Utils::VBO* vbo, map->getVBOSet().values())
{
unsigned int dataSize = vbo->dataSize();
if(dataSize == 3)
{
combo_positionVBO->addItem(QString::fromStdString(vbo->name()));
if(vbo == p.positionVBO)
combo_positionVBO->setCurrentIndex(i);
combo_normalVBO->addItem(QString::fromStdString(vbo->name()));
if(vbo == p.normalVBO)
combo_normalVBO->setCurrentIndex(i);
++i;
}
}
}
b_updatingUI = false;
}
} // namespace SCHNApps
} // namespace CGoGN
......@@ -73,7 +73,6 @@ protected:
qglviewer::Vec m_bbMin;
qglviewer::Vec m_bbMax;
QString m_name;
SCHNApps* m_schnapps;
......
// ShaderRadiancePerVertex::fragmentShaderText
// PRECISION; // pose un pb non élucidé. remplacé temporairement par :
precision highp float;
VARYING_FRAG vec3 vxColor;
FRAG_OUT_DEF;
void main (void)
{
FRAG_OUT = vec4(vxColor,1.0) ;
}
// ShaderRadiancePerVertex::geometryShaderText
VARYING_IN vec3 ColorAttrib[];
VARYING_OUT vec3 vxColor;
void main()
{
gl_Position = POSITION_IN(0);
vxColor = ColorAttrib[0];
EmitVertex();
gl_Position = POSITION_IN(1);
vxColor = ColorAttrib[1];
EmitVertex();
gl_Position = POSITION_IN(2);
vxColor = ColorAttrib[2];
EmitVertex();
EndPrimitive();
}
/*******************************************************************************
* 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 *
* *
*******************************************************************************/
#ifndef __CGOGN_SHADER_RADIANCEPERVERTEX__
#define __CGOGN_SHADER_RADIANCEPERVERTEX__
#include "Utils/GLSLShader.h"
#include "Utils/clippingShader.h"
#include "Utils/textures.h"
#include "Geometry/vector_gen.h"
namespace CGoGN
{
namespace Utils
{
class ShaderRadiancePerVertex : public ClippingShader
{
protected:
// shader sources
static std::string vertexShaderText;
static std::string geometryShaderText;
static std::string fragmentShaderText;
CGoGNGLuint m_uniform_resolution;
CGoGNGLuint m_uniform_tex;
CGoGNGLuint m_uniform_K_tab;
CGoGNGLuint m_uniform_cam;
VBO* m_vboPos;
VBO* m_vboNorm;
VBO* m_vboParam;
Utils::Texture<2, Geom::Vec3f>* m_tex_ptr;
unsigned int m_tex_unit;
int m_resolution;
float* K_tab;
Geom::Vec3f m_camera;
static int index (int l, int m) { return l*(l+1)+m; } // compute indices in K_tab
public:
ShaderRadiancePerVertex();