Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
LoopSubdivider.hpp
1 #pragma once
2 
3 #include <Core/Geometry/deprecated/TopologicalMesh.hpp>
4 #include <Core/Math/LinearAlgebra.hpp> // Math::pi
5 #include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
6 
7 namespace Ra {
8 namespace Core {
9 namespace Geometry {
10 
17 class RA_CORE_API LoopSubdivider
18  : public OpenMesh::Subdivider::Uniform::SubdividerT<deprecated::TopologicalMesh, Scalar>
19 {
20 
21  using base = OpenMesh::Subdivider::Uniform::SubdividerT<deprecated::TopologicalMesh, Scalar>;
22  using Weight = std::pair<Scalar, Scalar>;
23  using Weights = std::vector<Weight>;
24  using V_OP = std::pair<Scalar, deprecated::TopologicalMesh::VertexHandle>;
25  using V_OPS = std::pair<deprecated::TopologicalMesh::VertexHandle, std::vector<V_OP>>;
26  using SV_OPS = std::vector<V_OPS>;
27  using P_OP = std::pair<Scalar, deprecated::TopologicalMesh::HalfedgeHandle>;
28  using P_OPS = std::pair<deprecated::TopologicalMesh::HalfedgeHandle, std::vector<P_OP>>;
29  using SP_OPS = std::vector<P_OPS>;
30 
31  public:
32  LoopSubdivider() : base() {}
33 
34  explicit LoopSubdivider( deprecated::TopologicalMesh& mesh ) : base() { attach( mesh ); }
35 
36  ~LoopSubdivider() { detach(); }
37 
38  public:
39  const char* name( void ) const override { return "LoopSubdivider"; }
40 
46  // clang-format off
60  // clang-format on
61  void recompute( const Vector3Array& newCoarseVertices,
62  const Vector3Array& newCoarseNormals,
63  Vector3Array& newSubdivVertices,
64  Vector3Array& newSubdivNormals,
66 
67  protected:
69  void init_weights( size_t max_valence ) {
70  m_weights.resize( max_valence );
71  std::generate( m_weights.begin(), m_weights.end(), compute_weight() );
72  }
73 
74  bool prepare( deprecated::TopologicalMesh& mesh ) override;
75 
76  bool cleanup( deprecated::TopologicalMesh& mesh ) override;
77 
78  bool subdivide( deprecated::TopologicalMesh& mesh,
79  size_t n,
80  const bool updatePoints = true ) override;
81 
82  private:
84  struct compute_weight {
85  compute_weight() : m_valence( -1 ) {}
86  Weight operator()( void ) {
87  // 1
88  // alpha(n) = ---- * (40 - ( 3 + 2 cos( 2 Pi / n ) )^2 )
89  // 64
90  if ( ++m_valence ) {
91  double inv_v = 1.0 / double( m_valence );
92  double t = ( 3.0 + 2.0 * std::cos( 2.0 * Math::Pi * inv_v ) );
93  double alpha = ( 40.0 - t * t ) / 64.0;
94  return Weight( 1.0 - alpha, inv_v * alpha );
95  }
96  return Weight( 0, 0 );
97  }
98  int m_valence;
99  };
100 
101  private:
102  // topological modifiers
103 
105  void split_face( deprecated::TopologicalMesh& mesh,
106  const deprecated::TopologicalMesh::FaceHandle& fh,
107  size_t iter );
108 
110  void corner_cutting( deprecated::TopologicalMesh& mesh,
111  const deprecated::TopologicalMesh::HalfedgeHandle& he,
112  size_t iter );
113 
115  void split_edge( deprecated::TopologicalMesh& mesh,
116  const deprecated::TopologicalMesh::EdgeHandle& eh,
117  size_t iter );
118 
119  // geometry helpers
120 
122  void compute_midpoint( deprecated::TopologicalMesh& mesh,
123  const deprecated::TopologicalMesh::EdgeHandle& eh,
124  size_t iter );
125 
127  void smooth( deprecated::TopologicalMesh& mesh,
128  const deprecated::TopologicalMesh::VertexHandle& vh,
129  size_t iter );
130 
131  private:
133  OpenMesh::VPropHandleT<deprecated::TopologicalMesh::Point> m_vpPos;
134 
136  OpenMesh::EPropHandleT<deprecated::TopologicalMesh::VertexHandle> m_epPos;
137 
139  Weights m_weights;
140 
142  std::vector<SV_OPS> m_oldVertexOps;
143  std::vector<SV_OPS> m_newVertexOps;
144  std::vector<SP_OPS> m_newEdgePropOps;
145  std::vector<SP_OPS> m_newFacePropOps;
146 
148  OpenMesh::HPropHandleT<deprecated::TopologicalMesh::VertexHandle> m_hV;
149 };
150 
151 } // namespace Geometry
152 } // namespace Core
153 } // namespace Ra
void init_weights(size_t max_valence)
Pre-compute weights.
Definition: Cage.cpp:3