DiveInto: DNA System

Hi guys, what i intend to do (and hope other people will do for other parts of the blender code) is to write a small introduction to how the DNA system works.
I will refer to files in source, so i suppose you have an up to date source (here you can find how to download it using svn). Note that what i’m going to write is not granted to be corrected, this is what i understood from reading the code, and i’m still learning. So, i if someone knows it better than me, or see some errors, or whatever, post it down here and i will correct it :slight_smile: [Little note: if you have installed doxygen and you generate the documentation for blender is much easier to move from code to code to understand where things are declared or implemented, defined, assigned, what function reference to what, etc…] Since i still don’t know A LOT of the stuff in this system, everyone that have something to add don’t hesitate do post it here.

So, let’s start!

The files we are going to talk about are in

\BlenderSVN\blender\source\blender\makesdna\
\BlenderSVN\blender\source\blender\makesdna\intern\

Inside

\BlenderSVN\blender\source\blender\makesdna

you will find the definitions of the various types, like armatures, camera, object, scene, etc… This are all headers. And so, where this headers are included? The answer is in

\BlenderSVN\blender\source\blender\makesdna\intern

.
Here you’ll find dna_genfile.c and makesdns.c.
First of all let’s explain a bit better what the DNA system is.
Long story short, it is a system that allows to save all the runtime informations of blender inside a file. It is fast, since it is quite a dump of the memory, and this has a good forward and backward compatibility. When a file is saved, the current DNA is also stored inside a file (with current dna i mean that all the headers that were in makesdna when blender got compiled are saved to the file ). Whenever a file is loaded, the system checks the DNA stored inside the file and compare it with the dna of the currently used blender. If it is the same, it simply loads it, if not(eg a variable changed name, a float become an int, a new variable was added and another deleteed), it try to “convert” and make compatible the two different DNA, and loads whatever it manages to. This is also why opening a 2.49 file in 2.5 works, even if the new file format is different from the old one.

At the beginning of dna_genfile.c you will find a small “guide” written by ton that explains the bit alignment needed to make the system work if you want to add a new DNA type.

Here you’ll find also many functions that will convert the actual DNA to what will be wrote to the file, and vice versa(from the data of the file, reconstruct the DNA). I didn’t really looked too deeply here, so i can’t add more on this functions.

Now let’s pass to makesdna.c
here you can change the variable

int debugSDNA = 0;

at line 160 so that blender should print out more informations when you run it in debug mode(but i didn’t managed to make them print…)

int make_structDNA(char *baseDirectory, FILE *file)

at line 879 will create the DNA struct
to save in the file.

So, where all the saving magic happens?

It is in

BlenderSVN\blender\source\blender\blenloader\intern

Here you’ll find writefile.c
I thing here they tried to have a Object-Oriented-like stile written in C. In fact here is defined the WriteData struct that contains all the attributes need for the functions, and it is passed as first argument to quite all functions (similar to the

self

in python. It will store the pointer to the file, the error report and few other things.

static WriteData *writedata_new(int file)//initialize a new WriteData struct
static void writedata_do_write(WriteData *wd, void *mem, int memlen)//here happens the actual write
static void writedata_free(WriteData *wd)//free the previous struct

bgnwrite and endwrite will call the initialize and free functions, while mywrite will “wrap” the writedata_do_write, performing some checks.
After that, you’ll find a long list of functions, each of them like


static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
static void write_fcurves(WriteData *wd, ListBase *fcurves)
static void write_actions(WriteData *wd, ListBase *idbase)

etc… This functions are the specific part that will save to file the data that they should manage(so write_actions will write in the file the actions, and so on)


static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFile *current, int write_user_block, int write_flags, int *thumb)

is the main function that will manage the saving of the file, so, if someone needs to add a new DNA types to be saved, s/he should remember to add his writing function for this new type and add it there(i didn’t tried jet to do this, so i’m not sure if it is correct), while

int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *reports, int *thumb)

is the actual function called when a file is saved.

Well, this is what i understood from my last “researches” in the main code. I hope it will be useful, and with the help of other users it become complete and without errors.
And now guys, is your turn to look into the code :wink:

1 Like

Great job and thanks. I hope I can find time to do something similar.

Hi Makers_F, very nice … with a small ‘but’ … is the blender Wiki not a ‘better’ place?
blendercoders of the DNA (= Dynamic …?) would hopefully correct your investigations, if really wrong and send you into the good direction?

Good point, but since it is not really correct (and right now i’m focusing on university) i wrote it here (even because i fell that the wiki is really hard to use, i hardly can find what i need… If compared to python wiki it’s far from “product ready”). But yes, it can be a good thing to write it on the wiki. If you dare, you add it. If you can’t, maybe i’ll add it when i’ll have time :slight_smile: