Search code examples
pythonmayanurbs

Maya transform node not appearing in list


The Maya python code below gives a nurbs boolean surface by first taking the difference of two nurbs spheres, nurbsSphere1 and nurbsSphere2, to give the nurbs surface nurbsBooleanSurface1. It then takes the difference of this surface and a third sphere, nurbsSphere3. The result, as seen in the outliner, is the three nurbs spheres plus a surfaceVarGroup, nurbsBooleanSurface1, which 'parents' three transform nodes nurbsBooleanSurface1_1, nurbsBooleanSurface1_2 and nurbsBooleanSurface1_3.

import maya.cmds as cmds

cmds.sphere(nsp=10, r=50)

cmds.sphere(nsp=4, r=5)
cmds.setAttr("nurbsSphere2.translateX",-12.583733)
cmds.setAttr("nurbsSphere2.translateY",-2.2691557)
cmds.setAttr("nurbsSphere2.translateZ",48.33736)

cmds.nurbsBoolean("nurbsSphere1", "nurbsSphere2", nsf=1, op=1)

cmds.sphere(nsp=4, r=5)
cmds.setAttr("nurbsSphere3.translateX",-6.7379503)
cmds.setAttr("nurbsSphere3.translateY",3.6949043)
cmds.setAttr("nurbsSphere3.translateZ",49.40595)

cmds.nurbsBoolean("nurbsBooleanSurface1", "nurbsSphere3", nsf=1, op=1)

print(cmds.ls("nurbsBooleanSurface1_*", type="transform"))

Strangley (to me), the list command, cmds.ls("nurbsBooleanSurface1_*", type="transform") only yields [u'nurbsBooleanSurface1_1', u'nurbsBooleanSurface1_2']; nurbsBooleanSurface1_3 is missing.

But when, after having executed the above code, the print command

print(cmds.ls("nurbsBooleanSurface1_*", type="transform"))

is re-executed, the result is [u'nurbsBooleanSurface1_1', u'nurbsBooleanSurface1_2', u'nurbsBooleanSurface1_3'].

I've tried delaying the execution of the final print command using time.sleep(n) to no avail. I've played with the idea that the missing node might have spun off into another namespace and then re-appeared at the completion of the execution block (desperate, I know!). I've experimented with renaming the spheres and surfaces, using functions and threads (the latter only superficially). The cause of the unlisted nurbsBooleanSurface1_3 on the first execution of

print(cmds.ls("nurbsBooleanSurface1_*", type="transform"))

remains a mystery. Any help would be much appreciated.


Solution

  • A dirty way (but only way I could find) is to call cmds.refresh() during the script.

    I have rewritten your script here. Notice that I store each sphere in a variable, this is good practice to make sure it'll work, even if an existing object is already called nurbsSphere3 for example.

    import maya.cmds as cmds
    
    sphere1 = cmds.sphere(nsp=10, r=50)
    
    sphere2 = cmds.sphere(nsp=4, r=5)
    cmds.setAttr(sphere2[0] + ".translateX",-12.583733)
    cmds.setAttr(sphere2[0] + ".translateY",-2.2691557)
    cmds.setAttr(sphere2[0] + ".translateZ",48.33736)
    
    nurbsBool1 = cmds.nurbsBoolean("nurbsSphere1", "nurbsSphere2", nsf=1, op=1)
    
    sphere3 = cmds.sphere(nsp=4, r=5)
    cmds.setAttr(sphere3[0] + ".translateX",-6.7379503)
    cmds.setAttr(sphere3[0] + ".translateY",3.6949043)
    cmds.setAttr(sphere3[0] + ".translateZ",49.40595)
    
    nurbsBool2 = cmds.nurbsBoolean(nurbsBool1[0], sphere3[0], nsf=1, op=1)
    
    cmds.refresh(currentView=True)  # Force evaluation, of current view only
    
    print(cmds.listRelatives(nurbsBool2[0], children=True, type="transform"))
    

    When you create an object using cmds.sphere() it returns a list of the object name and more. To access this, you can use

    mySphere = cmds.sphere()
    print(mySphere)  
    # Result: [u'nurbsSphere1', u'makeNurbSphere1']
    
    print(mySphere[0])  # the first element in the list is the object name
    # Result: nurbsSphere1
    

    The same is true for the boolean operation. Look in the documentation for the command under Return value http://help.autodesk.com/cloudhelp/2016/ENU/Maya-Tech-Docs/CommandsPython/index.html