Field是对基本数据类型的封装,从而实现节点以及模块之间的数据传递。典型的数据类型包含如下几类:
Field之间的连接和断开主要依赖以下两个函数实现,连接过程中会进行数据有效性验证,如有效则返回true,无效返回false。
virtual bool connect(FBase* dst) = 0;
virtual bool disconnect(FBase* dst);
FBase作为所有Field的基类,其功能主要是对Field的连接状态进行统一管理。
connect(FBase* dst)在FBase中被定义为纯虚函数,因而其具体实现依赖于特定Field。该设计主要为了对数据连接行为进行有效的验证,防止将数据连接到错误的类型。
假设存在A、B、C三个Field类型数据,他们的连接关系设置为A->B->C。此时为了降低数据转换和存储开销,当我们对C的数据进行操作时,会根据其连接关系返回最顶端(这里对应的是A)的数据指针进行操作。
FVar:继承自FBase,是对单一数据类型的封装,包括标量数据,如int、float、double等;矢量数据,如Vec3f等;二阶张量数据,如Mat3f;文件路径类型数据,如FilePath。节点和模块中可以通过使用DEF_VAR/DEF_VAR_IN等宏定义来进行定义:
DEF_VAR(Real, TangentialFriction, 0.0, "Tangential friction");
其中Real代表数据类型,TangentialFriction代表数据名称,0.0代表初值,“Tangential friction"则表示数据的说明。通过DEF_VAR定义的数据实际使用过程中可以通var+数据名称的方式对数据进行操作。假设我们需要将上述Field连接到另一个功能模块,则可以调用如下接口进行:
this->varRestDensity()->connect(...);
常见数据类型定义及GUI视图如下:
(1)FVar,int类型:
C++代码定义:
DEF_VAR(int, Types, 4, "winds Types");
Qt视图:
(2)FVar,float类型:
C++代码定义:
DEF_VAR_IN(Real, Radius, "Search radius");
Qt视图:
(3)FVar,bool类型:
C++代码定义:
DEF_VAR(bool, Active, true, "Indicating whether the simulation is on for this node!");
Qt视图:
(4)FVar,FilePath类型:
C++代码定义:
DEF_VAR(FilePath, FileName, "", "");
Qt视图:
(5)FVar,Vec3f类型:
C++代码定义:
DEF_VAR(Vec3f, Location, 0, "Node location");
Qt视图:
(6)FVar,PEnum数据:枚举数据类型。通过DEF_ENUM定义数据,通过var+数据名称的对数据进行操作。ENUM类型定义如下:
C++代码定义:
DECLARE_ENUM(EKernelType,
KT_Smooth = 0,
KT_Spiky = 1);
DEF_ENUM(EKernelType, KernelType, EKernelType::KT_Spiky, "Rendering mode");
Qt视图:
参数类型为int、uint、Vec3f、Vec3d的FVar数据需要调用setRange()函数设置数据的有效范围,否则Qt界面可能会显示异常。
FArray:对Array.h中定义的一维数组进行封装,类似于STL中的vector。根据其在节点/模块中的不同功能,我们采用如下三种形式定义:
DEF_ARRAY_IN(Coord, Position, DeviceType::GPU, "Output"); //输入
输入数据,访问方式为in+数据名称,即inPosition()。
DEF_ARRAY_OUT(Coord, Position, DeviceType::GPU, "Output"); //输出
输出数据,访问方式为out+数据名称,即outPosition()。
DEF_ARRAY_STATE(Coord, Position, DeviceType::GPU, "Internal state"); //内部状态变量
状态变量,访问方式为state+数据名称,即statePosition()。
FArrayList:对ArrayList.h数据进行封装,用于支持CPU/GPU兼容的动态数据类型。其定义方式与FArray类似,即:
DEF_ARRAYLIST_IN(Coord, Position, DeviceType::GPU, "Input"); //输入
输入数据,访问方式为in+数据名称,即inPosition()。
DEF_ARRAYLIST_OUT(Coord, Position, DeviceType::GPU, "Output"); //输出
输出数据,访问方式为out+数据名称,即outPosition()。
DEF_ARRAYLIST_STATE(Coord, Position, DeviceType::GPU, "Internal state"); //内部状态变量
状态变量,访问方式为state+数据名称,即statePosition()。
FInstance:主要为了支持存在继承关系的数据之间的连接,典型应用为利用FInstance定义不同拓扑结构数据:
DEF_INSTANCE_IN(PointSet<TDataType>, PointSet, "PointSet is derived from TopologyModule"); //输入
输入数据,访问方式为in+数据名称,任意继承自PointSet的子类都可以连接到该数据。
DEF_INSTANCE_OUT(PointSet<TDataType>, PointSet, "Output"); //输出
输出数据,访问方式为out+数据名称。
DEF_INSTANCE_STATE(PointSet<TDataType>, PointSet, "Internal state"); //内部状态变量
状态变量,访问方式为state+数据名称,在Qt界面中,显示如下: