Commit 02c85dd9 authored by Pierre Kraemer's avatar Pierre Kraemer

non functional version of plugin surface deformation

parent 3cd5f660
cmake_minimum_required(VERSION 2.8)
ADD_SUBDIRECTORY(surface_import)
ADD_SUBDIRECTORY(surface_differentialProperties)
ADD_SUBDIRECTORY(surface_subdivision)
ADD_SUBDIRECTORY(surface_selection)
ADD_SUBDIRECTORY(surface_render)
ADD_SUBDIRECTORY(surface_renderVector)
ADD_SUBDIRECTORY(surface_renderScalar)
ADD_SUBDIRECTORY(surface_renderTopo)
ADD_SUBDIRECTORY(surface_differentialProperties)
ADD_SUBDIRECTORY(surface_subdivision)
ADD_SUBDIRECTORY(surface_selection)
ADD_SUBDIRECTORY(surface_deformation)
cmake_minimum_required(VERSION 2.8)
SET( PLUGIN_NAME SurfaceDeformation )
SET( PLUGIN_NAME Surface_Deformation )
SET( PLUGIN_ROOT_DIR ${SCHNApps_ROOT_DIR}/Plugins/surfaceDeformation )
SET( PLUGIN_ROOT_DIR ${SCHNApps_ROOT_DIR}/Plugins/surface_deformation )
INCLUDE_DIRECTORIES(
${PLUGIN_ROOT_DIR}/include
......@@ -25,8 +25,8 @@ file(
SET(
PLUGIN_QOBJECT_FILES
${PLUGIN_ROOT_DIR}/include/surfaceDeformation.h
${PLUGIN_ROOT_DIR}/include/surfaceDeformationDockTab.h
${PLUGIN_ROOT_DIR}/include/surface_deformation.h
${PLUGIN_ROOT_DIR}/include/surface_deformation_dockTab.h
)
include( ${SCHNApps_ROOT_DIR}/Plugins/plugins_cmake.txt )
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SurfaceDeformationWidget</class>
<widget class="QWidget" name="SurfaceDeformationWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>189</width>
<height>545</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="mapList"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Position :</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="combo_positionAttribute">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Select Vertices</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="radio_locked">
<property name="text">
<string>locked</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radio_handle">
<property name="text">
<string>handle</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>156</width>
<height>161</height>
</size>
</property>
</spacer>
</item>
</layout>
<zorder>mapList</zorder>
<zorder>label_2</zorder>
<zorder>groupBox</zorder>
</widget>
<resources/>
<connections/>
</ui>
#ifndef _SURFACEDEFORMATION_PLUGIN_H_
#define _SURFACEDEFORMATION_PLUGIN_H_
#include "plugin.h"
#include "surfaceDeformationDockTab.h"
#include "mapHandler.h"
#include "Utils/pointSprite.h"
#include "Container/fakeAttribute.h"
#include "NL/nl.h"
#include "Algo/LinearSolving/basic.h"
#include "Eigen/Dense"
namespace CGoGN
{
namespace SCHNApps
{
enum SelectionMode
{
LOCKED,
HANDLE
};
typedef NoNameIOAttribute<Eigen::Matrix3f> Eigen_Matrix3f ;
struct PerMapParameterSet
{
PerMapParameterSet(MapHandlerGen* mh);
~PerMapParameterSet();
void initParameters();
MapHandlerGen* mh;
VertexAttribute<PFP2::VEC3> positionAttribute;
CellMarker<VERTEX>* lockingMarker;
CellMarker<VERTEX>* handleMarker;
SelectionMode verticesSelectionMode;
std::vector<PFP2::VEC3> lockedVertices;
std::vector<PFP2::VEC3> handleVertices;
std::vector<unsigned int> handleVerticesId;
Utils::VBO* lockedVerticesVBO;
Utils::VBO* handleVerticesVBO;
VertexAttribute<PFP2::VEC3> positionInit;
VertexAttribute<PFP2::VEC3> vertexNormal;
EdgeAttribute<PFP2::REAL> edgeAngle;
EdgeAttribute<PFP2::REAL> edgeWeight;
VertexAttribute<PFP2::REAL> vertexArea;
VertexAttribute<PFP2::VEC3> diffCoord;
VertexAttribute<Eigen_Matrix3f> vertexRotationMatrix;
VertexAttribute<PFP2::VEC3> rotatedDiffCoord;
VertexAttribute<unsigned int> vIndex;
unsigned int nb_vertices;
NLContext nlContext;
};
struct ParameterSet
{
ParameterSet() : selectedMap(NULL)
{}
PerMapParameterSet* getCurrentMapParameterSet()
{
if(selectedMap)
return perMap[selectedMap->getName()];
else
return NULL;
}
QHash<QString, PerMapParameterSet*> perMap;
MapHandlerGen* selectedMap;
};
class SurfaceDeformationPlugin : public Plugin
{
Q_OBJECT
Q_INTERFACES(CGoGN::SCHNApps::Plugin)
public:
SurfaceDeformationPlugin() :
selecting(false),
dragging(false)
{
setProvidesRendering(true);
}
~SurfaceDeformationPlugin()
{}
virtual bool enable();
virtual void disable();
virtual void redraw(View *view);
virtual void keyPress(View* view, QKeyEvent* event);
virtual void keyRelease(View* view, QKeyEvent* event);
virtual void mousePress(View* view, QMouseEvent* event);
virtual void mouseRelease(View* view, QMouseEvent* event);
virtual void mouseMove(View* view, QMouseEvent* event);
virtual void wheelEvent(View* view, QWheelEvent* event);
protected:
SurfaceDeformationDockTab* m_dockTab;
QHash<View*, ParameterSet*> h_viewParams;
Utils::PointSprite* m_pointSprite;
Utils::VBO* selectionSphereVBO;
bool selecting;
PFP2::VEC3 selectionCenter;
PFP2::REAL selectionRadius;
bool dragging;
PFP2::REAL dragZ;
qglviewer::Vec dragPrevious;
public slots:
void viewLinked(View* view, Plugin* plugin);
void viewUnlinked(View* view, Plugin* plugin);
void currentViewChanged(View* view);
void mapLinked(MapHandlerGen* m);
void mapUnlinked(MapHandlerGen* m);
protected:
void addManagedMap(View *v, MapHandlerGen* m);
void removeManagedMap(View *v, MapHandlerGen* m);
public slots:
void changeSelectedMap(View* view, MapHandlerGen* map);
void changePositionAttribute(View* view, MapHandlerGen* map, VertexAttribute<PFP2::VEC3> attribute, bool fromUI = false);
void changeVerticesSelectionMode(View* view, MapHandlerGen* map, SelectionMode m, bool fromUI = false);
protected:
void matchDiffCoord(View* view, MapHandlerGen* map);
void asRigidAsPossible(View* view, MapHandlerGen* map);
};
} // namespace SCHNApps
} // namespace CGoGN
#endif
#ifndef _SURFACE_DEFORMATION_DOCK_TAB_H_
#define _SURFACE_DEFORMATION_DOCK_TAB_H_
#include "ui_surfaceDeformation.h"
namespace CGoGN
{
namespace SCHNApps
{
class Window;
class SurfaceDeformationPlugin;
struct ParameterSet;
class SurfaceDeformationDockTab : public QWidget, public Ui::SurfaceDeformationWidget
{
Q_OBJECT
public:
SurfaceDeformationDockTab(Window* w, SurfaceDeformationPlugin* p);
private:
Window* m_window;
SurfaceDeformationPlugin* m_plugin;
ParameterSet* m_currentParams;
bool b_refreshingUI;
public slots:
void refreshUI(ParameterSet* params);
void selectedMapChanged();
void positionAttributeChanged(int index);
void selectLockedVertices(bool b);
void selectHandleVertices(bool b);
void addAttributeToList(unsigned int orbit, const QString& nameAttr);
};
} // namespace SCHNApps
} // namespace CGoGN
#endif
#include "surfaceDeformation.h"
#include "Algo/Selection/raySelector.h"
#include "Algo/Selection/collector.h"
#include "Algo/Geometry/normal.h"
#include "Algo/Geometry/laplacian.h"
#include <QKeyEvent>
#include <QMouseEvent>
namespace CGoGN
{
namespace SCHNApps
{
PerMapParameterSet::PerMapParameterSet(MapHandlerGen* m) :
mh(m),
verticesSelectionMode(LOCKED),
nlContext(NULL)
{
QString positionName;
QString vec3TypeName = QString::fromStdString(nameOfType(PFP2::VEC3()));
const AttributeHash& attribs = mh->getAttributesList(VERTEX);
for(AttributeHash::const_iterator i = attribs.constBegin(); i != attribs.constEnd(); ++i)
{
if(i.value() == vec3TypeName)
{
if(positionName != "position") // try to select an attribute named "position"
positionName = i.key(); // or anything else if not found
}
}
positionAttribute = mh->getAttribute<PFP2::VEC3, VERTEX>(positionName);
PFP2::MAP* map = static_cast<MapHandler<PFP2>*>(mh)->getMap();
lockingMarker = new CellMarker<VERTEX>(*map);
handleMarker = new CellMarker<VERTEX>(*map);
lockedVerticesVBO = new Utils::VBO();
handleVerticesVBO = new Utils::VBO();
positionInit = mh->getAttribute<PFP2::VEC3, VERTEX>("positionInit", false) ;
if(!positionInit.isValid())
positionInit = mh->addAttribute<PFP2::VEC3, VERTEX>("positionInit", false) ;
vIndex = mh->getAttribute<unsigned int, VERTEX>("vIndex", false);
if(!vIndex.isValid())
vIndex = mh->addAttribute<unsigned int, VERTEX>("vIndex", false);
// edgeWeight = mh->getAttribute<PFP2::REAL, EDGE>("edgeWeight", false);
// if(!edgeWeight.isValid())
// edgeWeight = mh->addAttribute<PFP2::REAL, EDGE>("edgeWeight", false);
// vertexArea = mh->getAttribute<PFP2::REAL, VERTEX>("vertexArea", false);
// if(!vertexArea.isValid())
// vertexArea = mh->addAttribute<PFP2::REAL, VERTEX>("vertexArea", false);
diffCoord = mh->getAttribute<PFP2::VEC3, VERTEX>("diffCoord", false);
if(!diffCoord.isValid())
diffCoord = mh->addAttribute<PFP2::VEC3, VERTEX>("diffCoord", false);
vertexRotationMatrix = mh->getAttribute<Eigen_Matrix3f, VERTEX>("vertexRotationMatrix", false) ;
if(!vertexRotationMatrix.isValid())
vertexRotationMatrix = mh->addAttribute<Eigen_Matrix3f, VERTEX>("vertexRotationMatrix", false);
rotatedDiffCoord = mh->getAttribute<PFP2::VEC3, VERTEX>("rotatedDiffCoord", false) ;
if(!rotatedDiffCoord.isValid())
rotatedDiffCoord = mh->addAttribute<PFP2::VEC3, VERTEX>("rotatedDiffCoord", false);
initParameters();
}
PerMapParameterSet::~PerMapParameterSet()
{
delete lockingMarker;
delete handleMarker;
delete lockedVerticesVBO;
delete handleVerticesVBO;
nlDeleteContext(nlContext);
}
void PerMapParameterSet::initParameters()
{
if(positionAttribute.isValid())
{
PFP2::MAP* map = static_cast<MapHandler<PFP2>*>(mh)->getMap();
map->copyAttribute(positionInit, positionAttribute) ;
nb_vertices = static_cast<AttribMap*>(map)->computeIndexCells<VERTEX>(vIndex);
// Algo::Surface::Geometry::computeCotanWeightEdges<PFP2>(*map, positionAttribute, edgeWeight) ;
// Algo::Surface::Geometry::computeVoronoiAreaVertices<PFP2>(*map, positionAttribute, vertexArea) ;
// Algo::Surface::Geometry::computeLaplacianCotanVertices<PFP2>(*map, edgeWeight, vertexArea, positionAttribute, diffCoord) ;
Algo::Surface::Geometry::computeLaplacianTopoVertices<PFP2>(*map, positionAttribute, diffCoord) ;
for(unsigned int i = vertexRotationMatrix.begin(); i != vertexRotationMatrix.end() ; vertexRotationMatrix.next(i))
vertexRotationMatrix[i] = Eigen::Matrix3f::Identity();
if(nlContext)
nlDeleteContext(nlContext);
nlContext = nlNewContext();
nlSolverParameteri(NL_NB_VARIABLES, nb_vertices);
nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
nlSolverParameteri(NL_SOLVER, NL_CHOLMOD_EXT);
}
}
bool SurfaceDeformationPlugin::enable()
{
m_dockTab = new SurfaceDeformationDockTab(m_window, this);
addTabInDock(m_dockTab, "Surface Deformation");
selectionSphereVBO = new Utils::VBO();
m_pointSprite = new CGoGN::Utils::PointSprite();
registerShader(m_pointSprite);
connect(m_window, SIGNAL(viewAndPluginLinked(View*, Plugin*)), this, SLOT(viewLinked(View*, Plugin*)));
connect(m_window, SIGNAL(viewAndPluginUnlinked(View*, Plugin*)), this, SLOT(viewUnlinked(View*, Plugin*)));
connect(m_window, SIGNAL(currentViewChanged(View*)), this, SLOT(currentViewChanged(View*)));
return true;
}
void SurfaceDeformationPlugin::disable()
{
delete m_pointSprite;
}
void SurfaceDeformationPlugin::redraw(View* view)
{
ParameterSet* params = h_viewParams[view];
MapHandlerGen* mh = params->selectedMap;
if(mh)
{
PerMapParameterSet* perMap = params->perMap[mh->getName()];
if(!perMap->lockedVertices.empty() || !perMap->handleVertices.empty())
{
m_pointSprite->setAttributePosition(perMap->lockedVerticesVBO);
m_pointSprite->setSize(mh->getBBdiagSize() / 250.0f);
m_pointSprite->setColor(CGoGN::Geom::Vec4f(1.0f, 0.0f, 0.0f, 0.75f));
m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
m_pointSprite->enableVertexAttribs();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_POINTS, 0, perMap->lockedVertices.size());
glDisable(GL_BLEND);
m_pointSprite->disableVertexAttribs();
m_pointSprite->setAttributePosition(perMap->handleVerticesVBO);
m_pointSprite->setSize(mh->getBBdiagSize() / 250.0f);
m_pointSprite->setColor(CGoGN::Geom::Vec4f(0.0f, 1.0f, 0.0f, 0.75f));
m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
m_pointSprite->enableVertexAttribs();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_POINTS, 0, perMap->handleVertices.size());
glDisable(GL_BLEND);
m_pointSprite->disableVertexAttribs();
}
}
if(selecting)
{
std::vector<PFP2::VEC3> selectionPoint;
selectionPoint.push_back(selectionCenter);
selectionSphereVBO->updateData(selectionPoint);
m_pointSprite->setAttributePosition(selectionSphereVBO);
m_pointSprite->setSize(selectionRadius);
m_pointSprite->setColor(CGoGN::Geom::Vec4f(0.0f, 0.0f, 1.0f, 0.5f));
m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
m_pointSprite->enableVertexAttribs();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_POINTS, 0, 1);
glDisable(GL_BLEND);
m_pointSprite->disableVertexAttribs();
}
}
void SurfaceDeformationPlugin::keyPress(View* view, QKeyEvent* event)
{
if(event->key() == Qt::Key_Shift)
{
view->setMouseTracking(true);
selecting = true;
view->updateGL();
}
else if(event->key() == Qt::Key_R)
{
ParameterSet* params = h_viewParams[view];
MapHandlerGen* map = params->selectedMap;
if(map)
{
asRigidAsPossible(view, map);
PerMapParameterSet* perMap = params->perMap[map->getName()];
params->selectedMap->notifyAttributeModification(perMap->positionAttribute);
view->updateGL();
}
}
}
void SurfaceDeformationPlugin::keyRelease(View* view, QKeyEvent* event)
{
if(event->key() == Qt::Key_Shift)
{
view->setMouseTracking(false);
selecting = false;
view->updateGL();
}
}
void SurfaceDeformationPlugin::mousePress(View* view, QMouseEvent* event)
{
if(event->button() == Qt::LeftButton && selecting)
{
ParameterSet* params = h_viewParams[view];
PerMapParameterSet* perMap = params->getCurrentMapParameterSet();
if(perMap)
{
QPoint pixel(event->x(), event->y());
qglviewer::Vec orig;
qglviewer::Vec dir;
view->camera()->convertClickToLine(pixel, orig, dir);
PFP2::VEC3 rayA(orig.x, orig.y, orig.z);
PFP2::VEC3 AB(dir.x, dir.y, dir.z);
Dart d;
PFP2::MAP* map = static_cast<MapHandler<PFP2>*>(params->selectedMap)->getMap();
Algo::Selection::vertexRaySelection<PFP2>(*map, perMap->positionAttribute, rayA, AB, d);
if(d != NIL)
{
Algo::Surface::Selection::Collector_WithinSphere<PFP2> neigh(*map, perMap->positionAttribute, selectionRadius);
neigh.collectAll(d);
const std::vector<Dart>& insideV = neigh.getInsideVertices();
for(unsigned int i = 0; i < insideV.size(); ++i)
{
unsigned int v = map->getEmbedding<VERTEX>(insideV[i]);
if (!perMap->lockingMarker->isMarked(v))
{
if(perMap->verticesSelectionMode == LOCKED)
perMap->lockedVertices.push_back(perMap->positionAttribute[v]);
perMap->lockingMarker->mark(v);
}
if(perMap->verticesSelectionMode == HANDLE)
{
if(!perMap->handleMarker->isMarked(v))
{
perMap->handleVertices.push_back(perMap->positionAttribute[v]);
perMap->handleVerticesId.push_back(v);
perMap->handleMarker->mark(v);
}
}
}
nlMakeCurrent(perMap->nlContext) ;
nlReset(NL_FALSE) ;
perMap->lockedVerticesVBO->updateData(perMap->lockedVertices);
if(perMap->verticesSelectionMode == HANDLE)
perMap->handleVerticesVBO->updateData(perMap->handleVertices);
view->updateGL() ;
}
}
}