Friday, February 28, 2014

Maya Tools - Locator size by scale - Write a function

So, we saw there was a simple 4 lines script to adjust locator size by scale.
How to make a so called tool?
I have no idea whether there is a scientific approach of that. I know about writing a specification. As a matter of fact I found a good article about that: Painless Functional Specification
I simply skipped the first chapter because I knew that is important so I didn't need a tale about that :)

But before I even knew about specification I usually thought as a user because I stared my "career" as an artist not a TD.
In this case this tool  should be only one click solution: Set Locator Scale By Size. To make it clear it is not for locator type object but cameras and lights. There shouldn't have been any other things just one button to click so we can move on to technical specification.

First of all we should write a function:

 def LocatorSizeByScale(Selection):  
     for item in Selection:  
         scaleVal = cmds.getAttr(item + ".s")[0][0]   
         cmds.setAttr(item + ".s", 1, 1, 1)   
         cmds.setAttr(cmds.listRelatives(item, shapes = 1)[0] + ".locatorScale", scaleVal)  

The argument should be a Selection. In maya ls command results a list no matter whether it is one or more object so the Selection has to be a list (array). With for cycle it works more than just one object. So we can run the function like this:

 LocatorSizeByScale(cmds.ls(sl = 1))

But as I wrote before there could be a lot of error situation. I'm a visual thinker. I don't make every time flowcharts but for the sake of this demonstration I'm going through the whole process of visual design. I'm a self-taught programmer and this is my practice not a scientific approach.

First I made a sketch of a flowchart.



It took around 5 minutes and another 5 minutes to verify and add notes. After that I could start coding. I had a clear picture how it would work. Okay but I don't expect reading that from anybody. I made a better picture for this article.





This flowchart shows everything what we need. If we can draw a flowchart like this we have a clear picture how the function is going to work. So the coding is just an execution of the plan.

The result code:

 def LocatorSizeByScale(Selection):  
     '''  
     DESCRIPTION  
     Scaling camera for eg. can cause problems (Z-Depth pass can be wrong for eg.). So scale value should be transfered to the locatorScale attribute.  
     If the object (the selected node's first shape node) has locatorScale attr it will be adjusted by the transform node scale.  
     INPUT ARGUMENTS  
     list - Selection - Selected nodes  
     RETURN  
     None  
     DEPENDENCIES  
     maya.cmds  
     maya.mel  
     '''  
     if Selection:  
         for item in Selection:  
             if cmds.nodeType(item) == "transform":  
                 # Only checks scaleX attribute. That means non-uniform scale not handled.  
                 scaleXVal = cmds.getAttr(item + ".scale")[0][0]  
                 if scaleXVal != 1:  
                     # Only the first shape node considered  
                     shapeNode = cmds.listRelatives(item, shapes = 1)[0]  
                     if shapeNode:  
                         if mel.eval("attributeExists \"locatorScale\" " + shapeNode):  
                             locatorScaleVal = cmds.getAttr(shapeNode + ".locatorScale")  
                             cmds.setAttr(item + ".scale", 1, 1, 1)   
                             cmds.setAttr(shapeNode + ".locatorScale", locatorScaleVal * scaleXVal)  
                         else:  
                             raise StandardError("There is no locatorScale attribute to adjust.")  
                     else:  
                         raise StandardError("There is no shape node.")  
                 else:  
                     print "Default scale value. Skipped."  
             else:  
                 raise StandardError("Only works for transform selection.")  
     else:  
         raise StandardError("There is no selection.")  
 
Further development
Better error handling in connection with selection and selection types
Non-uniform scaled object
Option to warn non-uniform scaled object
Option to warn already set locatorScale value

We will continue...

No comments:

Post a Comment