We want to define an X3DTK::X3D::FCylinder
node, deriving from X3DTK::X3D::Cylinder
and that enables the control of the cylinder discretization.
Some important functions and classes:
X3DTK::X3D::Cylinder
and we add a section attribute. In the constructor the type name and its attribute are recorded.X3DTK::X3D::FCylinder
belongs to it.X3DTK::X3D::FCylinder
, we first have to define its openGL equivalent node, X3DTK::GL::FCylinder
. Note that there are different namespaces for the scene graphs X3D and GL. There is no attribute to add to the X3DTK::GL::Cylinder
. The update
method which updates the attributes of the node from the equivalent X3DTK::X3D::FCylinder x3dReference
has to be redefined. To the contrary, the draw
method has not to be redefined. However the type name of the node has to be recorded in the constructor.X3DTK::X3D::GLBuilderGeometry3DVisitor
, which will create the X3DTK::GL::FCylinder
from an X3DTK::X3D::FCylinder
.#ifndef FCYLINDER_H #define FCYLINDER_H #include <X3DTK/X3D/scenegraph.h> namespace X3DTK { namespace X3D { class FCylinder : public Cylinder { public: FCylinder(); virtual ~FCylinder(); void setSection(SFInt32 section); inline SFInt32 getSection() const {return _section;}; private: SFInt32 _section; }; } } #endif
#include "X3D_FCylinder.h" namespace X3DTK { namespace X3D { FCylinder::FCylinder() : Cylinder() { // Defines the tag of the node. This string is the one read in the X3D file. define(Recorder<FCylinder>::getTypeName("FCylinder")); // Defines an attribute. The first parameter is the string read in the X3D file. define(Recorder<FCylinder, SFInt32>::getAttribute("section", &FCylinder::_section, 8)); } FCylinder::~FCylinder() { } void FCylinder::setSection(SFInt32 section) { _section = section; } } }
#ifndef MYGEOMETRY3DCREATOR_H #define MYGEOMETRY3DCREATOR_H #include <X3DTK/X3D/scenegraph.h> namespace X3DTK { namespace X3D { // Concrete component Creator for the geometry3D component defining the default // X3D nodes. class MyGeometry3DCreator : public Geometry3DCreator { public: // Constructor. MyGeometry3DCreator(); }; } } #endif
#include "X3D_MyGeometry3DCreator.h" #include "X3D_FCylinder.h" namespace X3DTK { namespace X3D { MyGeometry3DCreator::MyGeometry3DCreator() : Geometry3DCreator() { // Defines a new creation function for the FCylinder node. define(Recorder<FCylinder>::getCreationFunction()); } } }
#ifndef GL_FCYLINDER_H #define GL_FCYLINDER_H #include <X3DTK/GL/scenegraph.h> namespace X3DTK { namespace GL { class FCylinder : public Cylinder { public: FCylinder(); virtual ~FCylinder(); virtual void update(); }; } } #endif
#include "GL_FCylinder.h" #include "X3D_FCylinder.h" #include <iostream> using namespace std; namespace X3DTK { namespace GL { FCylinder::FCylinder() : Cylinder() { // Defines the tag of the node. define(Recorder<FCylinder>::getTypeName("FCylinder")); } FCylinder::~FCylinder() { } 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())); } } }
#ifndef MYGLBUILDERGEOMETRY3DVISITOR_H #define MYGLBUILDERGEOMETRY3DVISITOR_H #include <X3DTK/X3D/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 an FCylinder. static void enterFCylinder(FCylinder *C); }; } } #endif
#include "X3D_MyGLBuilderGeometry3DVisitor.h" #include "X3D_FCylinder.h" #include "GL_FCylinder.h" #include <iostream> using namespace std; namespace X3DTK { namespace X3D { MyGLBuilderGeometry3DVisitor::MyGLBuilderGeometry3DVisitor() : GLBuilderGeometry3DVisitor() { // Define new enter function for FCylinder. define(Recorder<FCylinder>::getEnterFunction(&MyGLBuilderGeometry3DVisitor::enterFCylinder)); } void MyGLBuilderGeometry3DVisitor::enterFCylinder(FCylinder *C) { GLBuilderStateVariables *stateVariables = Singleton<GLBuilderStateVariables>::getInstance(); GL::X3DNode *GC = stateVariables->getNode(C); if (GC == 0) { GC = new GL::FCylinder(); GC->setX3DReference(C); stateVariables->addCoupleNode(C, GC); } stateVariables->pushNode(GC); } } }
#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 about(); QString helpString() const; void help() const; private: X3DTK::SimpleX3DGLScene scene; }; #endif
#include "Viewer.h" #include "X3D_MyGeometry3DCreator.h" #include "X3D_MyGLBuilderGeometry3DVisitor.h" #include <qfiledialog.h> #include <qmessagebox.h> #include <X3DTK/kernel.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()); #ifdef GL_RESCALE_NORMAL glEnable(GL_RESCALE_NORMAL); #endif about(); 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 inheritance tree. SFType::printInheritanceTree(); cout << endl; // QGLViewer settings. setSceneBoundingBox(scene.getBBoxMin().f_data(), scene.getBBoxMax().f_data()); showEntireScene(); } void Viewer::draw() { // Draws the scene. scene.draw(); } void Viewer::about() { QMessageBox::about(this, "about the newNodeViewer", "this is an example showing how to create a new node.Type 'h' to display help"); } QString Viewer::helpString() const { QString message(""); message += "<b>L</b>" + QString(" loads a new file<br>"); message += QGLViewer::helpString(); return message; } void Viewer::help() const { QMessageBox *mb = new QMessageBox("help", helpString(), QMessageBox::NoIcon,QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton,QMessageBox::NoButton, NULL, "Help", false,Qt::WStyle_DialogBorder | Qt::WType_Dialog | Qt::WDestructiveClose); mb->show(); }