Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

meshViewer

introduction

This is an example where we want to display and select the different entities of a Mesh structure. We define a processor called 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.

MESH::DrawerStateVariables

In the global variables to the 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 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 necessary to the loading, updating and rendering of the 3D scene. It is also the intermediate between the MESH::Drawer and the Viewer, the events being emitted by the Viewer and treated by the 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 {

// Global variables for the MeshDrawer processor.

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

  // Initializes and finishes the traversal.
  void initTraversal();
  void finishTraversal();

  // Pushes the transformation matrix.
  void pushMatrix(const SFMatrix34f &transformation);  
  
  // Pops the transformation matrix.
  void popMatrix();

  // Saves current matrix state and returns index in saved vector.
  // Call storeMesh() before calling ths function
  int getCurrentMeshId();
  // Saves mesh and associated current matrix.
  void storeMesh(Mesh* mesh);
  
  // Get i Mesh of the model.
  inline const Mesh* getMesh(int i) const {return _meshVector[i];};
  // Gets stored transformation matrix associated with a given Mesh.
  inline SFMatrix34f getMatrix(int i) const {return _matrixVector[i];};

  // Whether or not primitive IDs are pushed.
  inline void setSelectionMode(bool selectionMode) {_selectionMode = selectionMode;};
  inline bool getSelectionMode() const {return _selectionMode;};
    
  // Which mesh primitive type is rendered
  void setPrimitiveType(int primitiveType) {_primitiveType = primitiveType;};
  inline int getPrimitiveType() const {return _primitiveType;};
  
  // Whether each mesh is displayed with a specific color
  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);
}

void DrawerStateVariables::finishTraversal()
{
  _matrixStack.pop_front();
  if (_matrixStack.size() != 0)
    {
      qWarning("Non empty matrix stack at the end of Drawer traversal");
      _matrixStack.clear();
    }
  
  _matrixVector.clear();
  _meshVector.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;


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

  virtual void enterMesh(Mesh *M) const;

  virtual void enterTransform(Transform *T) const;

  virtual void leaveTransform(Transform *T) const;

protected:
  DrawerStateVariables *stateVariables;
};

}
}

#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.
  defineEnterFunction(&DrawerCoreVisitor::enterTransform);
  defineEnterFunction(&DrawerCoreVisitor::enterMesh);
  defineLeaveFunction(&DrawerCoreVisitor::leaveTransform);
  
  // StateVariables assignation.
  stateVariables = GraphTraversal::getInstanceOf<DrawerStateVariables>();
}

void DrawerCoreVisitor::enterTransform(Transform *T) const
{
  glMatrixMode(GL_MODELVIEW);
  stateVariables->pushMatrix(T->getTransform());
  glPushMatrix();
  glMultMatrixf(T->getTransform().toFloat16());
}

void DrawerCoreVisitor::leaveTransform(Transform *T) const
{
  glMatrixMode(GL_MODELVIEW);
  stateVariables->popMatrix();
  glPopMatrix();
}

void DrawerCoreVisitor::enterMesh(Mesh *M) const
{
  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(), end = vertices.end() ; v != end; ++v)
        {
          glPushName((*v)->getIndex());
          SFPoint3f point = (*v)->data().getPoint();
          glRasterPos3fv(point.f_data());
          glPopName();
        }
        glPopName();
      }
      else
      {
        glBegin(GL_POINTS);
        for (Mesh::MFVertex::const_iterator v = vertices.begin(), end = vertices.end() ; v != end; ++v)
        {
          SFPoint3f point = (*v)->data().getPoint();
          glVertex3fv(point.f_data());
        }
        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(), end = edges.end() ; e != 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
        Mesh::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.f_data());
           
        glBegin(GL_LINES);
        SFPoint3f point = (*e)->getFromVertex()->data().getPoint();
        glVertex3fv(point.f_data());
        point = (*e)->getToVertex()->data().getPoint();
        glVertex3fv(point.f_data());
        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(), end = faces.end() ; f != end; ++f)
      {
        if (!normalPerVertex)
        {
          SFVec3f normal = (*f)->data().getNormal();
          glNormal3fv(normal.f_data());
        }

        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 Mesh::MFEdge& edges = (*f)->getEdges();
        for (Mesh::MFEdge::const_iterator e = edges.begin(), end = edges.end() ; e != end; ++e)
        {
          if (normalPerVertex)
          {
            SFVec3f normal = (*e)->getFromVertex()->data().getNormalOfFace(*f);
            glNormal3fv(normal.f_data());
          }
          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.f_data());
        }
        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();
  
  //  Setting parameters.
  void changeDrawPoints();
  void changeDrawEdges();
  void changeDrawFaces(); 
  inline void changeOneColorPerMesh() {stateVariables->changeOneColorPerMesh();}; 
  void setSelectedType(SelectedType selectedType);
  void setSelectedMesh(int selectedMesh);
  void setSelectedId(int selectedId);
  
  // Getting parameters.
  inline SelectedType getSelectedType() const {return selectedType;};
  inline int getSelectedMesh() const {return selectedMesh;};
  inline int getSelectedId() const {return selectedId;};
  
  // Draw methods.
  void drawMesh(X3DNode *N, bool selection = false);
  void drawSelected();
 
protected:
  DrawerStateVariables* stateVariables;
  
  bool drawPoints, drawEdges, drawFaces;
  SelectedType selectedType;
  int selectedMesh;
  int selectedId;

  // Draw methods.
  void drawVertex(const Mesh::SFVertex *vertex);
  void drawEdge(Mesh::SFEdge *edge);
  void drawFace(const Mesh::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)
{
  stateVariables = GraphTraversal::getInstanceOf<DrawerStateVariables>();

  graphTraversal = new DFSGraphTraversal();
  graphTraversal->setComponentVisitor(new DrawerCoreVisitor());
}

Drawer::~Drawer()
{
  GraphTraversal::removeInstanceOf<DrawerStateVariables>();
  
  delete graphTraversal;
}

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

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

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

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)
{
  stateVariables->setSelectionMode(selection);
  
  if (selection || drawPoints)
  {
    stateVariables->setPrimitiveType(VERTICES);
    stateVariables->initTraversal();
    graphTraversal->traverse(N);
    stateVariables->finishTraversal();
  }  
  if (selection || drawEdges)
  {
    stateVariables->setPrimitiveType(EDGES);
    stateVariables->initTraversal();
    graphTraversal->traverse(N);
    stateVariables->finishTraversal();
  }  
  if (selection || drawFaces)
  {
    stateVariables->setPrimitiveType(FACES);  
    stateVariables->initTraversal();
    graphTraversal->traverse(N);
    stateVariables->finishTraversal();
  }  
}

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

  glPushMatrix();
  glMultMatrixf(stateVariables->getMatrix(selectedMesh).toFloat16());

  const Mesh *mesh = stateVariables->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);
      Mesh::SFVertex* vertex = (mesh->getVertices())[selectedId];
      const Mesh::MFFace& faces = vertex->getFaces();

      // Normal
      Mesh::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 Mesh::MFEdge& edges = vertex->getEdges();
      for (Mesh::MFEdge::const_iterator e = edges.begin(), end = edges.end() ; e != end; ++e)
        drawEdge(*e);

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

      // Normal
      Mesh::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 Mesh::MFFace& lfaces = edge->getLeftFaces();
      for (Mesh::MFFace::const_iterator f = lfaces.begin(), end = lfaces.end() ; f != end; ++f)
        drawFace(*f);

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

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

      // Normal
      Mesh::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 (Mesh::MFEdge::const_iterator e = edges.begin(), end = edges.end() ; e != end; ++e)
      {
        glColor3f(0.0, 0.8, 0.0);
        drawEdge(*e);
        glColor3f(0.7, 0.7, 0.7);
        drawVertex((*e)->getFromVertex());
      }

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

  glPopMatrix();
}

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

void Drawer::drawEdge(Mesh::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 Mesh::SFFace *face)
{
  const Mesh::MFEdge& edges = face->getEdges();
  glBegin(GL_POLYGON);
  for (Mesh::MFEdge::const_iterator e = edges.begin(), end = edges.end() ; e != 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>

namespace X3DTK {

class X3DMemReleaser;

namespace X3D {

class Scene;
class Loader;
class X3DBBoxUpdater;

}

namespace MESH {

class Scene;
class MeshNormalUpdater;
class Drawer;

}


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();
  
  // Events dispatched to the MeshDrawer.
  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);};
  
  // Gets the parameters.
  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::X3DBBoxUpdater *_bboxupdater;
  X3D::MeshBuilder *_builder;
  MESH::MeshNormalUpdater *_normalUpdater;
  MESH::Drawer *_drawer;
  X3DMemReleaser *_releaser;
};

}

#endif

SimpleMeshGLScene.cpp

#include "SimpleMeshGLScene.h"

#include <X3DTK/x3d_scenegraph.h>
#include <X3DTK/x3d_bboxupdater.h>
#include <X3DTK/mesh_meshnormalupdater.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 = X3DLoader::getInstanceOf<X3D::Loader>();
  _bboxupdater = X3DProcessor::getInstanceOf<X3D::BBoxUpdater>();
  _builder = X3DProcessor::getInstanceOf<X3D::MeshBuilder>();
  _drawer = X3DProcessor::getInstanceOf<MESH::Drawer>();
  _normalUpdater = X3DProcessor::getInstanceOf<MESH::MeshNormalUpdater>();
  _releaser = X3DProcessor::getInstanceOf<MemReleaser>();
}

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 "SimpleMeshGLScene.h"


class Viewer : public QGLViewer
{
public:
  Viewer();
  ~Viewer();
  
protected :
  void loadFile();
  void keyPressEvent(QKeyEvent *e);
  void init();
  void draw();
  void about();
  QString helpString() const;
  void select(const QMouseEvent* e);
  void help() const;
  
private:
  X3DTK::SimpleMeshGLScene scene;
  X3DTK::BBox BB;
  
  // Events dispatched to the scene.
  inline void toggleDrawPoints() {scene.changeDrawPoints();};
  inline void toggleDrawEdges() {scene.changeDrawEdges();};
  inline void toggleDrawFaces() {scene.changeDrawFaces();};
  inline void toggleOneColorPerMesh() {scene.changeOneColorPerMesh();};

};

#endif

Viewer.cpp

#include "Viewer.h"
#include <math.h>
#include <iostream>
#include <qfiledialog.h>
#include <qmessagebox.h> 

using namespace X3DTK;
using namespace std;

Viewer::Viewer()
{
}

Viewer::~Viewer()
{
  scene.release();
}

void Viewer::keyPressEvent(QKeyEvent *e)
{
  switch (e->key())
  {
    case Qt::Key_L : loadFile(); updateGL(); break;
    case Qt::Key_V : toggleDrawPoints(); updateGL(); break;
    case Qt::Key_E : toggleDrawEdges(); updateGL(); break;
    case Qt::Key_F : toggleDrawFaces(); updateGL(); break;
    case Qt::Key_C : toggleOneColorPerMesh(); updateGL(); 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);

  setSceneBoundingBox(scene.getBBoxMin().f_data(), scene.getBBoxMax().f_data());
  setSceneRadius(2.0f*sceneRadius());
  showEntireScene(); 
}

void Viewer::init()
{
  glPolygonOffset(-2.0, -2.0);
#ifdef GL_RESCALE_NORMAL
  glEnable(GL_RESCALE_NORMAL);
#endif
  loadFile();
}

void Viewer::draw()
{
  scene.drawMesh();
  scene.drawSelected();
}

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

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();
}

void Viewer::select(const QMouseEvent* e)
{
  // Make openGL context current
  makeCurrent();
  
  const int SENSITIVITY = 6;
  const int NB_HITS_MAX = 32768;
  
  // Prepare the selection mode
  static GLuint hits[NB_HITS_MAX];
  
  glSelectBuffer(NB_HITS_MAX, hits);
  glRenderMode(GL_SELECT);
  glInitNames();

  // Loads the matrices
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  GLint viewport[4];
  glGetIntegerv(GL_VIEWPORT,viewport);
  camera()->getViewport(viewport);
  gluPickMatrix(static_cast<GLdouble>(e->x()), static_cast<GLdouble>(e->y()), SENSITIVITY, SENSITIVITY, viewport);

  // Don't use loadProjectionMatrix() directly as it clears the GL_PROJECTION matrix with a glLoadIdentity.
  // The false flag indicates that no glLoadIdentity should be called, in order to combine the matrices.
  camera()->loadProjectionMatrix(false);
  camera()->loadModelViewMatrix();
  
  // Render scene with objects ids
  scene.drawMesh(true);
  
  glFlush();

  // Get the results
  GLint nb_hits = glRenderMode(GL_RENDER);

  // Too many elements in selection buffer
  if (nb_hits < 0)
    return;

  // No selection
  if (nb_hits == 0)
  {
    scene.setSelectedType(NOTHING);
    cout << "No selection" << endl;
    return;
  }
  
  // Interpret results
  unsigned int zMin = hits[1];
  scene.setSelectedMesh(hits[3]);
  scene.setSelectedType(static_cast<SelectedType>(hits[4]));
  scene.setSelectedId(hits[5]);
  
  for (int i=1; i<nb_hits; ++i)
    // Prefer vertices over edges and edges over faces
    if (hits[i*6+1] < zMin+(((int)scene.getSelectedType() - hits[i*6+4])*200000))
    {
      zMin = hits[i*6+1];
      scene.setSelectedMesh(hits[i*6+3]);
      scene.setSelectedType(static_cast<SelectedType>(hits[i*6+4]));
      scene.setSelectedId(hits[i*6+5]);
    }
  
  switch (scene.getSelectedType())
  {
    case NOTHING : break;
    case VERTICES :cout << "Vertex "; break;
    case EDGES :   cout << "Edge "; break;
    case FACES :   cout << "Face "; break;
  }
  cout << scene.getSelectedId() << " selected on mesh " << scene.getSelectedMesh() << endl;
}

QString Viewer::helpString() const
{
  QString message("<b>L</b> loads a new file<br>");
  message += "<b>F</b> toggles face display<br>";
  message += "<b>E</b> toggles edge display<br>";
  message += "<b>V</b> toggles vertex display<br>";
  message += "<b>C</b> toggles one color per mesh<br>";
  message += "<b>Shift+click</b> to select an element<br>";
  message += "<hr>";
  message += QGLViewer::helpString();
  return message;
}

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 Thu Dec 4 13:25:53 2003 for X3DToolKit by doxygen1.2.18