Skip to content

Commit 03467ce

Browse files
BotellaAclaude
andcommitted
fix(MSHInput): ignore elements with repeated nodes
An element listing the same node twice became a polygon or polyhedron with a repeated vertex, which is an invalid mesh element. Such elements are now skipped, with one warning giving how many were ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent d11fa30 commit 03467ce

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

‎src/geode/io/model/msh_input.cpp‎

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <absl/container/flat_hash_map.h>
3333
#include <absl/container/flat_hash_set.h>
34+
#include <absl/container/inlined_vector.h>
3435
#include <absl/strings/ascii.h>
3536
#include <absl/strings/str_cat.h>
3637
#include <absl/strings/str_split.h>
@@ -68,6 +69,7 @@
6869
namespace
6970
{
7071
constexpr geode::index_t POINT_TYPE{ 15 };
72+
constexpr geode::index_t MAX_ELEMENT_NODES{ 8 };
7173

7274
/// Counts read from the file are not trusted to reserve memory
7375
constexpr geode::index_t MAX_RESERVE{ 1U << 24U };
@@ -277,6 +279,11 @@ namespace
277279
nodes_read && elements_read, nullptr,
278280
geode::OpenGeodeException::TYPE::data,
279281
"[MSHInput::read_file] Missing $Nodes or $Elements section" );
282+
if( nb_degenerate_elements_ != 0 )
283+
{
284+
geode::Logger::warning( "[MSHInput] ", nb_degenerate_elements_,
285+
" elements with repeated nodes are ignored" );
286+
}
280287
}
281288

282289
void build_geometry()
@@ -708,7 +715,7 @@ namespace
708715
geode::index_t gmsh_type,
709716
absl::Span< const std::string_view > node_tokens )
710717
{
711-
component.types.push_back( gmsh_type );
718+
absl::InlinedVector< geode::index_t, MAX_ELEMENT_NODES > nodes;
712719
for( const auto& node : node_tokens )
713720
{
714721
const auto node_tag = geode::string_to_index( node );
@@ -718,8 +725,16 @@ namespace
718725
geode::OpenGeodeException::TYPE::data, "[MSHInput] Line ",
719726
line_number_, ": element refers to unknown node ",
720727
node_tag );
721-
component.nodes.push_back( node_id.value() );
728+
if( absl::c_linear_search( nodes, node_id.value() ) )
729+
{
730+
nb_degenerate_elements_++;
731+
return;
732+
}
733+
nodes.push_back( node_id.value() );
722734
}
735+
component.types.push_back( gmsh_type );
736+
component.nodes.insert(
737+
component.nodes.end(), nodes.begin(), nodes.end() );
723738
}
724739

725740
void read_element( const std::string& line )
@@ -1392,6 +1407,7 @@ namespace
13921407
double version_{ 2 };
13931408
bool has_entities_{ false };
13941409
geode::index_t line_number_{ 0 };
1410+
geode::index_t nb_degenerate_elements_{ 0 };
13951411
std::vector< geode::Point3D > nodes_;
13961412
NodeTags node_tags_;
13971413
std::array< absl::flat_hash_map< geode::index_t, ComponentElements >,

‎tests/model/test-msh.cpp‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,22 @@ namespace
551551
check_unique_vertices( brep );
552552
}
553553

554+
void test_degenerate_elements()
555+
{
556+
write_file( "degenerate_elements_v2.msh",
557+
absl::StrCat( V2_HEADER,
558+
"$Nodes\n4\n1 0 0 0\n2 1 0 0\n3 0 1 0\n4 1 1 0\n"
559+
"$EndNodes\n",
560+
"$Elements\n3\n1 2 2 0 1 1 2 3\n2 2 2 0 1 2 4 2\n"
561+
"3 1 2 0 2 4 4\n$EndElements\n" ) );
562+
const auto brep = geode::load_brep( "degenerate_elements_v2.msh" );
563+
geode::OpenGeodeIOModelException::test(
564+
first_surface_mesh( brep ).nb_polygons() == 1,
565+
"Degenerate polygon should be ignored" );
566+
geode::OpenGeodeIOModelException::test( brep.nb_lines() == 0,
567+
"Line with only a degenerate edge should be removed" );
568+
}
569+
554570
void test_is_loadable()
555571
{
556572
write_file( "unsupported_version.msh",
@@ -694,6 +710,7 @@ int main()
694710
test_empty_components();
695711
test_corner_with_several_nodes();
696712
test_unknown_bounding_entities();
713+
test_degenerate_elements();
697714

698715
geode::Logger::info( "TEST SUCCESS" );
699716
return 0;

0 commit comments

Comments
 (0)