OpenMesh
CompositeT_impl.hh
Go to the documentation of this file.
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2022, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 
48 //=============================================================================
49 //
50 // CLASS CompositeT - IMPLEMENTATION
51 //
52 //=============================================================================
53 
54 #ifndef OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITE_CC
55 #define OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITE_CC
56 
57 
58 //== INCLUDES =================================================================
59 
60 
61 #include <vector>
63 
64 
65 //== NAMESPACE ================================================================
66 
67 namespace OpenMesh { // BEGIN_NS_OPENMESH
68 namespace Subdivider { // BEGIN_NS_DECIMATER
69 namespace Uniform { // BEGIN_NS_UNIFORM
70 
71 
72 //== IMPLEMENTATION ==========================================================
73 
74 
75 template <typename MeshType, typename RealType>
77 {
78  // store mesh for later usage in subdivide(), cleanup() and all rules.
79  p_mesh_ = &_m;
80 
81  typename MeshType::VertexIter v_it(_m.vertices_begin());
82 
83  for (; v_it != _m.vertices_end(); ++v_it)
84  _m.data(*v_it).set_position(_m.point(*v_it));
85 
86  return true;
87 }
88 
89 
90 
91 template<typename MeshType, typename RealType>
93 {
94  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
95 
96  typename MeshType::VertexHandle vh;
97  typename MeshType::FaceIter f_it;
98  typename MeshType::EdgeIter e_it;
99  typename MeshType::VertexIter v_it;
100  typename MeshType::Point zero_point(0.0, 0.0, 0.0);
101  size_t n_edges, n_faces, n_vertices, j;
102 
103  // Store number of original edges
104  n_faces = mesh_.n_faces();
105  n_edges = mesh_.n_edges();
106  n_vertices = mesh_.n_vertices();
107 
108  // reserve enough memory for iterator
109  mesh_.reserve(n_vertices + n_faces, n_edges + 3 * n_faces, 3 * n_faces);
110 
111  // set new positions for vertices
112  v_it = mesh_.vertices_begin();
113  for (j = 0; j < n_vertices; ++j) {
114  mesh_.data(*v_it).set_position(mesh_.data(*v_it).position() * static_cast<typename MeshType::Point::value_type>(3.0) );
115  ++v_it;
116  }
117 
118  // Split each face
119  f_it = mesh_.faces_begin();
120  for (j = 0; j < n_faces; ++j) {
121 
122  vh = mesh_.add_vertex(zero_point);
123 
124  mesh_.data(vh).set_position(zero_point);
125 
126  mesh_.split(*f_it, vh);
127 
128  ++f_it;
129  }
130 
131  // Flip each old edge
132  std::vector<typename MeshType::EdgeHandle> edge_vector;
133  edge_vector.clear();
134 
135  e_it = mesh_.edges_begin();
136  for (j = 0; j < n_edges; ++j) {
137  if (mesh_.is_flip_ok(*e_it)) {
138  mesh_.flip(*e_it);
139  } else {
140  edge_vector.push_back(*e_it);
141  }
142  ++e_it;
143  }
144 
145  // split all boundary edges
146  while (!edge_vector.empty()) {
147  vh = mesh_.add_vertex(zero_point);
148  mesh_.data(vh).set_position(zero_point);
149  mesh_.split(edge_vector.back(), vh);
150  edge_vector.pop_back();
151  }
152 }
153 
154 
155 template<typename MeshType, typename RealType>
157 {
158  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
159 
160  typename MeshType::VertexHandle vh;
161  typename MeshType::FaceIter f_it;
162  typename MeshType::EdgeIter e_it;
163  typename MeshType::VertexIter v_it;
164  typename MeshType::Point zero_point(0.0, 0.0, 0.0);
165  size_t n_edges, n_faces, n_vertices, j;
166 
167  // Store number of original edges
168  n_faces = mesh_.n_faces();
169  n_edges = mesh_.n_edges();
170  n_vertices = mesh_.n_vertices();
171 
172  // reserve memory ahead for the succeeding operations
173  mesh_.reserve(n_vertices + n_edges, 2 * n_edges + 3 * n_faces, 4 * n_faces);
174 
175  // set new positions for vertices
176  v_it = mesh_.vertices_begin();
177  for (j = 0; j < n_vertices; ++j) {
178  mesh_.data(*v_it).set_position(mesh_.data(*v_it).position() * static_cast<typename MeshType::Point::value_type>(4.0) );
179  ++v_it;
180  }
181 
182  // Split each edge
183  e_it = mesh_.edges_begin();
184  for (j = 0; j < n_edges; ++j) {
185 
186  vh = split_edge(mesh_.halfedge_handle(*e_it, 0));
187  mesh_.data(vh).set_position(zero_point);
188 
189  ++e_it;
190  }
191 
192  // Corner Cutting of Each Face
193  f_it = mesh_.faces_begin();
194  for (j = 0; j < n_faces; ++j) {
195  typename MeshType::HalfedgeHandle heh1(mesh_.halfedge_handle(*f_it));
196  typename MeshType::HalfedgeHandle heh2(mesh_.next_halfedge_handle(mesh_.next_halfedge_handle(heh1)));
197  typename MeshType::HalfedgeHandle heh3(mesh_.next_halfedge_handle(mesh_.next_halfedge_handle(heh2)));
198 
199  // Cutting off every corner of the 6_gon
200 
201  corner_cutting(heh1);
202  corner_cutting(heh2);
203  corner_cutting(heh3);
204 
205  ++f_it;
206  }
207 }
208 
209 
210 template<typename MeshType, typename RealType>
212 {
213  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
214 
215  typename MeshType::VertexHandle vh;
216  typename MeshType::FaceIter f_it;
217  typename MeshType::EdgeIter e_it;
218  typename MeshType::VertexIter v_it;
219  typename MeshType::VertexFaceIter vf_it;
220  typename MeshType::FaceFaceIter ff_it;
221  typename MeshType::Point cog;
222  const typename MeshType::Point zero_point(0.0, 0.0, 0.0);
223  size_t n_edges, n_faces, n_vertices, j, valence;
224 
225  // Store number of original edges
226  n_faces = mesh_.n_faces();
227  n_edges = mesh_.n_edges();
228  n_vertices = mesh_.n_vertices();
229 
230  // reserve enough space for iterator
231  mesh_.reserve(n_vertices + n_faces, n_edges + 3 * n_faces, 3 * n_faces);
232 
233  // set new positions for vertices
234  v_it = mesh_.vertices_begin();
235  for (j = 0; j < n_vertices; ++j) {
236  valence = 0;
237  cog = zero_point;
238  for (vf_it = mesh_.vf_iter(*v_it); vf_it; ++vf_it) {
239  ++valence;
240  cog += vf_it->position();
241  }
242  cog /= valence;
243 
244  v_it->set_position(cog);
245  ++v_it;
246  }
247 
248  // Split each face, insert new vertex and calculate position
249  f_it = mesh_.faces_begin();
250  for (j = 0; j < n_faces; ++j) {
251 
252  vh = mesh_.add_vertex();
253 
254  valence = 0;
255  cog = zero_point;
256  for (ff_it = mesh_.ff_iter(*f_it); ff_it; ++ff_it) {
257  ++valence;
258  cog += ff_it->position();
259  }
260  cog /= valence;
261 
262  mesh_.split(*f_it, vh);
263 
264  for (vf_it = mesh_.vf_iter(vh); vf_it; ++vf_it) {
265  vf_it->set_position(f_it->position());
266  }
267 
268  mesh_.deref(vh).set_position(cog);
269 
270  mesh_.set_point(vh, cog);
271 
272  ++f_it;
273  }
274 
275  // Flip each old edge
276  e_it = mesh_.edges_begin();
277  for (j = 0; j < n_edges; ++j) {
278  if (mesh_.is_flip_ok(*e_it))
279  mesh_.flip(*e_it);
280  ++e_it;
281  }
282 }
283 
284 
285 
286 template<typename MeshType, typename RealType>
288 {
289  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
290 
291  typename MeshType::Point cog,zero_point(0.0, 0.0, 0.0);
292  typename MeshType::FaceVertexIter fv_it;
293  typename MeshType::FaceIter f_it;
294 
295  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) {
296 
297  unsigned int valence = 0;
298  cog = zero_point;
299 
300  for (fv_it = mesh_.fv_iter(*f_it); fv_it.is_valid(); ++fv_it) {
301  cog += mesh_.data(*fv_it).position();
302  ++valence;
303  }
304  cog /= valence;
305  mesh_.data(*f_it).set_position(cog);
306  }
307 }
308 
309 
310 template<typename MeshType, typename RealType>
312 {
313  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
314 
315  unsigned int valence[3], i;
316  typename MeshType::Point cog,zero_point(0.0, 0.0, 0.0);
317  typename MeshType::Scalar alpha;
318  typename MeshType::FaceIter f_it;
319  typename MeshType::HalfedgeHandle heh;
320  typename MeshType::VertexHandle vh[3];
321  typename MeshType::VertexOHalfedgeIter voh_it;
322  typename MeshType::FaceVertexIter fv_it;
323 
324  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) {
325 
326  heh = mesh_.halfedge_handle(*f_it);
327  for (i = 0; i <= 2; ++i) {
328 
329  valence[i] = 0;
330  vh[i] = mesh_.to_vertex_handle(heh);
331 
332  for (voh_it = mesh_.voh_iter(vh[i]); voh_it; ++voh_it) {
333  ++valence[i];
334  }
335 
336  heh = mesh_.next_halfedge_handle(heh);
337  }
338 
339  if (valence[0] <= valence[1])
340  if (valence[0] <= valence[2])
341  i = 0;
342  else
343  i = 2;
344  else
345  if (valence[1] <= valence[2])
346  i = 1;
347  else
348  i = 2;
349 
350  alpha = _coeff(valence[i]);
351 
352  cog = zero_point;
353 
354  for (fv_it = mesh_.fv_iter(*f_it); fv_it.is_valid(); ++fv_it) {
355  if (*fv_it == vh[i]) {
356  cog += fv_it->position() * alpha;
357  } else {
358  cog += fv_it->position() * (1.0 - alpha) / 2.0;
359  }
360  }
361 
362  f_it->set_position(cog);
363  }
364 }
365 
366 
367 template<typename MeshType, typename RealType>
369 {
370  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
371 
372  unsigned int valence[3], i;
373  typename MeshType::Point cog,
374  zero_point(0.0, 0.0, 0.0);
375  typename MeshType::FaceIter f_it;
376  typename MeshType::HalfedgeHandle heh;
377  typename MeshType::VertexHandle vh[3];
378  typename MeshType::VertexOHalfedgeIter voh_it;
379  typename MeshType::FaceVertexIter fv_it;
380 
381  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) {
382 
383  heh = mesh_.halfedge_handle(*f_it);
384  for (i = 0; i <= 2; ++i) {
385 
386  valence[i] = 0;
387  vh[i] = mesh_.to_vertex_handle(heh);
388 
389  for (voh_it = mesh_.voh_iter(vh[i]); voh_it; ++voh_it) {
390  ++valence[i];
391  }
392 
393  heh = mesh_.next_halfedge_handle(heh);
394  }
395 
396  if (valence[0] <= valence[1])
397  if (valence[0] <= valence[2])
398  i = 0;
399  else
400  i = 2;
401  else
402  if (valence[1] <= valence[2])
403  i = 1;
404  else
405  i = 2;
406 
407  cog = zero_point;
408 
409  for (fv_it = mesh_.fv_iter(*f_it); fv_it.is_valid(); ++fv_it) {
410  if (*fv_it == vh[i]) {
411  cog += fv_it->position() * _alpha;
412  } else {
413  cog += fv_it->position() * (1.0 - _alpha) / 2.0;
414  }
415  }
416 
417  f_it->set_position(cog);
418  }
419 }
420 
421 
422 template<typename MeshType, typename RealType>
424 {
425  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
426 
427  typename MeshType::Point cog,
428  zero_point(0.0, 0.0, 0.0);
429  typename MeshType::FaceFaceIter ff_it;
430  typename MeshType::FaceIter f_it;
431  std::vector<typename MeshType::Point> point_vector;
432 
433  point_vector.clear();
434 
435  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
436  {
437  unsigned int valence = 0;
438  cog = zero_point;
439 
440  for (ff_it = mesh_.ff_iter(*f_it); ff_it.is_valid(); ++ff_it)
441  {
442  cog += mesh_.data(*ff_it).position();
443  ++valence;
444  }
445  cog /= valence;
446  point_vector.push_back(cog);
447  }
448 
449  for (f_it = mesh_.faces_end(); f_it != mesh_.faces_begin(); )
450  {
451  --f_it;
452  mesh_.data(*f_it).set_position(point_vector.back());
453  point_vector.pop_back();
454  }
455 }
456 
457 
458 template<typename MeshType, typename RealType>
460 {
461  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
462 
463  typename MeshType::Point cog,
464  zero_point(0.0, 0.0, 0.0);
465  typename MeshType::FaceFaceIter ff_it;
466  typename MeshType::FaceIter f_it;
467  typename MeshType::Scalar c;
468  std::vector<typename MeshType::Point> point_vector;
469 
470  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) {
471 
472  unsigned int valence = 0;
473  cog = zero_point;
474 
475  for (ff_it = mesh_.ff_iter(*f_it); ff_it; ++ff_it) {
476  cog += ff_it->position();
477  ++valence;
478  }
479  cog /= valence;
480 
481  c = _coeff(valence);
482 
483  cog = cog * (1.0 - c) + f_it->position() * c;
484 
485  point_vector.push_back(cog);
486 
487  }
488  for (f_it = mesh_.faces_end(); f_it != mesh_.faces_begin(); ) {
489 
490  --f_it;
491  f_it->set_position(point_vector.back());
492  point_vector.pop_back();
493 
494  }
495 }
496 
497 
498 template<typename MeshType, typename RealType>
500 {
501  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
502 
503  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
504  typename MeshType::FaceFaceIter ff_it;
505  typename MeshType::FaceIter f_it;
506  std::vector<typename MeshType::Point> point_vector;
507 
508  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) {
509 
510  unsigned int valence = 0;
511  cog = zero_point;
512 
513  for (ff_it = mesh_.ff_iter(*f_it); ff_it; ++ff_it) {
514  cog += ff_it->position();
515  ++valence;
516  }
517  cog /= valence;
518 
519  cog = cog * (1.0 - _c) + f_it->position() * _c;
520 
521  point_vector.push_back(cog);
522 
523  }
524  for (f_it = mesh_.faces_end(); f_it != mesh_.faces_begin(); ) {
525 
526  --f_it;
527  f_it->set_position(point_vector.back());
528  point_vector.pop_back();
529  }
530 }
531 
532 
533 template<typename MeshType, typename RealType>
535 {
536  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
537 
538  typename MeshType::Point cog,
539  zero_point(0.0, 0.0, 0.0);
540  typename MeshType::VertexFaceIter vf_it;
541  typename MeshType::VertexIter v_it;
542 
543  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) {
544 
545  unsigned int valence = 0;
546  cog = zero_point;
547 
548  for (vf_it = mesh_.vf_iter(*v_it); vf_it; ++vf_it) {
549  cog += vf_it->position();
550  ++valence;
551  }
552  cog /= valence;
553  v_it->set_position(cog);
554  }
555 }
556 
557 
558 template<typename MeshType, typename RealType>
560 {
561  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
562 
563 
564  typename MeshType::Point cog,
565  zero_point(0.0, 0.0, 0.0);
566  scalar_t c;
567  typename MeshType::VertexOHalfedgeIter voh_it;
568  typename MeshType::VertexIter v_it;
569 
570  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) {
571 
572  unsigned int valence = 0;
573  cog = zero_point;
574 
575  for (voh_it = mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
576  ++valence;
577  }
578 
579  c = static_cast<scalar_t>(_coeff(valence));
580 
581  for (voh_it = mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
582 
583  if (mesh_.face_handle(*voh_it).is_valid()) {
584 
585  if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(*voh_it))).is_valid()) {
586  cog += mesh_.data(mesh_.face_handle(*voh_it)).position() * c;
587  cog += mesh_.data(mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(*voh_it)))).position() * (static_cast<typename MeshType::Point::value_type>(1.0) - c);
588  } else {
589  cog += mesh_.data(mesh_.face_handle(*voh_it)).position();
590  }
591  } else {
592  --valence;
593  }
594  }
595 
596  if (valence > 0)
597  cog /= valence;
598 
599  mesh_.data(*v_it).set_position(cog);
600  }
601 }
602 
603 
604 template<typename MeshType, typename RealType>
606 {
607  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
608 
609  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
610  typename MeshType::VertexOHalfedgeIter voh_it;
611  typename MeshType::VertexIter v_it;
612 
613  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) {
614 
615  unsigned int valence = 0;
616  cog = zero_point;
617 
618  for (voh_it = mesh_.voh_iter(*v_it); voh_it; ++voh_it) {
619  ++valence;
620  }
621 
622  for (voh_it = mesh_.voh_iter(*v_it); voh_it; ++voh_it) {
623 
624  if (mesh_.face_handle(*voh_it).is_valid()) {
625 
626  if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(*voh_it))).is_valid()) {
627  cog += mesh_.deref(mesh_.face_handle(*voh_it)).position() * _c;
628  cog += mesh_.deref(mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(*voh_it)))).position() * (1.0 - _c);
629  } else {
630  cog += mesh_.deref(mesh_.face_handle(*voh_it)).position();
631  }
632  } else {
633  --valence;
634  }
635  }
636 
637  if (valence > 0)
638  cog /= valence;
639 
640  v_it->set_position(cog);
641  }
642 }
643 
644 
645 template<typename MeshType, typename RealType>
647 {
648  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
649 
650  typename MeshType::EdgeIter e_it;
651  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
652  typename MeshType::HalfedgeHandle heh1, heh2;
653 
654  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it) {
655 
656  cog = zero_point;
657  unsigned int valence = 2;
658 
659  heh1 = mesh_.halfedge_handle(*e_it, 0);
660  heh2 = mesh_.opposite_halfedge_handle(heh1);
661  cog += mesh_.data(mesh_.to_vertex_handle(heh1)).position();
662  cog += mesh_.data(mesh_.to_vertex_handle(heh2)).position();
663 
664  if (!mesh_.is_boundary(heh1)) {
665  cog += mesh_.data(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh1))).position();
666  ++valence;
667  }
668 
669  if (!mesh_.is_boundary(heh2)) {
670  cog += mesh_.data(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh2))).position();
671  ++valence;
672  }
673 
674  cog /= valence;
675 
676  mesh_.data(*e_it).set_position(cog);
677  }
678 }
679 
680 
681 template<typename MeshType, typename RealType>
683 {
684  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
685 
686  typename MeshType::EdgeIter e_it;
687  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
688  typename MeshType::HalfedgeHandle heh;
689 
690  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it) {
691 
692  cog = zero_point;
693 
694  for (int i = 0; i <= 1; ++i) {
695 
696  heh = mesh_.halfedge_handle(*e_it, i);
697  if (!mesh_.is_boundary(heh))
698  {
699  cog += mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh))) * (0.5 - _c);
700  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * _c;
701  }
702  else
703  {
704  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position();
705  }
706  }
707 
708  mesh_.data(*e_it).set_position(cog);
709  }
710 }
711 
712 
713 template<typename MeshType, typename RealType>
715 {
716  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
717 
718  typename MeshType::EdgeIter e_it;
719  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
720  typename MeshType::HalfedgeHandle heh;
721  typename MeshType::VertexOHalfedgeIter voh_it;
722  unsigned int valence[2], i;
723 
724  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it) {
725 
726  cog = zero_point;
727 
728  for (i = 0; i <= 1; ++i)
729  {
730  heh = mesh_.halfedge_handle(*e_it, i);
731  valence[i] = 0;
732 
733  // look for lowest valence vertex
734  for (voh_it = mesh_.voh_iter(mesh_.to_vertex_handle(heh)); voh_it; ++voh_it)
735  {
736  ++valence[i];
737  }
738  }
739 
740  if (valence[0] < valence[1])
741  i = 0;
742  else
743  i = 1;
744 
745  heh = mesh_.halfedge_handle(*e_it, i);
746 
747  if (!mesh_.is_boundary(heh)) {
748  cog += mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh))) * (_gamma);
749  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * (1.0 - 3.0 * _gamma);
750  } else {
751  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * (1.0 - 2.0 * _gamma);
752  }
753 
754 
755  heh = mesh_.halfedge_handle(*e_it, 1-i);
756 
757  if (!mesh_.is_boundary(heh))
758  {
759  cog += mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh))) * (_gamma);
760  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * _gamma;
761  }
762  else
763  {
764  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * 2.0 * _gamma;
765  }
766 
767  mesh_.data(*e_it).set_position(cog);
768  }
769 }
770 
771 
772 template<typename MeshType, typename RealType>
774 {
775  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
776 
777  typename MeshType::EdgeIter e_it;
778  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
779  typename MeshType::HalfedgeHandle heh;
780  typename MeshType::VertexOHalfedgeIter voh_it;
781  unsigned int valence[2], i;
782  scalar_t gamma;
783 
784  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it) {
785 
786  cog = zero_point;
787 
788  for (i = 0; i <= 1; ++i) {
789 
790  heh = mesh_.halfedge_handle(*e_it, i);
791  valence[i] = 0;
792 
793  // look for lowest valence vertex
794  for (voh_it = mesh_.voh_iter(mesh_.to_vertex_handle(heh)); voh_it; ++voh_it)
795  {
796  ++valence[i];
797  }
798  }
799 
800  if (valence[0] < valence[1])
801  i = 0;
802  else
803  i = 1;
804 
805  gamma = _coeff(valence[i]);
806 
807  heh = mesh_.halfedge_handle(*e_it, i);
808 
809  if (!mesh_.is_boundary(heh))
810  {
811  cog += mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh))) * (gamma);
812  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * (1.0 - 3.0 * gamma);
813  }
814  else
815  {
816  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * (1.0 - 2.0 * gamma);
817  }
818 
819 
820  heh = mesh_.halfedge_handle(*e_it, 1-i);
821 
822  if (!mesh_.is_boundary(heh)) {
823  cog += mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh))) * (gamma);
824  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * gamma;
825  } else {
826  cog += mesh_.data(mesh_.to_vertex_handle(heh)).position() * 2.0 * gamma;
827  }
828 
829  mesh_.data(*e_it).set_position(cog);
830  }
831 }
832 
833 
834 template<typename MeshType, typename RealType>
836 {
837  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
838 
839  typename MeshType::VertexIter v_it;
840  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
841  typename MeshType::VertexEdgeIter ve_it;
842 
843  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
844  {
845  unsigned int valence = 0;
846  cog = zero_point;
847 
848  for (ve_it = mesh_.ve_iter(*v_it); ve_it; ++ve_it) {
849  cog += mesh_.data(ve_it).position();
850  ++valence;
851  }
852 
853  cog /= valence;
854 
855  mesh_.data(*v_it).set_position(cog);
856  }
857 }
858 
859 
860 template<typename MeshType, typename RealType>
862 {
863  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
864 
865  typename MeshType::VertexIter v_it;
866  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
867  typename MeshType::VertexOHalfedgeIter voh_it;
868  scalar_t c;
869 
870  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
871  {
872  unsigned int valence = 0;
873  cog = zero_point;
874 
875  for (voh_it = mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it)
876  {
877  ++valence;
878  }
879 
880  // Coefficients always work on double so we cast them to the correct scalar here
881  c = static_cast<scalar_t>(_coeff(valence));
882 
883  for (voh_it = mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
884  cog += mesh_.data(mesh_.edge_handle(*voh_it)).position() * c;
885  cog += mesh_.data(mesh_.edge_handle(mesh_.next_halfedge_handle(*voh_it))).position() * (1.0 - c);
886  }
887 
888  cog /= valence;
889 
890  mesh_.data(*v_it).set_position(cog);
891  }
892 }
893 
894 
895 template<typename MeshType, typename RealType>
897 {
898  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
899  typename MeshType::VertexIter v_it;
900  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
901  typename MeshType::VertexOHalfedgeIter voh_it;
902 
903  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) {
904  unsigned int valence = 0;
905  cog = zero_point;
906 
907  for (voh_it = mesh_.voh_iter(*v_it); voh_it; ++voh_it) {
908  ++valence;
909  }
910 
911  for (voh_it = mesh_.voh_iter(*v_it); voh_it; ++voh_it) {
912  cog += mesh_.data(mesh_.edge_handle(*voh_it)).position() * _c;
913  cog += mesh_.data(mesh_.edge_handle(mesh_.next_halfedge_handle(*voh_it))).position() * (1.0 - _c);
914  }
915 
916  cog /= valence;
917 
918  mesh_.data(*v_it).set_position(cog);
919  }
920 }
921 
922 
923 template<typename MeshType, typename RealType>
925 {
926  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
927 
928  typename MeshType::FaceIter f_it;
929  typename MeshType::FaceEdgeIter fe_it;
930  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
931 
932  for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) {
933  unsigned int valence = 0;
934  cog = zero_point;
935 
936  for (fe_it = mesh_.fe_iter(*f_it); fe_it; ++fe_it) {
937  ++valence;
938  cog += mesh_.data(fe_it).position();
939  }
940 
941  cog /= valence;
942  mesh_.data(*f_it).set_position(cog);
943  }
944 }
945 
946 
947 template<typename MeshType, typename RealType>
949 {
950  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
951 
952  typename MeshType::EdgeIter e_it;
953  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
954 
955  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it) {
956  unsigned int valence = 0;
957  cog = zero_point;
958 
959  if (mesh_.face_handle(mesh_.halfedge_handle(*e_it, 0)).is_valid()) {
960  cog += mesh_.data(mesh_.face_handle(mesh_.halfedge_handle(*e_it, 0))).position();
961  ++valence;
962  }
963 
964  if (mesh_.face_handle(mesh_.halfedge_handle(*e_it, 1)).is_valid()) {
965  cog += mesh_.data(mesh_.face_handle(mesh_.halfedge_handle(*e_it, 1))).position();
966  ++valence;
967  }
968 
969  cog /= valence;
970  mesh_.data(*e_it).set_position(cog);
971  }
972 }
973 
974 
975 template<typename MeshType, typename RealType>
977 {
978  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
979 
980  typename MeshType::EdgeIter e_it;
981  typename MeshType::Point cog;
982 
983  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it)
984  {
985  cog = mesh_.data(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0))).position();
986  cog += mesh_.data(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1))).position();
987  cog /= 2.0;
988  mesh_.data(*e_it).set_position(cog);
989  }
990 }
991 
992 
993 template<typename MeshType, typename RealType>
995 {
996  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
997 
998  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
999  typename MeshType::VertexVertexIter vv_it;
1000  typename MeshType::VertexIter v_it;
1001  std::vector<typename MeshType::Point> point_vector;
1002 
1003  point_vector.clear();
1004 
1005  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) {
1006 
1007  unsigned int valence = 0;
1008  cog = zero_point;
1009 
1010  for (vv_it = mesh_.vv_iter(*v_it); vv_it; ++vv_it) {
1011  cog += vv_it->position();
1012  ++valence;
1013  }
1014  cog /= valence;
1015  point_vector.push_back(cog);
1016  }
1017 
1018  for (v_it = mesh_.vertices_end(); v_it != mesh_.vertices_begin(); )
1019  {
1020  --v_it;
1021  mesh_.data(*v_it).set_position(point_vector.back());
1022  point_vector.pop_back();
1023  }
1024 }
1025 
1026 
1027 template<typename MeshType, typename RealType>
1029 {
1030  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
1031 
1032  typename MeshType::Point cog,
1033  zero_point(0.0, 0.0, 0.0);
1034  typename MeshType::VertexVertexIter vv_it;
1035  typename MeshType::VertexIter v_it;
1036  scalar_t c;
1037  std::vector<typename MeshType::Point> point_vector;
1038 
1039  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
1040  {
1041  unsigned int valence = 0;
1042  cog = zero_point;
1043 
1044  for (vv_it = mesh_.vv_iter(*v_it); vv_it; ++vv_it)
1045  {
1046  cog += vv_it->position();
1047  ++valence;
1048  }
1049  cog /= valence;
1050  c = _coeff(valence);
1051  cog = cog * (1 - c) + mesh_.data(*v_it).position() * c;
1052  point_vector.push_back(cog);
1053  }
1054  for (v_it = mesh_.vertices_end(); v_it != mesh_.vertices_begin(); )
1055  {
1056  --v_it;
1057  mesh_.data(*v_it).set_position(point_vector.back());
1058  point_vector.pop_back();
1059  }
1060 }
1061 
1062 
1063 template<typename MeshType, typename RealType>
1065 {
1066  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
1067 
1068  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
1069  typename MeshType::VertexVertexIter vv_it;
1070  typename MeshType::VertexIter v_it;
1071  std::vector<typename MeshType::Point> point_vector;
1072 
1073  for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) {
1074 
1075  unsigned int valence = 0;
1076  cog = zero_point;
1077 
1078  for (vv_it = mesh_.vv_iter(*v_it); vv_it; ++vv_it) {
1079  cog += mesh_.data(vv_it).position();
1080  ++valence;
1081  }
1082  cog /= valence;
1083 
1084  cog = cog * (1.0 - _c) + v_it->position() * _c;
1085 
1086  point_vector.push_back(cog);
1087 
1088  }
1089  for (v_it = mesh_.vertices_end(); v_it != mesh_.vertices_begin(); ) {
1090 
1091  --v_it;
1092  mesh_.data(*v_it).set_position(point_vector.back());
1093  point_vector.pop_back();
1094 
1095  }
1096 }
1097 
1098 
1099 template<typename MeshType, typename RealType>
1101 {
1102  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
1103 
1104  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
1105  typename MeshType::EdgeIter e_it;
1106  typename MeshType::HalfedgeHandle heh;
1107  std::vector<typename MeshType::Point> point_vector;
1108 
1109  point_vector.clear();
1110 
1111  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it) {
1112 
1113  unsigned int valence = 0;
1114  cog = zero_point;
1115 
1116  for (int i = 0; i <= 1; ++i) {
1117  heh = mesh_.halfedge_handle(*e_it, i);
1118  if (mesh_.face_handle(heh).is_valid())
1119  {
1120  cog += mesh_.data(mesh_.edge_handle(mesh_.next_halfedge_handle(heh))).position();
1121  cog += mesh_.data(mesh_.edge_handle(mesh_.next_halfedge_handle(mesh_.next_halfedge_handle(heh)))).position();
1122  ++valence;
1123  ++valence;
1124  }
1125  }
1126 
1127  cog /= valence;
1128  point_vector.push_back(cog);
1129  }
1130 
1131  for (e_it = mesh_.edges_end(); e_it != mesh_.edges_begin(); )
1132  {
1133  --e_it;
1134  mesh_.data(*e_it).set_position(point_vector.back());
1135  point_vector.pop_back();
1136  }
1137 }
1138 
1139 
1140 template<typename MeshType, typename RealType>
1142 {
1143  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
1144 
1145  typename MeshType::Point cog, zero_point(0.0, 0.0, 0.0);
1146  typename MeshType::EdgeIter e_it;
1147  typename MeshType::HalfedgeHandle heh;
1148  std::vector<typename MeshType::Point> point_vector;
1149 
1150  point_vector.clear();
1151 
1152  for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it)
1153  {
1154  unsigned int valence = 0;
1155  cog = zero_point;
1156 
1157  for (int i = 0; i <= 1; ++i) {
1158  heh = mesh_.halfedge_handle(*e_it, i);
1159  if (mesh_.face_handle(heh).is_valid())
1160  {
1161  cog += mesh_.data(mesh_.edge_handle(mesh_.next_halfedge_handle(heh))).position() * (1.0 - _c);
1162  cog += mesh_.data(mesh_.edge_handle(mesh_.next_halfedge_handle(mesh_.next_halfedge_handle(heh)))).position() * (1.0 - _c);
1163  ++valence;
1164  ++valence;
1165  }
1166  }
1167 
1168  cog /= valence;
1169  cog += mesh_.data(e_it).position() * _c;
1170  point_vector.push_back(cog);
1171  }
1172 
1173  for (e_it = mesh_.edges_end(); e_it != mesh_.edges_begin(); ) {
1174 
1175  --e_it;
1176  mesh_.data(*e_it).set_position(point_vector.back());
1177  point_vector.pop_back();
1178  }
1179 }
1180 
1181 
1183 template<typename MeshType, typename RealType>
1185 {
1186  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
1187 
1188  // Define Halfedge Handles
1189  typename MeshType::HalfedgeHandle heh5(_heh);
1190  typename MeshType::HalfedgeHandle heh6(mesh_.next_halfedge_handle(_heh));
1191 
1192  // Cycle around the polygon to find correct Halfedge
1193  for (; mesh_.next_halfedge_handle(mesh_.next_halfedge_handle(heh5)) != _heh;
1194  heh5 = mesh_.next_halfedge_handle(heh5)) {};
1195 
1196  typename MeshType::HalfedgeHandle heh2(mesh_.next_halfedge_handle(heh5));
1197  typename MeshType::HalfedgeHandle
1198  heh3(mesh_.new_edge(mesh_.to_vertex_handle(_heh),
1199  mesh_.to_vertex_handle(heh5)));
1200  typename MeshType::HalfedgeHandle heh4(mesh_.opposite_halfedge_handle(heh3));
1201 
1202  // Old and new Face
1203  typename MeshType::FaceHandle fh_old(mesh_.face_handle(heh6));
1204  typename MeshType::FaceHandle fh_new(mesh_.new_face());
1205 
1206  // Init new face
1207  mesh_.data(fh_new).set_position(mesh_.data(fh_old).position());
1208 
1209  // Re-Set Handles around old Face
1210  mesh_.set_next_halfedge_handle(heh4, heh6);
1211  mesh_.set_next_halfedge_handle(heh5, heh4);
1212 
1213  mesh_.set_face_handle(heh4, fh_old);
1214  mesh_.set_face_handle(heh5, fh_old);
1215  mesh_.set_face_handle(heh6, fh_old);
1216  mesh_.set_halfedge_handle(fh_old, heh4);
1217 
1218  // Re-Set Handles around new Face
1219  mesh_.set_next_halfedge_handle(_heh, heh3);
1220  mesh_.set_next_halfedge_handle(heh3, heh2);
1221 
1222  mesh_.set_face_handle(_heh, fh_new);
1223  mesh_.set_face_handle(heh2, fh_new);
1224  mesh_.set_face_handle(heh3, fh_new);
1225 
1226  mesh_.set_halfedge_handle(fh_new, _heh);
1227 }
1228 
1229 
1231 template<typename MeshType, typename RealType>
1232 typename MeshType::VertexHandle
1234 {
1235  assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
1236 
1237  HalfedgeHandle heh1;
1238  HalfedgeHandle heh2;
1239  HalfedgeHandle heh3;
1240  HalfedgeHandle temp_heh;
1241 
1242  VertexHandle
1243  vh,
1244  vh1(mesh_.to_vertex_handle(_heh)),
1245  vh2(mesh_.from_vertex_handle(_heh));
1246 
1247  // Calculate and Insert Midpoint of Edge
1248  vh = mesh_.add_vertex((mesh_.point(vh2) + mesh_.point(vh1)) / static_cast<typename MeshType::Point::value_type>(2.0) );
1249  // Re-Set Handles
1250  heh2 = mesh_.opposite_halfedge_handle(_heh);
1251 
1252  if (!mesh_.is_boundary(mesh_.edge_handle(_heh))) {
1253 
1254  for (temp_heh = mesh_.next_halfedge_handle(heh2);
1255  mesh_.next_halfedge_handle(temp_heh) != heh2;
1256  temp_heh = mesh_.next_halfedge_handle(temp_heh) ) {}
1257  } else {
1258  for (temp_heh = _heh;
1259  mesh_.next_halfedge_handle(temp_heh) != heh2;
1260  temp_heh = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(temp_heh))) {}
1261  }
1262 
1263  heh1 = mesh_.new_edge(vh, vh1);
1264  heh3 = mesh_.opposite_halfedge_handle(heh1);
1265  mesh_.set_vertex_handle(_heh, vh);
1266  mesh_.set_next_halfedge_handle(temp_heh, heh3);
1267  mesh_.set_next_halfedge_handle(heh1, mesh_.next_halfedge_handle(_heh));
1268  mesh_.set_next_halfedge_handle(_heh, heh1);
1269  mesh_.set_next_halfedge_handle(heh3, heh2);
1270  if (mesh_.face_handle(heh2).is_valid()) {
1271  mesh_.set_face_handle(heh3, mesh_.face_handle(heh2));
1272  mesh_.set_halfedge_handle(mesh_.face_handle(heh3), heh3);
1273  }
1274  mesh_.set_face_handle(heh1, mesh_.face_handle(_heh));
1275  mesh_.set_halfedge_handle(vh, heh1);
1276  mesh_.set_halfedge_handle(mesh_.face_handle(_heh), _heh);
1277  mesh_.set_halfedge_handle(vh1, heh3);
1278 
1279  return vh;
1280 }
1281 
1282 
1283 //=============================================================================
1284 } // END_NS_UNIFORM
1285 } // END_NS_SUBDIVIDER
1286 } // END_NS_OPENMESH
1287 //=============================================================================
1288 #endif // OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITE_CC defined
1289 //=============================================================================
1290 
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
void corner_cutting(HalfedgeHandle _heh)
Corner Cutting.
Definition: CompositeT_impl.hh:1184
void Tvv3()
Split Face, using Vertex information (1-3 split)
Definition: CompositeT_impl.hh:92
void EF()
Edge to face averaging.
Definition: CompositeT_impl.hh:924
void VVc(Coeff &_coeff)
Vertex to vertex averaging, weighted.
Definition: CompositeT_impl.hh:1028
void VF()
Vertex to Face Averaging.
Definition: CompositeT_impl.hh:287
void FV()
Face to vertex averaging.
Definition: CompositeT_impl.hh:534
void VFa(Coeff &_coeff)
Vertex to Face Averaging, weighted.
Definition: CompositeT_impl.hh:311
void FVc(Coeff &_coeff)
Weighted face to vertex Averaging with flaps.
Definition: CompositeT_impl.hh:559
bool prepare(MeshType &_m) override
Prepare mesh, e.g. add properties.
Definition: CompositeT_impl.hh:76
void EVc(Coeff &_coeff)
Weighted edge to vertex averaging.
Definition: CompositeT_impl.hh:861
void VdEg(Coeff &_coeff)
Weigthed vertex to edge averaging, using diamond of edges for irregular vertices.
Definition: CompositeT_impl.hh:773
void VdEc(scalar_t _c)
Weighted vertex to edge averaging, using diamond of edges.
Definition: CompositeT_impl.hh:682
void FE()
Face to edge averaging.
Definition: CompositeT_impl.hh:948
void FF()
Face to face averaging.
Definition: CompositeT_impl.hh:423
void EV()
Edge to vertex averaging.
Definition: CompositeT_impl.hh:835
VertexHandle split_edge(HalfedgeHandle _heh)
Split Edge.
Definition: CompositeT_impl.hh:1233
void FFc(Coeff &_coeff)
Weighted face to face averaging.
Definition: CompositeT_impl.hh:459
void EdEc(scalar_t _c)
Weighted edge to edge averaging w/ flap rule.
Definition: CompositeT_impl.hh:1141
void VE()
VE Step (Vertex to Edge Averaging)
Definition: CompositeT_impl.hh:976
void Tvv4()
Split Face, using Vertex information (1-4 split)
Definition: CompositeT_impl.hh:156
void VdE()
Vertex to edge averaging, using diamond of edges.
Definition: CompositeT_impl.hh:646
void Tfv()
Split Face, using Face Information.
Definition: CompositeT_impl.hh:211
void VV()
Vertex to vertex averaging.
Definition: CompositeT_impl.hh:994
void EdE()
Edge to edge averaging w/ flap rule.
Definition: CompositeT_impl.hh:1100
Abstract base class for coefficient functions.
Definition: CompositeT.hh:158

Project OpenMesh, ©  Visual Computing Institute, RWTH Aachen. Documentation generated using doxygen .