Home | Hierarchy | Members | Alphabetical | Related Pages |
draw()
function so you can display it.Let me insist on this again: when loading a VRML file you will just be given the content of the file in a C++ structure. No other computations are done. For example, the wrl::Group standard node has field wrl::Group::bboxCenter and wrl::Group::bboxSize. A VRML file might specify an bbox for a given group. But if is not the case, this field will be set to the default value specified y the standard and will not be computed by the loader. So you cannot rely on its value.
#ifndef TRAVERSER_H #define TRAVERSER_H class Traverser { public: void operator()(wrl::Node* node); protected: void treat(wrl::Group*); void treat(wrl::Shape*); void treat(wrl::Sphere*); void treat(wrl::Switch*); void treat(wrl::Transform*); }; #endif // TRAVERSER_H
void operator()(wrl::Node* node);
one. Here is what its implementation looks like: Node
as a "shortcut" for the true (completely qualified) name wrl::Node
. void Traverser::operator()(Node* node) { if (node == NULL) return; { Group* n = dynamic_cast<Group*>(node); if (n!=NULL) { treat(n); return; } } { Shape* n = dynamic_cast<Shape*>(node); if (n!=NULL) { treat(n); return; } } { Sphere* n = dynamic_cast<Sphere*>(node); if (n!=NULL) { treat(n); return; } } { Switch* n = dynamic_cast<Switch*>(node); if (n!=NULL) { treat(n); return; } } { Transform* n = dynamic_cast<Transform*>(node); if (n!=NULL) { treat(n); return; } } } // end of void Traverser::operator()(Node* node)
dynamic_cast
.
After you have written this dispatching function, you just need to write the appropriate code in the relevant treat
method. For example, here is what the usual treatment is for a wrl::Group node:
void Traverser::treat(Group* g) { for (MFNode::const_iterator iter = g->children.begin(); iter != g->children.end();++iter) { (*this)(*iter); } } // end of void Traverser::treat(Group* g)
For any other type of standard node, you will have to define the appropriate treat()
method in you traverser class. Don't forget to also add the corresponding lines in the dispatching function.
treat()
method for all standard node, and a complete dispatcher. The default method does nothing except for the grouping nodes listed below:
for which children are recursively traversed (actually it does a little bit more, as you will see in page Using the Transformator class, but for the moment it is not important).
#ifndef SPHERECOUNTER_H #define SPHERECOUNTER_H #include <xdkwrl/tools/traverser.h> class SphereCounter : public wrl::Traverser { public: SphereCounter(); unsigned int nbSpheres() const; protected: virtual void treat(wrl::Sphere*); private: unsigned int nbSpheres_; }; #endif // SPHERECOUNTER_H
xdkwrl/tools/traverser.h
. Then we override the treat(wrl::Sphere*) method
.The implementation is no that much complex:
#include "spherecounter.h" using namespace wrl; SphereCounter::SphereCounter() : nbSpheres_(0) { } unsigned int SphereCounter::nbSpheres() const { return nbSpheres_; } void SphereCounter::treat(wrl::Sphere*) { ++nbSpheres_; }
Finally, we put all this together, defining a main
function to load a VRML file (see Section Loading a VRML file for an explanation) and "apply" a sphere counter to its nodes.
#include "spherecounter.h" #include <xdkwrl/scene.h> #include <xdkwrl/tools/argstream.h> #include <iostream> #include <string> using namespace std; int main(int ,char** argv) { string fileName(argv[1]); // should do better checks!! wrl::Scene scene; scene.load(fileName); SphereCounter sc; for_each(scene.nodes.begin(),scene.nodes.end(),sc); cout<<fileName<<" contains "<<sc.nbSpheres()<<" spheres"<<endl; return 0; }
operator()
syntax for the wrl::Traverser class, it is a valid function object, that is it can be used exactly as a function. Therefore, we can use the STL algorithm for_each
to simply apply this "function" to all nodes in the scene. If you are not familiar with the STL, I strongly advice that you get some interest into it. Meanwhile, here is how you could achieve the same result without for_each
: for (unsigned int i=0;i<scene.nodes.size();++i) { sc(scene.nodes[i]); }
treat()
methods might be complex. But this is not of the concern of this library since it highly depends on what you want to do with the VRML file.However, very often, you would like to retrieve the geometry in the file. One complex thing in that case is to track the transformation hierarchy during the traversal. If you use the traversal to build an adjacent hierarchy (for example for ray-tracing) that contains also transformation nodes, then it is pretty straightforward. However, if you want to "flatten" out the hierarchy, that is retrieve all the geometry expressed in a single frame coordinate, it is more tricky. Hopefully, the XdkWrl library can still help you a little bit if this is what you need to do, by providing wrl::Transformator and a wrl::TransformatorHierarchy classes. For more information, read the page .
Generated on 24 Feb 2005 with version 1.3.9.1. |