48#define OPENMESH_SUBDIVIDER_UNIFORM_CATMULLCLARK_CC
53#include <OpenMesh/Tools/Utils/MeshCheckerT.hh>
63template <
typename MeshType,
typename RealType>
67 _m.add_property( vp_pos_ );
68 _m.add_property( ep_pos_ );
69 _m.add_property( fp_pos_ );
70 _m.add_property( creaseWeights_ );
73 for( EdgeIter e_it = _m.edges_begin(); e_it != _m.edges_end(); ++e_it)
74 _m.property(creaseWeights_, *e_it ) = 0.0;
81template <
typename MeshType,
typename RealType>
85 _m.remove_property( vp_pos_ );
86 _m.remove_property( ep_pos_ );
87 _m.remove_property( fp_pos_ );
88 _m.remove_property( creaseWeights_ );
94template <
typename MeshType,
typename RealType>
99 for (
size_t i = 0; i < _n; ++i)
103 for (
auto fh : _m.faces())
106 _m.calc_face_centroid( fh, centroid);
107 _m.property( fp_pos_, fh ) = centroid;
111 for (
auto eh : _m.edges())
112 compute_midpoint( _m, eh, _update_points );
118 for (
auto vh : _m.vertices())
119 update_vertex( _m, vh );
122 for (
auto vh : _m.vertices())
123 _m.set_point(vh, _m.property( vp_pos_, vh ) );
128 for (
auto eh : _m.edges())
129 split_edge( _m, eh );
133 for (
auto fh : _m.faces())
137#if defined(_DEBUG) || defined(DEBUG)
150template <
typename MeshType,
typename RealType>
164 size_t valence = _m.valence(_fh)/2;
167 VertexHandle vh = _m.add_vertex(_m.property( fp_pos_, _fh ));
174 _m.set_next_halfedge_handle(hend, hold);
175 _m.set_face_handle(hold, _fh);
177 hold = _m.opposite_halfedge_handle(hold);
179 for(
size_t i = 1; i < valence; i++)
185 _m.set_halfedge_handle(fnew, hh);
187 HalfedgeHandle hnew = _m.new_edge(_m.to_vertex_handle(hnext), vh);
189 _m.set_face_handle(hnew, fnew);
190 _m.set_face_handle(hold, fnew);
191 _m.set_face_handle(hh, fnew);
192 _m.set_face_handle(hnext, fnew);
194 _m.set_next_halfedge_handle(hnew, hold);
195 _m.set_next_halfedge_handle(hold, hh);
196 _m.set_next_halfedge_handle(hh, hnext);
197 hh = _m.next_halfedge_handle(hnext);
198 _m.set_next_halfedge_handle(hnext, hnew);
200 hold = _m.opposite_halfedge_handle(hnew);
203 _m.set_next_halfedge_handle(hold, hh);
204 _m.set_next_halfedge_handle(hh, hend);
205 hh = _m.next_halfedge_handle(hend);
206 _m.set_next_halfedge_handle(hend, hh);
207 _m.set_next_halfedge_handle(hh, hold);
209 _m.set_face_handle(hold, _fh);
211 _m.set_halfedge_handle(vh, hold);
216template <
typename MeshType,
typename RealType>
218CatmullClarkT<MeshType,RealType>::split_edge( MeshType& _m,
const EdgeHandle& _eh)
229 vh = _m.new_vertex( zero );
230 _m.set_point( vh, _m.property( ep_pos_, _eh ) );
233 if (_m.is_boundary(_eh))
236 _m.next_halfedge_handle(t_heh) != opp_heh;
237 t_heh = _m.opposite_halfedge_handle(_m.next_halfedge_handle(t_heh)))
242 for (t_heh = _m.next_halfedge_handle(opp_heh);
243 _m.next_halfedge_handle(t_heh) != opp_heh;
244 t_heh = _m.next_halfedge_handle(t_heh) )
248 new_heh = _m.new_edge(vh, vh1);
249 opp_new_heh = _m.opposite_halfedge_handle(new_heh);
250 _m.set_vertex_handle( heh, vh );
252 _m.set_next_halfedge_handle(t_heh, opp_new_heh);
253 _m.set_next_halfedge_handle(new_heh, _m.next_halfedge_handle(heh));
254 _m.set_next_halfedge_handle(heh, new_heh);
255 _m.set_next_halfedge_handle(opp_new_heh, opp_heh);
257 if (_m.face_handle(opp_heh).is_valid())
259 _m.set_face_handle(opp_new_heh, _m.face_handle(opp_heh));
260 _m.set_halfedge_handle(_m.face_handle(opp_new_heh), opp_new_heh);
263 if( _m.face_handle(heh).is_valid())
265 _m.set_face_handle( new_heh, _m.face_handle(heh) );
266 _m.set_halfedge_handle( _m.face_handle(heh), heh );
269 _m.set_halfedge_handle( vh, new_heh);
270 _m.set_halfedge_handle( vh1, opp_new_heh );
273 _m.adjust_outgoing_halfedge( vh );
274 _m.adjust_outgoing_halfedge( vh1 );
279template <
typename MeshType,
typename RealType>
281CatmullClarkT<MeshType,RealType>::compute_midpoint( MeshType& _m,
const EdgeHandle& _eh,
const bool _update_points)
283 HalfedgeHandle heh, opp_heh;
285 heh = _m.halfedge_handle( _eh, 0);
286 opp_heh = _m.halfedge_handle( _eh, 1);
288 Point pos( _m.point( _m.to_vertex_handle( heh)));
290 pos += _m.point( _m.to_vertex_handle( opp_heh));
294 if (_m.is_boundary(_eh) || !_update_points)
296 pos *=
static_cast<RealType
>(0.5);
306 pos += _m.property(fp_pos_, _m.face_handle(heh));
307 pos += _m.property(fp_pos_, _m.face_handle(opp_heh));
308 pos *=
static_cast<RealType
>(0.25);
310 _m.property( ep_pos_, _eh ) = pos;
315template <
typename MeshType,
typename RealType>
317CatmullClarkT<MeshType,RealType>::update_vertex( MeshType& _m,
const VertexHandle& _vh)
319 Point pos(0.0,0.0,0.0);
325 if ( _m.is_boundary( _vh))
328 VertexEdgeIter ve_itr;
329 for ( ve_itr = _m.ve_iter( _vh); ve_itr.is_valid(); ++ve_itr)
330 if ( _m.is_boundary( *ve_itr))
331 pos += _m.property( ep_pos_, *ve_itr);
358 RealType valence(0.0);
359 VOHIter voh_it = _m.voh_iter( _vh );
360 for( ; voh_it.is_valid(); ++voh_it )
362 pos += _m.point( _m.to_vertex_handle( *voh_it ) );
365 pos /= valence*valence;
367 VertexFaceIter vf_itr;
370 for ( vf_itr = _m.vf_iter( _vh); vf_itr.is_valid(); ++vf_itr)
372 Q += _m.property(fp_pos_, *vf_itr);
375 Q /= valence*valence;
377 pos += _m.point(_vh) * (valence - RealType(2.0) )/valence + Q;
381 _m.property( vp_pos_, _vh ) = pos;
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
Handle for a vertex entity.
Definition: Handles.hh:121
Handle for a halfedge entity.
Definition: Handles.hh:128
Handle for a edge entity.
Definition: Handles.hh:135
Handle for a face entity.
Definition: Handles.hh:142
T::value_type value_type
Type of the scalar value.
Definition: vector_traits.hh:94
Based on code from Leon Kos, CAD lab, Mech.Eng., University of Ljubljana, Slovenia (http://www....
Definition: CatmullClarkT.hh:86
virtual bool subdivide(MeshType &_m, size_t _n, const bool _update_points=true) override
Execute n subdivision steps.
Definition: CatmullClarkT_impl.hh:96
virtual bool prepare(MeshType &_m) override
Initialize properties and weights.
Definition: CatmullClarkT_impl.hh:65
virtual bool cleanup(MeshType &_m) override
Remove properties and weights.
Definition: CatmullClarkT_impl.hh:83
Check integrity of mesh.
Definition: MeshCheckerT.hh:74