Created
December 21, 2018 07:38
-
-
Save cgmb/6e0aabf45584a74b56114cd7405932d1 to your computer and use it in GitHub Desktop.
OpenVDB particles to mesh example
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
#include "opengl/extract_mesh.h" | |
#include "opengl/mesh.h" | |
#include <openvdb/openvdb.h> | |
#include <openvdb/tools/ParticlesToLevelSet.h> | |
#include <openvdb/tools/VolumeToMesh.h> | |
#include <openvdb/tools/LevelSetFilter.h> | |
static openvdb::Vec3R to_ovdb(const vec3f& p) { | |
return {p.x, p.y, p.z}; | |
} | |
static vec3f to_vec3f(const openvdb::Vec3s& p) { | |
return {p[0], p[1], p[2]}; | |
} | |
// An adaptor so OpenVDB can access my particle positions | |
class OvdbParticleList { | |
public: | |
using PosType = openvdb::Vec3R; | |
using value_type = openvdb::Vec3R; | |
explicit OvdbParticleList(absl::Span<const vec3f> positions) | |
: positions_(positions) { | |
} | |
size_t size() const { return positions_.size(); } | |
void getPos(size_t n, PosType& xyz) const { | |
xyz = to_ovdb(positions_[n]); | |
} | |
private: | |
const absl::Span<const vec3f> positions_; | |
}; | |
// transform container | |
static void to_vec_vec3f(std::vector<vec3f>& to, const std::vector<openvdb::Vec3s>& from) { | |
to.resize(from.size()); | |
std::transform(from.begin(), from.end(), to.begin(), to_vec3f); | |
} | |
// transform and flatten container | |
static void to_vec_4uint(std::vector<unsigned int>& to, const std::vector<openvdb::Vec4I>& from) { | |
to.resize(4*from.size()); | |
size_t i = 0; | |
for (const openvdb::Vec4I& qi : from) { | |
to[i++] = qi[0]; | |
to[i++] = qi[1]; | |
to[i++] = qi[2]; | |
to[i++] = qi[3]; | |
} | |
} | |
static QuadMesh create_mesh(const std::vector<openvdb::Vec3s>& vertexes, | |
const std::vector<openvdb::Vec4I>& indexes) { | |
QuadMesh m; | |
to_vec_vec3f(m.vertexes, vertexes); | |
to_vec_4uint(m.indexes, indexes); | |
return m; | |
} | |
QuadMesh extract_mesh(absl::Span<const vec3f> positions) { | |
// intialize openvdb | |
static bool is_initialized = false; | |
if (!is_initialized) { | |
openvdb::initialize(); | |
} | |
// generate our level set from our particles | |
constexpr float voxel_size = 1.f; | |
constexpr float half_width = 2.f; | |
openvdb::FloatGrid::Ptr levelset = openvdb::createLevelSet<openvdb::FloatGrid>(voxel_size, half_width); | |
openvdb::tools::ParticlesToLevelSet<openvdb::FloatGrid> raster(*levelset); | |
float radius = 2.f; | |
raster.setGrainSize(1); // passing 0 disables threading | |
OvdbParticleList particle_list(positions); | |
raster.rasterizeSpheres(particle_list, radius); | |
raster.finalize(); | |
// filter the level set | |
openvdb::tools::LevelSetFilter<openvdb::FloatGrid> filter(*levelset); | |
filter.dilate(1); | |
filter.gaussian(1); | |
filter.erode(1); | |
// turn our levelset into a polygonal mesh | |
constexpr double isovalue = 0; | |
std::vector<openvdb::Vec3s> vertexes; | |
std::vector<openvdb::Vec4I> quad_indexes; | |
/* | |
There's apparently an adaptive volumeToMesh in newer versions of openvdb, which could be interesting. | |
constexpr double adaptivity = 0; | |
constexpr bool relax_distorted_triangles = true; | |
std::vector<openvdb::Vec3I> triangle_indexes; | |
openvdb::tools::volumeToMesh(*levelset, vertexes, triangle_indexes, quad_indexes, isovalue, adaptivity, relax_distorted_trianges); | |
*/ | |
openvdb::tools::volumeToMesh(*levelset, vertexes, quad_indexes, isovalue); | |
return create_mesh(vertexes, quad_indexes); | |
} |
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
#pragma once | |
#include <absl/types/span.h> | |
#include "math/vec3f.h" | |
struct QuadMesh; | |
QuadMesh extract_mesh(absl::Span<const vec3f> positions); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment