201 bool subdivide( MeshType& _m,
size_t _n ,
const bool _update_points =
true)
206 typename MeshType::VertexIter vit;
207 typename MeshType::VertexVertexIter vvit;
208 typename MeshType::EdgeIter eit;
209 typename MeshType::FaceIter fit;
210 typename MeshType::FaceVertexIter fvit;
211 typename MeshType::FaceHalfedgeIter fheit;
212 typename MeshType::VertexHandle vh;
213 typename MeshType::HalfedgeHandle heh;
214 typename MeshType::Point pos(0,0,0), zero(0,0,0);
215 size_t &gen = _m.property( mp_gen_ );
217 for (
size_t l=0; l<_n; ++l)
220 for (eit=_m.edges_begin(); eit != _m.edges_end();++eit)
222 _m.status( *eit ).set_tagged(
true );
223 if ( (gen%2) && _m.is_boundary(*eit) )
224 compute_new_boundary_points( _m, *eit );
228 typename MeshType::FaceIter fend = _m.faces_end();
229 for (fit = _m.faces_begin();fit != fend; ++fit)
231 if (_m.is_boundary(*fit))
234 _m.property(fp_pos_, *fit).invalidate();
238 for( heh = _m.halfedge_handle(*fit); !_m.is_boundary( _m.opposite_halfedge_handle(heh) ); heh = _m.next_halfedge_handle(heh) )
240 assert(_m.is_boundary( _m.opposite_halfedge_handle(heh) ));
243 if( _m.is_boundary(_m.next_halfedge_handle(heh)) || _m.is_boundary(_m.prev_halfedge_handle(heh)) )
245 if(_m.is_boundary(_m.prev_halfedge_handle(heh)))
246 heh = _m.prev_halfedge_handle(heh);
248 if(_m.is_boundary(_m.next_halfedge_handle(_m.next_halfedge_handle(heh))))
251 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
252 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
253 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
257#ifdef MIRROR_TRIANGLES
259 pos += real_t(2.0/9) * _m.point(_m.to_vertex_handle(heh));
260 pos += real_t(4.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
261 pos += real_t(4.0/9) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
262 pos += real_t(-1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
264 pos += real_t(7.0/24) * _m.point(_m.to_vertex_handle(heh));
265 pos += real_t(3.0/8) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
266 pos += real_t(3.0/8) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
267 pos += real_t(-1.0/24) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
273 vh = _m.to_vertex_handle(_m.next_halfedge_handle(heh));
275 if((_m.valence(vh) == 6) || _m.is_boundary(vh))
277#ifdef MIRROR_TRIANGLES
279 pos += real_t(5.0/9) * _m.point(vh);
280 pos += real_t(3.0/9) * _m.point(_m.to_vertex_handle(heh));
281 pos += real_t(3.0/9) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
282 pos += real_t(-1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.next_halfedge_handle(heh)))));
283 pos += real_t(-1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
286 pos += real_t(1.0/9) * _m.point(vh);
287 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
288 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
289 pos += real_t(1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.next_halfedge_handle(heh)))));
290 pos += real_t(1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
292 pos += real_t(1.0/2) * _m.point(vh);
293 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
294 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
295 pos += real_t(-1.0/12) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.next_halfedge_handle(heh)))));
296 pos += real_t(-1.0/12) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
303 unsigned int K = _m.valence(vh);
304 pos += weights_[K][K]*_m.point(vh);
305 heh = _m.opposite_halfedge_handle( _m.next_halfedge_handle(heh) );
306 for(
unsigned int i = 0; i<K; ++i, heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)) )
308 pos += weights_[K][i]*_m.point(_m.to_vertex_handle(heh));
312 vh = _m.add_vertex( pos );
313 _m.property(fp_pos_, *fit) = vh;
322 for(fvit = _m.fv_iter( *fit ); fvit.is_valid(); ++fvit)
323 if( (_m.valence(*fvit)) == 6 || _m.is_boundary(*fvit) )
328 for(fheit = _m.fh_iter( *fit ); fheit.is_valid(); ++fheit)
332 assert(_m.to_vertex_handle(heh).is_valid());
333 pos += real_t(32.0/81) * _m.point(_m.to_vertex_handle(heh));
335 heh = _m.opposite_halfedge_handle(heh);
336 assert(heh.is_valid());
337 assert(_m.next_halfedge_handle(heh).is_valid());
338 assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
339 pos -= real_t(1.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
341 heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh));
342 assert(heh.is_valid());
343 assert(_m.next_halfedge_handle(heh).is_valid());
344 assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
345 pos -= real_t(2.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
346 heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh));
347 assert(heh.is_valid());
348 assert(_m.next_halfedge_handle(heh).is_valid());
349 assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
350 pos -= real_t(2.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
356 for(fheit = _m.fh_iter( *fit ); fheit.is_valid(); ++fheit)
358 vh = _m.to_vertex_handle(*fheit);
359 if( (_m.valence(vh) != 6) && (!_m.is_boundary(vh)) )
361 unsigned int K = _m.valence(vh);
362 pos += weights_[K][K]*_m.point(vh);
363 heh = _m.opposite_halfedge_handle( *fheit );
364 for(
unsigned int i = 0; i<K; ++i, heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)) )
366 pos += weights_[K][i]*_m.point(_m.to_vertex_handle(heh));
370 pos *= real_t(1.0/(3-nOrdinary));
373 vh = _m.add_vertex( pos );
374 _m.property(fp_pos_, *fit) = vh;
379 for (fit = _m.faces_begin();fit != fend; ++fit)
381 if ( _m.is_boundary(*fit) && (gen%2))
383 boundary_split( _m, *fit );
387 assert(_m.property(fp_pos_, *fit).is_valid());
388 _m.split( *fit, _m.property(fp_pos_, *fit) );
393 for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit)
394 if ( _m.status( *eit ).tagged() && !_m.is_boundary( *eit ) )
398 ASSERT_CONSISTENCY( MeshType, _m );