ParticleSkull Posted April 2, 2019 Share Posted April 2, 2019 (edited) Hey guys, I never got how does a foreach works in vex (at all!), can someone please explain me this? It does the same thing as the For-Each Loop node? Edited April 2, 2019 by ParticleSkull Quote Link to comment Share on other sites More sharing options...
ikoon Posted April 2, 2019 Share Posted April 2, 2019 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 1 Quote Link to comment Share on other sites More sharing options...
ParticleSkull Posted April 2, 2019 Author Share Posted April 2, 2019 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? 1 Quote Link to comment Share on other sites More sharing options...
ParticleSkull Posted April 2, 2019 Author Share Posted April 2, 2019 Thx Jiri! The example from cgwiki looks awesome, I'll check it right now 1 Quote Link to comment Share on other sites More sharing options...
ikoon Posted April 2, 2019 Share Posted April 2, 2019 (edited) 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 April 2, 2019 by ikoon 1 Quote Link to comment Share on other sites More sharing options...
ParticleSkull Posted April 2, 2019 Author Share Posted April 2, 2019 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 Quote Link to comment Share on other sites More sharing options...
ikoon Posted April 2, 2019 Share Posted April 2, 2019 (edited) 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 April 2, 2019 by ikoon 1 Quote Link to comment Share on other sites More sharing options...
ParticleSkull Posted April 2, 2019 Author Share Posted April 2, 2019 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) 1 Quote Link to comment Share on other sites More sharing options...
ikoon Posted April 2, 2019 Share Posted April 2, 2019 (edited) 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 April 2, 2019 by ikoon 1 Quote Link to comment Share on other sites More sharing options...
ikoon Posted April 2, 2019 Share Posted April 2, 2019 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}); } 1 Quote Link to comment Share on other sites More sharing options...
ikoon Posted April 2, 2019 Share Posted April 2, 2019 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. 1 Quote Link to comment Share on other sites More sharing options...
ParticleSkull Posted April 2, 2019 Author Share Posted April 2, 2019 This is awesome, now it makes perfect sense. It couldn't be more clear Thank you very much Now I'll try some complex examples to see how it goes thx! Quote Link to comment Share on other sites More sharing options...
ikoon Posted April 2, 2019 Share Posted April 2, 2019 You are most welcome. You do great and inspiring work, I am glad I was helpful with my little vex knowledge good luck with your amazing work! Quote Link to comment Share on other sites More sharing options...
ThomasPara Posted April 2, 2019 Share Posted April 2, 2019 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"); } 1 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.