Commit a75d3772 authored by Pierre Kraemer's avatar Pierre Kraemer

SCHNApps: several bug fixes + plugins UI code reorganization

parent 240da51a
...@@ -24,9 +24,10 @@ private: ...@@ -24,9 +24,10 @@ private:
MapHandlerGen* m_selectedMap; MapHandlerGen* m_selectedMap;
public slots: public slots:
void refreshUI(); void selectedMapChanged();
void addMapToList(MapHandlerGen* m); void addMapToList(MapHandlerGen* m);
void removeMapFromList(MapHandlerGen* m); void removeMapFromList(MapHandlerGen* m);
void addAttributeToList(unsigned int orbit, const QString& nameAttr);
}; };
} // namespace SCHNApps } // namespace SCHNApps
......
...@@ -24,9 +24,10 @@ private: ...@@ -24,9 +24,10 @@ private:
MapHandlerGen* m_selectedMap; MapHandlerGen* m_selectedMap;
public slots: public slots:
void refreshUI(); void selectedMapChanged();
void addMapToList(MapHandlerGen* m); void addMapToList(MapHandlerGen* m);
void removeMapFromList(MapHandlerGen* m); void removeMapFromList(MapHandlerGen* m);
void addAttributeToList(unsigned int orbit, const QString& nameAttr);
}; };
} // namespace SCHNApps } // namespace SCHNApps
......
...@@ -25,17 +25,17 @@ ComputeCurvatureDialog::ComputeCurvatureDialog(Window* w) : ...@@ -25,17 +25,17 @@ ComputeCurvatureDialog::ComputeCurvatureDialog(Window* w) :
connect(m_window, SIGNAL(mapAdded(MapHandlerGen*)), this, SLOT(addMapToList(MapHandlerGen*))); connect(m_window, SIGNAL(mapAdded(MapHandlerGen*)), this, SLOT(addMapToList(MapHandlerGen*)));
connect(m_window, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(removeMapFromList(MapHandlerGen*))); connect(m_window, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(removeMapFromList(MapHandlerGen*)));
connect(mapList, SIGNAL(itemSelectionChanged()), this, SLOT(refreshUI())); connect(mapList, SIGNAL(itemSelectionChanged()), this, SLOT(selectedMapChanged()));
const QList<MapHandlerGen*>& maps = m_window->getMapsList(); const QList<MapHandlerGen*>& maps = m_window->getMapsList();
foreach(MapHandlerGen* map, maps) foreach(MapHandlerGen* map, maps)
mapList->addItem(map->getName()); mapList->addItem(map->getName());
} }
void ComputeCurvatureDialog::refreshUI() void ComputeCurvatureDialog::selectedMapChanged()
{ {
if(m_selectedMap) if(m_selectedMap)
disconnect(m_selectedMap, SIGNAL(attributeAdded()), this, SLOT(refreshUI())); disconnect(m_selectedMap, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(addAttributeToList(unsigned int, const QString&)));
QList<QListWidgetItem*> currentItems = mapList->selectedItems(); QList<QListWidgetItem*> currentItems = mapList->selectedItems();
if(!currentItems.empty()) if(!currentItems.empty())
...@@ -47,53 +47,50 @@ void ComputeCurvatureDialog::refreshUI() ...@@ -47,53 +47,50 @@ void ComputeCurvatureDialog::refreshUI()
combo_KnormalAttribute->clear(); combo_KnormalAttribute->clear();
combo_kmaxAttribute->clear(); combo_kmaxAttribute->clear();
combo_kminAttribute->clear(); combo_kminAttribute->clear();
const QString& mapname = currentItems[0]->text(); const QString& mapname = currentItems[0]->text();
MapHandlerGen* mh = m_window->getMap(mapname); MapHandlerGen* mh = m_window->getMap(mapname);
GenericMap* map = mh->getGenericMap();
AttributeContainer& cont = map->getAttributeContainer<VERTEX>(); QString vec3TypeName = QString::fromStdString(nameOfType(PFP2::VEC3()));
QString realTypeName = QString::fromStdString(nameOfType(PFP2::REAL()));
std::vector<std::string> names;
std::vector<std::string> types;
cont.getAttributesNames(names);
cont.getAttributesTypes(types);
std::string vec3TypeName = nameOfType(PFP2::VEC3());
std::string realTypeName = nameOfType(PFP2::REAL());
unsigned int j = 0; unsigned int j = 0;
unsigned int k = 0; unsigned int k = 0;
for(unsigned int i = 0; i < names.size(); ++i) const AttributeHash& attribs = mh->getAttributesList(VERTEX);
for(AttributeHash::const_iterator i = attribs.constBegin(); i != attribs.constEnd(); ++i)
{ {
if(types[i] == vec3TypeName) if(i.value() == vec3TypeName)
{ {
combo_positionAttribute->addItem(QString::fromStdString(names[i])); combo_positionAttribute->addItem(i.key());
if(names[i] == "position") // try to select a position attribute named "position" if(i.key() == "position") // try to select a position attribute named "position"
combo_positionAttribute->setCurrentIndex(j); combo_positionAttribute->setCurrentIndex(j);
combo_normalAttribute->addItem(QString::fromStdString(names[i])); combo_normalAttribute->addItem(i.key());
if(names[i] == "normal") // try to select a normal attribute named "normal" if(i.key() == "normal") // try to select a normal attribute named "normal"
combo_normalAttribute->setCurrentIndex(j); combo_normalAttribute->setCurrentIndex(j);
combo_KmaxAttribute->addItem(QString::fromStdString(names[i])); combo_KmaxAttribute->addItem(i.key());
if(names[i] == "Kmax") // try to select a normal attribute named "Kmax" if(i.key() == "Kmax") // try to select a normal attribute named "Kmax"
combo_KmaxAttribute->setCurrentIndex(j); combo_KmaxAttribute->setCurrentIndex(j);
combo_KminAttribute->addItem(QString::fromStdString(names[i])); combo_KminAttribute->addItem(i.key());
if(names[i] == "Kmin") // try to select a normal attribute named "Kmin" if(i.key() == "Kmin") // try to select a normal attribute named "Kmin"
combo_KminAttribute->setCurrentIndex(j); combo_KminAttribute->setCurrentIndex(j);
combo_KnormalAttribute->addItem(QString::fromStdString(names[i])); combo_KnormalAttribute->addItem(i.key());
if(names[i] == "Knormal") // try to select a normal attribute named "Knormal" if(i.key() == "Knormal") // try to select a normal attribute named "Knormal"
combo_KnormalAttribute->setCurrentIndex(j); combo_KnormalAttribute->setCurrentIndex(j);
++j; ++j;
} }
else if(types[i] == realTypeName) else if(i.value() == realTypeName)
{ {
combo_kmaxAttribute->addItem(QString::fromStdString(names[i])); combo_kmaxAttribute->addItem(i.key());
if(names[i] == "kmax") // try to select a normal attribute named "kmax" if(i.key() == "kmax") // try to select a normal attribute named "kmax"
combo_kmaxAttribute->setCurrentIndex(k); combo_kmaxAttribute->setCurrentIndex(k);
combo_kminAttribute->addItem(QString::fromStdString(names[i])); combo_kminAttribute->addItem(i.key());
if(names[i] == "kmin") // try to select a normal attribute named "kmin" if(i.key() == "kmin") // try to select a normal attribute named "kmin"
combo_kminAttribute->setCurrentIndex(k); combo_kminAttribute->setCurrentIndex(k);
++k; ++k;
...@@ -101,7 +98,7 @@ void ComputeCurvatureDialog::refreshUI() ...@@ -101,7 +98,7 @@ void ComputeCurvatureDialog::refreshUI()
} }
m_selectedMap = mh; m_selectedMap = mh;
connect(m_selectedMap, SIGNAL(attributeAdded()), this, SLOT(refreshUI())); connect(m_selectedMap, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(addAttributeToList(unsigned int, const QString&)));
} }
else else
m_selectedMap = NULL; m_selectedMap = NULL;
...@@ -120,11 +117,33 @@ void ComputeCurvatureDialog::removeMapFromList(MapHandlerGen* m) ...@@ -120,11 +117,33 @@ void ComputeCurvatureDialog::removeMapFromList(MapHandlerGen* m)
if(m_selectedMap == m) if(m_selectedMap == m)
{ {
disconnect(m_selectedMap, SIGNAL(attributeAdded()), this, SLOT(refreshUI())); disconnect(m_selectedMap, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(addAttributeToList(unsigned int, const QString&)));
m_selectedMap = NULL; m_selectedMap = NULL;
} }
} }
void ComputeCurvatureDialog::addAttributeToList(unsigned int orbit, const QString& nameAttr)
{
QString vec3TypeName = QString::fromStdString(nameOfType(PFP2::VEC3()));
QString realTypeName = QString::fromStdString(nameOfType(PFP2::REAL()));
const QString& typeAttr = m_selectedMap->getAttributeTypeName(orbit, nameAttr);
if(typeAttr == vec3TypeName)
{
combo_positionAttribute->addItem(nameAttr);
combo_normalAttribute->addItem(nameAttr);
combo_KmaxAttribute->addItem(nameAttr);
combo_KminAttribute->addItem(nameAttr);
combo_KnormalAttribute->addItem(nameAttr);
}
else if(typeAttr == realTypeName)
{
combo_kmaxAttribute->addItem(nameAttr);
combo_kminAttribute->addItem(nameAttr);
}
}
} // namespace SCHNApps } // namespace SCHNApps
} // namespace CGoGN } // namespace CGoGN
...@@ -21,44 +21,41 @@ ComputeNormalDialog::ComputeNormalDialog(Window* w) : ...@@ -21,44 +21,41 @@ ComputeNormalDialog::ComputeNormalDialog(Window* w) :
connect(m_window, SIGNAL(mapAdded(MapHandlerGen*)), this, SLOT(addMapToList(MapHandlerGen*))); connect(m_window, SIGNAL(mapAdded(MapHandlerGen*)), this, SLOT(addMapToList(MapHandlerGen*)));
connect(m_window, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(removeMapFromList(MapHandlerGen*))); connect(m_window, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(removeMapFromList(MapHandlerGen*)));
connect(mapList, SIGNAL(itemSelectionChanged()), this, SLOT(refreshUI())); connect(mapList, SIGNAL(itemSelectionChanged()), this, SLOT(selectedMapChanged()));
const QList<MapHandlerGen*>& maps = m_window->getMapsList(); const QList<MapHandlerGen*>& maps = m_window->getMapsList();
foreach(MapHandlerGen* map, maps) foreach(MapHandlerGen* map, maps)
mapList->addItem(map->getName()); mapList->addItem(map->getName());
} }
void ComputeNormalDialog::refreshUI() void ComputeNormalDialog::selectedMapChanged()
{ {
if(m_selectedMap) if(m_selectedMap)
disconnect(m_selectedMap, SIGNAL(attributeAdded()), this, SLOT(refreshUI())); disconnect(m_selectedMap, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(addAttributeToList(unsigned int, const QString&)));
QList<QListWidgetItem*> currentItems = mapList->selectedItems(); QList<QListWidgetItem*> currentItems = mapList->selectedItems();
if(!currentItems.empty()) if(!currentItems.empty())
{ {
combo_positionAttribute->clear(); combo_positionAttribute->clear();
combo_normalAttribute->clear(); combo_normalAttribute->clear();
const QString& mapname = currentItems[0]->text(); const QString& mapname = currentItems[0]->text();
MapHandlerGen* mh = m_window->getMap(mapname); MapHandlerGen* mh = m_window->getMap(mapname);
GenericMap* map = mh->getGenericMap();
AttributeContainer& cont = map->getAttributeContainer<VERTEX>(); QString vec3TypeName = QString::fromStdString(nameOfType(PFP2::VEC3()));
std::vector<std::string> names;
std::vector<std::string> types;
cont.getAttributesNames(names);
cont.getAttributesTypes(types);
std::string vec3TypeName = nameOfType(PFP2::VEC3());
unsigned int j = 0; unsigned int j = 0;
for(unsigned int i = 0; i < names.size(); ++i) const AttributeHash& attribs = mh->getAttributesList(VERTEX);
for(AttributeHash::const_iterator i = attribs.constBegin(); i != attribs.constEnd(); ++i)
{ {
if(types[i] == vec3TypeName) if(i.value() == vec3TypeName)
{ {
combo_positionAttribute->addItem(QString::fromStdString(names[i])); combo_positionAttribute->addItem(i.key());
if(names[i] == "position") // try to select a position attribute named "position" if(i.key() == "position") // try to select a position attribute named "position"
combo_positionAttribute->setCurrentIndex(j); combo_positionAttribute->setCurrentIndex(j);
combo_normalAttribute->addItem(QString::fromStdString(names[i])); combo_normalAttribute->addItem(i.key());
if(names[i] == "normal") // try to select a normal attribute named "normal" if(i.key() == "normal") // try to select a normal attribute named "normal"
combo_normalAttribute->setCurrentIndex(j); combo_normalAttribute->setCurrentIndex(j);
++j; ++j;
...@@ -66,7 +63,7 @@ void ComputeNormalDialog::refreshUI() ...@@ -66,7 +63,7 @@ void ComputeNormalDialog::refreshUI()
} }
m_selectedMap = mh; m_selectedMap = mh;
connect(m_selectedMap, SIGNAL(attributeAdded()), this, SLOT(refreshUI())); connect(m_selectedMap, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(addAttributeToList(unsigned int, const QString&)));
} }
else else
m_selectedMap = NULL; m_selectedMap = NULL;
...@@ -85,11 +82,24 @@ void ComputeNormalDialog::removeMapFromList(MapHandlerGen* m) ...@@ -85,11 +82,24 @@ void ComputeNormalDialog::removeMapFromList(MapHandlerGen* m)
if(m_selectedMap == m) if(m_selectedMap == m)
{ {
disconnect(m_selectedMap, SIGNAL(attributeAdded()), this, SLOT(refreshUI())); disconnect(m_selectedMap, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(addAttributeToList(unsigned int, const QString&)));
m_selectedMap = NULL; m_selectedMap = NULL;
} }
} }
void ComputeNormalDialog::addAttributeToList(unsigned int orbit, const QString& nameAttr)
{
QString vec3TypeName = QString::fromStdString(nameOfType(PFP2::VEC3()));
const QString& typeAttr = m_selectedMap->getAttributeTypeName(orbit, nameAttr);
if(typeAttr == vec3TypeName)
{
combo_positionAttribute->addItem(nameAttr);
combo_normalAttribute->addItem(nameAttr);
}
}
} // namespace SCHNApps } // namespace SCHNApps
} // namespace CGoGN } // namespace CGoGN
...@@ -27,10 +27,11 @@ MapHandlerGen* ImportSurfacePlugin::importFromFile(const QString& fileName) ...@@ -27,10 +27,11 @@ MapHandlerGen* ImportSurfacePlugin::importFromFile(const QString& fileName)
PFP2::MAP* map = mh->getMap(); PFP2::MAP* map = mh->getMap();
std::vector<std::string> attrNames; std::vector<std::string> attrNames;
Algo::Surface::Import::importMesh<PFP2>(*map, fileName.toUtf8().constData(), attrNames); Algo::Surface::Import::importMesh<PFP2>(*map, fileName.toStdString(), attrNames);
// get vertex position attribute // get vertex position attribute
VertexAttribute<PFP2::VEC3> position = map->getAttribute<PFP2::VEC3, CGoGN::VERTEX>(attrNames[0]); VertexAttribute<PFP2::VEC3> position = map->getAttribute<PFP2::VEC3, CGoGN::VERTEX>(attrNames[0]);
mh->registerAttribute<PFP2::VEC3, VERTEX>(position);
// create VBO for vertex position attribute // create VBO for vertex position attribute
mh->createVBO(position); mh->createVBO(position);
......
...@@ -27,10 +27,11 @@ MapHandlerGen* ImportVolumePlugin::importFromFile(const QString& fileName) ...@@ -27,10 +27,11 @@ MapHandlerGen* ImportVolumePlugin::importFromFile(const QString& fileName)
PFP3::MAP* map = mh->getMap(); PFP3::MAP* map = mh->getMap();
std::vector<std::string> attrNames ; std::vector<std::string> attrNames ;
Algo::Volume::Import::importMesh<PFP3>(*map, fileName.toUtf8().constData(), attrNames); Algo::Volume::Import::importMesh<PFP3>(*map, fileName.toStdString(), attrNames);
// get vertex position attribute // get vertex position attribute
VertexAttribute<PFP3::VEC3> position = map->getAttribute<PFP3::VEC3, CGoGN::VERTEX>(attrNames[0]); VertexAttribute<PFP3::VEC3> position = map->getAttribute<PFP3::VEC3, CGoGN::VERTEX>(attrNames[0]);
mh->registerAttribute<PFP2::VEC3, VERTEX>(position);
// create VBO for vertex position attribute // create VBO for vertex position attribute
mh->createVBO(position); mh->createVBO(position);
......
...@@ -26,6 +26,7 @@ file( ...@@ -26,6 +26,7 @@ file(
SET( SET(
PLUGIN_QOBJECT_FILES PLUGIN_QOBJECT_FILES
${PLUGIN_ROOT_DIR}/include/render.h ${PLUGIN_ROOT_DIR}/include/render.h
${PLUGIN_ROOT_DIR}/include/renderDockTab.h
) )
include( ${SCHNApps_ROOT_DIR}/Plugins/plugins_cmake.txt ) include( ${SCHNApps_ROOT_DIR}/Plugins/plugins_cmake.txt )
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>RenderWidget</class> <class>RenderDockWidget</class>
<widget class="QWidget" name="RenderWidget"> <widget class="QWidget" name="RenderDockWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
......
...@@ -2,17 +2,18 @@ ...@@ -2,17 +2,18 @@
#define _RENDER_PLUGIN_H_ #define _RENDER_PLUGIN_H_
#include "plugin.h" #include "plugin.h"
#include "ui_render.h" #include "renderDockTab.h"
#include "Utils/Shaders/shaderFlat.h" #include "Utils/Shaders/shaderFlat.h"
#include "Utils/Shaders/shaderPhong.h" #include "Utils/Shaders/shaderPhong.h"
#include "Utils/Shaders/shaderSimpleColor.h" #include "Utils/Shaders/shaderSimpleColor.h"
#include "Utils/pointSprite.h" #include "Utils/pointSprite.h"
namespace CGoGN
{
using namespace CGoGN; namespace SCHNApps
using namespace SCHNApps; {
enum FaceShadingStyle enum FaceShadingStyle
{ {
...@@ -53,30 +54,13 @@ struct ParameterSet ...@@ -53,30 +54,13 @@ struct ParameterSet
}; };
class RenderPlugin;
class RenderDockTab : public QWidget, public Ui::RenderWidget
{
public:
RenderDockTab(RenderPlugin* p) : plugin(p)
{
setupUi(this);
}
void refreshUI(ParameterSet* params);
private:
RenderPlugin* plugin;
};
class RenderPlugin : public Plugin class RenderPlugin : public Plugin
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(CGoGN::SCHNApps::Plugin) Q_INTERFACES(CGoGN::SCHNApps::Plugin)
public: public:
RenderPlugin() : b_refreshingUI(false) RenderPlugin()
{ {
setProvidesRendering(true); setProvidesRendering(true);
} }
...@@ -96,8 +80,6 @@ public: ...@@ -96,8 +80,6 @@ public:
virtual void mouseMove(View* view, QMouseEvent* event) {} virtual void mouseMove(View* view, QMouseEvent* event) {}
virtual void wheelEvent(View* view, QWheelEvent* event) {} virtual void wheelEvent(View* view, QWheelEvent* event) {}
void setRefreshingUI(bool b) { b_refreshingUI = b; }
protected: protected:
RenderDockTab* m_dockTab; RenderDockTab* m_dockTab;
QHash<View*, ParameterSet*> h_viewParams; QHash<View*, ParameterSet*> h_viewParams;
...@@ -107,8 +89,6 @@ protected: ...@@ -107,8 +89,6 @@ protected:
CGoGN::Utils::ShaderSimpleColor* m_simpleColorShader; CGoGN::Utils::ShaderSimpleColor* m_simpleColorShader;
CGoGN::Utils::PointSprite* m_pointSprite; CGoGN::Utils::PointSprite* m_pointSprite;
bool b_refreshingUI;
public slots: public slots:
void viewLinked(View* view, Plugin* plugin); void viewLinked(View* view, Plugin* plugin);
void viewUnlinked(View* view, Plugin* plugin); void viewUnlinked(View* view, Plugin* plugin);
...@@ -128,15 +108,10 @@ public slots: ...@@ -128,15 +108,10 @@ public slots:
void changeRenderEdges(View* view, MapHandlerGen* map, bool b); void changeRenderEdges(View* view, MapHandlerGen* map, bool b);
void changeRenderFaces(View* view, MapHandlerGen* map, bool b); void changeRenderFaces(View* view, MapHandlerGen* map, bool b);
void changeFacesStyle(View* view, MapHandlerGen* map, FaceShadingStyle style); void changeFacesStyle(View* view, MapHandlerGen* map, FaceShadingStyle style);
void cb_selectedMapChanged();
void cb_positionVBOChanged(int index);
void cb_normalVBOChanged(int index);
void cb_renderVerticesChanged(bool b);
void cb_verticesScaleFactorChanged(int i);
void cb_renderEdgesChanged(bool b);
void cb_renderFacesChanged(bool b);
void cb_faceStyleChanged(QAbstractButton* b);
}; };
} // namespace SCHNApps
} // namespace CGoGN
#endif #endif
#ifndef _RENDER_DOCK_TAB_H_
#define _RENDER_DOCK_TAB_H_
#include "ui_render.h"
namespace CGoGN
{
namespace SCHNApps
{
class Window;
class RenderPlugin;
class ParameterSet;
class RenderDockTab : public QWidget, public Ui::RenderDockWidget
{
Q_OBJECT
public:
RenderDockTab(Window* w, RenderPlugin* p);
private:
Window* m_window;
RenderPlugin* m_plugin;
ParameterSet* m_currentParams;
bool b_refreshingUI;
public slots:
void refreshUI(ParameterSet* params);
void selectedMapChanged();
void positionVBOChanged(int index);
void normalVBOChanged(int index);
void renderVerticesChanged(bool b);
void verticesScaleFactorChanged(int i);
void renderEdgesChanged(bool b);
void renderFacesChanged(bool b);
void faceStyleChanged(QAbstractButton* b);
};
} // namespace SCHNApps
} // namespace CGoGN
#endif
...@@ -2,8 +2,11 @@ ...@@ -2,8 +2,11 @@
#include "mapHandler.h" #include "mapHandler.h"
#include "Algo/Import/import.h" namespace CGoGN
{
namespace SCHNApps
{
PerMapParameterSet::PerMapParameterSet(MapHandlerGen* map) : PerMapParameterSet::PerMapParameterSet(MapHandlerGen* map) :
positionVBO(NULL), positionVBO(NULL),
...@@ -14,25 +17,35 @@ PerMapParameterSet::PerMapParameterSet(MapHandlerGen* map) : ...@@ -14,25 +17,35 @@ PerMapParameterSet::PerMapParameterSet(MapHandlerGen* map) :
renderFaces(true), renderFaces(true),
faceStyle(FLAT) faceStyle(FLAT)
{ {
bool positionFound = false;
bool normalFound = false;
QList<Utils::VBO*> vbos = map->getVBOList(); QList<Utils::VBO*> vbos = map->getVBOList();
for(int i = 0; i < vbos.count(); ++i) for(int i = 0; i < vbos.count(); ++i)
{ {
if(vbos[i]->name() == "position") // try to select a VBO named "position" if(vbos[i]->dataSize() == 3)
positionVBO = vbos[i]; {
if(vbos[i]->name() == "normal") // try to select a VBO named "normal" if(!positionFound) positionVBO = vbos[i];
normalVBO = vbos[i]; if(vbos[i]->name() == "position") // try to select a VBO named "position"
}