meshViewer

Introduction

This example, close to myStructureComputer in its use of the library, shows how to make more complex requests to the X3DTK::MESH::Mesh. This demostrates the use of the MESH scene graph as well as the default Mesh datas.

We want to display and select the different entities of a MESH scene graph. We define a processor called X3DTK::MESH::Drawer that displays the content of the Mesh structure in order to display the 3D model and to enable selection. The different entities are the vertices, the edges and the faces.

The example is mainly based upon the creation of a X3DTK::X3DProcessor so you can see glNormalViewer before reading this example.

Some important functions and classes:

MESH::DrawerStateVariables

In the state variables to the X3DTK::MESH::Drawer traversal, we store the variables necessary to the display for the GL selection mechanism.

MESH::DrawerCoreVisitor

In the visitor of the Core component of the X3DTK::MESH::Drawer processor, we draw the different mesh entities and execute the GL commands relative to selection.

MESH::Drawer

This is the facade of the processor.

SimpleMeshGLScene

This class contains all the processors required to the loading, updating and rendering of the 3D scene. It is also the intermediate between the X3DTK::MESH::Drawer and the X3DTK::Viewer, the events being emitted by the X3DTK::Viewer and treated by the X3DTK::MESH::Drawer.

Viewer

This is the specialization of a QGLViewer, redefining particularly the draw and select methods.

Code

MESH_DrawerStateVariables.h

#ifndef MESH_DRAWER_GLOBALVARIABLES_H
#define MESH_DRAWER_GLOBALVARIABLES_H

#include <X3DTK/MESH/scenegraph.h>

#include <list>
#include <vector>

namespace X3DTK {
namespace MESH {

// State variables for the MESH::Drawer processor.

class DrawerStateVariables : public StateVariables
{
public:
  DrawerStateVariables();

  void initTraversal();
  void finishTraversal();

  void pushMatrix(const SFMatrix34f &transformation);  
  void popMatrix();

  int getCurrentMeshId();
  void storeMesh(Mesh *mesh);
  
  inline const Mesh *getMesh(int i) const {return _meshVector[i];};
  inline SFMatrix34f getMatrix(int i) const {return _matrixVector[i];};

  inline void setSelectionMode(bool selectionMode) {_selectionMode = selectionMode;};
  inline bool getSelectionMode() const {return _selectionMode;};
    
  void setPrimitiveType(int primitiveType) {_primitiveType = primitiveType;};
  inline int getPrimitiveType() const {return _primitiveType;};
  
  void changeOneColorPerMesh() {_oneColorPerMesh = !_oneColorPerMesh;};
  inline bool getOneColorPerMesh() const {return _oneColorPerMesh;};
  
private: 
  std::list<SFMatrix34f> _matrixStack;
  std::vector<SFMatrix34f> _matrixVector;
  std::vector<Mesh *> _meshVector;
  bool _selectionMode;
  bool _oneColorPerMesh;
  int _primitiveType;
};

}
}

#endif

MESH_DrawerStateVariables.cpp

#include "MESH_DrawerStateVariables.h"
#include <qglobal.h>

namespace X3DTK {
namespace MESH {

DrawerStateVariables::DrawerStateVariables()
: StateVariables(), _selectionMode(false), _oneColorPerMesh(true), _primitiveType(1)
{}

void DrawerStateVariables::initTraversal()
{
  _matrixStack.push_front(SFMatrix34f::identity);
  _matrixVector.clear();
  _meshVector.clear();
}

void DrawerStateVariables::finishTraversal()
{
  _matrixStack.pop_front();
  if (_matrixStack.size() != 0)
    {
      qWarning("Non empty matrix stack at the end of Drawer traversal");
      _matrixStack.clear();
    }
}

void DrawerStateVariables::pushMatrix(const SFMatrix34f &transformation)
{
  _matrixStack.push_front(_matrixStack.front()*transformation);
}

void DrawerStateVariables::popMatrix()
{
  _matrixStack.pop_front();
}

void DrawerStateVariables::storeMesh(Mesh* mesh)
{
  _matrixVector.push_back(_matrixStack.front());
  _meshVector.push_back(mesh);
}

int DrawerStateVariables::getCurrentMeshId()
{
  return _matrixVector.size() - 1;
}

}
}

MESH_DrawerCoreVisitor.h

#ifndef MESH_DRAWER_COREVISITOR_H
#define MESH_DRAWER_COREVISITOR_H

#include <X3DTK/MESH/scenegraph.h>
#include "MESH_DrawerStateVariables.h"

namespace X3DTK {
namespace MESH {

class Transform;

// Visitor for the Core component of the Drawer processor.

class DrawerCoreVisitor : public CoreVisitor
{
public:
  DrawerCoreVisitor();

  static void enterMesh(Mesh *M);
  static void enterTransform(Transform *T);
  static void leaveTransform(Transform *T);
};

}
}

#endif

MESH_DrawerCoreVisitor.cpp

#include "MESH_DrawerCoreVisitor.h"
#include <GL/gl.h>
#include <iostream>

using namespace std;

namespace X3DTK {
namespace MESH {

DrawerCoreVisitor::DrawerCoreVisitor()
{
  // Enter and leave functions.
  define(Recorder<Transform>::getEnterFunction(&DrawerCoreVisitor::enterTransform));
  define(Recorder<Mesh>::getEnterFunction(&DrawerCoreVisitor::enterMesh));
  define(Recorder<Transform>::getLeaveFunction(&DrawerCoreVisitor::leaveTransform));
}

void DrawerCoreVisitor::enterTransform(Transform *T)
{
  glMatrixMode(GL_MODELVIEW);
  Singleton<DrawerStateVariables>::getInstance()->pushMatrix(T->getTransform());
  glPushMatrix();
  glMultMatrixf(T->getTransform().toFloat16());
}

void DrawerCoreVisitor::leaveTransform(Transform *)
{
  glMatrixMode(GL_MODELVIEW);
  Singleton<DrawerStateVariables>::getInstance()->popMatrix();
  glPopMatrix();
}

void DrawerCoreVisitor::enterMesh(Mesh *M)
{
  // StateVariables assignation.
  DrawerStateVariables *stateVariables = Singleton<DrawerStateVariables>::getInstance();

  stateVariables->storeMesh(M);
  int meshId = stateVariables->getCurrentMeshId();

  if (stateVariables->getSelectionMode())
    glPushName(meshId);

  bool colorPerVertex = M->data().getColorPerVertex();
  bool normalPerVertex = M->data().getNormalPerVertex();
  
  switch (stateVariables->getPrimitiveType())
  {
    case 1 : // MeshViewer::VERTICES
    {
      glColor3f(1.0, 0.9, 0.8);
      glPointSize(6.0);
      const Mesh::MFVertex &vertices = M->getVertices();

      if (stateVariables->getSelectionMode())
      {
        glPushName(1);
        for (Mesh::MFVertex::const_iterator v = vertices.begin(); v != vertices.end(); ++v)
        {
          glPushName((*v)->getIndex());
          SFPoint3f point = (*v)->data().getPoint();
          glRasterPos3fv(point);
          glPopName();
        }
        glPopName();
      }
      else
      {
        glBegin(GL_POINTS);
        for (Mesh::MFVertex::const_iterator v = vertices.begin(); v != vertices.end(); ++v)
        {
          SFPoint3f point = (*v)->data().getPoint();
          glVertex3fv(point);
        }
        glEnd();
      }
      break;
    }
    
    case 2 : // MeshViewer::EDGES
    {
      glLineWidth(2.0);
      const Mesh::MFEdge &edges = M->getEdges();

      if (stateVariables->getSelectionMode())
        glPushName(2);

      int index = 0;
      for (Mesh::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e)
      {
        if (stateVariables->getSelectionMode())
          glPushName(index++);

        if ((*e)->isBoundary())
          glColor3f(0.3, 0.3, 0.9);
        else
          glColor3f(0.7, 0.7, 0.7);

        // Normal
        SFFace *firstFace = (*((*e)->getLeftFaces().begin()));
         
        if (!firstFace)
          firstFace = (*((*e)->getRightFaces().begin()));
        SFVec3f normal;
        if (normalPerVertex)
          normal = (*e)->getFromVertex()->data().getNormalOfFace(firstFace);
        else
          normal = firstFace->data().getNormal();
         
        glNormal3fv(normal);
           
        glBegin(GL_LINES);
        SFPoint3f point = (*e)->getFromVertex()->data().getPoint();
        glVertex3fv(point);
        point = (*e)->getToVertex()->data().getPoint();
        glVertex3fv(point);
        glEnd();
            
        if (stateVariables->getSelectionMode())
          glPopName();
      }
        
      if (stateVariables->getSelectionMode())
        glPopName();
        
      break;
    }

    case 3 : // MeshViewer::FACES
    {
      const Mesh::MFFace& faces = M->getFaces();
        
      if (stateVariables->getSelectionMode())
        glPushName(3);

      if (stateVariables->getOneColorPerMesh())
      {
        SFColorRGBA color = SFColorRGBA(0.1*((3+meshId*3)%10), 0.1*((5+meshId*4)%10), 0.1*((7+meshId*5)%10), 1.0);
        glColor4f(color.r, color.g, color.b, color.a);
      }
        
      for (Mesh::MFFace::const_iterator f = faces.begin(); f != faces.end(); ++f)
      {
        if (!normalPerVertex)
        {
          SFVec3f normal = (*f)->data().getNormal();
          glNormal3fv(normal);
        }

        if ((!colorPerVertex) && (!stateVariables->getOneColorPerMesh()))
        {
          SFColorRGBA color = (*f)->data().getColor();
          glColor4f(color.r, color.g, color.b, color.a);
        }
            
        if (stateVariables->getSelectionMode())
          glPushName((*f)->getIndex());

        glBegin(GL_POLYGON);
        const SFFace::MFEdge &edges = (*f)->getEdges();
        for (SFFace::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e)
        {
          if (normalPerVertex)
          {
            SFVec3f normal = (*e)->getFromVertex()->data().getNormalOfFace(*f);
            glNormal3fv(normal);
          }
          if ((colorPerVertex) && (!stateVariables->getOneColorPerMesh()))
          {
            SFColorRGBA color = (*e)->getFromVertex()->data().getColorOfFace(*f);
            glColor4f(color.r, color.g, color.b, color.a);
          }
          
          SFPoint3f point = (*e)->getFromVertex()->data().getPoint();
          glVertex3fv(point);
        }
        glEnd();

        if (stateVariables->getSelectionMode())
          glPopName();
      }

      if (stateVariables->getSelectionMode())
        glPopName();

      break;
    }
  }

  if (stateVariables->getSelectionMode())
    glPopName();
}

}
}

MESH_Drawer.h

#ifndef MESH_DRAWER_H
#define MESH_DRAWER_H

#include "MESH_DrawerStateVariables.h"

#include <X3DTK/kernel.h>
#include <X3DTK/MESH/scenegraph.h>

namespace X3DTK {

enum SelectedType {NOTHING, VERTICES, EDGES, FACES};

namespace MESH {

// Processor drawing the mesh from the Mesh scene graph.

class Drawer : public X3DOnePassProcessor
{
public:
  Drawer();
  virtual ~Drawer();
  
  void changeDrawPoints();
  void changeDrawEdges();
  void changeDrawFaces(); 
  void changeOneColorPerMesh(); 

  void setSelectedType(SelectedType selectedType);
  void setSelectedMesh(int selectedMesh);
  void setSelectedId(int selectedId);
  
  inline SelectedType getSelectedType() const {return selectedType;};
  inline int getSelectedMesh() const {return selectedMesh;};
  inline int getSelectedId() const {return selectedId;};
  
  void drawMesh(X3DNode *N, bool selection = false);
  void drawSelected();
 
private:
  bool drawPoints, drawEdges, drawFaces;
  SelectedType selectedType;
  int selectedMesh;
  int selectedId;

  // Draw methods.
  void drawVertex(const SFVertex *vertex);
  void drawEdge(SFEdge *edge);
  void drawFace(const SFFace *face);
};

}
}

#endif

MESH_Drawer.cpp

#include "MESH_Drawer.h"
#include "MESH_DrawerCoreVisitor.h"

#include <iostream>

using namespace std;

namespace X3DTK {
namespace MESH {

Drawer::Drawer()
: X3DOnePassProcessor(), drawPoints(false), drawEdges(true), drawFaces(true), selectedType(NOTHING)
{
  setGraphTraversal(new DFSGraphTraversal());
  setComponentVisitor(new DrawerCoreVisitor());
}

Drawer::~Drawer()
{
  Singleton<DrawerStateVariables>::removeInstance();
}

void Drawer::changeDrawPoints()
{
  drawPoints = !drawPoints;
}

void Drawer::changeDrawEdges()
{
  drawEdges = !drawEdges;
}

void Drawer::changeDrawFaces()
{
  drawFaces = !drawFaces;
}

void Drawer::changeOneColorPerMesh() 
{
  Singleton<DrawerStateVariables>::getInstance()->changeOneColorPerMesh();
}

void Drawer::setSelectedType(SelectedType selectedType)
{
  this->selectedType = selectedType;
}

void Drawer::setSelectedMesh(int selectedMesh)
{
  this->selectedMesh = selectedMesh;
}

void Drawer::setSelectedId(int selectedId)
{
  this->selectedId = selectedId;
}

void Drawer::drawMesh(X3DNode *N, bool selection)
{
  Singleton<DrawerStateVariables>::getInstance()->setSelectionMode(selection);
  
  if (selection || drawPoints)
  {
    Singleton<DrawerStateVariables>::getInstance()->setPrimitiveType(VERTICES);
    Singleton<DrawerStateVariables>::getInstance()->initTraversal();
    traverse(N);
    Singleton<DrawerStateVariables>::getInstance()->finishTraversal();
  }  
  if (selection || drawEdges)
  {
    Singleton<DrawerStateVariables>::getInstance()->setPrimitiveType(EDGES);
    Singleton<DrawerStateVariables>::getInstance()->initTraversal();
    traverse(N);
    Singleton<DrawerStateVariables>::getInstance()->finishTraversal();
  }  
  if (selection || drawFaces)
  {
    Singleton<DrawerStateVariables>::getInstance()->setPrimitiveType(FACES);  
    Singleton<DrawerStateVariables>::getInstance()->initTraversal();
    traverse(N);
    Singleton<DrawerStateVariables>::getInstance()->finishTraversal();
  }  
}

void Drawer::drawSelected()
{
  if (selectedType == NOTHING)
    return;

  glPushMatrix();
  glMultMatrixf(Singleton<DrawerStateVariables>::getInstance()->getMatrix(selectedMesh).toFloat16());

  const Mesh *mesh = Singleton<DrawerStateVariables>::getInstance()->getMesh(selectedMesh);
  bool normalPerVertex = mesh->data().getNormalPerVertex();

  glEnable(GL_POLYGON_OFFSET_FILL);
#ifdef GL_POLYGON_OFFSET_LINES
  glEnable(GL_POLYGON_OFFSET_LINES);
#endif
  
  glPointSize(15.0);
  glLineWidth(8.0);
  
  switch (selectedType)
  {
    case NOTHING :
      break;
    case VERTICES :
    {
      glPointSize(25.0);
      SFVertex *vertex = (mesh->getVertices())[selectedId];
      const SFVertex::MFFace &faces = vertex->getFaces();

      // Normal
      SFFace *firstFace = (*(faces.begin()));
      SFVec3f normal;
      if (normalPerVertex)
        normal = vertex->data().getNormalOfFace(firstFace);
      else
        normal = firstFace->data().getNormal();
      glNormal3fv(normal.f_data());

      glColor3f(1.0, 1.0, 0.0);
      drawVertex(vertex);

      glColor3f(0.0, 0.8, 0.0);
      const SFVertex::MFEdge &edges = vertex->getEdges();
      for (SFVertex::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e)
        drawEdge(*e);

      glColor3f(0.7, 0.9, 0.7);
      for (SFVertex::MFFace::const_iterator f = faces.begin(); f != faces.end(); ++f)
        drawFace(*f);
      break;
    }
    case EDGES :
    {
      glLineWidth(15.0);
      SFEdge *edge = (mesh->getEdges())[selectedId];

      // Normal
      SFFace *firstFace = (*(edge->getLeftFaces().begin()));
      if (!firstFace)
        firstFace = (*(edge->getRightFaces().begin()));
      SFVec3f normal;
      if (normalPerVertex)
        normal = edge->getFromVertex()->data().getNormalOfFace(firstFace);
      else
        normal = firstFace->data().getNormal();
      glNormal3fv(normal.f_data());

      glColor3f(1.0, 1.0, 0.0);
      drawEdge(edge);

      glColor3f(0.0, 0.8, 0.0);
      drawVertex(edge->getFromVertex());
      drawVertex(edge->getToVertex());

      glColor3f(0.9, 0.7, 0.7);
      const SFEdge::MFFace &lfaces = edge->getLeftFaces();
      for (SFEdge::MFFace::const_iterator lf = lfaces.begin(); lf != lfaces.end(); ++lf)
        drawFace(*lf);

      glColor3f(0.7, 0.9, 0.7);
      const SFEdge::MFFace &rfaces = edge->getRightFaces();
      for (SFEdge::MFFace::const_iterator rf = rfaces.begin(); rf != rfaces.end(); ++rf)
        drawFace(*rf);

      break;
    }
    case FACES :
    {
      SFFace *face = (mesh->getFaces())[selectedId];
      const SFFace::MFEdge &edges = face->getEdges();
      SFFace::MFVertex vertices = face->getVertices();

      // Normal
      SFEdge *firstEdge = (*(edges.begin()));
      SFVec3f normal;
      if (normalPerVertex)
        normal = firstEdge->getFromVertex()->data().getNormalOfFace(face);
      else
        normal = face->data().getNormal();
      glNormal3fv(normal.f_data());

      glColor3f(1.0, 1.0, 0.0);
      drawFace(face);

      for (SFFace::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e)
      {
        glColor3f(0.0, 0.8, 0.0);
        drawEdge(*e);
      }
      
      for (SFFace::MFVertex::const_iterator v = vertices.begin(); v != vertices.end(); ++v)
      {  
        glColor3f(0.7, 0.7, 0.7);
        drawVertex(*v);
      }

      break;
    }
  }
  glDisable(GL_POLYGON_OFFSET_FILL);
#ifdef GL_POLYGON_OFFSET_LINES
  glDisable(GL_POLYGON_OFFSET_LINES);
#endif

  glPopMatrix();
}

void Drawer::drawVertex(const SFVertex *vertex)
{
  glBegin(GL_POINTS);
  SFPoint3f point = vertex->data().getPoint();
  glVertex3fv(point.f_data());
  glEnd();
}

void Drawer::drawEdge(SFEdge *edge)
{
  glPolygonOffset(-100, -100);
  glDisable(GL_LIGHTING);
  glBegin(GL_LINES);
  SFPoint3f point = edge->getFromVertex()->data().getPoint();
  glVertex3fv(point.f_data());
  point = edge->getToVertex()->data().getPoint();
  glVertex3fv(point.f_data());
  glEnd();
  glEnable(GL_LIGHTING);
  glPolygonOffset(-2, -2);
}

void Drawer::drawFace(const SFFace *face)
{
  const SFFace::MFEdge &edges = face->getEdges();
  glBegin(GL_POLYGON);
  for (SFFace::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e)
  {
    SFPoint3f point = (*e)->getFromVertex()->data().getPoint();
    glVertex3fv(point.f_data());
  }
  glEnd();
}

}
}

SimpleMeshGLScene.h

#ifndef SIMPLEMESHGLSCENE_H
#define SIMPLEMESHGLSCENE_H

#include "MESH_Drawer.h"

#include <X3DTK/kernel.h>
#include <X3DTK/X3D/meshbuilder.h>
#include <X3DTK/MESH/normalsupdater.h>

namespace X3DTK {

class MemReleaser;

namespace X3D {

class Scene;
class Loader;
class BBoxUpdater;

}

namespace MESH {

class Scene;
class Drawer;

}

// Class defining a facade to allow an easy load and display of an X3D scene.

class SimpleMeshGLScene
{
public:
  SimpleMeshGLScene();
  virtual ~SimpleMeshGLScene();
  
  virtual void load(const char *file);
  virtual void drawMesh(bool selection = false);
  virtual void drawSelected();
  inline SFVec3f getBBoxMin() const {return min;};
  inline SFVec3f getBBoxMax() const {return max;};
  void release();
  
  inline void changeDrawPoints() {_drawer->changeDrawPoints();};
  inline void changeDrawEdges() {_drawer->changeDrawEdges();};
  inline void changeDrawFaces() {_drawer->changeDrawFaces();}; 
  inline void changeOneColorPerMesh() {_drawer->changeOneColorPerMesh();}; 
  inline void setSelectedType(SelectedType selectedType) {_drawer->setSelectedType(selectedType);};
  inline void setSelectedMesh(int selectedMesh) {_drawer->setSelectedMesh(selectedMesh);};
  inline void setSelectedId(int selectedId) {_drawer->setSelectedId(selectedId);};
  
  inline SelectedType getSelectedType() const {return _drawer->getSelectedType();};
  inline int getSelectedMesh() const {return _drawer->getSelectedMesh();};
  inline int getSelectedId() const {return _drawer->getSelectedId();};
  
protected:
  X3D::Scene *scene;
  MESH::Scene *meshScene;
  
  SFVec3f min;
  SFVec3f max;
  
  void loadFile(const char *file);
  void computeBBox();
  void buildMeshScene();

private:
  X3D::Loader *_loader;
  X3D::BBoxUpdater *_bboxupdater;
  X3D::MeshBuilder *_builder;
  MESH::NormalsUpdater *_normalUpdater;
  MESH::Drawer *_drawer;
  MemReleaser *_releaser;
};

}

#endif

SimpleMeshGLScene.cpp

#include "SimpleMeshGLScene.h"

#include <X3DTK/X3D/scenegraph.h>
#include <X3DTK/X3D/bboxupdater.h>
#include <X3DTK/memreleaser.h>
#include <X3DTK/MESH/scenegraph.h>

#include <iostream>
#include <time.h>

using namespace std;

namespace X3DTK {

SimpleMeshGLScene::SimpleMeshGLScene()
: scene(0), meshScene(0)
{
  _loader = Singleton<X3D::Loader>::getInstance();
  _bboxupdater = Singleton<X3D::BBoxUpdater>::getInstance();
  _builder = Singleton<X3D::MeshBuilder>::getInstance();
  _drawer = Singleton<MESH::Drawer>::getInstance();
  _normalUpdater = Singleton<MESH::NormalsUpdater>::getInstance();
  _releaser = Singleton<MemReleaser>::getInstance();
}

SimpleMeshGLScene::~SimpleMeshGLScene()
{
  _releaser->release(scene);
  _releaser->release(meshScene);  
  scene = 0;
  meshScene = 0;
}

void SimpleMeshGLScene::load(const char *file)
{
  loadFile(file);
  computeBBox();
  buildMeshScene();
}

void SimpleMeshGLScene::drawMesh(bool selection) 
{
  _drawer->drawMesh(meshScene, selection);
}

void SimpleMeshGLScene::drawSelected() 
{
  _drawer->drawSelected();
}
  

void SimpleMeshGLScene::release()
{
  _releaser->release(scene);
  _releaser->release(meshScene);
  scene = 0;
  meshScene = 0;  
}

void SimpleMeshGLScene::loadFile(const char *file)
{
  _releaser->release(scene);
  _releaser->release(meshScene);  
  scene = 0;
  meshScene = 0;
  
  scene = _loader->load(file, true);
}

void SimpleMeshGLScene::computeBBox()
{
  _bboxupdater->update(scene, true);
  
  if (scene != 0)
  {
    SFVec3f center = scene->getBBoxCenter();
    SFVec3f size = scene->getBBoxSize();

    SFVec3f A = center + 0.5f*size;
    SFVec3f B = center - 0.5f*size;

    if (A.x < B.x)
    {
      min.x = A.x;
      max.x = B.x;
    }  
    else
    {
      min.x = B.x;  
      max.x = A.x;
    }  
  
    if (A.y < B.y)
    {
      min.y = A.y;
      max.y = B.y;
    }  
    else
    {
      min.y = B.y;  
      max.y = A.y;
    }
  
    if (A.z < B.z)
    {
      min.z = A.z;
      max.z = B.z;
    }  
    else
    {
      min.z = B.z;  
      max.z = A.z;
    }  
  }  
}

void SimpleMeshGLScene::buildMeshScene()
{
  meshScene = _builder->build(scene);
  _normalUpdater->updateNormals(meshScene);
}

}

Viewer.h

#ifndef VIEWER_H
#define VIEWER_H

#include <QGLViewer/qglviewer.h>
#include <X3DTK/simplex3dglscene.h>

// Class providing an X3D Viewer by using X3DTK::SimpleX3DGLScene 

class Viewer : public QGLViewer
{
protected :
  void init();
  void draw();
  void keyPressEvent(QKeyEvent *e);
  void loadFile();
  void about();
  QString helpString() const;
  void help() const;
  
private:
  X3DTK::SimpleX3DGLScene scene;
};

#endif

Viewer.cpp

#include "Viewer.h"
#include <qfiledialog.h>
#include <qmessagebox.h> 
#include <X3DTK/kernel.h>

using namespace X3DTK;
using namespace std;

void Viewer::init()
{
#ifdef GL_RESCALE_NORMAL
  glEnable(GL_RESCALE_NORMAL);
#endif
  about();
  loadFile();
}

void Viewer::keyPressEvent(QKeyEvent *e)
{
  switch (e->key())
  {
    case Qt::Key_L : loadFile(); break;
    default:         QGLViewer::keyPressEvent(e);
  }
}

void Viewer::loadFile()
{
  QString name = QFileDialog::getOpenFileName("", "X3D files (*.x3d *.X3D);;All files (*)", this);
  
  // In case of Cancel
  if (name.isEmpty())
    return;

  // Loads the file name
  scene.load(name);
  
  // QGLViewer settings
  setSceneBoundingBox(scene.getBBoxMin().f_data(), scene.getBBoxMax().f_data());
  showEntireScene();
}

void Viewer::draw()
{
  // Draws the scene.
  scene.draw();
}

void Viewer::about()
{
  QMessageBox::about(this, "about the X3DViewer", "this is an example showing how to load and display a simple X3D scene.Type 'h' to display help");
}

QString Viewer::helpString() const
{
  QString message("");
  
  message += "<b>L</b>" + QString(" loads a new file<br>");
  
  message += QGLViewer::helpString();
  
  return message;
}

void Viewer::help() const
{
  QMessageBox *mb = new QMessageBox("help", helpString(), QMessageBox::NoIcon,QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton,QMessageBox::NoButton, NULL, "Help", false,Qt::WStyle_DialogBorder | Qt::WType_Dialog | Qt::WDestructiveClose);
  mb->show();
}

main.cpp

#include "Viewer.h"
#include <qapplication.h>

using namespace X3DTK;
using namespace std;

int main(int argc, char *argv[])
{
  // Read command lines arguments.
  QApplication application(argc, argv);

  // Instantiate the viewer.
  Viewer v;

  // Make the viewer window visible on screen.
  v.show();

  // Set the viewer as the application main widget.
  application.setMainWidget(&v);
  
  // Run main loop.
  return application.exec();
}

Generated on Fri Jul 30 12:02:32 2004 for X3DToolKit by doxygen 1.3.6