Unexpected behaviour: maya.cmds script



The script should take the position nearest to the first CV of a given curve and snap that CV to that point on the mesh WHILE keeping the length. The script kind of works, but for whatever reason it doesn’t keep the length, though the attribute becomes turned on and works well if the CVs moved manually

import maya.cmds as cmds

sel = cmds.ls(sl=True)

curves = cmds.listRelatives(sel[1:], s=True)
mesh = cmds.listRelatives(sel[0], s=True)

cpom = cmds.createNode("closestPointOnMesh")

#freeze tr and delete history on the mesh
cmds.makeIdentity(cmds.listRelatives(mesh, p=True), apply=True, t=True, r=True, s=True, n=False, pn=True)
cmds.delete(cmds.listRelatives(mesh, p=True), ch=True)

cmds.connectAttr(mesh[0] + ".outMesh", cpom + ".inMesh")

for crv in curves:
    if cmds.objExists(crv +  ".lockLength") == False:
       cmds.addAttr(crv, ln="lockLength", sn="ll", at="bool", k=True)
    cmds.setAttr(crv + ".lockLength", 1)
    cmds.connectAttr(crv + ".controlPoints[0]", cpom + ".inPosition")
    posX = cmds.getAttr(cpom + ".positionX")
    posY = cmds.getAttr(cpom + ".positionY")
    posZ = cmds.getAttr(cpom + ".positionZ")
    cmds.setAttr(crv + ".controlPoints[0].xValue",posX)
    cmds.setAttr(crv + ".controlPoints[0].yValue",posY)
    cmds.setAttr(crv + ".controlPoints[0].zValue",posZ)
    if cmds.connectionInfo( cpom + ".inPosition", isDestination=True):
       cmds.disconnectAttr(crv + ".controlPoints[0]", cpom + ".inPosition")

It looks like a bug, but I’ve checked the script in Maya 2016 and 2017.

I’d appreciate any help.


You seem to be adding the lockLength attribute manually.

When I try and do this, it also fails. But if I use the tool to enable lockLength, then it works. So there seems to be more to the command than simply adding the attribute.

Try this instead:



thank you for the reply.

I replaced

if cmds.objExists(crv +  ".lockLength") == False:
       cmds.addAttr(crv, ln="lockLength", sn="ll", at="bool", k=True)
cmds.setAttr(crv + ".lockLength", 1)

this with

It gives the same result. And the attribute didn’t get added. Doing something wrong?


It seems to be working on my side. What if you keep the line that sets the attribute? For me, it gets set automatically, but if it still set to off for you, you can set it 1 like you were doing:

cmds.setAttr(crv + ".lockLength", 1)


for me the cmds.LockCurveLength(crv) command doesn’t even create the attribute

import maya.mel as mel

this one works , but I can’t figure out how to add the argument “crv”.

also it’s very curious how this command worked for you

i thought run time commands aren’t supposed to work like this.


You are right. In my test, I still had the curve selected. Passing the curve as a parameter does nothing. In your script, you could select the curve in your loop before you run the command. Would that work?

If you need to restore your previous selection, you can store it as a variable, and then select it after the loop runs.



okay. it worked this time. but I am back to square one again.

If I manually grab a cv it’s locked indeed. But with the script it just stretches the curve and snaps the cv.