Skip to content

Commit 94660fa

Browse files
authored
Merge pull request #934 from Geode-solutions/fix/is-degenerated
fix(Mesh): add methos in mesh classes to ask if an element is degener…
2 parents ed36887 + 921fecf commit 94660fa

File tree

6 files changed

+143
-0
lines changed

6 files changed

+143
-0
lines changed

include/geode/mesh/core/edged_curve.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ namespace geode
6565

6666
Point< dimension > edge_barycenter( index_t edge_id ) const;
6767

68+
/*!
69+
* Return if an edge is degenerated (means stands into an
70+
* epsilon-large ball)
71+
*/
72+
bool is_edge_degenerated( index_t edge_id ) const;
73+
6874
Segment< dimension > segment( index_t edge_id ) const;
6975

7076
TextureManager1D texture_manager() const;

include/geode/mesh/core/solid_mesh.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,12 @@ namespace geode
439439
absl::optional< Vector3D > new_polyhedron_facet_normal(
440440
const PolyhedronFacet& polyhedron_facet ) const;
441441

442+
/*!
443+
* Return if a polyhedron is degenerated (means stands into an
444+
* epsilon-large plane)
445+
*/
446+
bool is_polyhedron_degenerated( index_t polyhedron_id ) const;
447+
442448
/*!
443449
* Returns the vertices linked by an edge to the given mesh vertex.
444450
*/

include/geode/mesh/core/surface_mesh.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,12 @@ namespace geode
348348
typename std::enable_if< T == 3, absl::optional< Vector3D > >::type
349349
polygon_vertex_normal( index_t vertex_id ) const;
350350

351+
/*!
352+
* Return if a polygon is degenerated (means stands into an
353+
* epsilon-large segment)
354+
*/
355+
bool is_polygon_degenerated( index_t polygon_id ) const;
356+
351357
/*!
352358
* Returns the vertices linked by an edge to the given mesh vertex.
353359
*/

src/geode/mesh/core/edged_curve.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ namespace geode
113113
return ( e0 + e1 ) / 2.;
114114
}
115115

116+
template < index_t dimension >
117+
bool EdgedCurve< dimension >::is_edge_degenerated( index_t edge_id ) const
118+
{
119+
return edge_length( edge_id ) <= global_epsilon;
120+
}
121+
116122
template < index_t dimension >
117123
template < typename Archive >
118124
void EdgedCurve< dimension >::serialize( Archive& archive )

src/geode/mesh/core/solid_mesh.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@
3333
#include <geode/basic/detail/mapping_after_deletion.h>
3434
#include <geode/basic/pimpl_impl.h>
3535

36+
#include <geode/geometry/basic_objects/plane.h>
3637
#include <geode/geometry/basic_objects/tetrahedron.h>
3738
#include <geode/geometry/basic_objects/triangle.h>
3839
#include <geode/geometry/bounding_box.h>
40+
#include <geode/geometry/distance.h>
3941
#include <geode/geometry/mensuration.h>
4042
#include <geode/geometry/vector.h>
4143

@@ -874,6 +876,52 @@ namespace geode
874876
}
875877
}
876878

879+
template < index_t dimension >
880+
bool SolidMesh< dimension >::is_polyhedron_degenerated(
881+
index_t polyhedron_id ) const
882+
{
883+
double max_area{ 0. };
884+
local_index_t max_area_facet{ 0 };
885+
for( const auto f : LRange{ nb_polyhedron_facets( polyhedron_id ) } )
886+
{
887+
const auto cur_area = polyhedron_facet_area( { polyhedron_id, f } );
888+
if( cur_area > max_area )
889+
{
890+
max_area = cur_area;
891+
max_area_facet = f;
892+
}
893+
}
894+
if( max_area < global_epsilon )
895+
{
896+
return true;
897+
}
898+
const auto vertices = polyhedron_vertices( polyhedron_id );
899+
const auto normal =
900+
new_polyhedron_facet_normal( { polyhedron_id, max_area_facet } );
901+
if( !normal )
902+
{
903+
return true;
904+
}
905+
const auto facet_vertices =
906+
polyhedron_facet_vertices( { polyhedron_id, max_area_facet } );
907+
Plane plane{ normal.value(), this->point( facet_vertices[0] ) };
908+
for( const auto vertex_id : vertices )
909+
{
910+
if( absl::c_find( facet_vertices, vertex_id )
911+
!= facet_vertices.end() )
912+
{
913+
continue;
914+
}
915+
if( std::get< 0 >(
916+
point_plane_distance( this->point( vertex_id ), plane ) )
917+
> global_epsilon )
918+
{
919+
return false;
920+
}
921+
}
922+
return true;
923+
}
924+
877925
template < index_t dimension >
878926
index_t SolidMesh< dimension >::nb_polyhedra() const
879927
{

src/geode/mesh/core/surface_mesh.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,32 @@
2828

2929
#include <bitsery/brief_syntax/array.h>
3030

31+
#include <geode/basic/attribute.h>
3132
#include <geode/basic/attribute_manager.h>
3233
#include <geode/basic/bitsery_archive.h>
3334
#include <geode/basic/cached_value.h>
3435
#include <geode/basic/detail/mapping_after_deletion.h>
3536
#include <geode/basic/pimpl_impl.h>
3637

38+
#include <geode/geometry/basic_objects/infinite_line.h>
39+
#include <geode/geometry/basic_objects/segment.h>
3740
#include <geode/geometry/basic_objects/triangle.h>
3841
#include <geode/geometry/bounding_box.h>
3942
#include <geode/geometry/distance.h>
4043
#include <geode/geometry/mensuration.h>
4144

4245
#include <geode/mesh/builder/surface_edges_builder.h>
4346
#include <geode/mesh/builder/surface_mesh_builder.h>
47+
#include <geode/mesh/builder/triangulated_surface_builder.h>
4448
#include <geode/mesh/core/detail/facet_storage.h>
4549
#include <geode/mesh/core/mesh_factory.h>
4650
#include <geode/mesh/core/polygonal_surface.h>
4751
#include <geode/mesh/core/private/surface_mesh_impl.h>
4852
#include <geode/mesh/core/surface_edges.h>
4953
#include <geode/mesh/core/texture2d.h>
5054
#include <geode/mesh/core/texture_storage.h>
55+
#include <geode/mesh/core/triangulated_surface.h>
56+
#include <geode/mesh/io/triangulated_surface_output.h>
5157

5258
namespace
5359
{
@@ -98,6 +104,25 @@ namespace
98104
"edge" );
99105
}
100106

107+
template < geode::index_t dimension >
108+
void output( const geode::SurfaceMesh< dimension >& mesh )
109+
{
110+
auto surf = geode::TriangulatedSurface< dimension >::create();
111+
auto bui =
112+
geode::TriangulatedSurfaceBuilder< dimension >::create( *surf );
113+
for( const auto v : geode::Range{ mesh.nb_vertices() } )
114+
{
115+
bui->create_point( mesh.point( v ) );
116+
}
117+
for( const auto p : geode::Range{ mesh.nb_polygons() } )
118+
{
119+
const auto vertices = mesh.polygon_vertices( p );
120+
bui->create_triangle( { vertices[0], vertices[1], vertices[2] } );
121+
}
122+
bui->delete_isolated_vertices();
123+
geode::save_triangulated_surface( *surf, "output.og_tsf3d" );
124+
}
125+
101126
template < geode::index_t dimension >
102127
geode::detail::PolygonsAroundVertexImpl compute_polygons_around_vertex(
103128
const geode::SurfaceMesh< dimension >& mesh,
@@ -147,6 +172,10 @@ namespace
147172
safety_count++;
148173
}
149174
}
175+
if( safety_count >= MAX_SAFETY_COUNT )
176+
{
177+
output( mesh );
178+
}
150179
OPENGEODE_EXCEPTION( safety_count < MAX_SAFETY_COUNT,
151180
"[SurfaceMesh::polygons_around_vertex] Too many polygons "
152181
"around vertex ",
@@ -1051,6 +1080,48 @@ namespace geode
10511080
}
10521081
}
10531082

1083+
template < index_t dimension >
1084+
bool SurfaceMesh< dimension >::is_polygon_degenerated(
1085+
index_t polygon_id ) const
1086+
{
1087+
double max_length{ 0. };
1088+
local_index_t max_length_edge{ 0 };
1089+
for( const auto e : LRange{ nb_polygon_edges( polygon_id ) } )
1090+
{
1091+
const auto cur_length = edge_length( PolygonEdge{ polygon_id, e } );
1092+
if( cur_length > max_length )
1093+
{
1094+
max_length = cur_length;
1095+
max_length_edge = e;
1096+
}
1097+
}
1098+
if( max_length < global_epsilon )
1099+
{
1100+
return true;
1101+
}
1102+
const auto vertices = polygon_vertices( polygon_id );
1103+
const auto next =
1104+
max_length_edge + 1 == nb_polygon_vertices( polygon_id )
1105+
? 0
1106+
: max_length_edge + 1;
1107+
InfiniteLine< dimension > line{ Segment< dimension >{
1108+
this->point( vertices[max_length_edge] ),
1109+
this->point( vertices[next] ) } };
1110+
for( const auto v : LIndices{ vertices } )
1111+
{
1112+
if( v == max_length_edge || v == next )
1113+
{
1114+
continue;
1115+
}
1116+
if( point_line_distance( this->point( vertices[v] ), line )
1117+
> global_epsilon )
1118+
{
1119+
return false;
1120+
}
1121+
}
1122+
return true;
1123+
}
1124+
10541125
template < index_t dimension >
10551126
std::unique_ptr< SurfaceMesh< dimension > >
10561127
SurfaceMesh< dimension >::clone() const

0 commit comments

Comments
 (0)