Skip to content

Instantly share code, notes, and snippets.

@AllanHasegawa
Last active August 29, 2015 14:06
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save AllanHasegawa/532b83b6a84350402e64 to your computer and use it in GitHub Desktop.
OpenVDB - create_levelset_volume
// 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