Jump to content

VEX - foreach - I don't get it


Recommended Posts

Hello Alvaro. The foreach() is intended to loop over items of an array. Those items are usually numbers, but you can have array of vectors, matrices etc. Those numbers can be @id of neigbouring primitives, which you stored in some upstream wrangle, or so.

Here is a nice explanation with an example:

http://www.tokeru.com/cgwiki/index.php?title=JoyOfVex13

  • Like 1
Link to comment
Share on other sites

So I got this from entagma, I think it's simple enough for a starting point. It works just like an attribute transfer:
 

vector pos = point(1, "P" , 0);

int points[] = pcfind(0 , "P" , pos , ch("radius") , 300);

foreach(int point ; points)
{
    setpointattrib(0 , "Cd" , point , {1,0,0});
}

The forach part starts at 6:20

and I transcripted what Moritz says:

Quote

 

what foreach needs is: first a variable which will contain an individual list entry when we loop through our array (int point;)

and it needs the array name, which we should loop through. in our case "points" without those curly brackets.

...

This construct will run a given number of times. it will run exactly as many times as there are elements in points
for each one it will copy an individual element from points into the variable called point so one after another we will go through the whole array and point will
contain each individual entry of the array, a single entry at a time.

 

I feel like it sounds dumb but i think i need to understand the very basic concept of this.
So we have foreach(int point ; points)  - what does the first (int point) and the second element (points) does?

int point is the number of points I have and the foreach will run points for each one of the points?

  • Like 1
Link to comment
Share on other sites

As regards entagma example:

vector pos = point(1, "P" , 0);

int points[] = pcfind(0 , "P" , pos , ch("radius") , 300);
// the above line creates a variable ... an array of integers "points" 
// and saves numbers of closest points in the array
// now points store something like this:
// {25,2684,654,489,9846,64} up to 300 items

foreach(int point ; points)
// the above line creates a temporary variable, single integer "point"
// we already have points

{
    setpointattrib(0 , "Cd" , point , {1,0,0});
    // in step 0, point equals 25
    // in step 1, point equals 2684
    // in step 2, point equals 654
    // etc for each member of points

}

 

Edited by ikoon
  • Thanks 1
Link to comment
Share on other sites

Jiri, this is perfect, thank you very much!

I might have some other questions later but right now what comes to my mind is: can I see the points attribute, like what im getting from pcfind? I tried to make it like i@points[] = pcfind... but it gives m an error

Link to comment
Share on other sites

There is a specific syntax to create attribute arrays:

i[]@name to create array of integers
f[]@name to create array of floats

I have more examples here, I hope that all are valid :) but you will see the pattern:
http://lex.ikoon.cz/vex-arrays-and-matrices/

 

So if you want to store an attribute and see it in the Geometry spreadsheet, just add this line:

int points[] = pcfind(0 , "P" , pos , ch("radius") , 300);
i[]@points = points; //add this line

 

Btw for me those [] were quite confusing. And still are.
When working with variable array, you write name[] only when you are defining it. Then use just the name.
When working with attribute array, you write i[]@name even when you are reading from it.

Edited by ikoon
  • Thanks 1
Link to comment
Share on other sites

Thx Jiri, I can see the array attribute now ;)
Nice, your website looks useful! thx for sharing it all

I still cant get some things into my mind but I'm already understanding it way better then before.
So, you said:

foreach(int point ; points)
// the above line creates a temporary variable, single integer "point"
// we already have points

//the above line creates a temporary variable, single integer"point"

what is this variable? what it does in the setpointattrib?

For me it looks like the the point variable is just getting the values of the pcfind as well (is it? it looks weird now that its written)

  • Like 1
Link to comment
Share on other sites

That entagma example could be rewritten into this (if I assume those numbers are those close points)

A.

int points[] = {25,2684,654,489,9846,64};

foreach(int point ; points)
{
    setpointattrib(0 , "Cd" , point , {1,0,0});
}

 

B. And the following code does exactly the same thing as whole A does. So, the foreach() does in fact this:
 

setpointattrib(0 , "Cd" , 25   , {1,0,0});
setpointattrib(0 , "Cd" , 2684 , {1,0,0});
setpointattrib(0 , "Cd" , 654  , {1,0,0});
setpointattrib(0 , "Cd" , 489  , {1,0,0});
setpointattrib(0 , "Cd" , 9846 , {1,0,0});
setpointattrib(0 , "Cd" , 64   , {1,0,0});

My english is poor :) I wanted to say that A = B.

Third argument of the setpointattrib() is the number of the point to set the attribute on: http://www.sidefx.com/docs/houdini/vex/functions/setpointattrib.html

Edited by ikoon
  • Like 1
Link to comment
Share on other sites

I have tried the method you were talking about, and it works. So here we have C. which does the same as A and B. So you were right:

 

vector pos = point(1, "P" , 0);

foreach(int point ;    pcfind(0 , "P" , pos , ch("radius") , 300)    )
{
    setpointattrib(0 , "Cd" , point , {1,0,0});
}

 

  • Like 1
Link to comment
Share on other sites

Btw there is also D. which does the same as A B and C:

foreach(int point ;   {25,2684,654,489,9846,64}   )
{
    setpointattrib(0 , "Cd" , point , {1,0,0});
}

It works, but it throws a warning. Houdini reads 25, 2684, 654 etc as floats ... and stores them into "int point" is an integer.

  • Like 1
Link to comment
Share on other sites

you can also put in a third argument in the foreach, the index you are running over.
 

//run over primitives, use this on a polyline and you will get the order of the points
int primpts[] = primpoints(0,@primnum);

foreach(int index;int i;primpts){
	setpointattrib(0,"index",i,index,"set");
	}

 

 

  • Like 1
  • Thanks 1
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...