Search code examples
fieldblenderfile-format

How to interpret Blender's SDNA structure field type index?


As someone commented that it's impossible to dump the contents of a ".blend" file, I started to write a parser for ".blend" files ;-) So far I can parse all the file blocks and the SDNA. However when it's about to read the file blocks' data into the corresponding structure fields, I'm running into a problem that I don't really know how to solve (due to lack of proper documentation):

If the n-th field of a structure has type index i, how do I decide whether type i is a structure recursively, or a simple type?

For example FileGlobal has a field short subversion, where the type index for short is 2. Obviously short is not a composite structure, but how does the parser decide?

In my parser's SDNA STRC index 2 is ListBase, while TYPE index 2 is short. Obviously the type index is valid in both tables, but have a different meaning...

So is my parser wrong, or what is the trick? For reference, here are some details of the SDNA I'm seeing:

file-header: BLENDER version 279 little-endian 64-bit ptr
...
file-block: code DNA1 size 90700 addr 55b81c6e7c80 SDNA 0 count 1
SDNA: names 4291
SDNA: NAME #0=*next
SDNA: NAME #1=*prev
SDNA: NAME #2=*data
...
SDNA: types 706
SDNA: TYPE #0=char
SDNA: TYPE #1=uchar
SDNA: TYPE #2=short
...
SDNA: TLEN #0=1
SDNA: TLEN #1=1
SDNA: TLEN #2=2
...
SDNA: structures 621
SDNA: STRC #0=stype 12 nfields 2
...
SDNA: STRC #2=stype 14 nfields 2
SDNA: STRC  field #0=ftype 11 name 3
SDNA: STRC  field #1=ftype 11 name 4
...

Insights?


Solution

  • As there is no answer yet, I'm trying to answer my question piece-by-piece (as I learn it):

    First, the SDNA index given in the file block seems to be the index of the type in the STRC table. However the type number of the type at index 0 is 12. That fixed offset (12) continues until index 12, where the type is 26. So actually you need another table (inverted index) that matches the type number to the index of the type in the STRC table.

    As the first type number in that table is 12, it seems the first twelve type numbers are used for these primitive types: char, uchar, short, ushort, int, long, ulong, float, double, int64_t, uint64_t, void

    However these types do not exist in STRC. So type #2 is not present in the inverted index, so it must be a primitive (non-composite) type.

    Unfortunately there seem to be exceptions from the rules above: The field types in STRC are not (like the SDNA index) an index into SDNA, but a type number, so you need to use the inverted index there. When using a recursive routine to decode (like me) the routine must know whether processing a "type index" or a "type number".