Skip to content

Commit b23b89a

Browse files
authored
Merge pull request #1184 from Geode-solutions/fix_removing_apex_refine_in_remesh
fix(Quality): adding function to compute triangle quality, based on angles.
2 parents 020a01c + e9431d2 commit b23b89a

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

include/geode/geometry/basic_objects/triangle.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ namespace geode
6868
normal() const;
6969
template < index_t T = dimension >
7070
[[nodiscard]]
71+
typename std::enable_if< T == 3, std::optional< Vector3D > >::type
72+
strict_normal() const;
73+
template < index_t T = dimension >
74+
[[nodiscard]]
7175
typename std::enable_if< T == 3, std::optional< Plane > >::type
7276
plane() const;
7377
template < index_t T = dimension >
@@ -79,6 +83,10 @@ namespace geode
7983
typename std::enable_if< T == 3, std::optional< local_index_t > >::type
8084
pivot() const;
8185
template < index_t T = dimension >
86+
[[nodiscard]] typename std::enable_if< T == 3,
87+
std::optional< std::pair< local_index_t, Vector3D > > >::type
88+
strict_pivot_and_normal() const;
89+
template < index_t T = dimension >
8290
[[nodiscard]] typename std::enable_if< T == 3,
8391
std::optional< std::pair< local_index_t, Vector3D > > >::type
8492
pivot_and_normal() const;

include/geode/geometry/quality.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
namespace geode
2929
{
3030
class Tetrahedron;
31+
FORWARD_DECLARATION_DIMENSION_CLASS( Triangle );
32+
ALIAS_2D_AND_3D( Triangle );
3133
} // namespace geode
3234

3335
namespace geode
@@ -39,4 +41,8 @@ namespace geode
3941

4042
[[nodiscard]] double opengeode_geometry_api
4143
tetrahedron_collapse_aspect_ratio( const Tetrahedron& tetra );
44+
45+
template < index_t dimension >
46+
[[nodiscard]] double triangle_angle_based_quality(
47+
const Triangle< dimension >& triangle );
4248
} // namespace geode

src/geode/geometry/basic_objects/triangle.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,18 @@ namespace geode
128128
return std::nullopt;
129129
}
130130

131+
template < typename PointType, index_t dimension >
132+
template < index_t T >
133+
typename std::enable_if< T == 3, std::optional< Vector3D > >::type
134+
GenericTriangle< PointType, dimension >::strict_normal() const
135+
{
136+
if( const auto result = strict_pivot_and_normal() )
137+
{
138+
return result->second;
139+
}
140+
return std::nullopt;
141+
}
142+
131143
template < typename PointType, index_t dimension >
132144
template < index_t T >
133145
typename std::enable_if< T == 3, std::optional< Plane > >::type
@@ -166,6 +178,27 @@ namespace geode
166178
return std::nullopt;
167179
}
168180

181+
template < typename PointType, index_t dimension >
182+
template < index_t T >
183+
typename std::enable_if< T == 3,
184+
std::optional< std::pair< local_index_t, Vector3D > > >::type
185+
GenericTriangle< PointType, dimension >::strict_pivot_and_normal() const
186+
{
187+
const auto result = simple_pivot_and_normal(
188+
{ vertices_[0], vertices_[1], vertices_[2] } );
189+
if( !result )
190+
{
191+
return std::nullopt;
192+
}
193+
if( result->pivot != NO_LID )
194+
{
195+
return std::optional< std::pair< local_index_t, Vector3D > >{
196+
std::make_pair( result->pivot, result->normal )
197+
};
198+
}
199+
return std::nullopt;
200+
}
201+
169202
template < typename PointType, index_t dimension >
170203
template < index_t T >
171204
typename std::enable_if< T == 3,
@@ -373,6 +406,8 @@ namespace geode
373406

374407
template opengeode_geometry_api std::optional< Vector3D >
375408
GenericTriangle< Point< 3 >, 3 >::normal< 3 >() const;
409+
template opengeode_geometry_api std::optional< Vector3D >
410+
GenericTriangle< Point< 3 >, 3 >::strict_normal< 3 >() const;
376411
template opengeode_geometry_api std::optional< Plane >
377412
GenericTriangle< Point< 3 >, 3 >::plane< 3 >() const;
378413
template opengeode_geometry_api std::optional< OwnerPlane >
@@ -382,9 +417,14 @@ namespace geode
382417
template opengeode_geometry_api
383418
std::optional< std::pair< local_index_t, Vector3D > >
384419
GenericTriangle< Point< 3 >, 3 >::pivot_and_normal< 3 >() const;
420+
template opengeode_geometry_api
421+
std::optional< std::pair< local_index_t, Vector3D > >
422+
GenericTriangle< Point< 3 >, 3 >::strict_pivot_and_normal< 3 >() const;
385423

386424
template opengeode_geometry_api std::optional< Vector3D >
387425
GenericTriangle< RefPoint< 3 >, 3 >::normal< 3 >() const;
426+
template opengeode_geometry_api std::optional< Vector3D >
427+
GenericTriangle< RefPoint< 3 >, 3 >::strict_normal< 3 >() const;
388428
template opengeode_geometry_api std::optional< Plane >
389429
GenericTriangle< RefPoint< 3 >, 3 >::plane< 3 >() const;
390430
template opengeode_geometry_api std::optional< OwnerPlane >
@@ -394,4 +434,8 @@ namespace geode
394434
template opengeode_geometry_api
395435
std::optional< std::pair< local_index_t, Vector3D > >
396436
GenericTriangle< RefPoint< 3 >, 3 >::pivot_and_normal< 3 >() const;
437+
template opengeode_geometry_api
438+
std::optional< std::pair< local_index_t, Vector3D > >
439+
GenericTriangle< RefPoint< 3 >, 3 >::strict_pivot_and_normal< 3 >()
440+
const;
397441
} // namespace geode

src/geode/geometry/quality.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,35 @@
2525

2626
#include <limits>
2727

28+
#include <geode/basic/logger.hpp>
29+
2830
#include <geode/geometry/basic_objects/tetrahedron.hpp>
2931
#include <geode/geometry/basic_objects/triangle.hpp>
3032
#include <geode/geometry/mensuration.hpp>
3133
#include <geode/geometry/square_matrix.hpp>
3234
#include <geode/geometry/vector.hpp>
3335

36+
#include <geode/basic/detail/disable_debug_logger.hpp>
37+
3438
namespace
3539
{
40+
template < geode::index_t dimension >
41+
double compute_angle( const geode::Point< dimension >& point,
42+
const geode::Point< dimension >& point_prev,
43+
const geode::Point< dimension >& point_next )
44+
{
45+
const auto prev =
46+
geode::Vector< dimension >{ point, point_prev }.normalize();
47+
const auto next =
48+
geode::Vector< dimension >{ point, point_next }.normalize();
49+
const auto dot = std::clamp( prev.dot( next ), -1.0, 1.0 );
50+
const auto angle = std::acos( dot );
51+
if( std::isnan( angle ) )
52+
{
53+
return 0;
54+
}
55+
return angle;
56+
}
3657

3758
std::array< geode::local_index_t, 3 > lu_decomposition(
3859
geode::SquareMatrix3D& matrix )
@@ -241,4 +262,45 @@ namespace geode
241262
}
242263
return ( longest_edge_length * heightinv ) / std::sqrt( 3. / 2. );
243264
}
265+
266+
template < index_t dimension >
267+
double triangle_angle_based_quality( const Triangle< dimension >& triangle )
268+
{
269+
try
270+
{
271+
const auto& vertices = triangle.vertices();
272+
std::array< double, 3 > sinus;
273+
for( const auto v : LRange{ 3 } )
274+
{
275+
const auto point = vertices[v].get();
276+
const auto point_prev = vertices[( v + 2 ) % 3].get();
277+
const auto point_next = vertices[( v + 1 ) % 3].get();
278+
const auto angle =
279+
compute_angle( point, point_prev, point_next );
280+
DEBUG( angle );
281+
sinus[v] = std::sin( angle );
282+
DEBUG( sinus[v] );
283+
}
284+
const auto denominator = sinus[0] + sinus[1] + sinus[2];
285+
if( denominator == 0 )
286+
{
287+
return 0;
288+
}
289+
const auto quality =
290+
4 * sinus[0] * sinus[1] * sinus[2] / ( denominator );
291+
DEBUG( quality );
292+
return quality;
293+
}
294+
catch( ... )
295+
{
296+
return 0;
297+
}
298+
}
299+
300+
template opengeode_geometry_api double triangle_angle_based_quality< 2 >(
301+
const Triangle2D& );
302+
template opengeode_geometry_api double triangle_angle_based_quality< 3 >(
303+
const Triangle3D& );
244304
} // namespace geode
305+
306+
#include <geode/basic/detail/enable_debug_logger.hpp>

0 commit comments

Comments
 (0)