Loading...
Searching...
No Matches
MidpointT.hh
#pragma once
#include <OpenMesh/Core/Mesh/BaseKernel.hh>
#include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
#include <OpenMesh/Core/Utils/PropertyManager.hh>
#include <algorithm>
namespace OpenMesh {
namespace Subdivider {
namespace Uniform {
template<typename MeshType, typename RealType = double>
class MidpointT : public SubdividerT<MeshType, RealType>
{
public:
typedef RealType real_t;
typedef MeshType mesh_t;
typedef SubdividerT<MeshType, RealType> parent_t;
// Inherited constructors
MidpointT() : parent_t() {}
MidpointT(mesh_t& _m) : parent_t(_m) {}
const char* name() const { return "midpoint"; }
protected: // SubdividerT interface
bool prepare(mesh_t& _m)
{
return true;
}
bool subdivide(mesh_t& _m, size_t _n, const bool _update_points = true)
{
_m.request_halfedge_status();
_m.request_edge_status();
_m.request_vertex_status();
_m.request_face_status();
PropertyManager<EPropHandleT<typename mesh_t::VertexHandle>> edge_midpoint(_m, "edge_midpoint");
PropertyManager<VPropHandleT<bool>> is_original_vertex(_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 (auto eh : _m.edges()) {
VertexHandle 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 (auto fh : _m.faces()) {
std::vector<typename mesh_t::VertexHandle> new_corners;
for (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 (auto vh : _m.vertices()) {
if (is_original_vertex[vh]) {
if (!_m.is_boundary(vh)) {
std::vector<typename mesh_t::VertexHandle> new_corners;
for (auto eh : _m.ve_range(vh))
new_corners.push_back(edge_midpoint[eh]);
std::reverse(new_corners.begin(), new_corners.end());
_m.add_face(new_corners);
}
}
}
for (auto vh : _m.vertices())
if (is_original_vertex[vh])
_m.delete_vertex(vh);
_m.garbage_collection();
}
_m.release_face_status();
_m.release_vertex_status();
_m.release_edge_status();
_m.release_halfedge_status();
return true;
}
bool cleanup(mesh_t& _m)
{
return true;
}
};
} // namespace Uniform
} // namespace Subdivider
} // namespace OpenMesh
SubdividerT.hh
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition MeshItems.hh:59
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition Handles.hh:121
OpenMesh::PropertyManager
This class is intended to manage the lifecycle of properties.
Definition PropertyManager.hh:76
OpenMesh::PropertyManager::set_range
void set_range(HandleTypeIterator begin, HandleTypeIterator end, const PROP_VALUE &value)
Conveniently set the property for an entire range of values.
Definition PropertyManager.hh:519
OpenMesh::Subdivider::Uniform::MidpointT
Midpoint subdivision algorithm.
Definition MidpointT.hh:28
OpenMesh::Subdivider::Uniform::MidpointT::cleanup
bool cleanup(mesh_t &_m)
Cleanup mesh after usage, e.g. remove added properties.
Definition MidpointT.hh:96
OpenMesh::Subdivider::Uniform::MidpointT::subdivide
bool subdivide(mesh_t &_m, size_t _n, const bool _update_points=true)
Performs one step of Midpoint subdivision.
Definition MidpointT.hh:48
OpenMesh::Subdivider::Uniform::MidpointT::prepare
bool prepare(mesh_t &_m)
Prepare mesh, e.g. add properties.
Definition MidpointT.hh:41
OpenMesh::Subdivider::Uniform::MidpointT::name
const char * name() const
Return name of subdivision algorithm.
Definition MidpointT.hh:38
OpenMesh::Subdivider::Uniform::SubdividerT
Abstract base class for uniform subdivision algorithms.
Definition SubdividerT.hh:89