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:
X3DTK::MESH::VertexData
aggregates X3DTK::MESH::VertexPointData
, X3DTK::MESH::VertexNormalData
, X3DTK::MESH::VertexColorData
and X3DTK::MESH::VertexTexCoordData
X3DTK::MESH::FaceData
aggregates X3DTK::MESH::FaceNormalData
, X3DTK::MESH::FaceColorData
X3DTK::MESH::MeshData
aggregates X3DTK::MESH::MeshNormalData
, X3DTK::MESH::MeshColorData
, X3DTK::MESH::MeshTexCoordData
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
structure as well as the matrix stack to enable the transformation of the vertices in the world coordinates.enterTransform
and leaveX3DGroupingNode
push and pop the transform matrices. enterMesh
fills the MySimpleMesh
structure thanks to the X3DTK::MESH::MyStructureComputerStateVariables
access.#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 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; } }
#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(); static void enterMesh(Mesh *M); static void enterTransform(Transform *T); static void leaveX3DGroupingNode(X3DGroupingNode *N); }; } } #endif
#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(); } } }
#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
#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(); } } }
#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; }