5050#include  < geode/model/mixin/core/surface.hpp> 
5151#include  < geode/model/representation/core/brep.hpp> 
5252
53+ #include  < geode/inspector/topology/internal/expected_nb_cmvs.hpp> 
5354#include  < geode/inspector/topology/internal/topology_helpers.hpp> 
5455
5556namespace 
@@ -128,22 +129,6 @@ namespace
128129        return  false ;
129130    }
130131
131-     template  < typename  Condition >
132-     geode::index_t  count_cmvs (
133-         absl::Span< const  geode::ComponentMeshVertex > cmvs,
134-         const  Condition& condition )
135-     {
136-         geode::index_t  counter{ 0  };
137-         for ( const  auto & cmv : cmvs )
138-         {
139-             if ( condition ( cmv ) )
140-             {
141-                 counter++;
142-             }
143-         }
144-         return  counter;
145-     }
146- 
147132    void  create_graph ( const  geode::BRep& brep,
148133        geode::GenericMapping< geode::uuid, geode::index_t  >&
149134            surface_uuids_to_graph_edges,
@@ -566,8 +551,7 @@ namespace geode
566551        }
567552        return  absl::StrCat ( " Unique vertex with index "  , unique_vertex_index,
568553            "  is part of two blocks, but not of a surface boundary to the " 
569-             " two " 
570-             " blocks, nor of a line boundary to one of the blocks incident " 
554+             " two blocks, nor of a line boundary to one of the blocks incident " 
571555            " surfaces."   );
572556    }
573557
@@ -577,159 +561,14 @@ namespace geode
577561    {
578562        const  auto  block_uuids = internal::components_uuids (
579563            brep_, unique_vertex_index, Block3D::component_type_static () );
580- 
581-         std::vector< ComponentMeshVertex > block_cmvs;
582-         std::vector< ComponentMeshVertex > surface_cmvs;
583-         std::vector< ComponentMeshVertex > line_cmvs;
584-         std::vector< ComponentMeshVertex > corner_cmvs;
585-         for ( const  auto & cmv :
586-             brep_.component_mesh_vertices ( unique_vertex_index ) )
587-         {
588-             if ( cmv.component_id .type () == Block3D::component_type_static () )
589-             {
590-                 block_cmvs.push_back ( cmv );
591-             }
592-             if ( cmv.component_id .type () == Surface3D::component_type_static () )
593-             {
594-                 surface_cmvs.push_back ( cmv );
595-             }
596-             if ( cmv.component_id .type () == Line3D::component_type_static () )
597-             {
598-                 line_cmvs.push_back ( cmv );
599-             }
600-             if ( cmv.component_id .type () == Corner3D::component_type_static () )
601-             {
602-                 corner_cmvs.push_back ( cmv );
603-             }
604-         }
564+         const  auto  component_cmvs =
565+             internal::vertex_cmvs_by_component ( brep_, unique_vertex_index );
605566        for ( const  auto & block_uuid : block_uuids )
606567        {
607-             const  auto  nb_block_cmvs =
608-                 count_cmvs ( block_cmvs, [&block_uuid]( const  auto & cmv ) {
609-                     return  cmv.component_id .id () == block_uuid;
610-                 } );
611- 
612-             const  auto  nb_internal_surface_cmvs = count_cmvs (
613-                 surface_cmvs, [&block_uuid, this ]( const  auto & cmv ) {
614-                     return  this ->brep_ .is_internal (
615-                         brep_.surface ( cmv.component_id .id () ),
616-                         brep_.block ( block_uuid ) );
617-                 } );
618- 
619-             const  auto  nb_boundary_surface_cmvs = count_cmvs (
620-                 surface_cmvs, [&block_uuid, this ]( const  auto & cmv ) {
621-                     return  this ->brep_ .is_boundary (
622-                         brep_.surface ( cmv.component_id .id () ),
623-                         brep_.block ( block_uuid ) );
624-                 } );
625-             const  auto  nb_boundary_line_cmvs =
626-                 count_cmvs ( line_cmvs, [&block_uuid, this ]( const  auto & cmv ) {
627-                     for ( const  auto & block_boundary :
628-                         this ->brep_ .boundaries ( brep_.block ( block_uuid ) ) )
629-                     {
630-                         for ( const  auto & surface_boundary :
631-                             this ->brep_ .boundaries ( block_boundary ) )
632-                         {
633-                             if ( surface_boundary.id () == cmv.component_id .id () )
634-                             {
635-                                 return  true ;
636-                             }
637-                         }
638-                         for ( const  auto & surface_internal :
639-                             this ->brep_ .internal_lines ( block_boundary ) )
640-                         {
641-                             if ( surface_internal.id () == cmv.component_id .id () )
642-                             {
643-                                 return  true ;
644-                             }
645-                         }
646-                     }
647-                     return  false ;
648-                 } );
649-             const  auto  nb_free_line_cmvs =
650-                 count_cmvs ( line_cmvs, [this ]( const  auto & cmv ) {
651-                     return  this ->brep_ .nb_incidences ( cmv.component_id .id () )
652-                                == 1 
653-                            && this ->brep_ .nb_embedding_surfaces (
654-                                   brep_.line ( cmv.component_id .id () ) )
655-                                   == 0 ;
656-                 } );
657-             if ( corner_cmvs.size () == 1  && nb_internal_surface_cmvs == 0  )
658-             {
659-                 if ( nb_boundary_line_cmvs == 1  )
660-                 {
661-                     if ( nb_block_cmvs != 1  )
662-                     {
663-                         return  absl::StrCat ( " Unique vertex with index "  ,
664-                             unique_vertex_index, "  is part of block "  ,
665-                             block_uuid.string (),
666-                             "  and exactly one corner and one line but " 
667-                             " has "  ,
668-                             nb_block_cmvs,
669-                             "  block component mesh vertices (should be " 
670-                             " 1)."   );
671-                     }
672-                     continue ;
673-                 }
674- 
675-                 const  auto  predicted_nb_block_cmvs = nb_boundary_surface_cmvs
676-                                                      + corner_cmvs.size ()
677-                                                      - nb_boundary_line_cmvs;
678-                 if ( nb_block_cmvs != predicted_nb_block_cmvs )
679-                 {
680-                     return  absl::StrCat ( " Unique vertex with index "  ,
681-                         unique_vertex_index, "  is part of the block "  ,
682-                         block_uuid.string (),
683-                         " , and of a corner, and of no internal line, "  ,
684-                         " and of "  , nb_boundary_surface_cmvs,
685-                         "  boundary surface(s), and of "  , nb_boundary_line_cmvs,
686-                         "  line(s) on block boundaries, with "  , nb_block_cmvs,
687-                         "  block component mesh vertices (should be "  ,
688-                         predicted_nb_block_cmvs, " )."   );
689-                 }
690-                 continue ;
691-             }
692- 
693-             if ( nb_internal_surface_cmvs == 0  )
568+             if ( auto  error_message = internal::wrong_nb_expected_block_cmvs (
569+                     brep_, unique_vertex_index, block_uuid, component_cmvs ) )
694570            {
695-                 const  auto  predicted_nb_block_cmvs =
696-                     nb_boundary_line_cmvs == 0  ? 1 
697-                                                : nb_boundary_surface_cmvs / 2 ;
698-                 if ( nb_block_cmvs != predicted_nb_block_cmvs )
699-                 {
700-                     return  absl::StrCat ( " Unique vertex with index "  ,
701-                         unique_vertex_index, "  is part of the block "  ,
702-                         block_uuid.string (),
703-                         "  and none of its internal surfaces but has "  ,
704-                         nb_block_cmvs,
705-                         "  block component mesh vertices (should be "  ,
706-                         predicted_nb_block_cmvs, " )."   );
707-                 }
708-                 continue ;
709-             }
710-             auto  predicted_nb_block_cmvs =
711-                 nb_internal_surface_cmvs < nb_free_line_cmvs + 1 
712-                     ? static_cast < index_t  >( 1  )
713-                     : nb_internal_surface_cmvs - nb_free_line_cmvs;
714-             if ( nb_internal_surface_cmvs - nb_free_line_cmvs == 1  )
715-             {
716-                 predicted_nb_block_cmvs++;
717-             }
718-             if ( nb_boundary_surface_cmvs > 1  && corner_cmvs.empty () )
719-             {
720-                 predicted_nb_block_cmvs += ( nb_boundary_surface_cmvs - 2  ) / 2 ;
721-             }
722-             if ( nb_block_cmvs != predicted_nb_block_cmvs )
723-             {
724-                 return  absl::StrCat ( " Unique vertex with index "  ,
725-                     unique_vertex_index, "  is part of the block "  ,
726-                     block_uuid.string (), " , has "  , nb_internal_surface_cmvs,
727-                     "  internal surface(s) component mesh vertices (CMVs), " 
728-                     " has "  ,
729-                     nb_boundary_surface_cmvs,
730-                     "  boundary surface(s) CMVs, and has "  , nb_free_line_cmvs,
731-                     "  free line(s) CMVs, with "  , nb_block_cmvs,
732-                     "  block CMVs (should be "  , predicted_nb_block_cmvs, " )."   );
571+                 return  error_message;
733572            }
734573        }
735574        return  std::nullopt ;
0 commit comments