3
$\begingroup$

Having a large amount of objects in several groups, not being instantiated, I would like to merge them all to a single group. What is the most efficient way to do it using Python API?

EDIT

A minimal example would be:

  1. Create a scene with two cubes, add them to Group1, save the file as file1.blend.
  2. Create a new file with another two cubes, add them to Group2, save the file as file2.blend.
  3. Start a new file and load groups from both using

    with bpy.data.libraries.load('file1.blend', link=False) as (data_src, data_dst):
        data_dst.groups = data_src.groups
    with bpy.data.libraries.load('file2.blend', link=False) as (data_src, data_dst):
        data_dst.groups = data_src.groups
    
  4. What is the most efficient way using Python API to merge Group1 and Group2 to a single group?
$\endgroup$
  • $\begingroup$ Put each group of objects in a set, and unionize the sets. $\endgroup$ – boardrider Jun 4 '17 at 8:58
  • $\begingroup$ Thank you @boardrider, but I have no idea how to implement it in the API. Could you please provide a piece of code as well? $\endgroup$ – Isolin Jun 4 '17 at 10:51
  • $\begingroup$ not unless you provide a stackoverflow.com/help/mcve, @Isolin. $\endgroup$ – boardrider Jun 5 '17 at 8:42
  • $\begingroup$ I think the question is formulated clearly enough, but I have now added an example as you requested. $\endgroup$ – Isolin Jun 5 '17 at 10:57
1
$\begingroup$

After trying some more elegant methods and failing, this is a brute force solution to what you're trying to achieve. It essentially appends all the objects from the provided list of files (without their groups), and then adds all the objects into one group called 'merged'. It's can probably be solved more elegantly with groups, but since this worked for your example, I stopped trying to find other workarounds.

import bpy
from os.path import join

for g in bpy.data.groups:
    g.user_clear()
    bpy.data.groups.remove( g )

baseDir = "path/to/blendfiles"

allObjects = []

files = ['f1.blend', 'f2.blend']
for f in files:
    fPath = join( baseDir, f )

    objects = []
    with bpy.data.libraries.load( fPath ) as (data_from, data_to):
        for name in data_from.objects:
            objects.append({'name': name})

    bpy.ops.wm.append( directory = fPath + "/Object/", files = objects )

mergedGroup = bpy.data.groups.new('merged')
for o in bpy.data.objects:
    mergedGroup.objects.link( o )
$\endgroup$
  • $\begingroup$ Thank you for your answer. Yes it works, I even figured out a simpler solution without the ops.wm.append, since I only need to instantiate the merged group once at the end. It is, however, only applicable to the simple example @boardrider requested. In the real use case I have 20k+ objects in each of the groups and it takes almost 4 hours to merge them this way. I am looking for a solution which would avoid any scene update calls until the very last step, i.e. adding a mergedGroup instance into the scene. I tried many variations, but yet I didn't find any efficient one. $\endgroup$ – Isolin Jun 16 '17 at 16:26

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.