LePetitNick Posted December 15, 2014 Share Posted December 15, 2014 I'm writing a SOP node using the HDK for the first time and everything's been pretty cruisy so far, but, I've noticed that when switching collision methods between a volume SDF and a VDB SDF by getting the gradient pushing the points out by the SDF's negative value, the VDB calls are roughly 3-4 times slower than the same calls to a volume. I've optimised the code by forcing a bounds check first which seems to speed things up, (making the assumption that the SDFs are not inverted and only in the edge cases where the SDF bounds only intersect a small portion of the input geo) but still the VDB is substantially slower. Anyone have any trick to speed up these lookups? GU_Detail *sdfInput = new GU_Detail; if (inputGeo(1, context) != NULL) duplicateSource(1, context, sdfInput); ... const GEO_PrimVDB *vdb = NULL; const GEO_PrimVolume *vol = NULL; UT_BoundingBox sdfBBox; sdfBBox.makeInvalid(); if (sdfInput != NULL && doCollision(t)) { for (GA_Iterator it(sdfInput->getPrimitiveRange()); !it.atEnd(); it.advance()) { GEO_Primitive *prim = sdfInput->getGEOPrimitive(it.getOffset()); if(dynamic_cast<const GEO_PrimVDB *>(prim) != NULL) { vdb = dynamic_cast<GEO_PrimVDB *>(prim); vdb->getBBox(&sdfBBox); break; } else if (dynamic_cast<const GEO_PrimVolume *>(prim) != NULL) { vol = dynamic_cast<const GEO_PrimVolume *>(prim); vol->getBBox(&sdfBBox); break; } } } ... UT_Vector3 position; UT_Vector3 gradient; fpreal signDistance; GA_Offset ptOffset; GA_FOR_ALL_PTOFF(gdb, ptOffset) { position = gdb->getPos3(ptOffset); if (!sdfBBox.isInvalid() && sdfBBox.isInside(position)) { if (vdb != NULL) { signDistance = vdb->getValueF(position); if (signDistance < 0) { gradient = vdb->getGradient(position); gdb->setPos3(ptOffset, position - (gradient * signDistance)); } } else if (vol != NULL) { signDistance = vol->getValue(position); if (signDistance < 0) { gradient = vol->getGradient(position); gdb->setPos3(ptOffset, position - (gradient * signDistance)); } } } } If you compile the SOP, plug a vdb sdf into the second input, check the time, then feed the vdb sdf into a vdb convert first and then plug the volume into the 2nd input, you'll notice that the vdb sdf collisions take roughly 3-4 times longer to evaluate than the volume sdf collisions... Ideally I'd like to have the vdb run at least as fast as the volume, and ideally speed up both of them, a lot - as of now a deformer SOP which takes 0.3s to run on 100K points skipping the sdf collisions, takes upwards of 4s with volume collisions enabled, 13s with vdbs... Quote Link to comment Share on other sites More sharing options...
Syrux Posted December 15, 2014 Share Posted December 15, 2014 (edited) Check this code -> http://forums.odforce.net/topic/17811-openvdb-sdf-data-access/ Also UT_Vector3 is deprecated Edited December 15, 2014 by Syrux Quote Link to comment Share on other sites More sharing options...
malexander Posted December 16, 2014 Share Posted December 16, 2014 Volume primitives have a nice, regular voxel structure, which makes it very easy to access neighbouring voxels. VDBs have a tree that needs to be traversed for neighbours. While VDBs are more memory efficient and certainly faster if you operate on each individual voxel (because they are sparse have so much fewer voxels then Volume prims), you do pay more of a cost to look up a voxel. My guess is that this cost is what you're seeing. 1 Quote Link to comment Share on other sites More sharing options...
edward Posted December 16, 2014 Share Posted December 16, 2014 That sampling interface on GEO_PrimVDB is mainly for compatibility with regular volume code. It should also be much faster you do vdb->getGrid() and then use a ValueAccessor that is shared across multiple evaluations. See http://www.openvdb.org/documentation/doxygen/codeExamples.html#sModifyingGrids Quote Link to comment Share on other sites More sharing options...
LePetitNick Posted December 16, 2014 Author Share Posted December 16, 2014 Thanks Edward, that's exactly what I was looking for! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.