Blender does not convert its data for saving: it writes its C structures as they
are. To make that readable by other versions and other programs, every file carries
the SDNA (“structure DNA”), a catalogue of the names, types, sizes and members of every
structure that can appear in it. It is the body of the DNA1 block. This
page follows the description in Blender’s dna_genfile.cc.
Layout
Counts are 32-bit and the other numbers 16-bit, in the file’s byte order. Each section starts on a 4-byte boundary, counted from the start of the block body.
| Part | Contents |
|---|---|
SDNA | four bytes of magic |
NAME | four bytes, an i32 count, then that many member names, each ended by a zero byte; then padding to 4 bytes |
TYPE | four bytes, an i32 count, then that many type names, each ended by a zero byte; then padding to 4 bytes |
TLEN | four bytes, then one i16 size in bytes per type, in the same order; then two bytes of padding when the count of types is odd |
STRC | four bytes, an i32 count, then one entry per structure |
Each structure entry is an i16 type index (the structure’s own name, in the type
list), an i16 count of members, then per member an i16 type index and an i16 name
index. The SDNAnr of a block header is a position in this list of
structures.
Types
The type list starts with the basic C types (such as char,
uchar, short, ushort, int,
long, ulong, float, double,
int64_t, uint64_t and void), whose sizes come
from TLEN like any other, and goes on with every structure name.
Blender may write only the structures a file uses and name the rest with
placeholders of the form # and a number, to keep the block small.
Member names
A member’s name carries part of its C declaration:
| Name | Means | Size |
|---|---|---|
totvert | a plain member of its type | the type’s size |
*next | a pointer | the file’s pointer size, whatever the type |
**mat | a pointer to pointers | the pointer size |
name[64] | an array | the type’s size × 64 |
mat[4][4] | an array of arrays | the type’s size × 16 |
(*func)() | a function pointer | the pointer size |
Members follow one another with no padding added by the reader: Blender pads its
saved structures explicitly, so the offsets are the running sum of the member sizes,
and a structure’s total matches its TLEN. Blender works out the pointer
size of a file from the SDNA itself, as half the size of the two-pointer
ListBase structure.
Reading a block with it
- Take the block’s
SDNAnrand find that structure inSTRC. - Walk its members, sizing each from its type and name as above.
- Read
nrstructures of that size from the body. - Turn each pointer value into the block whose
oldaddress it matches.
Blender itself compares the file’s SDNA with its own when loading and converts members that were added, removed, renamed or changed in type, which is how a file from one version opens in another.