[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