zingy
zingy

Reputation: 811

generating a mel script

Following the question I had asked yesterday which is here passing contents from multiple lists generated in different functions to a file I have written the code. Part of the code is below,

def lower_lip_under_upper_teeth_bezier(x_n, p0, p3) :
    """ Calculating sampling points using rational bezier curve equation"""
    lower_lip_under_upper_teeth_p_u_list = []
    u = x_n
    p1 = p0
    p2 = p3

    lower_lip_under_upper_teeth_p_u = math.pow(1 - u, 3) * p0 + 3 * u * math.pow(1 - u, 2) * p1 \
                                 + 3 * (1 - u) * math.pow(u, 2) * p2 + math.pow(u, 3) * p3
    lower_lip_under_upper_teeth_p_u = lower_lip_under_upper_teeth_p_u * w
    d = math.pow(1 - u, 3) * w + 3 * u * w * math.pow(1 - u, 2) + 3 * (1 - u) * w * math.pow(u, 2) + math.pow(u, 3) * w
    lower_lip_under_upper_teeth_p_u = lower_lip_under_upper_teeth_p_u / d

    print "p(u): ", lower_lip_under_upper_teeth_p_u
    lower_lip_under_upper_teeth_p_u_list.append(lower_lip_under_upper_teeth_p_u)

    return lower_lip_under_upper_teeth_p_u_list

def mel_script() :
  """ Generating the mel script with the animation information """
    print "\n The mel script generated for the input speech with the chosen energy level" 
    with open("mel.txt", "w") as melFile :
        melFile.write('setKeyframe "BS_stickyLips_SL_recept.head_geo_stickyLips_wire";'
                      'setKeyframe "BS_stickyLips_baseSL_recept.head_geo";'
                      'setKeyframe "BS_stickyLips_wireSL_recept.head_geo";'
                      'setKeyframe "blend_shape.lip_round";'
                      'setKeyframe "blend_shape.jaw_open";'
                      'setKeyframe "blend_shape.lips_spread";'
                      'setKeyframe "blend_shape.lips_part";'
                      'setKeyframe "blend_shape.lower_lip_under_upper_teeth";')

    for p in lower_lip_under_upper_teeth_bezier :
        melFile.write('setAttr "blend_shape.jaw_open" %f ;' % p )
        melFile.write('setKeyframe -breakdown 0 -hierarchy none -controlPoints 0 -shape 0 {"blend_shape"};')

But I am getting an error which is,

    for p in lower_lip_under_upper_teeth_bezier :
TypeError: 'function' object is not iterable

Upvotes: 1

Views: 221

Answers (2)

mac
mac

Reputation: 43061

lower_lip_under_upper_teeth_bezier is a function. The error message clearly tells it, there is no way around it.

You might believe that lower_lip_under_upper_teeth_bezier is an iterable, but it is not.

Now, mine is just a guess, but I believe what you want to do is something like:

def mel_script(lip_var):
    '''The mel script generated for the input speech with the chosen energy level'''
    with open("mel.txt", "w") as melFile :
        melFile.write('setKeyframe "BS_stickyLips_SL_recept.head_geo_stickyLips_wire";'
                      'setKeyframe "BS_stickyLips_baseSL_recept.head_geo";'
                      'setKeyframe "BS_stickyLips_wireSL_recept.head_geo";'
                      'setKeyframe "blend_shape.lip_round";'
                      'setKeyframe "blend_shape.jaw_open";'
                      'setKeyframe "blend_shape.lips_spread";'
                      'setKeyframe "blend_shape.lips_part";'
                      'setKeyframe "blend_shape.lower_lip_under_upper_teeth";')
    for p in lip_var:    # Check this out!!!
        melFile.write('setAttr "blend_shape.jaw_open" %f ;' % p )

EDIT (see comments): I think there is some basic misunderstanding on how python works going on here... In python (as in most programming languages!) when you declare a function, you declare its name and what arguments it expects.

If you are trying to pass 5 lists to mel_script, when you declare mel_script you should say so:

def mel_script(list1, list2, list3, list4, list5):
    # Your code here should work with list1, list2, etc...

Then, when calling mel_script, you need to pass these lists to it. If such lists are generated by functions (say f1, f2, f3...). You could do it all in one line with:

mel_script(f1(), f2(), f3(), f4(), f5())

otherwise you have to store the lists in temporary variables and pass those to mel_scirpt:

tmp1 = f1()
tmp2 = f2()
tmp3 = f3()
tmp4 = f4()
tmp5 = f5()
mel_script(tmp1, tmp2, tmp3, tmp4, tmp5)

In the above examples note that f1() has round parenthesis denoting the fact you are calling the function named f1. If you would omit those, then you would be passing the function itself, not its result.

In reality there are cleverer ways to achieve this (like passing a variable number of arguments, or using closures, but from your question I understand that you are not (yet!) proficient with python, so it would be better to stick with this method for now! :)

HTH!

Upvotes: 1

Sven Marnach
Sven Marnach

Reputation: 602475

You are not calling the function. To call it, use

lower_lip_under_upper_teeth_bezier(x_n, p0, p3)

and substitute appropriate values for the parameters.

Upvotes: 3

Related Questions