| 56 | //! Calculate the worldspace bounds - 0.5 padding required to include the full volume and not the bound of the voxel centres. |
| 57 | template<typename T> |
| 58 | Imath::Box<Imath::Vec3<T> > worldBound( const openvdb::GridBase *grid, float padding = 0.50f ) |
| 59 | { |
| 60 | openvdb::CoordBBox vdbBbox; |
| 61 | try |
| 62 | { |
| 63 | vdbBbox.min() = openvdb::Coord( grid->metaValue<openvdb::Vec3i>( grid->META_FILE_BBOX_MIN ) ); |
| 64 | vdbBbox.max() = openvdb::Coord( grid->metaValue<openvdb::Vec3i>( grid->META_FILE_BBOX_MAX ) ); |
| 65 | } |
| 66 | catch( ... ) |
| 67 | { |
| 68 | // If we don't have metadata available, then hopefully it's because the vdb was freshly created and |
| 69 | // hasn't been saved to file yet, which should mean it's fully loaded, and we can call |
| 70 | // evalActiveVoxelBoundingBox. |
| 71 | // \todo : Can we guarantee that every VDB either is loaded, or has metadata? |
| 72 | vdbBbox = grid->evalActiveVoxelBoundingBox(); |
| 73 | } |
| 74 | |
| 75 | openvdb::Vec3d offset = openvdb::Vec3d( padding ); |
| 76 | openvdb::BBoxd indexBounds = openvdb::BBoxd( vdbBbox.min() - offset, vdbBbox.max() + offset ); |
| 77 | openvdb::BBoxd worldBounds = grid->transform().indexToWorld( indexBounds ); |
| 78 | openvdb::Vec3d minBB = worldBounds.min(); |
| 79 | openvdb::Vec3d maxBB = worldBounds.max(); |
| 80 | |
| 81 | return Imath::Box<Imath::Vec3<T> >( Imath::Vec3<T>( minBB[0], minBB[1], minBB[2] ), Imath::Vec3<T>( maxBB[0], maxBB[1], maxBB[2] ) ); |
| 82 | } |
| 83 | |
| 84 | |
| 85 | //! allow hashing via a io stream interface. |