diff --git a/include/geode/inspector/topology/brep_lines_topology.hpp b/include/geode/inspector/topology/brep_lines_topology.hpp index 11e44c25..0aead114 100644 --- a/include/geode/inspector/topology/brep_lines_topology.hpp +++ b/include/geode/inspector/topology/brep_lines_topology.hpp @@ -68,6 +68,10 @@ namespace geode "Indices of unique vertices linked to several Lines but not " "linked to a Corner." }; + InspectionIssuesMap< index_t > + line_edges_with_wrong_component_edges_around{ + "Indices of line edges with wrong component edges around" + }; [[nodiscard]] index_t nb_issues() const; @@ -118,6 +122,10 @@ namespace geode vertex_has_lines_but_is_not_a_corner( index_t unique_vertex_index ) const; + [[nodiscard]] std::optional< std::string > + line_edge_has_wrong_component_edges_around( + const Line3D& line, const index_t edge_index ) const; + [[nodiscard]] BRepLinesTopologyInspectionResult inspect_lines_topology() const; diff --git a/include/geode/inspector/topology/brep_surfaces_topology.hpp b/include/geode/inspector/topology/brep_surfaces_topology.hpp index e5fbc2eb..01a4b410 100644 --- a/include/geode/inspector/topology/brep_surfaces_topology.hpp +++ b/include/geode/inspector/topology/brep_surfaces_topology.hpp @@ -62,6 +62,10 @@ namespace geode "Indices of unique vertices linked to a Line but not linked to " "a Surface border." }; + InspectionIssuesMap< index_t > + surface_polygons_with_wrong_component_facets_around{ + "Indices of surface polygons with wrong component facets around" + }; [[nodiscard]] index_t nb_issues() const; @@ -114,6 +118,10 @@ namespace geode vertex_is_part_of_line_and_not_on_surface_border( index_t unique_vertex_index ) const; + [[nodiscard]] std::optional< std::string > + surface_facet_has_wrong_component_facets_around( + const Surface3D& line, const index_t facet_index ) const; + [[nodiscard]] BRepSurfacesTopologyInspectionResult inspect_surfaces_topology() const; diff --git a/src/geode/inspector/topology/brep_blocks_topology.cpp b/src/geode/inspector/topology/brep_blocks_topology.cpp index 3bcf27fd..b3cb4399 100644 --- a/src/geode/inspector/topology/brep_blocks_topology.cpp +++ b/src/geode/inspector/topology/brep_blocks_topology.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -944,7 +943,7 @@ namespace geode } for( const auto& block : brep_.blocks() ) { - if( brep_.block( block.id() ).mesh().nb_vertices() != 0 ) + if( block_is_meshed( brep_.block( block.id() ) ) ) { meshed_blocks.push_back( block.id() ); } diff --git a/src/geode/inspector/topology/brep_lines_topology.cpp b/src/geode/inspector/topology/brep_lines_topology.cpp index 0823e1e8..95908c97 100644 --- a/src/geode/inspector/topology/brep_lines_topology.cpp +++ b/src/geode/inspector/topology/brep_lines_topology.cpp @@ -298,60 +298,52 @@ namespace geode } const auto cme = geode::component_mesh_edges( brep_, brep_.line( cmv.component_id.id() ), 0 ); - if( brep_.nb_incidences( cmv.component_id.id() ) >= 1 ) + for( const auto& incident_surface : + brep_.incidences( brep_.line( cmv.component_id.id() ) ) ) { - for( const auto& incident_surface : - brep_.incidences( brep_.line( cmv.component_id.id() ) ) ) + if( !cme.surface_edges.contains( incident_surface.id() ) ) { - if( !cme.surface_edges.contains( incident_surface.id() ) ) - { - return absl::StrCat( "Unique vertex with index ", - unique_vertex_index, " is part of line with uuid '", - cmv.component_id.id().string(), - "', which should be boundary of " - "surface with uuid '", - incident_surface.id().string() ); - } - const auto& surface_edges = - cme.surface_edges.at( incident_surface.id() ); - if( surface_edges.size() != 1 ) - { - return absl::StrCat( "Unique vertex with index ", - unique_vertex_index, " is part of line with uuid '", - cmv.component_id.id().string(), - "', which should not be boundary of " - "surface with uuid '", - incident_surface.id().string() ); - } + return absl::StrCat( "Unique vertex with index ", + unique_vertex_index, " is part of line with uuid '", + cmv.component_id.id().string(), + "', which should be boundary of " + "surface with uuid '", + incident_surface.id().string() ); + } + const auto& surface_edges = + cme.surface_edges.at( incident_surface.id() ); + if( surface_edges.size() != 1 ) + { + return absl::StrCat( "Unique vertex with index ", + unique_vertex_index, " is part of line with uuid '", + cmv.component_id.id().string(), + "', which should not be boundary of " + "surface with uuid '", + incident_surface.id().string() ); } } - if( brep_.nb_embedding_surfaces( - brep_.line( cmv.component_id.id() ) ) - >= 1 ) + for( const auto& embedding_surface : brep_.embedding_surfaces( + brep_.line( cmv.component_id.id() ) ) ) { - for( const auto& embedding_surface : brep_.embedding_surfaces( - brep_.line( cmv.component_id.id() ) ) ) + if( !cme.surface_edges.contains( embedding_surface.id() ) ) { - if( !cme.surface_edges.contains( embedding_surface.id() ) ) - { - return absl::StrCat( "Unique vertex with index ", - unique_vertex_index, " is part of line with uuid '", - cmv.component_id.id().string(), - "', which should not be embedded in " - "surface with uuid '", - embedding_surface.id().string() ); - } - const auto& surface_edges = - cme.surface_edges.at( embedding_surface.id() ); - if( surface_edges.size() <= 1 ) - { - return absl::StrCat( "Unique vertex with index ", - unique_vertex_index, " is part of line with uuid '", - cmv.component_id.id().string(), - "', which should not be embedded in " - "surface with uuid '", - embedding_surface.id().string() ); - } + return absl::StrCat( "Unique vertex with index ", + unique_vertex_index, " is part of line with uuid '", + cmv.component_id.id().string(), + "', which should not be embedded in " + "surface with uuid '", + embedding_surface.id().string() ); + } + const auto& surface_edges = + cme.surface_edges.at( embedding_surface.id() ); + if( surface_edges.size() <= 1 ) + { + return absl::StrCat( "Unique vertex with index ", + unique_vertex_index, " is part of line with uuid '", + cmv.component_id.id().string(), + "', which should not be embedded in " + "surface with uuid '", + embedding_surface.id().string() ); } } if( brep_.nb_incidences( cmv.component_id.id() ) < 1 @@ -404,6 +396,59 @@ namespace geode return std::nullopt; } + std::optional< std::string > + BRepLinesTopology::line_edge_has_wrong_component_edges_around( + const Line3D& line, const index_t edge_index ) const + { + const auto cme = component_mesh_edges( brep_, line, edge_index ); + for( const auto& [surface_id, surface_edges] : cme.surface_edges ) + { + if( brep_.is_boundary( line, brep_.surface( surface_id ) ) ) + { + if( surface_edges.size() != 1 ) + { + return absl::StrCat( "Line with uuid '", line.id().string(), + "' is boundary of surface with uuid '", + surface_id.string(), "', but has ", + surface_edges.size(), + " edges of this surface around it, it should be 1." ); + } + continue; + } + if( brep_.is_internal( line, brep_.surface( surface_id ) ) ) + { + if( surface_edges.size() != 2 ) + { + return absl::StrCat( "Line with uuid '", line.id().string(), + "' is internal to surface with uuid '", + surface_id.string(), "', but has ", + surface_edges.size(), + " edges of this surface around it, it should be 2." ); + } + continue; + } + return absl::StrCat( "Line with uuid '", line.id().string(), + "' has edge with id ", edge_index, + " in common with surface with uuid '", surface_id.string(), + "', but is neither boundary of nor internal to it." ); + } + for( const auto& [block_id, block_edges] : cme.block_edges ) + { + if( brep_.is_internal( line, brep_.block( block_id ) ) ) + { + if( block_edges.size() != 1 ) + { + return absl::StrCat( "Line with uuid '", line.id().string(), + "' is internal to block with uuid '", block_id.string(), + "', but has ", block_edges.size(), + " edges of this surface around it, it should be 1." ); + } + continue; + } + } + return std::nullopt; + } + BRepLinesTopologyInspectionResult BRepLinesTopology::inspect_lines_topology() const { @@ -427,6 +472,24 @@ namespace geode result.lines_not_linked_to_a_unique_vertex.add_issues_to_map( line.id(), std::move( line_result ) ); } + InspectionIssues< index_t > line_edges_with_wrong_cme{ absl::StrCat( + "Line ", line.id().string() ) }; + for( const auto edge_id : Range{ line.mesh().nb_edges() } ) + { + if( const auto problem_message = + line_edge_has_wrong_component_edges_around( + line, edge_id ) ) + { + line_edges_with_wrong_cme.add_issue( + edge_id, problem_message.value() ); + } + } + if( line_edges_with_wrong_cme.nb_issues() != 0 ) + { + result.line_edges_with_wrong_component_edges_around + .add_issues_to_map( + line.id(), std::move( line_edges_with_wrong_cme ) ); + } } for( const auto unique_vertex_id : Range{ brep_.nb_unique_vertices() } ) { diff --git a/src/geode/inspector/topology/brep_surfaces_topology.cpp b/src/geode/inspector/topology/brep_surfaces_topology.cpp index 1402c098..72862eec 100644 --- a/src/geode/inspector/topology/brep_surfaces_topology.cpp +++ b/src/geode/inspector/topology/brep_surfaces_topology.cpp @@ -33,6 +33,7 @@ #include +#include #include #include #include @@ -325,10 +326,50 @@ namespace geode return std::nullopt; } + std::optional< std::string > + BRepSurfacesTopology::surface_facet_has_wrong_component_facets_around( + const Surface3D& surface, const index_t facet_index ) const + { + const auto cmp = component_mesh_polygons( brep_, surface, facet_index ); + for( const auto& [block_id, block_facets] : cmp.block_polygons ) + { + if( brep_.is_boundary( surface, brep_.block( block_id ) ) ) + { + if( block_facets.size() != 1 ) + { + return absl::StrCat( "Surface with uuid '", + surface.id().string(), + "' is boundary of block with uuid '", block_id.string(), + "', but has ", block_facets.size(), + " facets of this block around it, it should be 1." ); + } + continue; + } + if( brep_.is_internal( surface, brep_.block( block_id ) ) ) + { + if( block_facets.size() != 2 ) + { + return absl::StrCat( "Surface with uuid '", + surface.id().string(), + "' is internal to block with uuid '", block_id.string(), + "', but has ", block_facets.size(), + " facets of this block around it, it should be 2." ); + } + continue; + } + return absl::StrCat( "Surface with uuid '", surface.id().string(), + "' has facet with id ", facet_index, + " in common with block with uuid '", block_id.string(), + "', but is neither boundary of nor internal to it." ); + } + return std::nullopt; + } + BRepSurfacesTopologyInspectionResult BRepSurfacesTopology::inspect_surfaces_topology() const { BRepSurfacesTopologyInspectionResult result; + const auto meshed_blocks = internal::brep_blocks_are_meshed( brep_ ); for( const auto& surface : brep_.surfaces() ) { if( !surface_is_meshed( brep_.surface( surface.id() ) ) ) @@ -348,6 +389,29 @@ namespace geode result.surfaces_not_linked_to_a_unique_vertex.add_issues_to_map( surface.id(), std::move( surface_result ) ); } + if( !meshed_blocks ) + { + continue; + } + InspectionIssues< index_t > surface_facets_with_wrong_cme{ + absl::StrCat( "Surface ", surface.id().string() ) + }; + for( const auto facet_id : Range{ surface.mesh().nb_polygons() } ) + { + if( const auto problem_message = + surface_facet_has_wrong_component_facets_around( + surface, facet_id ) ) + { + surface_facets_with_wrong_cme.add_issue( + facet_id, problem_message.value() ); + } + } + if( surface_facets_with_wrong_cme.nb_issues() != 0 ) + { + result.surface_polygons_with_wrong_component_facets_around + .add_issues_to_map( surface.id(), + std::move( surface_facets_with_wrong_cme ) ); + } } for( const auto unique_vertex_id : Range{ brep_.nb_unique_vertices() } ) {