Edit:
Actually the assumption on what data gets saved was wrong
data_blocks = set(bpy.context.selected_objects)
is enough to get all the linked materials, nodes etc.
The script to pack the texture images works just by
import bpy
bpy.ops.file.pack_all() #Tells blender to pack images into the file on save
data_blocks = {*bpy.context.selected_objects, }
bpy.data.libraries.write("my blendfile dir", data_blocks, compress=True)
bpy.ops.file.unpack_all() #Tells blender not to pack images into the file on save
The option compress=True adds compression to the library file.
The Problem
I think the selected_objects data only includes the data of the linked object:
- If it is a lamp it will contain brightness type etc
- If it is a mesh it will contain the vertices, faces and the link/name to the materials assignes but NOT the material/nodegroups/textures itself.
Also the Images need to be packed
The Research
Taking a look at the api docs:
https://docs.blender.org/api/blender_python_api_2_77_1/bpy.types.BlendDataLibraries.html
import bpy
filepath = "//new_library.blend"
# write selected objects and their data to a blend file
data_blocks = set(bpy.context.selected_objects)
bpy.data.libraries.write(filepath, data_blocks)
# write all meshes starting with a capital letter and
# set them with fake-user enabled so they aren't lost on re-saving
data_blocks = {mesh for mesh in bpy.data.meshes if mesh.name[:1].isupper()}
bpy.data.libraries.write(filepath, data_blocks, fake_user=True)
# write all materials, textures and node groups to a library
data_blocks = {*bpy.data.materials, *bpy.data.textures, *bpy.data.node_groups}
bpy.data.libraries.write(filepath, data_blocks, compress=True)
The Solution?
import bpy
bpy.ops.file.pack_all() #Pack all images into the file
data_blocks = {*bpy.context.selected_objects,
*bpy.data.images,
*bpy.data.materials,
*bpy.data.textures,
*bpy.data.node_groups }
bpy.data.libraries.write("my blendfile dir", data_blocks, compress=True)
bpy.ops.file.unpack_all() #Will unpack ALL files in the current file.
If the pack_all() command does not work or you don't want it, I think you could loop over all the images and pack them individually:
for image in bpy.data.images:
image.pack()
I tested the code on packing images (as images) and for me at least it works