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

meshTransformComputer

Introduction

This example is about how to write a template X3DTK::X3DProcessor of the MESH scene graph. The MESH scene graph is based upon two template nodes which are X3DTK::MESH::Mesh and X3DTK::MESH::VertexSet, allowing to write generic template processors that have these template parameters.

Here we write a simple X3DTK::X3DProcessor that traverses the MESH scene graph and prints some basic informations which are the matrix transformations to the world coordinates as well as the list of points (in the world coordinates) for a X3DTK::MESH::Mesh. For an example of processor creation see glNormalViewer.

This example illustrates simply the use of templates and the Mesh data mechanism. Indeed the flexibility of the library is that the user is free to choose the Mesh data and use any processor. At the instantiation of the template processor, the compilation will succeed depending on the presence of required data, allowing to have optional data. For more details about this mechanism, I recommend you to see ... or the meshExtension example.

MESH::TransformComputerStateVariables

We store the matrix stack to enable the transformation of the vertices in the world coordinates.

MESH::TransformComputerCoreVisitor

We define three enter functions for visited nodes. enterTransform and leaveX3DGroupingNode pushes and pops the transform matrices. enterMesh prints the informations. We test the presence of the VertexPointData by a call to the template method find of VData. Here this data is optional and the code will compile if it is not present in VData.

MESH::TransformComputer

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

Code

MESH_TransformComputerStateVariables.h

#ifndef MESHTRANSFORMCOMPUTERGLOBALVARIABLES_H
#define MESHTRANSFORMCOMPUTERGLOBALVARIABLES_H

#include <X3DTK/kernel.h>

#include <list>

namespace X3DTK {
namespace MESH {

// State variables for the MeshTransformComputer processor.

template<class MData, class VData, class EData, class FData, bool readOnly>
class TransformComputerStateVariables : public StateVariables
{
public:
  TransformComputerStateVariables();

  void init();
  void finish();

  void pushMatrix(const SFMatrix34f &transformation);  
  void popMatrix();
  
  SFMatrix34f getMatrix() const {return _matrixStack.front();};

private: 
  std::list<SFMatrix34f> _matrixStack;
};

}
}

#include "MESH_TransformComputerStateVariables.inl"

#endif

MESH_TransformComputerStateVariables.inl

namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool readOnly>
TransformComputerStateVariables<MData, VData, EData, FData, readOnly>::TransformComputerStateVariables()
: StateVariables()
{
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputerStateVariables<MData, VData, EData, FData, readOnly>::init()
{
  _matrixStack.push_front(SFMatrix34f::identity);
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputerStateVariables<MData, VData, EData, FData, readOnly>::finish()
{
  _matrixStack.clear();
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputerStateVariables<MData, VData, EData, FData, readOnly>::pushMatrix(const SFMatrix34f &transformation)
{
  _matrixStack.push_front(_matrixStack.front()*transformation);
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputerStateVariables<MData, VData, EData, FData, readOnly>::popMatrix()
{
  _matrixStack.pop_front();
}

}
}

MESH_TransformComputerCoreVisitor.h

#ifndef MESHTRANSFORMCOMPUTERCOREVISITOR_H
#define MESHTRANSFORMCOMPUTERCOREVISITOR_H

#include "MESH_TransformComputerStateVariables.h"

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

namespace X3DTK {
namespace MESH {

class X3DGroupingNode;
class Transform;

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

template<class MData, class VData, class EData, class FData, bool readOnly>
class TransformComputerCoreVisitor : public CoreVisitor
{
public:
  TransformComputerCoreVisitor();

  static void enterMesh(Mesh<MData, VData, EData, FData, readOnly> *M);
  static void enterTransform(Transform *T);
  static void leaveX3DGroupingNode(X3DGroupingNode *N);
};

}
}

#include "MESH_TransformComputerCoreVisitor.inl"

#endif

MESH_TransformComputerCoreVisitor.inl

namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool readOnly>
TransformComputerCoreVisitor<MData, VData, EData, FData, readOnly>::TransformComputerCoreVisitor()
{
  // Enter functions.
  defineEnterFunction(&TransformComputerCoreVisitor::enterMesh);
  defineEnterFunction(&TransformComputerCoreVisitor::enterTransform);
  // Leave function
  defineLeaveFunction(&TransformComputerCoreVisitor::leaveX3DGroupingNode);
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputerCoreVisitor<MData, VData, EData, FData, readOnly>::enterMesh(Mesh<MData, VData, EData, FData, readOnly> *M)
{
  // StateVariables assignation.
  TransformComputerStateVariables<MData, VData, EData, FData, readOnly> *stateVariables = GraphTraversal::getInstanceOf<TransformComputerStateVariables<MData, VData, EData, FData, readOnly> >();
  
  std::cout << "enter Mesh" << std::endl;
  std::cout << "Transform:" << std::endl << stateVariables->getMatrix() << std::endl;
  std::cout << "  number of vertices = " << M->getVertices().size() << std::endl;
  
  // Test the optional presence of MESH::VertexPointData in VData.
  if (VData::template find<MESH::VertexPointData>())
  {
    // Accessing the MESH::VertexPointData of VData.
    for (typename Mesh<MData, VData, EData, FData, readOnly>::MFVertex::const_iterator it = M->getVertices().begin(); it != M->getVertices().end(); ++it)
      std::cout << (*it)->template ogetData<MESH::VertexPointData>().getPoint() << std::endl;
  }    
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputerCoreVisitor<MData, VData, EData, FData, readOnly>::enterTransform(Transform *T)
{
  // Pushing the current transformation matrix on the stack.
  GraphTraversal::getInstanceOf<TransformComputerStateVariables<MData, VData, EData, FData, readOnly> >()->pushMatrix(T->getTransform());
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputerCoreVisitor<MData, VData, EData, FData, readOnly>::leaveX3DGroupingNode(X3DGroupingNode *)
{
  // Poping the current transformation matrix of the stack.
  GraphTraversal::getInstanceOf<TransformComputerStateVariables<MData, VData, EData, FData, readOnly> >()->popMatrix();
}

}
}

MESH_TransformComputer.h

#ifndef MESHTRANSFORMCOMPUTER_H
#define MESHTRANSFORMCOMPUTER_H

#include "MESH_TransformComputerStateVariables.h"
#include "MESH_TransformComputerCoreVisitor.h"

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

namespace X3DTK {
namespace MESH {

// MeshTransformComputer processor.

template<class MData, class VData, class EData, class FData, bool readOnly>
class TransformComputer : public X3DOnePassProcessor
{
public:
  TransformComputer();
  virtual ~TransformComputer();
  
  virtual void print(SFNode N);
 
protected:
  TransformComputerStateVariables<MData, VData, EData, FData, readOnly> *stateVariables;
};

}
}

#include "MESH_TransformComputer.inl"

#endif

MESH_TransformComputer.inl

namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool readOnly>
TransformComputer<MData, VData, EData, FData, readOnly>::TransformComputer()
{
  // Getting the StateVariables
  stateVariables = GraphTraversal::getInstanceOf<TransformComputerStateVariables<MData, VData, EData, FData, readOnly> >();
    
  graphTraversal = new DFSGraphTraversal();
  graphTraversal->setComponentVisitor(new TransformComputerCoreVisitor<MData, VData, EData, FData, readOnly>());
}

template<class MData, class VData, class EData, class FData, bool readOnly>
TransformComputer<MData, VData, EData, FData, readOnly>::~TransformComputer()
{
  GraphTraversal::removeInstanceOf<TransformComputerStateVariables<MData, VData, EData, FData, readOnly> >();

  delete graphTraversal;
}

template<class MData, class VData, class EData, class FData, bool readOnly>
void TransformComputer<MData, VData, EData, FData, readOnly>::print(SFNode N)
{
  // Testing the presence of MESH::VertexPointData
  if (VData::template find<MESH::VertexPointData>())
  {
    stateVariables->init();
    graphTraversal->traverse(N);
    stateVariables->finish();
  }  
}

}
}

main.cpp

#include "MESH_TransformComputer.h"

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

#include <iostream>

using namespace X3DTK;
using namespace std;

int main(int argc, char *argv[])
{
  if (argc <= 1)
  {
    cerr << "usage: meshtransformcomputer input" << endl;
    exit(0);
  }
  
  // DefaultLoader to load the default X3D Nodes.
  X3D::Loader *loader = X3DLoader::getInstanceOf<X3D::Loader>();
  // Instanciation of the new MeshBuilder.
  X3D::MeshBuilder<MESH::MeshData, MESH::VertexData, MESH::EdgeData, MESH::FaceData, true> *meshbuilder = X3DProcessor::getInstanceOf<X3D::MeshBuilder<MESH::MeshData, MESH::VertexData, MESH::EdgeData, MESH::FaceData, true> >();
  // Instanciation of the new MeshTransformComputer.
  MESH::TransformComputer<MESH::MeshData, MESH::VertexData, MESH::EdgeData, MESH::FaceData, true> *mtc = X3DProcessor::getInstanceOf<MESH::TransformComputer<MESH::MeshData, MESH::VertexData, MESH::EdgeData, MESH::FaceData, true> >();  
  
  // Loads the scene.
  X3D::Scene *s = loader->load(argv[1], false);
  MESH::Scene *ms = meshbuilder->build(s);
  
  // Prints the scene.
  mtc->print(ms);  
  
  // removes all instances.
  X3DProcessor::removeAllInstances();  
  X3DLoader::removeInstanceOf<X3D::Loader>();
    
  return 1;
}

Generated on Wed Apr 7 12:15:27 2004 for X3DToolKit by doxygen 1.3.3