Getting the points in a primitive group via HDK

   7721   5   3
User Avatar
Member
2 posts
Joined:
Offline
Hi, I am trying to get a list of all of the points in a primitive group with the HDK.

Currently, I looping through all of the group's primitives, getting its vertices' points, and putting them in a list if they don't already match points in my list, as such:


FOR_ALL_GROUP_PRIMITIVES(gdp, primGrp, prim)
{
for (int ii=0; ii < prim->getVertexCount(); ii++)
{
GEO_Point *pt = prim->getVertex(ii).getPt();
addPtIfItDoesntExist(pt, list);
}
}


This is quite slow. With models of 100,000 polygons or more this can take 15 minutes or so. Is there is a better method for getting the points associated with a primitive group?
User Avatar
Member
1908 posts
Joined: 11月 2006
Offline
I did something similar to this a little while ago. There isn't a simple and quick solution but there are some things you can do depending on what you want to do.

One idea would be to create a new GU_Detail based on each primitive group. You would then have a new detail with just all the points that are in that group.

You could also do what I did (upon suggestion from Mark Elendt) and use a UT_BitArray that is the same size (number of points in the detail) to keep track of which points are in the group. Basically loop through all the prims and their verts and set the bit at each point number. This way you don't have to do any expensive list sorting or duplicate removal.


UT_BitArray pmask(gdp->points().entries());
FOR_ALL_GROUP_PRIMITIVES(gdp, primgroup, prim)
{
for (unsigned vert_idx=0; vert_idx < prim->getVertexCount(); vert_idx++)
{
// Set the bit corresponding to the point number of the point
// for this vertex.
pmask.setBit(prim->getVertex(vert_idx).getPt()->getNum(), true);
}
}

// For each point we check to see if its corresponding bit was set. If it was then we do something.
FOR_ALL_GPOINTS(gdp, ppt)
{
if (pmask.getBit(ppt->getNum()))
// do something
}


Performance is pretty good. In my test I get ~ 0.8sec for computing the average point position for 1mil points in a group of 998k polygons.

There was something else I had wanted to try but didn't because my GU_Detail was const but I can't remember what it was.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
スタッフ
1072 posts
Joined: 7月 2005
Offline
The easiest way is to do something like:


GEO_Closure closure(*gdp);

GB_PointGroup *ptgroup = closure.getPointClosure(*primgroup);


This approach does require a non-const gdp, as it needs to create a new point group.
User Avatar
Member
2 posts
Joined:
Offline
Awesome! Thanks for the quick replies. That was exactly what I was hoping for!

I also have a const gdp, so I can't use the GEO_Closure, but I'm glad that I know about it now.

I feel silly for not thinking of the bitmask myself. I was hoping perhaps Houdini was secretly storing something like that somewhere itself and I just hadn't found it, but this should still be much faster than my method. Should bring me down from N-squared time to N. I'll give it a whirl today!
User Avatar
Member
46 posts
Joined: 1月 2012
Offline
Hi all
I'm trying the code:

GEO_Closure closure(*gdp);

GB_PointGroup *ptgroup = closure.getPointClosure(*primgroup);


can't find the way to convert “const GU_Detai” to “non-const gdp”,
have any body can share some of example about this?

really really thank you a lot
User Avatar
Member
1743 posts
Joined: 3月 2012
Offline
wei750830

GEO_Closure closure(*gdp);

GB_PointGroup *ptgroup = closure.getPointClosure(*primgroup);

Hi! It's a bit sad that GEO_Closure requires a non-const GEO_Detail reference, but we didn't have detached groups at the time it was created, so it had to create them on the detail.

Let's work around this by making a detached group, if it's actually a GA_PointGroup (GB doesn't exist anymore) that you need. Note that if you add or remove points, the capacity of the detached group will not be updated with the detail's points anymore, so if you need that behaviour, you should change the calling code and signature to give you a non-const detail instead. Assuming we're going with a detached group, the following should work:

GA_PointGroup *ptgroup = gdp->newDetachedPointGroup();
GEO_Primitive *prim;
GA_FOR_ALL_GROUP_PRIMITIVES(gdp, primgroup, prim)
prim->addPointRefToGroup(*ptgroup);

It's basically what GEO_Closure::getPointClosure does, only with a detached group. NOTE: To delete ptgroup when you're done with it, unlike with regular groups, you must call delete on it, because the detail doesn't keep track of it:

delete ptgroup;

Hopefully that works!
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
  • Quick Links