PixelApocalypse
PixelApocalypse

Reputation: 5

Python: keep objects selected throughout script

I'm quite new to programming. I got an assignment for school. What it has to do is:

By selecting 2 random objects clone the 2nd selected objects around the first selected object along it's rotation plane. This has to be done through a window with 2 options. 1 option to adjust the size of the radius of the cloned objects. The 2nd option is the number of clones you want to have. Pressing a button creates the cloned objects.

import maya.cmds as cmds

def setRadius(circleRadius):
    selected = cmds.ls( sl=True)         
    #selected = cmds.ls ('pCube1') + cmds.ls ('pCube2') #used for testing
    pivotcube = cmds.xform(selected[0], ws=True, q=True, t=True)
    satellite = cmds.xform(selected[1], ws=True, q=True, t=True)

def circularDuplicate(nrOfObjects):
    selected = cmds.ls( sl=True)         
    #selected = cmds.ls ('pCube1') + cmds.ls ('pCube2') #used for testing

Currently I'm actually having several problems. First I hard selected 2 objects in the scene for test convenience. Changing the code to manually selected objects and storing them in a list, introduced a problem. After the first Function has been called the Script gives an error that the list index is out of range. Apparently after the first function (which adjust the position of the 2nd selected object to fix the radius) the objects are deselected. Now i could just put

selected = cmds.ls( sl=True) 

outside of the functions but I want to be able to select 2 different objects and clone objects without having to close the window and to run the script again.

The second problem is the cloned objects all have the same translation values.... So i can't use any of the cloned objects and run the script again because the measuring will return an error. How can I clones in a decent way where all the clones have their own correct translate and rotation values?

Upvotes: 0

Views: 3751

Answers (1)

theodox
theodox

Reputation: 12218

There are three things going wrong for you here.

Selections

As long as you do not delete or rename objects within a single block of script code, you can 'restore' the selection by re-selecting your original list. In your example:

def setRadius(circleRadius):
    selected = cmds.ls( sl=True)         
    pivotcube = cmds.xform(selected[0], ws=True, q=True, t=True)
    satellite = cmds.xform(selected[1], ws=True, q=True, t=True)
    cmds.select(selected)  # reselect the original objects

will restore your selection.

As you get better you'll find there are still lots of ways this can go wrong - renaming, deleting and sometimes even creating objects can invalidate a selection that has been stored just as a list of names. For more complex examples you can create sets (using cmds.set) which will survive name changes.

If you switch to PyMel, the return values from commands like ls will be handles to the actual maya scene nodes (and not just string names, which is what you get from the cmds versions). Pymel objects retain their collection to the original scene nodes so they survive name changes, etc.

Getting/setting values

Your setRadius function doesn't do anything. You are asking for the world space pivot and target locations -- but you're not doing anything with them. Do you want to return them? Or are you trying to set them as the name of the def suggests? If you're getting them, add

return pivotcube, satellite 

to the end of the def. If you're setting them, you need to call xform without the q flag, and supply the values you want, something like

pivotpos = (0,0,0)
cmds.xform(selected[0], t=pivotpos, ws=True)

Doing the duplication

THere's nothing in the supplied code that actually does the radial duplication. You want something like this:

  1. select the target object
  2. move it to (0, 0, radius) of the pivot object. You could do this by getting the transform matrix of the pivot and multipling (0,0,radius) against it. However it's simpler to temporarily parent the duplicate object to the pivot object and set it's local position to (0,0, radius). For this example I'm assuming you want to rotate around the local Y of the pivot object - you could exchange coordinates as needed.
  3. zero out the local rotations of the target object
  4. set the world space pivot of the target to the world space pivot of the pivot
  5. As many times as needed: duplicate the object, rotated it by (0, 360/number-of-copies,0)
  6. (if desired) reset the pivot of the duplicate(s)

If you walk through this in the GUI and pay attention to the command output you should be able to see the way your actual script should go.

Upvotes: 1

Related Questions