BlenderDev/SDNA

Wikipedia,自由的百科全书

原文:http://www.blender3d.org/cms/Notes_on_SDNA.436.0.html


任何一个想给blender内核加入一些新功能的时候,都会面对这一个很奇怪的系统--在代码中我叫它SNDA或者是struct-dna。这个核心的内容早就应该写出文档了,但现在还不晚。


这个系统是为了支持blender的文件格式和内部库/数据库的系统。有了它blender可以进行运行时检查结构数据的内容。这样可以增加很多好的特性:

-你可以增加或者移除结构的变量,甚至增加或者移除整个结构体而不需要考虑blender的版本兼容性。

-你可以把它使用在blender的Python或是smart Button中,运行时检查提供了哪一些的变量和结构体。


Blender中所有的可以存储到文件中的结构体都被描述为SDNA。这是一长串的包含结构体,变量名,变量类型的代码。“sdna”管理这些,它有一个内建的.h头文件的列表,读取他们然后转换成SDNA文件。


当一个文件被存储了,写结构体的函数察看结构体代码,然后把它写入一个块(struct BHead,writefile.c)。在这个文件的末尾,完整描述SDNA的文件添加到.blender文件中,使文件前后版本兼容。


每一份编译的blender都也有一份SDNA描述。当一个文件被读取,它的SDNA结构与可执行的blender的SDNA进行比较。不同的结构被标记,然后读取得时候转换。

允许的转换(变化)有:


-如果名字是一样的但是类型不同,它就要试图转换。只有可能的转换才会发生(比如short->int,int->float),不然就置0。

-新的变量会被初始化为0。

-确定数组的大小(比如[3][3],[4][4])。

-纠正指针大小(比如32bit,64bit)。

-char到float:被255分割。

-结构体中的结构体的改变正常工作。


早些时候,我没有在系统中包含自动的“padding”…,在结构体中包含一些空位,这是面对数据对齐是编译器的系统依赖习惯。比如说:在SGI中一个int一直是以一个可以被4整除的地址开始。当你设计这样一个结构体的时候:

struct XYZ {

char x_flag;

float x;

char y_flag;

float y;

char z_flag;

float z;

}

实际的结构体长度应该是6*4=24byte。更糟的是:向一个这样的结构体:

struct ABC {

char a;

}

在ALPHA机器上是8位,在32位机器上是4位。


所以为了有正确的SDNA结构和所有支持的操作系统,你应该设计一个非填空的结构体,下面是一些规则:

-设计SDNA结构最主要的目的是在64位机器上以8位对齐的在32位系统上自动的会变成4位对齐。

-有意义的指针是8位长,在32位机器也是一样。

-结构的大小应该一直是8位的倍数。

-在结构体内的结构体应该从一个可以被8整除的地址开始。

-指针从可以被8整除的地址考试,除非它指向的变量也是一个指针。

-int/float从可以被4整除的地址开始。

-shorts从可以被2整除的地址开始。

如果你不能够较好地管理它,那么在结构体中加入“pad”变量。你会在blender中看到更多这样的用法,它表示了在以后可以使用的空的空间。但是在blender中不要用pad变量干什么事!!!


TypeError心得

读代码的第一步是研究sdna结构

sdna是blender中很另人感到骄傲的一个东西,它能使blender文件在横竖方向的移植都很方便。

在DNA_xxx.h的文件中包含了blender中所有读存取文档中需要的struct,比如mesh type,action type....

所有这些的结构体在makesdna的main函数下生成了一个dna.c的文件,这样这个文件就是包含了当前编译版本所有的结构体的信息:结构体的类型,名称,成员名称.....。存取blender文件的时候,记录下他的dna,然后和读取belnder文件的地方去比较sdna,如果一样表示版本一致,如果不一样,则(干什么现在还不知道).....

研究的时候只需要看DNA_ID.h,DNA_listbase.h,DNA_mesh_types.h,DNA_space_types.h (一个space就是一个可选的窗口,如3D_view窗口),DNA_vec_types.h,DNA_view2,3d_types.h这几个,其他的需要的时候再看。还有sdna。c一定要好好看,这个是生成dna.c的过程。

Personal tools