OpenVDB - create_levelset_volume
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// V type must provide "V::aabb()" and "V::distance(const glm::vec3&)" methods | |
template <typename GridType, typename V> | |
typename GridType::Ptr | |
create_levelset_volume(const V& kVolume, const float kVoxelSize, | |
const float kHalfWidth) | |
{ | |
using ValueType = typename GridType::ValueType; | |
// GridType::ValueType is required to be a floating-point scalar. | |
BOOST_STATIC_ASSERT( | |
boost::is_floating_point<typename GridType::ValueType>::value); | |
if (kVoxelSize <= 0.f) | |
throw std::runtime_error("create_levelset_volume: " | |
"voxel size must be positive."); | |
if (kHalfWidth <= 1.f) | |
throw std::runtime_error("create_levelset_volume: " | |
"half-width must be larger than one."); | |
const float kInvVoxelSize = 1.f/kVoxelSize; | |
typename GridType::Ptr grid = | |
openvdb::createLevelSet<GridType>(kVoxelSize, kHalfWidth); | |
typename GridType::Accessor accessor = grid->getAccessor(); | |
// AABB could be openvdb::v3_0_0::math::BBox<openvdb::Vec3<float>> | |
AABB vaabb = kVolume.aabb(); | |
// expand = Dilation operation on the AABB using a cube with diameter | |
// equal to "kHalfWidth" as the structuring element. | |
vaabb.expand(kHalfWidth); | |
vaabb.min_ *= kInvVoxelSize; | |
vaabb.max_ *= kInvVoxelSize; | |
int imin = glm::floor(vaabb.min_.x); int imax = glm::ceil(vaabb.max_.x); | |
int jmin = glm::floor(vaabb.min_.y); int jmax = glm::ceil(vaabb.max_.y); | |
int kmin = glm::floor(vaabb.min_.z); int kmax = glm::ceil(vaabb.max_.z); | |
openvdb::Coord ijk; | |
int& i = ijk[0]; int& j = ijk[1]; int& k = ijk[2]; | |
int m = 1; | |
for (i = imin; i <= imax; ++i) { | |
for (j = jmin; j <= jmax; ++j) { | |
for (k = kmin; k <= kmax; k += m) { | |
m = 1; | |
ValueType v = kVolume.distance(glm::vec3(i,j,k)*kVoxelSize)*kInvVoxelSize; | |
ValueType d = glm::abs(v); | |
if (d < kHalfWidth) { | |
accessor.setValue(ijk, v); | |
} else { | |
m += glm::floor(d-kHalfWidth); | |
} | |
} | |
} | |
} | |
grid->signedFloodFill(); | |
return grid; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment