Blender:SDNA
bf_dna静态库中定义了所有Blender中已知数据结构。这些定义文件统一以DNA_开头。
makesdna.exe
Makesdna创建一个.C文件,该文件具有编码Blender文件格式的长字符串。它速度快,因为它基本上是一个二进制转储。在重建文件时要考虑一些细节(字节顺序和字节对齐)。
这个小程序扫描需要序列化的所有结构,并确定所有成员的名称和类型。它计算存储该结构所需的内存(磁盘上或内存中),以及到达特定结构所需的偏移量。
有一个设施,从sdna得到详细的输出。搜索debugSDNA,这个int可以设置为0(没有输出)至某个整数。更高的数字给出更多的输出。
在makesdna.c文件中定义了
static const char *includefiles[] = {
/* if you add files here, please add them at the end
* of makesdna.c (this file) as well */
"DNA_listBase.h",
"DNA_vec_types.h",
"DNA_ID.h",
"DNA_ipo_types.h",
...
}数组,makesdna将对数组中每个.h文件进行处理,如对DNA_listBase.h文件处理将得到以下内容(可对照头文件中结构类型定义):
1 Converting d:\develop\Blender-git\Blender\source\blender\makesdna\DNA_listBase.h 2 | |-- detected struct Link 3 | | found type Link (*next ||*prev |) 4 | |-- detected struct LinkData 5 | | found type LinkData (*next ||*prev |) 6 | | found type void (*data |) 7 | |-- detected struct ListBase 8 | | found type void (*first ||*last |)
第2行,表示搜索到结构定义,将对该结构进行相关记录:
第三行发现定义了二个变量,类型为Link,变量名为:*next和*prev:
最后将names、types、structs三类数据以字符形式保存到DNAStr数组中,存于dna.c文件中。
DNA的解码:
DNA的解码就是将存储于dna.c文件中的DNAStr数组字符串读取并解码到SDNA结构中。由于dna.c代码已编译进库,所以可直接将DNAStr数据值赋值给SDNA结构的data成员。
在dna_genfile.c中定义了DNA_sdna_from_data、init_structDNA二个函数,DNA_sdna_from_data函数将DNAStr数组赋值给SDNA结构的data成员,init_structDNA将data中的字符数据进一步解码到SDNA结构中。
sdna->nr_names:name数,对应names数组长度
sdna->names:将names[0]、names[1]...作为指针分别指向data中对应第0、1的名称字符串;
sdna->nr_types:type数,对应types、typelens数组长度;
sdna->types:将types[0]、types[1]...作为指针分别指向data中对应第0、1的类型字符串;
sdna->typelens:typelens[0]、typelens[1]对应各type的数据字节数;
sdna->nr_structs:struct数,对应structs数组长度;
sdna->structs:structs[0]、structs[1]...作为指针分别指向data中对应第0、1的结构类型索引,索引号对应types数组元素;
sdna->structs_map:将structs数组中结构按顺序存入ghash表中,键:structs[0]值为为索引在types找到对应data中对应类型字符串的内存地址;值:structs数组序号;
例:*structs[0]值为:0x000c ---->types[0x000c]=0x00007FF660010066这个地址指向是类型名称在data中内存地址,以这个地址作为键;
0作为键对应的值,
sdna->pointerlen:最后根据listbase结构长度来确定它的值;
从以上分析来看,SDNA结构就是将Blender中所有需要的基础数据结构利用makesnda编码到DNAStr数组中,这个文件是blender版本特有的,只在不同Blender版本中才存在差异。主程序运行时将编码好的基础数据结构从DNAStr数组中解码到SDNA结构中。
DNA就是构成Blender基础数据结构,每个Blender版本中DNA差异决定了功能的差异,这对应了生物学中的DNA概念,DNA决定了物种。
而SDNA就是将这些所有的DNA集中结构化,便于程序使用。
makesrna
makesrna.c文件中定义了所有需要处理的rna:
static RNAProcessItem PROCESS_ITEMS[] = { {"rna_rna.c", NULL, RNA_def_rna}, {"rna_ID.c", NULL, RNA_def_ID}, {"rna_texture.c", "rna_texture_api.c", RNA_def_texture}, {"rna_action.c", "rna_action_api.c", RNA_def_action}, {"rna_animation.c", "rna_animation_api.c", RNA_def_animation}, ... {"rna_mask.c", NULL, RNA_def_mask}, {NULL, NULL} };