myStructureComputer

Introduction

In this example, we show how to use simply the MESH scene graph by using its default instantiation enabling not to write template classes. See the Mesh datas page.

Indeed the MESH scene graph is based upon two template nodes which are X3DTK::MESH::TemplateMesh and X3DTK::MESH::TemplateVertex. The X3DTK::MESH::Mesh node and X3DTK::MESH::Mesh node aggregate the default template Mesh data:

The X3DTK::MESH::Mesh is used to fill a structure called MySimpleMesh containing a list of vertices in the world coordinates and a list of faces, each of it being represented by a list of vertex indexes. We define a processor (see glNormalViewer) acting on the MESH scene graph, that transforms all the visited vertices into the world coordinates and stores the indexes of the faces.

Some important functions and classes:

MySimpleMesh

We define the required methods to fill the structure.

MESH::MyStructureComputerStateVariables

We store a pointer to the MySimpleMesh structure as well as the matrix stack to enable the transformation of the vertices in the world coordinates.

MESH::MyStructureComputerCoreVisitor

We define three enter functions for visited nodes. enterTransform and leaveX3DGroupingNode push and pop the transform matrices. enterMesh fills the MySimpleMesh structure thanks to the X3DTK::MESH::MyStructureComputerStateVariables access.

MESH::MyStructureComputer

This is the facade of the processor which aggregates the visitors of the different components.

Code

MySimpleMesh.h

#ifndef MYSIMPLEMESH_H
#define MYSIMPLEMESH_H

#include <vector>
#include <list>

struct MyVertex
{
  float x;
  float y;
  float z;
};

typedef std::list<unsigned int> MyFace;

// MySimpleMesh class.

class MySimpleMesh
{
public:
  MySimpleMesh();
  ~MySimpleMesh();
  
  void addVertex(float x, float y, float z);
  void addFace(const std::list<unsigned int> &indexes);
  void print() const;
  
  inline std::vector<MyVertex> &getVertexArray() {return _vertexArray;};
  inline std::vector<MyFace> &getIndexArray() {return _indexArray;};
  
private:
  std::vector<MyVertex> _vertexArray;
  std::vector<MyFace> _indexArray;
};

#endif

MySimpleMesh.cpp

#include "MySimpleMesh.h"

#include <iostream>

using namespace std;

MySimpleMesh::MySimpleMesh()
{
}

MySimpleMesh::~MySimpleMesh()
{
}
  
void MySimpleMesh::addVertex(float x, float y, float z)
{
  MyVertex v;
  v.x = x;
  v.y = y;
  v.z = z;
  
  _vertexArray.push_back(v);
}

void MySimpleMesh::addFace(const std::list<unsigned int> &indexes)
{
  _indexArray.push_back(indexes);
}

void MySimpleMesh::print() const
{
  cout << "Vertices: " << endl;
  for (vector<MyVertex>::const_iterator v = _vertexArray.begin(); v != _vertexArray.end(); ++v)
    cout << "  " << (*v).x << ", " << (*v).y << ", " << (*v).z << endl;
  
  cout << "Indexes: " << endl;
  for (vector<MyFace>::const_iterator i = _indexArray.begin(); i != _indexArray.end(); ++i)
  {
    MyFace face = *i;
    cout << "  ";
    for (MyFace::const_iterator f = face.begin(); f != face.end(); ++f)
      cout << *f << " ";
    cout << endl;
  }
}

MESH_MyStructureComputerStateVariables.h

#ifndef MYSTRUCTURECOMPUTERGLOBALVARIABLES_H
#define MYSTRUCTURECOMPUTERGLOBALVARIABLES_H

#include "MySimpleMesh.h"

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

namespace X3DTK {
namespace MESH {

// StateVariables for the MyStructureComputer processor.

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

  void init();
  void finish();

  void beginNewMesh();
  inline void addVertex(float x, float y, float z) {_mesh->addVertex(x, y, z);};
  void addFace(const MyFace &face);
  void pushMatrix(const SFMatrix34f &transformation);  
  void popMatrix();

  inline MySimpleMesh *getMesh() const {return _mesh;};  
  SFMatrix34f getMatrix() const {return _matrixStack.front();};

private: 
  MySimpleMesh *_mesh;
  unsigned int _decal;
  std::list<SFMatrix34f> _matrixStack;
};

}
}

#endif

MESH_MyStructureComputerStateVariables.cpp

#include "MESH_MyStructureComputerStateVariables.h"

namespace X3DTK {
namespace MESH {

MyStructureComputerStateVariables::MyStructureComputerStateVariables()
: StateVariables(), _mesh(0), _decal(0)
{
}

void MyStructureComputerStateVariables::init()
{
  _mesh = new MySimpleMesh();
  _matrixStack.push_front(SFMatrix34f::identity);
}

void MyStructureComputerStateVariables::finish()
{
  _matrixStack.clear();
}

void MyStructureComputerStateVariables::beginNewMesh()
{
  _decal = _mesh->getVertexArray().size();
}

void MyStructureComputerStateVariables::addFace(const MyFace &face)
{
  MyFace decalFace = face;
  for (MyFace::iterator it = decalFace.begin(); it != decalFace.end(); ++it)
    *it = _decal + *it;
    
  _mesh->addFace(decalFace);
};

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

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

}
}

MESH_MyStructureComputerCoreVisitor.h

#ifndef MYSTRUCTURECOMPUTERCOREVISITOR_H
#define MYSTRUCTURECOMPUTERCOREVISITOR_H

#include <X3DTK/MESH/scenegraph.h>

#include "MESH_MyStructureComputerStateVariables.h"

namespace X3DTK {
namespace MESH {

class X3DGroupingNode;
class Transform;


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

  static void enterMesh(Mesh *M);
  static void enterTransform(Transform *T);
  static void leaveX3DGroupingNode(X3DGroupingNode *N);
};

}
}

#endif

MESH_MyStructureComputerCoreVisitor.cpp

#include "MESH_MyStructureComputerCoreVisitor.h"

#include <iostream>

using namespace std;

namespace X3DTK {
namespace MESH {

MyStructureComputerCoreVisitor::MyStructureComputerCoreVisitor()
{
  // Enter functions.
  define(Recorder<Mesh>::getEnterFunction(&MyStructureComputerCoreVisitor::enterMesh));
  define(Recorder<Transform>::getEnterFunction(&MyStructureComputerCoreVisitor::enterTransform));
  // Leave function.
  define(Recorder<X3DGroupingNode>::getLeaveFunction(&MyStructureComputerCoreVisitor::leaveX3DGroupingNode));
}

void MyStructureComputerCoreVisitor::enterMesh(Mesh *M)
{
  // StateVariables assignation.
  MyStructureComputerStateVariables *stateVariables = Singleton<MyStructureComputerStateVariables>::getInstance();
    
  SFMatrix34f T = stateVariables->getMatrix();

  // Beginning a new Mesh by memorizing the current vertex index.
  stateVariables->beginNewMesh();

  // filling the vertices.
  for (Mesh::MFVertex::const_iterator v = M->getVertices().begin(); v != M->getVertices().end(); ++v)
  {
    SFPoint3f P = T*(*v)->data().getPoint();
    stateVariables->addVertex(P.x, P.y, P.z);
  }
  
  // filling the faces.
  for (Mesh::MFFace::const_iterator f = M->getFaces().begin(); f != M->getFaces().end(); ++f)
  {
    const SFFace::MFEdge &edges = (*f)->getEdges();
    list<unsigned int> indexList;
    for (SFFace::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e)
      indexList.push_back((*e)->getFromVertex()->getIndex());
    
    stateVariables->addFace(indexList);
  }  
}

void MyStructureComputerCoreVisitor::enterTransform(Transform *T)
{
  Singleton<MyStructureComputerStateVariables>::getInstance()->pushMatrix(T->getTransform());
}

void MyStructureComputerCoreVisitor::leaveX3DGroupingNode(X3DGroupingNode *)
{
  Singleton<MyStructureComputerStateVariables>::getInstance()->popMatrix();
}

}
}

MESH_MyStructureComputer.h

#ifndef MYSTRUCTURECOMPUTER_H
#define MYSTRUCTURECOMPUTER_H

#include "MESH_MyStructureComputerStateVariables.h"
#include "MySimpleMesh.h"

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

namespace X3DTK {
namespace MESH {

// MyStructureComputer processor.

class MyStructureComputer : public X3DOnePassProcessor
{
public:
  MyStructureComputer();
  virtual ~MyStructureComputer();
  
  virtual MySimpleMesh *compute(SFNode N);
};

}
}

#endif

MESH_MyStructureComputer.cpp

#include "MESH_MyStructureComputer.h"
#include "MESH_MyStructureComputerCoreVisitor.h"

namespace X3DTK {
namespace MESH {

MyStructureComputer::MyStructureComputer()
{
  setGraphTraversal(new DFSGraphTraversal());
  setComponentVisitor(new MyStructureComputerCoreVisitor());
}

MyStructureComputer::~MyStructureComputer()
{
  Singleton<MyStructureComputerStateVariables>::removeInstance();
}

MySimpleMesh *MyStructureComputer::compute(SFNode N)
{
  Singleton<MyStructureComputerStateVariables>::getInstance()->init();
  traverse(N);
  Singleton<MyStructureComputerStateVariables>::getInstance()->finish();
  
  return Singleton<MyStructureComputerStateVariables>::getInstance()->getMesh();
}

}
}

main.cpp

#include "MESH_MyStructureComputer.h"

#include <X3DTK/X3D/scenegraph.h>
#include <X3DTK/X3D/meshbuilder.h>
#include <X3DTK/memreleaser.h>

#include <iostream>
#include <X3DTK/graphtester.h>

using namespace X3DTK;
using namespace std;

int main(int argc, char *argv[])
{
  if (argc <= 1)
  {
    cerr << "usage: MyStructureComputer input" << endl;
    exit(0);
  }
  
  // DefaultLoader to load the default X3D Nodes.
  X3D::Loader *loader = Singleton<X3D::Loader>::getInstance();
  // Instanciation of the new MeshBuilder.
  X3D::MeshBuilder *meshbuilder = Singleton<X3D::MeshBuilder>::getInstance();
  // Instanciation of the new MyStructureComputer.
  MESH::MyStructureComputer *msc = Singleton<MESH::MyStructureComputer>::getInstance();  
  
  // Loads the scene.
  X3D::Scene *s = loader->load(argv[1], false);
  MESH::Scene *ms = meshbuilder->build(s);
  MySimpleMesh *mesh = msc->compute(ms);  
 
  GraphTester *gt = Singleton<GraphTester>::getInstance();
  gt->test(ms);
 
  // prints the content.
  mesh->print();
  
  // removes all the instances.
  Singleton<X3D::MeshBuilder>::removeInstance();
  Singleton<MESH::MyStructureComputer>::removeInstance();
  
  Singleton<X3D::Loader>::removeInstance();
  
  return 1;
}

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