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.
</p>
<p>
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: <ahref="http://download.blender.org/source/blender-2.48a.tar.gz">http://download.blender.org/source/blender-2.48a.tar.gz</a>
This section explains how the global file-structure can be read.
</p>
<ul>
<li>A blend-file always start with the <b>file-header</b></li>
<li>After the file-header, follows a list of <b>file-blocks</b> (the default blend file of Blender 2.48 contains more than 400 of these file-blocks).</li>
<li>Each file-block has a <b>file-block header</b> and <b>file-block data</b></li>
<li>At the end of the blend-file there is a section called "<ahref="#structure-DNA"style="font-weight:bold">Structure DNA</a>", which lists all the internal structures of the Blender release the file was created in</li>
<li>The blend-file ends with a file-block called 'ENDB'</li>
<ahref="https://en.wikipedia.org/wiki/Endianness">Endianness</a> addresses the way values are ordered in a sequence of bytes(see the <ahref="#example-endianess">example</a> below):
Writing the integer <codeclass="evidence">0x4A3B2C1Dh</code>, will be ordered:
<ul>
<li>in big endian as <codeclass="evidence">0x4Ah</code>, <codeclass="evidence">0x3Bh</code>, <codeclass="evidence">0x2Ch</code>, <codeclass="evidence">0x1Dh</code></li>
<li>in little endian as <codeclass="evidence">0x1Dh</code>, <codeclass="evidence">0x2Ch</code>, <codeclass="evidence">0x3Bh</code>, <codeclass="evidence">0x4Ah</code></li>
</ul>
</p>
</div>
<p>
Blender supports little-endian and big-endian.<br>
This means that when the endianness
is different between the blend-file and the PC your using, Blender changes it to the byte ordering
This hex-dump describes a file-header created with <code>blender</code><code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.
This hex-dump describes a File-block (= <spanclass="header">File-block header</span> + <spanclass="data">File-block data</span>) created with <code>blender</code><code>2.54</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
<codeclass="block"><spanclass="descr"> file-block
identifier='SC' data size=1404 old pointer SDNA index=150
0000 4430: <spanclass="header">[01 00 00 00]</span><spanclass="data">[xx xx xx xx xx xx xx xx xx xx xx xx</span> .... xxxx xxxx xxxx<spanclass="descr">
| |
count=1 file-block data (next 1404 bytes)</span>
</code>
</p>
<ul>
<li>The code <code>'SC'+0x00h</code> identifies that it is a Scene. </li>
<li>Size of the data is 1404 bytes (0x0000057Ch = 0x7Ch + 0x05h * 256 = 124 + 1280)</li>
<li>The old pointer is 0x0BFB3468h</li>
<li>The SDNA index is 150 (0x00000096h = 6 + 9 * 16 = 6 + 144)</li>
<li>The section contains a single scene (count = 1).</li>
</ul>
<p>
Before we can interpret the data of this file-block we first have to read the DNA structures in the file.
The section "<ahref="#structure-DNA">Structure DNA</a>" will show how to do that.
This hex-dump describes the file-block 'DNA1' header created with <code>blender</code><code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
structures in <ahref="#DNA1-data-array-types">types</a> in <ahref="#DNA1-data-array-types">types</a> in <ahref="#DNA1-data-array-names">names</a> in <ahref="#DNA1-data-array-types">types</a> in <ahref="#DNA1-data-array-names">names</a></span><spanclass="fade">
.... (398 structures, each one describeing own type, and type/name for each field)</span>
</code>
</p>
</div>
<p>
The DNA structures inside a Blender 2.48 blend-file can be found at <ahref="http://www.atmind.nl/blender/blender-sdna.html">http://www.atmind.nl/blender/blender-sdna.html</a>.
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.
</p>
<aname="reading-scene-information"href="#reading-scene-information"><h2>Reading scene information</h2></a>
<p>
Let us look at <ahref="#example-file-block-header">the file-block header we have seen earlier</a>:<br>
</p>
<ul>
<li>the file-block identifier is <code>'SC'+0x00h</code></li>
<li>the SDNA index is 150</li>
<li>the file-block size is 1404 bytes</li>
</ul>
<p>
Now note that:
<ul>
<li>the structure at index 150 in the DNA is a structure of type 'Scene' (counting from 0).</li>
<li>the associated type ('Scene') in the DNA has the length of 1404 bytes.</li>
</ul>
</p>
<p>
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.
<codeclass="block">struct Scene {
ID id; <spanclass="descr">// 52 bytes long (ID is different a structure)</span>
AnimData *adt; <spanclass="descr">// 4 bytes long (pointer to an AnimData structure)</span>
Object *camera; <spanclass="descr">// 4 bytes long (pointer to an Object structure)</span>
World *world; <spanclass="descr">// 4 bytes long (pointer to an Object structure)</span>
...
float cursor[3]; <spanclass="descr">// 12 bytes long (array of 3 floats)</span>
...
};
</code>
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).
<codeclass="block">struct ID {
void *next, *prev;
struct ID *newid;
struct Library *lib;
char name[24];
short us;
short flag;
int icon_id;
IDProperty *properties;
};
</code>
The first field in this structure has type 'void' and name '*next'. <br>
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'.
</p>
<p>
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.<br>
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.