Sometimes, we want to redefine an existing node that has some interesting properties. Let's take the following example. We want to extend the X3DTK::X3D::Shape
node into X3DTK::X3D::InfoShape
. Moreover we want that X3DTK::X3D::Shape
belongs to a new component. If it has the type name "InfoShape", then a third party X3D application won't be able to load the new node because it doesn´t know it. Nevertheless X3DTK::X3D::InfoShape
can be seen like a X3DTK::X3D::Shape
in a classical X3D viewer. The only thing you have to do is to give the type name "Shape".
X3DTK::X3D::Price
and X3DTK::X3D::Modeler
are the same nodes that those defined in infoReader example. X3DTK::X3D::InfoShape
is a mix between X3DTK::X3D::Shape
and X3DTK::X3D::Info
defined in infoReader. The only thing to do is to give X3DTK::X3D::InfoShape
the type name "Shape".
To load the new nodes, the creator for the new component is defined. It is necessary to give its name by the defineComponentName
command.
#include "X3D_InfoShape.h"
#include "X3D_Price.h"
#include "X3D_Modeler.h"
#include <iostream>
using namespace std;
namespace X3DTK {
namespace X3D {
InfoShape::InfoShape()
: Shape(), _date("0/0/0"), _price(0), _modeler(0)
{
defineTypeName("Shape", "MyComponent");
}
InfoShape::InfoShape(const InfoShape &I)
: Shape(I), _date(I._date), _price(I._price), _modeler(I._modeler)
{
}
InfoShape::~InfoShape()
{
removeParentFromChild(this, _price);
removeParentFromChild(this, _modeler);
}
SFAbstractNode InfoShape::clone() const
{
return new InfoShape(*this);
}
void InfoShape::setDate(const SFString &date)
{
_date = date;
}
void InfoShape::setPrice(Price *price)
{
removeParentFromChild(this, _price);
_price = price;
addParentToChild(this, _price);
}
void InfoShape::setModeler(Modeler *modeler)
{
removeParentFromChild(this, _modeler);
_modeler = modeler;
addParentToChild(this, _modeler);
}
MFAbstractNode InfoShape::getChildList() const
{
MFAbstractNode childrenList = Shape::getChildList();
if (_price != 0)
childrenList.push_back(_price);
if (_modeler != 0)
childrenList.push_back(_modeler);
return childrenList;
}
bool InfoShape::addChild(const SFAbstractNode &N)
{
if (dynamic_cast<Price *>(N) != 0)
{
if (_price != 0)
return false;
setPrice(static_cast<Price *>(N));
return true;
}
if (dynamic_cast<Modeler *>(N) != 0)
{
if (_modeler != 0)
return false;
setModeler(static_cast<Modeler *>(N));
return true;
}
Shape::addChild(N);
return false;
}
bool InfoShape::setChild(const SFAbstractNode &N)
{
if (dynamic_cast<Price *>(N) != 0)
{
setPrice(static_cast<Price *>(N));
return true;
}
if (dynamic_cast<Modeler *>(N) != 0)
{
setModeler(static_cast<Modeler *>(N));
return true;
}
Shape::setChild(N);
return false;
}
bool InfoShape::removeChild(const SFAbstractNode &N)
{
if (_price == N)
{
setPrice(0);
return true;
}
if (_modeler == N)
{
setModeler(0);
return true;
}
Shape::removeChild(N);
return false;
}
void InfoShape::load(const X3DFileElement *element)
{
Shape::load(element);
int index;
index = element->getIndexAttribute("date");
if (index != -1)
_date = element->getAttribute(index);
}
}
}
#ifndef PRICE_H
#define PRICE_H
#include <X3DTK/X3D/scenegraph.h>
namespace X3DTK {
namespace X3D {
class Price : public X3DChildNode
{
public:
Price();
Price(const SFFloat &price,
const SFString &money);
virtual SFAbstractNode clone() const;
void setPrice(const SFFloat &price);
void setMoney(const SFString &money);
inline const SFFloat &getPrice() const {return _price;};
inline const SFString &getMoney() const {return _money;};
virtual void load(const X3DFileElement *element);
virtual SFString write() const;
protected:
Price(const Price &I);
private:
SFFloat _price;
SFString _money;
};
}
}
#endif
#include "X3D_Price.h"
namespace X3DTK {
namespace X3D {
Price::Price()
: X3DChildNode(), _price(0.0f), _money("euro")
{
defineTypeName("Price");
}
Price::Price(const SFFloat &price, const SFString &money)
: X3DChildNode(), _price(price), _money(money)
{
defineTypeName("Price");
}
Price::Price(const Price &P)
: X3DChildNode(P), _price(P._price), _money(P._money)
{
}
SFAbstractNode Price::clone() const
{
return new Price(*this);
}
void Price::setPrice(const SFFloat &price)
{
_price = price;
}
void Price::setMoney(const SFString &money)
{
_money = money;
}
void Price::load(const X3DFileElement *element)
{
int index;
index = element->getIndexAttribute("price");
if (index != -1)
_price = element->getAttribute(index).toFloat();
index = element->getIndexAttribute("money");
if (index != -1)
_money = element->getAttribute(index);
}
SFString Price::write() const
{
SFString attr;
if (_price != 0.0f)
attr += " price=\"" + toSFString(_price) + "\"";
if (_money != "euro")
attr += " money=\"" + _money + "\"";
return attr;
}
}
}
#ifndef MODELER_H
#define MODELER_H
#include <X3DTK/X3D/scenegraph.h>
namespace X3DTK {
namespace X3D {
class Modeler : public X3DChildNode
{
public:
Modeler();
Modeler(const SFString &name);
virtual SFAbstractNode clone() const;
void setMName(const SFString &name);
inline const SFString &getMName() const {return _name;};
virtual void load(const X3DFileElement *element);
virtual SFString write() const;
protected:
Modeler(const Modeler &I);
private:
SFString _name;
};
}
}
#endif
#include "X3D_Modeler.h"
namespace X3DTK {
namespace X3D {
Modeler::Modeler()
: X3DChildNode(), _name("")
{
defineTypeName("Modeler");
}
Modeler::Modeler(const SFString &name)
: X3DChildNode(), _name(name)
{
defineTypeName("Modeler");
}
Modeler::Modeler(const Modeler &P)
: X3DChildNode(P), _name(P._name)
{
}
SFAbstractNode Modeler::clone() const
{
return new Modeler(*this);
}
void Modeler::setMName(const SFString &name)
{
_name = name;
}
void Modeler::load(const X3DFileElement *element)
{
int index;
index = element->getIndexAttribute("name");
if (index != -1)
_name = element->getAttribute(index);
}
SFString Modeler::write() const
{
SFString attr;
if (_name != "")
attr += " name=\"" + _name + "\"";
return attr;
}
}
}
#ifndef MYCOMPONENTCREATOR_H
#define MYCOMPONENTCREATOR_H
#include <X3DTK/X3D/scenegraph.h>
namespace X3DTK {
namespace X3D {
class MyComponentCreator : public X3DComponentCreator
{
public:
MyComponentCreator();
};
}
}
#endif
#include "X3D_MyComponentCreator.h"
#include "X3D_InfoShape.h"
namespace X3DTK {
namespace X3D {
MyComponentCreator::MyComponentCreator()
: X3DComponentCreator()
{
defineComponentName("MyComponent", "X3D");
define(Recorder<InfoShape>::getCreationFunction());
}
}
}
#include <X3DTK/X3D/scenegraph.h>
#include <X3DTK/graphtester.h>
#include <X3DTK/memreleaser.h>
#include "X3D_MyGroupingCreator.h"
#include "X3D_MyComponentCreator.h"
#include <iostream>
using namespace X3DTK;
using namespace std;
int main(int argc, char *argv[])
{
if (argc <= 1)
{
cerr << "usage: redefineNodeTester input" << endl;
exit(0);
}
X3D::Loader *loader = Singleton<X3D::Loader>::getInstance();
loader->setComponentCreator(new X3D::MyGroupingCreator());
MemReleaser *releaser = Singleton<MemReleaser>::getInstance();
GraphTester *graphtester = Singleton<GraphTester>::getInstance();
cout << "***Check x3dtk.log to see that Shape cannot have Price and Modeler children!***" << endl;
X3D::Scene *s = loader->load(argv[1], false);
graphtester->test(s);
releaser->release(s);
loader->setComponentCreator(new X3D::MyComponentCreator());
cout << "***Check x3dtk.log to see that Shape can have Price and Modeler children!***" << endl;
s = loader->load(argv[1], false);
graphtester->test(s);
return 1;
}
Generated on Thu Jun 3 10:12:14 2004 for X3DToolKit by
1.3.6