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 MeshDrawer 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::MeshDrawerGlobalVariables

In the global variables to the MeshDrawer traversal, we store the variables necessary to the display for the GL selection mechanism.

MESH::MeshDrawerCoreVisitor

In the visitor of the Core component of the code>MeshDrawer processor, we draw the different mesh entities and execute the GL commands relative to selection.

MESH::MeshDrawer

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 MeshDrawer and the Viewer, the events being emitted by the Viewer and treated by the MeshDrawer.

Viewer

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

MeshDrawerGlobalVariables.h




#ifndef MESH_DRAWER_GLOBALVARIABLES_H
#define MESH_DRAWER_GLOBALVARIABLES_H

#include <X3DTK/meshscenegraph.h>

#include <list>
#include <vector>

namespace X3DTK {
namespace MESH {

// Global variables for the MeshDrawer processor.

class MeshDrawerGlobalVariables : public GlobalVariables
{
public:
  MeshDrawerGlobalVariables();

  // 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

MeshDrawerGlobalVariables.cpp

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

namespace X3DTK {
namespace MESH {

MeshDrawerGlobalVariables::MeshDrawerGlobalVariables()
: GlobalVariables(), _selectionMode(false), _oneColorPerMesh(true), _primitiveType(1)
{}

void MeshDrawerGlobalVariables::initTraversal()
{
  _matrixStack.push_front(identity34());
}

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

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

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

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

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

}
}

MeshDrawerCoreVisitor.h




#ifndef MESH_DRAWER_COREVISITOR_H
#define MESH_DRAWER_COREVISITOR_H

#include <X3DTK/meshscenegraph.h>
#include "MeshDrawerGlobalVariables.h"

namespace X3DTK {
namespace MESH {

class Transform;


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

  virtual void enterMesh(Mesh *M) const;

  virtual void enterTransform(Transform *T) const;

  virtual void leaveTransform(Transform *T) const;

protected:
  MeshDrawerGlobalVariables *globalVariables;
};

}
}

#endif

MeshDrawerCoreVisitor.cpp

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

using namespace std;

namespace X3DTK {
namespace MESH {

MeshDrawerCoreVisitor::MeshDrawerCoreVisitor()
{
  // Enter and leave functions.
  defineNewEnterFunction(&MeshDrawerCoreVisitor::enterTransform);
  defineNewEnterFunction(&MeshDrawerCoreVisitor::enterMesh);
  defineNewLeaveFunction(&MeshDrawerCoreVisitor::leaveTransform);
  
  // GlobalVariables assignation.
  globalVariables = GVManager::getInstanceOf<MeshDrawerGlobalVariables>();
}

void MeshDrawerCoreVisitor::enterTransform(Transform *T) const
{
  globalVariables->pushMatrix(T->getTransform());
  glPushMatrix();
  glMultMatrixf(T->getTransform().toFloat16());
}

void MeshDrawerCoreVisitor::leaveTransform(Transform *) const
{
  globalVariables->popMatrix();
  glPopMatrix();
}

void MeshDrawerCoreVisitor::enterMesh(Mesh *M) const
{
  globalVariables->storeMesh(M);
  int meshId = globalVariables->getCurrentMeshId();

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

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

      if (globalVariables->getSelectionMode())
      {
        glPushName(1);
        for (Mesh::MVertex::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::MVertex::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::MEdge& edges = M->getEdges();

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

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

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

        // Normal
        Mesh::Face* firstFace = (*((*e)->getLeftFaces().begin()));
         
        if (!firstFace)
          firstFace = (*((*e)->getRightFaces().begin()));
        SFVec3f normal;
        if (normalPerVertex)
          normal = (*e)->getFromVertex()->data().getFaceData(firstFace)->getNormal();
        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 (globalVariables->getSelectionMode())
          glPopName();
      }
        
      if (globalVariables->getSelectionMode())
        glPopName();
        
      break;
    }

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

      if (globalVariables->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::MFace::const_iterator f = faces.begin(), end = faces.end() ; f != end; ++f)
      {
        if (!normalPerVertex)
        {
          SFVec3f normal = (*f)->data().getNormal();
          glNormal3fv(normal.f_data());
        }

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

        glBegin(GL_POLYGON);
        const Mesh::MEdge& edges = (*f)->getEdges();
        for (Mesh::MEdge::const_iterator e = edges.begin(), end = edges.end() ; e != end; ++e)
        {
          if (normalPerVertex)
          {
            SFVec3f normal = (*e)->getFromVertex()->data().getFaceData(*f)->getNormal();
            glNormal3fv(normal.f_data());
          }
          if ((colorPerVertex) && (!globalVariables->getOneColorPerMesh()))
          {
            SFColorRGBA color = (*e)->getFromVertex()->data().getFaceData(*f)->getColor();
            glColor4f(color.r, color.g, color.b, color.a);
          }
          
          SFPoint3f point = (*e)->getFromVertex()->data().getPoint();
          glVertex3fv(point.f_data());
        }
        glEnd();

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

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

      break;
    }
  }

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

}
}

MeshDrawer.h




#ifndef MESH_DRAWER_H
#define MESH_DRAWER_H

#include "MeshDrawerGlobalVariables.h"

#include <X3DTK/kernel.h>
#include <X3DTK/meshscenegraph.h>

namespace X3DTK {

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

namespace MESH {

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

class MeshDrawer : public X3DOnePassProcessor
{
public:
  MeshDrawer();
  virtual ~MeshDrawer();
  
  //  Setting parameters.
  void changeDrawPoints();
  void changeDrawEdges();
  void changeDrawFaces(); 
  inline void changeOneColorPerMesh() {globalVariables->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:
  MeshDrawerGlobalVariables* globalVariables;
  
  bool drawPoints, drawEdges, drawFaces;
  SelectedType selectedType;
  int selectedMesh;
  int selectedId;

  // Draw methods.
  void drawVertex(const Mesh::Vertex *vertex);
  void drawEdge(Mesh::Edge *edge);
  void drawFace(const Mesh::Face *face);
};

}
}

#endif

MeshDrawer.cpp

#include "MeshDrawer.h"
#include "MeshDrawerCoreVisitor.h"

namespace X3DTK {
namespace MESH {

MeshDrawer::MeshDrawer()
: X3DOnePassProcessor(), drawPoints(false), drawEdges(true), drawFaces(true)
{
  graphTraversal = new DFSGraphTraversal();
  graphTraversal->setComponentVisitor(new MeshDrawerCoreVisitor());
  
  globalVariables = GVManager::getInstanceOf<MeshDrawerGlobalVariables>();
}

MeshDrawer::~MeshDrawer()
{
  delete graphTraversal;
}

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

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

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

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

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

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

void MeshDrawer::drawMesh(X3DNode *N, bool selection)
{
  globalVariables->setSelectionMode(selection);
  
  if (selection || drawPoints)
  {
    globalVariables->setPrimitiveType(VERTICES);
    globalVariables->initTraversal();
    graphTraversal->traverse(N);
    globalVariables->finishTraversal();
  }  
  if (selection || drawEdges)
  {
    globalVariables->setPrimitiveType(EDGES);
    globalVariables->initTraversal();
    graphTraversal->traverse(N);
    globalVariables->finishTraversal();
  }  
  if (selection || drawFaces)
  {
    globalVariables->setPrimitiveType(FACES);  
    globalVariables->initTraversal();
    graphTraversal->traverse(N);
    globalVariables->finishTraversal();
  }  
}

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

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

  const Mesh *mesh = globalVariables->getMesh(selectedMesh);
  bool normalPerVertex = mesh->data().hasVertexNormal();

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

      // Normal
      Mesh::Face* firstFace = (*(faces.begin()));
      SFVec3f normal;
      if (normalPerVertex)
        normal = vertex->data().getFaceData(firstFace)->getNormal();
      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::MEdge& edges = vertex->getEdges();
      for (Mesh::MEdge::const_iterator e = edges.begin(), end = edges.end() ; e != end; ++e)
        drawEdge(*e);

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

      // Normal
      Mesh::Face* firstFace = (*(edge->getLeftFaces().begin()));
      if (!firstFace)
        firstFace = (*(edge->getRightFaces().begin()));
      SFVec3f normal;
      if (normalPerVertex)
        normal = edge->getFromVertex()->data().getFaceData(firstFace)->getNormal();
      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::MFace& lfaces = edge->getLeftFaces();
      for (Mesh::MFace::const_iterator f = lfaces.begin(), end = lfaces.end() ; f != end; ++f)
        drawFace(*f);

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

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

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

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

      for (Mesh::MEdge::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 MeshDrawer::drawVertex(const Mesh::Vertex *vertex)
{
  glBegin(GL_POINTS);
  SFPoint3f point = vertex->data().getPoint();
  glVertex3fv(point.f_data());
  glEnd();
}

void MeshDrawer::drawEdge(Mesh::Edge *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 MeshDrawer::drawFace(const Mesh::Face *face)
{
  const Mesh::MEdge& edges = face->getEdges();
  glBegin(GL_POLYGON);
  for (Mesh::MEdge::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 "MeshDrawer.h"

#include <X3DTK/kernel.h>
#include <X3DTK/meshbuilder.h>

namespace X3DTK {

class X3DMemReleaser;

namespace X3D {

class Scene;
class Loader;
class X3DBBoxUpdater;

}

namespace MESH {

class Scene;
class MeshNormalUpdater;
class MeshDrawer;

}


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::MeshDrawer *_drawer;
  X3DMemReleaser *_releaser;
};

}

#endif

SimpleMeshGLScene.cpp

#include "SimpleMeshGLScene.h"

#include <X3DTK/x3dscenegraph.h>
#include <X3DTK/bboxupdater.h>
#include <X3DTK/meshnormalupdater.h>
#include <X3DTK/memreleaser.h>
#include <X3DTK/meshscenegraph.h>

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

using namespace std;

namespace X3DTK {

SimpleMeshGLScene::SimpleMeshGLScene()
: scene(0), meshScene(0)
{
  _loader = new X3D::Loader();
  _bboxupdater = new X3D::BBoxUpdater();
  _builder = new X3D::MeshBuilder();
  _drawer = new MESH::MeshDrawer();
  _normalUpdater = new MESH::MeshNormalUpdater();
  _releaser = new MemReleaser();
}

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

  delete _loader;
  delete _bboxupdater;
  delete _builder;
  delete _drawer;
  delete _normalUpdater;
  delete _releaser;
}

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

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


Generated on Thu Oct 9 13:50:57 2003 for X3DToolKit by doxygen1.2.18