diff --git a/bindings/python/src/inspector/topology/brep_topology.h b/bindings/python/src/inspector/topology/brep_topology.h index 9ed10dc7..0c272837 100644 --- a/bindings/python/src/inspector/topology/brep_topology.h +++ b/bindings/python/src/inspector/topology/brep_topology.h @@ -31,7 +31,7 @@ namespace geode void define_brep_topology_inspector( pybind11::module& module ) { pybind11::class_< BRepCornersTopologyInspectionResult >( - module, "BRepCornersInspectionResult" ) + module, "BRepCornersTopologyInspectionResult" ) .def( pybind11::init<>() ) .def_readwrite( "multiple_corners_unique_vertices", &BRepCornersTopologyInspectionResult:: @@ -46,60 +46,61 @@ namespace geode &BRepCornersTopologyInspectionResult:: line_corners_without_boundary_status ); - pybind11::class_< BRepLinesInspectionResult >( - module, "BRepLinesInspectionResult" ) + pybind11::class_< BRepLinesTopologyInspectionResult >( + module, "BRepLinesTopologyInspectionResult" ) .def( pybind11::init<>() ) .def_readwrite( "part_of_not_boundary_nor_internal_line_unique_vertices", - &BRepLinesInspectionResult:: + &BRepLinesTopologyInspectionResult:: part_of_not_boundary_nor_internal_line_unique_vertices ) .def_readwrite( "part_of_line_with_invalid_internal_topology_unique_vertices", - &BRepLinesInspectionResult:: + &BRepLinesTopologyInspectionResult:: part_of_line_with_invalid_internal_topology_unique_vertices ) .def_readwrite( "part_of_invalid_unique_line_unique_vertices", - &BRepLinesInspectionResult:: + &BRepLinesTopologyInspectionResult:: part_of_invalid_unique_line_unique_vertices ) .def_readwrite( "part_of_lines_but_not_corner_unique_vertices", - &BRepLinesInspectionResult:: + &BRepLinesTopologyInspectionResult:: part_of_lines_but_not_corner_unique_vertices ); - pybind11::class_< BRepSurfacesInspectionResult >( - module, "BRepSurfacesInspectionResult" ) + pybind11::class_< BRepSurfacesTopologyInspectionResult >( + module, "BRepSurfacesTopologyInspectionResult" ) .def( pybind11::init<>() ) .def_readwrite( "part_of_not_boundary_nor_internal_surface_unique_vertices", - &BRepSurfacesInspectionResult:: + &BRepSurfacesTopologyInspectionResult:: part_of_not_boundary_nor_internal_surface_unique_vertices ) .def_readwrite( "part_of_surface_with_invalid_internal_topology_" "unique_vertices", - &BRepSurfacesInspectionResult:: + &BRepSurfacesTopologyInspectionResult:: part_of_surface_with_invalid_internal_topology_unique_vertices ) .def_readwrite( "part_of_invalid_unique_surface_unique_vertices", - &BRepSurfacesInspectionResult:: + &BRepSurfacesTopologyInspectionResult:: part_of_invalid_unique_surface_unique_vertices ) .def_readwrite( "part_of_invalid_multiple_surfaces_unique_vertices", - &BRepSurfacesInspectionResult:: + &BRepSurfacesTopologyInspectionResult:: part_of_invalid_multiple_surfaces_unique_vertices ) .def_readwrite( "part_of_line_and_not_on_surface_border_unique_vertices", - &BRepSurfacesInspectionResult:: + &BRepSurfacesTopologyInspectionResult:: part_of_line_and_not_on_surface_border_unique_vertices ); - pybind11::class_< BRepBlocksInspectionResult >( - module, "BRepBlocksInspectionResult" ) + pybind11::class_< BRepBlocksTopologyInspectionResult >( + module, "BRepBlocksTopologyInspectionResult" ) .def( pybind11::init<>() ) .def_readwrite( "part_of_invalid_blocks_unique_vertices", - &BRepBlocksInspectionResult:: + &BRepBlocksTopologyInspectionResult:: part_of_invalid_blocks_unique_vertices ); - pybind11::class_< BRepInspectionResult >( - module, "BRepInspectionResult" ) + pybind11::class_< BRepTopologyInspectionResult >( + module, "BRepTopologyInspectionResult" ) .def( pybind11::init<>() ) - .def_readwrite( "corners", &BRepInspectionResult::corners ) - .def_readwrite( "lines", &BRepInspectionResult::lines ) - .def_readwrite( "surfaces", &BRepInspectionResult::surfaces ) - .def_readwrite( "blocks", &BRepInspectionResult::blocks ); + .def_readwrite( "corners", &BRepTopologyInspectionResult::corners ) + .def_readwrite( "lines", &BRepTopologyInspectionResult::lines ) + .def_readwrite( + "surfaces", &BRepTopologyInspectionResult::surfaces ) + .def_readwrite( "blocks", &BRepTopologyInspectionResult::blocks ); pybind11::class_< BRepTopologyInspector >( module, "BRepTopologyInspector" ) @@ -113,12 +114,14 @@ namespace geode .def( "brep_unique_vertices_are_linked_to_a_component_vertex", &BRepTopologyInspector:: brep_unique_vertices_are_linked_to_a_component_vertex ) - .def( "unique_vertices_not_linked_to_a_component_vertex", + /*.def( "unique_vertices_not_linked_to_a_component_vertex", &BRepTopologyInspector:: unique_vertices_not_linked_to_a_component_vertex ) + */ .def( "invalid_components_topology_unique_vertices", &BRepTopologyInspector:: invalid_components_topology_unique_vertices ) - .def( "inspect_brep", &BRepTopologyInspector::inspect_brep ); + .def( "inspect_brep_topology", + &BRepTopologyInspector::inspect_brep_topology ); } } // namespace geode diff --git a/include/geode/inspector/information.h b/include/geode/inspector/information.h new file mode 100644 index 00000000..397598e9 --- /dev/null +++ b/include/geode/inspector/information.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 - 2023 Geode-solutions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include + +namespace geode +{ + template < typename ProblemType > + struct ProblemInspectionResult + { + ProblemInspectionResult( absl::string_view problem_descrption ) + : description{ problem_descrption } + { + } + + index_t number() + { + return problems.size(); + } + + void add_problem( + const ProblemType& problem, const std::string& message ) + { + problems.push_back( problem ); + messages.push_back( message ); + } + + std::string description; + std::vector< ProblemType > problems{}; + std::vector< std::string > messages{}; + }; +} // namespace geode \ No newline at end of file diff --git a/include/geode/inspector/topology/brep_blocks_topology.h b/include/geode/inspector/topology/brep_blocks_topology.h index ef9c1038..49bfa7f9 100644 --- a/include/geode/inspector/topology/brep_blocks_topology.h +++ b/include/geode/inspector/topology/brep_blocks_topology.h @@ -23,19 +23,32 @@ #pragma once +#include + #include +#include namespace geode { + struct ComponentMeshVertex; class BRep; + struct uuid; } // namespace geode namespace geode { - struct opengeode_inspector_inspector_api BRepBlocksInspectionResult + struct opengeode_inspector_inspector_api BRepBlocksTopologyInspectionResult { - std::vector< index_t > part_of_invalid_blocks_unique_vertices{}; + ProblemInspectionResult< uuid > blocks_not_meshed{ + "Blocks not meshed" + }; + ProblemInspectionResult< ComponentMeshVertex > + blocks_not_linked_to_unique_vertex{ + "Blocks without unique vertex" + }; + ProblemInspectionResult< index_t > + part_of_invalid_blocks_unique_vertices{ "" }; }; /*! * Class for inspecting the topology of a BRep model blocks through @@ -45,9 +58,6 @@ namespace geode { public: BRepBlocksTopology( const BRep& brep ); - - BRepBlocksTopology( const BRep& brep, bool verbose ); - /*! * Checks if the brep unique vertices are parts of valid blocks, * i.e. verify: @@ -56,13 +66,12 @@ namespace geode * the 2 blocks), or it is part of more than to blocks (and it is * either a corner, or not a corner but part of only one line). */ - bool brep_vertex_blocks_topology_is_valid( + absl::optional< std::string > brep_vertex_blocks_topology_is_valid( index_t unique_vertex_index ) const; - BRepBlocksInspectionResult inspect_blocks() const; + BRepBlocksTopologyInspectionResult inspect_blocks() const; private: const BRep& brep_; - bool verbose_; }; } // namespace geode \ No newline at end of file diff --git a/include/geode/inspector/topology/brep_corners_topology.h b/include/geode/inspector/topology/brep_corners_topology.h index 18b720ec..fe613d91 100644 --- a/include/geode/inspector/topology/brep_corners_topology.h +++ b/include/geode/inspector/topology/brep_corners_topology.h @@ -23,10 +23,11 @@ #pragma once -#include +#include +#include -#include #include +#include namespace geode { @@ -38,14 +39,21 @@ namespace geode { struct opengeode_inspector_inspector_api BRepCornersTopologyInspectionResult { - std::vector< ComponentMeshVertex > - corners_not_linked_to_unique_vertex{}; - absl::flat_hash_map< index_t, std::vector< std::string > > problems{}; - - std::vector< index_t > multiple_corners_unique_vertices{}; - std::vector< index_t > multiple_internals_corner_vertices{}; - std::vector< index_t > not_internal_nor_boundary_corner_vertices{}; - std::vector< index_t > line_corners_without_boundary_status{}; + ProblemInspectionResult< ComponentMeshVertex > + corners_not_linked_to_unique_vertex{ + "Corners without unique vertex" + }; + ProblemInspectionResult< index_t > multiple_corners_unique_vertices{ + "Unique vertices that are part of several corners." + }; + ProblemInspectionResult< index_t > multiple_internals_corner_vertices{ + "Corners with several embeddings" + }; + ProblemInspectionResult< index_t > + not_internal_nor_boundary_corner_vertices{ "Isolated Corners" }; + ProblemInspectionResult< index_t > line_corners_without_boundary_status{ + "Corner on line but not a boundary)" + }; }; class opengeode_inspector_inspector_api BRepCornersTopology diff --git a/include/geode/inspector/topology/brep_lines_topology.h b/include/geode/inspector/topology/brep_lines_topology.h index ca69e0d3..8decb950 100644 --- a/include/geode/inspector/topology/brep_lines_topology.h +++ b/include/geode/inspector/topology/brep_lines_topology.h @@ -22,24 +22,37 @@ */ #pragma once +#include #include +#include namespace geode { + struct ComponentMeshVertex; class BRep; + struct uuid; } // namespace geode namespace geode { - struct opengeode_inspector_inspector_api BRepLinesInspectionResult + struct opengeode_inspector_inspector_api BRepLinesTopologyInspectionResult { - std::vector< index_t > - part_of_not_boundary_nor_internal_line_unique_vertices{}; - std::vector< index_t > - part_of_line_with_invalid_internal_topology_unique_vertices{}; - std::vector< index_t > part_of_invalid_unique_line_unique_vertices{}; - std::vector< index_t > part_of_lines_but_not_corner_unique_vertices{}; + ProblemInspectionResult< uuid > lines_not_meshed{ "Lines not meshed" }; + ProblemInspectionResult< ComponentMeshVertex > + lines_not_linked_to_unique_vertex{ + "Lines not completly linked to unique vertex" + }; + ProblemInspectionResult< index_t > + part_of_not_boundary_nor_internal_line_unique_vertices{ "" }; + ProblemInspectionResult< index_t > + part_of_line_with_invalid_internal_topology_unique_vertices{ "" }; + ProblemInspectionResult< index_t > + part_of_invalid_unique_line_unique_vertices{ "" }; + ProblemInspectionResult< index_t > + part_of_lines_but_not_corner_unique_vertices{ + "unique vertices on a line " + }; }; /*! * Class for inspecting the topology of a BRep model lines through their @@ -50,8 +63,6 @@ namespace geode public: BRepLinesTopology( const BRep& brep ); - BRepLinesTopology( const BRep& brep, bool verbose ); - /*! * Checks if the brep unique vertices are parts of valid lines, i.e. * verify: @@ -65,22 +76,23 @@ namespace geode bool brep_vertex_lines_topology_is_valid( index_t unique_vertex_index ) const; - bool vertex_is_part_of_not_boundary_nor_internal_line( - const index_t unique_vertex_index ) const; + absl::optional< std::string > + vertex_is_part_of_not_boundary_nor_internal_line( + const index_t unique_vertex_index ) const; - bool vertex_is_part_of_line_with_invalid_internal_topology( - const index_t unique_vertex_index ) const; + absl::optional< std::string > + vertex_is_part_of_line_with_invalid_internal_topology( + const index_t unique_vertex_index ) const; - bool vertex_is_part_of_invalid_unique_line( + absl::optional< std::string > vertex_is_part_of_invalid_unique_line( index_t unique_vertex_index ) const; - bool vertex_has_lines_but_is_not_corner( + absl::optional< std::string > vertex_has_lines_but_is_not_corner( index_t unique_vertex_index ) const; - BRepLinesInspectionResult inspect_lines() const; + BRepLinesTopologyInspectionResult inspect_lines() const; private: const BRep& brep_; - bool verbose_; }; } // namespace geode \ No newline at end of file diff --git a/include/geode/inspector/topology/brep_surfaces_topology.h b/include/geode/inspector/topology/brep_surfaces_topology.h index c7eeea45..cb72192e 100644 --- a/include/geode/inspector/topology/brep_surfaces_topology.h +++ b/include/geode/inspector/topology/brep_surfaces_topology.h @@ -22,27 +22,43 @@ */ #pragma once +#include #include +#include namespace geode { + struct ComponentMeshVertex; class BRep; + struct uuid; } // namespace geode namespace geode { - struct opengeode_inspector_inspector_api BRepSurfacesInspectionResult + struct opengeode_inspector_inspector_api + BRepSurfacesTopologyInspectionResult { - std::vector< index_t > - part_of_not_boundary_nor_internal_surface_unique_vertices{}; - std::vector< index_t > - part_of_surface_with_invalid_internal_topology_unique_vertices{}; - std::vector< index_t > part_of_invalid_unique_surface_unique_vertices{}; - std::vector< index_t > - part_of_invalid_multiple_surfaces_unique_vertices{}; - std::vector< index_t > - part_of_line_and_not_on_surface_border_unique_vertices{}; + ProblemInspectionResult< uuid > surfaces_not_meshed{ + "Surface not meshed" + }; + + ProblemInspectionResult< ComponentMeshVertex > + surfaces_not_linked_to_unique_vertex{ + "Surfaces without unique vertex" + }; + ProblemInspectionResult< index_t > + part_of_not_boundary_nor_internal_surface_unique_vertices{ "" }; + ProblemInspectionResult< index_t > + part_of_surface_with_invalid_internal_topology_unique_vertices{ + "" + }; + ProblemInspectionResult< index_t > + part_of_invalid_unique_surface_unique_vertices{ "" }; + ProblemInspectionResult< index_t > + part_of_invalid_multiple_surfaces_unique_vertices{ "" }; + ProblemInspectionResult< index_t > + part_of_line_and_not_on_surface_border_unique_vertices{ "" }; }; /*! * Class for inspecting the topology of a BRep model surfaces through @@ -53,8 +69,6 @@ namespace geode public: BRepSurfacesTopology( const BRep& brep ); - BRepSurfacesTopology( const BRep& brep, bool verbose ); - /*! * Checks if the brep unique vertices are parts of valid surfaces, * i.e. verify: @@ -74,25 +88,28 @@ namespace geode bool brep_vertex_surfaces_topology_is_valid( index_t unique_vertex_index ) const; - bool vertex_is_part_of_not_boundary_nor_internal_surface( - const index_t unique_vertex_index ) const; + absl::optional< std::string > + vertex_is_part_of_not_boundary_nor_internal_surface( + const index_t unique_vertex_index ) const; - bool vertex_is_part_of_surface_with_invalid_internal_topology( - const index_t unique_vertex_index ) const; + absl::optional< std::string > + vertex_is_part_of_surface_with_invalid_internal_topology( + const index_t unique_vertex_index ) const; - bool vertex_is_part_of_invalid_unique_surface( + absl::optional< std::string > vertex_is_part_of_invalid_unique_surface( index_t unique_vertex_index ) const; - bool vertex_is_part_of_invalid_multiple_surfaces( - index_t unique_vertex_index ) const; + absl::optional< std::string > + vertex_is_part_of_invalid_multiple_surfaces( + index_t unique_vertex_index ) const; - bool vertex_is_part_of_line_and_not_on_surface_border( - index_t unique_vertex_index ) const; + absl::optional< std::string > + vertex_is_part_of_line_and_not_on_surface_border( + index_t unique_vertex_index ) const; - BRepSurfacesInspectionResult inspect_surfaces() const; + BRepSurfacesTopologyInspectionResult inspect_surfaces() const; private: const BRep& brep_; - bool verbose_; }; } // namespace geode \ No newline at end of file diff --git a/include/geode/inspector/topology/brep_topology.h b/include/geode/inspector/topology/brep_topology.h index 4b91bec7..b0ba36dc 100644 --- a/include/geode/inspector/topology/brep_topology.h +++ b/include/geode/inspector/topology/brep_topology.h @@ -39,12 +39,17 @@ namespace geode namespace geode { - struct opengeode_inspector_inspector_api BRepInspectionResult + struct opengeode_inspector_inspector_api BRepTopologyInspectionResult { BRepCornersTopologyInspectionResult corners; - BRepLinesInspectionResult lines; - BRepSurfacesInspectionResult surfaces; - BRepBlocksInspectionResult blocks; + BRepLinesTopologyInspectionResult lines; + BRepSurfacesTopologyInspectionResult surfaces; + BRepBlocksTopologyInspectionResult blocks; + + ProblemInspectionResult< index_t > + unique_vertex_not_linked_to_any_component{ + "Unique vertex not linked to any component" + }; }; /*! * Class for inspecting the topology of a BRep model corners @@ -74,13 +79,7 @@ namespace geode bool brep_unique_vertices_are_linked_to_a_component_vertex() const; - BRepInspectionResult inspect_brep() const; - - std::vector< ComponentMeshVertex > - component_vertices_not_linked_to_a_unique_vertex() const; - - std::vector< index_t > - unique_vertices_not_linked_to_a_component_vertex() const; + BRepTopologyInspectionResult inspect_brep_topology() const; std::vector< index_t > invalid_components_topology_unique_vertices() const; diff --git a/include/geode/inspector/topology/private/topology_helpers.h b/include/geode/inspector/topology/private/topology_helpers.h index b0c48294..e82e576f 100644 --- a/include/geode/inspector/topology/private/topology_helpers.h +++ b/include/geode/inspector/topology/private/topology_helpers.h @@ -48,7 +48,8 @@ namespace geode std::vector< uuid > components_uuids( absl::Span< const ComponentMeshVertex > components ); - std::vector< geode::ComponentMeshVertex > + std::pair< std::vector< geode::ComponentMeshVertex >, + std::vector< std::string > > brep_component_vertices_not_associated_to_unique_vertices( const geode::BRep& brep, const geode::ComponentID& component_id, diff --git a/src/bin/geode-inspector-brep.cpp b/src/bin/geode-inspector-brep.cpp index 16fc47f2..d684bd4d 100644 --- a/src/bin/geode-inspector-brep.cpp +++ b/src/bin/geode-inspector-brep.cpp @@ -67,9 +67,9 @@ void inspect_brep( const geode::BRep& brep ) { const auto verbose = absl::GetFlag( FLAGS_verbose ); const geode::BRepInspector brep_inspector{ brep, verbose }; - auto result = brep_inspector.inspect_brep(); + auto result = brep_inspector.inspect_brep_topology(); absl::InlinedVector< async::task< void >, 27 > tasks; - if( absl::GetFlag( FLAGS_component_linking ) ) + /*if( absl::GetFlag( FLAGS_component_linking ) ) { tasks.emplace_back( async::spawn( [&brep_inspector] { const auto unlinked_component_vertices = @@ -86,7 +86,7 @@ void inspect_brep( const geode::BRep& brep ) geode::Logger::info( nb_unlinked_uv, " unique vertices not linked to a component mesh vertex" ); } ) ); - } + }*/ if( absl::GetFlag( FLAGS_unique_vertices_colocation ) ) { tasks.emplace_back( async::spawn( [&brep_inspector] { @@ -108,26 +108,27 @@ void inspect_brep( const geode::BRep& brep ) { tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.multiple_corners_unique_vertices.size(); + result.corners.multiple_corners_unique_vertices.number(); geode::Logger::info( nb, " unique vertices associated to multiple corners." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.multiple_internals_corner_vertices.size(); + result.corners.multiple_internals_corner_vertices.number(); geode::Logger::info( nb, " unique vertices associated to a corner " "with multiple internals." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.not_internal_nor_boundary_corner_vertices.size(); + result.corners.not_internal_nor_boundary_corner_vertices + .number(); geode::Logger::info( nb, " unique vertices associated to a corner which is neither " "internal nor boundary." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.line_corners_without_boundary_status.size(); + result.corners.line_corners_without_boundary_status.number(); geode::Logger::info( nb, " unique vertices associated to a corner " "part of a line but not boundary of it." ); } ) ); @@ -138,7 +139,7 @@ void inspect_brep( const geode::BRep& brep ) const auto nb = result.lines .part_of_not_boundary_nor_internal_line_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a line which is " "neither internal nor boundary." ); } ) ); @@ -146,20 +147,21 @@ void inspect_brep( const geode::BRep& brep ) const auto nb = result.lines .part_of_line_with_invalid_internal_topology_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a line with " "invalid internal topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.lines.part_of_invalid_unique_line_unique_vertices.size(); + result.lines.part_of_invalid_unique_line_unique_vertices + .number(); geode::Logger::info( nb, " unique vertices part of a unique line " "with invalid topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = result.lines.part_of_lines_but_not_corner_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of multiple lines but not a corner." ); } ) ); @@ -170,7 +172,7 @@ void inspect_brep( const geode::BRep& brep ) const auto nb = result.surfaces .part_of_not_boundary_nor_internal_surface_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a surface which " "is neither internal nor boundary." ); } ) ); @@ -178,21 +180,21 @@ void inspect_brep( const geode::BRep& brep ) const auto nb = result.surfaces .part_of_surface_with_invalid_internal_topology_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a surface with " "invalid internal topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = result.surfaces.part_of_invalid_unique_surface_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a unique " "surface with invalid topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = result.surfaces - .part_of_invalid_multiple_surfaces_unique_vertices.size(); + .part_of_invalid_multiple_surfaces_unique_vertices.number(); geode::Logger::info( nb, " unique vertices part of multiple " "surfaces with invalid topology." ); } ) ); @@ -200,7 +202,7 @@ void inspect_brep( const geode::BRep& brep ) const auto nb = result.surfaces .part_of_line_and_not_on_surface_border_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a line and a surface but for " "which one of the associated vertex on the surface mesh is not " @@ -211,7 +213,7 @@ void inspect_brep( const geode::BRep& brep ) { tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.blocks.part_of_invalid_blocks_unique_vertices.size(); + result.blocks.part_of_invalid_blocks_unique_vertices.number(); geode::Logger::info( nb, " unique vertices part of blocks with invalid topology." ); } ) ); diff --git a/src/bin/geode-inspector-structural-model.cpp b/src/bin/geode-inspector-structural-model.cpp index 06640741..93a4d71e 100644 --- a/src/bin/geode-inspector-structural-model.cpp +++ b/src/bin/geode-inspector-structural-model.cpp @@ -83,26 +83,26 @@ void inspect_model( const geode::StructuralModel& model ) { const auto verbose = absl::GetFlag( FLAGS_verbose ); const geode::BRepInspector model_inspector{ model, verbose }; - auto result = model_inspector.inspect_brep(); + auto result = model_inspector.inspect_brep_topology(); absl::InlinedVector< async::task< void >, 27 > tasks; - if( absl::GetFlag( FLAGS_component_linking ) ) - { - tasks.emplace_back( async::spawn( [&model_inspector] { - const auto unlinked_component_vertices = - model_inspector - .component_vertices_not_linked_to_a_unique_vertex(); - geode::Logger::info( unlinked_component_vertices.size(), - " component vertices not linked to a unique vertex" ); - } ) ); - tasks.emplace_back( async::spawn( [&model_inspector] { - const auto nb_unlinked_uv = - model_inspector - .unique_vertices_not_linked_to_a_component_vertex() - .size(); - geode::Logger::info( nb_unlinked_uv, - " unique vertices not linked to a component mesh vertex" ); - } ) ); - } + /*if( absl::GetFlag( FLAGS_component_linking ) ) + { + tasks.emplace_back( async::spawn( [&model_inspector] { + const auto unlinked_component_vertices = + model_inspector + .component_vertices_not_linked_to_a_unique_vertex(); + geode::Logger::info( unlinked_component_vertices.size(), + " component vertices not linked to a unique vertex" ); + } ) ); + tasks.emplace_back( async::spawn( [&model_inspector] { + const auto nb_unlinked_uv = + model_inspector + .unique_vertices_not_linked_to_a_component_vertex() + .size(); + geode::Logger::info( nb_unlinked_uv, + " unique vertices not linked to a component mesh vertex" ); + } ) ); + }*/ if( absl::GetFlag( FLAGS_unique_vertices_colocation ) ) { tasks.emplace_back( async::spawn( [&model_inspector] { @@ -123,26 +123,27 @@ void inspect_model( const geode::StructuralModel& model ) { tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.multiple_corners_unique_vertices.size(); + result.corners.multiple_corners_unique_vertices.number(); geode::Logger::info( nb, " unique vertices associated to multiple corners." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.multiple_internals_corner_vertices.size(); + result.corners.multiple_internals_corner_vertices.number(); geode::Logger::info( nb, " unique vertices associated to a corner " "with multiple internals." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.not_internal_nor_boundary_corner_vertices.size(); + result.corners.not_internal_nor_boundary_corner_vertices + .number(); geode::Logger::info( nb, " unique vertices associated to a corner which is neither " "internal nor boundary." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.corners.line_corners_without_boundary_status.size(); + result.corners.line_corners_without_boundary_status.number(); geode::Logger::info( nb, " unique vertices associated to a corner " "part of a line but not boundary of it." ); } ) ); @@ -153,7 +154,7 @@ void inspect_model( const geode::StructuralModel& model ) const auto nb = result.lines .part_of_not_boundary_nor_internal_line_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a line which is " "neither internal nor boundary." ); } ) ); @@ -161,20 +162,21 @@ void inspect_model( const geode::StructuralModel& model ) const auto nb = result.lines .part_of_line_with_invalid_internal_topology_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a line with " "invalid internal topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.lines.part_of_invalid_unique_line_unique_vertices.size(); + result.lines.part_of_invalid_unique_line_unique_vertices + .number(); geode::Logger::info( nb, " unique vertices part of a unique line " "with invalid topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = result.lines.part_of_lines_but_not_corner_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of multiple lines but not a corner." ); } ) ); @@ -185,7 +187,7 @@ void inspect_model( const geode::StructuralModel& model ) const auto nb = result.surfaces .part_of_not_boundary_nor_internal_surface_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a surface which " "is neither internal nor boundary." ); } ) ); @@ -193,21 +195,21 @@ void inspect_model( const geode::StructuralModel& model ) const auto nb = result.surfaces .part_of_surface_with_invalid_internal_topology_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a surface with " "invalid internal topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = result.surfaces.part_of_invalid_unique_surface_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a unique " "surface with invalid topology." ); } ) ); tasks.emplace_back( async::spawn( [&result] { const auto nb = result.surfaces - .part_of_invalid_multiple_surfaces_unique_vertices.size(); + .part_of_invalid_multiple_surfaces_unique_vertices.number(); geode::Logger::info( nb, " unique vertices part of multiple " "surfaces with invalid topology." ); } ) ); @@ -215,7 +217,7 @@ void inspect_model( const geode::StructuralModel& model ) const auto nb = result.surfaces .part_of_line_and_not_on_surface_border_unique_vertices - .size(); + .number(); geode::Logger::info( nb, " unique vertices part of a line and a surface but for " "which one of the associated vertex on the surface mesh is not " @@ -226,7 +228,7 @@ void inspect_model( const geode::StructuralModel& model ) { tasks.emplace_back( async::spawn( [&result] { const auto nb = - result.blocks.part_of_invalid_blocks_unique_vertices.size(); + result.blocks.part_of_invalid_blocks_unique_vertices.number(); geode::Logger::info( nb, " unique vertices part of blocks with invalid topology." ); } ) ); diff --git a/src/geode/inspector/CMakeLists.txt b/src/geode/inspector/CMakeLists.txt index 64278357..5ba6e8bf 100644 --- a/src/geode/inspector/CMakeLists.txt +++ b/src/geode/inspector/CMakeLists.txt @@ -98,6 +98,7 @@ add_geode_library( "mixin/add_inspectors.h" "section_inspector.h" "brep_inspector.h" + "information.h" "pointset_inspector.h" "edgedcurve_inspector.h" "surface_inspector.h" diff --git a/src/geode/inspector/topology/brep_blocks_topology.cpp b/src/geode/inspector/topology/brep_blocks_topology.cpp index 0af8ef6a..f23765e2 100644 --- a/src/geode/inspector/topology/brep_blocks_topology.cpp +++ b/src/geode/inspector/topology/brep_blocks_topology.cpp @@ -60,18 +60,13 @@ namespace namespace geode { - BRepBlocksTopology::BRepBlocksTopology( const BRep& brep, bool verbose ) - : brep_( brep ), verbose_( verbose ) + BRepBlocksTopology::BRepBlocksTopology( const BRep& brep ) : brep_( brep ) { } - BRepBlocksTopology::BRepBlocksTopology( const BRep& brep ) - : BRepBlocksTopology( brep, false ) - { - } - - bool BRepBlocksTopology::brep_vertex_blocks_topology_is_valid( - index_t unique_vertex_index ) const + absl::optional< std::string > + BRepBlocksTopology::brep_vertex_blocks_topology_is_valid( + index_t unique_vertex_index ) const { const auto block_cmvs = brep_.component_mesh_vertices( unique_vertex_index, Block3D::component_type_static() ); @@ -86,7 +81,7 @@ namespace geode && brep_.Relationships::is_boundary( surface.component_id.id(), block_uuids[1] ) ) { - return true; + return absl::nullopt; } for( const auto& line : brep_.component_mesh_vertices( @@ -99,18 +94,16 @@ namespace geode || brep_.Relationships::is_boundary( surface.component_id.id(), block_uuids[1] ) ) ) { - return true; + return absl::nullopt; } } } - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", unique_vertex_index, - " is part of two blocks, but not of a surface boundary " - "to the two blocks, nor of a line boundary to one " - "of the blocks incident surfaces." ); - } - return false; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of two blocks, but not of a surface boundary " + "to the two blocks, nor of a line boundary to one " + "of the blocks incident surfaces." ); } const auto corner_cmvs = brep_.component_mesh_vertices( unique_vertex_index, Corner3D::component_type_static() ); @@ -176,18 +169,15 @@ namespace geode { if( nb_block_cmvs != 1 ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of the block ", - block_uuid.string(), - " and exactly one corner and one line but " - "has ", - nb_block_cmvs, - " block component mesh vertices (should be " - "1)." ); - } - return false; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of the block " ) + + block_uuid.string() + + std::string( " and exactly one corner and one " + "line but has " ) + + std::to_string( nb_block_cmvs ) + + std::string( " block component mesh vertices " + "(should be 1)." ); } continue; } @@ -197,23 +187,23 @@ namespace geode + corner_cmvs.size(); if( nb_block_cmvs != predicted_nb_block_cmvs ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of the block ", - block_uuid.string(), - ", and of a corner, and of no internal line, " - "and of ", - nb_boundary_surface_cmvs, - " boundary surface(s), and of ", - nb_boundary_line_cmvs, - " line(s) on block boundaries, with ", - nb_block_cmvs, - " block component mesh vertices" - "(should be ", - predicted_nb_block_cmvs, ")." ); - } - return false; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of the block " ) + + block_uuid.string() + + std::string( + ", and of a corner, and of no internal line, " ) + + std::string( "and of " ) + + std::to_string( nb_boundary_surface_cmvs ) + + std::string( " boundary surface(s), and of " ) + + std::to_string( nb_boundary_line_cmvs ) + + std::string( + " line(s) on block boundaries, with " ) + + std::to_string( nb_block_cmvs ) + + std::string( " block component mesh vertices" ) + + std::string( "(should be " ) + + std::to_string( predicted_nb_block_cmvs ) + + std::string( ")." ); } continue; } @@ -225,17 +215,17 @@ namespace geode : nb_boundary_surface_cmvs / 2; if( nb_block_cmvs != predicted_nb_block_cmvs ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of the block ", - block_uuid.string(), - " and none of its internal surfaces but has ", - nb_block_cmvs, - " block component mesh vertices (should be ", - predicted_nb_block_cmvs, ")." ); - } - return false; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of the block " ) + + block_uuid.string() + + std::string( " and none of its internal " + "surfaces but has " ) + + std::to_string( nb_block_cmvs ) + + std::string( " block component mesh vertices " + "(should be " ) + + std::to_string( predicted_nb_block_cmvs ) + + std::string( ")." ); } continue; } @@ -252,31 +242,59 @@ namespace geode } if( nb_block_cmvs != predicted_nb_block_cmvs ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of the block ", - block_uuid.string(), ", of ", nb_internal_surface_cmvs, - " internal surface(s), of ", nb_boundary_surface_cmvs, - " boundary surface(s), and of ", nb_free_line_cmvs, - " free line(s), with ", nb_block_cmvs, - " block component mesh vertices (should be ", - predicted_nb_block_cmvs, ")." ); - } - return false; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of the block " ) + + block_uuid.string() + std::string( ", of " ) + + std::to_string( nb_internal_surface_cmvs ) + + std::string( " internal surface(s), of " ) + + std::to_string( nb_boundary_surface_cmvs ) + + std::string( " boundary surface(s), and of " ) + + std::to_string( nb_free_line_cmvs ) + + std::string( " free line(s), with " ) + + std::to_string( nb_block_cmvs ) + + std::string( + " block component mesh vertices (should be " ) + + std::to_string( predicted_nb_block_cmvs ) + + std::string( ")." ); } } - return true; + return absl::nullopt; } - BRepBlocksInspectionResult BRepBlocksTopology::inspect_blocks() const + BRepBlocksTopologyInspectionResult + BRepBlocksTopology::inspect_blocks() const { - BRepBlocksInspectionResult result; + BRepBlocksTopologyInspectionResult result; + for( const auto& block : brep_.blocks() ) + { + if( brep_.block( block.id() ).mesh().nb_vertices() == 0 ) + { + result.blocks_not_meshed.add_problem( block.id(), + block.id().string() + + std::string( " is a block without mesh." ) ); + } + + auto block_result = detail:: + brep_component_vertices_not_associated_to_unique_vertices( + brep_, block.component_id(), block.mesh() ); + result.blocks_not_linked_to_unique_vertex.problems.insert( + result.blocks_not_linked_to_unique_vertex.problems.end(), + std::make_move_iterator( block_result.first.begin() ), + std::make_move_iterator( block_result.first.end() ) ); + result.blocks_not_linked_to_unique_vertex.messages.insert( + result.blocks_not_linked_to_unique_vertex.messages.end(), + std::make_move_iterator( block_result.second.begin() ), + std::make_move_iterator( block_result.second.end() ) ); + } for( const auto unique_vertex_id : Range{ brep_.nb_unique_vertices() } ) { - if( !brep_vertex_blocks_topology_is_valid( unique_vertex_id ) ) + const auto block_topology_is_valid = + brep_vertex_blocks_topology_is_valid( unique_vertex_id ); + + if( block_topology_is_valid ) { - result.part_of_invalid_blocks_unique_vertices.push_back( - unique_vertex_id ); + result.part_of_invalid_blocks_unique_vertices.add_problem( + unique_vertex_id, block_topology_is_valid.value() ); } } return result; diff --git a/src/geode/inspector/topology/brep_corners_topology.cpp b/src/geode/inspector/topology/brep_corners_topology.cpp index f9a3a918..55938355 100644 --- a/src/geode/inspector/topology/brep_corners_topology.cpp +++ b/src/geode/inspector/topology/brep_corners_topology.cpp @@ -171,46 +171,44 @@ namespace geode auto corner_result = detail:: brep_component_vertices_not_associated_to_unique_vertices( brep_, corner.component_id(), corner.mesh() ); - result.corners_not_linked_to_unique_vertex.insert( - result.corners_not_linked_to_unique_vertex.end(), - std::make_move_iterator( corner_result.begin() ), - std::make_move_iterator( corner_result.end() ) ); + result.corners_not_linked_to_unique_vertex.problems.insert( + result.corners_not_linked_to_unique_vertex.problems.end(), + std::make_move_iterator( corner_result.first.begin() ), + std::make_move_iterator( corner_result.first.end() ) ); + result.corners_not_linked_to_unique_vertex.messages.insert( + result.corners_not_linked_to_unique_vertex.messages.end(), + std::make_move_iterator( corner_result.second.begin() ), + std::make_move_iterator( corner_result.second.end() ) ); } for( const auto unique_vertex_id : Range{ brep_.nb_unique_vertices() } ) { - std::vector< std::string > unique_vertex_problems; const auto has_multiple_corners = unique_vertex_has_multiple_corners( unique_vertex_id ); if( has_multiple_corners ) { - unique_vertex_problems.push_back( - has_multiple_corners.value() ); + result.multiple_corners_unique_vertices.add_problem( + unique_vertex_id, has_multiple_corners.value() ); } const auto has_multiple_embeddings = corner_has_multiple_embeddings( unique_vertex_id ); if( has_multiple_embeddings ) { - unique_vertex_problems.push_back( - has_multiple_embeddings.value() ); + result.multiple_internals_corner_vertices.add_problem( + unique_vertex_id, has_multiple_embeddings.value() ); } const auto not_internal_nor_boundary = corner_is_not_internal_nor_boundary( unique_vertex_id ); if( not_internal_nor_boundary ) { - unique_vertex_problems.push_back( - not_internal_nor_boundary.value() ); + result.not_internal_nor_boundary_corner_vertices.add_problem( + unique_vertex_id, not_internal_nor_boundary.value() ); } const auto without_boundary_status = corner_is_part_of_line_but_not_boundary( unique_vertex_id ); if( without_boundary_status ) { - unique_vertex_problems.push_back( - without_boundary_status.value() ); - } - if( !unique_vertex_problems.empty() ) - { - result.problems.emplace( - unique_vertex_id, unique_vertex_problems ); + result.line_corners_without_boundary_status.add_problem( + unique_vertex_id, without_boundary_status.value() ); } } return result; diff --git a/src/geode/inspector/topology/brep_lines_topology.cpp b/src/geode/inspector/topology/brep_lines_topology.cpp index 5cc4f94b..7e61dc1c 100644 --- a/src/geode/inspector/topology/brep_lines_topology.cpp +++ b/src/geode/inspector/topology/brep_lines_topology.cpp @@ -27,6 +27,7 @@ #include +#include #include #include @@ -39,14 +40,7 @@ namespace geode { - BRepLinesTopology::BRepLinesTopology( const BRep& brep, bool verbose ) - : brep_( brep ), verbose_( verbose ) - { - } - BRepLinesTopology::BRepLinesTopology( const BRep& brep ) - : BRepLinesTopology( brep, false ) - { - } + BRepLinesTopology::BRepLinesTopology( const BRep& brep ) : brep_( brep ) {} bool BRepLinesTopology::brep_vertex_lines_topology_is_valid( index_t unique_vertex_index ) const @@ -69,8 +63,9 @@ namespace geode return true; } - bool BRepLinesTopology::vertex_is_part_of_not_boundary_nor_internal_line( - const index_t unique_vertex_index ) const + absl::optional< std::string > + BRepLinesTopology::vertex_is_part_of_not_boundary_nor_internal_line( + const index_t unique_vertex_index ) const { for( const auto& line : brep_.component_mesh_vertices( unique_vertex_index, Line3D::component_type_static() ) ) @@ -78,20 +73,18 @@ namespace geode if( brep_.nb_embeddings( line.component_id.id() ) < 1 && brep_.nb_incidences( line.component_id.id() ) < 1 ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of line with uuid '", - line.component_id.id().string(), - "', which is neither embedded nor incident." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of line with uuid '" ) + + line.component_id.id().string() + + std::string( + "', which is neither embedded nor incident." ); } } - return false; + return absl::nullopt; } - bool BRepLinesTopology:: + absl::optional< std::string > BRepLinesTopology:: vertex_is_part_of_line_with_invalid_internal_topology( const index_t unique_vertex_index ) const { @@ -104,16 +97,14 @@ namespace geode if( brep_.Relationships::is_boundary( line_id, embedding.id() ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of line with uuid '", - line_id.string(), - "', which is both boundary and embedded in " - "surface with uuid '", - embedding.id().string(), "'." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of line with uuid '" ) + + line_id.string() + + std::string( + "', which is both boundary and embedded in " + "surface with uuid '" ) + + embedding.id().string() + std::string( "'." ); } if( embedding.type() == Block3D::component_type_static() && !detail::brep_blocks_are_meshed( brep_ ) ) @@ -127,32 +118,32 @@ namespace geode return cmv.component_id.id() == embedding.id(); } ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of line with uuid '", - line_id.string(), - "', which is embedded in surface with uuid '", - embedding.id().string(), - "', but the unique vertex is not linked to the " - "surface mesh vertices." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of line with uuid '" ) + + line_id.string() + + std::string( + "', which is embedded in surface with uuid '" ) + + embedding.id().string() + + std::string( + "', but the unique vertex is not linked to the " + "surface mesh vertices." ); } } } - return false; + return absl::nullopt; } - bool BRepLinesTopology::vertex_is_part_of_invalid_unique_line( - index_t unique_vertex_index ) const + absl::optional< std::string > + BRepLinesTopology::vertex_is_part_of_invalid_unique_line( + index_t unique_vertex_index ) const { const auto line_uuids = detail::components_uuids( brep_.component_mesh_vertices( unique_vertex_index, Line3D::component_type_static() ) ); if( line_uuids.size() != 1 ) { - return false; + return absl::nullopt; } const auto& line_id = line_uuids[0]; const auto surface_uuids = @@ -168,19 +159,16 @@ namespace geode && brep_.Relationships::is_boundary( line_id, surface_uuids[0] ) ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of only one line, with uuid '", - line_id.string(), - "', and only one surface, with uuid '", - surface_uuids[0].string(), - "', but the line is neither embedded in the " - "surface, nor boundary of the surface while the " - "surface is embedded in a block." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of only one line, with uuid '" ) + + line_id.string() + + std::string( "', and only one surface, with uuid '" ) + + surface_uuids[0].string() + + std::string( + "', but the line is neither embedded in the " + "surface, nor boundary of the surface while the " + "surface is embedded in a block." ); } } else if( surface_uuids.empty() ) @@ -190,17 +178,14 @@ namespace geode && brep_.Relationships::is_internal( line_id, block_uuids[0] ) ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of only one line, with uuid '", - line_id.string(), - "', no surfaces, but is either part of no or " - "several blocks, or the line is not internal to " - "one." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of only one line, with uuid '" ) + + line_id.string() + + std::string( + "', no surfaces, but is either part of no or " + "several blocks, or the line is not internal to " + "one." ); } } else @@ -211,26 +196,26 @@ namespace geode && !brep_.Relationships::is_internal( line_id, surface_id ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of only one line, with uuid '", - line_id.string(), - "', and multiple surfaces, but the line is " - "neither internal nor boundary of surface with " - "uuid '", - surface_id.string(), "', in which the vertex is." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of only one line, with uuid '" ) + + line_id.string() + + std::string( + "', and multiple surfaces, but the line is " + "neither internal nor boundary of surface with " + "uuid '" ) + + surface_id.string() + + std::string( "', in which the vertex is." ); } } } - return false; + return absl::nullopt; } - bool BRepLinesTopology::vertex_has_lines_but_is_not_corner( - index_t unique_vertex_index ) const + absl::optional< std::string > + BRepLinesTopology::vertex_has_lines_but_is_not_corner( + index_t unique_vertex_index ) const { if( brep_.component_mesh_vertices( unique_vertex_index, Line3D::component_type_static() ) @@ -241,43 +226,72 @@ namespace geode unique_vertex_index, Corner3D::component_type_static() ) .empty() ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", unique_vertex_index, - " is part of multiple lines but is not a corner." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of multiple lines but is not a corner." ); } - return false; + return absl::nullopt; } - BRepLinesInspectionResult BRepLinesTopology::inspect_lines() const + BRepLinesTopologyInspectionResult BRepLinesTopology::inspect_lines() const { - BRepLinesInspectionResult result; + BRepLinesTopologyInspectionResult result; + for( const auto& line : brep_.lines() ) + { + if( brep_.line( line.id() ).mesh().nb_vertices() == 0 ) + { + result.lines_not_meshed.add_problem( line.id(), + line.id().string() + + std::string( " is a line without mesh." ) ); + } + + auto line_result = detail:: + brep_component_vertices_not_associated_to_unique_vertices( + brep_, line.component_id(), line.mesh() ); + result.lines_not_linked_to_unique_vertex.problems.insert( + result.lines_not_linked_to_unique_vertex.problems.end(), + std::make_move_iterator( line_result.first.begin() ), + std::make_move_iterator( line_result.first.end() ) ); + result.lines_not_linked_to_unique_vertex.messages.insert( + result.lines_not_linked_to_unique_vertex.messages.end(), + std::make_move_iterator( line_result.second.begin() ), + std::make_move_iterator( line_result.second.end() ) ); + } for( const auto unique_vertex_id : Range{ brep_.nb_unique_vertices() } ) { - if( vertex_is_part_of_not_boundary_nor_internal_line( - unique_vertex_id ) ) + const auto boundary_nor_internal_line = + vertex_is_part_of_not_boundary_nor_internal_line( + unique_vertex_id ); + if( boundary_nor_internal_line ) { result.part_of_not_boundary_nor_internal_line_unique_vertices - .push_back( unique_vertex_id ); + .add_problem( + unique_vertex_id, boundary_nor_internal_line.value() ); } - if( vertex_is_part_of_line_with_invalid_internal_topology( - unique_vertex_id ) ) + const auto invalid_internal_topology = + vertex_is_part_of_line_with_invalid_internal_topology( + unique_vertex_id ); + if( invalid_internal_topology ) { result .part_of_line_with_invalid_internal_topology_unique_vertices - .push_back( unique_vertex_id ); + .add_problem( + unique_vertex_id, invalid_internal_topology.value() ); } - if( vertex_is_part_of_invalid_unique_line( unique_vertex_id ) ) + const auto invalid_unique_line = + vertex_is_part_of_invalid_unique_line( unique_vertex_id ); + if( invalid_unique_line ) { - result.part_of_invalid_unique_line_unique_vertices.push_back( - unique_vertex_id ); + result.part_of_invalid_unique_line_unique_vertices.add_problem( + unique_vertex_id, invalid_unique_line.value() ); } - if( vertex_has_lines_but_is_not_corner( unique_vertex_id ) ) + const auto lines_but_is_not_corner = + vertex_has_lines_but_is_not_corner( unique_vertex_id ); + if( lines_but_is_not_corner ) { - result.part_of_lines_but_not_corner_unique_vertices.push_back( - unique_vertex_id ); + result.part_of_lines_but_not_corner_unique_vertices.add_problem( + unique_vertex_id, lines_but_is_not_corner.value() ); } } return result; diff --git a/src/geode/inspector/topology/brep_surfaces_topology.cpp b/src/geode/inspector/topology/brep_surfaces_topology.cpp index 9ed4638b..fea931b2 100644 --- a/src/geode/inspector/topology/brep_surfaces_topology.cpp +++ b/src/geode/inspector/topology/brep_surfaces_topology.cpp @@ -67,12 +67,8 @@ namespace namespace geode { - BRepSurfacesTopology::BRepSurfacesTopology( const BRep& brep, bool verbose ) - : brep_( brep ), verbose_( verbose ) - { - } BRepSurfacesTopology::BRepSurfacesTopology( const BRep& brep ) - : BRepSurfacesTopology( brep, false ) + : brep_( brep ) { } @@ -100,7 +96,7 @@ namespace geode return true; } - bool BRepSurfacesTopology:: + absl::optional< std::string > BRepSurfacesTopology:: vertex_is_part_of_not_boundary_nor_internal_surface( const index_t unique_vertex_index ) const { @@ -111,21 +107,19 @@ namespace geode if( brep_.nb_embeddings( surface_id ) < 1 && brep_.nb_incidences( surface_id ) < 1 ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, " is part of surface with uuid '", - surface_id.string(), - "', which is neither internal to a block nor a " - "boundary of a block." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of surface with uuid '" ) + + surface_id.string() + + std::string( + "', which is neither internal to a block nor a " + "boundary of a block." ); } } - return false; + return absl::nullopt; } - bool BRepSurfacesTopology:: + absl::optional< std::string > BRepSurfacesTopology:: vertex_is_part_of_surface_with_invalid_internal_topology( const index_t unique_vertex_index ) const { @@ -138,17 +132,14 @@ namespace geode if( brep_.Relationships::is_boundary( surface_id, embedding.id() ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of surface with uuid '", - surface_id.string(), - "', which is both internal and boundary of " - "block with uuid '", - embedding.id().string(), "'." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of surface with uuid '" ) + + surface_id.string() + + std::string( + "', which is both internal and boundary of " ) + + std::string( "block with uuid '" ) + + embedding.id().string() + std::string( "'." ); } if( detail::brep_blocks_are_meshed( brep_ ) && !absl::c_any_of( @@ -158,33 +149,32 @@ namespace geode return cmv.component_id.id() == embedding.id(); } ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of surface with uuid '", - surface_id.string(), - "', which is embedded in block with uuid '", - embedding.id().string(), - "', but the unique vertex is not linked to the " - "block vertices." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of surface with uuid '" ) + + surface_id.string() + + std::string( + "', which is embedded in block with uuid '" ) + + embedding.id().string() + + std::string( + "', but the unique vertex is not linked to the " + "block vertices." ); } } } - return false; + return absl::nullopt; } - bool BRepSurfacesTopology::vertex_is_part_of_invalid_unique_surface( - index_t unique_vertex_index ) const + absl::optional< std::string > + BRepSurfacesTopology::vertex_is_part_of_invalid_unique_surface( + index_t unique_vertex_index ) const { const auto surface_uuids = detail::components_uuids( brep_.component_mesh_vertices( unique_vertex_index, Surface3D::component_type_static() ) ); if( surface_uuids.size() != 1 ) { - return false; + return absl::nullopt; } const auto& surface_id = surface_uuids[0]; const auto block_uuids = @@ -192,13 +182,11 @@ namespace geode unique_vertex_index, Block3D::component_type_static() ) ); if( block_uuids.size() > 2 ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", unique_vertex_index, - " is part of only one surface, but is part of more " - "than two blocks." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of only one surface, but is part of more " + "than two blocks." ); } if( brep_.nb_embeddings( surface_id ) > 0 ) { @@ -206,27 +194,21 @@ namespace geode { if( block_uuids.size() != 1 ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of only one surface, which is " - "embedded, but not part of only one block." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of only one surface, which is " + "embedded, but not part of only one block." ); } else if( !brep_.Relationships::is_internal( surface_id, block_uuids[0] ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of only one surface, which is " - "embedded, and one block, but the surface is " - "not internal to the block." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of only one surface, which is " + "embedded, and one block, but the surface is " + "not internal to the block." ); } } } @@ -236,45 +218,43 @@ namespace geode { if( !brep_.Relationships::is_boundary( surface_id, block_id ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of only one surface, with uuid'", - surface_id.string(), - "' which is not embedded, but not boundary " - "either of block with uuid '", - block_id.string(), "', in which the vertex is." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of only one surface, with uuid'" ) + + surface_id.string() + + std::string( + "' which is not embedded, but not boundary " + "either of block with uuid '" ) + + block_id.string() + + std::string( "', in which the vertex is." ); } } } - return false; + return absl::nullopt; } - bool BRepSurfacesTopology::vertex_is_part_of_invalid_multiple_surfaces( - index_t unique_vertex_index ) const + absl::optional< std::string > + BRepSurfacesTopology::vertex_is_part_of_invalid_multiple_surfaces( + index_t unique_vertex_index ) const { const auto surface_uuids = detail::components_uuids( brep_.component_mesh_vertices( unique_vertex_index, Surface3D::component_type_static() ) ); if( surface_uuids.size() < 2 ) { - return false; + return absl::nullopt; } const auto line_cmvs = brep_.component_mesh_vertices( unique_vertex_index, Line3D::component_type_static() ); const auto line_uuids = detail::components_uuids( line_cmvs ); if( line_uuids.empty() ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", unique_vertex_index, - " is part of multiple surfaces, but not part of any " - "line." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of multiple surfaces, but not part of any " + "line." ); } if( line_uuids.size() == 1 ) { @@ -284,14 +264,11 @@ namespace geode .empty() && line_cmvs.size() < 2 ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of multiple surfaces and only one line, " - "but is a corner." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of multiple surfaces and only one line, " + "but is a corner." ); } for( const auto& surface_id : surface_uuids ) { @@ -300,18 +277,17 @@ namespace geode && !brep_.Relationships::is_internal( line_uuids[0], surface_id ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of multiple surfaces and only one " - "line, with uuid'", - line_uuids[0].string(), - "', but surface with uuid '", surface_id.string(), - "', in which the vertex is, is neither " - "incident nor embedding of the line." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of multiple surfaces and only one " + "line, with uuid'" ) + + line_uuids[0].string() + + std::string( "', but surface with uuid '" ) + + surface_id.string() + + std::string( + "', in which the vertex is, is neither " + "incident nor embedding of the line." ); } } } @@ -323,32 +299,31 @@ namespace geode && !line_is_boundary_of_at_least_two_surfaces_or_one_embedding_surface( brep_, line_id, surface_uuids ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of multiple surfaces and multiple " - "lines, but line with uuid'", - line_id.string(), - "' is neither internal, nor a boundary of at " - "least two surfaces or one embedding " - "surface." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( + " is part of multiple surfaces and multiple " + "lines, but line with uuid'" ) + + line_id.string() + + std::string( + "' is neither internal, nor a boundary of at " + "least two surfaces or one embedding " + "surface." ); } } } - return false; + return absl::nullopt; } - bool BRepSurfacesTopology::vertex_is_part_of_line_and_not_on_surface_border( - index_t unique_vertex_index ) const + absl::optional< std::string > + BRepSurfacesTopology::vertex_is_part_of_line_and_not_on_surface_border( + index_t unique_vertex_index ) const { const auto lines = brep_.component_mesh_vertices( unique_vertex_index, Line3D::component_type_static() ); if( lines.empty() ) { - return false; + return absl::nullopt; } for( const auto& surface_vertex : brep_.component_mesh_vertices( unique_vertex_index, Surface3D::component_type_static() ) ) @@ -363,58 +338,91 @@ namespace geode if( brep_.is_boundary( line, surface ) || brep_.is_internal( line, surface ) ) { - if( verbose_ ) - { - Logger::info( "Unique vertex with index ", - unique_vertex_index, - " is part of a line and of surface with " - "uuid '", - surface_vertex.component_id.id().string(), - "' but the associated vertex in the " - "surface mesh " - "is not on the mesh border." ); - } - return true; + return std::string( "Unique vertex with index " ) + + std::to_string( unique_vertex_index ) + + std::string( " is part of a line and of " + "surface with uuid '" ) + + surface_vertex.component_id.id().string() + + std::string( + "' but the associated vertex in the " + "surface mesh " + "is not on the mesh border." ); } } } } - return false; + return absl::nullopt; } - BRepSurfacesInspectionResult BRepSurfacesTopology::inspect_surfaces() const + BRepSurfacesTopologyInspectionResult + BRepSurfacesTopology::inspect_surfaces() const { - BRepSurfacesInspectionResult result; + BRepSurfacesTopologyInspectionResult result; + for( const auto& surface : brep_.surfaces() ) + { + if( brep_.surface( surface.id() ).mesh().nb_vertices() == 0 ) + { + result.surfaces_not_meshed.add_problem( surface.id(), + surface.id().string() + + std::string( " is a surface without mesh." ) ); + } + + auto surface_result = detail:: + brep_component_vertices_not_associated_to_unique_vertices( + brep_, surface.component_id(), surface.mesh() ); + result.surfaces_not_linked_to_unique_vertex.problems.insert( + result.surfaces_not_linked_to_unique_vertex.problems.end(), + std::make_move_iterator( surface_result.first.begin() ), + std::make_move_iterator( surface_result.first.end() ) ); + result.surfaces_not_linked_to_unique_vertex.messages.insert( + result.surfaces_not_linked_to_unique_vertex.messages.end(), + std::make_move_iterator( surface_result.second.begin() ), + std::make_move_iterator( surface_result.second.end() ) ); + } for( const auto unique_vertex_id : Range{ brep_.nb_unique_vertices() } ) { - if( vertex_is_part_of_not_boundary_nor_internal_surface( - unique_vertex_id ) ) + const auto not_boundary_nor_internal_surface = + vertex_is_part_of_not_boundary_nor_internal_surface( + unique_vertex_id ); + if( not_boundary_nor_internal_surface ) { result.part_of_not_boundary_nor_internal_surface_unique_vertices - .push_back( unique_vertex_id ); + .add_problem( unique_vertex_id, + not_boundary_nor_internal_surface.value() ); } - if( vertex_is_part_of_surface_with_invalid_internal_topology( - unique_vertex_id ) ) + const auto invalid_internal_topology = + vertex_is_part_of_surface_with_invalid_internal_topology( + unique_vertex_id ); + if( invalid_internal_topology ) { result .part_of_surface_with_invalid_internal_topology_unique_vertices - .push_back( unique_vertex_id ); + .add_problem( + unique_vertex_id, invalid_internal_topology.value() ); } - if( vertex_is_part_of_invalid_unique_surface( unique_vertex_id ) ) + const auto invalid_unique_surface = + vertex_is_part_of_invalid_unique_surface( unique_vertex_id ); + if( invalid_unique_surface ) { - result.part_of_invalid_unique_surface_unique_vertices.push_back( - unique_vertex_id ); + result.part_of_invalid_unique_surface_unique_vertices + .add_problem( + unique_vertex_id, invalid_unique_surface.value() ); } - if( vertex_is_part_of_invalid_multiple_surfaces( - unique_vertex_id ) ) + const auto invalid_multiple_surfaces = + vertex_is_part_of_invalid_multiple_surfaces( unique_vertex_id ); + if( invalid_multiple_surfaces ) { result.part_of_invalid_multiple_surfaces_unique_vertices - .push_back( unique_vertex_id ); + .add_problem( + unique_vertex_id, invalid_multiple_surfaces.value() ); } - if( vertex_is_part_of_line_and_not_on_surface_border( - unique_vertex_id ) ) + const auto line_and_not_on_surface_border = + vertex_is_part_of_line_and_not_on_surface_border( + unique_vertex_id ); + if( line_and_not_on_surface_border ) { result.part_of_line_and_not_on_surface_border_unique_vertices - .push_back( unique_vertex_id ); + .add_problem( unique_vertex_id, + line_and_not_on_surface_border.value() ); } } return result; diff --git a/src/geode/inspector/topology/brep_topology.cpp b/src/geode/inspector/topology/brep_topology.cpp index 0e238756..94765a27 100644 --- a/src/geode/inspector/topology/brep_topology.cpp +++ b/src/geode/inspector/topology/brep_topology.cpp @@ -80,32 +80,6 @@ namespace return true; } - std::vector< geode::ComponentMeshVertex > - brep_component_vertices_not_associated_to_unique_vertices( - const geode::BRep& brep, - const geode::ComponentID& component_id, - const geode::VertexSet& component_mesh, - bool verbose ) - { - std::vector< geode::ComponentMeshVertex > result; - for( const auto component_vertex : - geode::Range{ component_mesh.nb_vertices() } ) - { - geode::ComponentMeshVertex mesh_vertex{ component_id, - component_vertex }; - if( brep.unique_vertex( mesh_vertex ) == geode::NO_ID ) - { - if( verbose ) - { - geode::Logger::info( "Component vertex '", - mesh_vertex.string(), - "' is not linked to a unique vertex." ); - } - result.push_back( std::move( mesh_vertex ) ); - } - } - return result; - } } // namespace namespace geode @@ -113,10 +87,7 @@ namespace geode class BRepTopologyInspector::Impl { public: - Impl( const BRep& brep, bool verbose ) - : brep_( brep ), verbose_( verbose ) - { - } + Impl( const BRep& brep ) : brep_( brep ) {} bool brep_meshed_components_are_linked_to_unique_vertices() const { @@ -170,91 +141,46 @@ namespace geode return true; } - std::vector< ComponentMeshVertex > - component_vertices_not_linked_to_a_unique_vertex() const - { - std::vector< ComponentMeshVertex > result; - for( const auto& corner : brep_.corners() ) - { - auto corner_result = - brep_component_vertices_not_associated_to_unique_vertices( - brep_, corner.component_id(), corner.mesh(), verbose_ ); - result.insert( result.end(), - std::make_move_iterator( corner_result.begin() ), - std::make_move_iterator( corner_result.end() ) ); - } - for( const auto& line : brep_.lines() ) - { - auto line_result = - brep_component_vertices_not_associated_to_unique_vertices( - brep_, line.component_id(), line.mesh(), verbose_ ); - result.insert( result.end(), - std::make_move_iterator( line_result.begin() ), - std::make_move_iterator( line_result.end() ) ); - } - for( const auto& surface : brep_.surfaces() ) - { - auto surface_result = - brep_component_vertices_not_associated_to_unique_vertices( - brep_, surface.component_id(), surface.mesh(), - verbose_ ); - result.insert( result.end(), - std::make_move_iterator( surface_result.begin() ), - std::make_move_iterator( surface_result.end() ) ); - } - for( const auto& block : brep_.blocks() ) - { - auto block_result = - brep_component_vertices_not_associated_to_unique_vertices( - brep_, block.component_id(), block.mesh(), verbose_ ); - result.insert( result.end(), - std::make_move_iterator( block_result.begin() ), - std::make_move_iterator( block_result.end() ) ); - } - return result; - } - - std::vector< index_t > + std::pair< std::vector< index_t >, std::vector< std::string > > unique_vertices_not_linked_to_a_component_vertex() const { - std::vector< index_t > unlinked_uv; + std::pair< std::vector< index_t >, std::vector< std::string > > + result; for( const auto uv_id : Range{ brep_.nb_unique_vertices() } ) { if( brep_.component_mesh_vertices( uv_id ).empty() ) { - unlinked_uv.push_back( uv_id ); - if( verbose_ ) - { - Logger::info( "Unique vertex with id ", uv_id, - " is not linked to any component mesh vertex." ); - } + result.first.push_back( uv_id ); + result.second.push_back( + std::string( "Unique vertex with id " ) + + std::to_string( uv_id ) + + std::string( " is not linked to any component mesh " + "vertex." ) ); } } - return unlinked_uv; + return result; } private: const BRep& brep_; - DEBUG_CONST bool verbose_; }; BRepTopologyInspector::BRepTopologyInspector( const BRep& brep ) : BRepCornersTopology( brep ), - BRepLinesTopology( brep, false ), - BRepSurfacesTopology( brep, false ), - BRepBlocksTopology( brep, false ), - impl_( brep, false ), + BRepLinesTopology( brep ), + BRepSurfacesTopology( brep ), + BRepBlocksTopology( brep ), + impl_( brep ), brep_( brep ) { } - BRepTopologyInspector::BRepTopologyInspector( - const BRep& brep, bool verbose ) + const BRep& brep, bool verbause ) : BRepCornersTopology( brep ), - BRepLinesTopology( brep, verbose ), - BRepSurfacesTopology( brep, verbose ), - BRepBlocksTopology( brep, verbose ), - impl_( brep, verbose ), + BRepLinesTopology( brep ), + BRepSurfacesTopology( brep ), + BRepBlocksTopology( brep ), + impl_( brep ), brep_( brep ) { } @@ -298,28 +224,23 @@ namespace geode { return impl_->brep_unique_vertices_are_linked_to_a_component_vertex(); } - BRepInspectionResult BRepTopologyInspector::inspect_brep() const + BRepTopologyInspectionResult + BRepTopologyInspector::inspect_brep_topology() const { - BRepInspectionResult result; + BRepTopologyInspectionResult result; result.corners = inspect_corners(); result.lines = inspect_lines(); result.surfaces = inspect_surfaces(); result.blocks = inspect_blocks(); + const auto res = + impl_->unique_vertices_not_linked_to_a_component_vertex(); + result.unique_vertex_not_linked_to_any_component.problems = + std::move( res.first ); + result.unique_vertex_not_linked_to_any_component.messages = + std::move( res.second ); return result; } - std::vector< ComponentMeshVertex > BRepTopologyInspector:: - component_vertices_not_linked_to_a_unique_vertex() const - { - return impl_->component_vertices_not_linked_to_a_unique_vertex(); - } - - std::vector< index_t > BRepTopologyInspector:: - unique_vertices_not_linked_to_a_component_vertex() const - { - return impl_->unique_vertices_not_linked_to_a_component_vertex(); - } - std::vector< index_t > BRepTopologyInspector::invalid_components_topology_unique_vertices() const diff --git a/src/geode/inspector/topology/private/topology_helpers.cpp b/src/geode/inspector/topology/private/topology_helpers.cpp index d8e91d58..d04e8802 100644 --- a/src/geode/inspector/topology/private/topology_helpers.cpp +++ b/src/geode/inspector/topology/private/topology_helpers.cpp @@ -75,13 +75,16 @@ namespace geode return component_uuids; } - std::vector< geode::ComponentMeshVertex > + std::pair< std::vector< geode::ComponentMeshVertex >, + std::vector< std::string > > brep_component_vertices_not_associated_to_unique_vertices( const geode::BRep& brep, const geode::ComponentID& component_id, const geode::VertexSet& component_mesh ) { - std::vector< geode::ComponentMeshVertex > result; + std::pair< std::vector< geode::ComponentMeshVertex >, + std::vector< std::string > > + result; for( const auto component_vertex : geode::Range{ component_mesh.nb_vertices() } ) { @@ -89,7 +92,12 @@ namespace geode component_vertex }; if( brep.unique_vertex( mesh_vertex ) == geode::NO_ID ) { - result.push_back( std::move( mesh_vertex ) ); + result.first.push_back( std::move( mesh_vertex ) ); + result.second.push_back( + std::string( "Component vertex '" ) + + mesh_vertex.string() + + std::string( + "' is not linked to a unique vertex." ) ); } } return result; diff --git a/tests/inspector/test-brep.cpp b/tests/inspector/test-brep.cpp index 4bd4e6f1..60974f33 100644 --- a/tests/inspector/test-brep.cpp +++ b/tests/inspector/test-brep.cpp @@ -63,12 +63,12 @@ geode::index_t check_components_linking( geode::BRepInspector& brep_inspector ) nb_issues += nb_unlinked_blocks; geode::Logger::info( "There are ", nb_unlinked_blocks, " blocks not linked to a unique vertex." );*/ - const auto nb_unlinked_uv = + /*const auto nb_unlinked_uv = brep_inspector.unique_vertices_not_linked_to_a_component_vertex() .size(); nb_issues += nb_unlinked_uv; geode::Logger::info( "There are ", nb_unlinked_uv, - " unique vertices not linked to a component mesh vertex." ); + " unique vertices not linked to a component mesh vertex." );*/ return nb_issues; } @@ -105,80 +105,81 @@ geode::index_t launch_topological_validity_checks( geode::BRepInspector& brep_inspector ) { geode::index_t nb_issues{ 0 }; - auto result = brep_inspector.inspect_brep(); + auto result = brep_inspector.inspect_brep_topology(); - nb_issues += result.corners.multiple_corners_unique_vertices.size(); + nb_issues += result.corners.multiple_corners_unique_vertices.number(); geode::Logger::info( "There are ", - result.corners.multiple_corners_unique_vertices.size(), + result.corners.multiple_corners_unique_vertices.number(), " vertices with multiple corners." ); - nb_issues += result.corners.multiple_internals_corner_vertices.size(); + nb_issues += result.corners.multiple_internals_corner_vertices.number(); geode::Logger::info( "There are ", - result.corners.multiple_internals_corner_vertices.size(), + result.corners.multiple_internals_corner_vertices.number(), " vertices with multiple internals." ); nb_issues += - result.corners.not_internal_nor_boundary_corner_vertices.size(); + result.corners.not_internal_nor_boundary_corner_vertices.number(); geode::Logger::info( "There are ", - result.corners.multiple_internals_corner_vertices.size(), + result.corners.multiple_internals_corner_vertices.number(), " corner vertices with no boundary nor internal property." ); - nb_issues += result.corners.line_corners_without_boundary_status.size(); + nb_issues += result.corners.line_corners_without_boundary_status.number(); geode::Logger::info( "There are ", - result.corners.line_corners_without_boundary_status.size(), + result.corners.line_corners_without_boundary_status.number(), " corner vertices part of a line but not its boundary." ); nb_issues += result.lines.part_of_not_boundary_nor_internal_line_unique_vertices - .size(); + .number(); geode::Logger::info( "There are ", result.lines.part_of_not_boundary_nor_internal_line_unique_vertices - .size(), + .number(), " vertices part of a line which is not boundary not internal." ); nb_issues += - result.lines.part_of_invalid_unique_line_unique_vertices.size(); + result.lines.part_of_invalid_unique_line_unique_vertices.number(); geode::Logger::info( "There are ", - result.lines.part_of_invalid_unique_line_unique_vertices.size(), + result.lines.part_of_invalid_unique_line_unique_vertices.number(), " vertices part of a unique line with invalid toplogy." ); nb_issues += - result.lines.part_of_lines_but_not_corner_unique_vertices.size(); + result.lines.part_of_lines_but_not_corner_unique_vertices.number(); geode::Logger::info( "There are ", - result.lines.part_of_lines_but_not_corner_unique_vertices.size(), + result.lines.part_of_lines_but_not_corner_unique_vertices.number(), " vertices part of multiple lines but not corner." ); nb_issues += result.surfaces - .part_of_not_boundary_nor_internal_surface_unique_vertices.size(); + .part_of_not_boundary_nor_internal_surface_unique_vertices.number(); geode::Logger::info( "There are ", result.surfaces - .part_of_not_boundary_nor_internal_surface_unique_vertices.size(), + .part_of_not_boundary_nor_internal_surface_unique_vertices.number(), " vertices part of a surface which is neither internal nor boundary." ); nb_issues += result.surfaces .part_of_surface_with_invalid_internal_topology_unique_vertices - .size(); + .number(); geode::Logger::info( "There are ", result.surfaces .part_of_surface_with_invalid_internal_topology_unique_vertices - .size(), + .number(), " vertices part of a surface with invalid internal topology." ); nb_issues += - result.surfaces.part_of_invalid_unique_surface_unique_vertices.size(); + result.surfaces.part_of_invalid_unique_surface_unique_vertices.number(); geode::Logger::info( "There are ", - result.surfaces.part_of_invalid_unique_surface_unique_vertices.size(), + result.surfaces.part_of_invalid_unique_surface_unique_vertices.number(), " vertices part of a unique surface with invalid topology." ); - nb_issues += result.surfaces - .part_of_invalid_multiple_surfaces_unique_vertices.size(); + nb_issues += + result.surfaces.part_of_invalid_multiple_surfaces_unique_vertices + .number(); geode::Logger::info( "There are ", result.surfaces.part_of_invalid_multiple_surfaces_unique_vertices - .size(), + .number(), " vertices part of invalid multiple surfaces." ); nb_issues += result.surfaces.part_of_line_and_not_on_surface_border_unique_vertices - .size(); + .number(); geode::Logger::info( "There are ", result.surfaces.part_of_line_and_not_on_surface_border_unique_vertices - .size(), + .number(), " vertices part of a line and a surface but not on the surface " "border." ); - nb_issues += result.blocks.part_of_invalid_blocks_unique_vertices.size(); + nb_issues += result.blocks.part_of_invalid_blocks_unique_vertices.number(); geode::Logger::info( "There are ", - result.blocks.part_of_invalid_blocks_unique_vertices.size(), + result.blocks.part_of_invalid_blocks_unique_vertices.number(), " vertices with invalid block topology." ); ;