15 #include <boost/range/iterator_range.hpp>
21 #include <type_traits>
46 namespace DataStructures {
69 typedef typename std::add_lvalue_reference< const mesh_type >::type
ref_cmesh;
133 for(
auto eIt = eRange.begin(); eIt != eRange.end(); ++eIt)
136 (*eIt)->get_first_vertex() == (*eIt)->get_second_vertex())
150 return vertex->GetDegree();
161 return vertex->GetDegree() == 0u;
175 typedef edge_container_in_vertex::const_iterator it_type;
176 int nbBoundaryEdges = 0;
177 boost::iterator_range< it_type > edges_range =
incident_edges(vertex);
179 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
185 if((nbBoundaryEdges < 4) || (nbBoundaryEdges % 2 == 1))
188 return ((nbBoundaryEdges - 4) % 2 == 0);
202 auto it = incidentEdgesRange.begin();
203 auto ite = incidentEdgesRange.end();
204 for(; it != ite; ++it)
244 auto it = incidentEdgesRange.begin();
245 auto ite = incidentEdgesRange.end();
246 for(; it != ite; ++it)
269 typedef edge_container_in_vertex::const_iterator it_type;
270 boost::iterator_range< it_type > edges_range =
incident_edges(vertex);
272 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
307 typedef edge_container_in_vertex::const_iterator it_type;
308 boost::iterator_range< it_type > edges_range =
incident_edges(vertex);
310 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
337 typedef edge_container_in_vertex::const_iterator it_type;
338 boost::iterator_range< it_type > edges_range =
incident_edges(vertex);
340 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
360 typedef edge_container_in_vertex::const_iterator it_type;
361 boost::iterator_range< it_type > edges_range =
incident_edges(vertex1);
363 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
376 static std::vector< vertex_descriptor >
379 std::vector< vertex_descriptor > adjacent_v;
382 adjacent_v.reserve(incidentEdgesRange.size());
383 auto it = incidentEdgesRange.begin();
384 auto ite = incidentEdgesRange.end();
385 for (; it != ite; ++it)
398 static boost::iterator_range< edge_container_in_vertex::const_iterator >
402 throw std::invalid_argument(
403 "AIFTopologyHelpers::incident_edges -> no incident relation exists "
404 "for a null vertex.");
406 return vertex->GetIncidentEdges();
414 static boost::iterator_range< face_container_in_vertex::const_iterator >
417 if(!vertex->m_Incident_PtrFaces_Computed)
419 typedef edge_container_in_vertex::const_iterator it_type;
420 typedef face_container_in_edge::const_iterator it_type2;
422 boost::iterator_range< it_type > edges_range =
incident_edges(vertex);
424 std::set< face_descriptor > incFaces;
426 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
428 boost::iterator_range< it_type2 > faces_range =
430 incFaces.insert(faces_range.begin(), faces_range.end());
433 vertex->m_Incident_PtrFaces = common_faces;
434 vertex->m_Incident_PtrFaces_Computed =
true;
436 return boost::make_iterator_range(vertex->m_Incident_PtrFaces.cbegin(),
437 vertex->m_Incident_PtrFaces.cend());
450 vertex->m_Incident_PtrFaces.cend());
461 typedef edge_container_in_vertex::const_iterator it_type;
468 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
485 typedef edge_container_in_vertex::const_iterator it_type;
486 std::vector< edge_descriptor > com_edges;
487 boost::iterator_range< it_type > edges_range =
incident_edges(vertex1);
489 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
492 com_edges.push_back(*it);
525 throw std::invalid_argument(
526 "AIFTopologyHelpers::link_vertex_and_edge -> incident relation "
527 "already exists between the two elements.");
550 if(!edge_has_that_incident_vertex && !vertex_has_that_incident_edge)
551 throw std::invalid_argument(
552 "AIFTopologyHelpers::unlink_vertex_and_edge -> no incident relation "
553 "existing between the two elements.");
555 if(edge_has_that_incident_vertex)
560 if(vertex_has_that_incident_edge)
574 template<
typename ComparatorType >
575 static boost::iterator_range< vertex_container::const_iterator >
592 template<
typename ComparatorType >
593 static boost::iterator_range< vertex_container::const_iterator >
596 return sort_vertices< ComparatorType >(mesh.get(), cmp);
607 template<
typename ComparatorType >
608 static boost::iterator_range< vertex_container::const_iterator >
611 return sort_vertices< ComparatorType >(&mesh, cmp);
628 template<
typename ComparatorType >
629 static boost::iterator_range< edge_container_in_vertex::const_iterator >
631 const ComparatorType &cmp,
633 bool do_full_incident_edge_sorting)
635 if(do_full_incident_edge_sorting)
637 sort(vertex->m_Incident_PtrEdges.begin(),
638 vertex->m_Incident_PtrEdges.end(),
643 std::list< edge_descriptor > ltmp, ltmpnext;
644 edge_container_in_vertex::const_iterator
645 it = vertex->m_Incident_PtrEdges.begin(),
646 ite = vertex->m_Incident_PtrEdges.end();
647 while(it != ite && *it !=
edge)
649 ltmpnext.push_back(*it);
662 vertex->m_Incident_PtrEdges.clear();
663 vertex->m_Incident_PtrEdges.insert(
664 vertex->m_Incident_PtrEdges.end(), ltmp.begin(), ltmp.end());
665 vertex->m_Incident_PtrEdges.insert(
666 vertex->m_Incident_PtrEdges.end(), ltmpnext.begin(), ltmpnext.end());
684 template<
typename ComparatorType >
685 static boost::iterator_range< edge_container_in_vertex::const_iterator >
687 const ComparatorType &cmp,
688 bool do_full_incident_edge_sorting)
691 return sort_incident_edges_starting_with_edge< ComparatorType >(
694 *std::min_element(vertex->m_Incident_PtrEdges.begin(),
695 vertex->m_Incident_PtrEdges.end(),
697 do_full_incident_edge_sorting);
710 template<
typename ComparatorType >
712 const ComparatorType &cmp,
713 bool do_full_incident_edge_sorting)
715 sort_incident_edges< ComparatorType >(
716 edge->get_first_vertex(), cmp, do_full_incident_edge_sorting);
717 sort_incident_edges< ComparatorType >(
718 edge->get_second_vertex(), cmp, do_full_incident_edge_sorting);
729 template<
typename ComparatorType >
731 const ComparatorType &cmp)
733 typedef edge_container_in_vertex::const_iterator it_type;
734 boost::iterator_range< it_type > edges_range =
736 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
737 sort_incident_edges< ComparatorType >(
741 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
742 sort_incident_edges< ComparatorType >(
754 static std::vector< edge_descriptor >
757 std::vector< edge_descriptor > res;
761 typedef edge_container_in_vertex::const_iterator it_type;
762 boost::iterator_range< it_type > edges_range =
incident_edges(vertex);
764 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
767 (
degree((*it)->get_first_vertex()) > 2) &&
768 (
degree((*it)->get_second_vertex()) > 2)) ||
770 (
degree((*it)->get_second_vertex()) >= 2)))
775 std::vector< edge_descriptor > res_init(res.begin(), res.end());
776 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
778 if(std::find(res_init.begin(), res_init.end(), *it) == res_init.end())
780 auto iter = res_init.begin();
781 for(; iter != res_init.end(); ++iter)
804 static std::vector< edge_descriptor >
810 auto iter = std::find(res.begin(), res.end(), edge_to_remove);
811 if(iter != res.end())
826 typedef edge_container_in_vertex::const_iterator it_type;
831 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
851 typedef edge_container_in_vertex::const_iterator it_type;
856 for(it_type it = edges_range.begin(); it != edges_range.end(); ++it)
883 std::set< face_descriptor > current_faces(face_range.begin(),
894 (current_faces.find(current_f_tmp) != current_faces.end()))
897 auto it_f2 = face_range2.begin();
898 for(; it_f2 != face_range2.end(); ++it_f2)
900 if(*it_f2 != current_f_tmp)
902 current_faces.erase(current_f_tmp);
903 current_f_tmp = *it_f2;
911 if(current_f_tmp != face1)
912 current_faces.erase(current_f_tmp);
914 current_faces.insert(face1);
916 (current_faces.find(face1) != current_faces.end()))
919 auto it_f2 = face_range2.begin();
920 for(; it_f2 != face_range2.end(); ++it_f2)
924 current_faces.erase(face1);
997 return (
edge->get_first_vertex()->GetDegree() == 1u) &&
998 (
edge->get_second_vertex()->GetDegree() == 1u);
1024 return edge->GetDegree() > 2u;
1037 || (
edge->get_first_vertex() ==
edge->get_second_vertex())
1059 throw std::invalid_argument(
"AIFTopologyHelpers::common_vertex -> the 2 "
1060 "edge arguments are identical.");
1062 if((edge1->get_first_vertex() == edge2->get_first_vertex()) ||
1063 (edge1->get_first_vertex() == edge2->get_second_vertex()))
1065 return edge1->get_first_vertex();
1067 else if((edge1->get_second_vertex() == edge2->get_first_vertex()) ||
1068 (edge1->get_second_vertex() == edge2->get_second_vertex()))
1069 return edge1->get_second_vertex();
1083 auto iterE = edges_range.begin();
1084 for(; iterE != edges_range.end(); ++iterE)
1113 auto iterE = edges_range.begin();
1114 for(; iterE != edges_range.end(); ++iterE)
1138 return (
edge->get_first_vertex() == vertex) ||
1139 (
edge->get_second_vertex() == vertex);
1155 typedef face_container_in_edge::const_iterator it_type;
1158 for(it_type it = faces_range.begin(); it != faces_range.end(); ++it)
1178 return are_incident(edge2, edge1->get_first_vertex()) ||
1188 static boost::iterator_range< vertex_container_in_edge::const_iterator >
1193 throw std::invalid_argument(
"AIFTopologyHelpers::incident_vertices -> no "
1194 "incident relation exists for a null edge.");
1195 return edge->GetIncidentVertices();
1205 std::vector< edge_descriptor > adEdges1(
1206 edge->get_first_vertex()->GetIncidentEdges().begin(),
1207 edge->get_first_vertex()->GetIncidentEdges().end());
1208 std::vector< edge_descriptor > adEdges2(
1209 edge->get_second_vertex()->GetIncidentEdges().begin(),
1210 edge->get_second_vertex()->GetIncidentEdges().end());
1212 std::vector< edge_descriptor > res(
edge->get_first_vertex()->GetDegree() +
1213 edge->get_second_vertex()->GetDegree() -
1216 std::sort(adEdges1.begin(), adEdges1.end());
1217 std::sort(adEdges2.begin(), adEdges2.end());
1218 adEdges1.erase(std::find(adEdges1.begin(), adEdges1.end(),
edge));
1219 adEdges2.erase(std::find(adEdges2.begin(), adEdges2.end(),
edge));
1221 std::set_union(adEdges1.begin(),
1236 static boost::iterator_range< incident_face_iterator >
1240 throw std::invalid_argument(
"AIFTopologyHelpers::incident_faces -> no "
1241 "incident relation exists for a null edge.");
1243 return edge->GetIncidentFaces();
1255 if(
edge->get_first_vertex() == vertex)
1256 return vertex_pos::FIRST;
1257 else if(
edge->get_second_vertex() == vertex)
1258 return vertex_pos::SECOND;
1260 throw std::invalid_argument(
1261 "AIFTopologyHelpers::vertex_position -> given vertex not found.");
1273 if(
edge->get_first_vertex() == vertex)
1274 return edge->get_second_vertex();
1275 else if(
edge->get_second_vertex() == vertex)
1276 return edge->get_first_vertex();
1278 throw std::invalid_argument(
1279 "AIFTopologyHelpers::opposite_vertex -> given vertex not found.");
1289 edge->set_first_vertex(
edge->get_second_vertex());
1290 edge->set_second_vertex(v_temp);
1310 if(!face_has_that_incident_edge || !edge_has_that_incident_face)
1312 if(!face_has_that_incident_edge)
1314 if(!edge_has_that_incident_face)
1318 throw std::invalid_argument(
1319 "AIFTopologyHelpers::link_edge_and_face -> incident relation already "
1320 "exists between the two elements.");
1346 if(!face_has_that_incident_edge || !edge_has_that_incident_face)
1348 if(!face_has_that_incident_edge)
1350 if(!edge_has_that_incident_face)
1354 throw std::invalid_argument(
1355 "AIFTopologyHelpers::link_edge_and_face_around_face_after_edge -> "
1356 "incident relation already "
1357 "exists between the two elements.");
1377 std::vector< edge_descriptor > &
edges,
1382 std::vector< edge_descriptor >::iterator it(
edges.begin()),
1384 for(; it != ite; ++it)
1388 prev_edge = current_edge;
1403 if(!face_has_that_incident_edge && !edge_has_that_incident_face)
1404 throw std::invalid_argument(
1405 "AIFTopologyHelpers::unlink_edge_and_face -> no incident relation "
1406 "existing between the two elements.");
1408 if(edge_has_that_incident_face)
1413 if(face_has_that_incident_edge)
1426 std::vector< edge_descriptor >::iterator it(
edges.begin()),
1428 for(; it != ite; ++it)
1457 template<
typename ComparatorType >
1458 static boost::iterator_range< edge_container::const_iterator >
1474 template<
typename ComparatorType >
1475 static boost::iterator_range< edge_container::const_iterator >
1478 return sort_edges< ComparatorType >(mesh.get(), cmp);
1488 template<
typename ComparatorType >
1489 static boost::iterator_range< edge_container::const_iterator >
1492 return sort_edges< ComparatorType >(&mesh, cmp);
1514 auto it = edges_range.begin();
1515 for(; it != edges_range.end(); ++it)
1517 if((
degree((*it)->get_first_vertex()) > 2) ||
1518 (
degree((*it)->get_second_vertex()) > 2))
1539 for(
auto eIt = eRange.begin(); eIt != eRange.end(); ++eIt)
1567 auto it = edges_range.begin();
1568 for(; it != edges_range.end(); ++it)
1584 bool at_least_one_vertex_with_degree_greater_than_2 =
false;
1586 auto it = edges_range.begin();
1587 for(; it != edges_range.end(); ++it)
1591 if(!at_least_one_vertex_with_degree_greater_than_2 &&
1592 ((
degree((*it)->get_first_vertex()) > 2) ||
1593 (
degree((*it)->get_second_vertex()) > 2)))
1594 at_least_one_vertex_with_degree_greater_than_2 =
true;
1596 return at_least_one_vertex_with_degree_greater_than_2;
1609 auto it = edges_range.begin();
1610 for(; it != edges_range.end(); ++it)
1631 auto it = edges_range.begin();
1636 for(; it != edges_range.end(); ++it)
1655 auto it = edges_range.begin();
1656 for (; it != edges_range.end(); ++it)
1679 auto it = edges_range.begin();
1680 for (; it != edges_range.end(); ++it)
1686 if(it2==edges_range.end())
1687 it2 = edges_range.begin();
1691 else if(!border_edge_before_v)
1725 if(
face->m_Is_Incident_PtrVertices_Computed)
1728 return (std::find(
face->m_Incident_PtrVertices.begin(),
1729 face->m_Incident_PtrVertices.end(),
1730 vertex) !=
face->m_Incident_PtrVertices.end());
1735 auto it = edges_range.begin();
1736 for(; it != edges_range.end(); ++it)
1759 if(vertex->m_Incident_PtrFaces_Computed)
1762 return (std::find(vertex->m_Incident_PtrFaces.begin(),
1763 vertex->m_Incident_PtrFaces.end(),
1764 face) != vertex->m_Incident_PtrFaces.end());
1769 auto it = edges_range.begin();
1770 for(; it != edges_range.end(); ++it)
1797 auto it = edges_range.begin();
1798 for(; it != edges_range.end(); ++it)
1820 boost::iterator_range< incident_edge_iterator > edges_range =
1824 it != edges_range.end();
1838 static boost::iterator_range< vertex_container_in_face::const_iterator >
1842 throw std::invalid_argument(
"AIFTopologyHelpers::incident_vertices -> no "
1843 "incident relation exists for a null face.");
1845 return face->GetIncidentVertices();
1853 static boost::iterator_range< incident_edge_iterator >
1857 throw std::invalid_argument(
"AIFTopologyHelpers::incident_edges -> no "
1858 "incident relation exists for a null face.");
1860 return face->GetIncidentEdges();
1870 static std::vector< face_descriptor >
1872 bool one_neighborhood_sharing_edge =
true)
1874 std::set< face_descriptor > adFaces;
1875 if(one_neighborhood_sharing_edge)
1878 for(
auto eIt = eRange.begin(); eIt != eRange.end(); ++eIt)
1881 std::vector< face_descriptor > incidentFaces(fRange.begin(),
1883 incidentFaces.erase(
1884 std::find(incidentFaces.begin(), incidentFaces.end(),
face));
1885 adFaces.insert(incidentFaces.begin(), incidentFaces.end());
1891 for(
auto vIt = vRange.begin(); vIt != vRange.end(); ++vIt)
1894 std::vector< face_descriptor > incidentFaces(fRange.begin(),
1896 incidentFaces.erase(
1897 std::find(incidentFaces.begin(), incidentFaces.end(),
face));
1898 adFaces.insert(incidentFaces.begin(), incidentFaces.end());
1901 return std::vector< face_descriptor >(
1926 for(
auto vIt1 = vRange1.begin(); vIt1 != vRange1.end(); ++vIt1){
1927 for(
auto vIt2 = vRange2.begin(); vIt2 != vRange2.end(); ++vIt2){
1943 std::stack<face_descriptor> s;
1944 std::map< face_descriptor, bool> already_met;
1948 already_met[current] =
true;
1951 auto itF = facesRange.begin();
1952 for(; itF != facesRange.end(); ++itF){
1956 if(already_met.find(*itF)== already_met.end())
1977 auto it1 = vertices_range1.begin();
1978 for(; it1 != vertices_range1.end(); ++it1)
1980 auto it2 = vertices_range2.begin();
1981 for(; it2 != vertices_range2.end(); ++it2)
1986 if(it1_b == vertices_range1.begin())
1987 it1_b = vertices_range1.end();
1991 if(it1 == vertices_range1.end())
1992 it1 = vertices_range1.begin();
1995 if(it2_b == vertices_range2.begin())
1996 it2_b = vertices_range2.end();
2000 if(it2 == vertices_range2.end())
2001 it2 = vertices_range2.begin();
2003 if((*it1 == *it2) || (*it1_b == *it2_b))
2007 if((*it1 == *it2_b) || (*it1_b == *it2))
2033 auto iter_f1 = faceRange.begin();
2048 std::reverse(edgeRange.begin(), edgeRange.end());
2049 face->clear_vertex_incidency();
2060 auto iter_e = edge_range.begin(), iter_e_e = edge_range.end();
2061 for(; iter_e != iter_e_e; ++iter_e)
2077 typedef face_container_in_edge::const_iterator it_type;
2079 boost::iterator_range< it_type > faces_range =
incident_faces(edge1);
2081 for(it_type it = faces_range.begin(); it != faces_range.end(); ++it)
2098 typedef edge_container_in_face::const_iterator it_type;
2101 boost::iterator_range< it_type > edges_range1 =
incident_edges(face1);
2102 boost::iterator_range< it_type > edges_range2 =
incident_edges(face2);
2104 for(it_type it1 = edges_range1.begin(); it1 != edges_range1.end(); ++it1)
2106 for(it_type it2 = edges_range2.begin(); it2 != edges_range2.end(); ++it2)
2124 typedef edge_container_in_vertex::const_iterator it_type;
2125 std::vector< edge_descriptor > com_edges;
2126 boost::iterator_range< it_type > edges_range1 =
incident_edges(face1);
2127 boost::iterator_range< it_type > edges_range2 =
incident_edges(face2);
2129 for(it_type it1 = edges_range1.begin(); it1 != edges_range1.end(); ++it1)
2131 for(it_type it2 = edges_range2.begin(); it2 != edges_range2.end(); ++it2)
2133 if((*it1 == *it2) &&
2134 (std::find(com_edges.begin(), com_edges.end(), *it1) ==
2136 com_edges.push_back(*it1);
2226 static boost::iterator_range< vertex_container::const_iterator >
2237 static boost::iterator_range< vertex_container::const_iterator >
2248 static boost::iterator_range< vertex_container::const_iterator >
2260 static boost::iterator_range< edge_container::const_iterator >
2271 static boost::iterator_range< edge_container::const_iterator >
2274 return edges(mesh.get());
2282 static boost::iterator_range< edge_container::const_iterator >
2285 return edges(&mesh);
2300 auto vertexIter = verticesRange.begin(), vertexIterE = verticesRange.end();
2301 for(; vertexIter != vertexIterE; ++vertexIter)
2319 return edges(mesh.get());
2348 auto edgesRange = mesh->
GetEdges();
2349 auto edgeIter = edgesRange.begin(), edgeIterE = edgesRange.end();
2350 for(; edgeIter != edgeIterE; ++edgeIter)
2399 auto vertexIter = verticesRange.begin(), vertexIterE = verticesRange.end();
2400 for(; vertexIter != vertexIterE; ++vertexIter)
2441 auto edgesRange = mesh->
GetEdges();
2442 auto edgeIter = edgesRange.begin(), edgeIterE = edgesRange.end();
2443 bool meetFirstBorderEdge =
false;
2444 for(; edgeIter != edgeIterE; ++edgeIter)
2448 if(!meetFirstBorderEdge)
2449 meetFirstBorderEdge =
true;
2453 if(meetFirstBorderEdge)
2483 auto edgesRange = mesh->
GetEdges();
2484 auto edgeIter = edgesRange.begin(), edgeIterE = edgesRange.end();
2486 for(; edgeIter != edgeIterE; ++edgeIter)
2518 auto edgesRange = mesh->
GetEdges();
2519 auto edgeIter = edgesRange.begin(), edgeIterE = edgesRange.end();
2521 while(edgeIter != edgeIterE)
2527 swap(*edgeIter, *edgeIterE);
2561 static boost::iterator_range< edge_container::const_iterator >
2565 throw std::invalid_argument(
2566 "AIFTopologyHelpers::border_edges(m) -> mesh' edges have not been "
2567 "normalized, thus cannot deduced an iterator range over border "
2570 auto edgesRange = mesh->
GetEdges();
2571 auto edgeIter = edgesRange.begin(), edgeIterE = edgesRange.end();
2574 return boost::make_iterator_range(edgeIter, edgeIterE);
2582 static boost::iterator_range< edge_container::const_iterator >
2593 static boost::iterator_range< edge_container::const_iterator >
2605 static boost::iterator_range< face_container::const_iterator >
2616 static boost::iterator_range< face_container::const_iterator >
2619 return faces(mesh.get());
2627 static boost::iterator_range< face_container::const_iterator >
2630 return faces(&mesh);
2643 auto iter_range_v =
vertices(mesh);
2644 auto iter_v = iter_range_v.begin();
2645 for(; iter_v != iter_range_v.end(); ++iter_v)
2648 auto iter_range_e =
edges(mesh);
2649 auto iter_e = iter_range_e.begin();
2650 for(; iter_e != iter_range_e.end(); ++iter_e)
2653 auto iter_range_f =
faces(mesh);
2654 auto iter_f = iter_range_f.begin();
2655 for(; iter_f != iter_range_f.end(); ++iter_f)
2694 template<
typename InputIt >
2697 for(; first != last; ++first)
2836 static std::pair< edge_descriptor, bool >
2839 bool is_edge_insertion_done =
false;
2846 is_edge_insertion_done =
true;
2849 return std::pair< edge_descriptor, bool >(
edge, is_edge_insertion_done);
2861 static std::pair< edge_descriptor, bool >
2876 static std::pair< edge_descriptor, bool >
2949 throw std::invalid_argument(
2950 "AIFTopologyHelpers::clear_vertex(v) -> vertex is null, cannot clear "
2951 "its connectivity from mesh.");
2963 throw std::invalid_argument(
2964 "AIFTopologyHelpers::remove_vertex(v, m) -> vertex is null, cannot "
2965 "suppress it from mesh.");
2999 template<
typename InputIt,
typename MeshType >
3002 for(; first != last; ++first)
3015 throw std::invalid_argument(
3016 "AIFTopologyHelpers::remove_edge(e, m) -> edge is null, cannot "
3017 "suppress it from mesh.");
3019 std::set< vertex_descriptor > verticesToRemove;
3021 edge->get_first_vertex()->GetDegree() == 1)
3022 verticesToRemove.insert(
edge->get_first_vertex());
3024 edge->get_second_vertex()->GetDegree() == 1)
3025 verticesToRemove.insert(
edge->get_second_vertex());
3029 std::set< vertex_descriptor >::iterator itv = verticesToRemove.begin(),
3030 itve = verticesToRemove.end();
3031 for(; itv != itve; ++itv)
3066 template<
typename InputIt,
typename MeshType >
3069 for(; first != last; ++first)
3123 throw std::invalid_argument(
3124 "AIFTopologyHelpers::remove_face(f, m) -> face is null, cannot "
3125 "suppress it from mesh.");
3130 auto edgesRange =
face->GetIncidentEdges();
3131 std::list< edge_descriptor > edgesToRemove;
3132 std::set< vertex_descriptor > vertexWhichNeedsToClearPrecomputation;
3133 auto itE = edgesRange.begin();
3134 for(; itE != edgesRange.end(); ++itE)
3136 vertexWhichNeedsToClearPrecomputation.insert((*itE)->get_first_vertex());
3137 vertexWhichNeedsToClearPrecomputation.insert((*itE)->get_second_vertex());
3138 if((*itE)->GetDegree() == 1)
3140 edgesToRemove.push_back(*itE);
3145 std::list< edge_descriptor >::iterator it = edgesToRemove.begin(),
3146 ite = edgesToRemove.end();
3147 for(; it != ite; ++it)
3153 std::set< vertex_descriptor >::iterator
3154 itv = vertexWhichNeedsToClearPrecomputation.begin(),
3155 itve = vertexWhichNeedsToClearPrecomputation.end();
3156 for(; itv != itve; ++itv)
3158 (*itv)->m_Incident_PtrFaces.clear();
3159 (*itv)->m_Incident_PtrFaces_Computed =
false;
3192 template<
typename InputIt,
typename MeshType >
3195 for(; first != last; ++first)
3207 v2 =
edge->get_second_vertex();
3219 typedef edge_container_in_vertex::const_iterator it_type;
3220 boost::iterator_range< it_type > edges_range =
incident_edges(vertex);
3221 std::vector< edge_descriptor > edgesToUnlink;
3224 edges_range.begin(),
3226 std::back_inserter(edgesToUnlink));
3229 for(std::vector< edge_descriptor >::const_iterator it =
3230 edgesToUnlink.cbegin();
3231 it != edgesToUnlink.cend();
3243 std::vector< edge_descriptor > edgesToUnlink;
3246 edges_range.begin(),
3248 std::back_inserter(edgesToUnlink));
3251 for(std::vector< edge_descriptor >::const_iterator it =
3252 edgesToUnlink.cbegin();
3253 it != edgesToUnlink.cend();
3263 typedef face_container_in_edge::const_iterator it_type;
3265 std::vector< face_descriptor > facesToUnlink;
3268 faces_range.begin(),
3270 std::back_inserter(facesToUnlink));
3273 for(std::vector< face_descriptor >::const_iterator it =
3274 facesToUnlink.cbegin();
3275 it != facesToUnlink.cend();
3299 throw std::invalid_argument(
3300 "AIFTopologyHelpers::add_vertex(e, v) -> vertex is a null vertex.");
3303 throw std::invalid_argument(
3304 "AIFTopologyHelpers::add_vertex(e, v) -> edge is a null edge.");
3324 throw std::invalid_argument(
3325 "AIFTopologyHelpers::remove_vertex(e, v) -> edge is a null edge.");
3328 throw std::invalid_argument(
"AIFTopologyHelpers::remove_vertex(e, v) -> "
3329 "vertex is a null vertex.");
3349 throw std::invalid_argument(
3350 "AIFTopologyHelpers::add_edge(v, e) -> vertex is a null vertex.");
3353 throw std::invalid_argument(
3354 "AIFTopologyHelpers::add_edge(v, e) -> edge is a null edge.");
3373 throw std::invalid_argument(
3374 "AIFTopologyHelpers::remove_edge(v, e) -> vertex is a null vertex.");
3376 throw std::invalid_argument(
3377 "AIFTopologyHelpers::remove_edge(v, e) -> edge is a null edge.");
3395 throw std::invalid_argument(
3396 "AIFTopologyHelpers::add_face(e, f) -> edge is a null edge.");
3398 throw std::invalid_argument(
3399 "AIFTopologyHelpers::add_face(e, f) -> face is a null face.");
3417 throw std::invalid_argument(
3418 "AIFTopologyHelpers::remove_face(e, f) -> edge is a null edge.");
3420 throw std::invalid_argument(
3421 "AIFTopologyHelpers::remove_face(e, f) -> face is a null face.");
3439 throw std::invalid_argument(
3440 "AIFTopologyHelpers::add_edge(f, e) -> edge is a null edge.");
3442 throw std::invalid_argument(
3443 "AIFTopologyHelpers::add_edge(f, e) -> face is a null face.");
3461 throw std::invalid_argument(
3462 "AIFTopologyHelpers::add_edge(f, e) -> edge is a null edge.");
3464 throw std::invalid_argument(
3465 "AIFTopologyHelpers::add_edge(f, e) -> face is a null face.");
3480 static std::set< edge_descriptor >
3483 std::set< edge_descriptor > edgesToRemove(
incident_edges(v).begin(),
3485 std::set< edge_descriptor >
edges;
3486 std::set< edge_descriptor > oldEdges;
3490 face_container_in_vertex::iterator nextFace =
faces.begin();
3491 while(!
faces.empty())
3494 edges.insert(eRange.begin(), eRange.end());
3504 std::set< edge_descriptor > edgesTmp(eRange.begin(), eRange.end());
3505 std::set< edge_descriptor > edgesInter;
3506 std::set_intersection(edgesTmp.begin(),
3510 std::inserter(edgesInter, edgesInter.end()));
3512 std::set_difference(
edges.begin(),
3516 std::inserter(oldEdges, oldEdges.end()));
3518 edges.swap(oldEdges);
3521 faces.erase(nextFace);
3523 nextFace =
faces.begin();
3526 std::set< edge_descriptor > result;
3527 std::set< edge_descriptor >::iterator it(
edges.begin()), ite(
edges.end());
3528 for(; it != ite; ++it)
3530 if(edgesToRemove.find(*it) ==
3531 edgesToRemove.end())
3545 template<
typename T >
3548 const T &container_of_edge_one_ring,
3549 bool allow_multiple_incident_edges =
false,
3550 bool ensure_e_belongs_to_container =
true)
3553 if(ensure_e_belongs_to_container &&
3554 (std::find(container_of_edge_one_ring.begin(),
3555 container_of_edge_one_ring.end(),
3556 e) == container_of_edge_one_ring.end()))
3559 bool another_edge_incident_to_e_v1 =
false,
3560 another_edge_incident_to_e_v2 =
false;
3561 for(
auto element : container_of_edge_one_ring)
3563 if((element != e) &&
are_incident(element, e->get_first_vertex()))
3565 if(!allow_multiple_incident_edges)
3566 if(another_edge_incident_to_e_v1)
3568 another_edge_incident_to_e_v1 =
true;
3569 if(allow_multiple_incident_edges)
3570 if(another_edge_incident_to_e_v2)
3573 else if((element != e) &&
are_incident(element, e->get_second_vertex()))
3575 if(!allow_multiple_incident_edges)
3576 if(another_edge_incident_to_e_v2)
3578 another_edge_incident_to_e_v2 =
true;
3579 if(allow_multiple_incident_edges)
3580 if(another_edge_incident_to_e_v1)
3585 return another_edge_incident_to_e_v1 && another_edge_incident_to_e_v2;
3593 template<
typename T >
3596 const T &container_of_edge_one_ring)
3599 auto iter = edge_range.begin();
3600 for(; iter != edge_range.end(); ++iter)
3602 if((std::find(container_of_edge_one_ring.begin(),
3603 container_of_edge_one_ring.end(),
3604 *iter) != container_of_edge_one_ring.end()) &&
3615 template<
typename T >
3618 const T &container_of_edge_one_ring)
3620 for(
auto element : container_of_edge_one_ring)
3622 container_of_edge_one_ring))
3626 for(
auto element : container_of_edge_one_ring)
3631 for(
auto element : container_of_edge_one_ring)
3635 return *(container_of_edge_one_ring.begin());
3646 std::set< edge_descriptor > notSortedOneRing =
3648 std::set< edge_descriptor > notSortedOneRingSave(notSortedOneRing);
3651 if(notSortedOneRing.size() == 0)
3654 result.reserve(notSortedOneRing.size());
3662 while(!notSortedOneRing.empty())
3664 result.push_back(nextEdge);
3665 notSortedOneRing.erase(nextEdge);
3666 if(!notSortedOneRing.empty())
3668 if(notSortedOneRing.size() == 1)
3670 nextEdge = *notSortedOneRing.begin();
3674 std::set< edge_descriptor >::iterator it(notSortedOneRing.begin()),
3675 ite(notSortedOneRing.end());
3676 for(; it != ite; ++it)
3703 bool neverEnter =
true, atLeastOneAnotherAdjacent =
false;
3704 for(; it2 != ite; ++it2)
3708 atLeastOneAnotherAdjacent =
true;
3718 for(; it3 != ite; ++it3)
3726 *it2, notSortedOneRingSave,
true,
true) ||
3728 nextEdge, notSortedOneRingSave,
true,
true) &&
3738 if(atLeastOneAnotherAdjacent && neverEnter)
3743 for(; it2 != ite; ++it2)
3761 std::set< edge_descriptor > notUsedEdgesCopy(notSortedOneRing);
3765 it = notUsedEdgesCopy.begin();
3766 ite = notUsedEdgesCopy.end();
3770 for(; it != ite; ++it)
3774 notUsedEdgesCopy.erase(*it);
3781 it = notUsedEdgesCopy.begin();
3782 ite = notUsedEdgesCopy.end();
3789 || notUsedEdgesCopy.size() > 0)
3791 if(notUsedEdgesCopy.size() == 0)
3793 if(notSortedOneRing.size() == 2)
3795 if(
are_adjacent(*notSortedOneRing.begin(), result.front()))
3797 auto it_tmp = notSortedOneRing.begin();
3802 nextEdge = *notSortedOneRing.begin();
3805 nextEdge = *notSortedOneRing.begin();
3807 else if(notUsedEdgesCopy.size() <= 2)
3808 nextEdge = *notUsedEdgesCopy.begin();
3811 nextTmpEdge = *notUsedEdgesCopy.begin();
3812 it = notUsedEdgesCopy.begin();
3813 ite = notUsedEdgesCopy.end();
3817 for(; it != ite; ++it)
3821 notUsedEdgesCopy.erase(*it);
3827 it = notUsedEdgesCopy.begin();
3828 ite = notUsedEdgesCopy.end();
3831 nextEdge = nextTmpEdge;
3835 nextEdge = nextTmpEdge;
3844 size_t nbE = result.size();
3849 for(i = 0; i < nbE; ++i)
3865 size_t nbF =
faces.size();
3867 for(k = 0; k < nbF; ++k)
3885 bool v1BeforeV2InFace =
false;
3887 auto it = resV.begin();
3888 auto ite = resV.end();
3895 second_v = result[i]->get_second_vertex();
3900 if(**it == *(first_v))
3905 if(**it == *(second_v))
3911 else if(**it == *(second_v))
3916 if(**it != *(first_v))
3917 v1BeforeV2InFace =
true;
3929 if(!v1BeforeV2InFace)
3933 std::reverse(result.begin(), result.end());
3938 if(v1BeforeV2InFace)
3942 std::reverse(result.begin(), result.end());
3963 if(orderedOneRing[index]->get_first_vertex() ==
3964 orderedOneRing[index]->get_second_vertex())
3966 oneR.push_back(orderedOneRing[index]->get_first_vertex());
3970 auto edge_incident_faces =
incident_faces(orderedOneRing[index]);
3971 auto iter_f = edge_incident_faces.begin(),
3972 iter_f_e = edge_incident_faces.end();
3973 for(; iter_f != iter_f_e; ++iter_f)
3978 auto iter_v = f_incident_vertices.begin(),
3979 iter_v_e = f_incident_vertices.end();
3981 for(; iter_v != iter_v_e; ++iter_v)
3983 if(*iter_v == orderedOneRing[index]->get_first_vertex())
3986 if(iter_v == iter_v_e)
3987 iter_v = f_incident_vertices.begin();
3989 if(*iter_v == orderedOneRing[index]->get_second_vertex())
3991 oneR.push_back(orderedOneRing[index]->get_second_vertex());
3992 oneR.push_back(orderedOneRing[index]->get_first_vertex());
3996 oneR.push_back(orderedOneRing[index]->get_first_vertex());
3997 oneR.push_back(orderedOneRing[index]->get_second_vertex());
4001 else if(*iter_v == orderedOneRing[index]->get_second_vertex())
4004 if(iter_v == iter_v_e)
4005 iter_v = f_incident_vertices.begin();
4007 if(*iter_v == orderedOneRing[index]->get_first_vertex())
4009 oneR.push_back(orderedOneRing[index]->get_first_vertex());
4010 oneR.push_back(orderedOneRing[index]->get_second_vertex());
4014 oneR.push_back(orderedOneRing[index]->get_second_vertex());
4015 oneR.push_back(orderedOneRing[index]->get_first_vertex());
4037 auto &m_One_Ring_Vertices = v->m_One_Ring_Vertices;
4056 if(v->m_Is_One_Ring_Vertices_Computed)
4059 return m_One_Ring_Vertices;
4067 m_One_Ring_Vertices.clear();
4070 size_t nbE = orderedOneRing.size();
4072 return m_One_Ring_Vertices;
4082 if(
are_incident(orderedOneRing[0]->get_second_vertex(),
4085 oneR.push_back(orderedOneRing[0]->get_first_vertex());
4086 if(orderedOneRing[0]->get_first_vertex() !=
4087 orderedOneRing[0]->get_second_vertex())
4088 oneR.push_back(orderedOneRing[0]->get_second_vertex());
4089 lastVertex = orderedOneRing[0]->get_second_vertex();
4091 else if(
are_incident(orderedOneRing[0]->get_first_vertex(),
4094 oneR.push_back(orderedOneRing[0]->get_second_vertex());
4095 if(orderedOneRing[0]->get_first_vertex() !=
4096 orderedOneRing[0]->get_second_vertex())
4097 oneR.push_back(orderedOneRing[0]->get_first_vertex());
4098 lastVertex = orderedOneRing[0]->get_first_vertex();
4106 lastVertex = oneR.back();
4110 bool exist_2_connected_one_ring_edges =
false;
4112 for(i = 0; i < nbE - 1; ++i)
4115 orderedOneRing[i + 1]))
4117 exist_2_connected_one_ring_edges =
true;
4120 else if(
are_incident(orderedOneRing[i]->get_second_vertex(),
4121 orderedOneRing[i + 1]))
4123 exist_2_connected_one_ring_edges =
true;
4129 if(
are_incident(orderedOneRing[nbE - 1]->get_first_vertex(),
4132 exist_2_connected_one_ring_edges =
true;
4134 else if(
are_incident(orderedOneRing[nbE - 1]->get_second_vertex(),
4137 exist_2_connected_one_ring_edges =
true;
4141 if(exist_2_connected_one_ring_edges)
4144 for(
size_t j = i; j < nbE; ++j)
4145 tmp.push_back(orderedOneRing[j]);
4146 for(
size_t j = 0; j < i; ++j)
4147 tmp.push_back(orderedOneRing[j]);
4149 orderedOneRing.swap(tmp);
4151 if(
are_incident(orderedOneRing[0]->get_second_vertex(),
4154 oneR.push_back(orderedOneRing[0]->get_first_vertex());
4155 if(orderedOneRing[0]->get_first_vertex() !=
4156 orderedOneRing[0]->get_second_vertex())
4157 oneR.push_back(orderedOneRing[0]->get_second_vertex());
4158 lastVertex = orderedOneRing[0]->get_second_vertex();
4160 else if(
are_incident(orderedOneRing[0]->get_first_vertex(),
4163 oneR.push_back(orderedOneRing[0]->get_second_vertex());
4164 if(orderedOneRing[0]->get_first_vertex() !=
4165 orderedOneRing[0]->get_second_vertex())
4166 oneR.push_back(orderedOneRing[0]->get_first_vertex());
4167 lastVertex = orderedOneRing[0]->get_first_vertex();
4173 lastVertex = oneR.back();
4178 for(
size_t i = 1; i < nbE; ++i)
4205 if(
are_incident(orderedOneRing[i]->get_second_vertex(),
4206 orderedOneRing[i + 1]))
4208 if(std::find(oneR.begin(),
4210 orderedOneRing[i]->get_second_vertex()) !=
4213 if(orderedOneRing[i]->get_first_vertex() !=
4214 orderedOneRing[i]->get_second_vertex())
4216 oneR.push_back(orderedOneRing[i]->get_second_vertex());
4218 lastVertex = orderedOneRing[i]->get_first_vertex();
4222 if(orderedOneRing[i]->get_first_vertex() !=
4223 orderedOneRing[i]->get_second_vertex())
4225 oneR.push_back(orderedOneRing[i]->get_first_vertex());
4227 lastVertex = orderedOneRing[i]->get_second_vertex();
4230 else if(
are_incident(orderedOneRing[i]->get_first_vertex(),
4231 orderedOneRing[i + 1]))
4233 if(std::find(oneR.begin(),
4235 orderedOneRing[i]->get_first_vertex()) != oneR.end())
4237 if(orderedOneRing[i]->get_first_vertex() !=
4238 orderedOneRing[i]->get_second_vertex())
4240 oneR.push_back(orderedOneRing[i]->get_first_vertex());
4242 lastVertex = orderedOneRing[i]->get_second_vertex();
4246 if(orderedOneRing[i]->get_first_vertex() !=
4247 orderedOneRing[i]->get_second_vertex())
4249 oneR.push_back(orderedOneRing[i]->get_second_vertex());
4251 lastVertex = orderedOneRing[i]->get_first_vertex();
4258 if(orderedOneRing[i]->get_first_vertex() !=
4259 orderedOneRing[i]->get_second_vertex())
4262 lastVertex = oneR.back();
4266 lastVertex = orderedOneRing[i]->get_second_vertex();
4271 if(std::find(oneR.begin(), oneR.end(), lastVertex) != oneR.end())
4273 if((i + 1 == nbE) &&
4276 oneR.push_back(lastVertex);
4279 else if((i + 2 == nbE) &&
4281 orderedOneRing[i + 1], orderedOneRing,
true))
4283 oneR.push_back(lastVertex);
4289 oneR.push_back(lastVertex);
4294 v->m_Is_One_Ring_Vertices_Computed =
true;
4296 return m_One_Ring_Vertices;
4310 size_t nbE = resFullRing.size();
4316 auto it(resFullRing.begin());
4317 auto ite(resFullRing.end());
4321 oneR.push_back(*it);
4340 std::set< vertex_descriptor > starVertices;
4341 auto its = starEdges.begin();
4342 auto itse = starEdges.end();
4343 for (; its != itse; ++its)
4345 starVertices.insert((*its)->get_first_vertex());
4346 starVertices.insert((*its)->get_second_vertex());
4349 auto itvs = starVertices.begin();
4350 auto itvse = starVertices.end();
4351 for (; itvs != itvse; ++itvs)
4369 std::vector< edge_descriptor >::iterator
4370 it =
face->m_Incident_PtrEdges.begin(),
4371 ite =
face->m_Incident_PtrEdges.end();
4372 for(; it != ite; ++it)
4374 if((((*it)->get_first_vertex() == prev_edge->get_first_vertex()) &&
4375 ((*it)->get_second_vertex() == prev_edge->get_second_vertex())) ||
4376 (((*it)->get_first_vertex() == prev_edge->get_second_vertex()) &&
4377 ((*it)->get_second_vertex() == prev_edge->get_first_vertex())))
4381 it =
face->m_Incident_PtrEdges.begin();
4387 throw std::invalid_argument(
4388 "Helpers::get_edge_of_face_after_edge(f, pe) -> prev_edge does not "
4389 "belong to input face.");
4402 std::vector< edge_descriptor >::iterator
4403 it =
face->m_Incident_PtrEdges.begin(),
4404 ite =
face->m_Incident_PtrEdges.end();
4405 for(; it != ite; ++it)
4407 if((((*it)->get_first_vertex() == next_edge->get_first_vertex()) &&
4408 ((*it)->get_second_vertex() == next_edge->get_second_vertex())) ||
4409 (((*it)->get_first_vertex() == next_edge->get_second_vertex()) &&
4410 ((*it)->get_second_vertex() == next_edge->get_first_vertex())))
4412 if(it ==
face->m_Incident_PtrEdges.begin())
4422 throw std::invalid_argument(
4423 "Helpers::get_edge_of_face_before_edge(f, ne) -> next_edge does not "
4424 "belong to input face.");
4442 std::vector< edge_descriptor >::iterator
4443 it =
face->m_Incident_PtrEdges.begin(),
4444 ite =
face->m_Incident_PtrEdges.end();
4445 for(; it != ite; ++it)
4447 if((((*it)->get_first_vertex() == prev_edge->get_first_vertex()) &&
4448 ((*it)->get_second_vertex() == prev_edge->get_second_vertex())) ||
4449 (((*it)->get_first_vertex() == prev_edge->get_second_vertex()) &&
4450 ((*it)->get_second_vertex() == prev_edge->get_first_vertex())))
4456 face->m_Incident_PtrEdges.insert(it,
edge);
4458 face->clear_vertex_incidency();
4463 for(
auto vIt = vRange.begin(); vIt != vRange.end(); ++vIt)
4465 if((*vIt)->m_Is_One_Ring_Vertices_Computed)
4467 (*vIt)->m_Is_One_Ring_Vertices_Computed =
false;
4468 (*vIt)->m_One_Ring_Vertices.clear();
4469 (*vIt)->m_Incident_PtrFaces_Computed =
false;
4470 (*vIt)->m_Incident_PtrFaces.clear();
4500 if(position == vertex_pos::FIRST)
4502 edge->set_first_vertex(vertex);
4503 opp_v =
edge->get_second_vertex();
4507 edge->set_second_vertex(vertex);
4508 opp_v =
edge->get_first_vertex();
4511 vertex->m_Is_One_Ring_Vertices_Computed =
false;
4512 vertex->m_One_Ring_Vertices.clear();
4516 opp_v->m_Is_One_Ring_Vertices_Computed =
false;
4517 opp_v->m_One_Ring_Vertices.clear();
4539 vertex->m_Is_One_Ring_Vertices_Computed =
false;
4540 vertex->m_One_Ring_Vertices.clear();
4561 opp_v =
edge->get_second_vertex();
4566 opp_v =
edge->get_first_vertex();
4569 vertex->m_Is_One_Ring_Vertices_Computed =
false;
4570 vertex->m_One_Ring_Vertices.clear();
4574 opp_v->m_Is_One_Ring_Vertices_Computed =
false;
4575 opp_v->m_One_Ring_Vertices.clear();
4594 vertex->m_Is_One_Ring_Vertices_Computed =
false;
4595 vertex->m_One_Ring_Vertices.clear();
4612 face->clear_vertex_incidency();
4617 for(
auto vIt = vRange.begin(); vIt != vRange.end(); ++vIt)
4619 if((*vIt)->m_Is_One_Ring_Vertices_Computed)
4621 (*vIt)->m_Is_One_Ring_Vertices_Computed =
false;
4622 (*vIt)->m_One_Ring_Vertices.clear();
4623 (*vIt)->m_Incident_PtrFaces_Computed =
false;
4624 (*vIt)->m_Incident_PtrFaces.clear();
4645 for(
auto vIt = vRange.begin(); vIt != vRange.end(); ++vIt)
4647 (*vIt)->m_Is_One_Ring_Vertices_Computed =
false;
4648 (*vIt)->m_One_Ring_Vertices.clear();
4649 (*vIt)->m_Incident_PtrFaces_Computed =
false;
4650 (*vIt)->m_Incident_PtrFaces.clear();
4653 face->clear_vertex_incidency();
4672 for(
auto vIt = vRange.begin(); vIt != vRange.end(); ++vIt)
4674 (*vIt)->m_Is_One_Ring_Vertices_Computed =
false;
4675 (*vIt)->m_One_Ring_Vertices.clear();
4676 (*vIt)->m_Incident_PtrFaces_Computed =
false;
4677 (*vIt)->m_Incident_PtrFaces.clear();
4682 face->clear_vertex_incidency();
4701 for(
auto vIt = vRange.begin(); vIt != vRange.end(); ++vIt)
4705 (*vIt)->m_Is_One_Ring_Vertices_Computed =
false;
4706 (*vIt)->m_One_Ring_Vertices.clear();
4707 (*vIt)->m_Incident_PtrFaces_Computed =
false;
4708 (*vIt)->m_Incident_PtrFaces.clear();
4714 face->clear_vertex_incidency();
4722 template<
typename RandomIt,
typename Compare >
4723 static void sort(RandomIt first, RandomIt last, Compare comp)
4725 for(; first != last; ++first)
4727 auto min_location = first;
4728 auto first2 = min_location;
4730 for(; first2 != last; ++first2)
4732 if(comp(*first2, *min_location))
4734 min_location = first2;
4737 if(min_location != first)
4739 std::swap(*first, *min_location);
4764 bool do_validity_check =
true)
4771 throw std::runtime_error(
4772 "In AIFHalfEdge::AIFHalfEdge(s, t, f): invalid halfedge, no edge "
4773 "between the two vertices.");
4786 if(do_validity_check)
4790 return are_incident(e, f);
4793 throw std::runtime_error(
4794 "In AIFHalfEdge::AIFHalfEdge(s, t, f): invalid halfedge, not "
4795 "incident to the face.");
4799 #if 0 // to ensure that the halfedge is inside the face (not needed if you make
4802 auto iter = edgesRange.begin() ;
4806 while( !( ((e->get_first_vertex() == s) && (e->get_second_vertex()==t)) || ((e->get_first_vertex() == t) && (e->get_second_vertex()==s))) )
4810 if( iter == edgesRange.end() )
4811 iter = edgesRange.begin();
4814 if( e->get_first_vertex() == enext->get_first_vertex()
4815 || e->get_first_vertex() == enext->get_second_vertex() )
4820 else if( e->get_second_vertex() == enext->get_first_vertex()
4821 || e->get_second_vertex() == enext->get_second_vertex() )
4827 throw std::runtime_error(
"In AIFHalfEdge::AIFHalfEdge(s, t, f): unkown case.");
4843 bool do_validity_check =
true)
4857 if(do_validity_check)
4861 throw std::runtime_error(
4862 "In AIFHalfEdge::AIFHalfEdge(s, t, f): invalid halfedge, no edge "
4863 "between the two vertices.");
4866 return are_incident(e, f);
4869 throw std::runtime_error(
4870 "In AIFHalfEdge::AIFHalfEdge(s, t, f): invalid halfedge, not "
4871 "incident to the face.");
4875 #if 0 // to ensure that the halfedge is inside the face (not needed if you make
4878 auto iter = edgesRange.begin();
4882 while (!(((
edge->get_first_vertex() == s) && (
edge->get_second_vertex() == t)) || ((
edge->get_first_vertex() == t) && (
edge->get_second_vertex() == s))))
4886 if (iter == edgesRange.end())
4887 iter = edgesRange.begin();
4890 if (
edge->get_first_vertex() == enext->get_first_vertex()
4891 ||
edge->get_first_vertex() == enext->get_second_vertex())
4896 else if (
edge->get_second_vertex() == enext->get_first_vertex()
4897 ||
edge->get_second_vertex() == enext->get_second_vertex())
4903 throw std::runtime_error(
"In AIFHalfEdge::AIFHalfEdge(s, t, f): unkown case.");
4933 return !(*
this == other);
4954 auto edgesRange =
get_target()->GetIncidentEdges();
4955 auto itE = edgesRange.begin();
4956 for(; itE != edgesRange.end(); ++itE)
4970 if(isBorderHalfedge)
4981 auto edgesRange =
get_target()->GetIncidentEdges();
4982 auto itE = edgesRange.begin();
4983 for(; itE != edgesRange.end(); ++itE)
4988 auto verticesPair = (*itE)->GetIncidentVertices();
5012 itE = edgesRange.begin();
5013 for(; itE != edgesRange.end(); ++itE)
5015 auto verticesPair = (*itE)->GetIncidentVertices();
5023 if(itE == edgesRange.end())
5024 itE = edgesRange.begin();
5035 else if(ptrV1 == ptrV2)
5056 auto itF = facesRange.begin();
5059 for(; itF != facesRange.end(); ++itF)
5061 if(*itF == currentFaces[0])
5065 if(itF == facesRange.end())
5066 itF = facesRange.begin();
5067 rightFaceContainingNextHalfEdge = *itF;
5072 if (itF == facesRange.end())
5073 itF = facesRange.begin();
5074 rightFaceContainingNextHalfEdge = *itF;
5079 auto edgesRange =
incident_edges(rightFaceContainingNextHalfEdge);
5080 auto itE = edgesRange.begin();
5082 for(; itE != edgesRange.end(); ++itE)
5084 if(((*itE)->get_first_vertex() ==
get_target()) ||
5085 ((*itE)->get_second_vertex() ==
get_target()))
5092 throw std::runtime_error(
5093 "Error in AIFHalfEdge::next(): next halfedge cannot be "
5094 "found in a non-manifold context. Get unkown case "
5095 "while processing a cut-vertex.");
5103 bool same_orientation =
true;
5105 auto it1 = vertices_range1.begin();
5106 for (; it1 != vertices_range1.end(); ++it1) {
5110 if (it2 == vertices_range1.end())
5111 it2 = vertices_range1.begin();
5113 same_orientation =
false;
5120 rightFaceContainingNextHalfEdge,
5122 if(h.
prev(m).
get_edge() == ((same_orientation)?candidate2:candidate1))
5125 edge = ((same_orientation) ? candidate2 : candidate1);
5127 else if(h.
next(m).
get_edge() == ((same_orientation) ? candidate2 : candidate1))
5130 edge = ((same_orientation) ? candidate1 : candidate2);
5147 throw std::runtime_error(
5148 "Error in AIFHalfEdge::next(): next halfedge cannot be "
5149 "found in a non-manifold context. Get unkown case while "
5150 "processing a cut-vertex.");
5154 throw std::runtime_error(
5155 "Error in AIFHalfEdge::next(): next halfedge cannot be found "
5156 "in a non-manifold context. Current vertex is a cut-vertex.");
5160 throw std::runtime_error(
5161 "Error in AIFHalfEdge::next(): next halfedge cannot be found "
5162 "in a non-manifold context. Current vertex is degenerated.");
5165 throw std::runtime_error(
5166 "Error in AIFHalfEdge::next(): next halfedge cannot be found "
5167 "in a non-manifold context. Current vertex is isolated.");
5183 throw std::runtime_error(
5184 "Error in AIFHalfEdge::next(): next halfedge cannot be found in "
5185 "a non-manifold context.");
5191 auto edgesRange =
m_face->GetIncidentEdges();
5197 auto itF = facesRange.begin();
5199 for(; itF != facesRange.end(); ++itF)
5201 edgesRange = (*itF)->GetIncidentEdges();
5202 auto itE = edgesRange.begin();
5204 for(; itE != edgesRange.end(); ++itE)
5210 if(itE == edgesRange.end())
5211 itE = edgesRange.begin();
5220 edgesRange =
m_face->GetIncidentEdges();
5222 auto itE = edgesRange.begin();
5224 if(edgesRange.size() == 1)
5238 else if(edgesRange.size() == 2)
5254 bool is_current_Edge_present =
false;
5255 for(; itE != edgesRange.end(); ++itE)
5259 is_current_Edge_present =
true;
5262 auto verticesPair = (*itE)->GetIncidentVertices();
5272 if(is_current_Edge_present)
5288 if(is_current_Edge_present)
5303 itE = edgesRange.begin();
5304 for(; itE != edgesRange.end(); ++itE)
5306 auto verticesPair = (*itE)->GetIncidentVertices();
5314 if(itE == edgesRange.end())
5315 itE = edgesRange.begin();
5323 else if(ptrV1 == ptrV2)
5340 throw std::runtime_error(
5341 "Error in AIFHalfEdge::next(): next halfedge not found in face! "
5342 "Maybe the input halfedge is invalid (face/vertices mismatch).");
5357 if(isBorderHalfedge)
5363 auto edgesRange =
get_source()->GetIncidentEdges();
5364 auto itE = edgesRange.begin();
5365 for(; itE != edgesRange.end(); ++itE)
5370 auto verticesPair = (*itE)->GetIncidentVertices();
5400 auto itF = facesRange.begin();
5403 for(; itF != facesRange.end(); ++itF)
5405 if(*itF == currentFaces[0])
5408 if(itF == facesRange.begin())
5409 itF = facesRange.end();
5411 rightFaceContainingPrevHalfEdge = *itF;
5415 if (itF == facesRange.begin())
5416 itF = facesRange.end();
5418 rightFaceContainingPrevHalfEdge = *itF;
5423 auto edgesRange =
incident_edges(rightFaceContainingPrevHalfEdge);
5424 auto itE = edgesRange.begin();
5426 for(; itE != edgesRange.end(); ++itE)
5428 if(((*itE)->get_first_vertex() ==
get_source()) ||
5429 ((*itE)->get_second_vertex() ==
get_source()))
5436 throw std::runtime_error(
5437 "Error in AIFHalfEdge::prev(): prev halfedge cannot be "
5438 "found in a non-manifold context. Get unkown case "
5439 "while processing a cut-vertex.");
5447 bool same_orientation =
true;
5449 auto it1 = vertices_range1.begin();
5450 for (; it1 != vertices_range1.end(); ++it1) {
5454 if (it2 == vertices_range1.end())
5455 it2 = vertices_range1.begin();
5457 same_orientation =
false;
5464 rightFaceContainingPrevHalfEdge,
5491 throw std::runtime_error(
5492 "Error in AIFHalfEdge::prev(): prev halfedge cannot be "
5493 "found in a non-manifold context. Get unkown case while "
5494 "processing a cut-vertex.");
5498 throw std::runtime_error(
5499 "Error in AIFHalfEdge::prev(): prev halfedge cannot be found "
5500 "in a non-manifold context. Current vertex is a cut-vertex.");
5504 throw std::runtime_error(
5505 "Error in AIFHalfEdge::prev(): prev halfedge cannot be found "
5506 "in a non-manifold context. Current vertex is degenerated.");
5509 throw std::runtime_error(
5510 "Error in AIFHalfEdge::prev(): prev halfedge cannot be found "
5511 "in a non-manifold context. Current vertex is isolated.");
5516 auto edgesRange =
m_face->GetIncidentEdges();
5523 auto itF = facesRange.begin();
5525 for(; itF != facesRange.end(); ++itF)
5527 edgesRange = (*itF)->GetIncidentEdges();
5528 auto itE = edgesRange.begin();
5530 for(; itE != edgesRange.end(); ++itE)
5536 if(itE == edgesRange.end())
5537 itE = edgesRange.begin();
5546 edgesRange =
m_face->GetIncidentEdges();
5549 auto itE = edgesRange.begin();
5551 if(edgesRange.size() == 1)
5562 else if(edgesRange.size() == 2)
5575 bool is_current_Edge_present =
false;
5576 for(; itE != edgesRange.end(); ++itE)
5580 is_current_Edge_present =
true;
5583 auto verticesPair = (*itE)->GetIncidentVertices();
5592 if(is_current_Edge_present)
5607 if(is_current_Edge_present)
5621 itE = edgesRange.begin();
5622 for(; itE != edgesRange.end(); ++itE)
5624 auto verticesPair = (*itE)->GetIncidentVertices();
5631 if(itE == edgesRange.begin())
5632 itE = edgesRange.end();
5641 else if(ptrV1 == ptrV2)
5658 throw std::runtime_error(
5659 "Error in AIFHalfEdge::prev(): prev halfedge not found in face! "
5660 "Maybe the input halfedge is invalid (face/vertices mismatch).");
5676 auto itF = facesRange.begin();
5678 for(; itF != facesRange.end(); ++itF, ++cpt)
5696 auto itF = facesRange.begin();
5698 for(; itF != facesRange.end(); ++itF, ++cpt)
5705 throw std::invalid_argument(
5706 "AIFTopologyHelpers::opposite(h, m) -> several opposite edges "
5707 "exist, cannot proceed.");
5735 <<
", face=" << h.
get_face() <<
")";
5772 if(edgesRange.begin() == edgesRange.end())
5773 throw std::invalid_argument(
5774 "AIFTopologyHelpers::halfedge(f, m) -> no edge incident to face.");
5782 if(e->get_first_vertex() == enext->get_first_vertex() ||
5783 e->get_first_vertex() == enext->get_second_vertex())
5785 target = e->get_first_vertex();
5786 source = e->get_second_vertex();
5788 else if(e->get_second_vertex() == enext->get_first_vertex() ||
5789 e->get_second_vertex() == enext->get_second_vertex())
5791 target = e->get_second_vertex();
5792 source = e->get_first_vertex();
5795 throw std::runtime_error(
5796 "AIFTopologyHelpers::halfedge(f, m) -> the second edge in "
5797 "face-incident-edges container don't share any vertex with the first "
5798 "edge in container.");
5818 if(edgesRange.begin() == edgesRange.end())
5823 auto itE = edgesRange.begin();
5826 while(itE != edgesRange.end())
5828 if((facesRange.size() > 0) && (facesRange.size() < 3))
5831 if(itE != edgesRange.end())
5837 if(itE == edgesRange.end())
5838 throw std::invalid_argument(
5839 "AIFTopologyHelpers::halfedge(v, m) -> cannot find a manifold edge.");
5841 if(facesRange.begin() == facesRange.end())
5842 throw std::invalid_argument(
"AIFTopologyHelpers::halfedge(v, m) -> no "
5843 "face incident to selected edge.");
5849 auto iter = edgesRangeF.begin();
5853 while(!(((eF->get_first_vertex() == v) &&
5856 (eF->get_second_vertex() == v))))
5860 if(iter == edgesRangeF.end())
5861 iter = edgesRangeF.begin();
5864 if(eF->get_first_vertex() == eFnext->get_first_vertex() ||
5865 eF->get_first_vertex() == eFnext->get_second_vertex())
5867 if(eF->get_first_vertex() != v)
5869 if(facesRange.size() == 1)
5872 f = *(facesRange.begin() + 1);
5875 else if(eF->get_second_vertex() == eFnext->get_first_vertex() ||
5876 eF->get_second_vertex() == eFnext->get_second_vertex())
5878 if(eF->get_second_vertex() != v)
5880 if(facesRange.size() == 1)
5883 f = *(facesRange.begin() + 1);
5918 auto itF = facesRange.begin();
5920 for(; itF != facesRange.end(); ++itF, ++cpt)
5924 throw std::invalid_argument(
"AIFTopologyHelpers::halfedge(src, target, "
5925 "m) -> an incident face is degenerated.");
5930 auto edgesRange = (*itF)->GetIncidentEdges();
5931 auto itE = edgesRange.begin();
5933 for(; itE != edgesRange.end(); ++itE)
5935 if((((*itE)->get_first_vertex() == src) &&
5936 ((*itE)->get_second_vertex() ==
target)) ||
5937 (((*itE)->get_first_vertex() ==
target) &&
5938 ((*itE)->get_second_vertex() == src)))
5942 if(itE == edgesRange.end())
5943 itE = edgesRange.begin();
5957 if(cpt == 0 || cpt > 2)
5959 throw std::invalid_argument(
"AIFTopologyHelpers::halfedge(src, target, "
5960 "m) -> current halfedge is not manifold.");
5987 edge->get_first_vertex(),
edge->get_second_vertex(), mesh);
6018 throw std::invalid_argument(
"AIFTopologyHelpers::set_target(h, v, m) -> "
6019 "halfedge does not belong to input mesh.");
6045 throw std::invalid_argument(
"AIFTopologyHelpers::set_halfedge(v, h, m) "
6046 "-> halfedge does not belong to input mesh.");
6048 if(std::find(
target->GetIncidentEdges().begin(),
6049 target->GetIncidentEdges().end(),
6050 good_e) ==
target->GetIncidentEdges().end())
6080 throw std::invalid_argument(
"AIFTopologyHelpers::set_next(h1, h2, m) -> "
6081 "halfedge h1 does not belong to input mesh.");
6085 throw std::invalid_argument(
"AIFTopologyHelpers::set_next(h1, h2, m) -> "
6086 "halfedge h2 does not belong to input mesh.");
6088 current_next_h1_op = current_next_h1.
opposite(mesh);
6089 if(current_next_h1 != h2)
6100 std::vector< edge_descriptor > edges_to_insert_in_face;
6101 if(
face->GetDegree() > 0)
6104 while(tmp != current_next_h1_op)
6106 edges_to_insert_in_face.push_back(tmp.
get_edge());
6107 tmp = tmp.
next(mesh);
6113 edges_to_insert_in_face,
face, prev_edge);
6115 edges_to_insert_in_face,
6116 current_next_h1_op.get_face());
6125 if(std::find(current_next_h1.
get_edge()
6126 ->get_first_vertex()
6127 ->GetIncidentEdges()
6130 ->get_first_vertex()
6131 ->GetIncidentEdges()
6135 ->get_first_vertex()
6136 ->GetIncidentEdges()
6139 current_next_h1.
get_edge()->get_first_vertex(),
6142 if(std::find(current_next_h1.
get_edge()
6143 ->get_second_vertex()
6144 ->GetIncidentEdges()
6147 ->get_second_vertex()
6148 ->GetIncidentEdges()
6152 ->get_second_vertex()
6153 ->GetIncidentEdges()
6156 current_next_h1.
get_edge()->get_second_vertex(),
6162 auto h1itF = h1FaceRange.begin();
6163 while(h1itF != h1FaceRange.end())
6165 auto h2itF = h2FaceRange.begin();
6166 while(h2itF != h2FaceRange.end())
6168 if(*h1itF == *h2itF)
6183 assert(h1.
next(mesh) == h2);
6184 assert(h2.
prev(mesh) == h1);
6203 throw std::invalid_argument(
"AIFTopologyHelpers::set_face(h, f, m) -> "
6204 "halfedge does not belong to input mesh.");
6236 throw std::invalid_argument(
6237 "AIFTopologyHelpers::set_halfedge(f, h, m) -> face is a null face.");
6240 throw std::invalid_argument(
"AIFTopologyHelpers::set_halfedge(f, h, m) "
6241 "-> halfedge does not belong to input mesh.");