getParentRecursive()

hi folks,

if you ever wondered, how to get the root parent of a object, this might be useful for you.

This is the opposite of get.childrenRecursive().


#############################################
#    Copyright (C) 2011 by Severin Stirnemann                                                                                                                            
#    [email protected]
#    
#    feel free to use it                                                                                                                                                                                                                                                                                                                                                  
#############################################

__version__ = "1.0"
__author__  = "Severin Stirnemann"
__date__ = "2011-May-19"

import bge
G = bge.logic
R = bge.render

R.showMouse(1)

cont = G.getCurrentController()
object = cont.sensors[0].hitObject

def getParentRecursive(object, property, iterations):
    """
    returns the root parent of 'object'
    with given 'property' in range of 'iterations'
    """
    if object!= None:
        if object.parent:
            for i in range(iterations):
                if object.parent:
                    if property in object.parent:
                        return object.parent
                        break
                    else:
                        object = object.parent
                    
            if 'root' in object.parent:
                return object.parent
            else:
                return None
        else:
            print ("has no parent, this is root!")
            return object
            
root = getParentRecursive(object, 'root', 10)

print ("root:", root)
    



Attachments

getRootParent.blend (450 KB)

The better method would be to actually use recursion (not tested):


def getParentRecursive(object):
    # Base case
    if not object.parent:
        return object

    # Otherwise, recurse
    return getParentRecursive(object)

Whoa - I never would have thought of running a function in itself… That’s pretty out there thinking - great job, Moguri.

Also, good job, sevi - I hadn’t even thought of implementing parent recursive lookups before this.

@SolarLune:
Recursion is actually a pretty standard technique in programming/computer science:
http://en.wikipedia.org/wiki/Recursion_%28computer_science%29

So, it’s not really “out there thinking”. :wink:

Hi sevi,

you just need to know if the programming language supports it (the most do, but not all).
Such recursion can be easly transformed into iteration (as you already do):


def getRoot(obj):
  if obj is None:
    return
 
  root = obj  
  while root.parent is not None:
    root = root.parent
 
  return root
 
# or to use your interface:
def getParentRecursive(obj, property, iterations):
 
  if obj is None:
    return
 
  root = obj  
  depth = 0
  while ( depth<iterations and not isParent(root, property) ):
    root = root.parent
    depth += 1
 
  return root
 
def isParent(obj, property):
  if obj.parent is None:
    return True
  if property in obj:
    return True
 

Not tested either :wink:

Hint: avoid object - you overwrite the class object with that. You could get trouble with more complex code later. PEP008 recommends to use object_ instead. (Beliefe me I had a looooong search until I solved an error like that :wink: )

Monster

oh thats nice, thanks for reply Guys!

Many interesting things found in the thread until now.
I never tought about a function call itself, nice idea.

And also very important to NOT overwrite anything! i’ll change that and will have a look on my scripts… this could probably be a reason for some problems and crashes.

What does actually the ‘object’ mean?

This is the “master”-class. All Python classes inherit from this class == all python objects are "object"s.

There is an old way of defining classes wihout explicit making object the base class, but it is not recommended (as far as I know).
If you define a class from scratch you do this:


class myClass(object):
  def __init__(self):
    print ("I'm initialized")

One of the typical “overwriting” occurences is “range”. As this is a usefull function for loops, it gets quite problematic, if you assign another value to range e.g. range = 20.

Nice to help :slight_smile:

ah … ok, i read some about the ‘object’ but didnt get it.
I always use classes in blender like this:


class GameObj(bge.types.KX_GameObject,  MouseFunctions):
    """ registers and Indentify GameObjects """
    def __init__(self, this):
        """ initialises Object """
        
        # give Object a reference of its own
        bge.types.KX_GameObject.__init__(self)
        self['this'] = self



So i think it is not neccesary to overgive ‘object’ to the class, because ‘bge.types.KX_GameObject’ therefore would have ‘object’ inside…

As u can see, there is a ‘MouseFunctions’ Class overgiven to the class,
is it necessary to overgive ‘object’ to this class? What would be the point about it?

@Moguri - Hm… I still haven’t tried recursion before. I have quite a bit to learn. Thanks for the link.

@sevi

you implicit inherit object from the other two classes. So you do not need to provide it there.
I think you should have a look in here:
http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html
Look for “New Objects by Subclassing” there is a short desciption why not use “class MyClass:” but “class MyClass(AnyClass)”

Moderation:
This is a bit off-topic now. If you want I can move the posts regarding object into a separate thread in the discussion forum. So it does not hijack your resource thread :).

Monster

jes, its off topic, but worth the discussion. I tought the same.:yes:
@ Monster: if you like to move, feel free.:rolleyes:
Anyway, ill have a look on that class description, cause i’m just scratching on the surface of this theme, means, i can use classes, but i dont fully understand, what i’m dooing.