"Fossies" - the Fresh Open Source Software Archive

Member "blender-2.93.1/doc/blender_file_format/mystery_of_the_blend.html" (22 Apr 2021, 31906 Bytes) of package /linux/misc/blender-2.93.1.tar.xz:


Caution: In this restricted "Fossies" environment the current HTML page may not be correctly presentated and may have some non-functional links. You can here alternatively try to browse the pure source code or just view or download the uninterpreted raw source code. If the rendering is insufficient you may try to find and view the page on the blender-2.93.1.tar.xz project site itself.

The mystery of the blend
The blender file-format explained
Jeroen Bakker
j.bakker@atmind.nl
http://www.atmind.nl/blender
06-10-2010

Introduction

In this article I will describe the blend-file-format with a request to tool-makers to support blend-file.

First I'll describe how Blender works with blend-files. You'll notice why the blend-file-format is not that well documented, as from Blender's perspective this is not needed. We look at the global file-structure of a blend-file (the file-header and file-blocks). After this is explained, we go deeper to the core of the blend-file, the DNA-structures. They hold the blue-prints of the blend-file and the key asset of understanding blend-files. When that's done we can use these DNA-structures to read information from elsewhere in the blend-file.

In this article we'll be using the default blend-file from Blender 2.54, with the goal to read the output resolution from the Scene. The article is written to be programming language independent and I've setup a web-site for support.

Loading and saving in Blender

Loading and saving in Blender is very fast and Blender is known to have excellent downward and upward compatibility. Ton Roosendaal demonstrated that in December 2008 by loading a 1.0 blend-file using Blender 2.48a [ref: http://www.blendernation.com/2008/12/01/blender-dna-rna-and-backward-compatibility/].

Saving complex scenes in Blender is done within seconds. Blender achieves this by saving data in memory to disk without any transformations or translations. Blender only adds file-block-headers to this data. A file-block-header contains clues on how to interpret the data. After the data, all internally Blender structures are stored. These structures will act as blue-prints when Blender loads the file. Blend-files can be different when stored on different hardware platforms or Blender releases. There is no effort taken to make blend-files binary the same. Blender creates the blend-files in this manner since release 1.0. Backward and upwards compatibility is not implemented when saving the file, this is done during loading.

When Blender loads a blend-file, the DNA-structures are read first. Blender creates a catalog of these DNA-structures. Blender uses this catalog together with the data in the file, the internal Blender structures of the Blender release you're using and a lot of transformation and translation logic to implement the backward and upward compatibility. In the source code of blender there is actually logic which can transform and translate every structure used by a Blender release to the one of the release you're using [ref: http://download.blender.org/source/blender-2.48a.tar.gz blender/blenloader/intern/readfile.c lines 4946-7960]. The more difference between releases the more logic is executed.

The blend-file-format is not well documented, as it does not differ from internally used structures and the file can really explain itself.

Global file-structure

This section explains how the global file-structure can be read.

File.blend

File-header

File-block

Header

Data

File-block

File-block

File-block 'Structure DNA'

Header ('DNA1')

Data ('SDNA')

Names ('NAME')

Types ('TYPE')

Lengths ('TLEN')

Structures ('STRC')

File-Block 'ENDB'

File-Header

The first 12 bytes of every blend-file is the file-header. The file-header has information on Blender (version-number) and the PC the blend-file was saved on (pointer-size and endianness). This is required as all data inside the blend-file is ordered in that way, because no translation or transformation is done during saving. The next table describes the information in the file-header.

File-header
reference structure type offset size
identifier char[7] File identifier (always 'BLENDER') 0 7
pointer-size char Size of a pointer; all pointers in the file are stored in this format. '_' means 4 bytes or 32 bit and '-' means 8 bytes or 64 bits. 7 1
endianness char Type of byte ordering used; 'v' means little endian and 'V' means big endian. 8 1
version-number char[3] Version of Blender the file was created in; '254' means version 2.54 9 3

Endianness addresses the way values are ordered in a sequence of bytes(see the example below):

Nowadays, little-endian is the most commonly used.

Endianness Example

Writing the integer 0x4A3B2C1Dh, will be ordered:

Blender supports little-endian and big-endian.
This means that when the endianness is different between the blend-file and the PC your using, Blender changes it to the byte ordering of your PC.

File-header Example

This hex-dump describes a file-header created with blender 2.54.0 on little-endian hardware with a 32 bits pointer length. pointer-size version-number | | 0000 0000: [42 4C 45 4E 44 45 52] [5F] [76] [32 35 34] BLENDER_v254 | | identifier endianness

File-blocks

File-blocks contain a "file-block header" and "file-block data".

File-block headers

The file-block-header describes:

As we can see below, depending on the pointer-size stored in the file-header, a file-block-header can be 20 or 24 bytes long, hence it is always aligned at 4 bytes.

File-block-header
reference structure type offset size
code char[4] File-block identifier 0 4
size integer Total length of the data after the file-block-header 4 4
old memory address void* Memory address the structure was located when written to disk 8 pointer-size (4/8)
SDNA index integer Index of the SDNA structure 8+pointer-size 4
count integer Number of structure located in this file-block 12+pointer-size 4

The above table describes how a file-block-header is structured:

Example

This hex-dump describes a File-block (= File-block header + File-block data) created with blender 2.54 on little-endian hardware with a 32 bits pointer length.
file-block identifier='SC' data size=1404 old pointer SDNA index=150 | | | | 0000 4420: [53 43 00 00] [7C 05 00 00] [68 34 FB 0B] [96 00 00 00] SC.. `... ./.. .... 0000 4430: [01 00 00 00] [xx xx xx xx xx xx xx xx xx xx xx xx .... xxxx xxxx xxxx | | count=1 file-block data (next 1404 bytes)

Before we can interpret the data of this file-block we first have to read the DNA structures in the file. The section "Structure DNA" will show how to do that.

Structure DNA

The DNA1 file-block

Structure DNA is stored in a file-block with code 'DNA1'. It can be just before the 'ENDB' file-block.

The 'DNA1' file-block contains all internal structures of the Blender release the file was created in.
These structure can be described as C-structures: they can hold fields, arrays and pointers to other structures, just like a normal C-structure.

struct SceneRenderLayer { struct SceneRenderLayer *next, *prev; char name[32]; struct Material *mat_override; struct Group *light_override; unsigned int lay; unsigned int lay_zmask; int layflag; int pad; int passflag; int pass_xor; };

For example,a blend-file created with Blender 2.54 the 'DNA1' file-block is 57796 bytes long and contains 398 structures.

DNA1 file-block-header

The DNA1 file-block header follows the same rules of any other file-block, see the example below.

Example

This hex-dump describes the file-block 'DNA1' header created with blender 2.54.0 on little-endian hardware with a 32 bits pointer length.
(file-block identifier='DNA1') data size=57796 old pointer SDNA index=0 | | | | 0004 B060 [44 4E 41 31] [C4 E1 00 00] [C8 00 84 0B] [00 00 00 00] DNA1............ 0004 B070 [01 00 00 00] [53 44 4E 41 4E 41 4D 45 CB 0B 00 00 ....SDNANAME.... | | count=1 'DNA1' file-block data (next 57796 bytes)

DNA1 file-block data

The next section describes how this information is ordered in the data of the 'DNA1' file-block.

Structure of the DNA file-block-data
repeat condition name type length description
identifier char[4] 4 'SDNA'
name identifier char[4] 4 'NAME'
#names integer 4 Number of names follows
for(#names) name char[] ? Zero terminating string of name, also contains pointer and simple array definitions (e.g. '*vertex[3]\0')
type identifier char[4] 4 'TYPE' this field is aligned at 4 bytes
#types integer 4 Number of types follows
for(#types) type char[] ? Zero terminating string of type (e.g. 'int\0')
length identifier char[4] 4 'TLEN' this field is aligned at 4 bytes
for(#types) length short 2 Length in bytes of type (e.g. 4)
structure identifier char[4] 4 'STRC' this field is aligned at 4 bytes
#structures integer 4 Number of structures follows
for(#structures) structure type short 2 Index in types containing the name of the structure
.. #fields short 2 Number of fields in this structure
.. for(#field) field type short 2 Index in type
for end for end field name short 2 Index in name

As you can see, the structures are stored in 4 arrays: names, types, lengths and structures. Every structure also contains an array of fields. A field is the combination of a type and a name. From this information a catalog of all structures can be constructed. The names are stored as how a C-developer defines them. This means that the name also defines pointers and arrays. (When a name starts with '*' it is used as a pointer. when the name contains for example '[3]' it is used as a array of 3 long.) In the types you'll find simple-types (like: 'integer', 'char', 'float'), but also complex-types like 'Scene' and 'MetaBall'. 'TLEN' part describes the length of the types. A 'char' is 1 byte, an 'integer' is 4 bytes and a 'Scene' is 1376 bytes long.

Note

All identifiers, are arrays of 4 chars, hence they are all aligned at 4 bytes.

Example

Created with blender 2.54.0 on little-endian hardware with a 32 bits pointer length.

The names array

The first names are: *next, *prev, *data, *first, *last, x, y, xmin, xmax, ymin, ymax, *pointer, group, val, val2, type, subtype, flag, name[32], ... file-block-data identifier='SDNA' array-id='NAME' number of names=3019 | | | 0004 B070 01 00 00 00 [53 44 4E 41][4E 41 4D 45] [CB 0B 00 00] ....SDNANAME.... 0004 B080 [2A 6E 65 78 74 00][2A 70 72 65 76 00] [2A 64 61 74 *next.*prev.*dat | | | '*next\0' '*prev\0' '*dat' .... .... (3019 names)

Note

While reading the DNA you'll will come across some strange names like '(*doit)()'. These are method pointers and Blender updates them to the correct methods.

The types array

The first types are: char, uchar, short, ushort, int, long, ulong, float, double, void, Link, LinkData, ListBase, vec2s, vec2f, ... array-id='TYPE' | 0005 2440 6F 6C 64 5B 34 5D 5B 34 5D 00 00 00 [54 59 50 45] old[4][4]...TYPE 0005 2450 [C9 01 00 00] [63 68 61 72 00] [75 63 68 61 72 00][73 ....char.uchar.s | | | | number of types=457 'char\0' 'uchar\0' 's' .... .... (457 types)

The lengths array

char uchar ushort short array-id length length length length 'TLEN' 1 1 2 2 0005 3AA0 45 00 00 00 [54 4C 45 4E] [01 00] [01 00] [02 00] [02 00] E...TLEN........ .... 0005 3AC0 [08 00] [04 00] [08 00] [10 00] [10 00] [14 00] [4C 00] [34 00] ............L.4. 8 4 8 ListBase vec2s vec2f ... etc length len length .... .... (457 lengths, same as number of types)

The structures array

array-id='STRC' | 0005 3E30 40 00 38 00 60 00 00 00 00 00 00 00 [53 54 52 43] @.8.`.......STRC 0005 3E40 [8E 01 00 00] [0A 00] [02 00] [0A 00] [00 00] [0A 00] [01 00] ................ 398 10 2 10 0 10 0 number of index fields index index index index structures in types in types in names in types in names ' '----------------' '-----------------' ' ' field 0 field 1 ' '--------------------------------------------------------' structure 0 .... .... (398 structures, each one describeing own type, and type/name for each field)

The DNA structures inside a Blender 2.48 blend-file can be found at http://www.atmind.nl/blender/blender-sdna.html. If we understand the DNA part of the file it is now possible to read information from other parts file-blocks. The next section will tell us how.

Reading scene information

Let us look at the file-block header we have seen earlier:

Now note that:

We can map the Scene structure on the data of the file-blocks. But before we can do that, we have to flatten the Scene-structure. struct Scene { ID id; // 52 bytes long (ID is different a structure) AnimData *adt; // 4 bytes long (pointer to an AnimData structure) Object *camera; // 4 bytes long (pointer to an Object structure) World *world; // 4 bytes long (pointer to an Object structure) ... float cursor[3]; // 12 bytes long (array of 3 floats) ... }; The first field in the Scene-structure is of type 'ID' with the name 'id'. Inside the list of DNA structures there is a structure defined for type 'ID' (structure index 17). struct ID { void *next, *prev; struct ID *newid; struct Library *lib; char name[24]; short us; short flag; int icon_id; IDProperty *properties; }; The first field in this structure has type 'void' and name '*next'.
Looking in the structure list there is no structure defined for type 'void': it is a simple type and therefore the data should be read. The name '*next' describes a pointer. As we see, the first 4 bytes of the data can be mapped to 'id.next'.

Using this method we'll map a structure to its data. If we want to read a specific field we know at which offset in the data it is located and how much space it takes.
The next table shows the output of this flattening process for some parts of the Scene-structure. Not all rows are described in the table as there is a lot of information in a Scene-structure.

Flattened SDNA structure 150: Scene
reference structure typename offsetsize description
id.nextID void*next 0 4 Refers to the next scene
id.prevID void*prev 4 4 Refers to the previous scene
id.newidID ID*newid 8 4
id.libID Library*lib 12 4
id.nameID charname[24] 16 24 'SC'+the name of the scene as displayed in Blender
id.usID shortus 40 2
id.flagID shortflag422
id.icon_idID inticon_id44 4
id.propertiesID IDProperty*properties 48 4
adtSceneAnimData *adt 52 4
cameraScene Object *camera 56 4 Pointer to the current camera
worldScene World *world 60 4 Pointer to the current world
Skipped rows
r.xschRenderData shortxsch3822 X-resolution of the output when rendered at 100%
r.yschRenderData shortysch3842 Y-resolution of the output when rendered at 100%
r.xpartsRenderData shortxparts3862 Number of x-part used by the renderer
r.ypartsRenderData shortyparts3882 Number of x-part used by the renderer
Skipped rows
gpdScenebGPdata*gpd13764
physics_settings.gravityPhysicsSettings floatgravity[3]138012
physics_settings.flagPhysicsSettings intflag13924
physics_settings.quick_cache_stepPhysicsSettings intquick_cache_step13964
physics_settings.rtPhysicsSettings intrt14004

We can now read the X and Y resolution of the Scene:

Note

An array of chars can mean 2 things. The field contains readable text or it contains an array of flags (not humanly readable).

Note

A file-block containing a list refers to the DNA structure and has a count larger than 1. For example Vertices and Faces are stored in this way.