| 134 | template < typename PointType, index_t dimension > |
| 135 | template < index_t T > |
| 136 | std::enable_if_t< T == 3, std::optional< Vector3D > > |
| 137 | GenericPolygon< PointType, dimension >::normal() const |
| 138 | { |
| 139 | Vector3D normal; |
| 140 | const auto& p0 = vertices_[0]; |
| 141 | for( const auto v : Range{ 2, nb_vertices() } ) |
| 142 | { |
| 143 | const auto& p1 = vertices_[v - 1]; |
| 144 | const auto& p2 = vertices_[v]; |
| 145 | if( const auto triangle_normal = |
| 146 | Triangle< T >{ p0, p1, p2 }.normal() ) |
| 147 | { |
| 148 | normal += triangle_normal.value(); |
| 149 | } |
| 150 | } |
| 151 | try |
| 152 | { |
| 153 | return normal.normalize(); |
| 154 | } |
| 155 | catch( const OpenGeodeException& /*unused*/ ) |
| 156 | { |
| 157 | return std::nullopt; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | template < typename PointType, index_t dimension > |
| 162 | template < index_t T > |