Jump to content

point clouds and vex


Recommended Posts

Can someone fill me in on why the scheme in the attached file doesn't work?  Basically, I'm using a wrangle to do some point cloud searching.  I want to switch the searched geometry based on some attribute on the wrangle's input geo.  The vex for that looks like this:

float radius = ch("radius");
int npts = chi("numpts");

int handle;
if (@side > 0) {
    handle = pcopen(@OpInput2,"P",@P,radius,npts);
} else {
    handle = pcopen(@OpInput3,"P",@P,radius,npts);
}

v@Cd = pcimportbyidxv(handle,"Cd", 0);
i@num = pcnumfound(handle);

pcclose(handle);

I'm guessing that my implementation doesn't play nicely with the way that vex / point clouds parallelize, or something.  The result is that half of the points don't find any matched points at all (pcnumfound gives 0).

 

The attached file demonstrates it visually.  The code above (node "pc_broke") results in half of the points failing to find matches.  If I use the same search geo for both groups (node "pc_works"), then all points find matches.  And if I do it in two wrangles, each constrained to one group of points and one search geometry, I get the desired result (node "CORRECT").

 

Removing the pcclose() has no effect, btw.

pc_vex.hip

Edited by Mitch Deoudes
Link to comment
Share on other sites

I've experienced similar issues with pcopen(), however I'm not really sure what exactly is causing that

pcfind() approach seems to work though, so maybe you can use that instead

float radius = ch("radius");
int npts = chi("numpts");

int geo = @side > 0 ? 1 : 2;
int points[] = pcfind(geo,"P",@P,radius,npts);

v@Cd = point(geo, "Cd", points[0]);
i@num = len(points);
Link to comment
Share on other sites

Strange. Tomas's solution is neater of course, but it also works if you open both point clouds, and run your if statement on reading from the 2 open handles instead.

 

float radius = ch("radius");
int npts = chi("numpts");

int h1 = pcopen(1,"P",@P,radius,npts);
int h2 = pcopen(2,"P",@P,radius,npts);

if (@side > 0) {
    v@Cd = pcimportbyidxv(h1,"Cd", 0);
    i@num = pcnumfound(h1);
} else {
    v@Cd = pcimportbyidxv(h2,"Cd", 0);
    i@num = pcnumfound(h2);
}

pcclose(h1);
pcclose(h2);
Link to comment
Share on other sites

Interesting - thanks for the replies.  Is opening both clouds might be less efficient - or not, because they're "shared" between input points?  (This whole thing actually comes from inside a flip sim, which has a bunch of pcfilter()s and other stuff going on - so speed is a concern there, where it isn't in my little demo scene.)

 

Maybe someone with a bigger brain than mine can explain the difference between what's going on behind the scenes with pcfind() vs pcopen()?  My gut tells me there's an efficiency / parallelization issue there as well (pcfind doesn't require a matching pcclose, for instance), and possibly the same thing that allows the former to work where the latter fails.

 

Meantime, I'm just doing it with two Wrangles, group-constrained.  Which works and probably is efficient, but is a fair amount of duplicated code.

Link to comment
Share on other sites

Hi!

 

Just sample the handle inside your condition and all works!

float radius = ch("radius");
int npts = chi("numpts");

int handle;
if (@side > 0) {
    handle = pcopen(@OpInput2,"P",@P,radius,npts);
    v@Cd = pcimportbyidxv(handle,"Cd", 0);
    i@num = pcnumfound(handle);
} else {
    handle = pcopen(@OpInput3,"P",@P,radius,npts);
    v@Cd = pcimportbyidxv(handle,"Cd", 0);
    i@num = pcnumfound(handle);
}

pcclose(handle);
Edited by Pazuzu
Link to comment
Share on other sites

for a moment it felt like they are sharing oc-tree or something therefore using the same handle for more pointclouds would not work

but there is something more to it since following:

float radius = ch("radius");
int npts = chi("numpts");

int handle0 = pcopen(@OpInput2,"P",@P,radius,npts);
int handle1 = pcopen(@OpInput3,"P",@P,radius,npts);
int handles[] = array(handle0, handle1);

int i = i@side < 0;
int handle = handles[i];

v@Cd = pcimportbyidxv(handle,"Cd", 0);
pcclose(handle);

has 2 handles in an array called handles[]

i contains varying  0 and 1 based on the side, therefore handle = handles contains varying handle from array;

and yet pcimportbyidxv(handle,"Cd", 0); returns result from the same handle

 

but still changing single line to:

int handle = handles[0];

returns correctly result from that pointcloud

and int handle = handles[1]; from another, so the pointcloud handles are both stored in an array correctly and work when accessed directly, but not when accessed through varying variable

 

I'd be really curious what SideFx has to say to that, would be great to understand in detail

Link to comment
Share on other sites

Yeah - that's exactly the weird gut feeling I was getting about this issue, but couldn't put my finger on.  (btw - hi, tomas!)

 

I'll try cross-posting this to the sidefx forum, and see if anyone from sesi chimes in with a more detailed under-the-hood explanation.

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