Jump to content

Propagating point creation with VEX (TuftMaker v2.1 beta)


haki

Recommended Posts

[Edit Oct. 10 2020]

tuft_cover.thumb.png.17499713bb7bbb65b05e288a432868e6.png

Hey, it's been a while. Version 2.1 free here: https://gum.co/tuftMaker

So, I think I got totally carried away adding parameters and functionality. Good exercise, but I'm lost in it and probably you will be, too. Anyway, feel free to dissect the HDA and I hope there are bits and pieces that could be useful. That's not to say it doesn't work or anything, it does but it takes a moment to understand how, haha!

Cheers!

 

PAST BETA UPDATES:

- Fixed: wrong falloff values with geo coming in through input #2
- Fixed: Global seed for scattering not working when input #4 is connected.
- New: outputting 'type' primitive int attribute based on the iteration attribute if such is coming in through input #4
- The following documentation video demos available via F1:

 

LATEST WIP UPDATE:

Debugging

- Fixed scaling for anything outside the unit circle.

- Fixed curve framing with extreme angles by using dihedral to minimize rotation (thanks to Entagma for the theoretical insight on this one)

- Addressing tiny falloff value differences with a statistical variance check and a threshold parameter. (e.g. when the sample points are in a circle).

- Floating-point precision fix.

- Post carve 'curveu' recalculation takes care of the vertex colors ramp now.

 

Features

- Added point sampling mode switch (cone cap or cone volume)

- Added twist control

- (Obsolete since H18) Added per connected mesh UVs using Toraku's "Get correct uvs with a sweep sop" fix - http://www.tokeru.com/cgwiki/index.php?title=Houdini#Get_correct_uvs_with_a_sweep_sop

- "Listening" for N and iteration attributes.

- Using the new sweep sop now.

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------

THE BEGINNING OF THIS THREAD BELOW

----------------------------------------------------------------------------------------------------------------------------------------------------

Hi folks,

How would you go about adding points in a propagating manner in VEX. Here's what I mean:

- Start with several incoming base points, each with an up vector.

- For each one, add a new point somewhere along its up vector.

- Calculate a new up vector by subtracting base positions from new point positions and setting the new point up vector to the result

- Add the next new point somewhere along the previous point's up vector

 

So, I called it propagating, because every next point in part defines the following.

I think I'm on the right track here, but my gut's telling me I'm missing something.

 

I'm stuck. Here's what I got:

propagating_points.thumb.gif.5fb495efa23daa2932a7fea69824e1de.gif

 

vector up = point(0, "up", @ptnum);
vector currentPos = point(0, "P", @ptnum);
vector newPos = {0,0,0};


int pts[];

for(int i=0; i<@numelem; i++) {
    append(pts,i);
}


int iteration = chi("iteration");

for(int j=0; j<=iteration-1; j++){
    
    newPos = currentPos+up;
    int newPoint = addpoint(0, newPos);
    
    setpointattrib(0, "up", len(pts)+j, normalize(newPos), "set");
    currentPos = point(0, "P", len(pts)+j);
    up = normalize(newPos-currentPos);
    currentPos = newPos;
}

 

Where do you think I'm wrong here. What would you do? Cheers!

stipules_gen_gumroad_poster.png

Edited by haki
Link to comment
Share on other sites

You cant import attributes from points that are created in the same wrangle, you will only get values from the wrangle above.

And if you want to store attributes to a point you create you need to use the handle you have created. ex: setpointattrib(0,"attrib",newpoint,value,"set");

I think you might have been overthinking this one.

vector up = set(0,1,0);
vector this_pos = @P;
int samples = chi("samples");
for(int i = 0;i<samples;i++){
    this_pos += up*chf("lift");
    int newpoint = addpoint(0,this_pos);
    }

You can use this as base

Edited by ThomasPara
Link to comment
Share on other sites

20 hours ago, ThomasPara said:

You cant import attributes from points that are created in the same wrangle, you will only get values from the wrangle above.

And if you want to store attributes to a point you create you need to use the handle you have created. ex: setpointattrib(0,"attrib",newpoint,value,"set");

Cheers, Thomas! That explains some of the confusion I had. And, you're right I was probably overthinking it. Thanks for the base script!

I didn't write that in the post above, but I intended to later randomize the up vector direction for every new point and thus get a non-linear propagating pattern. I want to achieve a sort of (and I suspect that's not the right term here) parent-child behavior between every point and the next in line (something like tentacles constructed by points propagating in random directions). That's the reason why (in my head at least), calculating a new up by subtracting current_pos from new_pos and setting that at every sample is important.

Except, and this is probably going to seem totally dumb... at sample 2 it falls apart. Up is no longer pointing where I'd expect it to. I bet this has something to do with the last line current_pos = point(0, "P", new_point);

propagating_points_with_rand_dir.thumb.jpg.bfbe70173a42dfd0f174eb69d66b42e2.jpg

rand_dir_propagating_points.hiplc

vector up = @up;
vector current_pos = @P;
vector new_pos = 0;

int samples = chi("samples");
float offset = chf("offset");


for(int i = 0; i < samples; i++){


    new_pos += current_pos + up * offset;
    int new_point = addpoint(0, new_pos);
    
    up = normalize(new_pos-current_pos);
    setpointattrib(0, "up", new_point, up, "set");
    
    current_pos = point(0, "P", new_point);
    }

It appears at sample 2, the up direction is pointing away from the world origin, and not away from the points at sample 1. I feel like I'm missing something so basic...

Link to comment
Share on other sites

orientation.thumb.gif.99e0533ec112c12db1d197459d598336.gif

Thats because your current_pos always get set to (0,0,0)

Since you already have placed your point based on a vector, you dont need to "figure out" that vector again, it will only become the same vector. You can just offset with the same vector over and over again. You can then use the function "sample_direction_cone()" to vary your vector.

Link to comment
Share on other sites

Thanks, Thomas!

51 minutes ago, ThomasPara said:

Thats because your current_pos always get set to (0,0,0)

Ok. It seems I'm missing something here to understand why it always gets (0,0,0). On sample 1 it doesn't seem to get (0,0,0).

Let me see. Maybe my comment's complete nonsense, so back to the drawing board:

drawing_board_time.jpg.b99920601b2c266ef0ed0a51917019d9.jpg

It seems like this does what I've sketched above:

propagating_points_with_rand_dir_draw.thumb.jpg.bb1da2aa344e8752f3e432a050da7474.jpg

Now onto figuring out how to gain some degree of manual control over the random angle for each sample...

Cheers!

Link to comment
Share on other sites

Ta-da! I got the point arrays exactly in the correct order for the point number pattern I was getting.

propagating_points_with_rand_dir_prim.thumb.jpg.55ff25520c8a60e201a32d61dd2096e0.jpg

Alright, it's going to be smooth sailing from here on… (doing a little dance) Wait, what!? Addprim didn't do what you imagined? Documentation, here I come.

  • Like 1
Link to comment
Share on other sites

Eureka! (No need for point arrays after all...)

propagating_points_with_rand_dir_prim_eureka.thumb.jpg.f861c85db07ac63b92c06d9b1b54ffbb.jpg

So, from what I originally intended to be a grass generator... it will be a multi-purpose generator :D (including the effect on hair that electrocution has according to popular cartoon depictions)

Still to figure out a way to control the up angle at every sample... and to orient the points correctly based on the starting points (polyframe the prims I guess...)

[Edit] - With some finetuning below:

rand_dir_propagating_points_2.hiplc

Edited by haki
  • Like 3
Link to comment
Share on other sites

Hey folks, back with an update here, I took care of the curve framing:

Thanks to Entagma's Parallel Transport tutorial I understood the core concept here. I adapted it to my curves generator. I tried 2-3 alternatives, including the slideframe() function and the dihedral()*v0. Seems I got the best result by crossing vectors only. The slideframe and the dihedral seemed somewhat off, probably because I didn't do something right.

Here's the file if you wanna give it try: rand_dir_propagating_points_3.hiplc

 

[Edit] - With width and pscale attributes:

 

Debugging and adding some features:

 

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

Debugging

- Fixed scaling for anything outside the unit circle.

- Fixed curve framing with extreme angles by using dihedral to minimize rotation (thanks to Entagma for the theoretical insight on this one)

Features

- Added point sampling mode switch (cone cap or cone volume)

- Added twist control

- Added per connected mesh UVs using Toraku's "Get correct uvs with a sweep sop" fix - http://www.tokeru.com/cgwiki/index.php?title=Houdini#Get_correct_uvs_with_a_sweep_sop

 

Some practical results with it here (and one of my first ever tutorials, haha):

Give it a try and if you have suggestions, feel free. Cheers!

grass_n_stuff_gen_18_4b.hiplc

 

Edited by haki
  • Like 3
Link to comment
Share on other sites

  • 3 weeks later...

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...