Commit 789ca69d authored by Jan Möbius's avatar Jan Möbius

Merge branch 'midpoint-subdivision' into 'master'

add Midpoint subdivision scheme

See merge request !117
parents a1ee66ac e8247d64
Pipeline #4131 passed with stage
in 40 minutes and 32 seconds
......@@ -14,6 +14,7 @@ subdivision:
-# OpenMesh::Subdivider::Uniform::InterpolatingSqrt3LGT
-# OpenMesh::Subdivider::Uniform::CompositeT
-# OpenMesh::Subdivider::Uniform::CatmullClarkT
-# OpenMesh::Subdivider::Uniform::MidpointT
-# Adaptive subdivision
-# OpenMesh::Subdivider::Adaptive::CompositeT
-# Simple subdivision
......
......@@ -409,6 +409,22 @@ public:
return edge_vec.sqrnorm();
}
/** Calculates the midpoint of the halfedge _heh, defined by the positions of
the two incident vertices */
Point calc_edge_midpoint(HalfedgeHandle _heh) const
{
VertexHandle vh0 = this->from_vertex_handle(_heh);
VertexHandle vh1 = this->to_vertex_handle(_heh);
return 0.5 * (this->point(vh0) + this->point(vh1));
}
/** Calculates the midpoint of the edge _eh, defined by the positions of the
two incident vertices */
Point calc_edge_midpoint(EdgeHandle _eh) const
{
return calc_edge_midpoint(this->halfedge_handle(_eh, 0));
}
/** defines a consistent representation of a sector geometry:
the halfedge _in_heh defines the sector orientation
the vertex pointed by _in_heh defines the sector center
......
......@@ -88,7 +88,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
\note Needs a PolyMesh to work on!
*/
template <typename MeshType, typename RealType = float>
template <typename MeshType, typename RealType = double>
class CatmullClarkT : public SubdividerT< MeshType, RealType >
{
public:
......
......@@ -77,7 +77,7 @@ namespace Uniform { // BEGIN_NS_DECIMATER
/** Uniform composite Loop subdivision algorithm
*/
template <class MeshType, class RealType=float>
template <class MeshType, class RealType = double>
class CompositeLoopT : public CompositeT<MeshType, RealType>
{
public:
......
......@@ -77,7 +77,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
/** Uniform composite sqrt(3) subdivision algorithm
*/
template <typename MeshType, typename RealType=float>
template <typename MeshType, typename RealType = double>
class CompositeSqrt3T : public CompositeT<MeshType, RealType>
{
public:
......
......@@ -82,7 +82,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
//== CLASS DEFINITION =========================================================
template <typename MeshType, typename RealType = float>
template <typename MeshType, typename RealType = double>
class CompareLengthFunction {
public:
......
......@@ -92,7 +92,7 @@ namespace Uniform { // BEGIN_NS_DECIMATER
* M.S. Thesis, Department of Mathematics, University of Utah, August 1987.
*
*/
template <typename MeshType, typename RealType = float>
template <typename MeshType, typename RealType = double>
class LoopT : public SubdividerT<MeshType, RealType>
{
public:
......
#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 {
/**
* Midpoint subdivision algorithm.
*
* With every step, the set of vertices is replaced with by the midpoints of all
* current edges. Then, two sets of faces are created to set up the new
* connectivity: From all midpoints of edges surrounding an original face, a new
* face is created. Also, for all midpoints of edges surrounding an original
* vertex, a new face is created.
*
* @note This algorithm ignores the _update_points option.
* @note This algorithm is best suited for closed meshes since boundaries tend
* to fragment into isolated faces after a few iterations.
*/
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;
}
//! Performs one step of Midpoint subdivision.
//! @note The _update_points option is ignored
bool subdivide(mesh_t& _m, size_t _n, const bool _update_points = true)
{
PropertyManager<EPropHandleT<typename mesh_t::VertexHandle>, mesh_t> edge_midpoint(_m, "edge_midpoint");
PropertyManager<VPropHandleT<bool>, mesh_t> 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 (typename mesh_t::EdgeIter it = _m.edges_begin(), end = _m.edges_end(); it != end; ++it) {
EdgeHandle eh = *it;
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 (typename mesh_t::FaceIter it = _m.faces_begin(), end = _m.faces_end(); it != end; ++it) {
FaceHandle fh = *it;
std::vector<typename mesh_t::VertexHandle> new_corners;
for (typename mesh_t::FaceEdgeIter it = _m.fe_begin(fh), end = _m.fe_end(fh); it != end; ++it) {
EdgeHandle eh = *it;
new_corners.push_back(edge_midpoint[eh]);
}
_m.add_face(new_corners);
}
// Create new faces from original vertices
for (typename mesh_t::VertexIter it = _m.vertices_begin(), end = _m.vertices_end(); it != end; ++it) {
VertexHandle vh = *it;
if (is_original_vertex[vh]) {
if (!_m.is_boundary(vh)) {
std::vector<typename mesh_t::VertexHandle> new_corners;
for (typename mesh_t::VertexEdgeIter it = _m.ve_begin(vh), end = _m.ve_end(vh); it != end; ++it) {
EdgeHandle eh = *it;
new_corners.push_back(edge_midpoint[eh]);
}
std::reverse(new_corners.begin(), new_corners.end());
_m.add_face(new_corners);
}
}
}
for (typename mesh_t::VertexIter it = _m.vertices_begin(), end = _m.vertices_end(); it != end; ++it) {
VertexHandle vh = *it;
if (is_original_vertex[vh]) {
_m.delete_vertex(vh);
}
}
}
return true;
}
bool cleanup(mesh_t& _m)
{
return true;
}
};
} // namespace Uniform
} // namespace Subdivider
} // namespace OpenMesh
......@@ -95,7 +95,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
*
* Clement Courbet - clement.courbet@ecp.fr
*/
template <typename MeshType, typename RealType = float>
template <typename MeshType, typename RealType = double>
class ModifiedButterflyT : public SubdividerT<MeshType, RealType>
{
public:
......
......@@ -109,7 +109,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
* Clement Courbet - clement.courbet@ecp.fr
*/
template <typename MeshType, typename RealType = float>
template <typename MeshType, typename RealType = double>
class InterpolatingSqrt3LGT : public SubdividerT< MeshType, RealType >
{
public:
......
......@@ -99,7 +99,7 @@ namespace Uniform { // BEGIN_NS_DECIMATER
*
* L. Kobbelt, <a href="http://www-i8.informatik.rwth-aachen.de/publications/downloads/sqrt3.pdf">"Sqrt(3) subdivision"</a>, Proceedings of SIGGRAPH 2000.
*/
template <typename MeshType, typename RealType = float>
template <typename MeshType, typename RealType = double>
class Sqrt3T : public SubdividerT< MeshType, RealType >
{
public:
......
......@@ -79,18 +79,17 @@ namespace OpenMesh {
namespace Subdivider {
namespace Uniform {
//== CLASS DEFINITION =========================================================
/** Abstract base class for uniform subdivision algorithms.
*
* A derived class must overload the following functions:
* -# name()
* -# prepare()
* -# subdivide()
* -# cleanup()
* -# const char* name() const
* -# void prepare(MeshType&)
* -# void subdivide(MeshType&, size_t, bool)
* -# void cleanup(MeshType&)
*/
template <typename MeshType, typename RealType=float>
template <typename MeshType, typename RealType = double>
class SubdividerT : private Utils::Noncopyable
{
public:
......@@ -104,7 +103,7 @@ public:
//@{
/// Constructor to be used with interface 2
/// \see attach(), operator()(size_t), detach()
SubdividerT(void) : attached_(NULL) { }
SubdividerT(void) : attached_() { }
/// Constructor to be used with interface 1 (calls attach())
/// \see operator()( MeshType&, size_t )
......@@ -112,7 +111,7 @@ public:
//@}
/// Descructor (calls detach())
/// Destructor (calls detach())
virtual ~SubdividerT()
{ detach(); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment