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$
  • $\begingroup$ Someone asked about it and tis is the answerthat was okayed. $\endgroup$ – Lukasz-40sth Jun 16 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$ – miceterminator Jun 16 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$ – Pastrokkio Jun 16 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$ – Pastrokkio Jun 16 at 19:13
3
+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$
  • 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$ – miceterminator Jun 16 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$ – miceterminator Jun 16 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$ – miceterminator Jun 16 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$ – miceterminator Jun 16 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$ – miceterminator Jun 16 at 19:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.