简体   繁体   中英

How to pass variables between functions using python in maya?

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?

def planetRadius():

    planetRadiusStr = raw_input("Please enter the radius of the planet:")
    if float(planetRadiusStr)<float(sunRadiusStr):
        cmds.polySphere(radius=float(planetRadiusStr), n='planet1')
    else:
        print "Planet Radius must be less than Sun Radius"
        planetRadius()



def planetRings():

    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')
        cmds.scale(1,0.2,1)

    elif str(ringsStr) == "no":
        pass

    else:
       print "Please enter 'yes' or 'no'."
       planetRings()

(I can upload a photo of my code if that will be easier to read.) Thanks!

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')[0]
    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 :

def planetRadius(*args):

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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM