56 #define BASE_REMESHERT_C
62 #include "BaseRemesherT.hh"
65 #include "DiffGeoT.hh"
68 #include <OpenMesh/Core/Utils/Property.hh>
86 : mesh_(_mesh), refmesh_(0), bsp_(0), progress_(_progress) {
106 template <
class Mesh>
108 BaseRemesherT<Mesh>::
111 typename Mesh::VIter v_it, v_end;
112 typename Mesh::FIter f_it, f_end;
113 typename Mesh::CFVIter fv_it;
114 typename Mesh::VHandle v0, v1, v2;
118 if (bsp_) delete_reference();
121 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
123 mesh_.status(*v_it).set_tagged(!mesh_.status(*v_it).locked());
125 MeshSelection::growVertexSelection(&mesh_);
128 refmesh_ =
new Mesh();
131 mesh_.add_property(vhandles);
133 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
135 if (mesh_.status(*v_it).tagged())
136 mesh_.property(vhandles, *v_it) = refmesh_->
add_vertex(mesh_.point(*v_it));
138 for (f_it=mesh_.faces_begin(), f_end=mesh_.faces_end();
141 fv_it = mesh_.cfv_iter(*f_it);
146 if (mesh_.status(v0).tagged() &&
147 mesh_.status(v1).tagged() &&
148 mesh_.status(v2).tagged())
150 refmesh_->add_face( mesh_.property(vhandles, v0),
151 mesh_.property(vhandles, v1),
152 mesh_.property(vhandles, v2) );
156 MeshSelection::clearVertexSelection(&mesh_);
157 mesh_.remove_property(vhandles);
160 refmesh_->request_face_normals();
161 refmesh_->request_vertex_normals();
166 bsp_ =
new BSP(*refmesh_);
167 bsp_->reserve(refmesh_->n_faces());
168 for (f_it=refmesh_->faces_begin(), f_end=refmesh_->faces_end();
170 bsp_->push_back(*f_it);
171 bsp_->build(10, 100);
178 template <
class Mesh>
180 BaseRemesherT<Mesh>::
183 delete bsp_; bsp_ = 0;
184 delete refmesh_; refmesh_ = 0;
191 template <
class Mesh>
193 BaseRemesherT<Mesh>::
197 typename Mesh::FaceHandle fh = bsp_->nearest(p).handle;
199 if ( ! fh.is_valid() )
202 typename Mesh::CFVIter fv_it = refmesh_->cfv_iter(fh);
205 const typename Mesh::Point& p0 = refmesh_->point(*fv_it);
207 const typename Mesh::Point& p1 = refmesh_->point(*(++fv_it));
209 const typename Mesh::Point& p2 = refmesh_->point(*(++fv_it));
215 mesh_.set_point(_vh, p);
220 p[0] = p[1] = p[2] = 1.0/3.0;
229 mesh_.set_normal(_vh, n);
236 template <
class Mesh>
238 BaseRemesherT<Mesh>::
239 remesh(
unsigned int _iters,
240 unsigned int _area_iters,
241 bool _use_projection,
242 Selection _selection) {
246 if (_selection == VERTEX_SELECTION)
247 prepare_vertex_selection();
248 else if (_selection == FACE_SELECTION)
249 prepare_face_selection();
250 remeshh(_iters, _area_iters, _use_projection);
252 catch (std::bad_alloc&)
255 omerr() <<
"Remeshig: Out of memory\n";
263 template <
class Mesh>
268 typename Mesh::EIter e_it, e_end;
269 typename Mesh::VIter v_it, v_end;
270 typename Mesh::FIter f_it, f_end;
271 typename Mesh::CFVIter fv_it;
272 typename Mesh::CVOHIter vh_it;
273 typename Mesh::VHandle v0, v1;
274 typename Mesh::FHandle f0, f1;
278 mesh_.request_vertex_status();
279 mesh_.request_edge_status();
280 mesh_.request_face_status();
285 nothing_selected_ =
true;
286 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
288 if (mesh_.status(*v_it).selected())
289 { nothing_selected_ =
false;
break; }
291 if (nothing_selected_)
292 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
294 mesh_.status(*v_it).set_selected(
true);
299 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
301 mesh_.status(*v_it).set_locked(!mesh_.status(*v_it).selected());
303 for (e_it=mesh_.edges_begin(), e_end=mesh_.edges_end();
306 v0 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
307 v1 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1));
308 mesh_.status(*e_it).set_locked(mesh_.status(v0).locked() ||
309 mesh_.status(v1).locked());
317 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
320 if (mesh_.status(*v_it).feature())
323 for (vh_it=mesh_.cvoh_iter(*v_it); vh_it.is_valid(); ++vh_it)
324 if (mesh_.status(mesh_.edge_handle(*vh_it)).feature())
326 if (c!=2) mesh_.status(*v_it).set_locked(
true);
338 mesh_.add_property(valences_);
339 mesh_.add_property(update_);
340 mesh_.add_property(area_);
346 template <
class Mesh>
351 typename Mesh::EIter e_it, e_end;
352 typename Mesh::VIter v_it, v_end;
353 typename Mesh::FIter f_it, f_end;
354 typename Mesh::CFVIter fv_it;
355 typename Mesh::CVOHIter vh_it;
356 typename Mesh::VHandle v0, v1;
357 typename Mesh::FHandle f0, f1;
361 mesh_.request_vertex_status();
362 mesh_.request_edge_status();
363 mesh_.request_face_status();
366 nothing_selected_ =
true;
367 for (f_it = mesh_.faces_begin(), f_end = mesh_.faces_end(); f_it != f_end;
370 if (mesh_.status(*f_it).selected())
372 nothing_selected_ =
false;
377 if (nothing_selected_)
378 MeshSelection::selectAllFaces(&mesh_);
383 for (v_it = mesh_.vertices_begin(), v_end = mesh_.vertices_end();
384 v_it != v_end; ++v_it)
386 bool all_faces_selected =
true;
389 vf_it.is_valid(); ++vf_it)
391 if (!mesh_.status(*vf_it).selected())
393 all_faces_selected =
false;
397 mesh_.status(*v_it).set_locked(!all_faces_selected);
400 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end();
401 e_it != e_end; ++e_it)
403 if (mesh_.is_boundary(*e_it))
405 mesh_.status(*e_it).set_locked(
true);
409 f0 = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 0));
410 f1 = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 1));
412 mesh_.status(*e_it).set_locked(!(mesh_.status(f0).selected() && mesh_.status(f1).selected()));
416 MeshSelection::clearFaceSelection(&mesh_);
421 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
424 if (mesh_.status(*v_it).feature())
427 for (vh_it=mesh_.cvoh_iter(*v_it); vh_it.is_valid(); ++vh_it)
428 if (mesh_.status(mesh_.edge_handle(*vh_it)).feature())
430 if (c!=2) mesh_.status(*v_it).set_locked(
true);
442 mesh_.add_property(valences_);
443 mesh_.add_property(update_);
444 mesh_.add_property(area_);
451 template <
class Mesh>
455 unsigned int _area_iters,
bool _use_projection) {
457 double progress_step = 100.0 / (((double)_iters/4.0 + (
double)_area_iters));
458 double total_progress = 0.0;
460 for (
unsigned int i = 0; i < _iters; ++i) {
463 if(progress_ != NULL) {
464 total_progress += progress_step;
465 progress_->sendProgressSignal(total_progress);
468 collapse_short_edges();
469 if(progress_ != NULL) {
470 total_progress += progress_step;
471 progress_->sendProgressSignal(total_progress);
475 if(progress_ != NULL) {
476 total_progress += progress_step;
477 progress_->sendProgressSignal(total_progress);
480 tangential_smoothing(_use_projection);
481 if(progress_ != NULL) {
482 total_progress += progress_step;
483 progress_->sendProgressSignal(total_progress);
488 balanace_area(_area_iters, _use_projection);
489 if(progress_ != NULL) {
490 total_progress += progress_step;
491 progress_->sendProgressSignal(total_progress);
503 template <
class Mesh>
505 BaseRemesherT<Mesh>::
508 typename Mesh::EIter e_it, e_end;
509 typename Mesh::VIter v_it, v_end;
510 typename Mesh::FIter f_it, f_end;
511 typename Mesh::CFVIter fv_it;
512 typename Mesh::CVOHIter vh_it;
513 typename Mesh::VHandle v0, v1;
514 typename Mesh::FHandle f0, f1;
518 mesh_.remove_property(valences_);
519 mesh_.remove_property(update_);
520 mesh_.remove_property(area_);
528 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
531 mesh_.status(*v_it).set_locked(
false);
533 for (e_it=mesh_.edges_begin(), e_end=mesh_.edges_end();
536 mesh_.status(*e_it).set_locked(
false);
541 if (nothing_selected_)
542 for (v_it=mesh_.vertices_begin(), v_end=mesh_.vertices_end();
544 mesh_.status(*v_it).set_selected(
false);
549 mesh_.release_vertex_status();
550 mesh_.release_edge_status();
551 mesh_.release_face_status();
558 template <
class Mesh>
560 BaseRemesherT<Mesh>::
563 typename Mesh::VIter v_it, v_end;
564 typename Mesh::EIter e_it, e_end;
565 typename Mesh::VHandle v0, v1, vh;
566 typename Mesh::EHandle eh, e0, e1;
567 typename Mesh::FHandle f0, f1, f2, f3;
569 bool ok, is_feature, is_boundary;
573 for (v_it = mesh_.vertices_begin(), v_end = mesh_.vertices_end(); v_it != v_end; ++v_it)
574 mesh_.status(*v_it).set_tagged(
false);
578 mesh_.get_property_handle(pids,
"Nastran PIDs");
581 for (ok =
false, i = 0; !ok && i < 100; ++i) {
584 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end(); e_it != e_end; ++e_it) {
585 v0 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
586 v1 = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1));
588 if (!mesh_.status(*e_it).locked() && is_too_long(v0, v1)) {
592 is_feature = mesh_.status(*e_it).feature();
593 is_boundary = mesh_.is_boundary(*e_it);
596 mesh_.
split(*e_it, vh);
598 mesh_.status(vh).set_selected(
true);
601 eh = (is_boundary ? mesh_.edge_handle(mesh_.n_edges() - 2) : mesh_.edge_handle(mesh_.n_edges() - 3));
603 mesh_.status(eh).set_feature(
true);
604 mesh_.status(vh).set_feature(
true);
606 project_to_reference(vh);
611 e1 = (is_boundary ? mesh_.edge_handle(mesh_.n_edges() - 2) : mesh_.edge_handle(mesh_.n_edges() - 3));
613 f0 = mesh_.face_handle(mesh_.halfedge_handle(e0, 0));
614 f1 = mesh_.face_handle(mesh_.halfedge_handle(e0, 1));
615 f2 = mesh_.face_handle(mesh_.halfedge_handle(e1, 0));
616 f3 = mesh_.face_handle(mesh_.halfedge_handle(e1, 1));
618 if (f0.is_valid() && f3.is_valid()) mesh_.property(pids, f3) = mesh_.property(pids, f0);
620 if (f1.is_valid() && f2.is_valid()) mesh_.property(pids, f2) = mesh_.property(pids, f1);
628 if (i == 100) omlog() <<
"split break\n";
635 template <
class Mesh>
637 BaseRemesherT<Mesh>::
638 collapse_short_edges()
640 typename Mesh::EIter e_it, e_end;
641 typename Mesh::CVVIter vv_it;
642 typename Mesh::VHandle v0, v1;
643 typename Mesh::HHandle h0, h1, h01, h10;
645 bool ok, skip, b0, b1, l0, l1, f0, f1;
649 for (ok =
false, i = 0; !ok && i < 100; ++i) {
652 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end(); e_it != e_end; ++e_it) {
653 if (!mesh_.status(*e_it).deleted() && !mesh_.status(*e_it).locked()) {
654 h10 = mesh_.halfedge_handle(*e_it, 0);
655 h01 = mesh_.halfedge_handle(*e_it, 1);
656 v0 = mesh_.to_vertex_handle(h10);
657 v1 = mesh_.to_vertex_handle(h01);
659 if (is_too_short(v0, v1)) {
661 b0 = mesh_.is_boundary(v0);
662 b1 = mesh_.is_boundary(v1);
663 l0 = mesh_.status(v0).locked();
664 l1 = mesh_.status(v1).locked();
665 f0 = mesh_.status(v0).feature();
666 f1 = mesh_.status(v1).feature();
667 hcol01 = hcol10 =
true;
669 if (mesh_.status(*e_it).feature() && !f0 && !f1)
670 std::cerr <<
"Bad luck" << std::endl;
674 if (!mesh_.is_boundary(*e_it))
692 h0 = mesh_.prev_halfedge_handle(h01);
693 h1 = mesh_.next_halfedge_handle(h10);
694 if (mesh_.status(mesh_.edge_handle(h0)).feature() || mesh_.status(mesh_.edge_handle(h1)).feature())
696 h0 = mesh_.prev_halfedge_handle(h10);
697 h1 = mesh_.next_halfedge_handle(h01);
698 if (mesh_.status(mesh_.edge_handle(h0)).feature() || mesh_.status(mesh_.edge_handle(h1)).feature())
703 if (!mesh_.status(*e_it).feature())
707 h0 = mesh_.prev_halfedge_handle(h01);
708 h1 = mesh_.next_halfedge_handle(h10);
709 if (mesh_.status(mesh_.edge_handle(h0)).feature() || mesh_.status(mesh_.edge_handle(h1)).feature())
711 h0 = mesh_.prev_halfedge_handle(h10);
712 h1 = mesh_.next_halfedge_handle(h01);
713 if (mesh_.status(mesh_.edge_handle(h0)).feature() || mesh_.status(mesh_.edge_handle(h1)).feature())
722 hcol01 = mesh_.is_collapse_ok(h01);
724 hcol10 = mesh_.is_collapse_ok(h10);
727 if (hcol01 && hcol10) {
728 if (mesh_.valence(v0) < mesh_.valence(v1))
738 for (vv_it = mesh_.cvv_iter(v1); vv_it.is_valid() && !skip; ++vv_it)
739 if (is_too_long(v0, *vv_it))
752 for (vv_it = mesh_.cvv_iter(v0); vv_it.is_valid() && !skip; ++vv_it)
753 if (is_too_long(v1, *vv_it))
766 mesh_.garbage_collection();
769 omlog() <<
"collapse break\n";
776 template <
class Mesh>
778 BaseRemesherT<Mesh>::
781 typename Mesh::EIter e_it, e_end;
782 typename Mesh::VIter v_it, v_end;
783 typename Mesh::VHandle v0, v1, v2, v3, vh;
784 typename Mesh::HHandle hh;
786 typename Mesh::FHandle fh;
788 int val0, val1, val2, val3;
789 int val_opt0, val_opt1, val_opt2, val_opt3;
790 int ve0, ve1, ve2, ve3, ve_before, ve_after;
795 for (v_it = mesh_.vertices_begin(), v_end = mesh_.vertices_end(); v_it != v_end; ++v_it)
796 mesh_.property(valences_, *v_it) = mesh_.valence(*v_it);
799 for (ok =
false, i = 0; !ok && i < 100; ++i) {
802 for (e_it = mesh_.edges_begin(), e_end = mesh_.edges_end(); e_it != e_end; ++e_it) {
803 if (!mesh_.status(*e_it).locked() && !mesh_.status(*e_it).feature()) {
804 hh = mesh_.halfedge_handle(*e_it, 0);
805 v0 = mesh_.to_vertex_handle(hh);
806 v2 = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh));
807 if ( !mesh_.next_halfedge_handle(hh).is_valid() ) {
808 std::cerr <<
"Error v2" << std::endl;
811 hh = mesh_.halfedge_handle(*e_it, 1);
812 v1 = mesh_.to_vertex_handle(hh);
813 v3 = mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh));
814 if ( !mesh_.next_halfedge_handle(hh).is_valid() ) {
815 std::cerr <<
"Error v3" << std::endl;
822 if (!mesh_.status(v0).locked() && !mesh_.status(v1).locked() && !mesh_.status(v2).locked()
823 && !mesh_.status(v3).locked()) {
824 val0 = mesh_.property(valences_, v0);
825 val1 = mesh_.property(valences_, v1);
826 val2 = mesh_.property(valences_, v2);
827 val3 = mesh_.property(valences_, v3);
829 val_opt0 = (mesh_.is_boundary(v0) ? 4 : 6);
830 val_opt1 = (mesh_.is_boundary(v1) ? 4 : 6);
831 val_opt2 = (mesh_.is_boundary(v2) ? 4 : 6);
832 val_opt3 = (mesh_.is_boundary(v3) ? 4 : 6);
834 ve0 = (val0 - val_opt0);
836 ve1 = (val1 - val_opt1);
838 ve2 = (val2 - val_opt2);
840 ve3 = (val3 - val_opt3);
843 ve_before = ve0 + ve1 + ve2 + ve3;
850 ve0 = (val0 - val_opt0);
852 ve1 = (val1 - val_opt1);
854 ve2 = (val2 - val_opt2);
856 ve3 = (val3 - val_opt3);
859 ve_after = ve0 + ve1 + ve2 + ve3;
861 if (ve_before > ve_after && mesh_.is_flip_ok(*e_it)) {
863 --mesh_.property(valences_, v0);
864 --mesh_.property(valences_, v1);
865 ++mesh_.property(valences_, v2);
866 ++mesh_.property(valences_, v3);
875 omlog() <<
"flip break\n";
882 template <
class Mesh>
884 BaseRemesherT<Mesh>::
885 tangential_smoothing(
bool _use_projection)
887 typename Mesh::VIter v_it, v_end(mesh_.vertices_end());
888 typename Mesh::CVVIter vv_it;
894 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
895 mesh_.status(*v_it).set_tagged( !mesh_.status(*v_it).locked() &&
896 !mesh_.status(*v_it).feature() &&
897 !mesh_.is_boundary(*v_it) );
901 for (
int iters=0; iters<10; ++iters)
903 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
905 if (mesh_.status(*v_it).tagged())
910 for (vv_it=mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it)
912 u += mesh_.point(*vv_it);
919 u -= mesh_.point(*v_it);
920 n = mesh_.normal(*v_it);
925 mesh_.property(update_, *v_it) = u;
929 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
930 if (mesh_.status(*v_it).tagged())
931 mesh_.point(*v_it) += mesh_.property(update_, *v_it);
936 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
937 mesh_.status(*v_it).set_tagged(
false);
942 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
943 if (!mesh_.status(*v_it).locked() && !mesh_.status(*v_it).feature())
944 project_to_reference(*v_it);
951 template <
class Mesh>
953 BaseRemesherT<Mesh>::
954 balanace_area(
unsigned int _iters,
bool _use_projection)
956 typename Mesh::VIter v_it, v_end(mesh_.vertices_end());
957 typename Mesh::CVVIter vv_it;
962 DiffGeoT<Mesh> diffgeo(mesh_);
966 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
968 bool active = ( !mesh_.status(*v_it).locked() &&
969 !mesh_.status(*v_it).feature() &&
970 !mesh_.is_boundary(*v_it) );
973 for (vv_it=mesh_.cvv_iter(*v_it); active && vv_it.is_valid(); ++vv_it)
974 if (mesh_.is_boundary(*vv_it))
977 mesh_.status(*v_it).set_tagged( active );
982 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
984 mesh_.status(*v_it).set_tagged2(
false);
985 for (vv_it=mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it)
987 if (mesh_.status(*vv_it).tagged())
989 mesh_.status(*v_it).set_tagged2(
true);
997 for (
unsigned int bla=0; bla<_iters; ++bla)
1000 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1001 if (mesh_.status(*v_it).tagged2())
1002 mesh_.property(area_, *v_it) = pow(diffgeo.compute_area(*v_it), 2);
1007 for (
int iters=0; iters<10; ++iters)
1009 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1011 if (mesh_.status(*v_it).tagged())
1016 for (vv_it=mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it)
1018 w = mesh_.property(area_, *vv_it);
1019 u += mesh_.point(*vv_it) * w;
1026 u -= mesh_.point(*v_it);
1027 n = mesh_.normal(*v_it);
1034 mesh_.property(update_, *v_it) = u;
1038 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1039 if (!mesh_.status(*v_it).locked() &&
1040 !mesh_.status(*v_it).feature() &&
1041 !mesh_.is_boundary(*v_it))
1042 mesh_.point(*v_it) += mesh_.property(update_, *v_it);
1047 if (_use_projection)
1048 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
1049 if (!mesh_.status(*v_it).locked() && !mesh_.status(*v_it).feature())
1050 project_to_reference(*v_it);
1063 template <
class Mesh>
1065 BaseRemesherT<Mesh>::
1068 typename Mesh::EdgeIter e_it, e_end(mesh_.edges_end());
1069 typename Mesh::HalfedgeHandle h;
1070 typename Mesh::Scalar a0, a1, amin, aa(cos(170.0 * M_PI / 180.0));
1071 typename Mesh::VHandle v, vb, vd;
1072 typename Mesh::FHandle fb, fd;
1078 mesh_.get_property_handle(pids,
"Nastran PIDs");
1081 for (e_it=mesh_.edges_begin(); e_it!=e_end; ++e_it)
1083 if (!mesh_.status(*e_it).locked() &&
1084 mesh_.is_flip_ok(*e_it))
1086 h = mesh_.halfedge_handle(*e_it, 0);
1087 a = mesh_.point(mesh_.to_vertex_handle(h));
1089 h = mesh_.next_halfedge_handle(h);
1090 b = mesh_.point(vb=mesh_.to_vertex_handle(h));
1092 h = mesh_.halfedge_handle(*e_it, 1);
1093 c = mesh_.point(mesh_.to_vertex_handle(h));
1095 h = mesh_.next_halfedge_handle(h);
1096 d = mesh_.point(vd=mesh_.to_vertex_handle(h));
1098 a0 = ( (a-b).normalize() | (c-b).normalize() );
1099 a1 = ( (a-d).normalize() | (c-d).normalize() );
1101 if (a0 < a1) { amin = a0; v = vb; }
1102 else { amin = a1; v = vd; }
1108 if (mesh_.status(*e_it).feature() && mesh_.status(v).feature())
1114 fb = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 0));
1115 fd = mesh_.face_handle(mesh_.halfedge_handle(*e_it, 1));
1118 mesh_.property(pids, fb) = mesh_.property(pids, fd);
1120 mesh_.property(pids, fd) = mesh_.property(pids, fb);
1124 if (mesh_.status(*e_it).feature())
1125 mesh_.set_point(v, (a+c)*0.5);
void prepare_face_selection()
prepare for remeshing only vertices which are fully surrounded by selected faces (if no face was sele...
void prepare_vertex_selection()
prepare for remeshing only selected vertices (if no vertex was selected, remesh whole mesh) ...
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Kernel::Point Point
Coordinate type.
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
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)
Kernel::Scalar Scalar
Scalar type.
Kernel::ConstVertexFaceIter ConstVertexFaceIter
Circulator.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
VertexHandle split(EdgeHandle _eh, const Point &_p)
Edge split (= 2-to-4 split)
void update_normals()
Compute normals for all primitives.
Functions for selection on a mesh.
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)
Kernel::Normal Normal
Normal type.