Jump to content

How would you import multiple attributes into vex... arrays?


meshsmooth

Recommended Posts

I have a vop sop and i am looking to import a list of int point

attributes such as...

closest_pt_curve_0

closest_pt_curve_1

closest_pt_curve_2

closest_pt_curve_3

closest_pt_curve_4

closest_pt_curve_?

each attribute is needed to be tested against in a loop so if there are 18 attributes the first loop will need closest_pt_curve_0 and the last closest_pt_curve_17. the documentation is a bit lite on for vex arrays. I would probably would need to concatenate "closest_pt_curve_" with a number too which i am not confident will work ether?

i can turn what ever vex code into a VOP node later but for now i need some documentation or even someone to propose an answer my guess in pseudo code (python meets vex)

def importAttribNum( stem="closest_pt_curve_", attribNum=0):

int data = 0

import(stem + attribNum , data, 0)

return data

any ideas

Robert Kelly

Link to comment
Share on other sites

I'm not sure you need arrays if all you're doing is a consecutive inspection of these attributes. If this is the case, then you could just do a straight loop like this:

int i  = 0;
int pt = 0;
int ok = import("closest_pt_curve_0",pt,0);

while(ok) {
   i ++;
   // do something with the currently imported attribute (pt)
   // ...

   // get the next one if it exists
   ok = import(sprintf("closest_pt_curve_%d",i),pt,0);
}

// i holds number of imported "closest_pt_curve_X" attributes
//
//... more magic goes here 

Link to comment
Share on other sites

this is the ugly code I ended up with

if ($attrib_num == 0) $success = import($_attrib_0, $adata, $input_index, $ptnum);
else if ($attrib_num == 1) $success = import($_attrib_1, $adata, $input_index, $ptnum);
else if ($attrib_num == 2) $success = import($_attrib_2, $adata, $input_index, $ptnum);
else if ($attrib_num == 3) $success = import($_attrib_3, $adata, $input_index, $ptnum);
else if ($attrib_num == 4) $success = import($_attrib_4, $adata, $input_index, $ptnum);
else if ($attrib_num == 5) $success = import($_attrib_5, $adata, $input_index, $ptnum);
else if ($attrib_num == 6) $success = import($_attrib_6, $adata, $input_index, $ptnum);
else if ($attrib_num == 7) $success = import($_attrib_7, $adata, $input_index, $ptnum);
else if ($attrib_num == 8) $success = import($_attrib_8, $adata, $input_index, $ptnum);
else if ($attrib_num == 9) $success = import($_attrib_9, $adata, $input_index, $ptnum);
else if ($attrib_num == 10) $success = import($_attrib_10, $adata, $input_index, $ptnum);
\\ all the way to 50 \\

I did have allong with some other code something much like what you had

import(sprintf("closest_pt_curve_%s",i),pt,0);

But it would only import the closest_pt_curve_0 attributes. As far as importing dynamic strings isn't happening.

I have sprintf($yourFormattingHere,$yourIntHere) wrapped into a vop and then piped that into a parameter exporting the string and got closest_pt_curve_0, closest_pt_curve_1, closest_pt_curve_3... so it will make the srtings ok. Then I took that same calculated string and piped it into the import attribute but the same behaviour of getting the first string and then not updating it happened again.

Even my second last bit of ugly code was....

if ($attrib_num == 0) $attrib_current = $_attrib_0;
else if ($attrib_num == 1) $attrib_current = $_attrib_1;
else if ($attrib_num == 2) $attrib_current = $_attrib_2;
else if ($attrib_num == 3) $attrib_current = $_attrib_3;
\\  all the way to 50  \\
$success = import($attrib_current, $adata, $input_index, $ptnum)

This proved to get stuck on the first string as well.

So i am thinking there is a Bug / feature that prevents the import attribute from updating the attribute that it imports.

Edited by meshsmooth
Link to comment
Share on other sites

I did have allong with some other code something much like what you had

import(sprintf("closest_pt_curve_%s",i),pt,0);

But it would only import the closest_pt_curve_0 attributes. As far as importing dynamic strings isn't happening.

Hmm. I just tried it and I'm not seeing any of the problems you mention.

All I did is pretty much copy-paste what I wrote above.

Attached is an example using two methods: one using 50 individual attributes named "att_0" to "att_49", and the second method using a single array (of type float of course) with 50 elements. In both cases, the first VOP SOP in each chain creates the attribute(s) and the second modifies its(their) value(s) and re-exports the attribute. The end result in both cases is the reversed index sequence [49, 48, 47, ... 0]. No problems with "dynamic strings" that I can see (I imagine you mean the sprintf() function? -- anyway, that works fine too).

attributes.hip

Cheers!

Link to comment
Share on other sites

I can see the example file working. My test had 3 attributes and 3 points and for each point i imported a different attribute and that is when it got stuck so i will have to test your file on 3 points to see how it behaves. at the moment is operates on only one point but a shite load of attributes.

Thanks for the help by the way.

Link to comment
Share on other sites

  • 3 months later...

hi, I'm studying the hip file.

the inline vex code is this:

float $vals[] = array();

resize($vals,50);

int $i;

for($i=0;$i<50;$i++)

$vals[$i] = (float)$i;

addattribute("att_a",$vals,arraylength($vals));

in don't understand (float)$i; in the loop. what does it mean that (float) before the index?

Link to comment
Share on other sites

Guest Swann

Converts from int to float (casting).

In code they pack $i that is of type int into array of type float. If you don't convert it, it will throw error.

Link to comment
Share on other sites

Converts from int to float (casting).

In code they pack $i that is of type int into array of type float. If you don't convert it, it will throw error.

great, this was just my first thought (even if i don't know about casting), so for test if i was in error or not I changed the index to float in the declaration and removed the (float) inside the loop. but it doesn't work. why? maybe the loop function accept only integers?

thank you so much for the fasst response!

Link to comment
Share on other sites

Guest Swann

great, this was just my first thought (even if i don't know about casting), so for test if i was in error or not I changed the index to float in the declaration and removed the (float) inside the loop. but it doesn't work. why? maybe the loop function accept only integers?

thank you so much for the fasst response!

It's not a problem of loop.

You can't acces array elements using floats.

Here:

$vals[$i]

you specify in whitch place in array called "$vals" value will be stored. It has to be int. Array can be build from rows, columns or both (multidimensional, but they are not supported in VEX). It can't have 1.3 row or 4.3 column. It has to be 1st or 2nd row, 4th column etc. So if you changed $i to float before loop it will break. Thats wy cast is made inside loop.

Edited by SWANN
Link to comment
Share on other sites

It's not a problem of loop.

You can't acces array elements using floats.

Here:

$vals[$i]

you specify in whitch place in array called "$vals" value will be stored. It has to be int. Array can be build from rows, columns or both (multidimensional, but they are not supported in VEX). It can't have 1.3 row or 4.3 column. It has to be 1st or 2nd row, 4th column etc. So if you changed $i to float before loop it will break. Thats wy cast is made inside loop.

so it's a "limitation" of the loop itself.. if i use a float variable but my values are always integer it should work. I though that if I feed a float number this is automatically rounded to the nearest integer.

Thank you for the explanation. I come from mel, and I guess some of those castings are automatically made under the hood.

Managing varialbes In C or C++ it is similar to vex? just curiosity.

Link to comment
Share on other sites

Guest Swann

so it's a "limitation" of the loop itself.. if i use a float variable but my values are always integer it should work. I though that if I feed a float number this is automatically rounded to the nearest integer.

Thank you for the explanation. I come from mel, and I guess some of those castings are automatically made under the hood.

Managing varialbes In C or C++ it is similar to vex? just curiosity.

From int to float it will convert because you don't lose any data. It's called implicit cast.

There are other reasons why this is done like that.

$i in this code comes from input and it's a float. If you make cast before loop it will be cut to integer for all the code down. If you cast it inside loop it will be only cut inside loop, for code ouside loop it will still be available as a float.

Let say that $i has range from -1 to 1.

Then you test somewhere in your code if $i is bigger than 0 it will have yellow color, the bigger from zero the more intense. If you cast $i to integer outside loop your shading will be wrong because $i will have only values of (-1,0,1). So your yellow will have only one intensity = 1.

To my knowledge in C++ you don't have to cast but it's wrong because it may lead to problems that are hard to find.

Casting is like safety valve. You have to explicity say that you wan't cut some value.

Think that you have 500 lines of code and $i is "somewhere" cut into int. How you know when your value have been cut ? Maybe you will know where it's hapened but for somebody who will take your code finding it will be painfull.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...