| 170 | template < typename PointType, index_t dimension > |
| 171 | template < index_t T > |
| 172 | std::enable_if_t< T == 3, |
| 173 | std::optional< std::pair< local_index_t, Vector3D > > > |
| 174 | GenericTriangle< PointType, dimension >::pivot_and_normal() const |
| 175 | { |
| 176 | const auto result = simple_pivot_and_normal( |
| 177 | { vertices_[0], vertices_[1], vertices_[2] } ); |
| 178 | if( !result ) |
| 179 | { |
| 180 | return std::nullopt; |
| 181 | } |
| 182 | if( result->pivot != NO_LID ) |
| 183 | { |
| 184 | return std::optional< std::pair< local_index_t, Vector3D > >{ |
| 185 | std::make_pair( result->pivot, result->normal ) |
| 186 | }; |
| 187 | } |
| 188 | const auto max = absl::c_max_element( result->lengths ); |
| 189 | const local_index_t longest_e = |
| 190 | std::distance( result->lengths.begin(), max ); |
| 191 | const Point3D& point0 = vertices_[longest_e]; |
| 192 | const auto e1 = longest_e == 2 ? 0 : longest_e + 1; |
| 193 | const Point3D& point1 = vertices_[e1]; |
| 194 | const auto e2 = e1 == 2 ? 0 : e1 + 1; |
| 195 | const Point3D& point2 = vertices_[e2]; |
| 196 | if( point_segment_distance( point2, { point0, point1 } ) |
| 197 | > GLOBAL_EPSILON ) |
| 198 | { |
| 199 | const auto ratio = result->lengths[e2] |
| 200 | / ( result->lengths[e2] + result->lengths[e1] ); |
| 201 | const auto new_point = point0 * ( 1. - ratio ) + point1 * ratio; |
| 202 | const auto result_left = |
| 203 | simple_pivot_and_normal( { point0, new_point, point2 } ); |
| 204 | if( !result_left || result_left->pivot == NO_LID ) |
| 205 | { |
| 206 | return std::nullopt; |
| 207 | } |
| 208 | return std::make_pair( e2, result_left->normal ); |
| 209 | } |
| 210 | return std::nullopt; |
| 211 | } |
| 212 | |
| 213 | template < typename PointType, index_t dimension > |
| 214 | void GenericTriangle< PointType, dimension >::set_point( |
no test coverage detected