I am new to Python and creating a program within Maya, that creates a solar system. This is part of my code that is causing the problems (hopefully enough to understand). The first function defines the radius of the planet, and then creates a sphere accordingly. The second function needs to use the variable planetRadiusStr to determine the radius of the Torus(ring). However, planetRadiusStr is only defined in the first function, so I know I need to somehow pass the variable between functions. However, I cannot seem to get this to work. Can anyone help?
planetRadiusStr = raw_input("Please enter the radius of the planet:")
print "Planet Radius must be less than Sun Radius"
ringsStr = raw_input("Would you like this planet to have a ring?").lower()
if str(ringsStr) == "yes":
cmds.polyTorus(r=float(planetRadiusStr)*2, sr=0.5, n='ring1')
elif str(ringsStr) == "no":
print "Please enter 'yes' or 'no'."
(I can upload a photo of my code if that will be easier to read.)
A couple of things to consider here.
First, I'd get this working using only standard functions and not using
raw_input(). Until you have other users you can just type the values you want into the listener; when you do have users you can create a proper GUI that just passes arguments into the functions.
So, I'd suggest you try it by just making functions that take the info you need:
def create_planet(name, radius): planet, shape = cmds.polySphere(n = name, r = radius) return planet def create_sun (radius): cmds.polySphere(name = "sun", r = radius)
In this case, you don't need to track the planet radius: you can derive it from the history of the planet itself if you know which planet to look at
def create_ring (planet): planet_history = cmds.listHistory(planet) or  pSphere = cmds.ls(*planet_history , type = 'polySphere') planet_radius = cmds.getAttr(pSphere + ".radius") ring, ring_shape = cmds.polyTorus(r = planet_radius * 2, sr = .5, n = planet + "_ring") cmds.scale(1,0.2,1) cmds.parent(ring, planet, r=True)
With all that in place, you can manage the passing of arguments from one function to another manually in the listener:
p = create_planet("saturn", 1) create_ring(p)
or, you can create another function that does multiple passes:
def add_planet (sun, planet, distance): cmds.parent(planet, sun, r=True) cmds.xform(planet, t= (distance, 0 ,0), r=True) def solar_system (): sun = create_sun (10) mercury = create_planet( 'mercury', .5) add_planet(sun, mercury, 20) venus = create_planet( 'venus', .7) add_planet(sun, venus, 40) earth = create_planet( 'earth', .8) add_planet(sun, earth, 50) mars = create_planet( 'mars', .75) add_planet(sun, mars, 60) jupiter = create_planet( 'jupiter', 2) add_planet(sun, jupiter, 70) saturn = create_planet( 'satun', 1.2) add_planet(sun, saturn, 80) create_ring(saturn)
As you can see, as long as you're inside the function
solar_system you can keep variables alive and pass them around -- you'll also notice that
create_planet() returns the name of the planet created (maya may rename it behind you back, so it's a good idea to check this way) so you can pass that name along to other functions like 'create_ring' or 'add_planet' which need to know about other objrects.
def planetRadius(): planetRadiusStr = 42 #blas planetRings(planetRadiusStr) def planetRings(planetRadiusStr): #blas
def planetRadius(): size = 4 return size def planetRings(inputSize): "function placed here" print('my planet size was ' + str(inputSize)) var01 = planetRadius() planetRings(var01) #result : 'my planet size was 4'
If you are planning to create a UI, keep in mind that you should set your def as this :
Indeed, maya UI output a default boolean variable and will create an error if you don't put *args.
Furthermore, if you try to pass a variable through a UI as yours:
def planetRings(inputSize, *args): "function placed here" print('my planet size was ' + str(inputSize))
You will have to look for the module functools.partial to specify the input size :
from functools import partial import maya.cmds as cmds cmds.button(l='exec', c=partial(planetRings, inputSize))