Indeed the MESH scene graph is based upon two template nodes which are X3DTK::MESH::Mesh and X3DTK::MESH::VertexSet. The X3DTK::MESH::DefaultMesh aggregates the default template Mesh data:
#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
#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 it = _vertexArray.begin(); it != _vertexArray.end(); ++it) cout << " " << (*it).x << ", " << (*it).y << ", " << (*it).z << endl; cout << "Indexes: " << endl; for (vector<MyFace>::const_iterator it = _indexArray.begin(); it != _indexArray.end(); ++it) { MyFace face = *it; cout << " "; for (MyFace::const_iterator itIndex = face.begin(); itIndex != face.end(); ++itIndex) cout << *itIndex << " "; cout << endl; } }
#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
#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(); } } }
#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(); virtual void enterMesh(DefMesh *M) const; virtual void enterTransform(Transform *T) const; virtual void leaveX3DGroupingNode(X3DGroupingNode *N) const; protected: MyStructureComputerStateVariables *stateVariables; }; } } #endif
#include "MESH_MyStructureComputerCoreVisitor.h" #include <iostream> using namespace std; namespace X3DTK { namespace MESH { MyStructureComputerCoreVisitor::MyStructureComputerCoreVisitor() { // Enter functions. defineEnterFunction(&MyStructureComputerCoreVisitor::enterMesh); defineEnterFunction(&MyStructureComputerCoreVisitor::enterTransform); // Leave function. defineLeaveFunction(&MyStructureComputerCoreVisitor::leaveX3DGroupingNode); // StateVariables assignation. stateVariables = GraphTraversal::getInstanceOf<MyStructureComputerStateVariables>(); } void MyStructureComputerCoreVisitor::enterMesh(DefMesh *M) const { SFMatrix34f T = stateVariables->getMatrix(); // Beginning a new Mesh by memorizing the current vertex index. stateVariables->beginNewMesh(); // filling the vertices. for (DefMesh::MFVertex::const_iterator it = M->getVertices().begin(); it != M->getVertices().end(); ++it) { SFPoint3f P = T*(*it)->data().getPoint(); stateVariables->addVertex(P.x, P.y, P.z); } // filling the faces. for (DefMesh::MFFace::const_iterator it = M->getFaces().begin(); it != M->getFaces().end(); ++it) { const DefSFFace::MFEdge &edges = (*it)->getEdges(); list<unsigned int> indexList; for (DefSFFace::MFEdge::const_iterator itEdge = edges.begin(); itEdge != edges.end(); ++itEdge) indexList.push_back((*itEdge)->getFromVertex()->getIndex()); stateVariables->addFace(indexList); } } void MyStructureComputerCoreVisitor::enterTransform(Transform *T) const { stateVariables->pushMatrix(T->getTransform()); } void MyStructureComputerCoreVisitor::leaveX3DGroupingNode(X3DGroupingNode *) const { stateVariables->popMatrix(); } } }
#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); protected: MyStructureComputerStateVariables *stateVariables; }; } } #endif
#include "MESH_MyStructureComputer.h" #include "MESH_MyStructureComputerCoreVisitor.h" namespace X3DTK { namespace MESH { MyStructureComputer::MyStructureComputer() { // Getting the StateVariables. stateVariables = GraphTraversal::getInstanceOf<MyStructureComputerStateVariables>(); graphTraversal = new DFSGraphTraversal(); graphTraversal->setComponentVisitor(new MyStructureComputerCoreVisitor()); } MyStructureComputer::~MyStructureComputer() { GraphTraversal::removeInstanceOf<MyStructureComputerStateVariables>(); delete graphTraversal; } MySimpleMesh *MyStructureComputer::compute(SFNode N) { stateVariables->init(); graphTraversal->traverse(N); stateVariables->finish(); return stateVariables->getMesh(); } } }
#include "MESH_MyStructureComputer.h" #include <X3DTK/X3D/scenegraph.h> #include <X3DTK/X3D/meshbuilder.h> #include <X3DTK/memreleaser.h> #include <iostream> 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 = X3DLoader::getInstanceOf<X3D::Loader>(); // Instanciation of the new MeshBuilder. X3D::DefMeshBuilder *meshbuilder = X3DProcessor::getInstanceOf<X3D::DefMeshBuilder>(); // Instanciation of the new MyStructureComputer. MESH::MyStructureComputer *msc = X3DProcessor::getInstanceOf<MESH::MyStructureComputer>(); // Loads the scene. X3D::Scene *s = loader->load(argv[1], false); MESH::Scene *ms = meshbuilder->build(s); MySimpleMesh *mesh = msc->compute(ms); // prints the content. mesh->print(); // removes all the instances. X3DProcessor::removeAllInstances(); X3DLoader::removeInstanceOf<X3D::Loader>(); return 1; }