no Object.getChildren()

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Post Reply
MangoFusion
Posts: 0
Joined: Wed Nov 19, 2003 4:10 pm

no Object.getChildren()

Post by MangoFusion »

Hi there,

Recently i have come across the need to create a heirachy of objects in blender (like the OOPS Schematic).
However, it appears that the Object class only supports getting the parent of an object (getParent()), not getting its children which i need to do.

For the moment though, i have come up with this function to get the children of an object :

Code: Select all

def getChildren(obj):
	children = []
	for ob in Blender.Object.Get():
		if ob.getParent() == obj:
			children.append(ob)
	if len(children) != 0: return children
	else: return None
Example usage :

Code: Select all

def printChildren(obj,level=0):
	children = getChildren(obj)	
	if children == None: return
	else:
		for child in children:
			print "%s%s" % (" "*level, child.getName())
			printChildren(child,level+1)
	
print "Children of your object :"
printChildren(Blender.Object.Get("My Object"))
I hope somebody will find it useful.

gabio
Posts: 0
Joined: Thu Jan 15, 2004 6:41 am
Location: Canada - Québec - Sherbrooke
Contact:

Re: no Object.getChildren()

Post by gabio »

MangoFusion wrote:

Code: Select all

def getChildren(obj):
	children = []
	for ob in Blender.Object.Get():
		if ob.getParent() == obj:
			children.append(ob)
	if len(children) != 0: return children
	else: return None
Ok this work for now, but add more object and this will be a pain in the ass to execute. you'r right this function is missing from the api.

breakin
Posts: 0
Joined: Fri Aug 22, 2003 3:33 am

Post by breakin »

While this code snippet might seem slow, it's very obviously so. The alternative, providing a object.getChildren(), would be far slower unless the children of an object is already cached in Blender for each object (don't know about this). There has to be some sort of cache in order for this to work, there is no way getChildren() can be implemented otherwise in an efficient manner (read: as efficient as what you've done already in python).

From what I can see in the source the object-struct does not hold the children, only the parent, but there might be some other datastructure somewhere. Anyone who knows? I agree the lack of the function mentioned poses a problem.

acheater
Posts: 0
Joined: Tue Mar 30, 2004 9:52 pm
Contact:

Post by acheater »

I agree that this function is missing, I'm about to need this in my own script soon. In addition, there is no function to return the list of "root" objects (though this is trival, filter out the objects with no parents).

I'm likely going to be writing a class(es)/function(s) to produce a scene tree from a list of objects shortly unless someone beats me to it.

ideasman
Posts: 0
Joined: Tue Feb 25, 2003 2:37 pm

Post by ideasman »

Does it matter that getChildren might still be inefficient in C?

1) It will at least be a tiny bit more efficient
2) It will be efficient in the sense that people who need to get an objects children will be able to use a single command, without looking around on the net or writing there own.

The functionality for this is in blender With Select immidiate chaldren in the select menu.

I could probably modify this to make a python function ob.getChildren()

Any comments?

breakin
Posts: 0
Joined: Fri Aug 22, 2003 3:33 am

Post by breakin »

It's not really an c vs. python-issue, if the request is done naive then it's bad wherever it is. The problem is that to export N objects, getChildren has to be called N times and getChildren must loop through all the N objects, giving a complexity of N^2. If people choose to use the getChildren-function this way it's not that good because it's not very clear that it will be inefficient. There should be some kind of cache or accelerator so that, during a script sessions, some things are cached. Because people will call getChildren a lot during one script session (if they do so at all).

theeth
Posts: 500
Joined: Wed Oct 16, 2002 5:47 am
Location: Montreal
Contact:

Post by theeth »

Then it would be best to do it in Python in a separate module which, upon initialisation or specific update calls would build a parenting tree structure and a dictionnary of all the object names pointing to their place in the tree.

Martin
Life is what happens to you when you're busy making other plans.
- John Lennon

yann
Posts: 2
Joined: Wed Oct 16, 2002 12:42 pm

Re: no Object.getChildren()

Post by yann »

MangoFusion wrote:

Code: Select all

def getChildren(obj):
	children = []
	for ob in Blender.Object.Get():
		if ob.getParent() == obj:
			children.append(ob)
	if len(children) != 0: return children
	else: return None
Wouldn't this be the same as:

Code: Select all

def getChildren(obj):
    return filter(lambda x: x.parent==obj, Blender.Object.Get())
Except for the empty list. This policy of using None where an empty list or an exception makes sense confuses me. (Hint: None and empty lists are false, lists with entries are true.)

If you give the Object class a normal dictionary (which will make it faster anyhow), you can even shove an extra method in there with "Blender.Object.getChildren=getChildren". However that may be quite confusing.

Of course, one common thing to do is:

Code: Select all

children={}
for obj in Blender.Object.Get():
  if obj.parent:
    try:
      children[obj.parent.name].append(obj)
    except KeyError:
      children[obj.parent.name]=[obj]
Which will give you a dictionary indexed by object names, containing lists of objects. Objects without parents won't be in there, that's an excercise left for the reader.

Post Reply