Duplicate an object multiple times / ForEach in a Wrangle

   10918   21   1
User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
VEX is relativly nu to me, even when I am familiar with mel and some other programming languages.
So be Patient with me and dont make it to complicated

At the moment I am creating a brickwall with a few for each Loops and I thought, hey those simple
transformations can even be done in a wrangle.

but all those point creation and create geometry with vex tutorials doesn't take into account when
there is an incoming prim or box that should only be transformed - so i am more confused now.

can somebody give me a short forloop example to move and duplicate a box, when the box is piped into the wrangle?

thx
deHeavy
Edited by -heavy- - March 24, 2017 08:13:09
Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
682 posts
Joined: Sept. 2013
Offline
Hi,

let this run over the primitives of your input geometry.

vector offset = chv('Offset');
int copies = chi('Copies');
int prim_pts[] = primpoints(0, @primnum);
for(int i = 0; i < copies; i++){
    int add_prim = addprim(0, "poly"); 
    foreach(int pt; prim_pts){
        vector pt_pos = point(0, "P", pt);
        vector offset_mult = offset * (i + 1);
        int add_pt = addpoint(0, pt_pos + offset_mult);
        addvertex(0, add_prim, add_pt);
    }
}



Feel free to ask questions.

Attachments:
VEX_geo_copy.jpg (99.3 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
8766 posts
Joined: July 2007
Offline
if you can (and to save yourself some headaches) just create points with traditional instancing transform attributes in VEX, then copy your bricks using copy to points

trying to approach this using pure VEX is not a good idea unless it's a VEX exercise, it can get really tedious if you want to preserve input geo with all the attributes and it will be much slower and heavier as you lose advantage of instancing that Copy To Points can give you if you pack the geo
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
2120 posts
Joined: Sept. 2015
Offline
I thought this might be a good excercise in using some of the vex functions I don't see in the previous examples.

I also have a couple sliders that can shift your primitive selections, and one for the translations.

The merge node is only there in case you want to keep all the original boxes and the new box that's been translated.

If that's the case then un-comment the code I have in the wrangle that removes prims so that in the merge there is no duplicate primitives.
Edited by BabaJ - March 25, 2017 12:37:31

Attachments:
Translate with vex.hiplc (69.1 KB)

User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
Hey =]

first of all, thx for the answers it helped me a lot.

Konstantin, this is a really slick solution I understand and that fits in my workflow.
So it first creates an array and stores the points from the incoming geo, then iterates
through the copycount and creates prims, which seems to be only a container to hold the
points and vertex that are created in the foreach.
So basically its not the prim that is moved, its the points encapsulated in the prim.

Tomas - yes and now, its an excercise for sure but I really thought - I dont have points
to copy to and so I have to use foreach to duplicate the startBrick the way I want.
but then I read your post a second and a third time and something changed my mind.
hey damn yes I can create points in that grid like offsetted way I need and yes, then I
can copytopoints or copy stamp. So i keep that in mind and build something and will see
how far I can get.

And Baba… hmmm.. Magic i have to take a closer look and a slower look and a longer look.
but its quite interesting and even not to complicated. so thx.

heavy
Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
tamte
if you can (and to save yourself some headaches) just create points with traditional instancing transform attributes in VEX, then copy your bricks using copy to points

trying to approach this using pure VEX is not a good idea unless it's a VEX exercise, it can get really tedious if you want to preserve input geo with all the attributes and it will be much slower and heavier as you lose advantage of instancing that Copy To Points can give you if you pack the geo

I get stuck… last hour(s) I tried to get the defined point attributes values from the first wrangle into the detail wrangle afterwards I use to work with the prims or points

so for example i have one attribute i@countX = 20; defined in the first wrangle going over points, but
i dont get it in to the second wrangle in detail once mode on to my point added with addpoint…
Edited by -heavy- - March 25, 2017 20:01:03
Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
8766 posts
Joined: July 2007
Offline
in detail wrangle you can import any attribute of any point using point() function
or store using setpointattrib()
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
I tried that, several times and several version, but without luck, maybe i was to tired yesterday.
I give a new try today. If i run out of ideas i will be back.

EDIT TODAY: ..seems that i was really to tired yesterday.
importing the attributes and assigning them to my points works like a charm today
Edited by -heavy- - March 26, 2017 16:23:22
Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
tamte
in detail wrangle you can import any attribute of any point using point() function
or store using setpointattrib()


what if i store values not in an attribute of a Point but as variable in a wrangle?
Does this variable exist in the stream down and if yes - how can i reference it or grab its value
in a different wrangle down the line or elsewhere
or
does it only excists in the wrangle it is created and is invisible for all other nodes?

And can i reference values in a wrangle from other nodes then vex wrangles ?
for example:
when i create a wrangle, that holds for instance wallwidth and wallheight and other Parameter,
do i have the possibility to grab the values in a gridSOP.sizex & sizey?
Edited by -heavy- - March 27, 2017 09:17:10
Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
2120 posts
Joined: Sept. 2015
Offline
If you create a variable in the wrangle like say
float wallwidth;
it will only be available for that wrangle.

If you created it as
float @wallwidth;
it will be available ‘downstream’ to connected nodes when those nodes are in run over. I don't know if it's a bug but successive nodes can't access it in detail(once only) mode as only @wallwidth; nor does it work using detail or detailattrib function. Maybe still some learning I need to do.

But, if
float @wallwidth;
is done in a wrangle node that was running in detail mode then any other wrangle node, whether downstream or not can access with the detail or detailattrib function.

To help all this you can use the printf function to display to a console pop up.
Edited by BabaJ - March 27, 2017 10:32:18
User Avatar
Member
8766 posts
Joined: July 2007
Offline
lets not make it too confusing

float @wallwidth;
does not create a variable, but an attribute, whose value you can access by using f@wallwidth in the same or other
wrangle downstream of the same class
so f@wallwidth in detail wrangle will try to find and bind to detail attribute named wallwidth
so f@wallwidth in point wrangle will try to find and bind to point attribute named wallwidth
etc.

so if you create wallwidth using f@wallwidth in point wrangle, you will have wallwidth point attrib
and to access that in downstream detail wrangle you have to use point() function, as using f@wallwidth will look for detail attribute named wallwidth

there is as well a difference between doing
float @wallwidth = 1;
and
f@wallwidth = 1;

the first one just ensures that the wallwidth attrib exists and sets its default value to 1, however it doesn't modify the actual values if it already exists
the second one sets all the values to 1, but doesn't modify default value
if you just do
float @wallwidth;
then that is the same as doing
float @wallwidth = 0;

so to answer original questions
1. no, you cannot acces variables in other wrangles than the one created in
2. to pass the data between wrangles or other nodes use attributes, store data there then retrieve in other nodes through attribute binding {@} if applicable, or point(), vertex(), prim(), detail() VEX functions or in parameters of other nodes using HScript expressions of the same names, or using python
Edited by tamte - March 27, 2017 14:41:58
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
2120 posts
Joined: Sept. 2015
Offline
float @wallwidth;
then that is the same as doing
float @wallwidth = 0;

I am speaking of treating attributes like global variables.

If I have already created my attribute with

float @wallwidth

then I am not going to do it again, so it doesn't matter.

If I want to change it's value I will just use

@wallwidth = whatever;

I could be wrong, but I think the op is looking at how to ‘structure’ his code in terms of variables. Which is why I am presenting it the way I did.

But I think you are looking at more from the typical use of wrangles in run over mode.

For myself with what I like to do with wrangles, it makes much more sense to run in detail mode.

And because vex syntax is similar to c, running in detail mode allows me to structure my code that I understand and find easier to read than having to consider what is happening in run over mode with my code.

I also make use of functions that might have a few hundred lines of code that I simply put in a *.h file and reference that function with #include<file> in my wrangler.

So in my wrangler I might initially at the top have a few lines of defined local variables, and some ‘global variables’( I know technically - attribute) that I know I will be using elsewhere.

Then I will have a few functions that could represent together a couple thousand lines of codes.

So when I am using the ‘convention’:

#include <C:/functions A to C/AtoC.h>

float @mywall;
float tempwall;
flat @newwall;

tempwall = functionA();

@mywall = functionB( tempwall, blah);

@newall = functionC ( @mywall, tempwall);

…and so on.

I find it's a great approach in writing and reading code.

Of course this is just my personal way but I don't find it confusing to look at and treat a user created attribute as a ‘gobal variable’.

The original poster alluded to a background in other programming languages and was using the language of creating global variables.

I think my explanation lends itself to that orientation and really isn't confusing.

Except to say, I would agree if one starts to ‘mix and match’ their approach by using some detail mode and run over mode, then your point about the difference between

float @wallwidth = 1;
and
f@mywall = 1;

is important to know.
Edited by BabaJ - March 27, 2017 18:15:35
User Avatar
Member
8766 posts
Joined: July 2007
Offline
it's abdolutely fine if you treat it that way, I just find it important to shed some light to what it really does and why you can't think that once you create @attrib, that you can access it downstream no matter what
it has it's rules so if one understands what it really does one can take advantage of that
otherwise it can be confusing
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
2120 posts
Joined: Sept. 2015
Offline
I appreciate you pointing this out too and I agree it can be confusing if one is not aware of the differences and why.

Hopefully in the future when I attempt to help someone in the forum on this topic I will phrase my explanations differently taking into account what you've mentioned.
User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
that is very informative here.
what I dont get at the moment is what happend when there is no connection downstream or no point to store the values?

when I use the wrangle its easy and fast to create basic params and a few sliders and such stuff.
now when using @ to create attributes the attributes show up in the spreadsheet but with no Point
connected to the Input its only a columnheader in a table. But I know the value is there cause instantly
when a Point is connected the value is assigned and shown in the spreadsheet - now I can use
point() function to grab the values everywhere I want.

So can I get the value of this Attribute when there is no Point connected ?
and
Basic example
I have the wrangle that holds wallbounds, wallsizeX and wallsizeY, and the bricksize{x,y,z}.
And calculate brickcountX and brickcountY based on wallsize/brickwidth.
then I create a grid, grid has no Input so it can not be downstream of the wrangle.
the grid should get the sizeX and sizeY as reference to the values in the wrangle and
rows and columns should reference to countx and county.

When wallsize and bricksize are inputfields and sliders, I can ch ref and done but I can
not access the calculated brickcount.
So how about grabbing values in channels?

And is the way to go maybe vice versa, I mean create the grid then the wrangle and
manipulate the values afterwards - but size and rows is not an attribute so how to
access size row etc. there is no stamping or is it?

EDIT: with a bit of Google and a bit of luck i found that the Point() expression works fine for referencing
what confuses me is that the help doc said the function gets 3 Parameter
type point(string geometry, string attribute_name, int pointnumber)
but with a bit of luck and misstyping i get it to work with 4 Parameter…?
point(“../parameter/”, 0, “brickcountY”,0)

so whats the deal ?
Edited by -heavy- - March 29, 2017 08:08:17
Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
2120 posts
Joined: Sept. 2015
Offline
…what I dont get at the moment is what happend when there is no connection downstream or no point to store the
values?…
…So can I get the value of this Attribute when there is no Point connected ?…

Set your wrangle to detail - once only, and create the attribute like @YourAttrib. Then in any other wrangle, whether it's connected or not, use the detail or detailattrib function to get @YourAttrib.
User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
here is a small file that does not work, so, what do I miss?

Attachments:
detailtest.hipnc (39.9 KB)

Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
2120 posts
Joined: Sept. 2015
Offline
Need to use “op:”

float myNewVal_detAttrib = detailattrib("op:../para_creator", "myValue",0,1);
float myNewVal_detTest = detail("op:../para_creator", "myValue");
User Avatar
Member
62 posts
Joined: Oct. 2007
Offline
ahhh.

..you know why?
Edited by -heavy- - March 29, 2017 14:59:17
Janko Kissel
Maya & Houdini Smoke and Demolition VFX-Artist
http://vimeo.com/heavyatvimeo [vimeo.com]
https://www.youtube.com/user/masterheavyone/videos [youtube.com]
User Avatar
Member
2120 posts
Joined: Sept. 2015
Offline
I don't know exactly.

But in small part I think it's just an extension of the syntax to help the function find what it's looking for.

Even with say something like a transform node, just using “../transform/tx” is not enough although it's very specific to what parameter we are looking at; That it needs to be ch(“../transform/tx”) instead if we want to use it as a reference.

The same with the vex function, in this case detail attribute; although we are very specific about which attribute we are looking for - “MyValue”.

The docs have more information on this here:

http://www.sidefx.com/docs/houdini/io/op_syntax [sidefx.com]

In the docs on the detail function it gives an example of how to use it.

But no where is the use of op: shown. In the example it shows accessing a bgeo file.

vector uv;

// Get the value of the “uv” attribute for the detail.
uv = detail(“defgeo.bgeo”, “uv”);


What I am guessing is that this function(like others as well) has some flexibility in the data format in which to get the detail.

In the case of a bgeo it doesn't need additional syntax, but in the case of accessing the detail from a wrangle node it needs op:

Perhaps this saves the need for having two different functions for essentially doing the same thing?

Maybe someone more knowledgable will be able to clarify this.
Edited by BabaJ - March 29, 2017 16:14:21
  • Quick Links