Grouping particles (and other issues)

   4298   4   1
User Avatar
Member
13 posts
Joined: Sept. 2012
Offline
Ok. Bear with me. There might be better ways to do this, and I'm open to hearing from them, but first I want to get my approach to work right (since I'm still struggling with how Houdini thinks).

I'm trying to do something that has probably been done thousands of times… which is meshing particle trails. I thought of doing this by emitting a few particles (14 in this case, to get 14 “branches”), and spawning particles from them. I'd then get these trail spawns to take the shape of discs oriented towards the normal of the emitted particle (these spawns would be held in place by a drag force), and I'd then skin the discs to form my “branches”. Everything OK up until here? Ok.

So, I've been able to get my particles to emit properly, I've given them a nice motion by using some noise, and I've been able to spawn my static particles properly. I guessed that getting a shape on them would be straight forward, but then I thought… I can't just do that, because then when I skin the discs, the object will just become a huge mess. I gotta sort each “branch” of particles into its own group, so that I can then skin each group individually. That should get me the branches I need.
So, I went ahead and tried to devise a good strategy to group my particles.

I created a group for the original master particles (the ones that spawn the trails), just to keep track of them. I don't want to mix them up with the rest.
I then tried to figure out how to sort the rest of the particles into groups per branch. After reading the documentation on the Group POP node, it seemed that grouping using the Random option would do what I want. Specifically, the documentation for the Group Index parameter states:

“Sets the group the particle will be placed into. Normally, particles are sorted into groups in order (the first particle goes into the first group, etc.). You can use a custom expression here to manually determine which group number each particle goes into. If the expression evaluates to a number greater than the value in # of Groups, the number wraps around (that is, the value of the expression is modulo the number of groups).”

Since this is exactly what I want (I was actually looking first into how to write a modulo expression directly… unsuccessfully), I just set the # of Groups to 14 (since there are 14 master particles from which trailing particles are emitted), set the Group Index to $ID, and thought “that's great… 14 groups are created, and the first 14 particles are sorted accordingly, and then the 15th goes back into group 1, the 16th into group 2, and so on and so forth”, because that is what a Modulo function is supposed to do!
However, this is not what's happening. When I cook the sim and stop somewhere, if I inspect the node, I see that there's only 1 point in each of the new groups! The rest of the points are NOT being assigned, which means the function is not wrapping up! So my question is… is my expression written incorrectly? I'm guessing it it… here's more…

To further test this out, I decided to give each branch of particles its own color. My logic was that if I could color them by branch, I would certainly be able to group them by branch. I thought Houdini would be a lot more intelligent than forcing me to create 14 color nodes, and thought there should be a way where I could map the particles towards flags in a color ramp. I created my ramp with 14 flags, and set the Lookup parameter to $ID/14 (since I figured out that the flags are positioned in a normalized space), and it works!! My particles are nicely colored as specified. However, I still can't get to group my particles as needed (the same expression in the Group node doesn't work).

So, first question…

1. What's going on with the Group node? Why is it not wrapping around? Preserve Group is on, of course. Is the expression bogus?

Now, here's something else. I decided that to make the system more procedural, I'd try to reference the original number of particles being emitted in the Lookup parameter for the Color node, so that if I change the number of particles emitted, I can update the colors being used (I know I still have the issue of dynamically creating flags on the ramp on changes like these, but I'm honestly not touching that today…). So, instead of saying $ID/14, I tried referencing the paramter in my emitter over here using a copied relative reference. No go. I tried two things, each one giving me a different error…

$ID / chgroup(“/obj/geo1/popnet1/location/impulserate”): Does not error out, but all the particles fail to use the colors in the ramp (they're all being colored by the last flag)

$ID / chop(“../location/impulserate”): Does not error out, but now all particles are being colored by the first flag on the ramp.

$ID / chopcf(“/obj/geo1/popnet/location/impulserate”): Errors out. Houdini reports I'm using a bad data type for that function.

I got all those from different variations on how I was pasting the parameter onto the Lookup param. As a reference, relative reference, using spaces, no spaces… I don't know why, Houdini kept changing “ch” onto “chgroup”, “chop” and “chopcf” indistinctively, apparently. So, there goes question #2…

2. What would be the correct way of writing that expression so that it evaluates properly?

Lastly, in order to try to understand why my expression was not working, I decided to try it out in the Textport editor, to at least try to see if I could see what data type these expressions throw out (I was guessing I was getting a direct reference into the CHOP, instead of the float value stored by it). However, all those expressions just left the Textport editor with a big “?” on its face. I thought Textport would “talk” the same language as the expressions used by parameters, but I guess it's either “no”, or I'm missing an actual command to inspect or “execute” these expressions. So, question No. 3 would be…

3. How can I use Textport to evaluate expressions in it (if at all)? Or should I be using something else?

I appreciate any help over here. I'm trying to figure things on my own because that's the best way for me to learn, and I try to use the online help as much as possible so I can also learn my way around it, but now I'm stumped. So… a little push would be greatly appreciated

Thanks, and lets now go to bed! I'll see ya in the morning…
User Avatar
Staff
2540 posts
Joined: July 2005
Offline
Houdini doesn't think. It just does what you tell it to. It's just nodes working on geometry modified by other nodes is all. There is no magic in there. The magic lives in you (oh my now I sound like Celine Dion). No hidden operators to stupify the workflow.

Posting a hip file could have shrunk your above post to three or four sentences. Next time just post your hip file so we can see what you are up to. Hip files are completely self-documenting. Add Notes in networks where appropriate to clarify issues.

See the attached hip file.

—-

Skinning particles is generally done by first creating the “parent” attribute on the source and followed with a Split POP generating a fixed number of splits. Then use an Add SOP to build primitives by attribute. This workflow supports changing topology (I even use a fuse to consolidate co-incident points), varying source emission, whatever.

—-

Modulo is represented by % which is common in many programming languages.


Source POPs are limited to what local attributes it can access. See the Help for that Operator. Actually that is the first place to look when wondering about a node: the node help. Since it is creating the points, it doesn't have a filter to read in those attributes. Just add a POP after to do the filtering. POPs are creating a single rule set that is applied to the point accel, v and P.
That is why $ID doesn't work on the source emitter POP.


The Houdini textport is used to type in Hscirpt commands directly. To evaluate expressions, you need to use the echo command and encase your expression in back ticks for it to evaluate.

For example:

echo `sin($F*3) * ch(“/obj/geo1/point1/ty”)`

or

echo `rand(chs(“/obj/geo1/point1/group”)`

Attachments:
trail_curves_from_sources.jpg (114.9 KB)
trail_curves_from_sources.hip (1.3 MB)

There's at least one school like the old school!
User Avatar
Member
13 posts
Joined: Sept. 2012
Offline
jeff
Houdini doesn't think. It just does what you tell it to. It's just nodes working on geometry modified by other nodes is all. There is no magic in there. The magic lives in you (oh my now I sound like Celine Dion). No hidden operators to stupify the workflow.

Hey Jeff. Sorry for the delay. Got stuck in other things these days. First of all, thanks for the reply and the sample file. I took a look, and had further questions, if you don't mind.
First, what I meant by the above, is that Houdini has some quite specific requirements around how data needs to be fed to it so I can arrive to the result I need. These requirements are different to how I need to feed data to other DCC tools. That's basically what I meant by “learning how it thinks”.

Now, for the rest…

jeff
Posting a hip file could have shrunk your above post to three or four sentences. Next time just post your hip file so we can see what you are up to. Hip files are completely self-documenting. Add Notes in networks where appropriate to clarify issues.

See the attached hip file.

Thanks for the suggestion. Following your instructions, I've attached a file to this post that will probably offer a lot more visibility on what I'm trying to achieve than my attempts at explaining it.

jeff
Skinning particles is generally done by first creating the “parent” attribute on the source and followed with a Split POP generating a fixed number of splits. Then use an Add SOP to build primitives by attribute. This workflow supports changing topology (I even use a fuse to consolidate co-incident points), varying source emission, whatever.

I'll give this a go and see where it takes me.

—-
jeff
Modulo is represented by % which is common in many programming languages.

Nice. I'll try using it and see if I run into any problems. Thanks.

jeff
Source POPs are limited to what local attributes it can access. See the Help for that Operator. Actually that is the first place to look when wondering about a node: the node help. Since it is creating the points, it doesn't have a filter to read in those attributes. Just add a POP after to do the filtering. POPs are creating a single rule set that is applied to the point accel, v and P.
That is why $ID doesn't work on the source emitter POP.

Here's where I got a bit lost. I'm not quite sure how to do this in the file I've attached. If you could take a look and explain a bit, I'd sincerely appreciate it.

jeff
The Houdini textport is used to type in Hscirpt commands directly. To evaluate expressions, you need to use the echo command and encase your expression in back ticks for it to evaluate.

For example:

echo `sin($F*3) * ch(“/obj/geo1/point1/ty”)`

or

echo `rand(chs(“/obj/geo1/point1/group”)`

Ah, well, that helps a lot! Thanks! I'll keep this handy in my notes. Thanks a lot Jeff!

Attachments:
particle_trails_test.hipnc (96.3 KB)

User Avatar
Member
13 posts
Joined: Sept. 2012
Offline
I think I'm starting to understand how to use a POP Network to achieve what you explained. I'll try it out later…
User Avatar
Member
13 posts
Joined: Sept. 2012
Offline
Well, I've been able to solve some problems, and introduce others. I'll keep banging on this…
  • Quick Links