Jump to content

VEX: 'reset' a pciterate loop


nanocell

Recommended Posts

Greetings,

I am using an algorithm to process points from a point cloud that requires me to iterate over all the points twice (unfortunately). So, this begs the question: What is the proper way of resetting or restarting a pciterate loop? Do I have to close the handle (pcclose), and reopen the point again or is there some other way to simply loop again without having to pcclose/pcopen again? (To call the pcopen twice seems...unnecessary.)

Regards,

Van Aarde.

Link to comment
Share on other sites

I am using an algorithm to process points from a point cloud that requires me to iterate over all the points twice (unfortunately). So, this begs the question: What is the proper way of resetting or restarting a pciterate loop? Do I have to close the handle (pcclose), and reopen the point again or is there some other way to simply loop again without having to pcclose/pcopen again? (To call the pcopen twice seems...unnecessary.)

Yes, you should be able to iterate multiple times. However, you can't nest pciterate()'s on the same handle.

This won't work:

int handle = pcopen(...);
while(pciterate(handle)) {
   while(pchandle(handle)) {
   }
}
pcclose(handle);

But this should:

int handle1 = pcopen(...);
int handle2 = pcopen(...);
while(pciterate(handle1)) {
   while(pciterate(handle2)) {
   }
   pcclose(handle2);
}
pcclose(handle1);

Assuming that you need to nest them, of course. That is, assuming that your algorithm requires:

FOR_EVERY_POINT {
   FOR_EVERY_POINT {
   }
}

If, on the other hand, you just need separate "passes" over the data:

// set up parms for pass 1
FOR_EVERY_POINT { ... }
// set up parms for pass 2
FOR_EVERY_POINT { ... }

then you're probably better off encapsulating a pass as a function:

int doPass(string pcfile, /*... pass parameters*/) {
   int handle = pcopen(pcfile,....);
   if(handle<0) return FAILURE;
   while(pciterate(handle)) {
	  //do stuff
   }
   pcclose(handle);
   return SUCCESS;
}
surface some_shader( string pcfile=""; /*... other shader parms*/) {
   if(pcfile!="") {
	  // set up parms for pass 1
	  int status = doPass(pcfile,/*...pass 1 parms*/);
	  if(status) {
		 // set up parms for pass 2
		 status = doPass(pcfile,/*... pass 2 parms*/);
	  }
   }
}

Actually, you can do the same thing (function hiding the pcopen/pcclose) for the nested case... it just keeps things a little cleaner I think.

BTW, how's that project of yours going?

I haven't forgotten -- I'll post something on persistent storage as soon as I get a chance; promise. :)

Cheers!

Link to comment
Share on other sites

Hey Mario!

Thanks for your thorough reply!

The usage that I had in mind was the sequential iteration, on the same handle (or "passes" as you call them). Nested iteration...on the same handle?! Never! ;)

Your nested example peaked my interest:

int handle1 = pcopen(...);

int handle2 = pcopen(...);

while(pciterate(handle1)) {

while(pciterate(handle2)) {

}

pcclose(handle2);

}

pcclose(handle1);

Should that pcclose(handle2) function be inside the nested loop? I would think that the handle is invalidated (and memory is freed) upon calling the pcclose function, i.e., it cannot be used again. For me, this would make more sense:

int handle1 = pcopen(...);
int handle2 = pcopen(...);
while(pciterate(handle1)) {
   while(pciterate(handle2)) {
   }
}
pcclose(handle2);
pcclose(handle1);

In which case the iteration over handle2 would just be repeated.

At the hand of an example: Say we have a cluster of points. In the first pass, calclulate the center of the cluster. The second pass performs calculations based on how far each point is away from the center of the cluster, e.g.

int handle = pcopen(...)
while (handle)  //pass 1
{
  //calculate center
}
// should a pcclose() be in here??
while(handle) //pass 2
{
  //perform some point weighting based on distance from cluster center.
  //or do something else that sound really impressive.
}
pcclose(handle)  //invalidate handle (?) and release memory.

So, I guess my question is: Once an iterator reached its end, or completed its walk over the data, would the iterater start at the beginning again when doing another while( pciterate() ) loop or would it simply skip the second loop (since the iterator already reached the end of the list)?

The reason I haven't tested this is simply because it was not mission critical. It was merely a thought on optimization that I entertained.

BTW, how's that project of yours going?

I haven't forgotten -- I'll post something on persistent storage as soon as I get a chance; promise.

The Caustics Mapping in Houdini project is on the back burner for now (for the interested reader: http://graphics.cs.ucf.edu/caustics/ ). There are some more approaches to this that I want to explore at a later stage. So many things to implement! I have to make a list!!

I was working on a particle-driven foam shader for the past week (which triggered the point cloud questions). It proved to be quite a challenge and is still far from finished (the noise needs much work)! The next evolution of the foam shader will be using some ideas taken from the interactive foam implementation in Surfs Up. Can't wait!

Edited by nanocell
Link to comment
Share on other sites

Should that pcclose(handle2) function be inside the nested loop?

Ooops. Yup. Sorry about that.

So, I guess my question is: Once an iterator reached its end, or completed its walk over the data, would the iterater start at the beginning again when doing another while( pciterate() ) loop or would it simply skip the second loop (since the iterator already reached the end of the list)?

Right. Well, I think the answer is no, I believe you need to call pcopen() again, even if it's with the exact same parameters (whether VEX would recognize this situation and simply rewind the iterator is an open question), though I confess I haven't actually tested the behavior it you attempted to run pciterate() twice on the same handle... worth a test.

On the other hand, if all that the first loop is doing is computing a centroid, maybe you can pre-compute that bit in SOPs and stash it in an attribute?

Cheers.

Link to comment
Share on other sites

I did a bunch of testing over the weekend and it looks like every time pciterate is invoked it starts at the beginning of the points *unless* its being invoked inside of a loop.

Assuming there should be 10 iterations

So

int iterations = 0;

success = pciterate(handle);

success = pciterate(handle);

success = pciterate(handle);

while(pciterate(handle)) {

iterations += 1;

}

printf("iterations: %g\n",iterations);

is the same as

int iterations = 0;

while(pciterate(handle)) {

iterations += 1;

}

printf("iterations: %g\n",iterations);

int iterations = 0;

while(pciterate(handle)) {

iterations += 1;

if ( iterations > 5 )

break;

}

iterations = 0;

while(pciterate(handle)) {

iterations += 1;

}

printf("iterations: %g\n",iterations);

In all these cases iterations prints 10.

Edited by Wolfwood
Link to comment
Share on other sites

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