So, this took me while to figure out, so I want to share it. blendfile.py is a one-file module in blender/2.7x/addons/io_blend_utils/blend/ for reading and writing blend files. This can be especially useful if you require only one or two properties of the file: Now you can do so without loading the entire file in blender, which takes a while.
For the Wonderland Engine, I required the names and resolutions of the texture altases (uv_texture_atlas addon) from a bunch of blend files, here is how I did that:
blends = [...] atlases =  for blend_file_path in blends: with blendfile.open_blend(blend_file_path) as blend: scenes = [block for block in blend.blocks if block.code == b'SC'] for scene in scenes: # get custom properties properties = scene.get_pointer((b'id', b'properties')) # iterate through all the property groups iter = properties.get_pointer((b'data', b'group', b'first')) while iter is not None: group = iter.get_pointer((b'data', b'pointer')) if group is not None: # iterate over all the properties prop = group.get_pointer((b'data', b'group', b'first')) while prop is not None: name = prop.get(b'name') for x in prop.items_recursive_iter(): print(repr(x)) if name == 'name': offset = prop.get((b'data', b'pointer')) blk = blend.block_from_offset.get(offset) blend.handle.seek(blk.file_offset, os.SEEK_SET) atlas_name = blendfile.DNA_IO.read_string0(blend.handle, prop.get(b'len')) elif name == 'resolutionX': resX = prop.get((b'data', b'val')) elif name == 'resolutionY': resY = prop.get((b'data', b'val')) prop = prop.get_pointer(b'next') atlases.append((atlas_name, 2**(resX+8), 2**(resY+8))) iter = iter.get_pointer(b'next') for atlas in atlases: print(repr(atlas))
Since the blendfile module is not documented at all (only used for specific internal use cases), I hope this helps someone who has a similar use case.
This post was imported from my old wordpress site.