Jump to content

OpenVDB SDF data access


Recommended Posts

I am trying to access the data in a VDB sdf volume container that I use as a 3rd input in my node.

I managed to install the openvdb headers and everything seems to compile just fine.

All I'd like to do is basically access the distance and gradient values in the vdb sdf, given a world space position.

I found this beautiful method which seems to address the gradient question...

UT_Vector3 GEO_PrimVDB::getGradient ( const UT_Vector3 & pos ) const

And this is the code snippet I am using:


GU_Detail *sdfInput = new GU_Detail;
duplicateSource(2, context,sdfInput);

GU_PrimVDB myVDB(sdfInput,0);

UT_Vector3 samplepos(1.0,0.0,0.0);
UT_Vector3 gradient;
gradient=myVDB.getGradient(samplepos); // <--- CRASH
[/CODE]

... but when I try to use it , Houdini crashes (it crashes only on the line where I use getGradient method, it doesn't crash when I define *myVDB)

I couldn't find the method to access the distance value by the way.

I am pretty sure I am doing something terribly wrong cause of my limited c++ knowledge :)

Can someone help me to correct the above code snippet and add the method to access the 'distance' data ?

Edited by mrWolf
Link to comment
Share on other sites

You need to get the VDB primitive from sdfInput, not create a brand new VDB whose owner is sdfInput. You should loop through the primitives in sdfInput() and find the VDB primitive to use. ie. loop through the primitives in sdfInput, and use the first one which returns non-NULL for dynamic_cast<const GEO_PrimVDB *>(prim).

Link to comment
Share on other sites

Edward,

it worked perfectly,

thank you a lot for your help !

This is the code I'm using to access OpenVDB SDF:


UT_Vector3 samplepos(1.0,0.0,0.0); // just a random vector
UT_Vector3 gradient;
float signdistance;

for (int np=0; np < numprims; np++)
{
const GEO_Primitive *prim = gdp->primitives().entry(np);
const GEO_PrimVDB *vdb = dynamic_cast<const GEO_PrimVDB *>(prim);
gradient=vdb->getGradient(samplepos);
signdistance=vdb->getValueF(samplepos);

cout << "distance:" << signdistance << "\n";
cout << "gradient:" << gradient[0] << " " << gradient[1] << " " << gradient[2] << "\n";
}
[/CODE]

p.s.

I have an additional little question:

what is the method to access the GEO_Primitive starting from GA_Offset ?

You need to get the VDB primitive from sdfInput, not create a brand new VDB whose owner is sdfInput. You should loop through the primitives in sdfInput() and find the VDB primitive to use. ie. loop through the primitives in sdfInput, and use the first one which returns non-NULL for dynamic_cast<const GEO_PrimVDB *>(prim).

Edited by mrWolf
Link to comment
Share on other sites

worked like a charm.

I've added the null check too.

Thank you a lot Edward, i'm learning a lot here !

You can do: prim = gdp->getGEOPrimitive(offset);

To be safe, you should check if vdb is NULL, ie. in your loop after the dynamic_cast<>():

if (vdb == NULL)

continue;

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