3
$\begingroup$

I have noticed that it is a discourse of which one speaks little, the correct way to write a .blend file and save objects etc is for example

data_blocks = set(bpy.context.selected_objects)
bpy.data.libraries.write("my blendfile dir", data_blocks)

But I noticed that for example my models, if I move the file to another computer, the materials are not displayed (purple object) I was wondering if there was a way to "Pack into .blend" through the script like: bpy.data.libraries.write(#pack into blend = True)

I need this for create a .blend file that has textures and images packed without open new .blend file , "write" method think is incomplete because if i delete image or texture new .blend file loose the images/textures

$\endgroup$
4
  • $\begingroup$ Someone asked about it and tis is the answerthat was okayed. $\endgroup$ Jun 16, 2019 at 18:48
  • $\begingroup$ Thanks for linking. I still think that the problem (as Pastrokkio correctly identified) is the packing. He's not complaining about models not showing up, but about texture files not being present. I kind of think the linking to the scene is the difference between a library file and a "normal" blender file. You can still import the objects fine from the library because they will be linked on import. Also I was wrong about needing to add more data: The scripts works just fine with what Pastrokkio has written if you just add the pack/unpack stuff. $\endgroup$ Jun 16, 2019 at 19:09
  • $\begingroup$ I want to clarify that currently the object I write in the .blender file has all the textures, nodes, and images, but they are not packed, the problem is if i delete image folder or texture folder, i want pack the image into new file $\endgroup$
    – Noob Cat
    Jun 16, 2019 at 19:12
  • $\begingroup$ @Lukasz-40sth this is not my problem , the objects have all in new file, the problem is Pack the image into new file $\endgroup$
    – Noob Cat
    Jun 16, 2019 at 19:13

1 Answer 1

5
+50
$\begingroup$

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

$\endgroup$
15
  • 1
    $\begingroup$ I'm 90% sure it does. To test, I started from a non saved startup file, added an image and created a library file. As the library file gets completely rewritten every time and the file was present in the library file this worked. I'll quickly recheck! Tested, worked. $\endgroup$ Jun 16, 2019 at 18:08
  • 1
    $\begingroup$ Ah ok, then I need to modify to unpack after the library file is created. Are there already files packed in the current file that shouldn't be unpacked? $\endgroup$ Jun 16, 2019 at 18:14
  • 1
    $\begingroup$ Not sure if I understand you correctly: I am quite certain, blender doesn't do any compression (unless its lossless) if you save a file. I am not aware of a function that allows you to use some kind of proxy images. Of course the images the render operates at are uncompressed in memory, but should never bet touched in storage. $\endgroup$ Jun 16, 2019 at 18:26
  • 1
    $\begingroup$ I just tested the script again: With the minimal data_blocks = set(bpy.context.selected_objects). Blender saves the ONLY the textures connected to these (selected) Objects into the library file. To test it I created 2 objects with different textures. If selecting only one, only the texture used is saved to the library. The pack_all doesn't do anything on it's own except to tell blender to include the external images on the next save. $\endgroup$ Jun 16, 2019 at 19:24
  • 1
    $\begingroup$ The this should solve it. Writing the library file with packing enabled tells blender to write the images as well! Basically bpy.ops.file.pack_all() behaves somewhat like a libraries.write(**, pack=True) option (which unfortunately does not exist/ is not documented). $\endgroup$ Jun 16, 2019 at 19:41

You must log in to answer this question.

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