Issues with getting the root node of the hierarchy based on selection

67 views
Skip to first unread message

yann19

unread,
Sep 20, 2016, 9:22:29 PM9/20/16
to Python Programming for Autodesk Maya
Hi all, I need some help with this function of mine.
Suppose I have the following hierarchy as seen in the attachment.
Assuming that everything in that attachment is of custom nodes (I used locators, groups etc. for easy visual, i hope)
and I am trying to grab the Root Node in which its type is 'stkLevel'.

I am trying to fulfill a few conditions:
  1. User can select either the Root Node or the pCube#
  2. If User selects nothing in the scene, it will prompts a warning
  3. If User selects more than 2 Root Node, it will prompts a warning
  4. If User selects 1 or more 'pCube#', it will return the Root Node within the hierarchy
  5. Ultimately, this function must return the full path of the Root Node
def get_stkLevel():
    sel
= cmds.ls(selection=True, l=True)
   
if len(sel) == 0:
        cmds
.warning("Please select something")


    stkLevel_node
= cmds.ls(sel, type = "stkLevel")
   
if len(sel) > 1:
       
if stkLevel_node:
            cmds
.warning("Please select a valid stkLevel node")
       
else:
            root_list
= []
           
for item in sel:
                root_node
= item.split('|')[1]
               
if root_node not in root_list:
                    root_list
.append(root_node)
           
return cmds.ls(root_list, l=True)[0]
   
else:
       
return stkLevel_node[0]


I got the issue, where if I select only 1 pCube#, and it returns nothing, though it seems to be working if I only select 1 Root Node
While that is one of the issue, can someone kindly guide me if I am writing my code correctly?
I asked this because first I am still not that great of a scripter and I feel that I am forcing my way through while following those conditions


Justin Israel

unread,
Sep 21, 2016, 12:03:07 AM9/21/16
to python_in...@googlegroups.com

I got the issue, where if I select only 1 pCube#, and it returns nothing, though it seems to be working if I only select 1 Root Node
While that is one of the issue, can someone kindly guide me if I am writing my code correctly?

I could see why this might happen. The first thing you do is grab the current selection ("sel"). So if you have a 'pCube#' selection, then that is the item in the list. Then you call cmds.ls(sel, type='stkLevel') on that list. Are you expecting that to somehow resolve the root node for you? Because after you check if its the only item in the list, you hit the "else" branch and return stkLevel_node[0]. What does that actually return? What is in that list?
 
I asked this because first I am still not that great of a scripter and I feel that I am forcing my way through while following those conditions

Well I do see that you are not returning from your function after you print warnings. Like, if there is nothing selection, you still run the rest of your function.
 

Rémi Deletrain

unread,
Sep 21, 2016, 4:57:36 AM9/21/16
to Python Programming for Autodesk Maya
it's possible to use pymel for get root.
pm.selected()[0].root().

I use to function for get parent by type.

The first it's for get all parent of my node.
The second it's for check type of parent and break when i found my type. It's possible to transform this function for works with particular attribute or other system.
It's easy to add check selection (if is root, selection number, etc, etc).

def get_all_parents(s_node):

"""
!@Brief Get all parents of given node.

@type s_node: string
@param s_node: Node name for start surch.

@rtype: list(string)
@return: List of all parents
"""

if not isinstance(s_node, basestring):
s_node = s_node.name()

l_s_parent_nodes = list()
current_node = s_node
while cmds.listRelatives(current_node, parent=True, fullPath=True):
parent_node = cmds.listRelatives(current_node, parent=True, fullPath=True)[0]
l_s_parent_nodes.append(parent_node)
current_node = parent_node

return l_s_parent_nodes


def get_parent_by_type(s_node, node_type=None):

"""
!@brief Find first parent from given node type

@type s_node: string
@param s_node: Node name for start surch.
@type node_type: string
@param node_type: Type you want to surch

@rtype: string
@return: Parent node found. None if don't found node.
"""

if not isinstance(s_node, basestring):
s_node = s_node.name()

l_s_parent_nodes = get_all_parents(s_node)
for s_parent_node in l_s_parent_nodes:

if cmds.nodeType(s_parent_node) == "transform" and node_type != "transform":
l_s_shape_nodes = cmds.listRelatives(s_parent_node, shapes=True, fullPath=True, type=node_type)
if l_s_shape_nodes:
return s_parent_node
else:
return s_parent_node

return None

yann19

unread,
Sep 21, 2016, 1:17:36 PM9/21/16
to Python Programming for Autodesk Maya
@Justin
I was calling cmds.ls(sel, type='stkLevel') as a check to see if it is a stkLevel nodetype. If it is true and depending on how many items are being selected, it will check and iterate accordingly.
I believe my algorithm is not written properly here..  I am expecting stkLevel_node[0] to be returned as the fullpath of the Root node if the selection is 1 and if it is of stkLevel nodetype.

@Remi
I am planning to use cmds instead of pymel, rather than introducing a new module. WIthin my code, I have been using cmds, and hence I thought of standardizing it but I shall give a go to see if I can convert into cmds terms if possible

yann19

unread,
Sep 21, 2016, 1:42:58 PM9/21/16
to Python Programming for Autodesk Maya
So I did a new code (after some more thinking...) Do feel free to criticize and give pointers..
I tested a few scenarios and it seems to work, at least I think it did..

However now I am bumping into another problem.
Say, I have 2 same hierarchy of Root as seen in the attachment but the root nodes of these 2 are called 'Root1' and 'Root2' respectively.

If I select |Root1|locator1|pCube1 and |Root2|locator2|pCube2, it will returns me "|Root1" as the result. But if I inverse my selection, "|Root2" will be my output result.
What is the best way to get around it? Is putting in more checking or if-else statements a viable solution?

Sorry for the spam of questions and codes..

def get_selection():
   sel
= cmds.ls(selection=True, long=True)
   stkLevel_node
= cmds.ls(sel, type="stkLevel")
   
if stkLevel_node:
       
if len(stkLevel_node) > 1:
           cmds
.warning("Please select 1 stkLevel node only")
       
else:
           
return stkLevel_node
   
else:
        root_node
= []
       
for sel_path in sel:
            split_sel_path
= sel_path.split('|')[1]
           
if split_sel_path not in root_node:
                root_stack
.append(split_sel_path)
       
return cmds.ls(root_node, long=True)[0]

Justin Israel

unread,
Sep 21, 2016, 3:55:39 PM9/21/16
to Python Programming for Autodesk Maya

return cmds.ls(root_node, long=True)[0]

You return the first item of the list that you build up. If you want all of them, why don't you just return all of them?


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/15fb02f2-7cbf-4b2c-a3ef-58ccb8ebc86f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marcus Ottosson

unread,
Sep 21, 2016, 3:58:21 PM9/21/16
to python_in...@googlegroups.com

Maybe an an iterative loop could work?

def find_special(start):
    parent = start
    while parent:
        if cmds.nodeType(parent[0]) == "stkLevel":
            return parent[0]

        parent = cmds.listRelatives(parent, parent=True)

    return None # not found

Example

cmds.file(new=True, force=True)

# Generate hierarchy
cmds.spaceLocator(name="selectMe")
for group in range(5):
    cmds.group()

cmds.group(name="special")    
cmds.group()

# Select node
cmds.select("selectMe")

# Find "special"
def find_special(start):
    parent = start
    while parent:
        if parent[0] == "special":
            return parent[0]

        parent = cmds.listRelatives(parent, parent=True)

    return None # not found

start = cmds.ls(selection=True)
special = find_special(start)
print(special)

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.



--
Marcus Ottosson
konstr...@gmail.com

yann19

unread,
Sep 23, 2016, 12:51:49 AM9/23/16
to Python Programming for Autodesk Maya
Hi guys,

Thanks for all the help rendered. 
Reply all
Reply to author
Forward
0 new messages