diff --git a/Changes b/Changes index 0a59b6bd52..fdfdc932f1 100644 --- a/Changes +++ b/Changes @@ -1,10 +1,16 @@ 10.5.x.x (relative to 10.5.15.1) ======== +Fixes +----- + +- VDBObject : Fixed worldBound() result when bbox metadata not already present. + API --- - SConstruct : Install "private" headers. +- VDBObject : Marked metadata() as deprecated 10.5.15.1 (relative to 10.5.15.0) ========= diff --git a/include/IECoreVDB/VDBObject.h b/include/IECoreVDB/VDBObject.h index ea2f7eb650..b16efc8290 100644 --- a/include/IECoreVDB/VDBObject.h +++ b/include/IECoreVDB/VDBObject.h @@ -88,6 +88,12 @@ class IECOREVDB_API VDBObject : public IECoreScene::VisibleRenderable Imath::Box3f bound() const override; void render( IECoreScene::Renderer *renderer ) const override; + // \deprecated + // Not threadsafe ( it computes statistics if not present and stores them on the grids ). + // Instead, use the VDB api, for example: + // findGrid( name )->beginMeta() to iterate the metadata, + // or + // findGrid( name )->evalActiveVoxelBoundingBox() or activeVoxelCount() to compute statistics IECore::CompoundObjectPtr metadata( const std::string &name ); //! Are the grids in this VDBObject unmodified from the vdb file in filename? diff --git a/src/IECoreVDB/VDBObject.cpp b/src/IECoreVDB/VDBObject.cpp index 8a3d8244e0..41b09d6328 100644 --- a/src/IECoreVDB/VDBObject.cpp +++ b/src/IECoreVDB/VDBObject.cpp @@ -57,11 +57,23 @@ namespace template Imath::Box > worldBound( const openvdb::GridBase *grid, float padding = 0.50f ) { - openvdb::Vec3i min = grid->metaValue( grid->META_FILE_BBOX_MIN ); - openvdb::Vec3i max = grid->metaValue( grid->META_FILE_BBOX_MAX ); + openvdb::CoordBBox vdbBbox; + try + { + vdbBbox.min() = openvdb::Coord( grid->metaValue( grid->META_FILE_BBOX_MIN ) ); + vdbBbox.max() = openvdb::Coord( grid->metaValue( grid->META_FILE_BBOX_MAX ) ); + } + catch( ... ) + { + // If we don't have metadata available, then hopefully it's because the vdb was freshly created and + // hasn't been saved to file yet, which should mean it's fully loaded, and we can call + // evalActiveVoxelBoundingBox. + // \todo : Can we guarantee that every VDB either is loaded, or has metadata? + vdbBbox = grid->evalActiveVoxelBoundingBox(); + } openvdb::Vec3d offset = openvdb::Vec3d( padding ); - openvdb::BBoxd indexBounds = openvdb::BBoxd( min - offset, max + offset ); + openvdb::BBoxd indexBounds = openvdb::BBoxd( vdbBbox.min() - offset, vdbBbox.max() + offset ); openvdb::BBoxd worldBounds = grid->transform().indexToWorld( indexBounds ); openvdb::Vec3d minBB = worldBounds.min(); openvdb::Vec3d maxBB = worldBounds.max();