Bake object to world space

I want to bake a object possibly in any group to world space so I’m writing a script to do so but I’m not able to use disconnect Attribute in python. Please could you suggest me and guide me.

import maya.cmds as mc

obj = mc.ls(selection=True)

print obj

Loc = mc.spaceLocator()

mc.parentConstraint(obj,Loc)

mc.bakeResults(Loc, simulation=False, time(mc.playbackOptions(minTime=True, query=True),mc.playbackOptions(maxTime=True, query=True)))

mc.delete(constraints=True)

conn = mc.listConnections(obj)

print conn

mc.disconnectAttr(conn)

mc.parent(obj,world=True)

mc.parentConstraint(Loc,obj)

By default listConnections returns a list of connected nodes rather than the actual attribute that is connected. However, disconnectAttr accepts an attribute as a parameter, e.g. "pCube1.translateX". It won’t work if you just give it a node name, which is what you’re currently getting from listConnections.

listConnections has a parameter, though, called “connections” which will give you both attributes involved in each connection. From the docs:

connections(c)	- boolean:
    If true, return both attributes involved in the connection. The one on the specified object is given first. Default false.

Seems a little silly, but that’s how it works. Probably a legacy code support thing. I remember it tripping me up when I was learning too. EDIT: If you want listConnections to return pairs of (this object’s attr, other object’s attr), instead of (this object’s attr, other object), you have to be sure to set the plugs flag to true.

So instead of

conn = mc.listConnections(obj)
mc.disconnectAttr(conn)

You’d have to do

EDIT:

This is not correct. I was thinking of the way pymel.core.disconnectAttr works. The pymel version can work on one attribute and will disconnect from both sides of it, but maya.cmds.disconnectAttr needs two attributes as parameters for the source and destination side of the connection. See my other post below for how to do this correctly.

connections = mc.listConnections(obj, connections=True)
mc.disconnectAttr(connections)
........................................................

One important thing to be aware of… the “pairs” that listConnections(connections=True) returns are not sublists, but rather it puts everything in one large list (which is annoying). If you want to only disconnect attrs from the specified object you’ll have to iterate over the list two at a time and only disconnect the first of each pair or you can accidentally break other things. The pairs are also not always sorted in the order that mc.disconnectAttr needs them to be, which isn’t super helpful.

All of this is said to help you understand how it works, but to be honest with you I never use listConnections with the “connections” flag unless I need to do something very specific. Instead if I want to disconnect all attributes I just get all the keyable attributes with mc.listAttr(obj, keyable=True) and disconnect each of them in a for loop. I would recommend doing it that way instead if it works for your use case.

Thanks you for the explanation really helped clear my doubts related to listConnections, I just want to delete the translate and rotate attributes. so there anything specific to just these attributes so that other connections dont break?

EDIT: This is actually not the correct way to do it. See my other post below

In mel, an attribute is just “[node_name].[attribute_name]”, so for example, “pCube1.translateX”. So you can just type it in directly. Assuming that you want to unhook the translate connections on the node referenced by obj, all you have to do is this:

mc.disconnectAttr(obj + '.translate')

You can disconnect the X, Y, and Z separately, but since translate and rotate are compound attributes it’ll unhook all 3 if you just use ‘translate’

That’s not how it works.
translate is a compound attribute that just happens to be the parent of translateX, translateY, and translateZ. They are all handled separately, however.
You could have X/Y/Z connected without having translate connected, and then trying to disconnect translate leads to a RuntimeError

1 Like

Ah yeah, you’re right. That wasn’t correct. maya.cmds.disconnectAttr needs to have 2 parameters as well. PyMel has spoiled me a little bit

Ok, let’s try this again.

You can get a list of all the attributes connected to the input side of ‘translateX’ and disconnect them 1 at a time like this:

inputAttrs = cmds.listConnections(obj + '.translateX', source=True, destination=False, plugs=True)
for attr in inputAttrs:
    cmds.disconnectAttr(attr, obj + '.translateX')

Make sure to use plugs=True or it’ll give you back objects instead of attributes. Also if you don’t set destination=False, it defaults to true.

cmds.disconnectAttr expects the source-side attribute and the destination-side attribute of the connection to be passed in, in that order. cmds.listConnections(obj + '.translateX', connections=True, plugs=True) will give you pairs of attributes for every connection, but it puts the obj node’s attributes first so they won’t be in source / destination order, so it’d probably be simpler to handle input connections and output connections in separate loops, if you want to disconnect both. I’d make a function for that.

def disconnectAll(attribute):
    inputAttrs = cmds.listConnections(attribute, source=True, destination=False, plugs=True)
    outputAttrs = cmds.listConnections(attribute, source=False, destination=True, plugs=True)

    for inAttr in inputAttrs:
        cmds.disconnectAttr(inAttr, attribute)

    for outAttr in outputAttrs:
        cmds.disconnectAttr(attribute, outAttr)

disconnectAll(obj + '.translateX')
disconnectAll(obj + '.translateY')
disconnectAll(obj + '.translateZ')

That’ll unhook all connections from the translate attributes on obj
Sorry for posting incorrect info before. I usually triple-check my posts but I was in a rush today.


as suggested i tried to run these commands but only translate X is being disconnected and then it is giving a error saying NoneType’ object is not iterable. something wrong with my creating the obj.?

Ah yes, one of my “favorite” things about maya.cmdscmds.listConnections doesn’t return an empty list if there are no connections, it returns None. Iterating over an empty list will cause nothing to happen, but iterating over None causes that error you’re seeing. That’s one of the big problems with maya.cmds. It’s not very pythonic.

Either inputAttrs or outputAttrs is getting set to None. That’s what’s causing the problem. Adding

if inputAttrs is None:
    inputAttrs = list()
if outputAttrs is None:
    outputAttrs = list()

inside of that function should do the trick, or alternatively, I like doing it this way

inputAttrs = cmds.listConnections(attribute, ...) or []

adding the or [] onto the end says “if the result is falsy, use an empty list instead”. Empty lists and None are both falsy, but empty lists don’t cause errors if you try to iterate over them.

Sorry I missed that detail earlier. I’m used to PyMel where empty lists are returned instead of None and I forgot.

thank you so much it worked for the if statements. and the thank you for the explanation too this helped me understand the topic too.

1 Like