Merge branch 'midpoint-subdivision' into 'master'
add Midpoint subdivision scheme See merge request !117
This commit is contained in:
@@ -14,6 +14,7 @@ subdivision:
|
|||||||
-# OpenMesh::Subdivider::Uniform::InterpolatingSqrt3LGT
|
-# OpenMesh::Subdivider::Uniform::InterpolatingSqrt3LGT
|
||||||
-# OpenMesh::Subdivider::Uniform::CompositeT
|
-# OpenMesh::Subdivider::Uniform::CompositeT
|
||||||
-# OpenMesh::Subdivider::Uniform::CatmullClarkT
|
-# OpenMesh::Subdivider::Uniform::CatmullClarkT
|
||||||
|
-# OpenMesh::Subdivider::Uniform::MidpointT
|
||||||
-# Adaptive subdivision
|
-# Adaptive subdivision
|
||||||
-# OpenMesh::Subdivider::Adaptive::CompositeT
|
-# OpenMesh::Subdivider::Adaptive::CompositeT
|
||||||
-# Simple subdivision
|
-# Simple subdivision
|
||||||
|
|||||||
@@ -409,6 +409,22 @@ public:
|
|||||||
return edge_vec.sqrnorm();
|
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:
|
/** defines a consistent representation of a sector geometry:
|
||||||
the halfedge _in_heh defines the sector orientation
|
the halfedge _in_heh defines the sector orientation
|
||||||
the vertex pointed by _in_heh defines the sector center
|
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!
|
\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 >
|
class CatmullClarkT : public SubdividerT< MeshType, RealType >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace Uniform { // BEGIN_NS_DECIMATER
|
|||||||
|
|
||||||
/** Uniform composite Loop subdivision algorithm
|
/** Uniform composite Loop subdivision algorithm
|
||||||
*/
|
*/
|
||||||
template <class MeshType, class RealType=float>
|
template <class MeshType, class RealType = double>
|
||||||
class CompositeLoopT : public CompositeT<MeshType, RealType>
|
class CompositeLoopT : public CompositeT<MeshType, RealType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
|
|||||||
|
|
||||||
/** Uniform composite sqrt(3) subdivision algorithm
|
/** Uniform composite sqrt(3) subdivision algorithm
|
||||||
*/
|
*/
|
||||||
template <typename MeshType, typename RealType=float>
|
template <typename MeshType, typename RealType = double>
|
||||||
class CompositeSqrt3T : public CompositeT<MeshType, RealType>
|
class CompositeSqrt3T : public CompositeT<MeshType, RealType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
|
|||||||
|
|
||||||
//== CLASS DEFINITION =========================================================
|
//== CLASS DEFINITION =========================================================
|
||||||
|
|
||||||
template <typename MeshType, typename RealType = float>
|
template <typename MeshType, typename RealType = double>
|
||||||
class CompareLengthFunction {
|
class CompareLengthFunction {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace Uniform { // BEGIN_NS_DECIMATER
|
|||||||
* M.S. Thesis, Department of Mathematics, University of Utah, August 1987.
|
* 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>
|
class LoopT : public SubdividerT<MeshType, RealType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
105
src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh
Normal file
105
src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#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
|
* Clement Courbet - clement.courbet@ecp.fr
|
||||||
*/
|
*/
|
||||||
template <typename MeshType, typename RealType = float>
|
template <typename MeshType, typename RealType = double>
|
||||||
class ModifiedButterflyT : public SubdividerT<MeshType, RealType>
|
class ModifiedButterflyT : public SubdividerT<MeshType, RealType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ namespace Uniform { // BEGIN_NS_UNIFORM
|
|||||||
* Clement Courbet - clement.courbet@ecp.fr
|
* Clement Courbet - clement.courbet@ecp.fr
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename MeshType, typename RealType = float>
|
template <typename MeshType, typename RealType = double>
|
||||||
class InterpolatingSqrt3LGT : public SubdividerT< MeshType, RealType >
|
class InterpolatingSqrt3LGT : public SubdividerT< MeshType, RealType >
|
||||||
{
|
{
|
||||||
public:
|
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.
|
* 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 >
|
class Sqrt3T : public SubdividerT< MeshType, RealType >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -79,18 +79,17 @@ namespace OpenMesh {
|
|||||||
namespace Subdivider {
|
namespace Subdivider {
|
||||||
namespace Uniform {
|
namespace Uniform {
|
||||||
|
|
||||||
|
|
||||||
//== CLASS DEFINITION =========================================================
|
//== CLASS DEFINITION =========================================================
|
||||||
|
|
||||||
/** Abstract base class for uniform subdivision algorithms.
|
/** Abstract base class for uniform subdivision algorithms.
|
||||||
*
|
*
|
||||||
* A derived class must overload the following functions:
|
* A derived class must overload the following functions:
|
||||||
* -# name()
|
* -# const char* name() const
|
||||||
* -# prepare()
|
* -# void prepare(MeshType&)
|
||||||
* -# subdivide()
|
* -# void subdivide(MeshType&, size_t, bool)
|
||||||
* -# cleanup()
|
* -# void cleanup(MeshType&)
|
||||||
*/
|
*/
|
||||||
template <typename MeshType, typename RealType=float>
|
template <typename MeshType, typename RealType = double>
|
||||||
class SubdividerT : private Utils::Noncopyable
|
class SubdividerT : private Utils::Noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -104,7 +103,7 @@ public:
|
|||||||
//@{
|
//@{
|
||||||
/// Constructor to be used with interface 2
|
/// Constructor to be used with interface 2
|
||||||
/// \see attach(), operator()(size_t), detach()
|
/// \see attach(), operator()(size_t), detach()
|
||||||
SubdividerT(void) : attached_(NULL) { }
|
SubdividerT(void) : attached_() { }
|
||||||
|
|
||||||
/// Constructor to be used with interface 1 (calls attach())
|
/// Constructor to be used with interface 1 (calls attach())
|
||||||
/// \see operator()( MeshType&, size_t )
|
/// \see operator()( MeshType&, size_t )
|
||||||
@@ -112,7 +111,7 @@ public:
|
|||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// Descructor (calls detach())
|
/// Destructor (calls detach())
|
||||||
virtual ~SubdividerT()
|
virtual ~SubdividerT()
|
||||||
{ detach(); }
|
{ detach(); }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user