nodeCounter

Introduction

This an example very close to simpleNodeCounter about how to write a simple processor acting on the X3D scene graph. A processor is a graph traversal and a visitor that applies on each traversed node.

We want to count the number of X3DTK::X3D::X3DGeometryNode, the number of X3DTK::X3D::X3DGroupingNode, the number of X3DTK::X3D::X3DCoordinateNode and the number of visited nodes of an X3D scene.

Some important functions and classes:

X3D::NodeCounterStateVariables

To memorize the number of visited nodes, we use a state variables class that stores these numbers, and that is accessed by a singleton manager X3DTK::Singleton.

X3D::NodeCounterRenderingVisitor

We define a visitor for the Rendering component, because X3DTK::X3D::X3DGeometryNode and X3DTK::X3D::X3DCoordinateNode belong to the Rendering component. A simple function enterX3DGeometryNode that increases the number of such nodes by accessing the state variables, and recorded in the constructor is defined. To demonstrate the use of a walkOn function, we define walkOnX3DGeometryNode that returns true only if child is an X3DCoordinate node, meaning that only the X3DTK::X3D::X3DCoordinateNode are visited among the children of an X3DTK::X3D::X3DGeometryNode.

X3D::NodeCounterRenderingVisitor

We define a processor that counts the number of X3DTK::X3D::X3DGroupingNode.

X3D::NodeCounterCoreVisitor

We define a visitor for the Core component for the remaining nodes. A simple function enterX3DNode that increases the number of other nodes is defined.

X3D::NodeCounter

This is the facade of the processor which aggregates the visitors of the different components.

Code

X3D_NodeCounterStateVariables.h

#ifndef X3D_NODECOUNTERSTATEVARIABLES_H
#define X3D_NODECOUNTERSTATEVARIABLES_H

#include <X3DTK/kernel.h>

namespace X3DTK {
namespace X3D {

class NodeCounterStateVariables : public StateVariables
{
public:
  NodeCounterStateVariables();
  
  void init();
  
  void addX3DGeometryNode();
  void addX3DCoordinateNode();
  void addX3DGroupingNode();
  void addOtherNode();
  
  inline unsigned int getX3DGeometryNode() const {return _geometryCount;};
  inline unsigned int getX3DCoordinateNode() const {return _coordinateCount;};
  inline unsigned int getX3DGroupingNode() const {return _groupingCount;};
  inline unsigned int getOtherNode() const {return _otherCount;};
  
private:
  unsigned int _geometryCount;
  unsigned int _coordinateCount;
  unsigned int _groupingCount;
  unsigned int _otherCount;  
};

}
}

#endif

X3D_NodeCounterStateVariables.cpp

#include "X3D_NodeCounterStateVariables.h"

namespace X3DTK {
namespace X3D {

NodeCounterStateVariables::NodeCounterStateVariables()
: _geometryCount(0), _coordinateCount(0), _groupingCount(0), _otherCount(0)
{
}
 
void NodeCounterStateVariables::init()
{
  _geometryCount = 0;
  _groupingCount = 0;
  _coordinateCount = 0;
  _otherCount = 0;
}

void NodeCounterStateVariables::addX3DGeometryNode()
{
  ++_geometryCount;
}

void NodeCounterStateVariables::addX3DCoordinateNode()
{
  ++_coordinateCount;
}

void NodeCounterStateVariables::addX3DGroupingNode()
{
  ++_groupingCount;
}

void NodeCounterStateVariables::addOtherNode()
{
  ++_otherCount;
}

}
}

X3D_NodeCounterRenderingVisitor.h

#ifndef X3D_NODECOUNTERRENDERINGVISITOR_H
#define X3D_NODECOUNTERRENDERINGVISITOR_H

#include <X3DTK/kernel.h>
#include <X3DTK/X3D/scenegraph.h>

namespace X3DTK {
namespace X3D {

class NodeCounterRenderingVisitor : public RenderingVisitor
{
public:
  NodeCounterRenderingVisitor();
  
  static void enterX3DGeometryNode(X3DGeometryNode *N);
  static bool walkOnX3DGeometryNode(X3DGeometryNode *N, X3DAbstractNode *child);
  static void enterX3DCoordinateNode(X3DCoordinateNode *N);
};

}
}

#endif

X3D_NodeCounterRenderingVisitor.cpp

#include "X3D_NodeCounterRenderingVisitor.h"
#include "X3D_NodeCounterStateVariables.h"

namespace X3DTK {
namespace X3D {

NodeCounterRenderingVisitor::NodeCounterRenderingVisitor()
: RenderingVisitor()
{
  define(Recorder<X3DGeometryNode>::getEnterFunction(&NodeCounterRenderingVisitor::enterX3DGeometryNode));
  define(Recorder<X3DGeometryNode>::getWalkOnFunction(&NodeCounterRenderingVisitor::walkOnX3DGeometryNode));
  define(Recorder<X3DCoordinateNode>::getEnterFunction(&NodeCounterRenderingVisitor::enterX3DCoordinateNode));
}
  
void NodeCounterRenderingVisitor::enterX3DGeometryNode(X3DGeometryNode *N)
{
  Singleton<NodeCounterStateVariables>::getInstance()->addX3DGeometryNode();
}

bool NodeCounterRenderingVisitor::walkOnX3DGeometryNode(X3DGeometryNode *N, X3DAbstractNode *child)
{
  return (dynamic_cast<X3DCoordinateNode *>(child) != 0);
}

void NodeCounterRenderingVisitor::enterX3DCoordinateNode(X3DCoordinateNode *N)
{
  Singleton<NodeCounterStateVariables>::getInstance()->addX3DCoordinateNode();
}

}
}

X3D_NodeCounterGroupingVisitor.h

#ifndef X3D_NODECOUNTERGROUPINGVISITOR_H
#define X3D_NODECOUNTERGROUPINGVISITOR_H

#include <X3DTK/kernel.h>
#include <X3DTK/X3D/scenegraph.h>

namespace X3DTK {
namespace X3D {

class NodeCounterGroupingVisitor : public GroupingVisitor
{
public:
  NodeCounterGroupingVisitor();
  
  static void enterX3DGroupingNode(X3DGroupingNode *N);
};

}
}

#endif

X3D_NodeCounterGroupingVisitor.cpp

#include "X3D_NodeCounterGroupingVisitor.h"
#include "X3D_NodeCounterStateVariables.h"

namespace X3DTK {
namespace X3D {

NodeCounterGroupingVisitor::NodeCounterGroupingVisitor()
: GroupingVisitor()
{
  define(Recorder<X3DGroupingNode>::getEnterFunction(&NodeCounterGroupingVisitor::enterX3DGroupingNode));
}
  
void NodeCounterGroupingVisitor::enterX3DGroupingNode(X3DGroupingNode *N)
{
  Singleton<NodeCounterStateVariables>::getInstance()->addX3DGroupingNode();
}

}
}

X3D_NodeCounterCoreVisitor.h

#ifndef X3D_NODECOUNTERCOREVISITOR_H
#define X3D_NODECOUNTERCOREVISITOR_H

#include <X3DTK/kernel.h>
#include <X3DTK/X3D/scenegraph.h>

namespace X3DTK {
namespace X3D {

class NodeCounterCoreVisitor : public CoreVisitor
{
public:
  NodeCounterCoreVisitor();
  
  static void enterX3DNode(X3DNode *N);
};

}
}

#endif

X3D_NodeCounterCoreVisitor.cpp

#include "X3D_NodeCounterCoreVisitor.h"
#include "X3D_NodeCounterStateVariables.h"

namespace X3DTK {
namespace X3D {

NodeCounterCoreVisitor::NodeCounterCoreVisitor()
: CoreVisitor()
{
  define(Recorder<X3DNode>::getEnterFunction(&NodeCounterCoreVisitor::enterX3DNode));
}
  
void NodeCounterCoreVisitor::enterX3DNode(X3DNode *N)
{
  Singleton<NodeCounterStateVariables>::getInstance()->addOtherNode();
}

}
}

X3D_NodeCounter.h

#ifndef X3D_NODECOUNTER_H
#define X3D_NODECOUNTER_H

#include <X3DTK/kernel.h>
#include <X3DTK/X3D/scenegraph.h>

namespace X3DTK {
namespace X3D {

class NodeCounter : public X3DOnePassProcessor
{
public:
  NodeCounter();
  virtual ~NodeCounter();
  
  virtual void count(X3DNode *N);
};

}
}

#endif

X3D_NodeCounter.cpp

#include "X3D_NodeCounter.h"
#include "X3D_NodeCounterRenderingVisitor.h"
#include "X3D_NodeCounterGroupingVisitor.h"
#include "X3D_NodeCounterCoreVisitor.h"
#include "X3D_NodeCounterStateVariables.h"
#include <iostream>

using namespace std;

namespace X3DTK {
namespace X3D {

NodeCounter::NodeCounter()
: X3DOnePassProcessor()
{
  setGraphTraversal(new DFSGraphTraversal());
  setComponentVisitor(new NodeCounterRenderingVisitor());
  setComponentVisitor(new NodeCounterGroupingVisitor());
  setComponentVisitor(new NodeCounterCoreVisitor());
}

NodeCounter::~NodeCounter()
{
  Singleton<NodeCounterStateVariables>::removeInstance();
}
  
void NodeCounter::count(X3DNode *N)
{
  Singleton<NodeCounterStateVariables>::getInstance()->init();
  traverse(N);
  cout << "number of geometry nodes is " << Singleton<NodeCounterStateVariables>::getInstance()->getX3DGeometryNode() << endl;
  cout << "number of coordinate nodes is " << Singleton<NodeCounterStateVariables>::getInstance()->getX3DCoordinateNode() << endl;
  cout << "number of grouping nodes is " << Singleton<NodeCounterStateVariables>::getInstance()->getX3DGroupingNode() << endl;
  cout << "number of visited nodes is " << Singleton<NodeCounterStateVariables>::getInstance()->getOtherNode() 
                                 + Singleton<NodeCounterStateVariables>::getInstance()->getX3DGeometryNode() 
                                 + Singleton<NodeCounterStateVariables>::getInstance()->getX3DCoordinateNode() 
                                 + Singleton<NodeCounterStateVariables>::getInstance()->getX3DGroupingNode() << endl;
}
  
}
}  

Generated on Fri Jul 30 12:02:33 2004 for X3DToolKit by doxygen 1.3.6