From BlenderWiki

Jump to: navigation, search

Object Configuration

Public objects created by the user like lights and shaders have to be configured. In the current yafray core this is done by passing a parameter map. This map associates a label with a value which can be float, bool, a color, etc ... The problem with this is that we have to pass data using stl containers (i.e std::map and std::string).

Passing data from blender or other programs to a plugin that could be using other stl implementation is dangerous. Also it's a mess to respect the stupid free msvc law of allocating and deleting memory always in the same binary object.

Therefore, I propose here an alternative scheme to configure objects without using stl in the interface. The idea is to have a base class called </tt>configurable_t= which will hold the basic methods to perform the configuration.

<img src%ATTACHURLPATH%/configurable_class.png" alt="configurable_t class diagram" width="621" height="377" />

The simplified process would be this: 1. User request the creation of an instance of class A. 1. Class A constructor fills the defaults and prepares values to be configured. 1. User sets params by calling set(const char *attr,type value)= methods. 1. User adds the object to the scene. 1. Scene calls =init()= method to tell it configuration is done.

So now let's define that =configurable_t= class.

Set methods

They are called by the "user" program. The purpose is to configure certain attributes to concrete values of those types shown below.

bool set(const char *attr,float value);
bool set(const char *attr,bool value);
bool set(const char *attr,int value);
bool set(const char *attr,const char *str);
bool set(const char *attr,const color_t &color);
bool set(const char *attr,const vector3d_t &vec);
bool set(const char *attr,const point3d_t &p);


For instance, a sequence of actions to configure a point light could be:

light->set("from",point3d_t(0,0,10)); // Set possition
light->set("color",color_t(1,1,1)); // Set color to white
light->set("power",10.0); // Set power to 10
light->set("shadow",true); // Set shadows on


Push methods

We also take into account the object may have list of elements to configure. For instance, a mixer shading block with several inputs. We need a way to configure such list of inputs. For that reason we define a special set of methods to handle list configurations:

bool push(const char *attr,float value);
bool push(const char *attr,bool value);
bool push(const char *attr,int value);
bool push(const char *attr,const char *str);
bool push(const char *attr,const color_t &color);
bool push(const char *attr,const vector3d_t &vec);
bool push(const char *attr,const point3d_t &p);


The same syntax as "set" methods but instead of setting a single value, the given values are pushed at the end of a list associated withe the attribute name. For example, a mixer block configuration:

mixer->push("input","clouds12");
mixer->push("inputweight",0.5);
mixer->push("input","rgbred");
mixer->push("inputweight",0.25);
mixer->push("input","marble");
mixer->push("inputweight",0.25);


Regist methods

This is the scheme to export a certain member variable to be configured from the exterior.

Supose we have a class whose name is pointLight_t and looks like this:

class pointLight_t : public configurable_t
{
public:
pointLight_t();
protected:
point3d_t from;
color_t color;
float power;
};


The proposed convention is that in the constructor, this class registers those vars that could be configured by the user. For instance:

pointLight_t::pointLight_t()
{
regist("position",from);
regist("color",color);
regist("power",power);
}


To do this, we will put in configurable_t class the following methods:

void regist(const char *attr,float &value);
void regist(const char *attr,bool &value);
void regist(const char *attr,int &value);
void regist(const char *attr,std::string &str);
void regist(const char *attr,color_t &color);
void regist(const char *attr,vector3d_t &vec);
void regist(const char *attr,point3d_t &p);
// list version:
void regist(const char *attr,std::list<float> &value);
void regist(const char *attr,std::list<bool> &value);
void regist(const char *attr,std::list<int> &value);
void regist(const char *attr,std::list<std::string> &str);
void regist(const char *attr,std::list<color_t> &color);
void regist(const char *attr,std::list<vector3d_t> &vec);
void regist(const char *attr,std::list<point3d_t> &p);


-- AlejandroContyEstevez - 02 Nov 2004