From 50e3887abe143714ffd4541865ac366db70c7c58 Mon Sep 17 00:00:00 2001 From: Janis Born Date: Wed, 11 Jan 2017 17:27:44 +0100 Subject: [PATCH] add Midpoint uniform subdivision scheme --- .../Tools/Subdivider/Uniform/MidpointT.hh | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh new file mode 100644 index 00000000..99875135 --- /dev/null +++ b/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include + +#include + +namespace OpenMesh { +namespace Subdivider { +namespace Uniform { + +template +class MidpointT : public SubdividerT +{ +public: + using real_t = RealType; + using mesh_t = MeshType; + using parent_t = SubdividerT; + + using parent_t::parent_t; + + const char* name() const { return "midpoint"; } + +protected: // SubdividerT interface + bool prepare(mesh_t& _m) override + { + return true; + } + + bool subdivide(mesh_t& _m, size_t _n, const bool _update_points = true) override + { + auto edge_midpoint = makePropertyManagerFromNew>(_m, "edge_midpoint"); + auto is_original_vertex = makePropertyManagerFromNew>(_m, "is_original_vertex"); + + for (size_t iteration = 0; iteration < _n; ++iteration) { + is_original_vertex.set_range(_m.vertices_begin(), _m.vertices_end(), true); + // Create vertices on edge midpoints + for (const auto& eh : _m.edges()) { + auto new_vh = _m.new_vertex(_m.calc_edge_midpoint(eh)); + edge_midpoint[eh] = new_vh; + is_original_vertex[new_vh] = false; + } + // Create new faces from original faces + for (const auto& fh : _m.faces()) { + std::vector new_corners; + for (const auto& eh : _m.fe_range(fh)) { + new_corners.push_back(edge_midpoint[eh]); + } + _m.add_face(new_corners); + } + // Create new faces from original vertices + for (const auto& vh : _m.vertices()) { + if (is_original_vertex[vh]) { + if (!_m.is_boundary(vh)) { + std::vector new_corners; + for (const auto& eh : _m.ve_range(vh)) { + new_corners.push_back(edge_midpoint[eh]); + } + std::reverse(begin(new_corners), end(new_corners)); + _m.add_face(new_corners); + } + } + } + for (const auto& vh : _m.vertices()) { + if (is_original_vertex[vh]) { + _m.delete_vertex(vh); + } + } + } + return true; + } + + bool cleanup(mesh_t& _m) override + { + return true; + } +}; + +} // namespace Uniform +} // namespace Subdivider +} // namespace OpenMesh