3DCoat  3D-COAT 4.9.xx
3DCoat is the one application that has all the tools you need to take your 3D idea from a block of digital clay all the way to a production ready, fully textured organic or hard surface model.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
class_reg.h File Reference

The document describes macro definitions used to register members using BaseClass approach. More...

Macros

#define SERIALIZE()
 SERIALIZE() { ... } used to register variables and functions in the class. There are no input parameters. More...
 
#define SERIALIZE_LATER()
 SERIALIZE_LATER() used to register variables and functions in the class.
. More...
 
#define SERIALIZE_NOW(x)
 SERIALIZE_NOW(classname) { ... } used to register variables and functions in the class if SERIALIZE_LATER() was declared in the class. More...
 
#define FUNCTION_CALL(...)
 FUNCTION_CALL(method[,name,function_parameters]) used to register any function calls. More...
 
#define LAMBDA_CALL(...)
 LAMBDA_CALL(method[,name,function_parameters]) used to register any function calls. More...
 
#define ICON_BUTTON(...)
 Register function call as button. More...
 
#define LAMBDA_ICON_BUTTON(...)
 Register function call as button. More...
 
#define STATE_BUTTON(name, variable, value)   REG_TYPE_ANYTHING(variable, __state, name, (void*)cPtrDiff(value))
 STATE_BUTTON(var_name, int_variable_ref, ethalon_value) used to register state button. More...
 
#define REG_AUTO(...)   REG_AUTO_MACRO_CHOOSER(__VA_ARGS__)
 REG_AUTO(variable[,name]) used to register variables in the class. More...
 
#define _EACH(bcptr, be)
 _EACH(bcptr, be) - Walk through class members using the macro. It is most time effective method of access to all class fields. More...
 
#define _EACH_END
 _EACH_END - End of _EACH ... _EACH_END cycle More...
 
#define _EACH_FAST_END
 _EACH_FAST_END - In case when you don't need stringual name of member you may walk faster, in this case use _EACH ... _EACH_FAST_END cycle. More...
 
#define BCPrintf(...)   ((ForEachElem || (result && required_index == 0)) ? comms::cStr::Format(__VA_ARGS__) : comms::cStr::Empty)
 BCPrintf(...) - Use it if you want to compose name of object using printf - like syntax. Don't use sprintf directly, because BCPrintf makes string only when it is required, not each time when function called. More...
 
#define DELIMITER
 DELIMITER adds the delimiter in UI. More...
 
#define REG_DROPLIST(fieldID, name, EnumID)
 REG_DROPLIST(fieldID, name, EnumID) adds the droplist to UI, list into XML. The referred variable should be int. More...
 
#define MAKE_ENUMERATOR(name, content)
 Make Enumerator in just one line. More...
 
#define UI_LAYOUT(str)
 UI_LAYOUT(str) splits ui elements to several columns with proportional or fixed width. More...
 
#define UI_ONLY
 UI_ONLY and SAVE_ONLY used if you want to register UI section and Serialization sections separately
. More...
 
#define SAVE_ONLY
 SAVE_ONLY used to start serialization (only) definition section. Look UI_ONLY for details and example. More...
 
#define SAVE_OR_UI(save, ui)
 SAVE_OR_UI used to start conditional serialization or UI definition section. More...
 
#define SLIDER(var, name, minvalue, maxvalue)
 SLIDER(var,name,minvalue,maxvalue) to add integer/float slider in UI. Only float and int supported. More...
 
#define FSLIDER(var, name, minvalue, maxvalue, VisModulator, Inverse)
 FSLIDER(var,name,minvalue,maxvalue,scale,inversion) to add float slider in UI. It has a bit extended syntax, allows scaling and inversion. More...
 
#define FILEPATH(str, name, mask)
 use FILEPATH(str, name, mask) to add file selection control in UI. Only comms::cStr supported More...
 
#define REG_TEXTURE_2(x, y)
 use REG_TEXTURE(var[,name]) to register texture image in UI/XML More...
 
#define REG_VECTOR2D(vec)   {INVISIBLE REG_MEMBER(_float,vec.x);INVISIBLE REG_MEMBER(_float,vec.y);}
 register cVec2 More...
 
#define REG_RCT(R)   {REG_MEMBER(_float,R.x);REG_MEMBER(_float,R.y);REG_MEMBER(_float,R.w);REG_MEMBER(_float,R.h);}
 register Rct More...
 
#define REG_VECTOR3D(vec)   {INVISIBLE REG_MEMBER(_float,vec.x);INVISIBLE REG_MEMBER(_float,vec.y);INVISIBLE REG_MEMBER(_float,vec.z);}
 register Vector3D More...
 
#define REG_VECTOR4D(vec)   {INVISIBLE REG_MEMBER(_float,vec.x);INVISIBLE REG_MEMBER(_float,vec.y);INVISIBLE REG_MEMBER(_float,vec.z);INVISIBLE REG_MEMBER(_float,vec.w);}
 register Vector4D More...
 
#define REG_MATRIX4D(mat)   {for(int i=0;i<4;i++)for(int j=0;j<4;j++){INVISIBLE REG_MEMBER_EX2(_float,mat.Elem(i,j),BCPrintf("%s%d%d",#mat,i,j));}}
 register Matrix4D More...
 
#define REG_MATRIX3D(mat)   {for(int i=0;i<3;i++)for(int j=0;j<3;j++){INVISIBLE REG_MEMBER_EX2(_float,mat.Elem(i,j),BCPrintf("%s%d%d",#mat,i,j));}}
 register Matrix3D More...
 
#define NOHASH   if(!hash)
 Don't use fields in hash calculations. More...
 
#define INVISIBLE   __FIELD(Visible,false);
 An element which invisible in UI, but use in serialization. More...
 
#define READONLY   __FIELD(ReadOnly,true);
 An unediting element. More...
 
#define NOSAVE   __FIELD(Serialize,false);
 An element which visible in UI, but not use in serialization. More...
 
#define NORESET   __FIELD(Noreset,true);
 Element will not be initialised during reset_class. More...
 
#define NONAME   __FIELD(Noname,true);
 ID of the element is invisible in UI. More...
 
#define RENAME(id)   __ADDREG(cStr("[NAME ") + cStr(id) + cStr("]"));
 assign other ID in UI for the control More...
 
#define ICON(path)   __ADDREG("[ICON "##path##"]");
 Insert icon if control supports. More...
 
#define CHK_GROUP(g)   __ADDREG("[GROUP "#g"]");
 specify group for checkbox. More...
 
#define APPLYSCALE   __ADDREG("[APPLYSCALE]");
 apply scene scale to this control More...
 
#define SKIPHINT   __ADDREG("[NOHINT]");
 suppress hint for this element More...
 
#define DEFHOTKEY(combo)   __ADDREG("[HOTKEY "##combo"]");
 assign default hotkey to the UI element, like HOTKEY("CTRL E") More...
 
#define LEFTALIGN   __ADDREG("[LALIGN]");
 force left-align to the control More...
 
#define REG_OPT(x)   __ADDREG(x);
 
#define REG_COORD(x, y, z)
 Place 3 lines of code in correspondence with current coordinate system - Y-up or Z-up. More...
 
#define _MAKE_ONCE
 _MAKE_ONCE - Make some action within brackets {...} once More...
 
#define DEFINE_SECTION(x)   DEFINE_SECTION_SR(x, true)
 Define the collapsable section of parameters. More...
 

Detailed Description

The document describes macro definitions used to register members using BaseClass approach.

Author
Andrew Shpagin
Date
28 Aug 2019

Macro Definition Documentation

#define _EACH (   bcptr,
  be 
)

_EACH(bcptr, be) - Walk through class members using the macro. It is most time effective method of access to all class fields.

Parameters
bcptrBaseClass pointer
beBaseClassElement to be referred within the cycle.
_EACH(ClassPointer, be){
//write some code there, for example seek for object that contains substring in it's name
//This is actually lambda function if you will look the macro.
//be is reference to BaseClassElement, you may get any ingormation about the field from there.
if(be->ID.IndexOf("MySubString")!=-1){
// return true means exit out of the cycle _EACH ... _EACH_END
return true;
}
#define _EACH_END

_EACH_END - End of _EACH ... _EACH_END cycle

#define _EACH_FAST_END

_EACH_FAST_END - In case when you don't need stringual name of member you may walk faster, in this case use _EACH ... _EACH_FAST_END cycle.

BaseClass* B=nullptr;
_EACH(ClassPointer, be){
if(be->Ptr == MyPointer){
// return true means exit out of the cycle _EACH ... _EACH_FAST_END
B = be->BC;//found class that corresponds to the pointer MyPointer
return true;
}
#define _MAKE_ONCE

_MAKE_ONCE - Make some action within brackets {...} once

...do it once...
}
#define APPLYSCALE   __ADDREG("[APPLYSCALE]");

apply scene scale to this control

#define BCPrintf (   ...)    ((ForEachElem || (result && required_index == 0)) ? comms::cStr::Format(__VA_ARGS__) : comms::cStr::Empty)

BCPrintf(...) - Use it if you want to compose name of object using printf - like syntax. Don't use sprintf directly, because BCPrintf makes string only when it is required, not each time when function called.

class MyClass : public BaseClass{
int Array[32];
for(int i=0;i<32;i++){
REG_AUTO(Array[i],BCPrintf("A%d",i));
}
}
};
#define CHK_GROUP (   g)    __ADDREG("[GROUP "#g"]");

specify group for checkbox.

#define DEFHOTKEY (   combo)    __ADDREG("[HOTKEY "##combo"]");

assign default hotkey to the UI element, like HOTKEY("CTRL E")

#define DEFINE_SECTION (   x)    DEFINE_SECTION_SR(x, true)

Define the collapsable section of parameters.

DEFINE_SECTION(MySection){
//registration within the section will be applied for both - UI and serialization
}
}
#define DELIMITER

DELIMITER adds the delimiter in UI.

Example:

class MyClass : public BaseClass{
...
...
}
};
#define FILEPATH (   str,
  name,
  mask 
)

use FILEPATH(str, name, mask) to add file selection control in UI. Only comms::cStr supported

Parameters
str- string variable reference
name- name in UI
mask- mask for files, like "save:*.tif;*.tiff;*.exr;*.tga;*.bmp;*.png" (save dialog) or "load:*.tif;*.tiff;*.exr;*.tga;*.bmp;*.png" (open dialog)

Example:

class MyClass : public BaseClass{
comms::cStr path;
FILEPATH(path,"FilePath","save:*.tif;*.tiff;*.exr;*.tga;*.bmp;*.png");
}
};
#define FSLIDER (   var,
  name,
  minvalue,
  maxvalue,
  VisModulator,
  Inverse 
)

FSLIDER(var,name,minvalue,maxvalue,scale,inversion) to add float slider in UI. It has a bit extended syntax, allows scaling and inversion.

Parameters
varvariable ref
namename in UI
minvalueminimal value
maxvaluemaximal value
scalescaling value (100 if percents expected)
inversiontrue if value inverted, scale/value will be displayed

Example:

class MyClass : public BaseClass{
float y;
...
FSLIDER(y,"Y",0.0,10.0, 100, true);//100.0/y will be displayed with % sign
FSLIDER(y,"YP",0.0,10.0, 100, false);//100*y% will be displayed
...
}
};
#define FUNCTION_CALL (   ...)

FUNCTION_CALL(method[,name,function_parameters]) used to register any function calls.

Parameters
methodname of the function to call.
nameOptional identifier in UI for this function.
The identifier there can't be result of calculation, you can't pass the string there, only literal identifier.
If you want to pass string as identifier use RENAME(string) FUNCTION_CALL(function);
function_parametersif function has parameters, pass it there

Example:

class MyClass : public BaseClass{
int MyFunction1(int x, int y){
...
}
static void MyFunction2();
...
//button in UI: PressTheButton2
FUNCTION_CALL(MyFunction1,"PressTheButton2",1,2);
//button in UI: MyFunction3
FUNCTION_CALL(MyFunction2);
...
}
};
#define ICON (   path)    __ADDREG("[ICON "##path##"]");

Insert icon if control supports.

#define ICON_BUTTON (   ...)

Register function call as button.

Parameters
iconAll icons are placed in material.io/icons/black/ folder. Place new icons there, black icons on transparent
nameThe hint in UIbackground. Keep material.io style.
methodThe function name to call

Usually this method used to create bottom toolset for the class like in VoxTree, Layers, Retopo groups.
Class registration looks like:

//....some registrations....
UI_LAYOUT("BOTTOM [][]");//add 2 buttons at the bottom of the dialog
ICON_BUTTON("add_box",AddSomething,"ADD_SOMETHING_HINT");//add something
ICON_BUTTON("delete",DelSomething,"DEL_SOMETHING_HINT");//delete something
}
#define INVISIBLE   __FIELD(Visible,false);

An element which invisible in UI, but use in serialization.

#define LAMBDA_CALL (   ...)

LAMBDA_CALL(method[,name,function_parameters]) used to register any function calls.

Parameters
methodname of the function to call.
nameOptional identifier in UI for this function.
The identifier there can't be result of calculation, you can't pass the string there, only literal identifier.
If you want to pass string as identifier use RENAME(string) FUNCTION_CALL(function);
function_parametersif function has parameters, pass it there

Example:

class MyClass : public BaseClass{
...
//button in UI: PressTheButton2
LAMBDA_CALL([](){...},"PressTheButton");
...
}
};
#define LAMBDA_ICON_BUTTON (   ...)

Register function call as button.

Parameters
iconAll icons are placed in material.io/icons/black/ folder. Place new icons there, black icons on transparent
nameThe hint in UIbackground. Keep material.io style.
methodThe function name to call

Usually this method used to create bottom toolset for the class like in VoxTree, Layers, Retopo groups.
Class registration looks like:

//....some registrations....
LAMBDA_ICON_BUTTON("add_box",[](){...},"ADD_SOMETHING_HINT");//add something
}
#define LEFTALIGN   __ADDREG("[LALIGN]");

force left-align to the control

#define MAKE_ENUMERATOR (   name,
  content 
)

Make Enumerator in just one line.

Parameters
nameEnumerator name
contentList of items "Item1,Item2,...."
MAKE_ENUMERATOR("MYENUMERATOR2","Item1|Item2|Item3");
....somewhere...
REG_DROPLIST(x2, "droplist2", "MYENUMERATOR2");
#define NOHASH   if(!hash)

Don't use fields in hash calculations.

int x;
REG_AUTO(x);//participates in serialization
NOHASH{//M1,M2 will not be hashed
}
}
#define NONAME   __FIELD(Noname,true);

ID of the element is invisible in UI.

#define NORESET   __FIELD(Noreset,true);

Element will not be initialised during reset_class.

#define NOSAVE   __FIELD(Serialize,false);

An element which visible in UI, but not use in serialization.

#define READONLY   __FIELD(ReadOnly,true);

An unediting element.

#define REG_AUTO (   ...)    REG_AUTO_MACRO_CHOOSER(__VA_ARGS__)

REG_AUTO(variable[,name]) used to register variables in the class.

Parameters
methodname of the function to call if you want to rename it for UI/XML add second parameter
nameoptional, if present, used as identifier in UI for this variable, othervice variable name used.

Example:

class MyClass : public BaseClass{
int x;
bool checkbox;
cStr string;
...
REG_AUTO(x, "X");
REG_AUTO(checkbox);
REG_AUTO(string);
...
}
};
#define REG_COORD (   x,
  y,
 
)

Place 3 lines of code in correspondence with current coordinate system - Y-up or Z-up.

Parameters
xX - related item
yY - related item
zZ - related item
#define REG_DROPLIST (   fieldID,
  name,
  EnumID 
)

REG_DROPLIST(fieldID, name, EnumID) adds the droplist to UI, list into XML. The referred variable should be int.

Parameters
fieldID- variable reference, should be int
name- name in UI/XML
EnumID- enumerator reference. Maybe identifier like "enum_name" or explicit list of items like "Item1|Item2|Item3". See example for details.

Example:

class MyClass : public BaseClass{
int x1;
int x2;
...
//create enumerator just now and use immediately
REG_DROPLIST(x1, "droplist1", "Item1|Item2|Item3");
//Other option is to create Enumerator right there or somewhere in code
_MAKE_ONCE{//use it to avoid multiple call of code
Enumerator* E = ENUM.Get("MYENUMERATOR");
if(E->GetAmount() == 0){
E->Add("SomeItem1",Value1);
E->Add("SomeItem1",Value2);
...
}
}
REG_DROPLIST(x2, "droplist2", "MYENUMERATOR");
//You may define Enumerator just in one line
MAKE_ENUMERATOR("MYENUMERATOR2","Item1|Item2|Item3");
REG_DROPLIST(x2, "droplist2", "MYENUMERATOR2");
...
}
};
#define REG_MATRIX3D (   mat)    {for(int i=0;i<3;i++)for(int j=0;j<3;j++){INVISIBLE REG_MEMBER_EX2(_float,mat.Elem(i,j),BCPrintf("%s%d%d",#mat,i,j));}}

register Matrix3D

#define REG_MATRIX4D (   mat)    {for(int i=0;i<4;i++)for(int j=0;j<4;j++){INVISIBLE REG_MEMBER_EX2(_float,mat.Elem(i,j),BCPrintf("%s%d%d",#mat,i,j));}}

register Matrix4D

#define REG_OPT (   x)    __ADDREG(x);

Use REG_OPT to pass different settings to Class Editor. All settings should be quoted with "". We recommend using the individual defines above instead of REG_OPT for the prettiness of the code.

REG_OPT("[NOSAVE][NONAME]") REG_MEMBER(_float, X);

Possible options:

ValueDescription
[NAME NewName] assign other ID/Name for this control
[COLOR 0xXX...] specify color for the control.
[FONTCOLOR 0xXX....] specify font color.
[NOHINT] don't use hint for the control.
[LALIGN] force left align.
[TRIAL] not allowed in trial mode.
[TABMASK MaskValue] mask for tabs (like in settings).
[SPLIT] insert split icon for formatting.
[ICON PathToIcon] insert icon if control supports.
[HOTKEY keycombo] default hotkeys combination.
[write something except keywords] just something to make identifier unique and don't show the tag in UI.
#define REG_RCT (   R)    {REG_MEMBER(_float,R.x);REG_MEMBER(_float,R.y);REG_MEMBER(_float,R.w);REG_MEMBER(_float,R.h);}

register Rct

#define REG_TEXTURE_2 (   x,
 
)

use REG_TEXTURE(var[,name]) to register texture image in UI/XML

Parameters
x- int variable reference
name- name in UI/XML, optional parameter, if not present the variable name used
#define REG_VECTOR2D (   vec)    {INVISIBLE REG_MEMBER(_float,vec.x);INVISIBLE REG_MEMBER(_float,vec.y);}

register cVec2

#define REG_VECTOR3D (   vec)    {INVISIBLE REG_MEMBER(_float,vec.x);INVISIBLE REG_MEMBER(_float,vec.y);INVISIBLE REG_MEMBER(_float,vec.z);}

register Vector3D

#define REG_VECTOR4D (   vec)    {INVISIBLE REG_MEMBER(_float,vec.x);INVISIBLE REG_MEMBER(_float,vec.y);INVISIBLE REG_MEMBER(_float,vec.z);INVISIBLE REG_MEMBER(_float,vec.w);}

register Vector4D

#define RENAME (   id)    __ADDREG(cStr("[NAME ") + cStr(id) + cStr("]"));

assign other ID in UI for the control

#define SAVE_ONLY

SAVE_ONLY used to start serialization (only) definition section. Look UI_ONLY for details and example.

If you are using UI_ONLY or SAVE_ONLY, all commands like NOSAVE and INVISIBLE are ignored
If you are using UI_ONLY or SAVE_ONLY, all commands like NOSAVE and INVISIBLE are ignored
Example:

class MyClass : public BaseClass{
void button1();
void button2();
float x,y;
{//UI registration section
UI_LAYOUT("2");//two columns
FUNCTION_CALL(button1);
FUNCTION_CALL(button2);
}
{//Saving section
}
}
};
#define SAVE_OR_UI (   save,
  ui 
)

SAVE_OR_UI used to start conditional serialization or UI definition section.

Example:

class MyClass : public BaseClass{
void button1();
void button2();
float x,y;
bool ui_field;
bool save_fields;
{
SAVE_OR_UI(save_fields,ui_field);
UI_LAYOUT("2");//two columns
FUNCTION_CALL(button1);
FUNCTION_CALL(button2);
}
}
};
#define SERIALIZE ( )

SERIALIZE() { ... } used to register variables and functions in the class. There are no input parameters.

Example:

class MyClass : public BaseClass{
int x;
cStr string;
void doit(int x){
}
static void dostatic(){
}
...
REG_AUTO(x, "X");//register and change name
REG_AUTO(string);//register with default name
CLASS_METHOD_CALL(doit, "dosomething", 1);//register method of the class
if(x>3){//conditions allowed within the registration section
FUNCTION_CALL(dostatic);//register static call
}
...
}
};
#define SERIALIZE_LATER ( )

SERIALIZE_LATER() used to register variables and functions in the class.
.

The registration should be placed separately in cpp file using SERIALIZE_NOW(Classname) { ... }

Example:

class MyClass : public BaseClass{
int x;
cStr string;
void doit(int x){
}
static void dostatic(){
}
}
SERIALIZE_NOW(MyClass){
REG_AUTO(x, "X");//register and change name
REG_AUTO(string);//register with default name
CLASS_METHOD_CALL(doit, "dosomething", 1);//register method of the class
if(x>3){//conditions allowed within the registration section
FUNCTION_CALL(dostatic);//register static call
}
}
#define SERIALIZE_NOW (   x)

SERIALIZE_NOW(classname) { ... } used to register variables and functions in the class if SERIALIZE_LATER() was declared in the class.

Parameters
classnamethe name of the class to register

Example:

class MyClass : public BaseClass{
int x;
cStr string;
void doit(int x){
}
static void dostatic(){
}
}
SERIALIZE_NOW(MyClass){
REG_AUTO(x, "X");//register and change name
REG_AUTO(string);//register with default name
CLASS_METHOD_CALL(doit, "dosomething", 1);//register method of the class
FUNCTION_CALL(dostatic);//register static call
}
#define SKIPHINT   __ADDREG("[NOHINT]");

suppress hint for this element

#define SLIDER (   var,
  name,
  minvalue,
  maxvalue 
)

SLIDER(var,name,minvalue,maxvalue) to add integer/float slider in UI. Only float and int supported.

Parameters
varvariable ref
namename in UI
minvalueminimal value
maxvaluemaximal value

Example:

class MyClass : public BaseClass{
int x;
float y;
...
SLIDER(x,"X",0,10);
SLIDER(y,"Y",0.0,10.0);
...
}
};
#define STATE_BUTTON (   name,
  variable,
  value 
)    REG_TYPE_ANYTHING(variable, __state, name, (void*)cPtrDiff(value))

STATE_BUTTON(var_name, int_variable_ref, ethalon_value) used to register state button.

Parameters
methodname of the function to call if you want to rename it for UI/XML add second parameter
nameoptional, if present, used as identifier in UI for this variable, othervice variable name used.

Example:

class MyClass : public BaseClass{
MyClass(){
x = 1;
}
int x;
...
REG_AUTO(x, "Button1", 1);
REG_AUTO(x, "Button2", 2);
...
}
};
#define UI_LAYOUT (   str)

UI_LAYOUT(str) splits ui elements to several columns with proportional or fixed width.

Parameters
strtext that defines relation between controls width. Use [value_in_pixels] to define absolute width.

UI_LAYOUT may use two additional keywords: TOP and BOTTOM. TOP moves controls to the tor of the window frame (header -like)
BOTTOM moves elements to the bottom of the frame, like toolset buttons. It is recommended to use ICON_BUTTON/3/4 for bottom toolset.
Example:

class MyClass : public BaseClass{
void button();
void long_button();
void X();
...
//places next 3 controls in one line: [button][long_button][X], length of [button] is twice less than [long_button], [X] has fixed width 32
UI_LAYOUT("1 2 [32]");
CLASS_METHOD_CALL(button);//[button]
CLASS_METHOD_CALL(long_button);//[long_button]
CLASS_METHOD_CALL(X);//[X]
...
}
};
#define UI_ONLY

UI_ONLY and SAVE_ONLY used if you want to register UI section and Serialization sections separately
.

If you are using UI_ONLY or SAVE_ONLY, all commands like NOSAVE and INVISIBLE are ignored
Example:

class MyClass : public BaseClass{
void button1();
void button2();
float x,y;
{//UI registration section
UI_LAYOUT("2");//two columns
FUNCTION_CALL(button1);
FUNCTION_CALL(button2);
}
{//Saving section
}
}
};