How to store and then retreive parent-child depend

2020-03-30 06:42发布

问题:

I have a hierarchy that I need to:

  1. break apart
  2. doSomething()
  3. put it back together the same way it was before.

I know how to break things for sure, and have plan about what I need to do when they are flat in hierarchy. The problem is how do I parent them back?


Details

This is related to my previous question:

Freeze scale transform on a parent object with animated child (MAYA MEL/Python script)

I need to freeze scale transforms on all nodes in a hierarchy. Problem is that nodes have translate animations on them, and if I try to freeze scale on a parent node, it's child animation gets weird. However it looks like there is a solution, but I need help with implementation of it. I want to:

  1. Group each object
  2. Parent each group to the world
  3. Bake animation to the world space (getting rid of the group node)
  4. Freeze scale transform
  5. re Parent them back

It works when I do it manually, so everything should be ok. But if you think there is better way to achieve my main goal, please do tell me.

So, I've been thinking to write all nodes to a string and call them from there, but I don't know how to handle branches. For example: If it was a branchless hierarchy (one parent and one child all along) I could call them by two, and parent easily. But branches make names in string go like "parent, child, child, child, parent..."

Probably I'm thinking too much and in wrong direction. Any ideas?

回答1:

I would suggest using python if you aren't already - you can use pretty much any data types with each other to get what you need in a single data structure. It will make it much easier than creating a long string and breaking it back up again later.

to collect your hierarchy data:

import maya.cmds as mc

def hierarchyTree(parent, tree):
    children = mc.listRelatives(parent, c=True, type='transform')
    if children:
        tree[parent] = (children, {})
        for child in children:
            hierarchyTree(child, tree[parent][1])

top_node = 'name_of_node'  # could also use mc.ls(sl=True)[0] if you want...
hierarchy_tree = {}
hierarchyTree(top_node, hierarchy_tree)

this should basically start from your top node and recursively go down the hierarchy to create a data structure that's almost like nested dicts... each key is a parent node with it's key value being a tuple that stores a list of children and a dict of children data. Each child dict follows the same format - the child is a key with it's child data in a tuple, etc, etc, etc to the end of the hierarchy. I'm using the tuple with a list and a dict since dicts are unordered... the list will basically ensure you re-parent them in the same order they came from, but you could just store the dict if you don't really care about retaining the order...

To parent it all back, you'll do something like this:

def reparent(tree):
    for parent, data in tree.iteritems():
        children, child_tree = data
        mc.parent(children, parent)
        reparent(child_tree)

reparent(hierarchy_tree)

now... I haven't tested this code - kind of wrote it on the fly without bringing it into Maya. I'm more concerned about errors popping up in the re-parent function, so you may need a try/except in there, but hopefully it'll just skip any empty dict items and get you close to what you need for the in-parenting/re-parenting. This is also assuming all of your nodes have unique short names...

Oh, a note about recursive functions... make sure they'll terminate at some point or else you can get stuck in an infinite loop (this should be fine since we're tracing a hierarchy that has a definite end - ie: no more child nodes)