[Bf-python] cyclic dependency errors using Blender.Library

Goat Man goatman.py at gmail.com
Fri Dec 18 00:51:21 CET 2009


I can not find any documentation how to append an entire scene using
Blender.Library or the newer libData module that will always avoid cyclic
dependency errors.  The cyclic errors are caused when a dependent object is
loaded before the object it needs to reference.  For example the object may
be the child of the other, or a modifier might reference it.

Library.Datablocks('Object')

this function seems to return object names in random order, not their order
of dependence.
so simply iterating through the names, and calling: Library.Load(obname,
'Object',0) will cause the cyclic dependency errors.

Currently i am using this very ugly workaround to peek into a blend file
before loading it, checking every object in the scene and finding the
dependency order, this gets saved to a pickled file, which is then read and
gives Library.Load the proper order.  There must be a better way.

import Blender, bpy, random, pickle

def inspect():
    r = {}
    order = []
    objects = {}
    for bo in bpy.data.scenes.active.objects:
        r[ bo.name ] = []
        order.append( bo.name )
        objects[ bo.name ] = bo

    ##################################
    for bo in bpy.data.scenes.active.objects:

        if bo.parent:
            deps = r[ bo.parent.name ]
            if bo.name not in deps:
                deps.append( bo.name )
                #print 'parent-dependent ->', bo.parent.name, bo.name

        for mod in bo.modifiers:
            print mod
            try:
                mbo = mod[Blender.Modifier.Settings.OBJECT]
                deps = r[ mbo.name ]
                if bo.name not in deps:
                    deps.append( bo.name )
                    #print 'mod-dependent ->', mbo.name, bo.name

            except: pass

        for cns in bo.constraints:
            print cns
            target = None
            try: target = cns[ Blender.Constraint.Settings.TARGET ]
            except: pass
            if target:
                deps = r[ target.name ]
                if bo.name not in deps:
                    deps.append( bo.name )
                    print 'cns-dependent ->', target.name, bo.name

        #if bo.type == 'Mesh': print bo.name; print bo.modifiers[0]

    #random.shuffle( order )
    while True:
        #for p in range(4):
        stop = True
        for n1 in r:
            curidx = order.index( n1 )
            for n2 in r:
                if n1 != n2:
                    deps = r[n2]
                    if n1 in deps:
                        idx = order.index( n2 )
                        if curidx < idx:
                            stop = False
                            curidx = idx+1
                            order.remove( n1 )
                            order.insert( idx+1, n1 )
                            #print 'new idxs', order.index(n1),
order.index(n2)
                        elif curidx == idx: print 'this is a bug'

        #print order
        if stop: break
    #print order

    preempties = []
    postempties = []
    empties = []
    armatures = []
    meshes = []
    lattices = []
    lights = []
    cameras = []
    others = []
    for n in order:
        ob = objects[n]
        t = ob.type
        if t == 'Armature': armatures.append( n )
        elif t == 'Empty':
            empties.append( n )
            if ob.emptyShape == 4:        # single arrow
                postempties.append( n )
            else: preempties.append( n )
        elif t == 'Lattice': lattices.append( n )
        elif t == 'Lamp': lights.append( n )
        elif t == 'Camera': cameras.append( n )
        elif t == 'Mesh': meshes.append( n )
        else: others.append( n )

    ## this simple rule works ##
    loadorder = preempties + armatures + postempties + lattices + lights +
meshes + others
    dump = {
        'load-order' : loadorder,
        'empties' : empties,
        'armatures' : armatures,
        'meshes' : meshes,
        'lattices' : lattices,
        'lights'    : lights,
        'cameras' : cameras
    }
    return dump
pickle.dump( inspect(), open('/tmp/blend-inspection','wb'), -1 )
Blender.Quit()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.blender.org/pipermail/bf-python/attachments/20091218/5a73fea8/attachment.html>


More information about the Bf-python mailing list