Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

new X3D node

Introduction

This is a complete example on how to create a new X3DNode by deriving an exisiting node. Here we define an X3D::FCylinder node, deriving from X3D::Cylinder and that enables the control of the cylinder discretization.

deriving X3D::Cylinder

We derive X3D::Cylinder and we add a section attribute. Note that the copy constructor is protected, because the nodes must be passed by pointers, and not by value. Nevertheless we define a clone method. For the node be loaded, the loadAttributes has to be redefined, as well as the writeAttributes, to enable the writing of the FCylinder node in an X3D file.

loading X3D::FCylinder

To load the node, we have to derive the creator for the nodes belonging to the Geometry3D, because X3D::FCylinder belongs to it.

deriving GL::Cylinder

To render X3D::FCylinder, we first have to define its openGL equivalent node, GL::FCylinder. Note that there are different namespaces for the scene graphs X3D and GL. There is no attribute to add to the GL::Cylinder. The update method which updates the attributes of the node from the equivalent X3D::FCylinder x3dReference has to be redefined. To the contrary, the render has not to be redefined.

building GL::FCylinder

We derive the GLBuilderGeometry3DVisitor, which will create the GL::FCylinder from an X3D::FCylinder.

code

FCylinder

FCylinder.h

//                            FCylinder.h                                     //

#ifndef FCYLINDER_H
#define FCYLINDER_H

#include <X3DTK/kernel.h>

namespace X3DTK {
namespace X3D {

class FCylinder : public Cylinder
{
public:
  // Constructor.
  FCylinder();
  // Constructs a Cylinder from its attributes.
  FCylinder(SFBool bottom, 
            SFFloat radius, 
            SFFloat height, 
            SFBool side, 
            SFBool top,
            SFInt32 section);
            
  // Clones the node.
  virtual SFNode clone() const;  
  // sets the number of sections.
  void setSection(SFInt32 section);

  // gets the number of sections.
  inline SFInt32 getSection() const {return _section;};
  
  // Loads the attributes from a X3DFileElement e.
  virtual void load(const X3DFileElement *element);
  // Writes the attributes of the node.
  virtual SFString write() const;

protected:
  // Copy constructor.     
  FCylinder(const FCylinder &C);

private:
  SFInt32 _section;
};

}
}

#endif

FCylinder.cpp

#include "FCylinder.h"

namespace X3DTK {
namespace X3D {

FCylinder::FCylinder()
: Cylinder(), _section(8)
{
  // Defines the tag of the node. This string must be the same than the one 
  // entered for the creation function, otherwise the node won't be loaded.
  defineTypeName("FCylinder");
}

FCylinder::FCylinder(SFBool bottom, SFFloat radius, SFFloat height, SFBool side, SFBool top, SFInt32 section)
: Cylinder(bottom, radius, height, side, top), _section(section)
{
  // Defines the tag of the node.
  defineTypeName("FCylinder");
}

FCylinder::FCylinder(const FCylinder &C)
: Cylinder(C), _section(C._section)
{
}

SFNode FCylinder::clone() const
{
  return new FCylinder(*this);
}

void FCylinder::setSection(SFInt32 section)
{
  _section = section;
}

void FCylinder::load(const X3DFileElement *element)
{
  Cylinder::load(element);
  
  int index;
  index = element->getIndexAttribute("section");
  if (index != -1)
    _section = element->getAttribute(index).toInt();
}

SFString FCylinder::write() const
{
  SFString attr;
  if (_section != 8)    
    attr += " section=\"" + toSFString(_section) + "\"";
      
  return Cylinder::write() + attr;
}

}
}

MyGeometry3DCreator

MyGeometry3DCreator.h

//                            MyGeometry3DCreator.h                           //

#ifndef MYGEOMETRY3DCREATOR_H
#define MYGEOMETRY3DCREATOR_H

#include <X3DTK/kernel.h>

namespace X3DTK {
namespace X3D {

// Concrete component Creator for the geometry3D component defining the default 
// X3D nodes.

class MyGeometry3DCreator : public DefaultGeometry3DCreator
{
public:
  // Constructor.
  MyGeometry3DCreator();
  
  // Creates a FCylinder.
  SFNode createFCylinder() const;
};

}
}

#endif

MyGeometry3DCreator.cpp

#include "MyGeometry3DCreator.h"
#include "FCylinder.h"

namespace X3DTK {
namespace X3D {

MyGeometry3DCreator::MyGeometry3DCreator()
: DefaultGeometry3DCreator()
{
  // Defines a new creation function for the FCylinder node.
  defineNewCreationFunction<MyGeometry3DCreator>("FCylinder", &MyGeometry3DCreator::createFCylinder);
}

SFNode MyGeometry3DCreator::createFCylinder() const
{
  return new FCylinder();
}

}
}

GLFCylinder

GLFCylinder.h

//                            GLFCylinder.h                                   //

#ifndef GLFCYLINDER_H
#define GLFCYLINDER_H

#include <X3DTK/kernel.h>

namespace X3DTK {
namespace GL {

// Class providing a implementation of the X3DGLNode corresponding to the X3DNode 
// FCylinder.

class FCylinder : public Cylinder
{
public:
  // Constructor.
  FCylinder();
  // Clones the node.
  virtual SFNode clone() const;

  virtual void update();

protected:
  // Copy constructor.
  FCylinder(const FCylinder &C);  
};

}
}

#endif

GLFCylinder.cpp

#include "GLFCylinder.h"
#include "FCylinder.h"

namespace X3DTK {
namespace GL {

FCylinder::FCylinder()
: Cylinder()
{
  // Defines the tag of the node. 
  defineTypeName("FCylinder");
}

FCylinder::FCylinder(const FCylinder &C)
: Cylinder(C)
{
}

SFNode FCylinder::clone() const
{
  // returns the copy constructor.
  return new FCylinder(*this);
}

void FCylinder::update()
{
  X3D::FCylinder *C = static_cast<X3D::FCylinder *>(x3dReference);
  
  // update the attributes.
  setBottom(C->getBottom());
  setRadius(C->getRadius());
  setHeight(C->getHeight());
  setSide(C->getSide());
  setTop(C->getTop());
  
  // Get the instance of CylinderDrawArray.
  setCylinderArray(CylinderDrawArray::getInstanceOfSection(C->getSection()));
}

}
}

MyGLBuilderGeometry3DVisitor

MyGLBuilderGeometry3DVisitor.h

//                            MyGLBuilderGeometry3DVisitor.h                  //

#ifndef MYGLBUILDERGEOMETRY3DVISITOR_H
#define MYGLBUILDERGEOMETRY3DVISITOR_H

#include <X3DTK/glbuilder.h>

namespace X3DTK {
namespace X3D {

class FCylinder;

// My visitor for the Geometry3D component of the GLCreator module.

class MyGLBuilderGeometry3DVisitor : public GLBuilderGeometry3DVisitor
{
public:
  // Constructor.
  MyGLBuilderGeometry3DVisitor();

  // Enters a FCylinder.
  virtual void enterFCylinder(FCylinder *C) const;
};

}
}

#endif

MyGLBuilderGeometry3DVisitor.cpp

#include "MyGLBuilderGeometry3DVisitor.h"
#include "FCylinder.h"
#include "GLFCylinder.h"

#include <iostream>

using namespace std;

namespace X3DTK {
namespace X3D {

MyGLBuilderGeometry3DVisitor::MyGLBuilderGeometry3DVisitor()
: GLBuilderGeometry3DVisitor()
{
  // Define new enter function for FCylinder.
  defineNewEnterFunction<MyGLBuilderGeometry3DVisitor, FCylinder>(&MyGLBuilderGeometry3DVisitor::enterFCylinder);
}

void MyGLBuilderGeometry3DVisitor::enterFCylinder(FCylinder *C) const
{
  // Creation of the GLFCylinder.
  GL::FCylinder *GC = new GL::FCylinder();
  GC->setX3DReference(C);
  globalVariables->getTop()->addChild(GC);
  globalVariables->pushNode(GC);
}

}
}

Viewer

Viewer.h

//                            Viewer.h                                        //

#ifndef VIEWER_H
#define VIEWER_H

#include <QGLViewer/qglviewer.h>
#include <X3DTK/simplex3dglscene.h>

// Class providing an X3D Viewer by implementing QGLViewer.

class Viewer : public QGLViewer
{
protected :
  void init();
  void draw();
  void keyPressEvent(QKeyEvent *e);
  void loadFile();
  void help();
  
private:
  X3DTK::SimpleX3DGLScene scene;
};

#endif

Viewer.cpp

#include "Viewer.h"
#include "MyGeometry3DCreator.h"
#include "MyGLBuilderGeometry3DVisitor.h"

#include <X3DTK/kernel.h>

#include <qfiledialog.h>

using namespace X3DTK;
using namespace std;

void Viewer::init()
{
  // We customize the SimpleX3DGLScene, by changing its X3DLoader, GLCreator
  scene.getLoader()->setComponentCreator(new X3D::MyGeometry3DCreator());
  scene.getGLBuilder()->setComponentVisitor(new X3D::MyGLBuilderGeometry3DVisitor());
  
  glEnable(GL_RESCALE_NORMAL);
  help();
  loadFile();
}

void Viewer::keyPressEvent(QKeyEvent *e)
{
  switch (e->key())
  {
    case Qt::Key_L : loadFile(); break;
    default:         QGLViewer::keyPressEvent(e);
  }
}

void Viewer::loadFile()
{
  QString name = QFileDialog::getOpenFileName("", "X3D files (*.x3d *.X3D);;All files (*)", this);
  
  // In case of Cancel
  if (name.isEmpty())
    return;

  scene.release();
  // Loads the scene.
  scene.load(name);
  
  // Shows the derivation tree.
  Type::printDerivationTree(); 
  cout << endl;
  
  // QGLViewer settings.
  setSceneBoundingBox(scene.getBboxMin().f_data(), scene.getBboxMax().f_data());
  showEntireScene();
}

void Viewer::draw()
{
  // Draws the scene.
  scene.draw();
}

void Viewer::help()
{
  cout << endl << "\t\t- -  x 3 d V i e w e r  - -" << endl << endl;
  cout << "This example uses the libX3D library to load a x3d object file." << endl;
  cout << "Press 'L'(oad) to open a x3d file." << endl << endl;
}

Generated on Tue Jul 15 16:46:54 2003 for X3DToolKit by doxygen1.3