Recursive pop splitting?

   15993   18   1
User Avatar
Member
36 posts
Joined: Aug. 2006
Offline
Hello,

I'm trying to do something like this: Start with one particle, then every 10 frames, birth a new particle off every even-numbered particle, like so:

Frame —— Particle Numbers (a->b means b is birthed from a)

0 ————- 0
10 ———— 0->1
20 ———— 0->2, 1
30 ———— 0->3, 1, 2->4


The key thing here is that the birthed particles later become the birthing particles. I've tried to acheive this with a split pop but there seems to be an impassible boundary between birthing and birthed particles, ie. particles birthed by the split pop cannot be fed back into the same split pop to birth more particles. I know they could be fed into ANOTHER split pop, but I really want a loop type structure with indefinite levels of recursion. Is this kind of recursive data flow possible in houdini? I am definitely a novice, so please feel free to try to educate me on any basic houdini paradigm that would make this problem (and preferably its resolution) more clear to me.

Thanks in advance,

Jeremy.
User Avatar
Member
4256 posts
Joined: July 2005
Offline
Houdini loves recursion. Two Group POPs should do the trick.

Attachments:
SplitEvens.hip (44.8 KB)

if(coffees<2,round(float),float)
User Avatar
Member
36 posts
Joined: Aug. 2006
Offline
Bloody awesome. Thanks for the .hip file. Yes, I figured recursion would be right up houdini's alley, just couldn't get the logistics right.

Let me see if I fully understand how this works. It seems that you have to put particles in a group in order for them to be considered in the next iteration, and make sure “preserve group” is enabled in group-creating pops so that they append to groups made in previous iterations instead of wiping the slate each time. In your example Wolfwood, I noticed that it was neccessary to turn on “preserve goup” in the group1 and split1 pops, although it was not necessary in the group2 pop. I'm guessing this is because in group2, SplitEvens is immediately unioned with EvenParts, which is in turn preserved by group1.

I've attempted to attach a further simplified version of your example - this time, EVERY particle splits every 10 frames. I notice that if you don't specify a Source Group in the split1 pop (enter “” instead of “splitme”), only the original location1-created particle gets split, not those created by previous iterations of the split1 pop. This was a little counter-intuitive to me, as I assumed leaving Source Group blank would make the pop apply to all particles, whereas specifying a group would apply to a subset. However, it appears groups aren't just subsets, but also have magical trans-frame powers. This is what prompted my above theory that particles MUST be in a group to be fed back into the chain recursively in subsequent frames.

Does this make sense? Again, any education much appreciated. And thanks again for the .hip!

Jeremy.



EDIT:

Oops, looks like I can't uplad .hipnc files. Well, the same principle would be demonstrated by voiding the Source Group field in Wolfwood's example, but just in case you're wondering, here's an opscript for a geo node that contains my pop net:


RE-EDIT:

Removed lengthy + useless opscript.
Edited by - Aug. 23, 2006 12:30:04
User Avatar
Member
4256 posts
Joined: July 2005
Offline
You're right that you can't upload hipncs, (bad SESI bad), you can just zip the file up, then upload that. (Forums support .zips). Posting scripts straight is bit rough since it does line breaks and makes it hard, (impossible), to copy and paste. You can protect it by putting
around it.


It was not necessary in the group2 pop. I'm guessing this is because in group2, SplitEvens is immediately unioned with EvenParts, which is in turn preserved by group1.

Indeed. You actually don't need that last Group SOP. All the grouping can take place in group1. POPs themselves are recursive. The POP network's output of each frame is the next frame's input. The preserve group means append particles to the already existing group. If preserve group is turned off then it replaces the old group.
Edited by - Aug. 22, 2006 16:20:11

Attachments:
splitevens.hip (43.0 KB)

if(coffees<2,round(float),float)
User Avatar
Member
36 posts
Joined: Aug. 2006
Offline
Cool, here's the zip.

Attachments:
recursiveSplit.zip (20.2 KB)

User Avatar
Member
4256 posts
Joined: July 2005
Offline
Another example.

Also, I did some editting of my previous post after you had posted, so it might be worth rereading.
Edited by - Aug. 22, 2006 16:23:49

Attachments:
splitevens.hip (48.1 KB)

if(coffees<2,round(float),float)
User Avatar
Member
36 posts
Joined: Aug. 2006
Offline
Cool, here's the zip.

Attachments:
recursiveSplit.zip (20.2 KB)

User Avatar
Member
4256 posts
Joined: July 2005
Offline
If you want all the particles to split every 10 frames you just need two POPs, the location and the split. Just make sure you define a preserved group for both the Location and the Split. Then in the Source Group for the Split POP enter in both group names.

By default particles birthed from the Split POP will only birth on particles generated during the current iteration. To override this you can use Groups. A fun test is to take the above setup (2 POPs, and apply a 2nd Split POP.)
if(coffees<2,round(float),float)
User Avatar
Staff
1072 posts
Joined: July 2005
Offline
It's worth noting that this only works by exploiting the fact that POPs do not verify that the particles in source groups originate in the proper input stream.

With that warning, you can probably get away with eliminating the named groups entirely, and just specify 0-$NPT:2 (to split even numbered particles) or 0-$NPT (to split all particles) as the Source Group to the split POP.
User Avatar
Member
7714 posts
Joined: July 2005
Offline
Maybe it would be better if emcjagger's post got all the opscript output removed? BTW, I prefer “iterative” rather than “recursive” in this case but we're splitting hairs.
User Avatar
Member
36 posts
Joined: Aug. 2006
Offline
Wolfwood
By default particles birthed from the Split POP will only birth on particles generated during the current iteration. To override this you can use Groups.

Ondrej
It's worth noting that this only works by exploiting the fact that POPs do not verify that the particles in source groups originate in the proper input stream.

Thanks again for the feedback folks. So, to clarify, is this property of group persistance across iterations a deliberate, designed aspect of houdini particles (as implied by Wolfwood's “By default” comment) or more of a buggy loophole that isn't stable and could be “fixed” in future versions (as implied by Ondrej's “do not verify…proper input stream” comment)? Should I rely on + design around this behaviour?

Jeremy.

ps. edward: opscript removed, terminology adjusted.
User Avatar
Staff
1072 posts
Joined: July 2005
Offline
emcjagger
So, to clarify, is this property of group persistance across iterations a deliberate, designed aspect of houdini particles (as implied by Wolfwood's “By default” comment) or more of a buggy loophole that isn't stable and could be “fixed” in future versions (as implied by Ondrej's “do not verify…proper input stream” comment)? Should I rely on + design around this behaviour?

I don't believe it to be a deliberate part of the design, but more of an unforeseen loophole. That being said, I've been aware of it for quite a few versions, but have been in no real hurry to “fix” it, and don't really foresee that changing any time in the near future.
User Avatar
Member
4256 posts
Joined: July 2005
Offline
Forgive me, (my reading comprehension skills haven't absorbed enough coffee yet), but which example above uses the unforeseen loophole?
if(coffees<2,round(float),float)
User Avatar
Staff
1072 posts
Joined: July 2005
Offline
Any example using groups to process particles that would not normally be processed by that operator. The group field was intended to specify a subset of the particles a given operator would process without a group specified, not a superset.
User Avatar
Member
4256 posts
Joined: July 2005
Offline
Ondrej
Any example using groups to process particles that would not normally be processed by that operator. The group field was intended to specify a subset of the particles a given operator would process without a group specified, not a superset.

And all this time I thought that was a feature.

So the *proper* way to setup the above examples would be to use a Collect POP and a Group POP after that?

Attachments:
splitevens.hip (44.0 KB)

if(coffees<2,round(float),float)
User Avatar
Staff
1072 posts
Joined: July 2005
Offline
No, even in that example the split POP is using the group to gain access to particles it wouldn't normally be able to touch. Without exploiting this little loophole, there is no way that I can see to get recursive splitting of this sort.

A loophole in the rigid laws of POPs or a feature? Just semantics at this point since I don't foresee this changing.
User Avatar
Member
4256 posts
Joined: July 2005
Offline
Side Effects indeed.
if(coffees<2,round(float),float)
User Avatar
Member
36 posts
Joined: Aug. 2006
Offline
This is beginning to make sense. Thanks for the help everyone.
User Avatar
Member
4256 posts
Joined: July 2005
Offline
yea yea, its ‘thread necromancy’ but an additional example is always useful.

Attachments:
splitCollisions.hip (110.3 KB)

if(coffees<2,round(float),float)
  • Quick Links