Generalize Dual Contouring to run on any domain.

This commit is contained in:
Daniel Zint 2022-09-19 14:36:52 +02:00
parent f6cdcb4441
commit 2ff88cb02c
2 changed files with 16 additions and 16 deletions

View File

@ -53,20 +53,20 @@ void dual_contouring(const Domain_& domain, const typename Domain_::FT iso_value
// static_assert(Domain_::CELL_TYPE & ANY_CELL); // static_assert(Domain_::CELL_TYPE & ANY_CELL);
internal::Dual_contouring_position_functor<Domain_, Positioning> pos_func(domain, iso_value, positioning); internal::Dual_contouring_vertex_positioning<Domain_, Positioning> pos_func(domain, iso_value, positioning);
domain.iterate_cells(pos_func, Concurrency_tag()); domain.iterate_cells(pos_func, Concurrency_tag());
internal::Dual_contouring_quads_functor<Domain_> quad_func(domain, iso_value); internal::Dual_contouring_face_generation<Domain_> face_generation(domain, iso_value);
domain.iterate_edges(quad_func, Concurrency_tag()); domain.iterate_edges(face_generation, Concurrency_tag());
// write points and quads in ranges // write points and faces in ranges
points.resize(pos_func.points_counter); points.resize(pos_func.points_counter);
for (const auto& vtop : pos_func.map_voxel_to_point) { for (const auto& vtop : pos_func.map_voxel_to_point) {
points[pos_func.map_voxel_to_point_id[vtop.first]] = vtop.second; points[pos_func.map_voxel_to_point_id[vtop.first]] = vtop.second;
} }
polygons.reserve(quad_func.quads.size()); polygons.reserve(face_generation.faces.size());
for (const auto& q : quad_func.quads) { for (const auto& q : face_generation.faces) {
std::vector<std::size_t> vertex_ids; std::vector<std::size_t> vertex_ids;
for (const auto& v_id : q.second) { for (const auto& v_id : q.second) {
if (pos_func.map_voxel_to_point_id.count(v_id) > 0) { if (pos_func.map_voxel_to_point_id.count(v_id) > 0) {

View File

@ -268,7 +268,7 @@ public:
} // namespace Positioning } // namespace Positioning
template <class Domain_, class Positioning_> template <class Domain_, class Positioning_>
class Dual_contouring_position_functor { class Dual_contouring_vertex_positioning {
private: private:
typedef Domain_ Domain; typedef Domain_ Domain;
typedef Positioning_ Positioning; typedef Positioning_ Positioning;
@ -278,7 +278,7 @@ private:
typedef typename Domain::Cell_handle Cell_handle; typedef typename Domain::Cell_handle Cell_handle;
public: public:
Dual_contouring_position_functor(const Domain& domain, FT iso_value, const Positioning& positioning) Dual_contouring_vertex_positioning(const Domain& domain, FT iso_value, const Positioning& positioning)
: domain(domain), iso_value(iso_value), positioning(positioning), points_counter(0) {} : domain(domain), iso_value(iso_value), positioning(positioning), points_counter(0) {}
void operator()(const Cell_handle& v) { void operator()(const Cell_handle& v) {
@ -305,7 +305,7 @@ public:
}; };
template <class Domain_> template <class Domain_>
class Dual_contouring_quads_functor { class Dual_contouring_face_generation {
private: private:
typedef Domain_ Domain; typedef Domain_ Domain;
@ -314,30 +314,30 @@ private:
typedef typename Domain_::Cell_handle Cell_handle; typedef typename Domain_::Cell_handle Cell_handle;
public: public:
Dual_contouring_quads_functor(const Domain& domain, FT iso_value) : domain(domain), iso_value(iso_value) {} Dual_contouring_face_generation(const Domain& domain, FT iso_value) : domain(domain), iso_value(iso_value) {}
void operator()(const Edge_handle& e) { void operator()(const Edge_handle& e) {
// save all quads // save all faces
const auto& vertices = domain.edge_vertices(e); const auto& vertices = domain.edge_vertices(e);
const FT s0 = domain.value(vertices[0]); const FT s0 = domain.value(vertices[0]);
const FT s1 = domain.value(vertices[1]); const FT s1 = domain.value(vertices[1]);
if (s0 <= iso_value && s1 > iso_value) { if (s0 <= iso_value && s1 > iso_value) {
const auto voxels = domain.cells_incident_to_edge(e); const auto& voxels = domain.cells_incident_to_edge(e);
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
quads[e] = {voxels[0], voxels[1], voxels[2], voxels[3]}; faces[e].insert(faces[e].begin(), voxels.begin(), voxels.end());
} else if (s1 <= iso_value && s0 > iso_value) { } else if (s1 <= iso_value && s0 > iso_value) {
const auto voxels = domain.cells_incident_to_edge(e); const auto& voxels = domain.cells_incident_to_edge(e);
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
quads[e] = {voxels[0], voxels[3], voxels[2], voxels[1]}; faces[e].insert(faces[e].begin(), voxels.rbegin(), voxels.rend());
} }
} }
// private: // private:
std::map<Edge_handle, std::array<Cell_handle, 4>> quads; std::map<Edge_handle, std::vector<Cell_handle>> faces;
const Domain& domain; const Domain& domain;
FT iso_value; FT iso_value;