48 #define BASE_REMESHERT_C 54 #include "BaseRemesherT.hh" 57 #include "DiffGeoT.hh" 60 #include <OpenMesh/Core/Utils/Property.hh> 78 : mesh_(_mesh), refmesh_(0), bsp_(0), nothing_selected_(true),progress_(_progress) {
100 BaseRemesherT<Mesh>::
103 typename Mesh::VIter v_it, v_end;
104 typename Mesh::FIter f_it, f_end;
105 typename Mesh::CFVIter fv_it;
106 typename Mesh::VHandle v0, v1, v2;
110 if (bsp_) delete_reference();
113 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
115 mesh_.status(*v_it).set_tagged(!mesh_.status(*v_it).locked());
120 refmesh_ =
new Mesh();
123 mesh_.add_property(vhandles);
125 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
127 if (mesh_.status(*v_it).tagged())
128 mesh_.property(vhandles, *v_it) = refmesh_->
add_vertex(mesh_.point(*v_it));
130 for (f_it=mesh_.faces_begin(), f_end=mesh_.faces_end();
133 fv_it = mesh_.cfv_iter(*f_it);
138 if (mesh_.status(v0).tagged() &&
139 mesh_.status(v1).tagged() &&
140 mesh_.status(v2).tagged())
142 refmesh_->add_face( mesh_.property(vhandles, v0),
143 mesh_.property(vhandles, v1),
144 mesh_.property(vhandles, v2) );
149 mesh_.remove_property(vhandles);
152 refmesh_->request_face_normals();
153 refmesh_->request_vertex_normals();
158 bsp_ =
new BSP(*refmesh_);
159 bsp_->
reserve(refmesh_->n_faces());
160 for (f_it=refmesh_->faces_begin(), f_end=refmesh_->faces_end();
163 bsp_->
build(10, 100);
170 template <
class Mesh>
172 BaseRemesherT<Mesh>::
175 delete bsp_; bsp_ = 0;
176 delete refmesh_; refmesh_ = 0;
183 template <
class Mesh>
185 BaseRemesherT<Mesh>::
189 typename Mesh::FaceHandle fh = bsp_->
nearest(p).handle;
191 if ( ! fh.is_valid() )
194 typename Mesh::CFVIter fv_it = refmesh_->cfv_iter(fh);
197 const typename Mesh::Point& p0 = refmesh_->point(*fv_it);
199 const typename Mesh::Point& p1 = refmesh_->point(*(++fv_it));
201 const typename Mesh::Point& p2 = refmesh_->point(*(++fv_it));
207 mesh_.set_point(_vh, p);
212 p[0] = p[1] = p[2] = 1.0/3.0;
221 mesh_.set_normal(_vh, n);
228 template <
class Mesh>
230 BaseRemesherT<Mesh>::
231 remesh(
unsigned int _iters,
232 unsigned int _area_iters,
233 bool _use_projection,
234 Selection _selection) {
238 if (_selection == VERTEX_SELECTION)
240 else if (_selection == FACE_SELECTION)
242 remeshh(_iters, _area_iters, _use_projection);
244 catch (std::bad_alloc&)
247 omerr() <<
"Remeshig: Out of memory\n";
255 template <
class Mesh>
260 typename Mesh::EIter e_it, e_end;
261 typename Mesh::VIter v_it, v_end;
262 typename Mesh::FIter f_it, f_end;
263 typename Mesh::CFVIter fv_it;
264 typename Mesh::CVOHIter vh_it;
265 typename Mesh::VHandle v0, v1;
266 typename Mesh::FHandle f0, f1;
270 mesh_.request_vertex_status();
271 mesh_.request_edge_status();
272 mesh_.request_face_status();
277 nothing_selected_ =
true;
278 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
280 if (mesh_.status(*v_it).selected())
281 { nothing_selected_ =
false;
break; }
283 if (nothing_selected_)
284 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
286 mesh_.status(*v_it).set_selected(
true);
291 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
293 mesh_.status(*v_it).set_locked(!mesh_.status(*v_it).selected());
295 for (e_it=mesh_.edges_begin(), e_end=mesh_.edges_end();
298 v0 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
299 v1 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1));
300 mesh_.status(*e_it).set_locked(mesh_.status(v0).locked() ||
301 mesh_.status(v1).locked());
309 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
312 if (mesh_.status(*v_it).feature())
315 for (vh_it=mesh_.cvoh_iter(*v_it); vh_it.is_valid(); ++vh_it)
316 if (mesh_.status(mesh_.edge_handle(*vh_it)).feature())
318 if (c!=2) mesh_.status(*v_it).set_locked(
true);
330 mesh_.add_property(valences_);
331 mesh_.add_property(update_);
332 mesh_.add_property(area_);
338 template <
class Mesh>
343 typename Mesh::EIter e_it, e_end;
344 typename Mesh::VIter v_it, v_end;
345 typename Mesh::FIter f_it, f_end;
346 typename Mesh::CFVIter fv_it;
347 typename Mesh::CVOHIter vh_it;
348 typename Mesh::VHandle v0, v1;
349 typename Mesh::FHandle f0, f1;
353 mesh_.request_vertex_status();
354 mesh_.request_edge_status();
355 mesh_.request_face_status();
358 nothing_selected_ =
true;
359 for (f_it = mesh_.faces_begin(), f_end = mesh_.faces_end(); f_it != f_end;
362 if (mesh_.status(*f_it).selected())
364 nothing_selected_ =
false;
369 if (nothing_selected_)
370 MeshSelection::selectAllFaces(&mesh_);
375 for (v_it = mesh_.vertices_begin(), v_end = mesh_.vertices_end();
376 v_it != v_end; ++v_it)
378 bool all_faces_selected =
true;
381 vf_it.is_valid(); ++vf_it)
383 if (!mesh_.status(*vf_it).selected())
385 all_faces_selected =
false;
389 mesh_.status(*v_it).set_locked(!all_faces_selected);
392 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end();
393 e_it != e_end; ++e_it)
395 if (mesh_.is_boundary(*e_it))
397 mesh_.status(*e_it).set_locked(
true);
401 f0 = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 0));
402 f1 = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 1));
404 mesh_.status(*e_it).set_locked(!(mesh_.status(f0).selected() && mesh_.status(f1).selected()));
408 MeshSelection::clearFaceSelection(&mesh_);
413 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
416 if (mesh_.status(*v_it).feature())
419 for (vh_it=mesh_.cvoh_iter(*v_it); vh_it.is_valid(); ++vh_it)
420 if (mesh_.status(mesh_.edge_handle(*vh_it)).feature())
422 if (c!=2) mesh_.status(*v_it).set_locked(
true);
434 mesh_.add_property(valences_);
435 mesh_.add_property(update_);
436 mesh_.add_property(area_);
443 template <
class Mesh>
447 unsigned int _area_iters,
bool _use_projection) {
449 double progress_step = 100.0 / (((double)_iters/4.0 + (
double)_area_iters));
450 double total_progress = 0.0;
452 for (
unsigned int i = 0; i < _iters; ++i) {
455 if(progress_ != NULL) {
456 total_progress += progress_step;
457 progress_->sendProgressSignal(total_progress);
460 collapse_short_edges();
461 if(progress_ != NULL) {
462 total_progress += progress_step;
463 progress_->sendProgressSignal(total_progress);
467 if(progress_ != NULL) {
468 total_progress += progress_step;
469 progress_->sendProgressSignal(total_progress);
472 tangential_smoothing(_use_projection);
473 if(progress_ != NULL) {
474 total_progress += progress_step;
475 progress_->sendProgressSignal(total_progress);
480 balanace_area(_area_iters, _use_projection);
481 if(progress_ != NULL) {
482 total_progress += progress_step;
483 progress_->sendProgressSignal(total_progress);
495 template <
class Mesh>
500 typename Mesh::EIter e_it, e_end;
501 typename Mesh::VIter v_it, v_end;
502 typename Mesh::FIter f_it, f_end;
503 typename Mesh::CFVIter fv_it;
504 typename Mesh::CVOHIter vh_it;
505 typename Mesh::VHandle v0, v1;
506 typename Mesh::FHandle f0, f1;
510 mesh_.remove_property(valences_);
511 mesh_.remove_property(update_);
512 mesh_.remove_property(area_);
520 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
523 mesh_.status(*v_it).set_locked(
false);
525 for (e_it=mesh_.edges_begin(), e_end=mesh_.edges_end();
528 mesh_.status(*e_it).set_locked(
false);
533 if (nothing_selected_)
534 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
536 mesh_.status(*v_it).set_selected(
false);
541 mesh_.release_vertex_status();
542 mesh_.release_edge_status();
543 mesh_.release_face_status();
550 template <
class Mesh>
555 typename Mesh::VIter v_it, v_end;
556 typename Mesh::EIter e_it, e_end;
557 typename Mesh::VHandle v0, v1, vh;
558 typename Mesh::EHandle eh, e0, e1;
559 typename Mesh::FHandle f0, f1, f2, f3;
561 bool ok, is_feature, is_boundary;
565 for (v_it = mesh_.vertices_begin(), v_end = mesh_.vertices_end(); v_it != v_end; ++v_it)
566 mesh_.status(*v_it).set_tagged(
false);
570 mesh_.get_property_handle(pids,
"Nastran PIDs");
573 for (ok =
false, i = 0; !ok && i < 100; ++i) {
576 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end(); e_it != e_end; ++e_it) {
577 v0 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
578 v1 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1));
580 if (!mesh_.status(*e_it).locked() && is_too_long(v0, v1)) {
584 is_feature = mesh_.status(*e_it).feature();
585 is_boundary = mesh_.is_boundary(*e_it);
588 mesh_.
split(*e_it, vh);
590 mesh_.status(vh).set_selected(
true);
593 eh = (is_boundary ? mesh_.edge_handle(mesh_.n_edges() - 2) : mesh_.edge_handle(mesh_.n_edges() - 3));
595 mesh_.status(eh).set_feature(
true);
597 project_to_reference(vh);
602 e1 = (is_boundary ? mesh_.edge_handle(mesh_.n_edges() - 2) : mesh_.edge_handle(mesh_.n_edges() - 3));
604 f0 = mesh_.face_handle(mesh_.halfedge_handle(e0, 0));
605 f1 = mesh_.face_handle(mesh_.halfedge_handle(e0, 1));
606 f2 = mesh_.face_handle(mesh_.halfedge_handle(e1, 0));
607 f3 = mesh_.face_handle(mesh_.halfedge_handle(e1, 1));
609 if (f0.is_valid() && f3.is_valid()) mesh_.property(pids, f3) = mesh_.property(pids, f0);
611 if (f1.is_valid() && f2.is_valid()) mesh_.property(pids, f2) = mesh_.property(pids, f1);
619 if (i == 100) omlog() <<
"split break\n";
626 template <
class Mesh>
631 typename Mesh::EIter e_it, e_end;
632 typename Mesh::CVVIter vv_it;
633 typename Mesh::VHandle v0, v1;
634 typename Mesh::HHandle h0, h1, h01, h10;
636 bool ok, skip, b0, b1, l0, l1, f0, f1;
640 for (ok =
false, i = 0; !ok && i < 100; ++i) {
643 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end(); e_it != e_end; ++e_it) {
644 if (!mesh_.status(*e_it).deleted() && !mesh_.status(*e_it).locked()) {
645 h10 = mesh_.halfedge_handle(*e_it, 0);
646 h01 = mesh_.halfedge_handle(*e_it, 1);
647 v0 = mesh_.to_vertex_handle(h10);
648 v1 = mesh_.to_vertex_handle(h01);
650 if (is_too_short(v0, v1)) {
652 b0 = mesh_.is_boundary(v0);
653 b1 = mesh_.is_boundary(v1);
654 l0 = mesh_.status(v0).locked();
655 l1 = mesh_.status(v1).locked();
656 f0 = mesh_.status(v0).feature();
657 f1 = mesh_.status(v1).feature();
658 hcol01 = hcol10 =
true;
662 if (!mesh_.is_boundary(*e_it))
690 int feature_valence_0 = 0;
691 for (
auto eh : mesh_.ve_range(v0))
692 if (mesh_.status(eh).feature())
694 if (feature_valence_0 == 2)
696 if (!mesh_.status(*e_it).feature())
699 else if (feature_valence_0 != 0)
704 int feature_valence_1 = 0;
705 for (
auto eh : mesh_.ve_range(v1))
706 if (mesh_.status(eh).feature())
708 if (feature_valence_1 == 2)
710 if (!mesh_.status(*e_it).feature())
713 else if (feature_valence_1 != 0)
718 h0 = mesh_.prev_halfedge_handle(h01);
719 h1 = mesh_.next_halfedge_handle(h10);
720 if (mesh_.status(mesh_.edge_handle(h0)).feature() || mesh_.status(mesh_.edge_handle(h1)).feature())
722 h0 = mesh_.prev_halfedge_handle(h10);
723 h1 = mesh_.next_halfedge_handle(h01);
724 if (mesh_.status(mesh_.edge_handle(h0)).feature() || mesh_.status(mesh_.edge_handle(h1)).feature())
729 hcol01 = mesh_.is_collapse_ok(h01);
731 hcol10 = mesh_.is_collapse_ok(h10);
734 if (hcol01 && hcol10) {
735 if (mesh_.valence(v0) < mesh_.valence(v1))
742 if (collapse_flips_normal(h01))
744 if (collapse_flips_normal(h10))
751 for (vv_it = mesh_.cvv_iter(v1); vv_it.is_valid() && !skip; ++vv_it)
752 if (is_too_long(v0, *vv_it))
765 for (vv_it = mesh_.cvv_iter(v0); vv_it.is_valid() && !skip; ++vv_it)
766 if (is_too_long(v1, *vv_it))
779 mesh_.garbage_collection();
782 omlog() <<
"collapse break\n";
789 template <
class Mesh>
794 typename Mesh::EIter e_it, e_end;
795 typename Mesh::VIter v_it, v_end;
796 typename Mesh::VHandle v0, v1, v2, v3, vh;
797 typename Mesh::HHandle hh;
799 typename Mesh::FHandle fh;
801 int val0, val1, val2, val3;
802 int val_opt0, val_opt1, val_opt2, val_opt3;
803 int ve0, ve1, ve2, ve3, ve_before, ve_after;
808 for (v_it = mesh_.vertices_begin(), v_end = mesh_.vertices_end(); v_it != v_end; ++v_it)
809 mesh_.property(valences_, *v_it) = mesh_.valence(*v_it);
812 for (ok =
false, i = 0; !ok && i < 100; ++i) {
815 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end(); e_it != e_end; ++e_it) {
816 if (!mesh_.status(*e_it).locked() && !mesh_.status(*e_it).feature()) {
817 hh = mesh_.halfedge_handle(*e_it, 0);
818 v0 = mesh_.to_vertex_handle(hh);
819 v2 = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh));
820 if ( !mesh_.next_halfedge_handle(hh).is_valid() ) {
821 std::cerr <<
"Error v2" << std::endl;
824 hh = mesh_.halfedge_handle(*e_it, 1);
825 v1 = mesh_.to_vertex_handle(hh);
826 v3 = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh));
827 if ( !mesh_.next_halfedge_handle(hh).is_valid() ) {
828 std::cerr <<
"Error v3" << std::endl;
835 if (!mesh_.status(v0).locked() && !mesh_.status(v1).locked() && !mesh_.status(v2).locked()
836 && !mesh_.status(v3).locked()) {
837 val0 = mesh_.property(valences_, v0);
838 val1 = mesh_.property(valences_, v1);
839 val2 = mesh_.property(valences_, v2);
840 val3 = mesh_.property(valences_, v3);
842 val_opt0 = (mesh_.is_boundary(v0) ? 4 : 6);
843 val_opt1 = (mesh_.is_boundary(v1) ? 4 : 6);
844 val_opt2 = (mesh_.is_boundary(v2) ? 4 : 6);
845 val_opt3 = (mesh_.is_boundary(v3) ? 4 : 6);
847 ve0 = (val0 - val_opt0);
849 ve1 = (val1 - val_opt1);
851 ve2 = (val2 - val_opt2);
853 ve3 = (val3 - val_opt3);
856 ve_before = ve0 + ve1 + ve2 + ve3;
863 ve0 = (val0 - val_opt0);
865 ve1 = (val1 - val_opt1);
867 ve2 = (val2 - val_opt2);
869 ve3 = (val3 - val_opt3);
872 ve_after = ve0 + ve1 + ve2 + ve3;
874 if (ve_before > ve_after && mesh_.is_flip_ok(*e_it) && !edge_flip_flips_normal(*e_it)) {
876 --mesh_.property(valences_, v0);
877 --mesh_.property(valences_, v1);
878 ++mesh_.property(valences_, v2);
879 ++mesh_.property(valences_, v3);
888 omlog() <<
"flip break\n";
895 template <
class Mesh>
900 typename Mesh::VIter v_it, v_end(mesh_.vertices_end());
901 typename Mesh::CVVIter vv_it;
906 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
907 mesh_.status(*v_it).set_tagged( !mesh_.status(*v_it).locked() &&
908 !mesh_.status(*v_it).feature() &&
909 !mesh_.is_boundary(*v_it) );
913 double damping = 1.0;
916 for (
int iters=0; iters<10; ++iters)
918 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
920 if (mesh_.status(*v_it).tagged())
924 int feature_valence = 0;
926 for (
auto heh : mesh_.voh_range(*v_it))
928 u += mesh_.point(mesh_.to_vertex_handle(heh));
929 if (mesh_.status(mesh_.edge_handle(heh)).feature())
937 u -= mesh_.point(*v_it);
938 n = mesh_.normal(*v_it);
943 if (feature_valence == 2)
947 for (
auto heh : mesh_.voh_range(*v_it))
949 if (mesh_.status(mesh_.edge_handle(heh)).feature())
951 auto dir = mesh_.point(mesh_.to_vertex_handle(heh)) - mesh_.point(mesh_.from_vertex_handle(heh));
952 if ((dir | feature_dir) > 0)
958 if (feature_dir.sqrnorm() > 0)
959 feature_dir.normalize();
960 u = (feature_dir | u) * feature_dir;
962 else if (feature_valence != 0)
968 mesh_.property(update_, *v_it) = u;
972 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
973 if (mesh_.status(*v_it).tagged())
974 mesh_.point(*v_it) += damping*mesh_.property(update_, *v_it);
977 bool normals_changed =
false;
978 for (
auto fh : mesh_.faces())
982 normals_changed =
true;
990 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
991 if (mesh_.status(*v_it).tagged())
992 mesh_.point(*v_it) -= damping*mesh_.property(update_, *v_it);
999 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1000 mesh_.status(*v_it).set_tagged(
false);
1004 if (_use_projection)
1005 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1006 if (!mesh_.status(*v_it).locked() && !mesh_.status(*v_it).feature())
1007 project_to_reference(*v_it);
1014 template <
class Mesh>
1019 typename Mesh::VIter v_it, v_end(mesh_.vertices_end());
1020 typename Mesh::CVVIter vv_it;
1029 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1031 bool active = ( !mesh_.status(*v_it).locked() &&
1032 !mesh_.status(*v_it).feature() &&
1033 !mesh_.is_boundary(*v_it) );
1036 for (vv_it=mesh_.cvv_iter(*v_it); active && vv_it.is_valid(); ++vv_it)
1037 if (mesh_.is_boundary(*vv_it))
1040 mesh_.status(*v_it).set_tagged( active );
1045 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1047 mesh_.status(*v_it).set_tagged2(
false);
1048 for (vv_it=mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it)
1050 if (mesh_.status(*vv_it).tagged())
1052 mesh_.status(*v_it).set_tagged2(
true);
1060 for (
unsigned int bla=0; bla<_iters; ++bla)
1063 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1064 if (mesh_.status(*v_it).tagged2())
1065 mesh_.property(area_, *v_it) = pow(diffgeo.compute_area(*v_it), 2);
1070 for (
int iters=0; iters<10; ++iters)
1072 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1074 if (mesh_.status(*v_it).tagged())
1079 for (vv_it=mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it)
1081 w = mesh_.property(area_, *vv_it);
1082 u += mesh_.point(*vv_it) * w;
1089 u -= mesh_.point(*v_it);
1090 n = mesh_.normal(*v_it);
1097 mesh_.property(update_, *v_it) = u;
1101 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1102 if (!mesh_.status(*v_it).locked() &&
1103 !mesh_.status(*v_it).feature() &&
1104 !mesh_.is_boundary(*v_it))
1105 mesh_.point(*v_it) += mesh_.property(update_, *v_it);
1110 if (_use_projection)
1111 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1112 if (!mesh_.status(*v_it).locked() && !mesh_.status(*v_it).feature())
1113 project_to_reference(*v_it);
1126 template <
class Mesh>
1131 typename Mesh::EdgeIter e_it, e_end(mesh_.edges_end());
1132 typename Mesh::HalfedgeHandle h;
1133 typename Mesh::Scalar a0, a1, amin, aa(cos(170.0 * M_PI / 180.0));
1134 typename Mesh::VHandle v, vb, vd;
1135 typename Mesh::FHandle fb, fd;
1141 mesh_.get_property_handle(pids,
"Nastran PIDs");
1144 for (e_it=mesh_.edges_begin(); e_it!=e_end; ++e_it)
1146 if (!mesh_.status(*e_it).locked() &&
1147 mesh_.is_flip_ok(*e_it))
1149 h = mesh_.halfedge_handle(*e_it, 0);
1150 a = mesh_.point(mesh_.to_vertex_handle(h));
1152 h = mesh_.next_halfedge_handle(h);
1153 b = mesh_.point(vb=mesh_.to_vertex_handle(h));
1155 h = mesh_.halfedge_handle(*e_it, 1);
1156 c = mesh_.point(mesh_.to_vertex_handle(h));
1158 h = mesh_.next_halfedge_handle(h);
1159 d = mesh_.point(vd=mesh_.to_vertex_handle(h));
1161 a0 = ( (a-b).normalize() | (c-b).normalize() );
1162 a1 = ( (a-d).normalize() | (c-d).normalize() );
1164 if (a0 < a1) { amin = a0; v = vb; }
1165 else { amin = a1; v = vd; }
1171 if (mesh_.status(*e_it).feature() && mesh_.status(v).feature())
1177 fb = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 0));
1178 fd = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 1));
1181 mesh_.property(pids, fb) = mesh_.property(pids, fd);
1183 mesh_.property(pids, fd) = mesh_.property(pids, fb);
1187 if (mesh_.status(*e_it).feature())
1188 mesh_.set_point(v, (a+c)*0.5);
1198 template<
class Mesh>
1203 if (mesh_.is_boundary(_eh))
1206 auto heh = mesh_.halfedge_handle(_eh, 0);
1209 auto p0 = mesh_.point(mesh_.to_vertex_handle(heh));
1210 auto p1 = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(heh)));
1211 auto p2 = mesh_.point(mesh_.from_vertex_handle(heh));
1212 auto p3 = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(mesh_.opposite_halfedge_handle(heh))));
1215 auto n0_before = (p1-p0) % (p2-p0);
1216 auto n1_before = (p2-p0) % (p3-p0);
1219 auto n0_after = (p1-p0) % (p3-p0);
1220 auto n1_after = (p3-p2) % (p1-p2);
1223 if ((n0_before | n0_after) < 0 || (n1_before | n1_after) < 0 ||
1224 (n0_before | n1_after) < 0 || (n1_before | n0_after) < 0)
1231 template<
class Mesh>
1236 if (!mesh_.is_collapse_ok(_heh))
1240 auto fh0 = mesh_.face_handle(_heh);
1241 auto fh1 = mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh));
1243 auto collapsing_vertex = mesh_.from_vertex_handle(_heh);
1244 auto point_before = mesh_.point(collapsing_vertex);
1248 for (
auto fh : mesh_.vf_range(collapsing_vertex))
1252 mesh_.point(collapsing_vertex) = mesh_.point(mesh_.to_vertex_handle(_heh));
1254 bool collapse_ok =
true;
1257 for (
auto fh : mesh_.vf_range(collapsing_vertex))
1259 if (fh != fh0 && fh != fh1)
1262 if ((normal_after | normals_before[i]) <= 0)
1263 collapse_ok =
false;
1269 mesh_.point(collapsing_vertex) = point_before;
1271 return !collapse_ok;
Handle for a face entity.
Kernel::ConstVertexFaceIter ConstVertexFaceIter
Circulator.
Kernel::Normal Normal
Normal type.
Kernel::Point Point
Coordinate type.
void clearVertexSelection(MeshT *_mesh)
Set all vertices to unselected.
void build(unsigned int _max_handles, unsigned int _max_depth)
bool is_valid() const
The handle is valid iff the index is not negative.
void push_back(Handle _h)
Add a handle to the BSP.
void prepare_face_selection()
prepare for remeshing only vertices which are fully surrounded by selected faces (if no face was sele...
bool baryCoord(const VectorT< Scalar, 3 > &_p, const VectorT< Scalar, 3 > &_u, const VectorT< Scalar, 3 > &_v, const VectorT< Scalar, 3 > &_w, VectorT< Scalar, 3 > &_result)
Normal calc_face_normal(FaceHandle _fh) const
Functions for selection on a mesh.
SmartVertexHandle add_vertex(const Point &_p)
Vec::value_type distPointTriangle(const Vec &_p, const Vec &_v0, const Vec &_v1, const Vec &_v2, Vec &_nearestPoint)
distance from point _p to triangle (_v0, _v1, _v2)
SmartVertexHandle split(EdgeHandle _eh, const Point &_p)
Edge split (= 2-to-4 split)
void reserve(size_t _n)
Reserve memory for _n entries.
void update_normals()
Compute normals for all primitives.
NearestNeighbor nearest(const Point &_p) const
Return handle of the nearest neighbor face.
Kernel::Scalar Scalar
Scalar type.
void prepare_vertex_selection()
prepare for remeshing only selected vertices (if no vertex was selected, remesh whole mesh) ...
void update_face_normals()
Update normal vectors for all faces.
void growVertexSelection(MeshT *_mesh)
Grow vertex selection.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.