Working around the Gradient Control in MEL

We have all seen a Gradient Control somewhere within Maya, whether it be a color ramp or the Soft Select curve within the tool controls. They are very powerful tools, and the ones built into Maya are wonderful and easy to work with. I can tell you from experience, working with them within your own script and GUI can be one of the biggest pains there is. They are buggy, undocumented, and a downright pain to get to work. I have worked with one, and if you look at my final for MEL you can see just what lengths I had to go through to get everything to interact correctly. A quick note, this write-up is for gradientControlNoAttr in the curve mode. So lets look at the control itself:

When you first put it into a script you are only given the curve editor and nothing else. All the extra boxes and fields are things I added within my own script. Just as a note this post will deal ONLY with  the curve and NOT the color ramp. They both work primarily the same but the token hacks I did will only work with the curve editor. So as far as the GUI elements there is the gradient control itself, the two fields and the optionMenu. Normally when we see this kind of control built within maya you see all 3 together. For those of you who want to follow along within my script they can be found here and here. Now the start of the frame that holds all you see in the above snapshot is at line 93 all the way down to line 118 in the GUI script. For the rest of this script I will have assumed you have my script open and looked up the flags for every command I am talking about. Should you have any questions about this post a comment or shoot me an email.

Now, the NoAttr version of the Gradient Control stores all of its data within an optionVar(ie global variable). Well I take that back, it temporarily stores it in a seperate location within the control and whenever the window is closed the data then gets stored to the optionVar of the correct name. You should set up the optionVar location yourself using the -optionVar flag. Since this is a global variable, the longer and more descriptive the name the better. The first issue I have with the overall design of this control is the data stored locally and within the optionVar are first of all in different ways, and in strings! They could have used a float array but they chose strings, why is beyond me. So, lets say I use this command: “gradientControlNoAttr -q -asString extrudeCurve”. I am querying what the control thinks are the current values. In the case of the above image I am returned: “0,1,2,1,0,3,0.412698,0.162621,3,0.484,0.442,1,0.73,0.515,0,0.412698,0.628641,3,0.81,0.386,1,
0.825397,0.230583,3,0.452381,0.313107,3,0.556,0.803,1″ For those of you confused, that is one string, no designation of what values are what, or when a new set begins or ends. In case you are still confused it spits out something akin to “position,value,interpolation,position,value,interpolation,position,value,interpolation” etc until it get all the values. Keep in mind what gets returned is a STRING. So I can’t just grab the data or store it into an array to use. When I use the optionVar equivalent command (optionVar -q sgkCurvesExtrudeTaperOptionVar) I am given: // Result: 0,1,2 1,0,3 0.412698,0.162621,3 0.484,0.442,1 0.73,0.515,0 0.412698,0.628641,3 0.81,0.386,1 0.825397,0.230583,3 0.452381,0.313107,3 0.556,0.803,1 //. Triplets? Well at least the data is semi organized, but again it is as String data. So what do we do with this data? Well we have to tokenize it. Since the data we want is seperated out with “,” we can use that as the substring. Not the most helpful documentation to be sure, but it is basically in the syntax of `tokenize “list” “sub-string token to search for” $storageVar`.

To even get the fields and control to interact requires the hackjob of coding you see starting at line 169. My script is mostly documented on what it is doing at this point, but you can see the difference in method of working with the gradientControl (case 1) and the optionVar (case 0). In case you were wondering, case 2 is what gets executed each time the window gets opened, it ensures that all the values in the gradientControl match what is stored in the optionVar. There are bugs everywhere, so alot of this code is just work arounds to make sure things are updating and when the data gets used(and you get proper interpolation between indexes of data). The gradientControl finally gets used in my script(we are now in the brain script) on line 309. So the optionVar stores the general info of JUST the indexes, as in the user made points with interpolation between them. When that data gets put into the control it draws the curve based on value and the interpolation type. In my script you will notice once you actually hit that extrude button the GUI window closes and opens itself, to make sure when the valueAtPoint gets used it is actually seeing the correct value. There are a lot of cases when the value shown in the control itself isn’t even the value being temporarily stored. Again buggy all around.

Oh dear, this post is rambling even for myself. I want to stress something, especially to my fellow students. There is no instantly correct answer to anything, nothing in the 971 lines of code I did for my final I instantly knew would work the first time. Everything I did, I wrote out, tested, tweaked, tested, and repeated hundreds of times. There is no right answer, there is the answer that works for you and what your conditions call for; there are wrong answers, but never a 100% correct and perfect method. I broke this script and all its many little parts at least 50 times each.

The gradientControlNoAttr is by far one of the worst put together parts of MEL I have ever had the pleasure to work with. It doesn’t interact with itself very well nor even other parts of elements that should be easy to link together. I want to stress my solution is not complete, it still has its share of problems and will continue to because I can say I will probably never use it again. It stores its data badly in multiple places and even has trouble reading it sometimes. Try it out, tell me what you want me to explain better and hope for the best. Honestly there isn’t much I can say to make using this any easier, well besides learning how the tokenize command works and building up strings of data yourself.

Write a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>