Blender stores the session contents in a binary file format. But actually, much of that data is not really "binary" (like a e.g. a sound file), but structured data, similar to program code.

Are there any tools (either built-in or external), allowing to find out the precise difference between two blender files? And if so, when working with these tools, are spurious diffs an issue? (e.g. rounding errors in numbers, reordering of entries in collections).

Background information: I'm trying to build up a controlled work environment and workflow, as I know it from software development.


1 Answer 1


You would need to write an export script to dump all the data of the .blend files you want to compare into a text file.

From python you could use difflib to compare them like:

import difflib
import os

old_file = "C:\\Users\\user\Documents\\Blender\\dump1.txt"
new_file = "C:\\Users\\user\Documents\\Blender\\dump2.txt"
a = open(old_file).readlines()
b = open(new_file).readlines()
diff_string = difflib.unified_diff(a=a, b=b)

for line in diff_string:

While it makes almost no sense to compare the meshes between edited versions of a mesh (besides some stats like how the number of polygons has increased etc.) In this BA thread you find more thoughts on that. CoDEmanX linked his git project blend_stats there.

I started a script which is incomplete and has issues with links in objects. You could use it as a starting point and improve it:

import bpy
import mathutils

debug = False

def dump(obj, name="", level=0):
    if level > 10:
    if debug:
        print("call %d obj=%s type=%s" % (level, str(obj), str(type(obj))))
    if str(type(obj)) in ("<class 'builtin_function_or_method'>",):
    if isinstance(obj, mathutils.Vector):
        print("%s=%s" % (name,str(obj.to_tuple())))

    if str(type(obj)) == "<class 'bpy_prop_collection'>":
        for item in obj:
            dump( item, name , level+1)

    if str(type(obj)) == "<class 'tuple'>":
        for item in obj:
            dump( item, name + "[" +str(idx) + "]", level+1)
            idx = idx+1

    for attr in dir(obj):
       if not hasattr(obj, attr ) or attr.startswith("__") or attr in ("bl_rna","base","rna_type"):
       if attr == "particle_edit":
           return # crashes otherwise
       if name+"."+attr in map:
           if debug  or True:
               print("already dumped=%s" % name+"."+attr )
       val = getattr(obj, attr)
       if isinstance(val, (int, float, str, bool)):
          print("%s.%s=%s" % (name,attr,val))
          dump( val, name + "." + attr, level+1)


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .