PDA

View Full Version : problem with recalling values in array


cgbeige
02-04-2011, 06:57 PM
I have a script that renders out separate renders for lights and I am working on a portion that deals with V-Ray meshes with light mats attached. I can't just hide these objects since they affect occlusion so I need to store the colour multiplier value of all selected meshlights and then zero this, then setting the individual objects to their stored value and rendering the pass, then setting it back to 0, doing the same for the others and restoring the original values. I can't just run a simple for each loop so I'm wondering what the best way to approach this is. Here's the code as is


string $meshLights[] = `ls -sl`;
string $docName = `file -q -shortName -sceneName`;
int $RE_value = `getAttr vraySettings.relements_enableall`;

//initialize vrayFileNamePrefix string
unifiedRenderGlobalsWindow;

//disable render elements for light renders
if ($RE_value == 1)
{
setAttr "vraySettings.relements_enableall" 0;
}

//ZERO ENVMAP CONTRIBUTION
string $currentRenderName = `textFieldGrp -q -text -forceChangeCommand vrayFileNamePrefix`;
int $envMapState = `getAttr "vraySettings.cam_overrideEnvtex"`;
if ($envMapState == 1)
{
setAttr "vraySettings.cam_overrideEnvtex" 0;
}
//END ZERO ENVMAP CONTRIBUTION

//Zero MatLights for bulb-based passes

for ( $each in $meshLights )
{
select -r $each;
string $shapes[] = `listRelatives -s $each`;
string $sGroup[] = `listSets -type 1 -o $shapes[0]`;
string $sGroupMat[] = `listConnections -d 0 -s 1 $sGroup[0]`;
float $currentLightMatValue = `getAttr ($sGroupMat[0] + ".colorMultiplier")`;
//print $currentLightMatValue;
setAttr ($sGroupMat[0] + ".colorMultiplier") 0;

//set to current value and render each mesh light contribution
//STUCK HERE - MANAGES TO ZERO ALL MAT LIGHTS BUT CAN'T FIGURE OUT HOW TO DO SINGLE CONTRIB WITHOUT EACH. figure out how to store all in array and recall value later, per object.

setAttr ($sGroupMat[0] + ".colorMultiplier") $currentLightMatValue;

textFieldGrp -e -text ($docName + "_" + $each) -forceChangeCommand vrayFileNamePrefix;
RedoPreviousRender;
}

cgbeige
02-06-2011, 04:23 PM
ok - I figured out that I'd have to do this the long way, avoiding $each, since it's not storing a useful array index (yes, I'm new). My problem now is that the values of the object in the index array isn't corresponding to the right stored attribute in the index. I tried a simple test with spheres and scaleX and none of these scale values are correctly mapped to the corresponding object they are taken from:

http://grab.by/grabs/513a993213b21f474a166685e4d5d998.png

So I can't say

setAttr ($objectto[$i] + ".scaleX") $storedScale[$i]

since they are all out of whack. Is there something I'm missing here to enforce this proper order when getting the values?

NaughtyNathan
02-06-2011, 09:24 PM
Dave, in line 5 you are initialising a new float array with only one value, the scaleX value of the LAST item in the object array. If you want to create an array of values you'd need to create a for loop and add to the array:

string $myStoredScales[] = {}; // initialise an EMPTY! array
for ($n=0 ; $n<size($mySelection) ; $n++)
$myStoredScales[$n] = `getAttr ($mySelection[$n]+".scaleX")`;
now your arrays will be synced.
:nathaN

cgbeige
02-06-2011, 09:58 PM
Thanks - I somehow knew you'd be the guy to set this straight. We need to team up and create a "beer for Nathan" fund.

NaughtyNathan
02-06-2011, 10:26 PM
haha. thanks... then I just need to find a bar that accepts Paypal and I'm all set! :D ;)
:beer:

cgbeige
02-06-2011, 10:27 PM
It never ends, apparently. Now it's tripping on the part where I try and set the value from the stored array value:

// Error: setAttr: Error reading data element number 1: 0.478789937 //

This is what I have now:

string $mySelection[] = `ls -sl`;
//store original scales
string $myStoredScales[] = {}; // initialise an EMPTY! array

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$myStoredScales[$n] = `getAttr ($mySelection[$n]+".scaleX")`;
}

print $mySelection;
print $myStoredScales;

//zero scaleX for all
for ($n=0 ; $n<size($mySelection) ; $n++)
{
setAttr ($mySelection[$n] + ".scaleX") 0.1;
}

for ($n=0 ; $n<size($mySelection) ; $n++)
{
setAttr ($mySelection[$n] + ".scaleX") $myStoredScales[$n];
RedoPreviousRender;
setAttr ($mySelection[$n] + ".scaleX") 0.1;
}



I'm not sure if there's some way you're supposed to quote array variables to have them expanded properly as floats.

NaughtyNathan
02-07-2011, 08:56 AM
oops! sorry, my fault.. it should be a float array.. I made a string array in my example and you've copied my error! :blush:
float $myStoredScales[] = {}; // initialise an EMPTY! FLOAT arraysorry! :)
:nathaN

cgbeige
02-07-2011, 02:23 PM
aw - I should have caught that. Thanks - works great now. I'm going to build the long and hairy V-Ray material version from this now:

string $mySelection[] = `ls -sl`;
float $myStoredScales[] = {}; // initialise an EMPTY! array

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$myStoredScales[$n] = `getAttr ($mySelection[$n]+".scaleX")`;
}

//zero scaleX for all
for ($n=0 ; $n<size($mySelection) ; $n++)
{
setAttr ($mySelection[$n] + ".scaleX") 0.1;
}

//set original scale for each and render
for ($n=0 ; $n<size($mySelection) ; $n++)
{
setAttr ($mySelection[$n] + ".scaleX") $myStoredScales[$n];
RedoPreviousRender;
setAttr ($mySelection[$n] + ".scaleX") 0.1;
}

//restore starting state
for ($n=0 ; $n<size($mySelection) ; $n++)
{
setAttr ($mySelection[$n] + ".scaleX") $myStoredScales[$n] ;
}

cgbeige
02-09-2011, 05:00 AM
Sorry - I really want this thread to die but now I am having a problem with the final script. It seems that the stuff that works outside of the loop doesn't work inside. I get stuck pretty early:

string $mySelection[] = {};
string $mySelection[] = `ls -sl`;
string $shapes[] = {};
string $sGroup[] = {};
string $sGroupMat[] = {};
string $myStoredMats[] = {};
float $myStoredMultipliers[] = {};

for ($n=0 ; $n<size($mySelection) ; $n++)
{
string $shapes[$n] = `listRelatives -s $mySelection[$n]`;
}

print $shapes;

that throws up a syntax error on the line inside the for statement. So I can't even begin this breakdown:

for ( $each in $meshLights )
{
select -r $each;
string $shapes[] = `listRelatives -s $each`;
string $sGroup[] = `listSets -type 1 -o $shapes[0]`;
string $sGroupMat[] = `listConnections -d 0 -s 1 $sGroup[0]`;
float $currentLightMatValue = `getAttr ($sGroupMat[0] + ".colorMultiplier")`;

efecto
02-09-2011, 06:46 AM
try something like this.

Firstly you already have declared $shapes at top.

So you don't want to redeclare it in the loop like you had.
Second problem was that listRelatives cmd gives you an array so I declared $tmp array outside of the loop then assigned 'listRelatives return' to $tmp then assigned 1st item in the array to $shapes[$n].

i hope it makes sense.


string $mySelection[];
string $mySelection[] = `ls -sl`;
string $shapes[];
string $sGroup[];
string $sGroupMat[];
string $myStoredMats[];
float $myStoredMultipliers[];
string $tmp[]; // declare temp array

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmp = `listRelatives -s $mySelection[$n]`; // assign results to $tmp array
$shapes[$n] = $tmp[0]; // assign 1st item in $tmp array to $shapes[$n] in each loop
}

print $shapes;

cgbeige
02-09-2011, 02:09 PM
I guess I'm confused as to when I need to declare an empty array to populate, since Nathan just told me above to use the empty float array and fill it with the loop.

WesHowe
02-09-2011, 02:40 PM
In your $n loop, each time it iterates you are declaring a new empty $shapes[$n] variable, which replaces the one created in the previous iteration, and filling the final entry from $tmp[0].

I would expect at the end of this you would only have one valid entry, in the last slot of the array, as all of the previous ones were erased iteration after iteration.

In MEL the arrays are dynamic, so you can just keep adding new entries and the engine will make sure that enough memory is allocated to hold it all. (Within the obvious limits of available resources).

<* Wes *>

cgbeige
02-09-2011, 03:28 PM
ok - so I understand that now. But the final bit trips on one of those painful "// Error: Cannot convert data of type float to type float[]. //" errors:

string $mySelection[];
string $mySelection[] = `ls -sl`;
string $shapes[];
string $sGroup[];
string $sGroupMat[];
float $myStoredMultipliers[];
string $tmp[]; // declare temp array
float $tmpFloat[];

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmp = `listRelatives -s $mySelection[$n]`; // assign results to $tmp array
$shapes[$n] = $tmp[0]; // assign 1st item in $tmp array to $shapes[$n] in each loop
}

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmp = `listSets -type 1 -o $shapes[$n]`; // assign results to $tmp array
$sGroup[$n] = $tmp[0]; // assign 1st item in $tmp array to $shapes[$n] in each loop
}

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmp = `listConnections -d 0 -s 1 $sGroup[$n]`; // assign results to $tmp array
$sGroupMat[$n] = $tmp[0]; // assign 1st item in $tmp array to $shapes[$n] in each loop
}

print $sGroupMat;
getAttr ($sGroupMat[0] + ".colorMultiplier");

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmpFloat = `getAttr ($sGroupMat[$n] + ".colorMultiplier")`;
$myStoredMultipliers[$n] = $tmpFloat[0];
}

print $myStoredMultipliers;

NaughtyNathan
02-09-2011, 03:32 PM
the key here Dave is that whenever you specify the TYPE, you are declaring a NEW variable.

string $array[] = {}; // this creates a new string array, and initialises it empty
for ($item in $someList)
{
string $array[] = `someFunc`; // this creates a NEW string array, unrelated to the original
print `size $array`; // result here could be, say, 8 for example...
}
print $array;
// Result: (empty!)

If you wanted the above loop to alter the original array you wouldn't specify the type (this includes the array braces [])
string $array[] = {}; // this creates a new string array, and initialises it empty
for ($item in $someList)
{
$array = `someFunc`; // this simply populates the existing $array
print `size $array`; // result here could be, say, 8 for example...
}
print $array;
// Result: pCube1 pCube9 pCube10 pCone1 pCone2 pCone3 polySurface712 polySurface802

The key is the scope braces {} as any variables declared inside them are local to (only exist inside) that block, which is how you can have two with the same name, and hence this confusion.
:nathaN

NaughtyNathan
02-09-2011, 03:37 PM
// Error: Cannot convert data of type float to type float[]. //

is unfortunately an error which we all get often. Every command that returns something does so in a specific type. `ls` for example always returns a string[] array, `fmod` always returns a float, etc.. unless you have memorized every return type you'll always fall foul of this error. However, if you show line numbers in your errors is always a simple case of changing the type you are expecting in the offending line (or creating a new variable type to fit).

:nathaN

cgbeige
02-09-2011, 03:38 PM
ok - I got it. I realized the tmp was redundant for the last one so this works now.

string $mySelection[];
string $mySelection[] = `ls -sl`;
string $shapes[];
string $sGroup[];
string $sGroupMat[];
float $myStoredMultipliers[];
string $tmp[]; // declare temp array
float $tmpFloat[];

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmp = `listRelatives -s $mySelection[$n]`; // assign results to $tmp array
$shapes[$n] = $tmp[0]; // assign 1st item in $tmp array to $shapes[$n] in each loop
}

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmp = `listSets -type 1 -o $shapes[$n]`; // assign results to $tmp array
$sGroup[$n] = $tmp[0]; // assign 1st item in $tmp array to $shapes[$n] in each loop
}

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$tmp = `listConnections -d 0 -s 1 $sGroup[$n]`; // assign results to $tmp array
$sGroupMat[$n] = $tmp[0]; // assign 1st item in $tmp array to $shapes[$n] in each loop
}

for ($n=0 ; $n<size($mySelection) ; $n++)
{
$myStoredMultipliers[$n] = `getAttr ($sGroupMat[$n] + ".colorMultiplier")`;
}

print $myStoredMultipliers;

Thanks for all the feedback. I'm obviously new to C and MEL in general (I think I learned how to declare a variable 6 months ago) and, in my defence, my degree is in Painting and Drawing :p

But this is fun to learn and I'll comb this thread to be better understand how the variables and arrays are working. It's one of those things that just needs to click and it's not clicking right now, although your last explanation helped. I was confused as how populating and declaring were different.

Redsand1080
02-09-2011, 03:49 PM
the key here Dave is that whenever you specify the TYPE, you are declaring a NEW variable.


When I finally learned that it was like a light bulb went on and all of a sudden a bunch of "strange" things in my script that didn't make sense all of a sudden clicked! I've never seen that documented anywhere, one of my co-workers who has had a number of years of programming experience told me that one. I wish that piece of info was better documented. I don't mean to go off topic here...I just had to throw that out there because it tripped me up as well at one point. :)

cgbeige
02-09-2011, 04:07 PM
so, as a thanks to all you guys for the help, here is the rather cool fruits of our labour:

http://vimeo.com/19752448

The env map contribution part and file naming based on the object was already set up, so I just plugged in this stuff and now it's all working.

I am working on a Maxwell-style multilight script for V-Ray and Nuke and this was the hard part. The per-light part was already working so now I just need to mash the two parts together and force them to make sweet love together.

CGTalk Moderation
02-09-2011, 04:07 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.