2
$\begingroup$

What I'm trying to do is fairly simple but I've found no way to do it. I want to store each object in a scene into a separate blender file. Here's my code:

import bpy
import os
destination_folder = "destination_folder"

for idx, obj in enumerate(bpy.data.objects):
    ctx = bpy.context.copy()
    ctx['selected_objects'] = obj
    file_name = 'file_number' + str(idx) + '.blend'
    bpy.ops.wm.save_as_mainfile(ctx, filepath=os.path.join(destination_folder, file_name))

The problem is that the operator bpy.ops.wm.save_as_mainfile() doesn't have the flag "selected" as many others wm operators do. Any idea? I think context override is a good idea but I'm struggling to do it

$\endgroup$
4
  • $\begingroup$ Is your approach above getting isolated objects? Are you getting partially successful results? Why is the ["selected"] useful? $\endgroup$ Jul 28, 2020 at 16:18
  • $\begingroup$ Do you have collections of objects ? Parent Child relationships in your data? $\endgroup$ Jul 28, 2020 at 16:21
  • $\begingroup$ How many files need to be transformed? How many objects need to be isolated? $\endgroup$ Jul 28, 2020 at 16:34
  • $\begingroup$ @atomicbezierslinger No, my approach it's not working. ctx["selected"] is useful for context override (docs.blender.org/api/current/bpy.ops.html). Yes, I may have parentship in my files. The file is unique but It potentially contains a large number of files to be isolated $\endgroup$
    – Rage
    Jul 28, 2020 at 16:59

2 Answers 2

2
$\begingroup$

Saving multiple objects as separate Blender's files can be done by using BlendDataLibraries (https://docs.blender.org/api/current/bpy.types.BlendDataLibraries.html)

import bpy
import os
destination_folder = "destination_folder"

for idx, obj in enumerate(bpy.data.objects):
    ctx = bpy.context.copy()
    ctx['selected_objects'] = obj
    filename = 'file_number' + str(idx) + '.blend'
    filepath = os.path.join(destination_folder, filename)
    bpy.data.libraries.write(filepath, set(ctx['selected_objects']), fake_user=True)

This code snippet will save the object in a blender's file. To load then the data in the visible user interface a second snippet can be run on the opened saved file:

collection = bpy.data.collections.new('collection')
for obj in bpy.data.objects:
  collection.objects.link(obj) #link object to collection
bpy.context.scene.collection.children.link(collection) #add collection

This second script creates a collection and loads all the objects in the Blender file into it and (in some sense) sets it visible/active

$\endgroup$
-2
$\begingroup$

File Append

You might consider a script ..

  • Opens a new Blender file or reuses a single file in RAM...
  • [File Append] (or Link) from the existing large Blender File. [File Append] is more tested than anything you will write in the next N months. N ∈ {3,4,5 ...}
  • Saves the file to hard disk or similar, with a unique path name. This implies a Python [for] as in the original question.

  • Blender can take command line Python script name to (enumerate) and select a given object for the command [File Append]
  • The Python script needs an enumeration to Append a different object each time.
  • The Python script can Append, File Save, Destroy All Objects ,to reduce Object Count to Zero for the next iteration. You will need a Python list to record your desired [Append] actions.

Perhaps an option

  • An OS Script (Linux Windows Mac) to Launch Blender (this may be optional to reduce exectution time)
$\endgroup$
1
  • $\begingroup$ No, opening a new file each time is way too expensive. This approach for sure would work, but the running time will exceed by far my requirements $\endgroup$
    – Rage
    Jul 28, 2020 at 17:00

You must log in to answer this question.

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