Friday, November 16, 2012

[Python] Getting an intField to only accept odd numbers

I know it's odd (pun!), but I needed to have an intField only accept odd numbers.  Initially, I'd done something like this:

import maya.cmds as mc def exampleUI(): exampleWin = mc.window() mc.columnLayout() testField = mc.intField(value = 63) number = mc.intField(testField, query = True, value = True) mc.button(label = "OK", command = lambda *args: exampleDef(number) ) mc.showWindow( exampleWin ) def exampleDef(number): if number % 2 != 0: print "It's odd! Yay!" else: print "Your number is even, prepare to die!"

If the value in the intField was odd, continue. If the value was even, error out and prompt the user to change it.  But it didn't do what I wanted, which was to force an odd number.  I didn't know if this was possible, but it sounded like it should have been.  I asked for help on the CGTalk Maya Programming forum and I learned two things.
Click here to see the thread

1) Use the intfield's changeCommand flag.  After the value in the field changed, it would run another block of code that would check whether or not the number was odd.  In the event it found an even number, it would either reset the value or increase the number by 1.

2) Another person agreed with the solution above and took it a step further.  He suggested this, and I think it's brilliant:

def setMyOddInt(integer): oddInt = integer/2*2+1 mc.intField('oddIntField', e=1, v=oddInt) def exampleUI(): exampleWin = mc.window() mc.columnLayout() testField = mc.intField('oddIntField', value=0, changeCommand=setMyOddInt) mc.showWindow( exampleWin )

I really like this bit here "oddInt = integer 2*2+1".  I wondered, why not just check to see if the number was even, and then say + 1 and return the new value?  You can do this and it will work but it would take three lines of code.  Here, it was done with one.

When you divide an int, most (if not all) languages will just round down to the next whole number.  Example, 3/2 will equal 1, not 1.5 (that would be a float, not an integer).

If we continue to use the number 3 as our example, 3/2 = 1.  Then 1*2 = 2 and finally, 2 + 1 = 3.  So you'd end up with your original odd number, 3.  But say we had an even number: 4.  4/2 = 2,  2*2 = 4 then 4 + 1 = 5.  See?  "integer/2*2+1", will always produce an odd number and this number will be placed into the intField automatically because of the changeCommand flag.

In the end, either way works.   As a side note, if you wanted to round down, you could just say -1 instead of +1.

Fun stuff.

I needed this for my hair script, which I'm converting to Python.  Hopefully I'll have more updates on that soon.


Tuesday, November 13, 2012

CGSociety Article - Rock in the Road

Rock in the Road

There's a really great CGSociety feature of Rock in the Road that talks about the road to starting and completing the project.  There's also a forum discussion if you're interested.  If you haven't already seen Rock in the Road, take a few moments and watch it.