| 119 | } |
| 120 | |
| 121 | void SelfIntersection::handle_intersection_candidate( |
| 122 | size_t f_idx_1, size_t f_idx_2) { |
| 123 | auto duplicated_vertices = topological_overlap(f_idx_1, f_idx_2); |
| 124 | const Vector3I f1 = m_faces.row(f_idx_1); |
| 125 | const Vector3I f2 = m_faces.row(f_idx_2); |
| 126 | const Triangle_3 t1(m_points[f1[0]], m_points[f1[1]], m_points[f1[2]]); |
| 127 | const Triangle_3 t2(m_points[f2[0]], m_points[f2[1]], m_points[f2[2]]); |
| 128 | |
| 129 | bool is_intersecting = false; |
| 130 | const size_t num_duplicated_vertices = duplicated_vertices.size(); |
| 131 | switch (num_duplicated_vertices) { |
| 132 | case 0: |
| 133 | // triangles do not touch. |
| 134 | { |
| 135 | bool t1_degenerate = t1.is_degenerate(); |
| 136 | bool t2_degenerate = t2.is_degenerate(); |
| 137 | if (t1_degenerate || t2_degenerate) { |
| 138 | // Degenerated triangles are considered as |
| 139 | // self-intersecting. |
| 140 | is_intersecting = true; |
| 141 | } else { |
| 142 | is_intersecting = CGAL::do_intersect(t1, t2); |
| 143 | } |
| 144 | } |
| 145 | break; |
| 146 | case 3: |
| 147 | // duplicated face |
| 148 | is_intersecting = true; |
| 149 | break; |
| 150 | case 1: |
| 151 | { |
| 152 | // touch at a vertex. |
| 153 | size_t shared_vertex = duplicated_vertices[0]; |
| 154 | Vector2I opp_edge_1 = get_opposite_edge(f1, shared_vertex); |
| 155 | Vector2I opp_edge_2 = get_opposite_edge(f2, shared_vertex); |
| 156 | Segment_3 seg_1(m_points[opp_edge_1[0]], m_points[opp_edge_1[1]]); |
| 157 | Segment_3 seg_2(m_points[opp_edge_2[0]], m_points[opp_edge_2[1]]); |
| 158 | is_intersecting = |
| 159 | CGAL::do_intersect(t1, seg_2) || |
| 160 | CGAL::do_intersect(t2, seg_1); |
| 161 | } |
| 162 | break; |
| 163 | case 2: |
| 164 | { |
| 165 | // touch at an edge. |
| 166 | Vector2I shared_edge(duplicated_vertices[0], |
| 167 | duplicated_vertices[1]); |
| 168 | size_t v1 = get_opposite_vertex(f1, shared_edge); |
| 169 | size_t v2 = get_opposite_vertex(f2, shared_edge); |
| 170 | const auto& p1 = m_points[v1]; |
| 171 | const auto& p2 = m_points[v2]; |
| 172 | const auto& p3 = m_points[shared_edge[0]]; |
| 173 | const auto& p4 = m_points[shared_edge[1]]; |
| 174 | if (CGAL::coplanar(p1, p2, p3, p4)) { |
| 175 | if (CGAL::collinear(p3, p4, p1)) { |
| 176 | is_intersecting = true; |
| 177 | } else if (CGAL::collinear(p3, p4, p2)) { |
| 178 | is_intersecting = true; |
no test coverage detected