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