OpenMesh
CompositeT_impl.hh
Go to the documentation of this file.
1/* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2025, 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
67namespace OpenMesh { // BEGIN_NS_OPENMESH
68namespace Subdivider { // BEGIN_NS_DECIMATER
69namespace Uniform { // BEGIN_NS_UNIFORM
70
71
72//== IMPLEMENTATION ==========================================================
73
74
75template <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
91template<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
155template<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;
182 // Split each edge
183 e_it = mesh_.edges_begin();
184 for (j = 0; j < n_edges; ++j) {
186 vh = split_edge(mesh_.halfedge_handle(*e_it, 0));
187 mesh_.data(vh).set_position(zero_point);
189 ++e_it;
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)));
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;
207}
208
210template<typename MeshType, typename RealType>
212{
213 assert(p_mesh_); MeshType& mesh_ = *p_mesh_;
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
286template<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
310template<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
367template<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
422template<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
458template<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
498template<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
533template<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
558template<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
604template<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
645template<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
681template<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
713template<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
772template<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
834template<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
860template<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
895template<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
923template<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
947template<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
975template<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
993template<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
1027template<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
1063template<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
1099template<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
1140template<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
1183template<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
1231template<typename MeshType, typename RealType>
1232typename 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.
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 .