From 7716920339833117777f81b32d6beb9d14a4f187 Mon Sep 17 00:00:00 2001 From: MelchiorSchuh Date: Wed, 24 Jun 2026 13:18:40 +0200 Subject: [PATCH 1/2] fix(Model): Added api functions to use and define internal relations between corners and closed lines --- .../representation/builder/brep_builder.cpp | 2 + .../builder/section_builder.cpp | 2 + .../src/model/representation/core/brep.cpp | 32 ++++++++ .../src/model/representation/core/section.cpp | 36 ++++++++- .../representation/builder/brep_builder.hpp | 3 + .../builder/section_builder.hpp | 3 + .../geode/model/representation/core/brep.hpp | 35 +++++++++ .../model/representation/core/section.hpp | 36 +++++++++ .../representation/builder/brep_builder.cpp | 6 ++ .../builder/section_builder.cpp | 6 ++ src/geode/model/representation/core/brep.cpp | 71 ++++++++++++++++++ .../model/representation/core/section.cpp | 75 +++++++++++++++++++ 12 files changed, 306 insertions(+), 1 deletion(-) diff --git a/bindings/python/src/model/representation/builder/brep_builder.cpp b/bindings/python/src/model/representation/builder/brep_builder.cpp index 4e8ffefd4..64ca347a2 100644 --- a/bindings/python/src/model/representation/builder/brep_builder.cpp +++ b/bindings/python/src/model/representation/builder/brep_builder.cpp @@ -89,6 +89,8 @@ namespace geode &BRepBuilder::add_line_surface_boundary_relationship ) .def( "add_surface_block_boundary_relationship", &BRepBuilder::add_surface_block_boundary_relationship ) + .def( "add_corner_line_internal_relationship", + &BRepBuilder::add_corner_line_internal_relationship ) .def( "add_corner_surface_internal_relationship", &BRepBuilder::add_corner_surface_internal_relationship ) .def( "add_line_surface_internal_relationship", diff --git a/bindings/python/src/model/representation/builder/section_builder.cpp b/bindings/python/src/model/representation/builder/section_builder.cpp index 3f4c79bad..a18188a86 100644 --- a/bindings/python/src/model/representation/builder/section_builder.cpp +++ b/bindings/python/src/model/representation/builder/section_builder.cpp @@ -79,6 +79,8 @@ namespace geode &SectionBuilder::add_corner_line_boundary_relationship ) .def( "add_line_surface_boundary_relationship", &SectionBuilder::add_line_surface_boundary_relationship ) + .def( "add_corner_line_internal_relationship", + &SectionBuilder::add_corner_line_internal_relationship ) .def( "add_corner_surface_internal_relationship", &SectionBuilder::add_corner_surface_internal_relationship ) .def( "add_line_surface_internal_relationship", diff --git a/bindings/python/src/model/representation/core/brep.cpp b/bindings/python/src/model/representation/core/brep.cpp index c23d8e5fb..2713e8d8a 100644 --- a/bindings/python/src/model/representation/core/brep.cpp +++ b/bindings/python/src/model/representation/core/brep.cpp @@ -111,6 +111,20 @@ namespace geode return components; }, pybind11::return_value_policy::reference ) + .def( "nb_internal_corners_of_line", + static_cast< index_t ( BRep::* )( const Line3D& ) const >( + &BRep::nb_internal_corners ) ) + .def( + "internal_corners_of_line", + []( const BRep& brep, const Line3D& line ) { + std::vector< const Corner3D* > components; + for( const auto& component : brep.internal_corners( line ) ) + { + components.push_back( &component ); + } + return components; + }, + pybind11::return_value_policy::reference ) .def( "nb_internal_corners_of_surface", static_cast< index_t ( BRep::* )( const Surface3D& ) const >( &BRep::nb_internal_corners ) ) @@ -183,6 +197,21 @@ namespace geode return components; }, pybind11::return_value_policy::reference ) + .def( "nb_embedding_lines_of_corner", + static_cast< index_t ( BRep::* )( const Corner3D& ) const >( + &BRep::nb_embedding_lines ) ) + .def( + "embedding_lines_of_corner", + []( const BRep& brep, const Corner3D& corner ) { + std::vector< const Line3D* > components; + for( const auto& component : + brep.embedding_lines( corner ) ) + { + components.push_back( &component ); + } + return components; + }, + pybind11::return_value_policy::reference ) .def( "nb_embedding_surfaces_of_corner", static_cast< index_t ( BRep::* )( const Corner3D& ) const >( &BRep::nb_embedding_surfaces ) ) @@ -332,6 +361,9 @@ namespace geode .def( "is_block_boundary", static_cast< bool ( BRep::* )( const Surface3D&, const Block3D& ) const >( &BRep::is_boundary ) ) + .def( "is_corner_in_line_internals", + static_cast< bool ( BRep::* )( const Corner3D&, const Line3D& ) + const >( &BRep::is_internal ) ) .def( "is_corner_in_surface_internals", static_cast< bool ( BRep::* )( const Corner3D&, const Surface3D& ) const >( &BRep::is_internal ) ) diff --git a/bindings/python/src/model/representation/core/section.cpp b/bindings/python/src/model/representation/core/section.cpp index 825611e80..560b743df 100644 --- a/bindings/python/src/model/representation/core/section.cpp +++ b/bindings/python/src/model/representation/core/section.cpp @@ -87,8 +87,24 @@ namespace geode return components; }, pybind11::return_value_policy::reference ) + .def( "nb_internal_corners_of_line", + static_cast< index_t ( Section::* )( const Line2D& ) const >( + &Section::nb_internal_corners ) ) + .def( + "internal_corners_of_line", + []( const Section& section, const Line2D& line ) { + std::vector< const Corner2D* > components; + for( const auto& component : + section.internal_corners( line ) ) + { + components.push_back( &component ); + } + return components; + }, + pybind11::return_value_policy::reference ) .def( "nb_internal_corners_of_surface", - &Section::nb_internal_corners ) + static_cast< index_t ( Section::* )( const Surface2D& ) const >( + &Section::nb_internal_corners ) ) .def( "internal_corners_of_surface", []( const Section& section, const Surface2D& surface ) { @@ -114,6 +130,21 @@ namespace geode return components; }, pybind11::return_value_policy::reference ) + .def( "nb_embedding_lines_of_corner", + static_cast< index_t ( Section::* )( const Corner2D& ) const >( + &Section::nb_embedding_lines ) ) + .def( + "embedding_lines_of_corner", + []( const Section& section, const Corner2D& corner ) { + std::vector< const Line2D* > components; + for( const auto& component : + section.embedding_lines( corner ) ) + { + components.push_back( &component ); + } + return components; + }, + pybind11::return_value_policy::reference ) .def( "nb_embedding_surfaces_of_corner", static_cast< index_t ( Section::* )( const Corner2D& ) const >( &Section::nb_embedding_surfaces ) ) @@ -202,6 +233,9 @@ namespace geode .def( "is_surface_boundary", static_cast< bool ( Section::* )( const Line2D&, const Surface2D& ) const >( &Section::is_boundary ) ) + .def( "is_corner_in_line_internals", + static_cast< bool ( Section::* )( const Corner2D&, + const Line2D& ) const >( &Section::is_internal ) ) .def( "is_corner_in_surface_internals", static_cast< bool ( Section::* )( const Corner2D&, const Surface2D& ) const >( &Section::is_internal ) ) diff --git a/include/geode/model/representation/builder/brep_builder.hpp b/include/geode/model/representation/builder/brep_builder.hpp index e258309b8..a3dfc5070 100644 --- a/include/geode/model/representation/builder/brep_builder.hpp +++ b/include/geode/model/representation/builder/brep_builder.hpp @@ -211,6 +211,9 @@ namespace geode void add_surface_block_boundary_relationship( const Surface3D& surface, const Block3D& block ); + void add_corner_line_internal_relationship( + const Corner3D& corner, const Line3D& line ); + void add_corner_surface_internal_relationship( const Corner3D& corner, const Surface3D& surface ); diff --git a/include/geode/model/representation/builder/section_builder.hpp b/include/geode/model/representation/builder/section_builder.hpp index 73cab5c2e..f33e13a43 100644 --- a/include/geode/model/representation/builder/section_builder.hpp +++ b/include/geode/model/representation/builder/section_builder.hpp @@ -179,6 +179,9 @@ namespace geode void add_line_surface_boundary_relationship( const Line2D& line, const Surface2D& surface ); + void add_corner_line_internal_relationship( + const Corner2D& corner, const Line2D& line ); + void add_corner_surface_internal_relationship( const Corner2D& corner, const Surface2D& surface ); diff --git a/include/geode/model/representation/core/brep.hpp b/include/geode/model/representation/core/brep.hpp index fc35cc931..bdb8de8a5 100644 --- a/include/geode/model/representation/core/brep.hpp +++ b/include/geode/model/representation/core/brep.hpp @@ -208,6 +208,7 @@ namespace geode : public Relationships::InternalRangeIterator { public: + InternalCornerRange( const BRep& brep, const Line3D& line ); InternalCornerRange( const BRep& brep, const Surface3D& surface ); InternalCornerRange( const BRep& brep, const Block3D& block ); InternalCornerRange( const InternalCornerRange& range ); @@ -266,6 +267,26 @@ namespace geode const BRep& brep_; }; + class opengeode_model_api EmbeddingLineRange + : public Relationships::EmbeddingRangeIterator + { + public: + EmbeddingLineRange( const BRep& brep, const Corner3D& corner ); + EmbeddingLineRange( const EmbeddingLineRange& range ); + ~EmbeddingLineRange(); + + [[nodiscard]] const EmbeddingLineRange& begin() const; + + [[nodiscard]] const EmbeddingLineRange& end() const; + + void operator++(); + + [[nodiscard]] const Line3D& operator*() const; + + private: + const BRep& brep_; + }; + class opengeode_model_api EmbeddingSurfaceRange : public Relationships::EmbeddingRangeIterator { @@ -415,6 +436,11 @@ namespace geode [[nodiscard]] IncidentBlockRange incidences( const Surface3D& surface ) const; + [[nodiscard]] index_t nb_internal_corners( const Line3D& line ) const; + + [[nodiscard]] InternalCornerRange internal_corners( + const Line3D& line ) const; + [[nodiscard]] index_t nb_internal_corners( const Surface3D& surface ) const; @@ -443,6 +469,12 @@ namespace geode [[nodiscard]] InternalSurfaceRange internal_surfaces( const Block3D& block ) const; + [[nodiscard]] index_t nb_embedding_lines( + const Corner3D& corner ) const; + + [[nodiscard]] EmbeddingLineRange embedding_lines( + const Corner3D& corner ) const; + [[nodiscard]] index_t nb_embedding_surfaces( const Corner3D& corner ) const; @@ -499,6 +531,9 @@ namespace geode [[nodiscard]] bool is_boundary( const Surface3D& surface, const Block3D& block ) const; + [[nodiscard]] bool is_internal( + const Corner3D& corner, const Line3D& surface ) const; + [[nodiscard]] bool is_internal( const Corner3D& corner, const Surface3D& surface ) const; diff --git a/include/geode/model/representation/core/section.hpp b/include/geode/model/representation/core/section.hpp index 012583a8a..b7c7c523c 100644 --- a/include/geode/model/representation/core/section.hpp +++ b/include/geode/model/representation/core/section.hpp @@ -186,6 +186,7 @@ namespace geode : public Relationships::InternalRangeIterator { public: + InternalCornerRange( const Section& section, const Line2D& line ); InternalCornerRange( const Section& section, const Surface2D& surface ); InternalCornerRange( const InternalCornerRange& range ); @@ -203,6 +204,27 @@ namespace geode const Section& section_; }; + class opengeode_model_api EmbeddingLineRange + : public Relationships::EmbeddingRangeIterator + { + public: + EmbeddingLineRange( + const Section& section, const Corner2D& corner ); + EmbeddingLineRange( const EmbeddingLineRange& range ); + ~EmbeddingLineRange(); + + [[nodiscard]] const EmbeddingLineRange& begin() const; + + [[nodiscard]] const EmbeddingLineRange& end() const; + + void operator++(); + + [[nodiscard]] const Line2D& operator*() const; + + private: + const Section& section_; + }; + class opengeode_model_api EmbeddingSurfaceRange : public Relationships::EmbeddingRangeIterator { @@ -306,6 +328,11 @@ namespace geode [[nodiscard]] IncidentSurfaceRange incidences( const Line2D& line ) const; + [[nodiscard]] index_t nb_internal_corners( const Line2D& line ) const; + + [[nodiscard]] InternalCornerRange internal_corners( + const Line2D& line ) const; + [[nodiscard]] index_t nb_internal_corners( const Surface2D& surface ) const; @@ -318,6 +345,12 @@ namespace geode [[nodiscard]] InternalLineRange internal_lines( const Surface2D& surface ) const; + [[nodiscard]] index_t nb_embedding_lines( + const Corner2D& corner ) const; + + [[nodiscard]] EmbeddingLineRange embedding_lines( + const Corner2D& corner ) const; + [[nodiscard]] index_t nb_embedding_surfaces( const Corner2D& corner ) const; @@ -349,6 +382,9 @@ namespace geode [[nodiscard]] bool is_boundary( const Line2D& line, const Surface2D& surface ) const; + [[nodiscard]] bool is_internal( + const Corner2D& corner, const Line2D& line ) const; + [[nodiscard]] bool is_internal( const Corner2D& corner, const Surface2D& surface ) const; diff --git a/src/geode/model/representation/builder/brep_builder.cpp b/src/geode/model/representation/builder/brep_builder.cpp index e4ffb94fe..f48ed5833 100644 --- a/src/geode/model/representation/builder/brep_builder.cpp +++ b/src/geode/model/representation/builder/brep_builder.cpp @@ -444,6 +444,12 @@ namespace geode add_boundary_relation( surface.component_id(), block.component_id() ); } + void BRepBuilder::add_corner_line_internal_relationship( + const Corner3D& corner, const Line3D& line ) + { + add_internal_relation( corner.component_id(), line.component_id() ); + } + void BRepBuilder::add_line_surface_internal_relationship( const Line3D& line, const Surface3D& surface ) { diff --git a/src/geode/model/representation/builder/section_builder.cpp b/src/geode/model/representation/builder/section_builder.cpp index 9939230cd..0bba84560 100644 --- a/src/geode/model/representation/builder/section_builder.cpp +++ b/src/geode/model/representation/builder/section_builder.cpp @@ -366,6 +366,12 @@ namespace geode add_boundary_relation( line.component_id(), surface.component_id() ); } + void SectionBuilder::add_corner_line_internal_relationship( + const Corner2D& corner, const Line2D& line ) + { + add_internal_relation( corner.component_id(), line.component_id() ); + } + void SectionBuilder::add_corner_surface_internal_relationship( const Corner2D& corner, const Surface2D& surface ) { diff --git a/src/geode/model/representation/core/brep.cpp b/src/geode/model/representation/core/brep.cpp index 6157f6456..c79c7f9dd 100644 --- a/src/geode/model/representation/core/brep.cpp +++ b/src/geode/model/representation/core/brep.cpp @@ -320,6 +320,18 @@ namespace geode Relationships::InternalRangeIterator::operator*().id() ); } + BRep::InternalCornerRange BRep::internal_corners( const Line3D& line ) const + { + return { *this, line }; + } + + BRep::InternalCornerRange::InternalCornerRange( + const BRep& brep, const Line3D& line ) + : Relationships::InternalRangeIterator( brep, line.id() ), brep_( brep ) + { + internal::next_filtered_internal_iterator< Corner3D >( *this ); + } + BRep::InternalCornerRange BRep::internal_corners( const Surface3D& surface ) const { @@ -423,6 +435,50 @@ namespace geode Relationships::InternalRangeIterator::operator*().id() ); } + BRep::EmbeddingLineRange BRep::embedding_lines( + const Corner3D& corner ) const + { + return { *this, corner }; + } + + BRep::EmbeddingLineRange::EmbeddingLineRange( + const BRep& brep, const Corner3D& corner ) + : Relationships::EmbeddingRangeIterator( brep, corner.id() ), + brep_( brep ) + { + internal::next_filtered_embedding_iterator< Line3D >( *this ); + } + + BRep::EmbeddingLineRange::EmbeddingLineRange( + const EmbeddingLineRange& range ) + : Relationships::EmbeddingRangeIterator{ range }, brep_( range.brep_ ) + { + } + + BRep::EmbeddingLineRange::~EmbeddingLineRange() = default; + + auto BRep::EmbeddingLineRange::begin() const -> const EmbeddingLineRange& + { + return *this; + } + + auto BRep::EmbeddingLineRange::end() const -> const EmbeddingLineRange& + { + return *this; + } + + void BRep::EmbeddingLineRange::operator++() + { + Relationships::EmbeddingRangeIterator::operator++(); + internal::next_filtered_embedding_iterator< Surface3D >( *this ); + } + + const Line3D& BRep::EmbeddingLineRange::operator*() const + { + return brep_.line( + Relationships::EmbeddingRangeIterator::operator*().id() ); + } + BRep::EmbeddingSurfaceRange BRep::embedding_surfaces( const Corner3D& corner ) const { @@ -761,6 +817,11 @@ namespace geode return { *this, collection }; } + index_t BRep::nb_internal_corners( const Line3D& line ) const + { + return detail::count_range_elements( internal_corners( line ) ); + } + index_t BRep::nb_internal_corners( const Surface3D& surface ) const { return detail::count_range_elements( internal_corners( surface ) ); @@ -786,6 +847,11 @@ namespace geode return detail::count_range_elements( internal_surfaces( block ) ); } + index_t BRep::nb_embedding_lines( const Corner3D& corner ) const + { + return detail::count_range_elements( embedding_lines( corner ) ); + } + index_t BRep::nb_embedding_surfaces( const Corner3D& corner ) const { return detail::count_range_elements( embedding_surfaces( corner ) ); @@ -837,6 +903,11 @@ namespace geode return Relationships::is_boundary( surface.id(), block.id() ); } + bool BRep::is_internal( const Corner3D& corner, const Line3D& line ) const + { + return Relationships::is_internal( corner.id(), line.id() ); + } + bool BRep::is_internal( const Corner3D& corner, const Surface3D& surface ) const { diff --git a/src/geode/model/representation/core/section.cpp b/src/geode/model/representation/core/section.cpp index b61973dbc..537250da0 100644 --- a/src/geode/model/representation/core/section.cpp +++ b/src/geode/model/representation/core/section.cpp @@ -245,6 +245,20 @@ namespace geode Relationships::InternalRangeIterator::operator*().id() ); } + Section::InternalCornerRange Section::internal_corners( + const Line2D& line ) const + { + return { *this, line }; + } + + Section::InternalCornerRange::InternalCornerRange( + const Section& section, const Line2D& line ) + : Relationships::InternalRangeIterator( section, line.id() ), + section_( section ) + { + internal::next_filtered_internal_iterator< Corner2D >( *this ); + } + Section::InternalCornerRange Section::internal_corners( const Surface2D& surface ) const { @@ -291,6 +305,51 @@ namespace geode Relationships::InternalRangeIterator::operator*().id() ); } + Section::EmbeddingLineRange Section::embedding_lines( + const Corner2D& corner ) const + { + return { *this, corner }; + } + + Section::EmbeddingLineRange::EmbeddingLineRange( + const Section& section, const Corner2D& corner ) + : Relationships::EmbeddingRangeIterator( section, corner.id() ), + section_( section ) + { + internal::next_filtered_embedding_iterator< Line2D >( *this ); + } + + Section::EmbeddingLineRange::EmbeddingLineRange( + const EmbeddingLineRange& range ) + : Relationships::EmbeddingRangeIterator{ range }, + section_( range.section_ ) + { + } + + Section::EmbeddingLineRange::~EmbeddingLineRange() = default; + + auto Section::EmbeddingLineRange::begin() const -> const EmbeddingLineRange& + { + return *this; + } + + auto Section::EmbeddingLineRange::end() const -> const EmbeddingLineRange& + { + return *this; + } + + void Section::EmbeddingLineRange::operator++() + { + Relationships::EmbeddingRangeIterator::operator++(); + internal::next_filtered_embedding_iterator< Line2D >( *this ); + } + + const Line2D& Section::EmbeddingLineRange::operator*() const + { + return section_.line( + Relationships::EmbeddingRangeIterator::operator*().id() ); + } + Section::EmbeddingSurfaceRange Section::embedding_surfaces( const Corner2D& corner ) const { @@ -521,6 +580,11 @@ namespace geode return { *this, collection }; } + index_t Section::nb_internal_corners( const Line2D& line ) const + { + return detail::count_range_elements( internal_corners( line ) ); + } + index_t Section::nb_internal_corners( const Surface2D& surface ) const { return detail::count_range_elements( internal_corners( surface ) ); @@ -531,6 +595,11 @@ namespace geode return detail::count_range_elements( internal_lines( surface ) ); } + index_t Section::nb_embedding_lines( const Corner2D& corner ) const + { + return detail::count_range_elements( embedding_lines( corner ) ); + } + index_t Section::nb_embedding_surfaces( const Corner2D& corner ) const { return detail::count_range_elements( embedding_surfaces( corner ) ); @@ -558,6 +627,12 @@ namespace geode return Relationships::is_boundary( line.id(), surface.id() ); } + bool Section::is_internal( + const Corner2D& corner, const Line2D& line ) const + { + return Relationships::is_internal( corner.id(), line.id() ); + } + bool Section::is_internal( const Corner2D& corner, const Surface2D& surface ) const { From 88e64d952b6799e8bc4febab6f77d8983eed639e Mon Sep 17 00:00:00 2001 From: MelchiorSchuh Date: Wed, 24 Jun 2026 15:30:33 +0200 Subject: [PATCH 2/2] added tests --- src/geode/model/representation/core/brep.cpp | 2 +- tests/model/test-brep.cpp | 48 ++++++++++++++------ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/geode/model/representation/core/brep.cpp b/src/geode/model/representation/core/brep.cpp index c79c7f9dd..abba02ca6 100644 --- a/src/geode/model/representation/core/brep.cpp +++ b/src/geode/model/representation/core/brep.cpp @@ -470,7 +470,7 @@ namespace geode void BRep::EmbeddingLineRange::operator++() { Relationships::EmbeddingRangeIterator::operator++(); - internal::next_filtered_embedding_iterator< Surface3D >( *this ); + internal::next_filtered_embedding_iterator< Line3D >( *this ); } const Line3D& BRep::EmbeddingLineRange::operator*() const diff --git a/tests/model/test-brep.cpp b/tests/model/test-brep.cpp index 7dba368c2..ee257e5a6 100644 --- a/tests/model/test-brep.cpp +++ b/tests/model/test-brep.cpp @@ -66,7 +66,6 @@ std::array< geode::uuid, 6 > add_corners( { uuids[c] = builder.add_corner(); builder.set_corner_name( uuids[c], absl::StrCat( "corner", c + 1 ) ); - SDEBUG( uuids[c] ); } const auto& temp_corner = model.corner( builder.add_corner( geode::OpenGeodePointSet3D::impl_name_static() ) ); @@ -164,11 +163,9 @@ geode::uuid add_block( const geode::BRep& model, geode::BRepBuilder& builder ) geode::detail::count_range_elements( model.blocks() ) == 1, message ); geode::OpenGeodeModelException::test( model.block( block_uuid ).name() == "block1", "Wrong Block name" ); - DEBUG( model.nb_active_blocks() ); geode::OpenGeodeModelException::test( model.nb_active_blocks() == 1, message ); builder.set_block_active( block_uuid, false ); - DEBUG( model.nb_active_blocks() ); geode::OpenGeodeModelException::test( model.nb_active_blocks() == 0, "BRep should have 0 active block" ); geode::OpenGeodeModelException::test( @@ -374,7 +371,7 @@ void add_corner_line_boundary_relation( const geode::BRep& model, builder.add_corner_line_boundary_relationship( model.corner( corner_uuids[3] ), model.line( line_uuids[6] ) ); builder.add_corner_line_boundary_relationship( - model.corner( corner_uuids[3] ), model.line( line_uuids[8] ) ); + model.corner( corner_uuids[3] ), model.line( line_uuids[7] ) ); builder.add_corner_line_boundary_relationship( model.corner( corner_uuids[4] ), model.line( line_uuids[3] ) ); builder.add_corner_line_boundary_relationship( @@ -386,7 +383,7 @@ void add_corner_line_boundary_relation( const geode::BRep& model, builder.add_corner_line_boundary_relationship( model.corner( corner_uuids[5] ), model.line( line_uuids[7] ) ); builder.add_corner_line_boundary_relationship( - model.corner( corner_uuids[5] ), model.line( line_uuids[8] ) ); + model.corner( corner_uuids[5] ), model.line( line_uuids[6] ) ); for( const auto& corner_id : corner_uuids ) { @@ -402,18 +399,27 @@ void add_corner_line_boundary_relation( const geode::BRep& model, "All Corners should be connected to 3 Lines" ); } - for( const auto& line_id : line_uuids ) + for( const auto& line_id : geode::Range{ line_uuids.size() - 1 } ) { - for( const auto& boundary : model.boundaries( model.line( line_id ) ) ) + for( const auto& boundary : + model.boundaries( model.line( line_uuids[line_id] ) ) ) { geode::OpenGeodeModelException::test( absl::c_find( corner_uuids, boundary.id() ) != corner_uuids.end(), "All Lines incidences should be Corners" ); } - geode::OpenGeodeModelException::test( - model.nb_boundaries( line_id ) == 2, - "All Lines should be connected to 2 Corners" ); + const auto nb_boundaries = model.nb_boundaries( line_uuids[line_id] ); + if( line_id < 6 ) + { + geode::OpenGeodeModelException::test( nb_boundaries == 2, + "Line should be connected to 2 Corners, not ", nb_boundaries ); + } + else + { + geode::OpenGeodeModelException::test( nb_boundaries == 3, + "Line should be connected to 3 Corners, not ", nb_boundaries ); + } } } @@ -625,11 +631,14 @@ void add_block_in_block_collection( const geode::BRep& model, void add_internal_corner_relations( const geode::BRep& model, geode::BRepBuilder& builder, absl::Span< const geode::uuid > corner_uuids, + absl::Span< const geode::uuid > line_uuids, absl::Span< const geode::uuid > surface_uuids, const geode::uuid& block_uuid ) { for( const auto& corner_id : corner_uuids ) { + builder.add_corner_line_internal_relationship( + model.corner( corner_id ), model.line( line_uuids.back() ) ); builder.add_corner_surface_internal_relationship( model.corner( corner_id ), model.surface( surface_uuids.front() ) ); builder.add_corner_block_internal_relationship( @@ -638,6 +647,16 @@ void add_internal_corner_relations( const geode::BRep& model, for( const auto& corner_id : corner_uuids ) { + for( const auto& embedding : + model.embedding_lines( model.corner( corner_id ) ) ) + { + geode::OpenGeodeModelException::test( + line_uuids.back() == embedding.id(), + "All Corners should be embedded in the same Line" ); + geode::OpenGeodeModelException::test( + model.nb_internal_corners( embedding ) == corner_uuids.size(), + "Line should embed all Corners" ); + } for( const auto& embedding : model.embedding_surfaces( model.corner( corner_id ) ) ) { @@ -658,8 +677,11 @@ void add_internal_corner_relations( const geode::BRep& model, "Block should embed all Corners" ); } geode::OpenGeodeModelException::test( - model.nb_embeddings( corner_id ) == 2, - "All Corners should be embedded to 1 Block and 1 Surface" ); + model.nb_embeddings( corner_id ) == 3, + "All Corners should be embedded to 1 Block, 1 Surface and 1 Line" ); + geode::OpenGeodeModelException::test( + model.nb_embedding_lines( model.corner( corner_id ) ) == 1, + "All Corners should be embedded to 1 Line" ); geode::OpenGeodeModelException::test( model.nb_embedding_surfaces( model.corner( corner_id ) ) == 1, "All Corners should be embedded to 1 Surface" ); @@ -1560,7 +1582,7 @@ void test() add_block_in_block_collection( model, builder, block_uuid, block_collection_uuid ); add_internal_corner_relations( - model, builder, corner_uuids, surface_uuids, block_uuid ); + model, builder, corner_uuids, line_uuids, surface_uuids, block_uuid ); add_internal_line_relations( model, builder, line_uuids, surface_uuids, block_uuid ); add_internal_surface_block_relations(