简体   繁体   中英

Hide unselected in Maya/Python

I'm trying for a while to get this sorted out in Maya: I want a script which can hide my unselected lights for example, so the only way which comes to mind (and doesn't work) is this one:

lt=cmds.ls(lt=True,sl=False)
cmds.hide(lt)

I see that the argument False with selection doesn't work, so I want to find out about some other ways...thanks

@goncalops answer will work if you select the light shapes , but not their transforms.

Try:

lights = cmds.ls(type = 'light') or []
lights = set(cmds.listRelatives(*lights, p=True) or [])
for item in lights.difference(set(cmds.ls(sl=True))):
    cmds.hide(item)

Reading the documentation for the ls command in Maya 2011 , it doesn't seem to have either lt or sl parameters, although it has lights and selection .

Further, it seems the selection argument only serves the purpose of returning the selected arguments, not of filtering unselected ones. OTOH, the hide method accepts a single argument.

Try this:

lights= set(cmds.ls(lights=True)) - set(cmds.ls(selection=True))
for light in lights:
    cmds.hide(light)

this will work for your condition

hide_light = set(cmds.ls(lights=True, l=True)) -  set(cmds.ls(sl=True, dag=True, l=True, leaf=True))
for each_lit in hide_light:
    cmds.setAttr("%s.visibility" % each_lit, 0)

I think most of the answers go into over engineering land. The question is how to hide non selected lights at the end of your operation , Nothing says you can not hide them all and bring the lights selected back. So conceptually easier is to do (and slightly faster but that's beside the point):

cmds.hide(cmds.ls(lights=True, dag=True))
cmds.showHidden()

One comment: There's no need to fetch shapes separately in this case, as it has a the dag flag for this. See conceptually Maya items are packets of transform and the shape separately. However its so common occurrence that you want to convert between the shape and dag to shape that ls offers a way to do this with the dag and shapes flags.

Second comment: If you do not pass a list to Maya it will operate on selection thats why showHidden works without any data.

PS: conceptually neither my answer nor @ theodox answer will work in all cases as you MAY indeed have selected the shape. However most users will not so it will commonly work this way.

Let's discuss the problem a bit:

There are a few things to consider. When users select a light, (from the Viewport or the Outliner), most of the time they would really be selecting the transform node of a light.

When we perform a cmds.ls(type='lights') , we are actually selecting their shape nodes . This is in line with what @theodox is saying.

I don't know about you, but when I hide lights manually, I select lights in Outliner/Viewport. When I hide them (ctrl-h), they grey out in the outliner. What I've done is hidden their transform nodes (not their shape nodes).

To make things more complicated, Maya actually lets us hide shape nodes too. But the transform node will not grey out when the shape node is hidden.

Imagine if my script were to hide the light shape node, in the Outliner there would be no indication that those lights are hidden, if the Outliner is not set to display shape nodes (this is the default setting in the Outliner). Without the greying-out to indicate that the lights are hidden, many artists especially less experienced ones would assume that lights are turned on when they have already been disabled and hidden. This is going to cost a lot of confusion, time wasted, frustration, basically not what we want.

Thus when I write a script like this I'll expect the user to be selecting transform nodes. Also when I hide lights, I will hide the transform nodes of the lights instead of hiding the light shapes directly. That would be my game plan.

import maya.cmds as mc
def hideDeselected(targetNodeType):
    # selectedNodeTransforms will contain transform nodes 
    # of all target node type shapes that are selected
    selectedNodeTransforms = []
    for selNode in mc.ls(sl=True):
        if targetNodeType in mc.nodeType(selNode):
            # selected node is the correct type
            # add the transform node to selectedNodeTransforms
            selectedNodeTransforms.append(mc.listRelatives(selNode, parent=True))
        elif mc.listRelatives(selNode, children=True, type=targetNodeType):
            # selected node is a transform node 
            # with a child node of the correct type
            # add the transform node to selectedNodeTransforms
            selectedNodeTransforms.append(selNode)

    if selectedNodeTransforms:
        # only if something is selected, do the hiding thing.
        # If we do not do this check, and if nothing is selected
        # all transform nodes of targetNodeType will be hidden
        print 'selected objects:',selectedNodeTransforms
        for thisNode in mc.ls(type=targetNodeType): 
            # loops through all target shapes in the scene
            # get the transform node
            thisNodeTransform = mc.listRelatives(thisNode, parent=True)[0]
            if not thisNodeTransform in selectedNodeTransforms:
                print 'hiding', thisNodeTransform
                hide(thisNodeTransform)
    else:
        print 'nothing is selected'
hideDeselected('light')

In the code above, I've made a function out of it so we can pass in any dag node type that is able to have a parent in the scene, and the code will work.

Thus, to hide all the other cameras in the scene that are not currently selected, we just have to call the function with the camera node type:

hideDeselected('camera')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM