Inexplicable variable problems

hello all,

I hope my question isn't too naive, I'm having terrible trouble with a mel script.

These procedures are all contained in a file named buildGeoSphere.mel:

== buildGeoSphere.mel ========================================================================
// Build a geodesic sphere by iteratively subdividing an icosahedron
global proc buildGeoSphere (float $radius, int $iterations) {...}

// Provide a graphical interface to buildGeoSphere
global proc buildGeoSphereUI (){

if( `window -exists buildGeoUI` != 1 ){

string $myWin = `window -title "GeoSphere Options"
			-rtf true
			-sizeable false
			-maximizeButton false buildGeoUI`
			;

columnLayout;
$radiusGrp = `floatSliderGrp -value 1 -field true -min 0 -max 10 -fieldMinValue 0 -fieldMaxValue 1000000000 -label "Radius"`;
$iterationsGrp = `intSliderGrp -value 0 -field true -min 0 -max 10 -fieldMinValue 0 -fieldMaxValue 1000000000 -label "Iterations"`;

print ("radiusGrp = " + $radiusGrp);
print ("iterationsGrp = " + $iterationsGrp); 

rowLayout -nc 3 -columnAttach3 "both" "both" "both" -columnAlign3 "center" "center" "center";
  • button -width 130 -label "Create" -command "buttonAction(1, $radiusGrp, $iterationsGrp)";
  • button -width 130 -label "Apply" -command "buttonAction(2, $radiusGrp, $iterationsGrp)";

    button -width 130 -label "Close" -command "closeUI();";

    showWindow $myWin;
    }

}

// Close the graphical interface
proc closeUI (){...}

// Perform button actions
proc buttonAction (int $whichButton, string $r_field, string $i_field){...1}

== end of buildGeoSphere.mel =================================================================

Now when I source and run my script in Maya: (source buildGeoSphere; buildGeoSphereUI;), I encounter the following terrible and inexplicable errors:

a) nothing works unless all the procs are global
on the lines marked by * Maya complains that $radiusGrp and $iterationsGrp are undefined, even though there are clearly defined just three lines above.

Incidentally the print statements work, and output the following:
radiusGrp = buildGeoUI|columnLayout2|floatSliderGrp1
iterationsGrp = buildGeoUI|columnLayout2|intSliderGrp1

and the whole layout is visible, sliders, buttons and all.

I would appreciate help on both accounts, how can I avoid making all the procs global and why are my variables coming up undefined when they're clearly defined?

Warmest Regards,

Alex Kessaris

  1. the procs that are called from interface items are called outside of the script, and as such, they cant see the contents of a script to be able to call local procs, they must be globally registered so they can be called from anywhere. make sense?

  2. following the same reasoning above, the commands attached to those UI items will not know anything about the script that generated them, and hence northing of the globally undefined variables you've placed there in the raw. in order to call those procedures/commands with the contents of those variables at the time of item creation, you just need to concatenate them into the command string, baking their values into it ...

button -width 130 -label "Apply" -command ("buttonAction(2, " + $radiusGrp + ", " + $iterationsGrp + ") ");

you may need to present the string arguments to these procedures encapsulated within quotes ..so add escaped quotations, ", within the string your building.

see how ya go.

Campbell,

Thank you for your thoughtful reply.

I tried catenating the values of my variables into a 'baked' string prior to passing them into the button statement, but that resulted in an error which I have previously encountered:

Error: Invalid use of Maya object "buildGeoUI|columnLayout4|floatSliderGrp1".

However, it's ok, because I remedied the problem by making those two variables global.

I just don't like having every single proc be global, it seems that once they're sourced they reside in memory permanently, if I'm not mistaken. Is there any context whereby one can use local procs?

Bottom line:

I got it to work, but everything had to be global. I would much rather everything be local, can you ever use just regular procs? it doesn't seem like you can.

thanks again for your reply, I could send you a copy of the script if you want, it's rather neat.

-Alex

local procs are as previously mentioned only available to a GLOBAL proc that resides in tha same file as the local one. So basicaly youd normaly only make the input proc global while all otthers are local and all initialisaiton is done trough the one global porc.

yes, that's exactly what I thought, however it seems that my local procs are unavailable to my global proc (which I'm calling from a shelf button, if that makes any difference)

so for instance I have a global proc makeUI(){...}

and a local proc closeUI(){}

and within makeUI one of the buttons calls closeUI well it won't work. It just says it can't find closeUI even though they're all in the same file.

yes, that's exactly what I thought, however it seems that my local procs are unavailable to my global proc (which I'm calling from a shelf button, if that makes any difference)

so for instance I have a global proc makeUI(){...}

and a local proc closeUI(){}

and within makeUI one of the buttons calls closeUI well it won't work. It just says it can't find closeUI even though they're all in the same file.

is the global proc last in the file?

thing is, with building an interafce your just doing the construction of it, sending it off as a bubble for prodding at a latter point, wehere as other script/code plays out its task in an uninterupted stream of calls that can be made globally, and w/i the local/script envoronment. the script that builds the interface doesnt stay live, it only stays w/i that script environment for the duration of the build. so, for the interface elements to have their attached command callbacks recognised they have to be global (as they no longer have knowledge of the parent script that gave birth to them). your right, this means these procedures have to remain in memory, or at least findalble (but so would a constructor script with its local procs and varialbles if it were to remain live for the duration of its constructed UI element). is there anyway arround this?, keep them local? yep, you could have the procedures that are called by the UI items actually be the procedure in its full body - as the script/action itself. (i.e, instead of -comman "proc()", it is "{ proc contents; }"), so the interface item would call/do it's task right their in its own little local scope/environment.

not sure if that makes it any clearer, and it may just be a pecualrity of maya's interface building architecture that requires getting use to (im not sure how other applications go about building their interfaces, coded or scripted).