Defining a processor

Introduction

The library provides different views of the 3D models which are the scene graphs. It also provides an easy way to traverse and process them. A processor is made up of a walker and a visitor. The walker gives the traversal order of the nodes of the scene graph, whereas the visitor processes the traversed nodes. Usually the graph traversal is a Depth First Search algorithm. Then you just have to define and record callbacks. For more details about how the callbacks are applied, see the concepts page.

For a step-by-step processor definition, see the simpleNodeCounter example.

Two types of processors exist: X3DTK::X3DOnePassProcessor and X3DTK::X3DMultiPassProcessor. You derive them and add functions: For example:

#include <X3DTK/kernel.h> namespace X3DTK { namespace X3D { class MyProcessor : public X3DOnePassProcessor { public: MyProcessor(); void compute(X3DNode *N); } } }

Walker

Only a Depth First Search algorithm is provided by the library. You specify the graph traversal of X3DTK::X3DOnePassProcessor like this:

MyProcessor::MyProcessor() : X3DOnePassProcessor() { setGraphTraversal(new DFSGraphTraversal()); ... }

For an X3DTK::X3DMultiPassProcessor which has two passes (Faces and Vertices):

MyProcessor::MyProcessor() : X3DMultiPassProcessor() { setGraphTraversal("Faces", new DFSGraphTraversal()); setGraphTraversal("Vertices", new DFSGraphTraversal()); ... }

Visitor

The visitor pattern is implemented for the process of the traversed nodes. The X3D nodes belong to different components, so that a visitor is the aggregation of several component visitors.

Component visitor

To define a new component visitor, you just have to derive the empty class of the related component, define static callback functions and record them in the constructor.

Declaring callbacks

Here is an interface of a visitor for the Rendering component where we have defined an enter function, a walkOn function and a leave function for the X3DTK::X3D::X3DGeometryNode:

#include <X3DTK/X3D/scenegraph.h> namespace X3DTK { namespace X3D { class MyRenderingVisitor : public RenderingVisitor { public: MyRenderingVisitor(); static void enterX3DGeometryNode(X3DGeometryNode *N); static bool walkOnX3DGeometryNode(X3DGeometryNode *N, X3DAbstractNode *child); static void leaveX3DGeometryNode(X3DGeometryNode *N); } } }

Declaring callbacks

The callbacks are defined like normal functions that process the visited node. For implementation constraints due to the possibility of calling such functions in another component visitor, these methods must be static. The access of the state variables is made by the singleton manager.

Here is an example:

void MyRenderingVisitor::enterX3DGeometryNode(X3DGeometryNode *N) { // using N... Singleton<MyProcessorStateVariables>::getInstance()->addNode(N); ... } bool MyRenderingVisitor::walkOnX3DGeometryNode(X3DGeometryNode *N, X3DAbstractNode *child) { return (dynamic_cast<Coordinate *>(child) != 0); }

These callbacks are recorded in the constructor of the component visitor:

MyRenderingVisitor::MyRenderingVisitor() : RenderingVisitor() { define(Recorder<X3DGeometryNode>::getEnterFunction(&MyRenderingVisitor::enterX3DGeometryNode)); define(Recorder<X3DGeometryNode>::getWalkOnFunction(&MyRenderingVisitor::walkOnX3DGeometryNode)); define(Recorder<X3DGeometryNode>::getLeaveFunction(&MyRenderingVisitor::leaveX3DGeometryNode)); }

This is a portable syntax. The recording of functions can also be done like this, using template function that are not well implemented on some compilers:

MyRenderingVisitor::MyRenderingVisitor() : RenderingVisitor() { defineEnterFunction(&MyRenderingVisitor::enterX3DGeometryNode); defineWalkOnFunction(&MyRenderingVisitor::walkOnX3DGeometryNode); defineLeaveFunction(&MyRenderingVisitor::leaveX3DGeometryNode); }

Adding a component visitor to the visitor

Let's come back to the end of the definition of the constructor of MyProcessor: Component visitors are added to the different walkers:

MyProcessor::MyProcessor() : X3DOnePassProcessor() { setGraphTraversal(new DFSGraphTraversal()); setComponentVisitor(new MyRenderingVisitor()); }

For an X3DTK::X3DMultiPassProcessor which has two passes (Faces and Vertices):

MyProcessor::MyProcessor() : X3DMultiPassProcessor() { setGraphTraversal("Faces", new DFSGraphTraversal()); setGraphTraversal("Vertices", new DFSGraphTraversal()); setComponentVisitor("Faces", new MyRenderingFacesVisitor()); setComponentVisitor("Vertices", new MyRenderingVerticesVisitor()); }

Predefined processors

You can find a list of the processors provided by the library in the Provided processors page.

Concrete examples

Here is the list of the examples where concrete processors are defined:
Generated on Fri Jul 30 12:02:31 2004 for X3DToolKit by doxygen 1.3.6